qa: Avoid deprecation warnings for QList/QSet conversions
[quassel.git] / src / client / bufferviewoverlay.cpp
index 66dec13..455f273 100644 (file)
@@ -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"
 
 #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<int> 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<BufferViewConfig *>(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<int>::const_iterator iter;
+    for (iter = currentIds.constBegin(); iter != currentIds.constEnd(); ++iter) {
+        addView(*iter);
+    }
 }
 
-void BufferViewOverlay::viewInitialized() {
-  BufferViewConfig *config = qobject_cast<BufferViewConfig *>(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() {
-  bool changed = false;
-
-  bool addBuffersAutomatically = false;
-  bool hideInactiveBuffers = true;
-  int allowedBufferTypes = 0;
-  int minimumActivity = -1;
-  QSet<NetworkId> networkIds;
-  QSet<BufferId> buffers;
-  QSet<BufferId> removedBuffers;
-  QSet<BufferId> tempRemovedBuffers;
-
-  if(Client::bufferViewManager()) {
-    BufferViewConfig *config = 0;
-    QSet<int>::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<BufferId> 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();
+}
+
+void BufferViewOverlay::removeView(int viewId)
+{
+    if (!_bufferViewIds.contains(viewId))
+        return;
 
-        bufferIds.clear();
-        foreach(BufferId bufferId, config->temporarilyRemovedBuffers()) {
-          if(Client::networkModel()->networkId(bufferId) == networkId)
-            bufferIds << bufferId;
+    _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<int>::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();
     }
-  }
-
-  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;
-
-  if(changed)
-    emit hasChanged();
-}
-
-void BufferViewOverlay::customEvent(QEvent *event) {
-  if(event->type() == _updateEventId) {
-    updateHelper();
+
+    update();
+    if (!wasInitialized && isInitialized())
+        emit initDone();
+    save();
+}
+
+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();
+}
+
+void BufferViewOverlay::viewInitialized()
+{
+    auto* config = qobject_cast<BufferViewConfig*>(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;
+
+    int allowedBufferTypes = 0;
+    int minimumActivity = -1;
+    QSet<NetworkId> networkIds;
+    QSet<BufferId> buffers;
+    QSet<BufferId> removedBuffers;
+    QSet<BufferId> tempRemovedBuffers;
+
+    if (Client::bufferViewManager()) {
+        BufferViewConfig* config = nullptr;
+        QSet<int>::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<BufferId> 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<BufferId> BufferViewOverlay::filterBuffersByConfig(const QList<BufferId>& buffers, const BufferViewConfig* config)
+{
+    Q_ASSERT(config);
+
+    QSet<BufferId> 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<NetworkId>& BufferViewOverlay::networkIds()
+{
+    updateHelper();
+    return _networkIds;
+}
+
+const QSet<BufferId>& BufferViewOverlay::bufferIds()
+{
+    updateHelper();
+    return _buffers;
+}
+
+const QSet<BufferId>& BufferViewOverlay::removedBufferIds()
+{
+    updateHelper();
+    return _removedBuffers;
+}
+
+const QSet<BufferId>& BufferViewOverlay::tempRemovedBufferIds()
+{
+    updateHelper();
+    return _tempRemovedBuffers;
+}
+
+int BufferViewOverlay::allowedBufferTypes()
+{
+    updateHelper();
+    return _allowedBufferTypes;
+}
+
+int BufferViewOverlay::minimumActivity()
+{
+    updateHelper();
+    return _minimumActivity;
 }