You've all been waiting for it: day change messages!
authorMarcus Eggenberger <egs@quassel-irc.org>
Tue, 30 Sep 2008 12:05:15 +0000 (14:05 +0200)
committerMarcus Eggenberger <egs@quassel-irc.org>
Tue, 30 Sep 2008 12:05:15 +0000 (14:05 +0200)
Known issues:
 - aren't very pretty yet
 - as there is one day change message that is displayed in all buffers
   this results in a bit of a day-change-message spam if you reach the top
   of a buffer. this is intended to be filtered out in the future.

src/client/messagemodel.cpp
src/client/messagemodel.h
src/qtui/chatscene.cpp

index 5269d0a..7633f82 100644 (file)
@@ -32,6 +32,15 @@ public:
 MessageModel::MessageModel(QObject *parent)
   : QAbstractItemModel(parent)
 {
+  QDateTime now = QDateTime::currentDateTime();
+  now.setTimeSpec(Qt::UTC);
+  _nextDayChange.setTimeSpec(Qt::UTC);
+  _nextDayChange.setTime_t(((now.toTime_t() / 86400) + 1) * 86400);
+  _nextDayChange.setTimeSpec(Qt::LocalTime);
+  qDebug() << _nextDayChange;
+  _dayChangeTimer.setInterval(QDateTime::currentDateTime().secsTo(_nextDayChange) * 1000);
+  _dayChangeTimer.start();
+  connect(&_dayChangeTimer, SIGNAL(timeout()), this, SLOT(changeOfDay()));
 }
 
 QVariant MessageModel::data(const QModelIndex &index, int role) const {
@@ -79,22 +88,18 @@ void MessageModel::insertMessages(const QList<Message> &msglist) {
   if(msglist.isEmpty())
     return;
 
-//   if(_messageList.isEmpty()) {
-//     insertMessageGroup(msglist);
-//   } else {
-    int processedMsgs = insertMessagesGracefully(msglist);
-    int remainingMsgs = msglist.count() - processedMsgs;
-    if(remainingMsgs > 0) {
-      if(msglist.first().msgId() < msglist.last().msgId()) {
-       // in Order
-       _messageBuffer << msglist.mid(0, remainingMsgs);
-      } else {
-       _messageBuffer << msglist.mid(processedMsgs);
-      }
-      qSort(_messageBuffer);
-      QCoreApplication::postEvent(this, new ProcessBufferEvent());
+  int processedMsgs = insertMessagesGracefully(msglist);
+  int remainingMsgs = msglist.count() - processedMsgs;
+  if(remainingMsgs > 0) {
+    if(msglist.first().msgId() < msglist.last().msgId()) {
+      // in Order
+      _messageBuffer << msglist.mid(0, remainingMsgs);
+    } else {
+      _messageBuffer << msglist.mid(processedMsgs);
     }
-//   }
+    qSort(_messageBuffer);
+    QCoreApplication::postEvent(this, new ProcessBufferEvent());
+  }
 }
 
 void MessageModel::insertMessageGroup(const QList<Message> &msglist) {
@@ -110,11 +115,33 @@ void MessageModel::insertMessageGroup(const QList<Message> &msglist) {
       idx--;
     }
   }
-  beginInsertRows(QModelIndex(), idx, idx+msglist.count()-1);
+  Message dayChangeMsg;
+  bool needsDayChangeMsg = false;
+  if(idx < _messageList.count() && _messageList[idx]->msgType() != Message::DayChange) {
+    QDateTime nextTs = _messageList[idx]->timeStamp();
+    QDateTime prevTs = msglist.last().timestamp();
+    nextTs.setTimeSpec(Qt::UTC);
+    prevTs.setTimeSpec(Qt::UTC);
+    uint nextDay = nextTs.toTime_t() / 86400;
+    uint prevDay = prevTs.toTime_t() / 86400;
+    if(nextDay != prevDay) {
+      nextTs.setTime_t(nextDay * 86400);
+      nextTs.setTimeSpec(Qt::LocalTime);
+      dayChangeMsg = Message::ChangeOfDay(nextTs);
+      dayChangeMsg.setMsgId(msglist.last().msgId());
+      needsDayChangeMsg = true;
+    }
+  }
+  int start = idx;
+  int end = idx + msglist.count() - 1;
+  beginInsertRows(QModelIndex(), start, end);
   foreach(Message msg, msglist) {
     _messageList.insert(idx, createMessageModelItem(msg));
     idx++;
   }
+  if(needsDayChangeMsg) {
+    _messageList.insert(idx, createMessageModelItem(dayChangeMsg));
+  }
   endInsertRows();
 }
 
@@ -190,7 +217,20 @@ int MessageModel::insertMessagesGracefully(const QList<Message> &msglist) {
 
       if((*iter).msgId() != dupeId) {
        if(!grouplist.isEmpty()) {
-         qWarning() << "copy day change check";
+         QDateTime nextTs = grouplist.value(0).timestamp();
+         QDateTime prevTs = (*iter).timestamp();
+         nextTs.setTimeSpec(Qt::UTC);
+         prevTs.setTimeSpec(Qt::UTC);
+         uint nextDay = nextTs.toTime_t() / 86400;
+         uint prevDay = prevTs.toTime_t() / 86400;
+         if(nextDay != prevDay) {
+           nextTs.setTime_t(nextDay * 86400);
+           nextTs.setTimeSpec(Qt::LocalTime);
+           Message dayChangeMsg = Message::ChangeOfDay(nextTs);
+           dayChangeMsg.setMsgId((*iter).msgId());
+           grouplist.prepend(dayChangeMsg);
+           dupeCount--;
+         }
        }
        grouplist.prepend(*iter);
       } else {
@@ -252,6 +292,23 @@ int MessageModel::indexForId(MsgId id) {
   }
 }
 
+void MessageModel::changeOfDay() {
+  _dayChangeTimer.setInterval(86400000);
+  qDebug() << _nextDayChange;
+  if(!_messageList.isEmpty()) {
+    int idx = _messageList.count();
+    while(idx > 0 && _messageList[idx - 1]->timeStamp() > _nextDayChange) {
+      idx--;
+    }
+    beginInsertRows(QModelIndex(), idx, idx);
+    Message dayChangeMsg = Message::ChangeOfDay(_nextDayChange);
+    dayChangeMsg.setMsgId(_messageList[idx - 1]->msgId());
+    _messageList.insert(idx, createMessageModelItem(dayChangeMsg));
+    endInsertRows();
+  }
+  _nextDayChange = _nextDayChange.addSecs(86400);
+}
+
 /**********************************************************************************/
 
 MessageModelItem::MessageModelItem(const Message &msg) :
index a9ae901..5b756df 100644 (file)
@@ -72,6 +72,9 @@ protected:
   virtual MessageModelItem *createMessageModelItem(const Message &) = 0;
   virtual void customEvent(QEvent *event);
 
+private slots:
+  void changeOfDay();
+
 private:
   void insertMessageGroup(const QList<Message> &);
   int insertMessagesGracefully(const QList<Message> &); // inserts as many contiguous msgs as possible. returns numer of inserted msgs.
@@ -79,8 +82,13 @@ private:
 
   QList<MessageModelItem *> _messageList;
   QList<Message> _messageBuffer;
+  QTimer _dayChangeTimer;
+  QDateTime _nextDayChange;
 };
 
+// **************************************************
+//  MessageModelItem
+// **************************************************
 class MessageModelItem {
 public:
   //! Creates a MessageModelItem from a Message object.
index 10ef5d8..1bee955 100644 (file)
@@ -463,6 +463,9 @@ void ChatScene::requestBacklog() {
   int backlogSize = model()->rowCount();
   if(isSingleBufferScene() && backlogSize != 0 && _lastBacklogSize + REQUEST_COUNT <= backlogSize) {
     QModelIndex msgIdx = model()->index(0, 0);
+    while((Message::Type)(model()->data(msgIdx, ChatLineModel::TypeRole).toInt()) == Message::DayChange) {
+      msgIdx = msgIdx.sibling(msgIdx.row() + 1, 0);
+    }
     MsgId msgId = model()->data(msgIdx, ChatLineModel::MsgIdRole).value<MsgId>();
     BufferId bufferId = model()->data(msgIdx, ChatLineModel::BufferIdRole).value<BufferId>();
     _lastBacklogSize = backlogSize;