Sync last message id per buffer
[quassel.git] / src / core / corebuffersyncer.cpp
index fc4812a..2829f5d 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-2015 by the Quassel Project                        *
+ *   Copyright (C) 2005-2020 by the Quassel Project                        *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
 
 #include "corebuffersyncer.h"
 
+#include <algorithm>
+#include <iterator>
+#include <set>
+
 #include "core.h"
-#include "coresession.h"
 #include "corenetwork.h"
+#include "coresession.h"
 #include "ircchannel.h"
+#include "util.h"
 
 class PurgeEvent : public QEvent
 {
 public:
-    PurgeEvent() : QEvent(QEvent::User) {}
+    PurgeEvent()
+        : QEvent(QEvent::User)
+    {}
 };
 
-
-INIT_SYNCABLE_OBJECT(CoreBufferSyncer)
-CoreBufferSyncer::CoreBufferSyncer(CoreSession *parent)
-    : BufferSyncer(Core::bufferLastSeenMsgIds(parent->user()), Core::bufferMarkerLineMsgIds(parent->user()), parent),
-    _coreSession(parent),
-    _purgeBuffers(false)
+CoreBufferSyncer::CoreBufferSyncer(CoreSession* parent)
+    : BufferSyncer(Core::bufferLastMsgIds(parent->user()),
+                   Core::bufferLastSeenMsgIds(parent->user()),
+                   Core::bufferMarkerLineMsgIds(parent->user()),
+                   Core::bufferActivities(parent->user()),
+                   Core::highlightCounts(parent->user()),
+                   parent)
+    , _coreSession(parent)
+    , _purgeBuffers(false)
 {
+    connect(parent, &CoreSession::displayMsg, this, &CoreBufferSyncer::addBufferActivity);
+    connect(parent, &CoreSession::displayMsg, this, &CoreBufferSyncer::addCoreHighlight);
 }
 
-
-void CoreBufferSyncer::requestSetLastSeenMsg(BufferId buffer, const MsgId &msgId)
+void CoreBufferSyncer::requestSetLastSeenMsg(BufferId buffer, const MsgId& msgId)
 {
-    if (setLastSeenMsg(buffer, msgId))
+    if (setLastSeenMsg(buffer, msgId)) {
+        int activity = Core::bufferActivity(buffer, msgId);
+        int highlightCount = Core::highlightCount(buffer, msgId);
+
+        setBufferActivity(buffer, activity);
+        setHighlightCount(buffer, highlightCount);
+
         dirtyLastSeenBuffers << buffer;
+    }
 }
 
-
-void CoreBufferSyncer::requestSetMarkerLine(BufferId buffer, const MsgId &msgId)
+void CoreBufferSyncer::requestSetMarkerLine(BufferId buffer, const MsgId& msgId)
 {
     if (setMarkerLine(buffer, msgId))
         dirtyMarkerLineBuffers << buffer;
 }
 
-
 void CoreBufferSyncer::storeDirtyIds()
 {
     UserId userId = _coreSession->user();
     MsgId msgId;
-    foreach(BufferId bufferId, dirtyLastSeenBuffers) {
+    foreach (BufferId bufferId, dirtyLastSeenBuffers) {
         msgId = lastSeenMsg(bufferId);
         if (msgId.isValid())
             Core::setBufferLastSeenMsg(userId, bufferId, msgId);
     }
 
-    foreach(BufferId bufferId, dirtyMarkerLineBuffers) {
+    foreach (BufferId bufferId, dirtyMarkerLineBuffers) {
         msgId = markerLine(bufferId);
         if (msgId.isValid())
             Core::setBufferMarkerLineMsg(userId, bufferId, msgId);
     }
 
+    foreach (BufferId bufferId, dirtyActivities) {
+        Core::setBufferActivity(userId, bufferId, activity(bufferId));
+    }
+
+    foreach (BufferId bufferId, dirtyHighlights) {
+        Core::setHighlightCount(userId, bufferId, highlightCount(bufferId));
+    }
+
     dirtyLastSeenBuffers.clear();
     dirtyMarkerLineBuffers.clear();
+    dirtyActivities.clear();
+    dirtyHighlights.clear();
 }
 
-
 void CoreBufferSyncer::removeBuffer(BufferId bufferId)
 {
     BufferInfo bufferInfo = Core::getBufferInfo(_coreSession->user(), bufferId);
@@ -90,12 +115,12 @@ void CoreBufferSyncer::removeBuffer(BufferId bufferId)
     }
 
     if (bufferInfo.type() == BufferInfo::ChannelBuffer) {
-        CoreNetwork *net = _coreSession->network(bufferInfo.networkId());
+        CoreNetworknet = _coreSession->network(bufferInfo.networkId());
         if (!net) {
             qWarning() << "CoreBufferSyncer::removeBuffer(): Received BufferInfo with unknown networkId!";
             return;
         }
-        IrcChannel *chan = net->ircChannel(bufferInfo.bufferName());
+        IrcChannelchan = net->ircChannel(bufferInfo.bufferName());
         if (chan) {
             qWarning() << "CoreBufferSyncer::removeBuffer(): Unable to remove Buffer for joined Channel:" << bufferInfo.bufferName();
             return;
@@ -105,7 +130,6 @@ void CoreBufferSyncer::removeBuffer(BufferId bufferId)
         BufferSyncer::removeBuffer(bufferId);
 }
 
-
 void CoreBufferSyncer::renameBuffer(BufferId bufferId, QString newName)
 {
     BufferInfo bufferInfo = Core::getBufferInfo(_coreSession->user(), bufferId);
@@ -123,18 +147,20 @@ void CoreBufferSyncer::renameBuffer(BufferId bufferId, QString newName)
         BufferSyncer::renameBuffer(bufferId, newName);
 }
 
-
 void CoreBufferSyncer::mergeBuffersPermanently(BufferId bufferId1, BufferId bufferId2)
 {
     BufferInfo bufferInfo1 = Core::getBufferInfo(_coreSession->user(), bufferId1);
     BufferInfo bufferInfo2 = Core::getBufferInfo(_coreSession->user(), bufferId2);
     if (!bufferInfo1.isValid() || !bufferInfo2.isValid()) {
-        qWarning() << "CoreBufferSyncer::mergeBufferPermanently(): invalid BufferIds:" << bufferId1 << bufferId2 << "for User:" << _coreSession->user();
+        qWarning() << "CoreBufferSyncer::mergeBuffersPermanently(): invalid BufferIds:" << bufferId1 << bufferId2
+                   << "for User:" << _coreSession->user();
         return;
     }
 
-    if (bufferInfo1.type() != BufferInfo::QueryBuffer || bufferInfo2.type() != BufferInfo::QueryBuffer) {
-        qWarning() << "CoreBufferSyncer::mergeBufferPermanently(): only QueryBuffers can be merged!" << bufferId1 << bufferId2;
+    if ((bufferInfo1.type() != BufferInfo::QueryBuffer && bufferInfo1.type() != BufferInfo::ChannelBuffer)
+        || (bufferInfo2.type() != BufferInfo::QueryBuffer && bufferInfo2.type() != BufferInfo::ChannelBuffer)) {
+        qWarning() << "CoreBufferSyncer::mergeBuffersPermanently(): only QueryBuffers and/or ChannelBuffers can be merged!" << bufferId1
+                   << bufferId2;
         return;
     }
 
@@ -143,8 +169,7 @@ void CoreBufferSyncer::mergeBuffersPermanently(BufferId bufferId1, BufferId buff
     }
 }
 
-
-void CoreBufferSyncer::customEvent(QEvent *event)
+void CoreBufferSyncer::customEvent(QEvent* event)
 {
     if (event->type() != QEvent::User)
         return;
@@ -153,7 +178,6 @@ void CoreBufferSyncer::customEvent(QEvent *event)
     event->accept();
 }
 
-
 void CoreBufferSyncer::requestPurgeBufferIds()
 {
     if (_purgeBuffers)
@@ -163,20 +187,30 @@ void CoreBufferSyncer::requestPurgeBufferIds()
     QCoreApplication::postEvent(this, new PurgeEvent());
 }
 
-
 void CoreBufferSyncer::purgeBufferIds()
 {
     _purgeBuffers = false;
-    QList<BufferInfo> bufferInfos = Core::requestBuffers(_coreSession->user());
-    QSet<BufferId> actualBuffers;
-    foreach(BufferInfo bufferInfo, bufferInfos) {
-        actualBuffers << bufferInfo.bufferId();
-    }
-
-    QSet<BufferId> storedIds = lastSeenBufferIds().toSet() + markerLineBufferIds().toSet();
-    foreach(BufferId bufferId, storedIds) {
-        if (!actualBuffers.contains(bufferId)) {
+    auto bufferInfos = Core::requestBuffers(_coreSession->user());
+    std::set<BufferId> actualBuffers;
+    std::transform(bufferInfos.cbegin(), bufferInfos.cend(), std::inserter(actualBuffers, actualBuffers.end()),
+                   [](auto&& bufferInfo) { return bufferInfo.bufferId(); });
+
+    QSet<BufferId> storedIds = toQSet(lastSeenBufferIds()) + toQSet(markerLineBufferIds());
+    foreach (BufferId bufferId, storedIds) {
+        if (actualBuffers.find(bufferId) == actualBuffers.end()) {
             BufferSyncer::removeBuffer(bufferId);
         }
     }
 }
+
+void CoreBufferSyncer::setBufferActivity(BufferId buffer, int activity)
+{
+    BufferSyncer::setBufferActivity(buffer, activity);
+    dirtyActivities << buffer;
+}
+
+void CoreBufferSyncer::setHighlightCount(BufferId buffer, int highlightCount)
+{
+    BufferSyncer::setHighlightCount(buffer, highlightCount);
+    dirtyHighlights << buffer;
+}