chatdialog: Fix issue of creating QObjects in different thread.

Change-Id: I2f0dc2006cc330cd9d4fc5973eb475d841103b59
diff --git a/src/chatdialog.cpp b/src/chatdialog.cpp
index e43aa78..6603183 100644
--- a/src/chatdialog.cpp
+++ b/src/chatdialog.cpp
@@ -77,7 +77,7 @@
   m_localChatPrefix.append("chronos").append(m_chatroomPrefix.get(-1)).append(randString.toStdString());
 
   m_session = static_cast<uint64_t>(time::now());
-  m_scene = new DigestTreeScene(this);
+  m_scene = new DigestTreeScene(m_ioService, this);
 
   initializeSetting();
   updateLabels();
@@ -122,6 +122,19 @@
           this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
   connect(m_scene, SIGNAL(rosterChanged(QStringList)), 
           this, SLOT(updateRosterList(QStringList)));
+  connect(this, SIGNAL(triggerHello()),
+          this, SLOT(sendHello()));
+  connect(this, SIGNAL(triggerJoin()),
+          this, SLOT(sendJoin()));
+  connect(this, SIGNAL(triggerLeave()),
+          this, SLOT(sendLeave()));
+  connect(this, SIGNAL(triggerReplot()),
+          this, SLOT(replot()));
+  connect(this, SIGNAL(triggerEnableTreeDisplay()),
+          this, SLOT(enableTreeDisplay()));
+  connect(this, SIGNAL(triggerReap()),
+          this, SLOT(reap()));
+  
 
 
   initializeSync();
@@ -180,14 +193,14 @@
   
   usleep(100000);
 
-  m_scheduler.scheduleEvent(time::milliseconds(600), bind(&ChatDialog::sendJoin, this));
+  m_scheduler.scheduleEvent(time::milliseconds(600), bind(&ChatDialog::sendJoinWrapper, this));
 
   if(static_cast<bool>(m_replotEventId))
     m_scheduler.cancelEvent(m_replotEventId);
   m_replotEventId = m_scheduler.schedulePeriodicEvent(time::seconds(0), time::milliseconds(FRESHNESS * 1000),
-                                                      bind(&ChatDialog::replot, this));
+                                                      bind(&ChatDialog::replotWrapper, this));
   disableTreeDisplay();
-  m_scheduler.scheduleEvent(time::milliseconds(2200), bind(&ChatDialog::enableTreeDisplay, this));
+  m_scheduler.scheduleEvent(time::milliseconds(2200), bind(&ChatDialog::enableTreeDisplayWrapper, this));
 }
 
 void
@@ -386,6 +399,10 @@
 }
 
 void
+ChatDialog::enableTreeDisplayWrapper()
+{ emit triggerEnableTreeDisplay(); }
+
+void
 ChatDialog::processTreeUpdateWrapper(const vector<Sync::MissingDataInfo>& v, Sync::SyncSocket *sock)
 {
   emit treeUpdated(v);
@@ -520,10 +537,14 @@
   boost::random::random_device rng;
   boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
   m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
-  m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval), bind(&ChatDialog::sendHello, this));
+  m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval), bind(&ChatDialog::sendHelloWrapper, this));
 }
 
 void
+ChatDialog::sendJoinWrapper()
+{ emit triggerJoin(); }
+
+void
 ChatDialog::sendHello()
 {
   int64_t now = time::now();
@@ -536,16 +557,20 @@
     boost::random::random_device rng;
     boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
     m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
-    m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval), bind(&ChatDialog::sendHello, this));
+    m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval), bind(&ChatDialog::sendHelloWrapper, this));
   }
   else
   {
     m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval - elapsed * 1000), 
-                              bind(&ChatDialog::sendHello, this));
+                              bind(&ChatDialog::sendHelloWrapper, this));
   }
 }
 
 void
+ChatDialog::sendHelloWrapper()
+{ emit triggerHello(); }
+
+void
 ChatDialog::sendLeave()
 {
   SyncDemo::ChatMessage msg;
@@ -559,6 +584,10 @@
 }
 
 void
+ChatDialog::sendLeaveWrapper()
+{ emit triggerLeave(); }
+
+void
 ChatDialog::replot()
 {
   boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
@@ -567,6 +596,10 @@
 }
 
 void
+ChatDialog::replotWrapper()
+{ emit triggerReplot(); }
+
+void
 ChatDialog::summonReaper()
 {
   Sync::SyncLogic &logic = m_sock->getLogic ();
@@ -617,11 +650,15 @@
     m_zombieIndex++;
     // reap again in 10 seconds
     m_scheduler.scheduleEvent(time::milliseconds(10000), 
-                              bind(&ChatDialog::reap, this));
+                              bind(&ChatDialog::reapWrapper, this));
   }
 }
 
 void
+ChatDialog::reapWrapper()
+{ emit triggerReap(); }
+
+void
 ChatDialog::updateRosterList(QStringList staleUserList)
 {
   boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
@@ -702,13 +739,13 @@
                                     bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
                                     bind(&ChatDialog::processRemoveWrapper, this, _1));
       usleep(100000);
-      m_scheduler.scheduleEvent(time::milliseconds(600), bind(&ChatDialog::sendJoin, this));
+      m_scheduler.scheduleEvent(time::milliseconds(600), bind(&ChatDialog::sendJoinWrapper, this));
       if(static_cast<bool>(m_replotEventId))
         m_scheduler.cancelEvent(m_replotEventId);
       m_replotEventId = m_scheduler.schedulePeriodicEvent(time::seconds(0), time::milliseconds(FRESHNESS * 1000),
-                                                          bind(&ChatDialog::replot, this));
+                                                          bind(&ChatDialog::replotWrapper, this));
       disableTreeDisplay();
-      m_scheduler.scheduleEvent(time::milliseconds(2200), bind(&ChatDialog::enableTreeDisplay, this));
+      m_scheduler.scheduleEvent(time::milliseconds(2200), bind(&ChatDialog::enableTreeDisplayWrapper, this));
     }catch(Face::Error& e){
       emit noNdnConnection(QString::fromStdString("Cannot conect to ndnd!\n Have you started your ndnd?"));
     }