Fixing a bug in introducing others
diff --git a/src/chatdialog.cpp b/src/chatdialog.cpp
index f56ccc0..e0304a6 100644
--- a/src/chatdialog.cpp
+++ b/src/chatdialog.cpp
@@ -78,6 +78,9 @@
   m_rosterModel = new QStringListModel(this);
   ui->listView->setModel(m_rosterModel);
 
+  createActions();
+  createTrayIcon();
+
   m_timer = new QTimer(this);
 
   setWrapper(trial);
@@ -98,114 +101,33 @@
           this, SLOT(replot()));
   connect(m_scene, SIGNAL(replot()), 
           this, SLOT(replot()));
-  // TODO: TrayIcon
-  // connect(trayIcon, SIGNAL(messageClicked()), 
-  //         this, SLOT(showNormal()));
-  // connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), 
-  //         this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
+  connect(trayIcon, SIGNAL(messageClicked()), 
+          this, SLOT(showNormal()));
+  connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), 
+          this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
   connect(m_scene, SIGNAL(rosterChanged(QStringList)), 
           this, SLOT(updateRosterList(QStringList)));
 
-  // m_identityManager = ndn::Ptr<ndn::security::IdentityManager>::Create();
-  // // ndn::Ptr<ndn::security::EncryptionManager> encryptionManager = ndn::Ptr<ndn::security::EncryptionManager>(new ndn::security::BasicEncryptionManager(privateStorage, "/tmp/encryption.db"));
-
-  // ndn::Name certificateName = m_identityManager->getDefaultCertificateNameByIdentity(m_defaultIdentity);
-  // m_syncPolicyManager = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(m_defaultIdentity, certificateName, m_chatroomPrefix));
 
   initializeSync();
 }
 
-// ChatDialog::ChatDialog(const ndn::Name& chatroomPrefix,
-// 		       const ndn::Name& localPrefix,
-//                        const ndn::Name& defaultIdentity,
-//                        const ndn::security::IdentityCertificate& identityCertificate,
-// 		       QWidget *parent) 
-//     : QDialog(parent)
-//     , ui(new Ui::ChatDialog)
-//     , m_chatroomPrefix(chatroomPrefix)
-//     , m_localPrefix(localPrefix)
-//     , m_defaultIdentity(defaultIdentity)
-//     , m_invitationPolicyManager(ndn::Ptr<InvitationPolicyManager>(new InvitationPolicyManager(m_chatroomPrefix.get(-1).toUri())))
-
-//     , m_sock(NULL)
-//     , m_lastMsgTime(0)
-//     // , m_historyInitialized(false)
-//     , m_joined(false)
-// {
-//   qRegisterMetaType<std::vector<Sync::MissingDataInfo> >("std::vector<Sync::MissingDataInfo>");
-//   qRegisterMetaType<size_t>("size_t");
-
-//   ui->setupUi(this);
-
-//   m_localChatPrefix = m_localPrefix;
-//   m_localChatPrefix.append("FH").append(m_defaultIdentity);
-//   m_localChatPrefix.append("chronos").append(m_chatroomPrefix.get(-1));
-
-//   m_session = time(NULL);
-//   m_scene = new DigestTreeScene(this);
-
-//   initializeSetting();
-//   updateLabels();
-
-//   ui->treeViewer->setScene(m_scene);
-//   ui->treeViewer->hide();
-//   m_scene->plot("Empty");
-//   QRectF rect = m_scene->itemsBoundingRect();
-//   m_scene->setSceneRect(rect);
-
-//   m_rosterModel = new QStringListModel(this);
-//   ui->listView->setModel(m_rosterModel);
-
-//   m_timer = new QTimer(this);
-
-//   setWrapper();
-
-//   connect(ui->lineEdit, SIGNAL(returnPressed()), 
-//           this, SLOT(returnPressed()));
-//   connect(ui->treeButton, SIGNAL(pressed()), 
-//           this, SLOT(treeButtonPressed()));
-//   connect(this, SIGNAL(dataReceived(QString, const char *, size_t, bool, bool)), 
-//           this, SLOT(processData(QString, const char *, size_t, bool, bool)));
-//   connect(this, SIGNAL(treeUpdated(const std::vector<Sync::MissingDataInfo>)), 
-//           this, SLOT(processTreeUpdate(const std::vector<Sync::MissingDataInfo>)));
-//   connect(m_timer, SIGNAL(timeout()), 
-//           this, SLOT(replot()));
-//   connect(m_scene, SIGNAL(replot()), 
-//           this, SLOT(replot()));
-//   // TODO: TrayIcon
-//   // connect(trayIcon, SIGNAL(messageClicked()), 
-//   //         this, SLOT(showNormal()));
-//   // connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), 
-//   //         this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
-//   connect(m_scene, SIGNAL(rosterChanged(QStringList)), 
-//           this, SLOT(updateRosterList(QStringList)));
-
-//   // m_identityManager = ndn::Ptr<ndn::security::IdentityManager>::Create();
-//   // // ndn::Ptr<ndn::security::EncryptionManager> encryptionManager = ndn::Ptr<ndn::security::EncryptionManager>(new ndn::security::BasicEncryptionManager(privateStorage, "/tmp/encryption.db"));
-
-//   // ndn::Name certificateName = m_identityManager->getDefaultCertificateNameByIdentity(m_defaultIdentity);
-//   // m_syncPolicyManager = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(m_defaultIdentity, certificateName, m_chatroomPrefix));
-
-//   initializeSync();
-// }
 
 ChatDialog::~ChatDialog()
 {
-  _LOG_DEBUG("about to leave 4!");
   if(m_sock != NULL)
     {
       sendLeave();
       delete m_sock;
       m_sock = NULL;
     }
-  // m_handler->shutdown();
+  m_handler->shutdown();
 }
 
 void
 ChatDialog::setWrapper(bool trial)
 {
   m_identityManager = ndn::Ptr<ndn::security::IdentityManager>::Create();
-  // ndn::Ptr<ndn::security::EncryptionManager> encryptionManager = ndn::Ptr<ndn::security::EncryptionManager>(new ndn::security::BasicEncryptionManager(privateStorage, "/tmp/encryption.db"));
 
   ndn::Name certificateName = m_identityManager->getDefaultCertificateNameByIdentity(m_defaultIdentity);
   m_syncPolicyManager = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(m_defaultIdentity, certificateName, m_chatroomPrefix));
@@ -235,7 +157,6 @@
 void
 ChatDialog::initializeSetting()
 {
-  // TODO: nick name may be changed.
   m_user.setNick(QString::fromStdString(m_nick));
   m_user.setChatroom(QString::fromStdString(m_chatroomPrefix.get(-1).toUri()));
   m_user.setOriginPrefix(QString::fromStdString(m_localPrefix.toUri()));
@@ -288,7 +209,6 @@
   interestName.append(sigBits.buf(), sigBits.size());
   interestName.appendVersion();
 
-
   ndn::Ptr<ndn::Interest> interest = ndn::Ptr<ndn::Interest>(new ndn::Interest(interestName));
   ndn::Ptr<ndn::Closure> closure = ndn::Ptr<ndn::Closure>(new ndn::Closure(boost::bind(&ChatDialog::onInviteReplyVerified,
                                                                                        this,
@@ -319,14 +239,14 @@
 { m_syncPolicyManager->addChatDataRule(prefix, identityCertificate, isIntroducer); }
 
 void
-ChatDialog::publishIntroCert(ndn::Ptr<ndn::security::IdentityCertificate> dskCertificate, bool isIntroducer)
+ChatDialog::publishIntroCert(const ndn::security::IdentityCertificate& dskCertificate, bool isIntroducer)
 {
   SyncIntroCertificate syncIntroCertificate(m_chatroomPrefix,
-                                            dskCertificate->getPublicKeyName(),
+                                            dskCertificate.getPublicKeyName(),
                                             m_identityManager->getDefaultKeyNameForIdentity(m_defaultIdentity),
-                                            dskCertificate->getNotBefore(),
-                                            dskCertificate->getNotAfter(),
-                                            dskCertificate->getPublicKeyInfo(),
+                                            dskCertificate.getNotBefore(),
+                                            dskCertificate.getNotAfter(),
+                                            dskCertificate.getPublicKeyInfo(),
                                             (isIntroducer ? SyncIntroCertificate::INTRODUCER : SyncIntroCertificate::PRODUCER));
   ndn::Name certName = m_identityManager->getDefaultCertificateNameByIdentity(m_defaultIdentity);
   _LOG_DEBUG("publishIntroCert: " << syncIntroCertificate.getName());
@@ -349,7 +269,7 @@
   const ndn::Name & keyLocatorName = sha256sig->getKeyLocator().getKeyName();
   ndn::Ptr<ndn::security::IdentityCertificate> dskCertificate = m_invitationPolicyManager->getValidatedDskCertificate(keyLocatorName);
   m_syncPolicyManager->addChatDataRule(inviteePrefix, *dskCertificate, isIntroducer);
-  publishIntroCert(dskCertificate, isIntroducer);
+  publishIntroCert(*dskCertificate, isIntroducer);
 }
 
 void 
@@ -775,6 +695,83 @@
 }
 
 void
+ChatDialog::iconActivated(QSystemTrayIcon::ActivationReason reason)
+{
+  switch (reason)
+  {
+  case QSystemTrayIcon::Trigger:
+  case QSystemTrayIcon::DoubleClick:
+    break;
+  case QSystemTrayIcon::MiddleClick:
+    // showMessage();
+    break;
+  default:;
+  }
+}
+
+
+void
+ChatDialog::messageClicked()
+{
+  this->showMaximized();
+}
+
+
+void
+ChatDialog::createActions()
+{
+  // minimizeAction = new QAction(tr("Mi&nimize"), this);
+  // connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));
+
+  // maximizeAction = new QAction(tr("Ma&ximize"), this);
+  // connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
+
+  // restoreAction = new QAction(tr("&Restore"), this);
+  // connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));
+
+  // settingsAction = new QAction(tr("Settings"), this);
+  // connect (settingsAction, SIGNAL(triggered()), this, SLOT(buttonPressed()));
+
+  // settingsAction->setMenuRole (QAction::PreferencesRole);
+
+  // updateLocalPrefixAction = new QAction(tr("Update local prefix"), this);
+  // connect (updateLocalPrefixAction, SIGNAL(triggered()), this, SLOT(updateLocalPrefix()));
+
+  // quitAction = new QAction(tr("Quit"), this);
+  // connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+}
+
+void
+ChatDialog::createTrayIcon()
+{
+  // trayIconMenu = new QMenu(this);
+  // trayIconMenu->addAction(minimizeAction);
+  // trayIconMenu->addAction(maximizeAction);
+  // trayIconMenu->addAction(restoreAction);
+  // trayIconMenu->addSeparator();
+  // trayIconMenu->addAction(settingsAction);
+  // trayIconMenu->addSeparator();
+  // trayIconMenu->addAction(updateLocalPrefixAction);
+  // trayIconMenu->addSeparator();
+  // trayIconMenu->addAction(quitAction);
+
+  trayIcon = new QSystemTrayIcon(this);
+  // trayIcon->setContextMenu(trayIconMenu);
+
+  QIcon icon(":/images/icon_small.png");
+  trayIcon->setIcon(icon);
+  setWindowIcon(icon);
+  trayIcon->setToolTip("ChronoChat System Tray Icon");
+  trayIcon->setVisible(true);
+
+  // // QApplication::getMenu ()->addMenu (trayIconMenu);
+  // QMenuBar *bar = new QMenuBar ();
+  // bar->setMenu (trayIconMenu);
+  // setMenuBar (bar);
+}
+
+
+void
 ChatDialog::resizeEvent(QResizeEvent *e)
 {
   fitView();
@@ -816,6 +813,22 @@
 }
 
 void
+ChatDialog::changeEvent(QEvent *e)
+{
+  switch(e->type())
+  {
+  case QEvent::ActivationChange:
+    if (isActiveWindow())
+    {
+      trayIcon->setIcon(QIcon(":/images/icon_small.png"));
+    }
+    break;
+  default:
+    break;
+  }
+}
+
+void
 ChatDialog::appendMessage(const SyncDemo::ChatMessage msg, bool isHistory)
 {
   boost::recursive_mutex::scoped_lock lock(m_msgMutex);
@@ -952,9 +965,8 @@
 {
   if (!isActiveWindow())
   {
-    //TODO: Notification to be done
-    // trayIcon->showMessage(QString("Chatroom %1 has a new message").arg(m_user.getChatroom()), QString("<%1>: %2").arg(from).arg(data), QSystemTrayIcon::Information, 20000);
-    // trayIcon->setIcon(QIcon(":/images/note.png"));
+    trayIcon->showMessage(QString("Chatroom %1 has a new message").arg(m_user.getChatroom()), QString("<%1>: %2").arg(from).arg(data), QSystemTrayIcon::Information, 20000);
+    trayIcon->setIcon(QIcon(":/images/note.png"));
   }
 }
 
diff --git a/src/chatdialog.h b/src/chatdialog.h
index 951edbb..b59a5a4 100644
--- a/src/chatdialog.h
+++ b/src/chatdialog.h
@@ -17,6 +17,7 @@
 #include <QTextTable>
 #include <QStringListModel>
 #include <QTimer>
+#include <QSystemTrayIcon>
 
 #include "invitelistdialog.h"
 
@@ -94,8 +95,15 @@
   void 
   processRemoveWrapper(std::string);
 
+  void
+  publishIntroCert(const ndn::security::IdentityCertificate& dskCertificate, bool isIntroducer);
+
 protected:
-  void closeEvent(QCloseEvent *e);
+  void 
+  closeEvent(QCloseEvent *e);
+
+  void
+  changeEvent(QEvent *e);
 
 private:
 
@@ -110,9 +118,6 @@
 
   void
   initializeSync();
-
-  void
-  publishIntroCert(ndn::Ptr<ndn::security::IdentityCertificate> dskCertificate, bool isIntroducer);
   
   void 
   onInviteReplyVerified(ndn::Ptr<ndn::Data> data, const ndn::Name& identity, bool isIntroducer);
@@ -161,6 +166,12 @@
   void 
   fitView();
 
+  void 
+  createActions();
+
+  void
+  createTrayIcon();
+
   QString 
   formatTime(time_t);
 
@@ -225,6 +236,12 @@
   reap();
 
   void 
+  iconActivated(QSystemTrayIcon::ActivationReason reason);
+
+  void
+  messageClicked();
+
+  void 
   showMessage(QString, QString);
   
   void
@@ -257,7 +274,7 @@
   int m_randomizedInterval;
   QTimer *m_timer;
   QStringListModel *m_rosterModel;
-  
+  QSystemTrayIcon *trayIcon;
 
   // QQueue<SyncDemo::ChatMessage> m_history;
   // bool m_historyInitialized;
diff --git a/src/contactpanel.cpp b/src/contactpanel.cpp
index d29fdb0..8775ae5 100644
--- a/src/contactpanel.cpp
+++ b/src/contactpanel.cpp
@@ -408,12 +408,9 @@
     }
   
   m_currentSelectedContact = m_contactList[i];
-  QString name = QString::fromStdString(m_currentSelectedContact->getName());
-  QString institution = QString::fromStdString(m_currentSelectedContact->getInstitution());
-  QString nameSpace = QString::fromStdString(m_currentSelectedContact->getNameSpace().toUri());
-  ui->NameData->setText(name);
-  ui->NameSpaceData->setText(nameSpace);
-  ui->InstitutionData->setText(institution);
+  ui->NameData->setText(QString::fromStdString(m_currentSelectedContact->getName()));
+  ui->NameSpaceData->setText(QString::fromStdString(m_currentSelectedContact->getNameSpace().toUri()));
+  ui->InstitutionData->setText(QString::fromStdString(m_currentSelectedContact->getInstitution()));
 
   if(m_currentSelectedContact->isIntroducer())
     {
@@ -512,7 +509,7 @@
   m_contactList = m_contactManager->getContactItemList();
   QStringList contactNameList;
   for(int i = 0; i < m_contactList.size(); i++)
-    contactNameList << QString::fromUtf8(m_contactList[i]->getAlias().c_str());
+    contactNameList << QString::fromStdString(m_contactList[i]->getAlias());
 
   m_contactListModel->setStringList(contactNameList);
 }
@@ -524,6 +521,7 @@
   menu.addAction(m_menuInvite);
   connect(m_menuInvite, SIGNAL(triggered()),
           this, SLOT(openStartChatDialog()));
+  menu.addSeparator();
   menu.addAction(m_menuAlias);
   connect(m_menuAlias, SIGNAL(triggered()),
           this, SLOT(openSetAliasDialog()));
@@ -548,10 +546,6 @@
 void
 ContactPanel::openStartChatDialog()
 {
-  // TimeInterval ti = time::NowUnixTimestamp();
-  // ostringstream oss;
-  // oss << ti.total_seconds();
-
   Name chatroom("/ndn/broadcast/chronos");
   chatroom.append(string("chatroom-") + getRandomString());
 
@@ -563,10 +557,6 @@
 void
 ContactPanel::startChatroom(const QString& chatroom, const QString& invitee, bool isIntroducer)
 {
-  _LOG_DEBUG("room: " << chatroom.toUtf8().constData());
-  _LOG_DEBUG("invitee: " << invitee.toUtf8().constData());
-  _LOG_DEBUG("introducer: " << std::boolalpha << isIntroducer);
-
   Name chatroomName(chatroom.toUtf8().constData());
   ChatDialog* chatDialog = new ChatDialog(m_contactManager, chatroomName, m_localPrefix, m_defaultIdentity, m_nickName);
   m_chatDialogs.insert(pair <Name, ChatDialog*> (chatroomName, chatDialog));
@@ -588,24 +578,21 @@
 ContactPanel::startChatroom2(const ChronosInvitation& invitation, 
                              const security::IdentityCertificate& identityCertificate)
 {
-  _LOG_DEBUG("room: " << invitation.getChatroom().toUri());
-  _LOG_DEBUG("inviter: " << invitation.getInviterNameSpace().toUri());
-
   Name chatroomName("/ndn/broadcast/chronos");
   chatroomName.append(invitation.getChatroom());
   ChatDialog* chatDialog = new ChatDialog(m_contactManager, chatroomName, m_localPrefix, m_defaultIdentity, m_nickName, true);
+
   connect(chatDialog, SIGNAL(closeChatDialog(const ndn::Name&)),
           this, SLOT(removeChatDialog(const ndn::Name&)));
 
   chatDialog->addChatDataRule(invitation.getInviterPrefix(), identityCertificate, true);
+  chatDialog->publishIntroCert(identityCertificate, true);
 
   Ptr<ContactItem> inviterItem = m_contactManager->getContact(invitation.getInviterNameSpace());
   chatDialog->addTrustAnchor(inviterItem->getSelfEndorseCertificate());
   
   m_chatDialogs.insert(pair <Name, ChatDialog*> (chatroomName, chatDialog));
 
-
-
   chatDialog->show();
 }
 
@@ -614,10 +601,7 @@
                                const security::IdentityCertificate& identityCertificate)
 {
   string prefix = m_localPrefix.toUri();
-
   m_handler->publishDataByIdentity (invitation.getInterestName(), prefix);
-  //TODO:: open chat dialog
-  _LOG_DEBUG("TO open chat dialog");
   startChatroom2(invitation, identityCertificate);
 }
 
@@ -639,7 +623,6 @@
       
       string filter("contact_namespace = '");
       filter.append(m_currentSelectedContact->getNameSpace().toUri()).append("'");
-      _LOG_DEBUG("filter: " << filter);
 
       m_trustScopeModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
       m_trustScopeModel->setTable("TrustScope");
@@ -648,8 +631,6 @@
       m_trustScopeModel->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
       m_trustScopeModel->setHeaderData(1, Qt::Horizontal, QObject::tr("Contact"));
       m_trustScopeModel->setHeaderData(2, Qt::Horizontal, QObject::tr("TrustScope"));
-      _LOG_DEBUG("row count: " << m_trustScopeModel->rowCount());
-
 
       ui->trustScopeList->setModel(m_trustScopeModel);
       ui->trustScopeList->setColumnHidden(0, true);
@@ -713,9 +694,7 @@
 
 void
 ContactPanel::saveScopeClicked()
-{
-  m_trustScopeModel->submitAll();
-}
+{ m_trustScopeModel->submitAll(); }
 
 void
 ContactPanel::endorseButtonClicked()
@@ -728,15 +707,15 @@
 ContactPanel::removeChatDialog(const ndn::Name& chatroomName)
 {
   map<Name, ChatDialog*>::iterator it = m_chatDialogs.find(chatroomName);
-  _LOG_DEBUG("about to leave 2!");
-  ChatDialog* deletedChat;
+
+  ChatDialog* deletedChat = NULL;
   if(it != m_chatDialogs.end())
     {
-      _LOG_DEBUG("about to leave 3!");
       deletedChat = it->second;
       m_chatDialogs.erase(it);      
     }
-  delete deletedChat;
+  if (deletedChat != NULL)
+    delete deletedChat;
 }
 
 #if WAF
diff --git a/src/contactpanel.h b/src/contactpanel.h
index fd76b0b..f6e794c 100644
--- a/src/contactpanel.h
+++ b/src/contactpanel.h
@@ -96,8 +96,8 @@
 
   void
   onDnsEndorseeTimeout(ndn::Ptr<ndn::Closure> closure, 
-                      ndn::Ptr<ndn::Interest> interest, 
-                      int count);
+                       ndn::Ptr<ndn::Interest> interest, 
+                       int count);
   
   void
   onDnsEndorseeUnverified(ndn::Ptr<ndn::Data> data, int count);