gui: adjust display of sync tree

Change-Id: Ie6afc35aae2a6414d3660cbb8151c625c43c0f69
diff --git a/src/chat-dialog-backend.cpp b/src/chat-dialog-backend.cpp
index 216f465..6cd24ad 100644
--- a/src/chat-dialog-backend.cpp
+++ b/src/chat-dialog-backend.cpp
@@ -222,11 +222,6 @@
                         2);
     }
 
-    // prepare notification to frontend
-    NodeInfo nodeInfo;
-    nodeInfo.sessionPrefix = QString::fromStdString(updates[i].session.toUri());
-    nodeInfo.seqNo = updates[i].high;
-    nodeInfos.push_back(nodeInfo);
   }
 
   // reflect the changes on GUI
@@ -280,24 +275,7 @@
       BOOST_ASSERT(false);
     }
 
-    // If we haven't got any message from this session yet.
-    if (m_roster[remoteSessionPrefix].hasNick == false) {
-      m_roster[remoteSessionPrefix].userNick = msg.from();
-      m_roster[remoteSessionPrefix].hasNick = true;
-      emit sessionAdded(QString::fromStdString(remoteSessionPrefix.toUri()),
-                        QString::fromStdString(msg.from()),
-                        msg.timestamp());
-
-      emit addInRoster(remoteSessionPrefix.getPrefix(IDENTITY_OFFSET),
-                       Name::Component(m_chatroomName));
-    }
-
-    // If we get a new nick for an existing session, update it.
-    if (m_roster[remoteSessionPrefix].userNick != msg.from()) {
-      m_roster[remoteSessionPrefix].userNick = msg.from();
-      emit nickUpdated(QString::fromStdString(remoteSessionPrefix.toUri()),
-                       QString::fromStdString(msg.from()));
-    }
+    uint64_t seqNo = data->getName().get(-1).toNumber();
 
     // If a timeout event has been scheduled, cancel it.
     if (static_cast<bool>(it->second.timeoutEventId))
@@ -322,7 +300,27 @@
     }
 
     // Notify frontend to plot notification on DigestTree.
-    emit messageReceived(QString::fromStdString(remoteSessionPrefix.toUri()));
+
+    // If we haven't got any message from this session yet.
+    if (m_roster[remoteSessionPrefix].hasNick == false) {
+      m_roster[remoteSessionPrefix].userNick = msg.from();
+      m_roster[remoteSessionPrefix].hasNick = true;
+
+      emit messageReceived(QString::fromStdString(remoteSessionPrefix.toUri()),
+                           QString::fromStdString(msg.from()),
+                           seqNo,
+                           msg.timestamp(),
+                           true);
+
+      emit addInRoster(remoteSessionPrefix.getPrefix(IDENTITY_OFFSET),
+                       Name::Component(m_chatroomName));
+    }
+    else
+      emit messageReceived(QString::fromStdString(remoteSessionPrefix.toUri()),
+                           QString::fromStdString(msg.from()),
+                           seqNo,
+                           msg.timestamp(),
+                           false);
   }
 }
 
@@ -369,6 +367,12 @@
 
   emit syncTreeUpdated(nodeInfos,
                        QString::fromStdString(getHexEncodedDigest(m_sock->getRootDigest())));
+
+  emit messageReceived(QString::fromStdString(sessionName.toUri()),
+                       QString::fromStdString(msg.from()),
+                       nextSequence,
+                       msg.timestamp(),
+                       msg.type() == SyncDemo::ChatMessage::JOIN);
 }
 
 void
@@ -382,11 +386,6 @@
 
   m_helloEventId = m_scheduler->scheduleEvent(HELLO_INTERVAL,
                                               bind(&ChatDialogBackend::sendHello, this));
-
-  Name sessionName = m_sock->getLogic().getSessionName();
-  emit sessionAdded(QString::fromStdString(sessionName.toUri()),
-                    QString::fromStdString(msg.from()),
-                    msg.timestamp());
 }
 
 void
diff --git a/src/chat-dialog-backend.hpp b/src/chat-dialog-backend.hpp
index 26f588b..f0fead3 100644
--- a/src/chat-dialog-backend.hpp
+++ b/src/chat-dialog-backend.hpp
@@ -111,16 +111,11 @@
   chatMessageReceived(QString nick, QString text, time_t timestamp);
 
   void
-  sessionAdded(QString sessionPrefix, QString nick, time_t timestamp);
-
-  void
   sessionRemoved(QString sessionPrefix, QString nick, time_t timestamp);
 
   void
-  nickUpdated(QString sessionPrefix, QString nick);
-
-  void
-  messageReceived(QString sessionPrefix);
+  messageReceived(QString sessionPrefix, QString nick, uint64_t seqNo, time_t timestamp,
+                  bool addSession);
 
   void
   chatPrefixChanged(ndn::Name newChatPrefix);
diff --git a/src/chat-dialog.cpp b/src/chat-dialog.cpp
index 3f6070e..1167799 100644
--- a/src/chat-dialog.cpp
+++ b/src/chat-dialog.cpp
@@ -20,6 +20,7 @@
 Q_DECLARE_METATYPE(ndn::Name)
 Q_DECLARE_METATYPE(time_t)
 Q_DECLARE_METATYPE(std::vector<chronochat::NodeInfo>)
+Q_DECLARE_METATYPE(uint64_t)
 
 namespace chronochat {
 
@@ -46,6 +47,7 @@
   qRegisterMetaType<ndn::Name>("ndn::Name");
   qRegisterMetaType<time_t>("time_t");
   qRegisterMetaType<std::vector<chronochat::NodeInfo> >("std::vector<chronochat::NodeInfo>");
+  qRegisterMetaType<uint64_t>("uint64_t");
 
   m_scene = new DigestTreeScene(this);
   m_trustScene = new TrustTreeScene(this);
@@ -78,6 +80,8 @@
   roster << "- " + m_nick;
   m_rosterModel->setStringList(roster);
 
+  ui->syncTreeButton->setText("Hide ChronoSync Tree");
+
   // When backend receives a sync update, notify frontend to update sync tree
   connect(&m_backend, SIGNAL(syncTreeUpdated(std::vector<chronochat::NodeInfo>, QString)),
           this,       SLOT(updateSyncTree(std::vector<chronochat::NodeInfo>, QString)));
@@ -86,21 +90,13 @@
   connect(&m_backend, SIGNAL(chatMessageReceived(QString, QString, time_t)),
           this,       SLOT(receiveChatMessage(QString, QString, time_t)));
 
-  // When backend detects a new session, notify frontend to print the message.
-  connect(&m_backend, SIGNAL(sessionAdded(QString, QString, time_t)),
-          this,       SLOT(addSession(QString, QString, time_t)));
-
   // When backend detects a deleted session, notify frontend to print the message.
   connect(&m_backend, SIGNAL(sessionRemoved(QString, QString, time_t)),
           this,       SLOT(removeSession(QString, QString, time_t)));
 
-  // When backend detects nick changed, notify frontend to print the new nick
-  connect(&m_backend, SIGNAL(nickUpdated(QString, QString)),
-          this,       SLOT(updateNick(QString, QString)));
-
   // When backend receives a new message, notify frontend to print notification
-  connect(&m_backend, SIGNAL(messageReceived(QString)),
-          this,       SLOT(receiveMessage(QString)));
+  connect(&m_backend, SIGNAL(messageReceived(QString, QString, uint64_t, time_t, bool)),
+          this,       SLOT(receiveMessage(QString, QString, uint64_t, time_t, bool)));
 
   // When backend updates prefix, notify frontend to update labels.
   connect(&m_backend, SIGNAL(chatPrefixChanged(ndn::Name)),
@@ -337,15 +333,6 @@
 }
 
 void
-ChatDialog::addSession(QString sessionPrefix, QString nick, time_t timestamp)
-{
-  appendControlMessage(nick, "enters room", timestamp);
-  m_scene->updateNick(sessionPrefix, nick);
-  m_rosterModel->setStringList(m_scene->getRosterList());
-  fitView();
-}
-
-void
 ChatDialog::removeSession(QString sessionPrefix, QString nick, time_t timestamp)
 {
   appendControlMessage(nick, "leaves room", timestamp);
@@ -355,16 +342,15 @@
 }
 
 void
-ChatDialog::updateNick(QString sessionPrefix, QString nick)
+ChatDialog::receiveMessage(QString sessionPrefix, QString nick, uint64_t seqNo, time_t timestamp,
+                           bool addSession)
 {
-  m_scene->updateNick(sessionPrefix, nick);
-  m_rosterModel->setStringList(m_scene->getRosterList());
-}
-
-void
-ChatDialog::receiveMessage(QString sessionPrefix)
-{
+  m_scene->updateNode(sessionPrefix, nick, seqNo);
   m_scene->messageReceived(sessionPrefix);
+  if (addSession) {
+    appendControlMessage(nick, "enters room", timestamp);
+    m_rosterModel->setStringList(m_scene->getRosterList());
+  }
 }
 
 void
diff --git a/src/chat-dialog.hpp b/src/chat-dialog.hpp
index 919c511..6510297 100644
--- a/src/chat-dialog.hpp
+++ b/src/chat-dialog.hpp
@@ -132,16 +132,11 @@
   receiveChatMessage(QString nick, QString text, time_t timestamp);
 
   void
-  addSession(QString sessionPrefix, QString nick, time_t timestamp);
-
-  void
   removeSession(QString sessionPrefix, QString nick, time_t timestamp);
 
   void
-  updateNick(QString sessionPrefix, QString nick);
-
-  void
-  receiveMessage(QString sessionPrefix);
+  receiveMessage(QString sessionPrefix, QString nick, uint64_t seqNo, time_t timestamp,
+                 bool addSession);
 
   void
   updateLabels(ndn::Name newChatPrefix);
diff --git a/src/digest-tree-scene.cpp b/src/digest-tree-scene.cpp
index a38658d..17bc67a 100644
--- a/src/digest-tree-scene.cpp
+++ b/src/digest-tree-scene.cpp
@@ -39,46 +39,33 @@
                                    const QString& digest)
 {
   m_rootDigest = digest;
+}
 
-  bool rePlot = false;
-
-  // Update roster info
-  for (size_t i = 0; i < nodeInfos.size(); i++) {
-    Roster_iterator it = m_roster.find(nodeInfos[i].sessionPrefix);
-    if (it == m_roster.end()) {
-      rePlot = true;
-
-      DisplayUserPtr p(new DisplayUser());
-      p->setPrefix(nodeInfos[i].sessionPrefix);
-      p->setSeq(nodeInfos[i].seqNo);
-      m_roster.insert(p->getPrefix(), p);
-    }
-    else {
-      it.value()->setSeq(nodeInfos[i].seqNo);
-    }
-  }
-
-  if (rePlot)
-    // If new nodes exist, we need to re-arrange node
+void
+DigestTreeScene::updateNode(QString sessionPrefix, QString nick, uint64_t seqNo)
+{
+  Roster_iterator it = m_roster.find(sessionPrefix);
+  if (it == m_roster.end()) {
+    DisplayUserPtr p(new DisplayUser());
+    p->setPrefix(sessionPrefix);
+    p->setSeq(seqNo);
+    m_roster.insert(p->getPrefix(), p);
     plot(m_rootDigest);
-  else {
-    // No new node, update seqNo & digest
-    for (size_t i = 0; i < nodeInfos.size(); i++) {
-      Roster_iterator it = m_roster.find(nodeInfos[i].sessionPrefix);
-      if (it != m_roster.end()) {
-        DisplayUserPtr p = it.value();
-        QGraphicsTextItem *item = p->getSeqTextItem();
-        QGraphicsRectItem *rectItem = p->getInnerRectItem();
-        std::string s = boost::lexical_cast<std::string>(p->getSeqNo());
-        item->setPlainText(s.c_str());
-        QRectF textBR = item->boundingRect();
-        QRectF rectBR = rectItem->boundingRect();
-        item->setPos(rectBR.x() + (rectBR.width() - textBR.width())/2,
-                     rectBR.y() + (rectBR.height() - textBR.height())/2);
-      }
-    }
-    m_displayRootDigest->setPlainText(digest);
   }
+  else {
+    it.value()->setSeq(seqNo);
+    DisplayUserPtr p = it.value();
+    QGraphicsTextItem *item = p->getSeqTextItem();
+    QGraphicsRectItem *rectItem = p->getInnerRectItem();
+    std::string s = boost::lexical_cast<std::string>(p->getSeqNo());
+    item->setPlainText(s.c_str());
+    QRectF textBR = item->boundingRect();
+    QRectF rectBR = rectItem->boundingRect();
+    item->setPos(rectBR.x() + (rectBR.width() - textBR.width())/2,
+                 rectBR.y() + (rectBR.height() - textBR.height())/2);
+  }
+  m_displayRootDigest->setPlainText(m_rootDigest);
+  updateNick(sessionPrefix, nick);
 }
 
 void
diff --git a/src/digest-tree-scene.hpp b/src/digest-tree-scene.hpp
index 3720d4b..0e69528 100644
--- a/src/digest-tree-scene.hpp
+++ b/src/digest-tree-scene.hpp
@@ -51,6 +51,9 @@
                     const QString& digest);
 
   void
+  updateNode(QString sessionPrefix, QString nick, uint64_t seqNo);
+
+  void
   updateNick(QString sessionPrefix, QString nick);
 
   void