X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fclient%2Fbufferviewoverlay.cpp;h=455f27350660b496747f3961b2bc4cd436266205;hp=cba8035a7389d7de9a12ef12d99d147e9c00f404;hb=52209badc8e769e50aa3019b63689dda0e79e9d0;hpb=7fc418e5841a1633f651e08a34ccd2123ba6e0db diff --git a/src/client/bufferviewoverlay.cpp b/src/client/bufferviewoverlay.cpp index cba8035a..455f2735 100644 --- a/src/client/bufferviewoverlay.cpp +++ b/src/client/bufferviewoverlay.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-08 by the Quassel Project * + * Copyright (C) 2005-2019 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -15,7 +15,7 @@ * 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. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "bufferviewoverlay.h" @@ -24,223 +24,290 @@ #include "bufferviewconfig.h" #include "client.h" +#include "clientbacklogmanager.h" #include "clientbufferviewmanager.h" #include "networkmodel.h" +#include "util.h" const int BufferViewOverlay::_updateEventId = QEvent::registerEventType(); -BufferViewOverlay::BufferViewOverlay(QObject *parent) - : QObject(parent), - _aboutToUpdate(false), - _addBuffersAutomatically(false), - _hideInactiveBuffers(false), - _allowedBufferTypes(0), - _minimumActivity(0) +BufferViewOverlay::BufferViewOverlay(QObject* parent) + : QObject(parent) +{} + +void BufferViewOverlay::reset() { + _aboutToUpdate = false; + + _bufferViewIds.clear(); + _uninitializedViewCount = 0; + + _networkIds.clear(); + _allowedBufferTypes = 0; + _minimumActivity = 0; + + _buffers.clear(); + _removedBuffers.clear(); + _tempRemovedBuffers.clear(); } -void BufferViewOverlay::addView(int viewId) { - if(_bufferViewIds.contains(viewId)) - return; +void BufferViewOverlay::save() +{ + CoreAccountSettings().setBufferViewOverlay(_bufferViewIds); +} - BufferViewConfig *config = Client::bufferViewManager()->bufferViewConfig(viewId); - if(!config) { - qDebug() << "BufferViewOverlay::addView(): no such buffer view:" << viewId; - return; - } +void BufferViewOverlay::restore() +{ + QSet currentIds = _bufferViewIds; + reset(); + currentIds += CoreAccountSettings().bufferViewOverlay(); - _bufferViewIds << viewId; - if(config->isInitialized()) { - viewInitialized(config); - } else { - disconnect(config, SIGNAL(initDone()), this, SLOT(viewInitialized())); - connect(config, SIGNAL(initDone()), this, SLOT(viewInitialized())); - } -} - -void BufferViewOverlay::removeView(int viewId) { - if(!_bufferViewIds.contains(viewId)) - return; - - _bufferViewIds.remove(viewId); - BufferViewConfig *config = qobject_cast(sender()); - if(config) - disconnect(config, 0, this, 0); - update(); -} - -void BufferViewOverlay::viewInitialized(BufferViewConfig *config) { - if(!config) { - qWarning() << "BufferViewOverlay::viewInitialized() received invalid view!"; - return; - } - disconnect(config, SIGNAL(initDone()), this, SLOT(viewInitialized())); - - connect(config, SIGNAL(networkIdSet(const NetworkId &)), this, SLOT(update())); - connect(config, SIGNAL(addNewBuffersAutomaticallySet(bool)), this, SLOT(update())); - connect(config, SIGNAL(sortAlphabeticallySet(bool)), this, SLOT(update())); - connect(config, SIGNAL(hideInactiveBuffersSet(bool)), this, SLOT(update())); - connect(config, SIGNAL(allowedBufferTypesSet(int)), this, SLOT(update())); - connect(config, SIGNAL(minimumActivitySet(int)), this, SLOT(update())); - connect(config, SIGNAL(bufferListSet()), this, SLOT(update())); - connect(config, SIGNAL(bufferAdded(const BufferId &, int)), this, SLOT(update())); - connect(config, SIGNAL(bufferRemoved(const BufferId &)), this, SLOT(update())); - connect(config, SIGNAL(bufferPermanentlyRemoved(const BufferId &)), this, SLOT(update())); - - // check if the view was removed in the meantime... - if(_bufferViewIds.contains(config->bufferViewId())) - update(); + QSet::const_iterator iter; + for (iter = currentIds.constBegin(); iter != currentIds.constEnd(); ++iter) { + addView(*iter); + } } -void BufferViewOverlay::viewInitialized() { - BufferViewConfig *config = qobject_cast(sender()); - Q_ASSERT(config); - - viewInitialized(config); -} - -void BufferViewOverlay::update() { - if(_aboutToUpdate) { - return; - } - _aboutToUpdate = true; - QCoreApplication::postEvent(this, new QEvent((QEvent::Type)_updateEventId)); -} - -void BufferViewOverlay::updateHelper() { - if(!_aboutToUpdate) - return; - - bool changed = false; - - bool addBuffersAutomatically = false; - bool hideInactiveBuffers = true; - int allowedBufferTypes = 0; - int minimumActivity = -1; - QSet networkIds; - QSet buffers; - QSet removedBuffers; - QSet tempRemovedBuffers; - - if(Client::bufferViewManager()) { - BufferViewConfig *config = 0; - QSet::const_iterator viewIter; - for(viewIter = _bufferViewIds.constBegin(); viewIter != _bufferViewIds.constEnd(); viewIter++) { - config = Client::bufferViewManager()->bufferViewConfig(*viewIter); - if(!config) - continue; - - networkIds << config->networkId(); - if(config->networkId().isValid()) { - NetworkId networkId = config->networkId(); - // we have to filter out all the buffers that don't belong to this net... :/ - QSet bufferIds; - foreach(BufferId bufferId, config->bufferList()) { - if(Client::networkModel()->networkId(bufferId) == networkId) - bufferIds << bufferId; +void BufferViewOverlay::addView(int viewId) +{ + if (_bufferViewIds.contains(viewId)) + return; + + BufferViewConfig* config = Client::bufferViewManager()->bufferViewConfig(viewId); + if (!config) { + qDebug() << "BufferViewOverlay::addView(): no such buffer view:" << viewId; + return; + } + + _bufferViewIds << viewId; + bool wasInitialized = isInitialized(); + _uninitializedViewCount++; + + if (config->isInitialized()) { + viewInitialized(config); + + if (wasInitialized) { + BufferIdList buffers; + if (config->networkId().isValid()) { + foreach (BufferId bufferId, config->bufferList()) { + if (Client::networkModel()->networkId(bufferId) == config->networkId()) + buffers << bufferId; + } + for (BufferId bufferId : config->temporarilyRemovedBuffers()) { + if (Client::networkModel()->networkId(bufferId) == config->networkId()) + buffers << bufferId; + } + } + else { + buffers = (toQSet(config->bufferList()) + config->temporarilyRemovedBuffers()).values(); + } + Client::backlogManager()->checkForBacklog(buffers); } - buffers += bufferIds; + } + else { + // we use a queued connection here since manipulating the connection list of a sending object + // doesn't seem to be such a good idea while executing a connected slots. + connect(config, &BufferViewConfig::initDone, this, selectOverload<>(&BufferViewOverlay::viewInitialized), Qt::QueuedConnection); + } + save(); +} - bufferIds.clear(); - foreach(BufferId bufferId, config->temporarilyRemovedBuffers()) { - if(Client::networkModel()->networkId(bufferId) == networkId) - bufferIds << bufferId; +void BufferViewOverlay::removeView(int viewId) +{ + if (!_bufferViewIds.contains(viewId)) + return; + + _bufferViewIds.remove(viewId); + BufferViewConfig* config = Client::bufferViewManager()->bufferViewConfig(viewId); + if (config) + disconnect(config, nullptr, this, nullptr); + + // update initialized State: + bool wasInitialized = isInitialized(); + _uninitializedViewCount = 0; + QSet::iterator viewIter = _bufferViewIds.begin(); + while (viewIter != _bufferViewIds.end()) { + config = Client::bufferViewManager()->bufferViewConfig(*viewIter); + if (!config) { + viewIter = _bufferViewIds.erase(viewIter); + } + else { + if (!config->isInitialized()) + _uninitializedViewCount++; + ++viewIter; } - tempRemovedBuffers += bufferIds; - } else { - buffers += config->bufferList().toSet(); - tempRemovedBuffers += config->temporarilyRemovedBuffers(); - } - - // in the overlay a buffer is removed it is removed from all views - if(removedBuffers.isEmpty()) - removedBuffers = config->removedBuffers(); - else - removedBuffers.intersect(config->removedBuffers()); - - - addBuffersAutomatically |= config->addNewBuffersAutomatically(); - hideInactiveBuffers &= config->hideInactiveBuffers(); - allowedBufferTypes |= config->allowedBufferTypes(); - if(minimumActivity == -1 || config->minimumActivity() < minimumActivity) - minimumActivity = config->minimumActivity(); } - QSet availableBuffers = Client::networkModel()->allBufferIds().toSet(); - buffers.intersect(availableBuffers); - tempRemovedBuffers.intersect(availableBuffers); - } - - changed |= (addBuffersAutomatically != _addBuffersAutomatically); - changed |= (hideInactiveBuffers != _hideInactiveBuffers); - changed |= (allowedBufferTypes != _allowedBufferTypes); - changed |= (minimumActivity != _minimumActivity); - changed |= (networkIds != _networkIds); - changed |= (buffers != _buffers); - changed |= (removedBuffers != _removedBuffers); - changed |= (tempRemovedBuffers != _tempRemovedBuffers); - - _addBuffersAutomatically = addBuffersAutomatically; - _hideInactiveBuffers = hideInactiveBuffers; - _allowedBufferTypes = allowedBufferTypes; - _minimumActivity = minimumActivity; - _networkIds = networkIds; - _buffers = buffers; - _removedBuffers = removedBuffers; - _tempRemovedBuffers = tempRemovedBuffers; - - _aboutToUpdate = false; - - if(changed) - emit hasChanged(); -} - -void BufferViewOverlay::customEvent(QEvent *event) { - if(event->type() == _updateEventId) { - updateHelper(); - } + + update(); + if (!wasInitialized && isInitialized()) + emit initDone(); + save(); } -bool BufferViewOverlay::allNetworks() { - updateHelper(); - return _networkIds.contains(NetworkId()); +void BufferViewOverlay::viewInitialized(BufferViewConfig* config) +{ + if (!config) { + qWarning() << "BufferViewOverlay::viewInitialized() received invalid view!"; + return; + } + connect(config, &BufferViewConfig::configChanged, this, &BufferViewOverlay::update); + + // check if the view was removed in the meantime... + if (_bufferViewIds.contains(config->bufferViewId())) + update(); + + _uninitializedViewCount--; + if (isInitialized()) + emit initDone(); } -const QSet &BufferViewOverlay::networkIds() { - updateHelper(); - return _networkIds; +void BufferViewOverlay::viewInitialized() +{ + auto* config = qobject_cast(sender()); + Q_ASSERT(config); + + viewInitialized(config); } -const QSet &BufferViewOverlay::bufferIds() { - updateHelper(); - return _buffers; +void BufferViewOverlay::update() +{ + if (_aboutToUpdate) { + return; + } + _aboutToUpdate = true; + QCoreApplication::postEvent(this, new QEvent((QEvent::Type)_updateEventId)); } -const QSet &BufferViewOverlay::removedBufferIds() { - updateHelper(); - return _removedBuffers; +void BufferViewOverlay::updateHelper() +{ + if (!_aboutToUpdate) + return; + + bool changed = false; + + int allowedBufferTypes = 0; + int minimumActivity = -1; + QSet networkIds; + QSet buffers; + QSet removedBuffers; + QSet tempRemovedBuffers; + + if (Client::bufferViewManager()) { + BufferViewConfig* config = nullptr; + QSet::const_iterator viewIter; + for (viewIter = _bufferViewIds.constBegin(); viewIter != _bufferViewIds.constEnd(); ++viewIter) { + config = Client::bufferViewManager()->bufferViewConfig(*viewIter); + if (!config) + continue; + + allowedBufferTypes |= config->allowedBufferTypes(); + if (minimumActivity == -1 || config->minimumActivity() < minimumActivity) + minimumActivity = config->minimumActivity(); + + networkIds << config->networkId(); + + // we have to apply several filters before we can add a buffer to a category (visible, removed, ...) + buffers += filterBuffersByConfig(config->bufferList(), config); + tempRemovedBuffers += filterBuffersByConfig(config->temporarilyRemovedBuffers().values(), config); + removedBuffers += config->removedBuffers(); + } + + // prune the sets from overlap + QSet availableBuffers = toQSet(Client::networkModel()->allBufferIds()); + + buffers.intersect(availableBuffers); + + tempRemovedBuffers.intersect(availableBuffers); + tempRemovedBuffers.subtract(buffers); + + removedBuffers.intersect(availableBuffers); + removedBuffers.subtract(tempRemovedBuffers); + removedBuffers.subtract(buffers); + } + + changed |= (allowedBufferTypes != _allowedBufferTypes); + changed |= (minimumActivity != _minimumActivity); + changed |= (networkIds != _networkIds); + changed |= (buffers != _buffers); + changed |= (removedBuffers != _removedBuffers); + changed |= (tempRemovedBuffers != _tempRemovedBuffers); + + _allowedBufferTypes = allowedBufferTypes; + _minimumActivity = minimumActivity; + _networkIds = networkIds; + _buffers = buffers; + _removedBuffers = removedBuffers; + _tempRemovedBuffers = tempRemovedBuffers; + + _aboutToUpdate = false; + + if (changed) + emit hasChanged(); +} + +QSet BufferViewOverlay::filterBuffersByConfig(const QList& buffers, const BufferViewConfig* config) +{ + Q_ASSERT(config); + + QSet bufferIds; + BufferInfo bufferInfo; + foreach (BufferId bufferId, buffers) { + bufferInfo = Client::networkModel()->bufferInfo(bufferId); + if (!(bufferInfo.type() & config->allowedBufferTypes())) + continue; + if (config->networkId().isValid() && bufferInfo.networkId() != config->networkId()) + continue; + bufferIds << bufferId; + } + + return bufferIds; +} + +void BufferViewOverlay::customEvent(QEvent* event) +{ + if (event->type() == _updateEventId) { + updateHelper(); + } +} + +bool BufferViewOverlay::allNetworks() +{ + updateHelper(); + return _networkIds.contains(NetworkId()); } -const QSet &BufferViewOverlay::tempRemovedBufferIds() { - updateHelper(); - return _tempRemovedBuffers; +const QSet& BufferViewOverlay::networkIds() +{ + updateHelper(); + return _networkIds; } -bool BufferViewOverlay::addBuffersAutomatically() { - updateHelper(); - return _addBuffersAutomatically; +const QSet& BufferViewOverlay::bufferIds() +{ + updateHelper(); + return _buffers; } -bool BufferViewOverlay::hideInactiveBuffers() { - updateHelper(); - return _hideInactiveBuffers; +const QSet& BufferViewOverlay::removedBufferIds() +{ + updateHelper(); + return _removedBuffers; } -int BufferViewOverlay::allowedBufferTypes() { - updateHelper(); - return _allowedBufferTypes; +const QSet& BufferViewOverlay::tempRemovedBufferIds() +{ + updateHelper(); + return _tempRemovedBuffers; +} + +int BufferViewOverlay::allowedBufferTypes() +{ + updateHelper(); + return _allowedBufferTypes; } -int BufferViewOverlay::minimumActivity() { - updateHelper(); - return _minimumActivity; +int BufferViewOverlay::minimumActivity() +{ + updateHelper(); + return _minimumActivity; }