Untie the marker line from lastSeenMsg
authorManuel Nickschas <sputnick@quassel-irc.org>
Thu, 8 Oct 2009 08:54:11 +0000 (10:54 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Fri, 1 Jan 2010 21:07:56 +0000 (22:07 +0100)
We now handle the marker line position independently from lastSeenMsg in the backend. This will
allow for setting the marker line manually in the future, for people who don't want the automatic
mark-as-read thingy. Currently, it's still set on buffer change, and the behavior should be the same
as before.

Note that this needs an updated core to work correctly, and will be disabled (= forced auto) else.

14 files changed:
src/client/client.cpp
src/client/client.h
src/client/networkmodel.cpp
src/client/networkmodel.h
src/common/buffersyncer.cpp
src/common/buffersyncer.h
src/core/corebuffersyncer.cpp
src/core/corebuffersyncer.h
src/qtui/chatitem.cpp
src/qtui/chatitem.h
src/qtui/chatline.cpp
src/qtui/chatviewsearchcontroller.cpp
src/uisupport/abstractbuffercontainer.cpp
src/uisupport/abstractbuffercontainer.h

index 30c1100..07b3c26 100644 (file)
@@ -316,6 +316,7 @@ void Client::setSyncedToCore() {
   Q_ASSERT(!_bufferSyncer);
   _bufferSyncer = new BufferSyncer(this);
   connect(bufferSyncer(), SIGNAL(lastSeenMsgSet(BufferId, MsgId)), _networkModel, SLOT(setLastSeenMsgId(BufferId, MsgId)));
   Q_ASSERT(!_bufferSyncer);
   _bufferSyncer = new BufferSyncer(this);
   connect(bufferSyncer(), SIGNAL(lastSeenMsgSet(BufferId, MsgId)), _networkModel, SLOT(setLastSeenMsgId(BufferId, MsgId)));
+  connect(bufferSyncer(), SIGNAL(markerLineSet(BufferId,MsgId)), _networkModel, SLOT(setMarkerLineMsgId(BufferId,MsgId)));
   connect(bufferSyncer(), SIGNAL(bufferRemoved(BufferId)), this, SLOT(bufferRemoved(BufferId)));
   connect(bufferSyncer(), SIGNAL(bufferRenamed(BufferId, QString)), this, SLOT(bufferRenamed(BufferId, QString)));
   connect(bufferSyncer(), SIGNAL(buffersPermanentlyMerged(BufferId, BufferId)), this, SLOT(buffersPermanentlyMerged(BufferId, BufferId)));
   connect(bufferSyncer(), SIGNAL(bufferRemoved(BufferId)), this, SLOT(bufferRemoved(BufferId)));
   connect(bufferSyncer(), SIGNAL(bufferRenamed(BufferId, QString)), this, SLOT(bufferRenamed(BufferId, QString)));
   connect(bufferSyncer(), SIGNAL(buffersPermanentlyMerged(BufferId, BufferId)), this, SLOT(buffersPermanentlyMerged(BufferId, BufferId)));
@@ -468,9 +469,13 @@ void Client::recvMessage(const Message &msg) {
 }
 
 void Client::setBufferLastSeenMsg(BufferId id, const MsgId &msgId) {
 }
 
 void Client::setBufferLastSeenMsg(BufferId id, const MsgId &msgId) {
-  if(!bufferSyncer())
-    return;
-  bufferSyncer()->requestSetLastSeenMsg(id, msgId);
+  if(bufferSyncer())
+    bufferSyncer()->requestSetLastSeenMsg(id, msgId);
+}
+
+void Client::setBufferMarkerLine(BufferId id, const MsgId &msgId) {
+  if(bufferSyncer())
+    bufferSyncer()->requestSetMarkerLine(id, msgId);
 }
 
 void Client::removeBuffer(BufferId id) {
 }
 
 void Client::removeBuffer(BufferId id) {
index 53dc786..e401f46 100644 (file)
@@ -127,6 +127,7 @@ public:
   static void userInput(const BufferInfo &bufferInfo, const QString &message);
 
   static void setBufferLastSeenMsg(BufferId id, const MsgId &msgId); // this is synced to core and other clients
   static void userInput(const BufferInfo &bufferInfo, const QString &message);
 
   static void setBufferLastSeenMsg(BufferId id, const MsgId &msgId); // this is synced to core and other clients
+  static void setBufferMarkerLine(BufferId id, const MsgId &msgId); // this is synced to core and other clients
   static void removeBuffer(BufferId id);
   static void renameBuffer(BufferId bufferId, const QString &newName);
   static void mergeBuffersPermanently(BufferId bufferId1, BufferId bufferId2);
   static void removeBuffer(BufferId id);
   static void renameBuffer(BufferId bufferId, const QString &newName);
   static void mergeBuffersPermanently(BufferId bufferId1, BufferId bufferId2);
index 1c365a4..6bc96f8 100644 (file)
@@ -68,6 +68,7 @@ QVariant NetworkItem::data(int column, int role) const {
   }
 }
 
   }
 }
 
+// FIXME shouldn't we check the bufferItemCache here?
 BufferItem *NetworkItem::findBufferItem(BufferId bufferId) {
   BufferItem *bufferItem = 0;
 
 BufferItem *NetworkItem::findBufferItem(BufferId bufferId) {
   BufferItem *bufferItem = 0;
 
@@ -231,8 +232,13 @@ void BufferItem::setActivityLevel(BufferInfo::ActivityLevel level) {
 
 void BufferItem::clearActivityLevel() {
   _activity = BufferInfo::NoActivity;
 
 void BufferItem::clearActivityLevel() {
   _activity = BufferInfo::NoActivity;
-  _lastSeenMarkerMsgId = _lastSeenMsgId;
   _firstUnreadMsgId = MsgId();
   _firstUnreadMsgId = MsgId();
+
+  // FIXME remove with core proto v11
+  if(!Client::coreFeatures() & Quassel::SynchronizedMarkerLine) {
+    _markerLineMsgId = _lastSeenMsgId;
+  }
+
   emit dataChanged();
 }
 
   emit dataChanged();
 }
 
@@ -286,6 +292,8 @@ QVariant BufferItem::data(int column, int role) const {
     return (int)activityLevel();
   case NetworkModel::BufferFirstUnreadMsgIdRole:
     return qVariantFromValue(firstUnreadMsgId());
     return (int)activityLevel();
   case NetworkModel::BufferFirstUnreadMsgIdRole:
     return qVariantFromValue(firstUnreadMsgId());
+  case NetworkModel::MarkerLineMsgIdRole:
+    return qVariantFromValue(markerLineMsgId());
   default:
     return PropertyMapItem::data(column, role);
   }
   default:
     return PropertyMapItem::data(column, role);
   }
@@ -307,14 +315,23 @@ void BufferItem::setBufferName(const QString &name) {
   emit dataChanged(0);
 }
 
   emit dataChanged(0);
 }
 
-void BufferItem::setLastSeenMsgId(const MsgId &msgId) {
+void BufferItem::setLastSeenMsgId(MsgId msgId) {
   _lastSeenMsgId = msgId;
   _lastSeenMsgId = msgId;
-  if(!isCurrentBuffer()) {
-    _lastSeenMarkerMsgId = msgId;
+
+  // FIXME remove with core protocol v11
+  if(!Client::coreFeatures() & Quassel::SynchronizedMarkerLine) {
+    if(!isCurrentBuffer())
+      _markerLineMsgId = msgId;
   }
   }
+
   setActivityLevel(BufferInfo::NoActivity);
 }
 
   setActivityLevel(BufferInfo::NoActivity);
 }
 
+void BufferItem::setMarkerLineMsgId(MsgId msgId) {
+  _markerLineMsgId = msgId;
+  emit dataChanged();
+}
+
 bool BufferItem::isCurrentBuffer() const {
   return _bufferInfo.bufferId() == Client::bufferModel()->currentIndex().data(NetworkModel::BufferIdRole).value<BufferId>();
 }
 bool BufferItem::isCurrentBuffer() const {
   return _bufferInfo.bufferId() == Client::bufferModel()->currentIndex().data(NetworkModel::BufferIdRole).value<BufferId>();
 }
@@ -979,13 +996,14 @@ MsgId NetworkModel::lastSeenMsgId(BufferId bufferId) const {
   return _bufferItemCache[bufferId]->lastSeenMsgId();
 }
 
   return _bufferItemCache[bufferId]->lastSeenMsgId();
 }
 
-MsgId NetworkModel::lastSeenMarkerMsgId(BufferId bufferId) const {
+MsgId NetworkModel::markerLineMsgId(BufferId bufferId) const {
   if(!_bufferItemCache.contains(bufferId))
     return MsgId();
 
   if(!_bufferItemCache.contains(bufferId))
     return MsgId();
 
-  return _bufferItemCache[bufferId]->lastSeenMarkerMsgId();
+  return _bufferItemCache[bufferId]->markerLineMsgId();
 }
 
 }
 
+// FIXME we always seem to use this (expensive) non-const version
 MsgId NetworkModel::lastSeenMsgId(const BufferId &bufferId) {
   BufferItem *bufferItem = findBufferItem(bufferId);
   if(!bufferItem) {
 MsgId NetworkModel::lastSeenMsgId(const BufferId &bufferId) {
   BufferItem *bufferItem = findBufferItem(bufferId);
   if(!bufferItem) {
@@ -1006,6 +1024,16 @@ void NetworkModel::setLastSeenMsgId(const BufferId &bufferId, const MsgId &msgId
   bufferItem->setLastSeenMsgId(msgId);
 }
 
   bufferItem->setLastSeenMsgId(msgId);
 }
 
+void NetworkModel::setMarkerLineMsgId(const BufferId &bufferId, const MsgId &msgId) {
+  BufferItem *bufferItem = findBufferItem(bufferId);
+  if(!bufferItem) {
+    qDebug() << "NetworkModel::setMarkerLineMsgId(): buffer is unknown:" << bufferId;
+    Client::purgeKnownBufferIds();
+    return;
+  }
+  bufferItem->setMarkerLineMsgId(msgId);
+}
+
 void NetworkModel::updateBufferActivity(Message &msg) {
   int redirectionTarget = 0;
   switch(msg.type()) {
 void NetworkModel::updateBufferActivity(Message &msg) {
   int redirectionTarget = 0;
   switch(msg.type()) {
index 09f9ece..52b49eb 100644 (file)
@@ -105,9 +105,11 @@ public:
 
   virtual inline bool isActive() const { return qobject_cast<NetworkItem *>(parent())->isActive(); }
 
 
   virtual inline bool isActive() const { return qobject_cast<NetworkItem *>(parent())->isActive(); }
 
-  inline const MsgId &lastSeenMsgId() const { return _lastSeenMsgId; }
-  inline const MsgId &lastSeenMarkerMsgId() const { return _lastSeenMarkerMsgId; }
-  void setLastSeenMsgId(const MsgId &msgId);
+  inline MsgId lastSeenMsgId() const { return _lastSeenMsgId; }
+  inline MsgId markerLineMsgId() const { return _markerLineMsgId; }
+  void setLastSeenMsgId(MsgId msgId);
+  void setMarkerLineMsgId(MsgId msgId);
+
   inline BufferInfo::ActivityLevel activityLevel() const { return _activity; }
   void setActivityLevel(BufferInfo::ActivityLevel level);
   void clearActivityLevel();
   inline BufferInfo::ActivityLevel activityLevel() const { return _activity; }
   void setActivityLevel(BufferInfo::ActivityLevel level);
   void clearActivityLevel();
@@ -125,7 +127,7 @@ private:
   BufferInfo _bufferInfo;
   BufferInfo::ActivityLevel _activity;
   MsgId _lastSeenMsgId;
   BufferInfo _bufferInfo;
   BufferInfo::ActivityLevel _activity;
   MsgId _lastSeenMsgId;
-  MsgId _lastSeenMarkerMsgId;
+  MsgId _markerLineMsgId;
   MsgId _firstUnreadMsgId;
 };
 
   MsgId _firstUnreadMsgId;
 };
 
@@ -275,6 +277,7 @@ public:
     IrcUserRole,
     IrcChannelRole,
     BufferFirstUnreadMsgIdRole,
     IrcUserRole,
     IrcChannelRole,
     BufferFirstUnreadMsgIdRole,
+    MarkerLineMsgIdRole,
   };
 
   enum ItemType {
   };
 
   enum ItemType {
@@ -317,7 +320,7 @@ public:
   BufferInfo::Type bufferType(BufferId bufferId) const;
   BufferInfo bufferInfo(BufferId bufferId) const;
   MsgId lastSeenMsgId(BufferId bufferId) const;
   BufferInfo::Type bufferType(BufferId bufferId) const;
   BufferInfo bufferInfo(BufferId bufferId) const;
   MsgId lastSeenMsgId(BufferId bufferId) const;
-  MsgId lastSeenMarkerMsgId(BufferId bufferId) const;
+  MsgId markerLineMsgId(BufferId bufferId) const;
   NetworkId networkId(BufferId bufferId) const;
   QString networkName(BufferId bufferId) const;
 
   NetworkId networkId(BufferId bufferId) const;
   QString networkName(BufferId bufferId) const;
 
@@ -330,6 +333,7 @@ public slots:
   void removeBuffer(BufferId bufferId);
   MsgId lastSeenMsgId(const BufferId &bufferId);
   void setLastSeenMsgId(const BufferId &bufferId, const MsgId &msgId);
   void removeBuffer(BufferId bufferId);
   MsgId lastSeenMsgId(const BufferId &bufferId);
   void setLastSeenMsgId(const BufferId &bufferId, const MsgId &msgId);
+  void setMarkerLineMsgId(const BufferId &bufferId, const MsgId &msgId);
   void setBufferActivity(const BufferId &bufferId, BufferInfo::ActivityLevel activity);
   void clearBufferActivity(const BufferId &bufferId);
   void updateBufferActivity(Message &msg);
   void setBufferActivity(const BufferId &bufferId, BufferInfo::ActivityLevel activity);
   void clearBufferActivity(const BufferId &bufferId);
   void updateBufferActivity(Message &msg);
index 82fe0da..4987429 100644 (file)
@@ -26,16 +26,15 @@ BufferSyncer::BufferSyncer(QObject *parent)
 {
 }
 
 {
 }
 
-BufferSyncer::BufferSyncer(const QHash<BufferId, MsgId> &lastSeenMsg, QObject *parent)
+BufferSyncer::BufferSyncer(const QHash<BufferId, MsgId> &lastSeenMsg, const QHash<BufferId, MsgId> &markerLines, QObject *parent)
   : SyncableObject(parent),
   : SyncableObject(parent),
-    _lastSeenMsg(lastSeenMsg)
+    _lastSeenMsg(lastSeenMsg),
+    _markerLines(markerLines)
 {
 }
 
 MsgId BufferSyncer::lastSeenMsg(BufferId buffer) const {
 {
 }
 
 MsgId BufferSyncer::lastSeenMsg(BufferId buffer) const {
-  if(_lastSeenMsg.contains(buffer))
-    return _lastSeenMsg[buffer];
-  return MsgId();
+  return _lastSeenMsg.value(buffer, MsgId());
 }
 
 bool BufferSyncer::setLastSeenMsg(BufferId buffer, const MsgId &msgId) {
 }
 
 bool BufferSyncer::setLastSeenMsg(BufferId buffer, const MsgId &msgId) {
@@ -52,13 +51,27 @@ bool BufferSyncer::setLastSeenMsg(BufferId buffer, const MsgId &msgId) {
   return false;
 }
 
   return false;
 }
 
+MsgId BufferSyncer::markerLine(BufferId buffer) const {
+  return _markerLines.value(buffer, MsgId());
+}
+
+bool BufferSyncer::setMarkerLine(BufferId buffer, const MsgId &msgId) {
+  if(!msgId.isValid())
+    return false;
+
+  _markerLines[buffer] = msgId;
+  SYNC(ARG(buffer), ARG(msgId))
+  emit markerLineSet(buffer, msgId);
+  return true;
+}
+
 QVariantList BufferSyncer::initLastSeenMsg() const {
   QVariantList list;
   QHash<BufferId, MsgId>::const_iterator iter = _lastSeenMsg.constBegin();
   while(iter != _lastSeenMsg.constEnd()) {
     list << QVariant::fromValue<BufferId>(iter.key())
 QVariantList BufferSyncer::initLastSeenMsg() const {
   QVariantList list;
   QHash<BufferId, MsgId>::const_iterator iter = _lastSeenMsg.constBegin();
   while(iter != _lastSeenMsg.constEnd()) {
     list << QVariant::fromValue<BufferId>(iter.key())
-        << QVariant::fromValue<MsgId>(iter.value());
-    iter++;
+         << QVariant::fromValue<MsgId>(iter.value());
+    ++iter;
   }
   return list;
 }
   }
   return list;
 }
@@ -67,13 +80,34 @@ void BufferSyncer::initSetLastSeenMsg(const QVariantList &list) {
   _lastSeenMsg.clear();
   Q_ASSERT(list.count() % 2 == 0);
   for(int i = 0; i < list.count(); i += 2) {
   _lastSeenMsg.clear();
   Q_ASSERT(list.count() % 2 == 0);
   for(int i = 0; i < list.count(); i += 2) {
-    setLastSeenMsg(list[i].value<BufferId>(), list[i+1].value<MsgId>());
+    setLastSeenMsg(list.at(i).value<BufferId>(), list.at(i+1).value<MsgId>());
+  }
+}
+
+QVariantList BufferSyncer::initMarkerLines() const {
+  QVariantList list;
+  QHash<BufferId, MsgId>::const_iterator iter = _markerLines.constBegin();
+  while(iter != _markerLines.constEnd()) {
+    list << QVariant::fromValue<BufferId>(iter.key())
+         << QVariant::fromValue<MsgId>(iter.value());
+    ++iter;
+  }
+  return list;
+}
+
+void BufferSyncer::initSetMarkerLines(const QVariantList &list) {
+  _markerLines.clear();
+  Q_ASSERT(list.count() % 2 == 0);
+  for(int i = 0; i < list.count(); i += 2) {
+    setMarkerLine(list.at(i).value<BufferId>(), list.at(i+1).value<MsgId>());
   }
 }
 
 void BufferSyncer::removeBuffer(BufferId buffer) {
   if(_lastSeenMsg.contains(buffer))
     _lastSeenMsg.remove(buffer);
   }
 }
 
 void BufferSyncer::removeBuffer(BufferId buffer) {
   if(_lastSeenMsg.contains(buffer))
     _lastSeenMsg.remove(buffer);
+  if(_markerLines.contains(buffer))
+    _markerLines.remove(buffer);
   SYNC(ARG(buffer))
   emit bufferRemoved(buffer);
 }
   SYNC(ARG(buffer))
   emit bufferRemoved(buffer);
 }
@@ -81,6 +115,8 @@ void BufferSyncer::removeBuffer(BufferId buffer) {
 void BufferSyncer::mergeBuffersPermanently(BufferId buffer1, BufferId buffer2) {
   if(_lastSeenMsg.contains(buffer2))
     _lastSeenMsg.remove(buffer2);
 void BufferSyncer::mergeBuffersPermanently(BufferId buffer1, BufferId buffer2) {
   if(_lastSeenMsg.contains(buffer2))
     _lastSeenMsg.remove(buffer2);
+  if(_markerLines.contains(buffer2))
+    _markerLines.remove(buffer2);
   SYNC(ARG(buffer1), ARG(buffer2))
   emit buffersPermanentlyMerged(buffer1, buffer2);
 }
   SYNC(ARG(buffer1), ARG(buffer2))
   emit buffersPermanentlyMerged(buffer1, buffer2);
 }
index 4893189..5519828 100644 (file)
@@ -30,17 +30,22 @@ class BufferSyncer : public SyncableObject {
 
 public:
   explicit BufferSyncer(QObject *parent);
 
 public:
   explicit BufferSyncer(QObject *parent);
-  explicit BufferSyncer(const QHash<BufferId, MsgId> &lastSeenMsg, QObject *parent);
+  explicit BufferSyncer(const QHash<BufferId, MsgId> &lastSeenMsg, const QHash<BufferId, MsgId> &markerLines, QObject *parent);
 
   inline virtual const QMetaObject *syncMetaObject() const { return &staticMetaObject; }
 
   MsgId lastSeenMsg(BufferId buffer) const;
 
   inline virtual const QMetaObject *syncMetaObject() const { return &staticMetaObject; }
 
   MsgId lastSeenMsg(BufferId buffer) const;
+  MsgId markerLine(BufferId buffer) const;
 
 public slots:
   QVariantList initLastSeenMsg() const;
   void initSetLastSeenMsg(const QVariantList &);
 
 
 public slots:
   QVariantList initLastSeenMsg() const;
   void initSetLastSeenMsg(const QVariantList &);
 
+  QVariantList initMarkerLines() const;
+  void initSetMarkerLines(const QVariantList &);
+
   virtual inline void requestSetLastSeenMsg(BufferId buffer, const MsgId &msgId) { REQUEST(ARG(buffer), ARG(msgId)) }
   virtual inline void requestSetLastSeenMsg(BufferId buffer, const MsgId &msgId) { REQUEST(ARG(buffer), ARG(msgId)) }
+  virtual inline void requestSetMarkerLine(BufferId buffer, const MsgId &msgId) { REQUEST(ARG(buffer), ARG(msgId)) }
 
   virtual inline void requestRemoveBuffer(BufferId buffer) { REQUEST(ARG(buffer)) }
   virtual void removeBuffer(BufferId buffer);
 
   virtual inline void requestRemoveBuffer(BufferId buffer) { REQUEST(ARG(buffer)) }
   virtual void removeBuffer(BufferId buffer);
@@ -55,16 +60,23 @@ public slots:
 
 signals:
   void lastSeenMsgSet(BufferId buffer, const MsgId &msgId);
 
 signals:
   void lastSeenMsgSet(BufferId buffer, const MsgId &msgId);
+  void markerLineSet(BufferId buffer, const MsgId &msgId);
   void bufferRemoved(BufferId buffer);
   void bufferRenamed(BufferId buffer, QString newName);
   void buffersPermanentlyMerged(BufferId buffer1, BufferId buffer2);
 
 protected slots:
   bool setLastSeenMsg(BufferId buffer, const MsgId &msgId);
   void bufferRemoved(BufferId buffer);
   void bufferRenamed(BufferId buffer, QString newName);
   void buffersPermanentlyMerged(BufferId buffer1, BufferId buffer2);
 
 protected slots:
   bool setLastSeenMsg(BufferId buffer, const MsgId &msgId);
-  QList<BufferId> bufferIds() const { return _lastSeenMsg.keys(); }
+  bool setMarkerLine(BufferId buffer, const MsgId &msgId);
+
+protected:
+  inline QList<BufferId> lastSeenBufferIds() const { return _lastSeenMsg.keys(); }
+  inline QList<BufferId> markerLineBufferIds() const { return _markerLines.keys(); }
+  inline QHash<BufferId, MsgId> markerLines() const { return _markerLines; }
 
 private:
   QHash<BufferId, MsgId> _lastSeenMsg;
 
 private:
   QHash<BufferId, MsgId> _lastSeenMsg;
+  QHash<BufferId, MsgId> _markerLines;
 };
 
 #endif
 };
 
 #endif
index 37ff255..55c28b2 100644 (file)
@@ -32,7 +32,7 @@ public:
 
 INIT_SYNCABLE_OBJECT(CoreBufferSyncer)
 CoreBufferSyncer::CoreBufferSyncer(CoreSession *parent)
 
 INIT_SYNCABLE_OBJECT(CoreBufferSyncer)
 CoreBufferSyncer::CoreBufferSyncer(CoreSession *parent)
-  : BufferSyncer(Core::bufferLastSeenMsgIds(parent->user()), parent),
+  : BufferSyncer(Core::bufferLastSeenMsgIds(parent->user()), Core::bufferMarkerLineMsgIds(parent->user()), parent),
     _coreSession(parent),
     _purgeBuffers(false)
 {
     _coreSession(parent),
     _purgeBuffers(false)
 {
@@ -40,18 +40,31 @@ CoreBufferSyncer::CoreBufferSyncer(CoreSession *parent)
 
 void CoreBufferSyncer::requestSetLastSeenMsg(BufferId buffer, const MsgId &msgId) {
   if(setLastSeenMsg(buffer, msgId))
 
 void CoreBufferSyncer::requestSetLastSeenMsg(BufferId buffer, const MsgId &msgId) {
   if(setLastSeenMsg(buffer, msgId))
-    dirtyBuffers << buffer;
+    dirtyLastSeenBuffers << buffer;
+}
+
+void CoreBufferSyncer::requestSetMarkerLine(BufferId buffer, const MsgId &msgId) {
+  if(setMarkerLine(buffer, msgId))
+    dirtyMarkerLineBuffers << buffer;
 }
 
 void CoreBufferSyncer::storeDirtyIds() {
   UserId userId = _coreSession->user();
   MsgId msgId;
 }
 
 void CoreBufferSyncer::storeDirtyIds() {
   UserId userId = _coreSession->user();
   MsgId msgId;
-  foreach(BufferId bufferId, dirtyBuffers) {
+  foreach(BufferId bufferId, dirtyLastSeenBuffers) {
     msgId = lastSeenMsg(bufferId);
     if(msgId.isValid())
       Core::setBufferLastSeenMsg(userId, bufferId, msgId);
   }
     msgId = lastSeenMsg(bufferId);
     if(msgId.isValid())
       Core::setBufferLastSeenMsg(userId, bufferId, msgId);
   }
-  dirtyBuffers.clear();
+
+  foreach(BufferId bufferId, dirtyMarkerLineBuffers) {
+    msgId = markerLine(bufferId);
+    if(msgId.isValid())
+      Core::setBufferMarkerLineMsg(userId, bufferId, msgId);
+  }
+
+  dirtyLastSeenBuffers.clear();
+  dirtyMarkerLineBuffers.clear();
 }
 
 void CoreBufferSyncer::removeBuffer(BufferId bufferId) {
 }
 
 void CoreBufferSyncer::removeBuffer(BufferId bufferId) {
@@ -140,7 +153,7 @@ void CoreBufferSyncer::purgeBufferIds() {
     actualBuffers << bufferInfo.bufferId();
   }
 
     actualBuffers << bufferInfo.bufferId();
   }
 
-  QList<BufferId> storedIds = bufferIds();
+  QSet<BufferId> storedIds = lastSeenBufferIds().toSet() + markerLineBufferIds().toSet();
   foreach(BufferId bufferId, storedIds) {
     if(!actualBuffers.contains(bufferId)) {
       BufferSyncer::removeBuffer(bufferId);
   foreach(BufferId bufferId, storedIds) {
     if(!actualBuffers.contains(bufferId)) {
       BufferSyncer::removeBuffer(bufferId);
index f567735..89694bf 100644 (file)
@@ -34,6 +34,7 @@ public:
 
 public slots:
   virtual void requestSetLastSeenMsg(BufferId buffer, const MsgId &msgId);
 
 public slots:
   virtual void requestSetLastSeenMsg(BufferId buffer, const MsgId &msgId);
+  virtual void requestSetMarkerLine(BufferId buffer, const MsgId &msgId);
 
   virtual inline void requestRemoveBuffer(BufferId buffer) { removeBuffer(buffer); }
   virtual void removeBuffer(BufferId bufferId);
 
   virtual inline void requestRemoveBuffer(BufferId buffer) { removeBuffer(buffer); }
   virtual void removeBuffer(BufferId bufferId);
@@ -55,7 +56,8 @@ private:
   CoreSession *_coreSession;
   bool _purgeBuffers;
 
   CoreSession *_coreSession;
   bool _purgeBuffers;
 
-  QSet<BufferId> dirtyBuffers;
+  QSet<BufferId> dirtyLastSeenBuffers;
+  QSet<BufferId> dirtyMarkerLineBuffers;
 
   void purgeBufferIds();
 };
 
   void purgeBufferIds();
 };
index c40fd34..6add446 100644 (file)
@@ -31,6 +31,7 @@
 #include "buffermodel.h"
 #include "bufferview.h"
 #include "chatitem.h"
 #include "buffermodel.h"
 #include "bufferview.h"
 #include "chatitem.h"
+#include "chatline.h"
 #include "chatlinemodel.h"
 #include "contextmenuactionprovider.h"
 #include "iconloader.h"
 #include "chatlinemodel.h"
 #include "contextmenuactionprovider.h"
 #include "iconloader.h"
@@ -49,6 +50,14 @@ ChatItem::ChatItem(const qreal &width, const qreal &height, const QPointF &pos,
   setPos(pos);
 }
 
   setPos(pos);
 }
 
+const QAbstractItemModel *ChatItem::model() const {
+  return static_cast<ChatLine *>(parentItem())->model();
+}
+
+int ChatItem::row() const {
+  return static_cast<ChatLine *>(parentItem())->row();
+}
+
 QVariant ChatItem::data(int role) const {
   QModelIndex index = model()->index(row(), column());
   if(!index.isValid()) {
 QVariant ChatItem::data(int role) const {
   QModelIndex index = model()->index(row(), column());
   if(!index.isValid()) {
index 3d5ad2f..36fb1c1 100644 (file)
@@ -38,8 +38,8 @@ protected:
   ChatItem(const qreal &width, const qreal &height, const QPointF &pos, QGraphicsItem *parent);
 
 public:
   ChatItem(const qreal &width, const qreal &height, const QPointF &pos, QGraphicsItem *parent);
 
 public:
-  inline const QAbstractItemModel *model() const;
-  inline int row() const;
+  const QAbstractItemModel *model() const;
+  int row() const;
   virtual ChatLineModel::ColumnType column() const = 0;
   inline ChatScene *chatScene() const { return qobject_cast<ChatScene *>(scene()); }
 
   virtual ChatLineModel::ColumnType column() const = 0;
   inline ChatScene *chatScene() const { return qobject_cast<ChatScene *>(scene()); }
 
@@ -268,9 +268,4 @@ private:
 
 /*************************************************************************************************/
 
 
 /*************************************************************************************************/
 
-// Avoid circular include deps
-#include "chatline.h"
-const QAbstractItemModel *ChatItem::model() const { return static_cast<ChatLine *>(parentItem())->model(); }
-int ChatItem::row() const { return static_cast<ChatLine *>(parentItem())->row(); }
-
 #endif
 #endif
index c1c98da..38e78c6 100644 (file)
@@ -184,7 +184,7 @@ void ChatLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
     // don't show the marker if we wrote that new line
     if(!(flags & Message::Self)) {
       BufferId bufferId = BufferId(chatScene()->idString().toInt());
     // don't show the marker if we wrote that new line
     if(!(flags & Message::Self)) {
       BufferId bufferId = BufferId(chatScene()->idString().toInt());
-      MsgId lastSeenMsgId = Client::networkModel()->lastSeenMarkerMsgId(bufferId);
+      MsgId lastSeenMsgId = Client::networkModel()->markerLineMsgId(bufferId);
       if(lastSeenMsgId < myMsgId && lastSeenMsgId >= prevMsgId) {
         QLinearGradient gradient(0, 0, 0, contentsItem().fontMetrics()->lineSpacing());
         gradient.setColorAt(0, QtUi::style()->brush(UiStyle::MarkerLine).color()); // FIXME: Use full (gradient?) brush instead of just the color
       if(lastSeenMsgId < myMsgId && lastSeenMsgId >= prevMsgId) {
         QLinearGradient gradient(0, 0, 0, contentsItem().fontMetrics()->lineSpacing());
         gradient.setColorAt(0, QtUi::style()->brush(UiStyle::MarkerLine).color()); // FIXME: Use full (gradient?) brush instead of just the color
index c732486..add7478 100644 (file)
@@ -24,6 +24,7 @@
 #include <QPainter>
 
 #include "chatitem.h"
 #include <QPainter>
 
 #include "chatitem.h"
+#include "chatline.h"
 #include "chatlinemodel.h"
 #include "chatscene.h"
 #include "messagemodel.h"
 #include "chatlinemodel.h"
 #include "chatscene.h"
 #include "messagemodel.h"
index 7be93f0..8fa4351 100644 (file)
@@ -79,7 +79,10 @@ void AbstractBufferContainer::currentChanged(const QModelIndex &current, const Q
 void AbstractBufferContainer::setCurrentBuffer(BufferId bufferId) {
   BufferId prevBufferId = currentBuffer();
   if(prevBufferId.isValid() && _chatViews.contains(prevBufferId)) {
 void AbstractBufferContainer::setCurrentBuffer(BufferId bufferId) {
   BufferId prevBufferId = currentBuffer();
   if(prevBufferId.isValid() && _chatViews.contains(prevBufferId)) {
-    Client::setBufferLastSeenMsg(prevBufferId, _chatViews[prevBufferId]->lastMsgId());
+    MsgId msgId = _chatViews.value(prevBufferId)->lastMsgId();
+    Client::setBufferLastSeenMsg(prevBufferId, msgId);
+    if(autoSetMarkerLine())
+      Client::setBufferMarkerLine(prevBufferId, msgId);
   }
 
   if(!bufferId.isValid()) {
   }
 
   if(!bufferId.isValid()) {
@@ -94,10 +97,7 @@ void AbstractBufferContainer::setCurrentBuffer(BufferId bufferId) {
   _currentBuffer = bufferId;
   showChatView(bufferId);
   Client::networkModel()->clearBufferActivity(bufferId);
   _currentBuffer = bufferId;
   showChatView(bufferId);
   Client::networkModel()->clearBufferActivity(bufferId);
+  Client::setBufferLastSeenMsg(bufferId, _chatViews[bufferId]->lastMsgId());
   Client::backlogManager()->checkForBacklog(bufferId);
   setFocus();
   Client::backlogManager()->checkForBacklog(bufferId);
   setFocus();
-
-  if(bufferId.isValid() && _chatViews.contains(bufferId)) {
-    Client::setBufferLastSeenMsg(bufferId, _chatViews[bufferId]->lastMsgId());
-  }
 }
 }
index bf58333..84ab280 100644 (file)
@@ -52,6 +52,8 @@ protected:
    */
   virtual void removeChatView(BufferId) = 0;
 
    */
   virtual void removeChatView(BufferId) = 0;
 
+  virtual inline bool autoSetMarkerLine() const { return true; }
+
 protected slots:
   virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous);
   virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
 protected slots:
   virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous);
   virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);