separate ChatDialog frontend & backend
Change-Id: I824e58579a9aaac0264561cc7ae3d4977d98a3bf
diff --git a/src/chat-dialog-backend.cpp b/src/chat-dialog-backend.cpp
new file mode 100644
index 0000000..87eed37
--- /dev/null
+++ b/src/chat-dialog-backend.cpp
@@ -0,0 +1,386 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "chat-dialog-backend.hpp"
+
+#ifndef Q_MOC_RUN
+#include <ndn-cxx/util/io.hpp>
+#include "logging.h"
+#endif
+
+
+INIT_LOGGER("ChatDialogBackend");
+
+namespace chronos {
+
+static const time::milliseconds FRESHNESS_PERIOD(60000);
+static const time::seconds HELLO_INTERVAL(60);
+static const uint8_t ROUTING_HINT_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.
+
+ChatDialogBackend::ChatDialogBackend(const Name& chatroomPrefix,
+ const Name& userChatPrefix,
+ const Name& routingPrefix,
+ const std::string& chatroomName,
+ const std::string& nick,
+ QObject* parent)
+ : QThread(parent)
+ , m_localRoutingPrefix(routingPrefix)
+ , m_chatroomPrefix(chatroomPrefix)
+ , m_userChatPrefix(userChatPrefix)
+ , m_chatroomName(chatroomName)
+ , m_nick(nick)
+ , m_scheduler(m_face.getIoService())
+{
+ updatePrefixes();
+}
+
+
+ChatDialogBackend::~ChatDialogBackend()
+{
+}
+
+// protected methods:
+void
+ChatDialogBackend::run()
+{
+ initializeSync();
+
+ m_face.processEvents();
+
+ std::cerr << "Bye!" << std::endl;
+}
+
+// private methods:
+void
+ChatDialogBackend::initializeSync()
+{
+ QMutexLocker locker(&mutex);
+
+ // if a SyncSocket is running, turn it off
+ if (static_cast<bool>(m_sock)) {
+ if (m_joined)
+ sendLeave();
+ m_sock.reset();
+
+ usleep(100000);
+ }
+
+ // create a new SyncSocket
+ m_sock = make_shared<chronosync::Socket>(m_chatroomPrefix,
+ m_routableUserChatPrefix,
+ ref(m_face),
+ bind(&ChatDialogBackend::processSyncUpdate, this, _1));
+
+ // schedule a new join event
+ m_scheduler.scheduleEvent(time::milliseconds(600),
+ bind(&ChatDialogBackend::sendJoin, this));
+
+ // cancel existing hello event if it exists
+ if (static_cast<bool>(m_helloEventId)) {
+ m_scheduler.cancelEvent(m_helloEventId);
+ m_helloEventId.reset();
+ }
+}
+
+void
+ChatDialogBackend::processSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates)
+{
+ _LOG_DEBUG("<<< processing Tree Update");
+
+ if (updates.empty()) {
+ return;
+ }
+
+ std::vector<NodeInfo> nodeInfos;
+
+
+ for (int i = 0; i < updates.size(); i++) {
+ // update roster
+ if (m_roster.find(updates[i].session) == m_roster.end()) {
+ m_roster[updates[i].session].sessionPrefix = updates[i].session;
+ m_roster[updates[i].session].hasNick = false;
+ }
+
+ // fetch missing chat data
+ if (updates[i].high - updates[i].low < 3) {
+ for (chronosync::SeqNo seq = updates[i].low; seq <= updates[i].high; ++seq) {
+ m_sock->fetchData(updates[i].session, seq,
+ bind(&ChatDialogBackend::processChatData, this, _1, true),
+ 2);
+ _LOG_DEBUG("<<< Fetching " << updates[i].session << "/" << seq);
+ }
+ }
+ else {
+ // There are too many msgs to fetch, let's just fetch the latest one
+ m_sock->fetchData(updates[i].session, updates[i].high,
+ bind(&ChatDialogBackend::processChatData, this, _1, false),
+ 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
+ emit syncTreeUpdated(nodeInfos,
+ QString::fromStdString(getHexEncodedDigest(m_sock->getRootDigest())));
+}
+
+void
+ChatDialogBackend::processChatData(const ndn::shared_ptr<const ndn::Data>& data, bool needDisplay)
+{
+ SyncDemo::ChatMessage msg;
+
+ if (!msg.ParseFromArray(data->getContent().value(), data->getContent().value_size())) {
+ _LOG_DEBUG("Errrrr.. Can not parse msg with name: " <<
+ data->getName() << ". what is happening?");
+ // nasty stuff: as a remedy, we'll form some standard msg for inparsable msgs
+ msg.set_from("inconnu");
+ msg.set_type(SyncDemo::ChatMessage::OTHER);
+ return;
+ }
+
+ Name remoteSessionPrefix = data->getName().getPrefix(-1);
+
+ if (msg.type() == SyncDemo::ChatMessage::LEAVE) {
+ BackendRoster::iterator it = m_roster.find(remoteSessionPrefix);
+
+ if (it != m_roster.end()) {
+ // cancel timeout event
+ if (static_cast<bool>(it->second.timeoutEventId))
+ m_scheduler.cancelEvent(it->second.timeoutEventId);
+
+ // notify frontend to remove the remote session (node)
+ emit sessionRemoved(QString::fromStdString(remoteSessionPrefix.toUri()),
+ QString::fromStdString(msg.from()),
+ msg.timestamp());
+
+ // remove roster entry
+ m_roster.erase(remoteSessionPrefix);
+ }
+ }
+ else {
+ BackendRoster::iterator it = m_roster.find(remoteSessionPrefix);
+
+ if (it == m_roster.end()) {
+ // Should not happen
+ 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());
+ }
+
+ // 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()));
+ }
+
+ // If a timeout event has been scheduled, cancel it.
+ if (static_cast<bool>(it->second.timeoutEventId))
+ m_scheduler.cancelEvent(it->second.timeoutEventId);
+
+ // (Re)schedule another timeout event after 3 HELLO_INTERVAL;
+ it->second.timeoutEventId =
+ m_scheduler.scheduleEvent(HELLO_INTERVAL * 3,
+ bind(&ChatDialogBackend::remoteSessionTimeout,
+ this, remoteSessionPrefix));
+
+ // If chat message, notify the frontend
+ if (msg.type() == SyncDemo::ChatMessage::CHAT)
+ emit chatMessageReceived(QString::fromStdString(msg.from()),
+ QString::fromStdString(msg.data()),
+ msg.timestamp());
+
+ // Notify frontend to plot notification on DigestTree.
+ emit messageReceived(QString::fromStdString(remoteSessionPrefix.toUri()));
+ }
+}
+
+void
+ChatDialogBackend::remoteSessionTimeout(const Name& sessionPrefix)
+{
+ time_t timestamp =
+ static_cast<time_t>(time::toUnixTimestamp(time::system_clock::now()).count() / 1000);
+
+ // notify frontend
+ emit sessionRemoved(QString::fromStdString(sessionPrefix.toUri()),
+ QString::fromStdString(m_roster[sessionPrefix].userNick),
+ timestamp);
+
+ // remove roster entry
+ m_roster.erase(sessionPrefix);
+}
+
+void
+ChatDialogBackend::sendMsg(SyncDemo::ChatMessage& msg)
+{
+ // send msg
+ ndn::OBufferStream os;
+ msg.SerializeToOstream(&os);
+
+ if (!msg.IsInitialized()) {
+ _LOG_DEBUG("Errrrr.. msg was not probally initialized " << __FILE__ <<
+ ":" << __LINE__ << ". what is happening?");
+ abort();
+ }
+
+ uint64_t nextSequence = m_sock->getLogic().getSeqNo() + 1;
+
+ m_sock->publishData(os.buf()->buf(), os.buf()->size(), FRESHNESS_PERIOD);
+
+ std::vector<NodeInfo> nodeInfos;
+ NodeInfo nodeInfo = {QString::fromStdString(m_routableUserChatPrefix.toUri()),
+ nextSequence};
+ nodeInfos.push_back(nodeInfo);
+
+ emit syncTreeUpdated(nodeInfos,
+ QString::fromStdString(getHexEncodedDigest(m_sock->getRootDigest())));
+}
+
+void
+ChatDialogBackend::sendJoin()
+{
+ m_joined = true;
+
+ SyncDemo::ChatMessage msg;
+ prepareControlMessage(msg, SyncDemo::ChatMessage::JOIN);
+ sendMsg(msg);
+
+ m_helloEventId = m_scheduler.scheduleEvent(HELLO_INTERVAL,
+ bind(&ChatDialogBackend::sendHello, this));
+
+ emit sessionAdded(QString::fromStdString(m_routableUserChatPrefix.toUri()),
+ QString::fromStdString(msg.from()),
+ msg.timestamp());
+}
+
+void
+ChatDialogBackend::sendHello()
+{
+ SyncDemo::ChatMessage msg;
+ prepareControlMessage(msg, SyncDemo::ChatMessage::HELLO);
+ sendMsg(msg);
+
+ m_helloEventId = m_scheduler.scheduleEvent(HELLO_INTERVAL,
+ bind(&ChatDialogBackend::sendHello, this));
+}
+
+void
+ChatDialogBackend::sendLeave()
+{
+ SyncDemo::ChatMessage msg;
+ prepareControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
+ sendMsg(msg);
+
+ usleep(5000);
+ m_joined = false;
+}
+
+void
+ChatDialogBackend::prepareControlMessage(SyncDemo::ChatMessage& msg,
+ SyncDemo::ChatMessage::ChatMessageType type)
+{
+ msg.set_from(m_nick);
+ msg.set_to(m_chatroomName);
+ int32_t seconds =
+ static_cast<int32_t>(time::toUnixTimestamp(time::system_clock::now()).count() / 1000);
+ msg.set_timestamp(seconds);
+ msg.set_type(type);
+}
+
+void
+ChatDialogBackend::prepareChatMessage(const QString& text,
+ time_t timestamp,
+ SyncDemo::ChatMessage &msg)
+{
+ msg.set_from(m_nick);
+ msg.set_to(m_chatroomName);
+ msg.set_data(text.toStdString());
+ msg.set_timestamp(timestamp);
+ msg.set_type(SyncDemo::ChatMessage::CHAT);
+}
+
+void
+ChatDialogBackend::updatePrefixes()
+{
+ m_routableUserChatPrefix.clear();
+
+ if (m_localRoutingPrefix.isPrefixOf(m_userChatPrefix))
+ m_routableUserChatPrefix = m_userChatPrefix;
+ else
+ m_routableUserChatPrefix.append(m_localRoutingPrefix)
+ .append(ROUTING_HINT_SEPARATOR, 2)
+ .append(m_userChatPrefix);
+
+ emit chatPrefixChanged(m_routableUserChatPrefix);
+}
+
+std::string
+ChatDialogBackend::getHexEncodedDigest(ndn::ConstBufferPtr digest)
+{
+ std::stringstream os;
+
+ CryptoPP::StringSource(digest->buf(), digest->size(), true,
+ new CryptoPP::HexEncoder(new CryptoPP::FileSink(os), false));
+ return os.str();
+}
+
+
+// public slots:
+void
+ChatDialogBackend::sendChatMessage(QString text, time_t timestamp)
+{
+ SyncDemo::ChatMessage msg;
+ prepareChatMessage(text, timestamp, msg);
+ sendMsg(msg);
+
+ emit chatMessageReceived(QString::fromStdString(msg.from()),
+ QString::fromStdString(msg.data()),
+ msg.timestamp());
+}
+
+void
+ChatDialogBackend::updateRoutingPrefix(const QString& localRoutingPrefix)
+{
+ Name newLocalRoutingPrefix(localRoutingPrefix.toStdString());
+
+ if (!newLocalRoutingPrefix.empty() && newLocalRoutingPrefix != m_localRoutingPrefix) {
+ // Update localPrefix
+ m_localRoutingPrefix = newLocalRoutingPrefix;
+
+ updatePrefixes();
+
+ initializeSync();
+ }
+}
+
+void
+ChatDialogBackend::shutdown()
+{
+ m_face.getIoService().stop();
+}
+
+} // namespace chronos
+
+#if WAF
+#include "chat-dialog-backend.moc"
+// #include "chat-dialog-backend.cpp.moc"
+#endif
diff --git a/src/chat-dialog-backend.hpp b/src/chat-dialog-backend.hpp
new file mode 100644
index 0000000..eda4094
--- /dev/null
+++ b/src/chat-dialog-backend.hpp
@@ -0,0 +1,156 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef CHRONOCHAT_CHAT_DIALOG_BACKEND_HPP
+#define CHRONOCHAT_CHAT_DIALOG_BACKEND_HPP
+
+#include <QThread>
+#include <QMutex>
+
+#ifndef Q_MOC_RUN
+#include "common.hpp"
+#include "chatroom-info.hpp"
+#include "chatbuf.pb.h"
+#include <socket.hpp>
+#endif
+
+namespace chronos {
+
+class NodeInfo {
+public:
+ QString sessionPrefix;
+ chronosync::SeqNo seqNo;
+};
+
+class UserInfo {
+public:
+ ndn::Name sessionPrefix;
+ bool hasNick;
+ std::string userNick;
+ ndn::EventId timeoutEventId;
+};
+
+class ChatDialogBackend : public QThread
+{
+ Q_OBJECT
+
+public:
+ ChatDialogBackend(const Name& chatroomPrefix,
+ const Name& userChatPrefix,
+ const Name& routingPrefix,
+ const std::string& chatroomName,
+ const std::string& nick,
+ QObject* parent = 0);
+
+ ~ChatDialogBackend();
+
+protected:
+ void
+ run();
+
+private:
+ void
+ initializeSync();
+
+ void
+ processSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates);
+
+ void
+ processChatData(const ndn::shared_ptr<const ndn::Data>& data, bool needDisplay);
+
+ void
+ remoteSessionTimeout(const Name& sessionPrefix);
+
+ void
+ sendMsg(SyncDemo::ChatMessage& msg);
+
+ void
+ sendJoin();
+
+ void
+ sendHello();
+
+ void
+ sendLeave();
+
+ void
+ prepareControlMessage(SyncDemo::ChatMessage& msg,
+ SyncDemo::ChatMessage::ChatMessageType type);
+
+ void
+ prepareChatMessage(const QString& text,
+ time_t timestamp,
+ SyncDemo::ChatMessage &msg);
+
+ void
+ updatePrefixes();
+
+ std::string
+ getHexEncodedDigest(ndn::ConstBufferPtr digest);
+
+signals:
+ void
+ syncTreeUpdated(std::vector<chronos::NodeInfo> updates, QString digest);
+
+ void
+ 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);
+
+ void
+ chatPrefixChanged(ndn::Name newChatPrefix);
+
+public slots:
+ void
+ sendChatMessage(QString text, time_t timestamp);
+
+ void
+ updateRoutingPrefix(const QString& localRoutingPrefix);
+
+ void
+ shutdown();
+
+private:
+ typedef std::map<ndn::Name, UserInfo> BackendRoster;
+
+ ndn::Face m_face;
+
+ Name m_localRoutingPrefix; // routable local prefix
+ Name m_chatroomPrefix; // chatroom sync prefix
+ Name m_userChatPrefix; // user chat prefix
+ Name m_routableUserChatPrefix; // routable user chat prefix
+
+ std::string m_chatroomName; // chatroom name
+ std::string m_nick; // user nick
+
+ shared_ptr<chronosync::Socket> m_sock; // SyncSocket
+
+ ndn::Scheduler m_scheduler; // scheduler
+ ndn::EventId m_helloEventId; // event id of timeout
+
+ QMutex mutex; // mutex used for prefix updates
+
+ bool m_joined; // true if in a chatroom
+
+ BackendRoster m_roster; // User roster
+};
+
+} // namespace chronos
+
+#endif // CHRONOCHAT_CHAT_DIALOG_BACKEND_HPP
diff --git a/src/chat-dialog.cpp b/src/chat-dialog.cpp
index 0079f4f..a475c16 100644
--- a/src/chat-dialog.cpp
+++ b/src/chat-dialog.cpp
@@ -17,99 +17,100 @@
#include <QMessageBox>
#include <QCloseEvent>
-#ifndef Q_MOC_RUN
-#include <sync-intro-certificate.h>
-#include <boost/random/random_device.hpp>
-#include <boost/random/uniform_int_distribution.hpp>
-#include <ndn-cxx/util/random.hpp>
-#include <ndn-cxx/encoding/buffer-stream.hpp>
-#include "cryptopp.hpp"
-#include <queue>
-#include "logging.h"
-
-#define SECURITY_ENABLED false
-#endif
-
-
-// INIT_LOGGER("ChatDialog");
-
-Q_DECLARE_METATYPE(std::vector<Sync::MissingDataInfo> )
-Q_DECLARE_METATYPE(ndn::shared_ptr<const ndn::Data>)
-Q_DECLARE_METATYPE(ndn::Interest)
-Q_DECLARE_METATYPE(size_t)
-
+Q_DECLARE_METATYPE(ndn::Name)
+Q_DECLARE_METATYPE(time_t)
+Q_DECLARE_METATYPE(std::vector<chronos::NodeInfo>)
namespace chronos {
-using std::vector;
-using std::string;
-using std::map;
-using std::queue;
+static const Name PRIVATE_PREFIX("/private/local");
+static const uint8_t ROUTING_HINT_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.
-using ndn::IdentityCertificate;
-using ndn::SecRuleRelative;
-using ndn::Face;
-using ndn::OBufferStream;
-using ndn::OnDataValidated;
-using ndn::OnDataValidationFailed;
-
-
-static const int HELLO_INTERVAL = FRESHNESS * 3 / 4;
-static const uint8_t CHRONOS_RP_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.
-
-ChatDialog::ChatDialog(ContactManager* contactManager,
- shared_ptr<Face> face,
- const IdentityCertificate& myCertificate,
- const Name& chatroomPrefix,
- const Name& localPrefix,
+ChatDialog::ChatDialog(const Name& chatroomPrefix,
+ const Name& userChatPrefix,
+ const Name& routingPrefix,
+ const std::string& chatroomName,
const std::string& nick,
- bool withSecurity,
+ bool isSecured,
QWidget* parent)
: QDialog(parent)
, ui(new Ui::ChatDialog)
- , m_contactManager(contactManager)
- , m_face(face)
- , m_myCertificate(myCertificate)
- , m_chatroomName(chatroomPrefix.get(-1).toUri())
- , m_chatroomPrefix(chatroomPrefix)
- , m_localPrefix(localPrefix)
- , m_useRoutablePrefix(false)
- , m_nick(nick)
- , m_lastMsgTime(time::toUnixTimestamp(time::system_clock::now()).count())
- , m_joined(false)
- , m_sock(NULL)
- , m_session(static_cast<uint64_t>(time::toUnixTimestamp(time::system_clock::now()).count()))
- , m_inviteListDialog(new InviteListDialog)
- //ymj
- //, m_trustModel(withSecurity)
+ , m_backend(chatroomPrefix, userChatPrefix, routingPrefix, chatroomName, nick)
+ , m_chatroomName(chatroomName)
+ , m_nick(nick.c_str())
+ , m_isSecured(isSecured)
{
- qRegisterMetaType<std::vector<Sync::MissingDataInfo> >("std::vector<Sync::MissingDataInfo>");
- qRegisterMetaType<ndn::shared_ptr<const ndn::Data> >("ndn.DataPtr");
- qRegisterMetaType<ndn::Interest>("ndn.Interest");
- qRegisterMetaType<size_t>("size_t");
+ qRegisterMetaType<ndn::Name>("ndn::Name");
+ qRegisterMetaType<time_t>("time_t");
+ qRegisterMetaType<std::vector<chronos::NodeInfo> >("std::vector<chronos::NodeInfo>");
m_scene = new DigestTreeScene(this);
m_trustScene = new TrustTreeScene(this);
m_rosterModel = new QStringListModel(this);
- m_timer = new QTimer(this);
ui->setupUi(this);
+
ui->syncTreeViewer->setScene(m_scene);
m_scene->setSceneRect(m_scene->itemsBoundingRect());
ui->syncTreeViewer->hide();
+
ui->trustTreeViewer->setScene(m_trustScene);
m_trustScene->setSceneRect(m_trustScene->itemsBoundingRect());
ui->trustTreeViewer->hide();
+
ui->listView->setModel(m_rosterModel);
- m_identity =
- IdentityCertificate::certificateNameToPublicKeyName(m_myCertificate.getName()).getPrefix(-1);
+ Name routablePrefix;
- updatePrefix();
+ if (routingPrefix.isPrefixOf(userChatPrefix))
+ routablePrefix = userChatPrefix;
+ else
+ routablePrefix.append(routingPrefix)
+ .append(ROUTING_HINT_SEPARATOR, 2)
+ .append(userChatPrefix);
- updateLabels();
+ updateLabels(routablePrefix);
- m_scene->setCurrentPrefix(QString(m_localChatPrefix.toUri().c_str()));
+ QStringList roster;
+ roster << "- " + m_nick;
+ m_rosterModel->setStringList(roster);
+
+ // When backend receives a sync update, notify frontend to update sync tree
+ connect(&m_backend, SIGNAL(syncTreeUpdated(std::vector<chronos::NodeInfo>, QString)),
+ this, SLOT(updateSyncTree(std::vector<chronos::NodeInfo>, QString)));
+
+ // When backend receives a new chat message, notify frontent to print it out.
+ 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)));
+
+ // When backend updates prefix, notify frontend to update labels.
+ connect(&m_backend, SIGNAL(chatPrefixChanged(ndn::Name)),
+ this, SLOT(updateLabels(ndn::Name)));
+
+ // When frontend gets a message to send, notify backend.
+ connect(this, SIGNAL(msgToSent(QString, time_t)),
+ &m_backend, SLOT(sendChatMessage(QString, time_t)));
+
+ // When frontend gets a shutdown command, notify backend.
+ connect(this, SIGNAL(shutdownBackend()),
+ &m_backend, SLOT(shutdown()));
+
m_scene->plot("Empty");
connect(ui->lineEdit, SIGNAL(returnPressed()),
@@ -118,123 +119,23 @@
this, SLOT(onSyncTreeButtonPressed()));
connect(ui->trustTreeButton, SIGNAL(pressed()),
this, SLOT(onTrustTreeButtonPressed()));
- connect(m_scene, SIGNAL(replot()),
- this, SLOT(onReplot()));
- connect(m_scene, SIGNAL(rosterChanged(QStringList)),
- this, SLOT(onRosterChanged(QStringList)));
- connect(m_timer, SIGNAL(timeout()),
- this, SLOT(onReplot()));
- connect(this, SIGNAL(processData(const ndn::shared_ptr<const ndn::Data>&, bool, bool)),
- this, SLOT(onProcessData(const ndn::shared_ptr<const ndn::Data>&, bool, bool)));
- connect(this, SIGNAL(processTreeUpdate(const std::vector<Sync::MissingDataInfo>)),
- this, SLOT(onProcessTreeUpdate(const std::vector<Sync::MissingDataInfo>)));
- connect(this, SIGNAL(reply(const ndn::Interest&,
- const ndn::shared_ptr<const ndn::Data>&,
- size_t, bool)),
- this, SLOT(onReply(const ndn::Interest&,
- const ndn::shared_ptr<const ndn::Data>&,
- size_t, bool)));
- connect(this, SIGNAL(replyTimeout(const ndn::Interest&, size_t)),
- this, SLOT(onReplyTimeout(const ndn::Interest&, size_t)));
- connect(this, SIGNAL(introCert(const ndn::Interest&, const ndn::shared_ptr<const ndn::Data>&)),
- this, SLOT(onIntroCert(const ndn::Interest&, const ndn::shared_ptr<const ndn::Data>&)));
- connect(this, SIGNAL(introCertTimeout(const ndn::Interest&, int, const QString&)),
- this, SLOT(onIntroCertTimeout(const ndn::Interest&, int, const QString&)));
+ disableSyncTreeDisplay();
+ QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
- if (withSecurity) {
- m_invitationValidator = make_shared<chronos::ValidatorInvitation>();
- m_dataRule = make_shared<SecRuleRelative>("([^<CHRONOCHAT-DATA>]*)<CHRONOCHAT-DATA><>",
- "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
- "==", "\\1", "\\1", true);
-
- ui->inviteButton->setEnabled(true);
- ui->trustTreeButton->setEnabled(true);
-
- connect(ui->inviteButton, SIGNAL(clicked()),
- this, SLOT(onInviteListDialogRequested()));
- connect(m_inviteListDialog, SIGNAL(sendInvitation(const QString&)),
- this, SLOT(onSendInvitation(const QString&)));
- connect(this, SIGNAL(waitForContactList()),
- m_contactManager, SLOT(onWaitForContactList()));
- connect(m_contactManager, SIGNAL(contactAliasListReady(const QStringList&)),
- m_inviteListDialog, SLOT(onContactAliasListReady(const QStringList&)));
- connect(m_contactManager, SIGNAL(contactIdListReady(const QStringList&)),
- m_inviteListDialog, SLOT(onContactIdListReady(const QStringList&)));
-
- m_trustModel = ChatroomInfo::TRUST_MODEL_WEBOFTRUST;
- }
- else
- m_trustModel = ChatroomInfo::TRUST_MODEL_NONE;
-
- initializeSync();
+ m_backend.start();
}
ChatDialog::~ChatDialog()
{
- if (SECURITY_ENABLED) {
- if (m_certListPrefixId)
- m_face->unsetInterestFilter(m_certListPrefixId);
-
- if (m_certSinglePrefixId)
- m_face->unsetInterestFilter(m_certSinglePrefixId);
- }
-
- if (m_sock != NULL) {
- sendLeave();
- delete m_sock;
- m_sock = NULL;
- }
}
-// public methods:
-void
-ChatDialog::addSyncAnchor(const Invitation& invitation)
-{
- // _LOG_DEBUG("Add sync anchor from invitation");
- // Add inviter certificate as trust anchor.
- m_sock->addParticipant(invitation.getInviterCertificate());
- plotTrustTree();
-
- // Ask inviter for IntroCertificate
- Name inviterNameSpace =
- IdentityCertificate::certificateNameToPublicKeyName(
- invitation.getInviterCertificate().getName()).getPrefix(-1);
- fetchIntroCert(inviterNameSpace, invitation.getInviterRoutingPrefix());
-}
-
-void
-ChatDialog::processTreeUpdateWrapper(const vector<Sync::MissingDataInfo>& v,
- Sync::SyncSocket *sock)
-{
- emit processTreeUpdate(v);
- // _LOG_DEBUG("<<< Tree update signal emitted");
-}
-
-void
-ChatDialog::processDataWrapper(const shared_ptr<const Data>& data)
-{
- emit processData(data, true, false);
- // _LOG_DEBUG("<<< " << data->getName() << " fetched");
-}
-
-void
-ChatDialog::processDataNoShowWrapper(const shared_ptr<const Data>& data)
-{
- emit processData(data, false, false);
-}
-
-void
-ChatDialog::processRemoveWrapper(const string& prefix)
-{
- // _LOG_DEBUG("Sync REMOVE signal received for prefix: " << prefix);
-}
-
-// protected methods:
void
ChatDialog::closeEvent(QCloseEvent *e)
{
+ // When close button is clicked, do not close the dialog immediately.
+
QMessageBox::information(this, tr("ChronoChat"),
tr("The chatroom will keep running in the "
"system tray. To close the chatroom, "
@@ -270,355 +171,28 @@
fitView();
}
+shared_ptr<ChatroomInfo>
+ChatDialog::getChatroomInfo()
+{
+ shared_ptr<ChatroomInfo> chatroomInfo = make_shared<ChatroomInfo>();
+
+ chatroomInfo->setName(Name::Component(m_chatroomName));
+
+ QStringList prefixList = m_scene->getRosterPrefixList();
+ for(QStringList::iterator it = prefixList.begin();
+ it != prefixList.end(); ++it ) {
+ Name participant = Name(it->toStdString()).getPrefix(-3);
+ chatroomInfo->addParticipant(participant);
+ }
+
+ if (m_isSecured)
+ chatroomInfo->setTrustModel(ChatroomInfo::TRUST_MODEL_WEBOFTRUST);
+ else
+ chatroomInfo->setTrustModel(ChatroomInfo::TRUST_MODEL_NONE);
+ return chatroomInfo;
+}
+
// private methods:
-void
-ChatDialog::updatePrefix()
-{
- m_certListPrefix.clear();
- m_certSinglePrefix.clear();
- m_localChatPrefix.clear();
- m_chatPrefix.clear();
- m_chatPrefix.append(m_identity)
- .append("CHRONOCHAT-DATA")
- .append(m_chatroomName)
- .append(getRandomString());
- if (!m_localPrefix.isPrefixOf(m_identity)) {
- m_useRoutablePrefix = true;
- m_certListPrefix.append(m_localPrefix).append(CHRONOS_RP_SEPARATOR, 2);
- m_certSinglePrefix.append(m_localPrefix).append(CHRONOS_RP_SEPARATOR, 2);
- m_localChatPrefix.append(m_localPrefix).append(CHRONOS_RP_SEPARATOR, 2);
- }
- m_certListPrefix.append(m_identity).append("CHRONOCHAT-CERT-LIST").append(m_chatroomName);
- m_certSinglePrefix.append(m_identity).append("CHRONOCHAT-CERT-SINGLE").append(m_chatroomName);
- m_localChatPrefix.append(m_chatPrefix);
-
- if (SECURITY_ENABLED) {
- if (static_cast<bool>(m_certListPrefixId))
- m_face->unsetInterestFilter(m_certListPrefixId);
-
- m_certListPrefixId = m_face->setInterestFilter(m_certListPrefix,
- bind(&ChatDialog::onCertListInterest,
- this, _1, _2),
- bind(&ChatDialog::onCertListRegisterFailed,
- this, _1, _2));
-
- if (static_cast<bool>(m_certSinglePrefixId))
- m_face->unsetInterestFilter(m_certSinglePrefixId);
-
- m_certSinglePrefixId = m_face->setInterestFilter(m_certSinglePrefix,
- bind(&ChatDialog::onCertSingleInterest,
- this, _1, _2),
- bind(&ChatDialog::onCertSingleRegisterFailed,
- this, _1, _2));
- }
-}
-
-void
-ChatDialog::updateLabels()
-{
- QString settingDisp = QString("Chatroom: %1").arg(QString::fromStdString(m_chatroomName));
- ui->infoLabel->setStyleSheet("QLabel {color: #630; font-size: 16px; font: bold \"Verdana\";}");
- ui->infoLabel->setText(settingDisp);
- QString prefixDisp;
- Name privatePrefix("/private/local");
- if (privatePrefix.isPrefixOf(m_localChatPrefix)) {
- prefixDisp =
- QString("<Warning: no connection to hub or hub does not support prefix autoconfig.>\n"
- "<Prefix = %1>")
- .arg(QString::fromStdString(m_localChatPrefix.toUri()));
- ui->prefixLabel->setStyleSheet(
- "QLabel {color: red; font-size: 12px; font: bold \"Verdana\";}");
- }
- else {
- prefixDisp = QString("<Prefix = %1>")
- .arg(QString::fromStdString(m_localChatPrefix.toUri()));
- ui->prefixLabel->setStyleSheet(
- "QLabel {color: Green; font-size: 12px; font: bold \"Verdana\";}");
- }
- ui->prefixLabel->setText(prefixDisp);
-}
-
-void
-ChatDialog::initializeSync()
-{
-
- m_sock = new Sync::SyncSocket(m_chatroomPrefix,
- m_chatPrefix,
- m_session,
- m_useRoutablePrefix,
- m_localPrefix,
- m_face,
- m_myCertificate,
- m_dataRule,
- bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
- bind(&ChatDialog::processRemoveWrapper, this, _1));
-
- usleep(100000);
-
- QTimer::singleShot(600, this, SLOT(sendJoin()));
- m_timer->start(FRESHNESS * 1000);
- disableSyncTreeDisplay();
- QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
-}
-
-void
-ChatDialog::sendInvitation(shared_ptr<Contact> contact, bool isIntroducer)
-{
- // Add invitee as a trust anchor.
- m_invitationValidator->addTrustAnchor(contact->getPublicKeyName(),
- contact->getPublicKey());
-
- // Prepared an invitation interest without routable prefix.
- Invitation invitation(contact->getNameSpace(),
- m_chatroomName,
- m_localPrefix,
- m_myCertificate);
- Interest tmpInterest(invitation.getUnsignedInterestName());
- m_keyChain.sign(tmpInterest, m_myCertificate.getName());
-
- // Get invitee's routable prefix
- // (ideally it will do some DNS lookup, but we assume everyone use /ndn/broadcast
- Name routablePrefix = getInviteeRoutablePrefix(contact->getNameSpace());
-
- // Check if we need to prepend the routable prefix to the interest name.
- bool requireRoutablePrefix = false;
- Name interestName;
- size_t routablePrefixOffset = 0;
- if (!routablePrefix.isPrefixOf(tmpInterest.getName())) {
- interestName.append(routablePrefix).append(CHRONOS_RP_SEPARATOR, 2);
- requireRoutablePrefix = true;
- routablePrefixOffset = routablePrefix.size() + 1;
- }
- interestName.append(tmpInterest.getName());
-
- // Send the invitation out
- Interest interest(interestName);
- interest.setMustBeFresh(true);
- // _LOG_DEBUG("sendInvitation: " << interest.getName());
- m_face->expressInterest(interest,
- bind(&ChatDialog::replyWrapper,
- this, _1, _2, routablePrefixOffset, isIntroducer),
- bind(&ChatDialog::replyTimeoutWrapper,
- this, _1, routablePrefixOffset));
-}
-
-void
-ChatDialog::replyWrapper(const Interest& interest,
- Data& data,
- size_t routablePrefixOffset,
- bool isIntroducer)
-{
- // _LOG_DEBUG("ChatDialog::replyWrapper");
- emit reply(interest, data.shared_from_this(), routablePrefixOffset, isIntroducer);
- // _LOG_DEBUG("OK?");
-}
-
-void
-ChatDialog::replyTimeoutWrapper(const Interest& interest,
- size_t routablePrefixOffset)
-{
- // _LOG_DEBUG("ChatDialog::replyTimeoutWrapper");
- emit replyTimeout(interest, routablePrefixOffset);
-}
-
-void
-ChatDialog::onReplyValidated(const shared_ptr<const Data>& data,
- size_t inviteeRoutablePrefixOffset,
- bool isIntroducer)
-{
- if (data->getName().size() <= inviteeRoutablePrefixOffset) {
- Invitation invitation(data->getName());
- invitationRejected(invitation.getInviteeNameSpace());
- }
- else {
- Name inviteePrefix;
- inviteePrefix.wireDecode(data->getName().get(inviteeRoutablePrefixOffset).blockFromValue());
- IdentityCertificate inviteeCert;
- inviteeCert.wireDecode(data->getContent().blockFromValue());
- invitationAccepted(inviteeCert, inviteePrefix, isIntroducer);
- }
-}
-
-void
-ChatDialog::onReplyValidationFailed(const shared_ptr<const Data>& data,
- const string& failureInfo)
-{
- // _LOG_DEBUG("Invitation reply cannot be validated: " + failureInfo + " ==> " +
- // data->getName().toUri());
-}
-
-void
-ChatDialog::invitationRejected(const Name& identity)
-{
- QString msg = QString::fromStdString(identity.toUri()) + " rejected your invitation!";
- emit inivationRejection(msg);
-}
-
-void
-ChatDialog::invitationAccepted(const IdentityCertificate& inviteeCert,
- const Name& inviteePrefix,
- bool isIntroducer)
-{
- // Add invitee certificate as trust anchor.
- m_sock->addParticipant(inviteeCert);
- plotTrustTree();
-
- // Ask invitee for IntroCertificate.
- Name inviteeNameSpace =
- IdentityCertificate::certificateNameToPublicKeyName(inviteeCert.getName()).getPrefix(-1);
- fetchIntroCert(inviteeNameSpace, inviteePrefix);
-}
-
-void
-ChatDialog::fetchIntroCert(const Name& identity, const Name& prefix)
-{
- Name interestName;
-
- if (!prefix.isPrefixOf(identity))
- interestName.append(prefix).append(CHRONOS_RP_SEPARATOR, 2);
-
- interestName.append(identity)
- .append("CHRONOCHAT-CERT-LIST")
- .append(m_chatroomName)
- .appendVersion();
-
- Interest interest(interestName);
- interest.setMustBeFresh(true);
-
- m_face->expressInterest(interest,
- bind(&ChatDialog::onIntroCertList, this, _1, _2),
- bind(&ChatDialog::onIntroCertListTimeout, this, _1, 1,
- "IntroCertList: " + interestName.toUri()));
-}
-
-void
-ChatDialog::onIntroCertList(const Interest& interest, const Data& data)
-{
- Chronos::IntroCertListMsg introCertList;
- if (!introCertList.ParseFromArray(data.getContent().value(), data.getContent().value_size()))
- return;
-
- for (int i = 0; i < introCertList.certname_size(); i++) {
- Name certName(introCertList.certname(i));
- Interest interest(certName);
- interest.setMustBeFresh(true);
-
- // _LOG_DEBUG("onIntroCertList: to fetch " << certName);
-
- m_face->expressInterest(interest,
- bind(&ChatDialog::introCertWrapper, this, _1, _2),
- bind(&ChatDialog::introCertTimeoutWrapper, this, _1, 0,
- QString("IntroCert: %1").arg(introCertList.certname(i).c_str())));
- }
-}
-
-void
-ChatDialog::onIntroCertListTimeout(const Interest& interest, int retry, const string& msg)
-{
- if (retry > 0) {
- m_face->expressInterest(interest,
- bind(&ChatDialog::onIntroCertList, this, _1, _2),
- bind(&ChatDialog::onIntroCertListTimeout, this, _1, retry - 1, msg));
- }
- else {
- // _LOG_DEBUG(msg << " TIMEOUT!");
- }
-}
-
-void
-ChatDialog::introCertWrapper(const Interest& interest, Data& data)
-{
- emit introCert(interest, data.shared_from_this());
-}
-
-void
-ChatDialog::introCertTimeoutWrapper(const Interest& interest, int retry, const QString& msg)
-{
- emit introCertTimeout(interest, retry, msg);
-}
-
-void
-ChatDialog::onCertListInterest(const ndn::Name& prefix, const ndn::Interest& interest)
-{
- vector<Name> certNameList;
- m_sock->getIntroCertNames(certNameList);
-
- Chronos::IntroCertListMsg msg;
-
- for (vector<Name>::const_iterator it = certNameList.begin(); it != certNameList.end(); it++) {
- Name certName;
- certName.append(m_certSinglePrefix).append(*it);
- msg.add_certname(certName.toUri());
- }
- OBufferStream os;
- msg.SerializeToOstream(&os);
-
- shared_ptr<Data> data = make_shared<Data>(interest.getName());
- data->setContent(os.buf());
- m_keyChain.sign(*data, m_myCertificate.getName());
-
- m_face->put(*data);
-}
-
-void
-ChatDialog::onCertListRegisterFailed(const ndn::Name& prefix, const std::string& msg)
-{
- _LOG_DEBUG("ChatDialog::onCertListRegisterFailed failed: " + msg);
-}
-
-void
-ChatDialog::onCertSingleInterest(const Name& prefix, const Interest& interest)
-{
- try {
- Name certName = interest.getName().getSubName(prefix.size());
- const Sync::IntroCertificate& introCert = m_sock->getIntroCertificate(certName);
-
- shared_ptr<Data> data = make_shared<Data>(interest.getName());
- data->setContent(introCert.wireEncode());
- m_keyChain.sign(*data, m_myCertificate.getName());
- m_face->put(*data);
- }
- catch(Sync::SyncSocket::Error& e) {
- return;
- }
-}
-
-void
-ChatDialog::onCertSingleRegisterFailed(const Name& prefix, const std::string& msg)
-{
- _LOG_DEBUG("ChatDialog::onCertListRegisterFailed failed: " + msg);
-}
-
-void
-ChatDialog::sendMsg(SyncDemo::ChatMessage &msg)
-{
- // send msg
- OBufferStream os;
- msg.SerializeToOstream(&os);
-
- if (!msg.IsInitialized()) {
- // _LOG_DEBUG("Errrrr.. msg was not probally initialized " << __FILE__ <<
- // ":" << __LINE__ << ". what is happening?");
- abort();
- }
- uint64_t nextSequence = m_sock->getNextSeq();
- m_sock->publishData(os.buf()->buf(), os.buf()->size(), FRESHNESS);
-
- m_lastMsgTime = time::toUnixTimestamp(time::system_clock::now()).count();
-
- Sync::MissingDataInfo mdi = {m_localChatPrefix.toUri(),
- Sync::SeqNo(0),
- Sync::SeqNo(nextSequence)};
- vector<Sync::MissingDataInfo> v;
- v.push_back(mdi);
- {
- boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
- m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
- m_scene->msgReceived(QString::fromStdString(m_localChatPrefix.toUri()),
- QString::fromStdString(m_nick));
- }
-}
-
void ChatDialog::disableSyncTreeDisplay()
{
ui->syncTreeButton->setEnabled(false);
@@ -627,130 +201,61 @@
}
void
-ChatDialog::appendMessage(const SyncDemo::ChatMessage msg, bool isHistory)
+ChatDialog::appendChatMessage(const QString& nick, const QString& text, time_t timestamp)
{
- boost::recursive_mutex::scoped_lock lock(m_msgMutex);
+ QTextCharFormat nickFormat;
+ nickFormat.setForeground(Qt::darkGreen);
+ nickFormat.setFontWeight(QFont::Bold);
+ nickFormat.setFontUnderline(true);
+ nickFormat.setUnderlineColor(Qt::gray);
- if (msg.type() == SyncDemo::ChatMessage::CHAT) {
- if (!msg.has_data()) {
- return;
- }
+ // Print who & when
+ QTextCursor cursor(ui->textEdit->textCursor());
+ cursor.movePosition(QTextCursor::End);
+ QTextTableFormat tableFormat;
+ tableFormat.setBorder(0);
+ QTextTable *table = cursor.insertTable(1, 2, tableFormat);
+ QString from = QString("%1 ").arg(nick);
+ QTextTableCell fromCell = table->cellAt(0, 0);
+ fromCell.setFormat(nickFormat);
+ fromCell.firstCursorPosition().insertText(from);
+ printTimeInCell(table, timestamp);
- if (msg.from().empty() || msg.data().empty()) {
- return;
- }
+ // Print what
+ QTextCursor nextCursor(ui->textEdit->textCursor());
+ nextCursor.movePosition(QTextCursor::End);
+ table = nextCursor.insertTable(1, 1, tableFormat);
+ table->cellAt(0, 0).firstCursorPosition().insertText(text);
- if (!msg.has_timestamp()) {
- return;
- }
-
- // if (m_history.size() == MAX_HISTORY_ENTRY)
- // {
- // m_history.dequeue();
- // }
-
- // m_history.enqueue(msg);
-
- QTextCharFormat nickFormat;
- nickFormat.setForeground(Qt::darkGreen);
- nickFormat.setFontWeight(QFont::Bold);
- nickFormat.setFontUnderline(true);
- nickFormat.setUnderlineColor(Qt::gray);
-
- QTextCursor cursor(ui->textEdit->textCursor());
- cursor.movePosition(QTextCursor::End);
- QTextTableFormat tableFormat;
- tableFormat.setBorder(0);
- QTextTable *table = cursor.insertTable(1, 2, tableFormat);
- QString from = QString("%1 ").arg(msg.from().c_str());
- QTextTableCell fromCell = table->cellAt(0, 0);
- fromCell.setFormat(nickFormat);
- fromCell.firstCursorPosition().insertText(from);
-
- time_t timestamp = msg.timestamp();
- printTimeInCell(table, timestamp);
-
- QTextCursor nextCursor(ui->textEdit->textCursor());
- nextCursor.movePosition(QTextCursor::End);
- table = nextCursor.insertTable(1, 1, tableFormat);
- table->cellAt(0, 0).firstCursorPosition().insertText(QString::fromUtf8(msg.data().c_str()));
- if (!isHistory) {
- showMessage(from, QString::fromUtf8(msg.data().c_str()));
- }
- }
-
- if (msg.type() == SyncDemo::ChatMessage::JOIN || msg.type() == SyncDemo::ChatMessage::LEAVE) {
- QTextCharFormat nickFormat;
- nickFormat.setForeground(Qt::gray);
- nickFormat.setFontWeight(QFont::Bold);
- nickFormat.setFontUnderline(true);
- nickFormat.setUnderlineColor(Qt::gray);
-
- QTextCursor cursor(ui->textEdit->textCursor());
- cursor.movePosition(QTextCursor::End);
- QTextTableFormat tableFormat;
- tableFormat.setBorder(0);
- QTextTable *table = cursor.insertTable(1, 2, tableFormat);
- QString action;
- if (msg.type() == SyncDemo::ChatMessage::JOIN) {
- action = "enters room";
- }
- else {
- action = "leaves room";
- }
-
- QString from = QString("%1 %2 ").arg(msg.from().c_str()).arg(action);
- QTextTableCell fromCell = table->cellAt(0, 0);
- fromCell.setFormat(nickFormat);
- fromCell.firstCursorPosition().insertText(from);
-
- time_t timestamp = msg.timestamp();
- printTimeInCell(table, timestamp);
- }
+ // Popup notification
+ showMessage(from, text);
QScrollBar *bar = ui->textEdit->verticalScrollBar();
bar->setValue(bar->maximum());
}
void
-ChatDialog::processRemove(QString prefix)
+ChatDialog::appendControlMessage(const QString& nick,
+ const QString& action,
+ time_t timestamp)
{
- // _LOG_DEBUG("<<< remove node for prefix" << prefix.toStdString());
+ QTextCharFormat nickFormat;
+ nickFormat.setForeground(Qt::gray);
+ nickFormat.setFontWeight(QFont::Bold);
+ nickFormat.setFontUnderline(true);
+ nickFormat.setUnderlineColor(Qt::gray);
- bool removed = m_scene->removeNode(prefix);
- if (removed) {
- boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
- m_scene->plot(m_sock->getRootDigest().c_str());
- }
-}
+ QTextCursor cursor(ui->textEdit->textCursor());
+ cursor.movePosition(QTextCursor::End);
+ QTextTableFormat tableFormat;
+ tableFormat.setBorder(0);
+ QTextTable *table = cursor.insertTable(1, 2, tableFormat);
-Name
-ChatDialog::getInviteeRoutablePrefix(const Name& invitee)
-{
- return Name("/ndn/broadcast");
-}
-
-void
-ChatDialog::formChatMessage(const QString &text, SyncDemo::ChatMessage &msg) {
- msg.set_from(m_nick);
- msg.set_to(m_chatroomName);
- msg.set_data(text.toStdString());
- int32_t seconds =
- static_cast<int32_t>(time::toUnixTimestamp(time::system_clock::now()).count()/1000);
- msg.set_timestamp(seconds);
- msg.set_type(SyncDemo::ChatMessage::CHAT);
-}
-
-void
-ChatDialog::formControlMessage(SyncDemo::ChatMessage &msg,
- SyncDemo::ChatMessage::ChatMessageType type)
-{
- msg.set_from(m_nick);
- msg.set_to(m_chatroomName);
- int32_t seconds =
- static_cast<int32_t>(time::toUnixTimestamp(time::system_clock::now()).count()/1000);
- msg.set_timestamp(seconds);
- msg.set_type(type);
+ QString controlMsg = QString("%1 %2 ").arg(nick).arg(action);
+ QTextTableCell fromCell = table->cellAt(0, 0);
+ fromCell.setFormat(nickFormat);
+ fromCell.firstCursorPosition().insertText(controlMsg);
+ printTimeInCell(table, timestamp);
}
QString
@@ -788,21 +293,6 @@
timeCell.firstCursorPosition().insertText(formatTime(timestamp));
}
-string
-ChatDialog::getRandomString()
-{
- uint32_t r = ndn::random::generateWord32();
- std::stringstream ss;
- {
- using namespace CryptoPP;
- StringSource(reinterpret_cast<uint8_t*>(&r), 4, true,
- new HexEncoder(new FileSink(ss), false));
-
- }
-
- return ss.str();
-}
-
void
ChatDialog::showMessage(const QString& from, const QString& data)
{
@@ -814,7 +304,6 @@
void
ChatDialog::fitView()
{
- boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
QRectF rect = m_scene->itemsBoundingRect();
m_scene->setSceneRect(rect);
ui->syncTreeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
@@ -824,200 +313,8 @@
ui->trustTreeViewer->fitInView(m_trustScene->itemsBoundingRect(), Qt::KeepAspectRatio);
}
-void
-ChatDialog::summonReaper()
-{
- Sync::SyncLogic &logic = m_sock->getLogic ();
- map<string, bool> branches = logic.getBranchPrefixes();
- QMap<QString, DisplayUserPtr> roster = m_scene->getRosterFull();
-
- m_zombieList.clear();
-
- QMapIterator<QString, DisplayUserPtr> it(roster);
- map<string, bool>::iterator mapIt;
- while (it.hasNext()) {
- it.next();
- DisplayUserPtr p = it.value();
- if (p != DisplayUserNullPtr) {
- mapIt = branches.find(p->getPrefix().toStdString());
- if (mapIt != branches.end()) {
- mapIt->second = true;
- }
- }
- }
-
- for (mapIt = branches.begin(); mapIt != branches.end(); ++mapIt) {
- // this is zombie. all active users should have been marked true
- if (! mapIt->second) {
- m_zombieList.append(mapIt->first.c_str());
- }
- }
-
- m_zombieIndex = 0;
-
- // start reaping
- reap();
-}
-
-void
-ChatDialog::getTree(TrustTreeNodeList& nodeList)
-{
- typedef map<Name, shared_ptr<TrustTreeNode> > NodeMap;
-
- vector<Name> certNameList;
- NodeMap nodeMap;
-
- m_sock->getIntroCertNames(certNameList);
-
- for (vector<Name>::const_iterator it = certNameList.begin(); it != certNameList.end(); it++) {
- Name introducerCertName;
- Name introduceeCertName;
-
- introducerCertName.wireDecode(it->get(-2).blockFromValue());
- introduceeCertName.wireDecode(it->get(-3).blockFromValue());
-
- Name introducerName =
- IdentityCertificate::certificateNameToPublicKeyName(introducerCertName).getPrefix(-1);
- Name introduceeName =
- IdentityCertificate::certificateNameToPublicKeyName(introduceeCertName).getPrefix(-1);
-
- NodeMap::iterator introducerIt = nodeMap.find(introducerName);
- if (introducerIt == nodeMap.end()) {
- shared_ptr<TrustTreeNode> introducerNode(new TrustTreeNode(introducerName));
- nodeMap[introducerName] = introducerNode;
- }
- shared_ptr<TrustTreeNode> erNode = nodeMap[introducerName];
-
- NodeMap::iterator introduceeIt = nodeMap.find(introduceeName);
- if (introduceeIt == nodeMap.end()) {
- shared_ptr<TrustTreeNode> introduceeNode(new TrustTreeNode(introduceeName));
- nodeMap[introduceeName] = introduceeNode;
- }
- shared_ptr<TrustTreeNode> eeNode = nodeMap[introduceeName];
-
- erNode->addIntroducee(eeNode);
- eeNode->addIntroducer(erNode);
- }
-
- nodeList.clear();
- queue<shared_ptr<TrustTreeNode> > nodeQueue;
-
- NodeMap::iterator nodeIt = nodeMap.find(m_identity);
- if (nodeIt == nodeMap.end())
- return;
-
- nodeQueue.push(nodeIt->second);
- nodeIt->second->setLevel(0);
- while (!nodeQueue.empty()) {
- shared_ptr<TrustTreeNode>& node = nodeQueue.front();
- node->setVisited();
-
- TrustTreeNodeList& introducees = node->getIntroducees();
- for (TrustTreeNodeList::iterator eeIt = introducees.begin();
- eeIt != introducees.end(); eeIt++) {
- // _LOG_DEBUG("introducee: " << (*eeIt)->name() <<
- // " visited: " << std::boolalpha << (*eeIt)->visited());
- if (!(*eeIt)->visited()) {
- nodeQueue.push(*eeIt);
- (*eeIt)->setLevel(node->level()+1);
- }
- }
-
- nodeList.push_back(node);
- nodeQueue.pop();
- }
-}
-
-void
-ChatDialog::plotTrustTree()
-{
- TrustTreeNodeList nodeList;
-
- getTree(nodeList);
- {
- boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
- m_trustScene->plotTrustTree(nodeList);
- fitView();
- }
-}
-
-shared_ptr<ChatroomInfo>
-ChatDialog::getChatroomInfo() const
-{
- shared_ptr<ChatroomInfo> chatroom = make_shared<ChatroomInfo>();
- chatroom->setName(Name::Component(m_chatroomName));
-
- Roster roster = m_scene->getRosterFull();
- Roster_iterator it = roster.begin();
-
- for(it = roster.begin(); it != roster.end(); ++it )
- {
- Name participant = Name(it.key().toStdString()).getPrefix(-3);
- chatroom->addParticipant(participant);
- }
-
- chatroom->setTrustModel(m_trustModel);
- return chatroom;
-}
-
-
// public slots:
void
-ChatDialog::onLocalPrefixUpdated(const QString& localPrefix)
-{
- Name newLocalPrefix(localPrefix.toStdString());
- if (!newLocalPrefix.empty() && newLocalPrefix != m_localPrefix) {
- // Update localPrefix
- m_localPrefix = newLocalPrefix;
-
- updatePrefix();
- updateLabels();
- m_scene->setCurrentPrefix(QString(m_localChatPrefix.toUri().c_str()));
-
- if (m_sock != NULL) {
- {
- boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
- m_scene->clearAll();
- m_scene->plot("Empty");
- }
-
- ui->textEdit->clear();
-
- if (m_joined) {
- sendLeave();
- }
-
- delete m_sock;
- m_sock = NULL;
-
- usleep(100000);
- m_sock = new Sync::SyncSocket(m_chatroomPrefix,
- m_chatPrefix,
- m_session,
- m_useRoutablePrefix,
- m_localPrefix,
- m_face,
- m_myCertificate,
- m_dataRule,
- bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
- bind(&ChatDialog::processRemoveWrapper, this, _1));
- usleep(100000);
- QTimer::singleShot(600, this, SLOT(sendJoin()));
- m_timer->start(FRESHNESS * 1000);
- disableSyncTreeDisplay();
- QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
- }
- else
- initializeSync();
- }
- else
- if (m_sock == NULL)
- initializeSync();
-
- fitView();
-}
-
-void
ChatDialog::onShow()
{
this->show();
@@ -1026,42 +323,104 @@
}
void
-ChatDialog::onClose()
+ChatDialog::shutdown()
{
+ if (m_backend.isRunning()) {
+ emit shutdownBackend();
+ m_backend.wait();
+ }
hide();
emit closeChatDialog(QString::fromStdString(m_chatroomName));
}
-
// private slots:
void
+ChatDialog::updateSyncTree(std::vector<chronos::NodeInfo> updates, QString rootDigest)
+{
+ m_scene->processSyncUpdate(updates, rootDigest);
+}
+
+void
+ChatDialog::receiveChatMessage(QString nick, QString text, time_t timestamp)
+{
+ appendChatMessage(nick, text, timestamp);
+}
+
+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());
+}
+
+void
+ChatDialog::removeSession(QString sessionPrefix, QString nick, time_t timestamp)
+{
+ appendControlMessage(nick, "leaves room", timestamp);
+ m_scene->removeNode(sessionPrefix);
+ m_rosterModel->setStringList(m_scene->getRosterList());
+}
+
+void
+ChatDialog::updateNick(QString sessionPrefix, QString nick)
+{
+ m_scene->updateNick(sessionPrefix, nick);
+ m_rosterModel->setStringList(m_scene->getRosterList());
+}
+
+void
+ChatDialog::receiveMessage(QString sessionPrefix)
+{
+ m_scene->messageReceived(sessionPrefix);
+}
+
+void
+ChatDialog::updateLabels(Name newChatPrefix)
+{
+ // Reset DigestTree
+ m_scene->clearAll();
+ m_scene->plot("Empty");
+
+ // Display chatroom name
+ QString chatroomName = QString("Chatroom: %1").arg(QString::fromStdString(m_chatroomName));
+ ui->infoLabel->setStyleSheet("QLabel {color: #630; font-size: 16px; font: bold \"Verdana\";}");
+ ui->infoLabel->setText(chatroomName);
+
+ // Display chat message prefix
+ QString chatPrefix;
+ if (PRIVATE_PREFIX.isPrefixOf(newChatPrefix)) {
+ chatPrefix =
+ QString("<Warning: no connection to hub or hub does not support prefix autoconfig.>\n"
+ "<Prefix = %1>")
+ .arg(QString::fromStdString(newChatPrefix.toUri()));
+ ui->prefixLabel->setStyleSheet(
+ "QLabel {color: red; font-size: 12px; font: bold \"Verdana\";}");
+ }
+ else {
+ chatPrefix = QString("<Prefix = %1>")
+ .arg(QString::fromStdString(newChatPrefix.toUri()));
+ ui->prefixLabel->setStyleSheet(
+ "QLabel {color: Green; font-size: 12px; font: bold \"Verdana\";}");
+ }
+ ui->prefixLabel->setText(chatPrefix);
+}
+
+void
ChatDialog::onReturnPressed()
{
QString text = ui->lineEdit->text();
+
if (text.isEmpty())
return;
ui->lineEdit->clear();
- if (text.startsWith("boruoboluomi")) {
- summonReaper ();
- // reapButton->show();
- fitView();
- return;
- }
+ time_t timestamp =
+ static_cast<time_t>(time::toUnixTimestamp(time::system_clock::now()).count() / 1000);
+ // appendChatMessage(m_nick, text, timestamp);
- if (text.startsWith("minimanihong")) {
- // reapButton->hide();
- fitView();
- return;
- }
-
- SyncDemo::ChatMessage msg;
- formChatMessage(text, msg);
-
- appendMessage(msg);
-
- sendMsg(msg);
+ emit msgToSent(text, timestamp);
fitView();
}
@@ -1096,252 +455,11 @@
fitView();
}
-void
-ChatDialog::onProcessData(const ndn::shared_ptr<const ndn::Data>& data, bool show, bool isHistory)
-{
- SyncDemo::ChatMessage msg;
- bool corrupted = false;
- if (!msg.ParseFromArray(data->getContent().value(), data->getContent().value_size())) {
- // _LOG_DEBUG("Errrrr.. Can not parse msg with name: " <<
- // data->getName() << ". what is happening?");
- // nasty stuff: as a remedy, we'll form some standard msg for inparsable msgs
- msg.set_from("inconnu");
- msg.set_type(SyncDemo::ChatMessage::OTHER);
- corrupted = true;
- }
-
- //std::cout << "onProcessData: " << show << std::endl;
- //std::cout << "onProcessData: " << corrupted << std::endl;
-
- // display msg received from network
- // we have to do so; this function is called by ccnd thread
- // so if we call appendMsg directly
- // Qt crash as "QObject: Cannot create children for a parent that is in a different thread"
- // the "cannonical" way to is use signal-slot
- if (show && !corrupted) {
- appendMessage(msg, isHistory);
- }
-
- if (!isHistory) {
- // update the tree view
- string prefix = data->getName().getPrefix(-2).toUri();
- // _LOG_DEBUG("<<< updating scene for" << prefix << ": " << msg.from());
- if (msg.type() == SyncDemo::ChatMessage::LEAVE) {
- processRemove(prefix.c_str());
- }
- else {
- boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
- m_scene->msgReceived(prefix.c_str(), msg.from().c_str());
- }
- }
- fitView();
-}
-
-void
-ChatDialog::onProcessTreeUpdate(const vector<Sync::MissingDataInfo>& v)
-{
- _LOG_DEBUG("<<< processing Tree Update");
-
- if (v.empty()) {
- return;
- }
-
- // reflect the changes on digest tree
- {
- boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
- m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
- }
-
- int n = v.size();
- int totalMissingPackets = 0;
- for (int i = 0; i < n; i++) {
- totalMissingPackets += v[i].high.getSeq() - v[i].low.getSeq() + 1;
- }
-
- for (int i = 0; i < n; i++) {
- if (totalMissingPackets < 4) {
- for (Sync::SeqNo seq = v[i].low; seq <= v[i].high; ++seq) {
- m_sock->fetchData(v[i].prefix, seq, bind(&ChatDialog::processDataWrapper, this, _1), 2);
- _LOG_DEBUG("<<< Fetching " << v[i].prefix << "/" <<seq.getSession() <<"/" << seq.getSeq());
- }
- }
- else {
- m_sock->fetchData(v[i].prefix, v[i].high,
- bind(&ChatDialog::processDataNoShowWrapper, this, _1), 2);
- }
- }
- // adjust the view
- fitView();
-}
-
-void
-ChatDialog::onReplot()
-{
- boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
- m_scene->plot(m_sock->getRootDigest().c_str());
- fitView();
-}
-
-void
-ChatDialog::onRosterChanged(QStringList staleUserList)
-{
- boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
- QStringList rosterList = m_scene->getRosterList();
- m_rosterModel->setStringList(rosterList);
- QString user;
- QStringListIterator it(staleUserList);
- while (it.hasNext()) {
- string nick = it.next().toStdString();
- if (nick.empty())
- continue;
-
- SyncDemo::ChatMessage msg;
- formControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
- msg.set_from(nick);
- appendMessage(msg);
- }
- plotTrustTree();
-
- emit rosterChanged(*getChatroomInfo());
-}
-
-void
-ChatDialog::onInviteListDialogRequested()
-{
- emit waitForContactList();
- m_inviteListDialog->setInviteLabel(m_chatroomPrefix.toUri());
- m_inviteListDialog->show();
-}
-
-void
-ChatDialog::sendJoin()
-{
- m_joined = true;
- SyncDemo::ChatMessage msg;
- formControlMessage(msg, SyncDemo::ChatMessage::JOIN);
- sendMsg(msg);
- boost::random::random_device rng;
- boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
- m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
- QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
-}
-
-void
-ChatDialog::sendHello()
-{
- int64_t now = time::toUnixTimestamp(time::system_clock::now()).count();
- int elapsed = (now - m_lastMsgTime) / 1000;
- if (elapsed >= m_randomizedInterval / 1000) {
- SyncDemo::ChatMessage msg;
- formControlMessage(msg, SyncDemo::ChatMessage::HELLO);
- sendMsg(msg);
- boost::random::random_device rng;
- boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
- m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
- QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
- }
- else {
- QTimer::singleShot((m_randomizedInterval - elapsed * 1000), this, SLOT(sendHello()));
- }
-}
-
-void
-ChatDialog::sendLeave()
-{
- SyncDemo::ChatMessage msg;
- formControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
- sendMsg(msg);
- usleep(500000);
- m_sock->leave();
- usleep(5000);
- m_joined = false;
- // _LOG_DEBUG("Sync REMOVE signal sent");
-}
-
void ChatDialog::enableSyncTreeDisplay()
{
ui->syncTreeButton->setEnabled(true);
- // treeViewer->show();
- // fitView();
-}
-
-void
-ChatDialog::reap()
-{
- if (m_zombieIndex < m_zombieList.size()) {
- string prefix = m_zombieList.at(m_zombieIndex).toStdString();
- m_sock->remove(prefix);
- // _LOG_DEBUG("Reaped: prefix = " << prefix);
- m_zombieIndex++;
- // reap again in 10 seconds
- QTimer::singleShot(10000, this, SLOT(reap()));
- }
-}
-
-void
-ChatDialog::onSendInvitation(QString invitee)
-{
- Name inviteeNamespace(invitee.toStdString());
- shared_ptr<Contact> inviteeItem = m_contactManager->getContact(inviteeNamespace);
- sendInvitation(inviteeItem, true);
-}
-
-void
-ChatDialog::onReply(const Interest& interest,
- const shared_ptr<const Data>& data,
- size_t routablePrefixOffset,
- bool isIntroducer)
-{
- OnDataValidated onValidated = bind(&ChatDialog::onReplyValidated,
- this, _1,
- //RoutablePrefix will be removed before passing to validator
- interest.getName().size()-routablePrefixOffset,
- isIntroducer);
-
- OnDataValidationFailed onFailed = bind(&ChatDialog::onReplyValidationFailed,
- this, _1, _2);
-
- if (routablePrefixOffset > 0) {
- // It is an encapsulated packet, we only validate the inner packet.
- shared_ptr<Data> innerData = make_shared<Data>();
- innerData->wireDecode(data->getContent().blockFromValue());
- m_invitationValidator->validate(*innerData, onValidated, onFailed);
- }
- else
- m_invitationValidator->validate(*data, onValidated, onFailed);
-}
-
-void
-ChatDialog::onReplyTimeout(const ndn::Interest& interest,
- size_t routablePrefixOffset)
-{
- Name interestName;
- if (routablePrefixOffset > 0)
- interestName = interest.getName().getSubName(routablePrefixOffset);
- else
- interestName = interest.getName();
-
- Invitation invitation(interestName);
-
- QString msg = QString::fromUtf8("Your invitation to ") +
- QString::fromStdString(invitation.getInviteeNameSpace().toUri()) + " times out!";
- emit inivationRejection(msg);
-}
-
-void
-ChatDialog::onIntroCert(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data)
-{
- Data innerData;
- innerData.wireDecode(data->getContent().blockFromValue());
- Sync::IntroCertificate introCert(innerData);
- m_sock->addParticipant(introCert);
- plotTrustTree();
-}
-
-void
-ChatDialog::onIntroCertTimeout(const ndn::Interest& interest, int retry, const QString& msg)
-{
- // _LOG_DEBUG("onIntroCertTimeout: " << msg.toStdString());
+ ui->syncTreeViewer->show();
+ fitView();
}
} // namespace chronos
diff --git a/src/chat-dialog.hpp b/src/chat-dialog.hpp
index 7c63b30..7f1a726 100644
--- a/src/chat-dialog.hpp
+++ b/src/chat-dialog.hpp
@@ -20,30 +20,16 @@
#include <QTimer>
#ifndef Q_MOC_RUN
-#include "common.hpp"
-#include "contact-manager.hpp"
#include "invitation.hpp"
-#include "contact.hpp"
-#include "chatbuf.pb.h"
-#include "intro-cert-list.pb.h"
+
#include "digest-tree-scene.hpp"
#include "trust-tree-scene.hpp"
#include "trust-tree-node.hpp"
-#include "validator-invitation.hpp"
-#include <sync-socket.h>
-#include <sync-seq-no.h>
-#include <ndn-cxx/security/key-chain.hpp>
-#include <boost/thread/locks.hpp>
-#include <boost/thread/recursive_mutex.hpp>
-#include <boost/thread/thread.hpp>
+#include "chat-dialog-backend.hpp"
+
#include "chatroom-info.hpp"
#endif
-#include "invite-list-dialog.hpp"
-
-
-#define MAX_HISTORY_ENTRY 20
-
namespace Ui {
class ChatDialog;
}
@@ -56,37 +42,17 @@
public:
explicit
- ChatDialog(ContactManager* contactManager,
- shared_ptr<ndn::Face> face,
- const ndn::IdentityCertificate& myCertificate,
- const Name& chatroomPrefix,
- const Name& localPrefix,
+ ChatDialog(const Name& chatroomPrefix,
+ const Name& userChatPrefix,
+ const Name& routingPrefix,
+ const std::string& chatroomName,
const std::string& nick,
- bool witSecurity,
+ bool isSecured = false,
QWidget* parent = 0);
~ChatDialog();
void
- addSyncAnchor(const Invitation& invitation);
-
- void
- processTreeUpdateWrapper(const std::vector<Sync::MissingDataInfo>&, Sync::SyncSocket *);
-
- void
- processDataWrapper(const shared_ptr<const Data>& data);
-
- void
- processDataNoShowWrapper(const shared_ptr<const Data>& data);
-
- void
- processRemoveWrapper(const std::string& prefix);
-
- //ymj
- shared_ptr<ChatroomInfo>
- getChatroomInfo() const;
-
- void
closeEvent(QCloseEvent* e);
void
@@ -98,91 +64,29 @@
void
showEvent(QShowEvent* e);
+ ChatDialogBackend*
+ getBackend()
+ {
+ return &m_backend;
+ }
+
+ void
+ addSyncAnchor(const Invitation& invitation)
+ {
+ }
+
+ shared_ptr<ChatroomInfo>
+ getChatroomInfo();
+
private:
void
- updatePrefix();
-
- void
- updateLabels();
-
- void
- initializeSync();
-
- void
- sendInvitation(shared_ptr<Contact> contact, bool isIntroducer);
-
- void
- replyWrapper(const Interest& interest, Data& data,
- size_t routablePrefixOffset, bool isIntroducer);
-
- void
- replyTimeoutWrapper(const Interest& interest,
- size_t routablePrefixOffset);
-
- void
- onReplyValidated(const ndn::shared_ptr<const ndn::Data>& data,
- size_t inviteeRoutablePrefixOffset,
- bool isIntroduce);
-
- void
- onReplyValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
- const std::string& failureInfo);
-
- void
- invitationRejected(const Name& identity);
-
- void
- invitationAccepted(const ndn::IdentityCertificate& inviteeCert,
- const Name& inviteePrefix, bool isIntroducer);
-
- void
- fetchIntroCert(const Name& identity, const Name& prefix);
-
- void
- onIntroCertList(const Interest& interest, const Data& data);
-
- void
- onIntroCertListTimeout(const Interest& interest, int retry, const std::string& msg);
-
- void
- introCertWrapper(const Interest& interest, Data& data);
-
- void
- introCertTimeoutWrapper(const Interest& interest, int retry, const QString& msg);
-
- void
- onCertListInterest(const ndn::Name& prefix, const ndn::Interest& interest);
-
- void
- onCertListRegisterFailed(const ndn::Name& prefix, const std::string& msg);
-
- void
- onCertSingleInterest(const Name& prefix, const Interest& interest);
-
- void
- onCertSingleRegisterFailed(const Name& prefix, const std::string& msg);
-
-
- void
- sendMsg(SyncDemo::ChatMessage& msg);
-
- void
disableSyncTreeDisplay();
void
- appendMessage(const SyncDemo::ChatMessage msg, bool isHistory = false);
+ appendChatMessage(const QString& nick, const QString& text, time_t timestamp);
void
- processRemove(QString prefix);
-
- ndn::Name
- getInviteeRoutablePrefix(const Name& invitee);
-
- void
- formChatMessage(const QString& text, SyncDemo::ChatMessage& msg);
-
- void
- formControlMessage(SyncDemo::ChatMessage &msg, SyncDemo::ChatMessage::ChatMessageType type);
+ appendControlMessage(const QString& nick, const QString& action, time_t timestamp);
QString
formatTime(time_t timestamp);
@@ -190,61 +94,29 @@
void
printTimeInCell(QTextTable* table, time_t timestamp);
- std::string
- getRandomString();
-
void
showMessage(const QString&, const QString&);
void
fitView();
- void
- summonReaper();
-
- void
- getTree(TrustTreeNodeList& nodeList);
-
- void
- plotTrustTree();
-
signals:
void
- processData(const ndn::shared_ptr<const ndn::Data>& data,
- bool show, bool isHistory);
+ shutdownBackend();
void
- processTreeUpdate(const std::vector<Sync::MissingDataInfo>);
+ msgToSent(QString text, time_t timestamp);
void
closeChatDialog(const QString& chatroomName);
void
- inivationRejection(const QString& msg);
-
- void
showChatMessage(const QString& chatroomName, const QString& from, const QString& data);
void
resetIcon();
void
- reply(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data,
- size_t routablePrefixOffset, bool isIntroducer);
-
- void
- replyTimeout(const ndn::Interest& interest, size_t routablePrefixOffset);
-
- void
- introCert(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data);
-
- void
- introCertTimeout(const ndn::Interest& interest, int retry, const QString& msg);
-
- void
- waitForContactList();
-
- void
rosterChanged(const chronos::ChatroomInfo& info);
public slots:
@@ -252,13 +124,31 @@
onShow();
void
- onLocalPrefixUpdated(const QString& localPrefix);
-
- void
- onClose();
+ shutdown();
private slots:
void
+ updateSyncTree(std::vector<chronos::NodeInfo> updates, QString rootDigest);
+
+ void
+ 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);
+
+ void
+ updateLabels(ndn::Name newChatPrefix);
+
+ void
onReturnPressed();
void
@@ -268,97 +158,21 @@
onTrustTreeButtonPressed();
void
- onProcessData(const ndn::shared_ptr<const ndn::Data>& data, bool show, bool isHistory);
-
- void
- onProcessTreeUpdate(const std::vector<Sync::MissingDataInfo>&);
-
- void
- onReplot();
-
- void
- onRosterChanged(QStringList staleUserList);
-
- void
- onInviteListDialogRequested();
-
- void
- sendJoin();
-
- void
- sendHello();
-
- void
- sendLeave();
-
- void
enableSyncTreeDisplay();
- void
- reap();
-
- void
- onSendInvitation(QString invitee);
-
- void
- onReply(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data,
- size_t routablePrefixOffset, bool isIntroducer);
-
- void
- onReplyTimeout(const ndn::Interest& interest, size_t routablePrefixOffset);
-
- void
- onIntroCert(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data);
-
- void
- onIntroCertTimeout(const ndn::Interest& interest, int retry, const QString& msg);
-
private:
- Ui::ChatDialog *ui;
- ndn::KeyChain m_keyChain;
+ Ui::ChatDialog* ui;
- ContactManager* m_contactManager;
- shared_ptr<ndn::Face> m_face;
-
- ndn::IdentityCertificate m_myCertificate;
- Name m_identity;
-
- Name m_certListPrefix;
- const ndn::RegisteredPrefixId* m_certListPrefixId;
- Name m_certSinglePrefix;
- const ndn::RegisteredPrefixId* m_certSinglePrefixId;
+ ChatDialogBackend m_backend;
std::string m_chatroomName;
- Name m_chatroomPrefix;
- Name m_localPrefix;
- bool m_useRoutablePrefix;
- Name m_chatPrefix;
- Name m_localChatPrefix;
- std::string m_nick;
- DigestTreeScene *m_scene;
- TrustTreeScene *m_trustScene;
- QStringListModel *m_rosterModel;
- QTimer* m_timer;
+ QString m_nick;
+ bool m_isSecured;
- int64_t m_lastMsgTime;
- int m_randomizedInterval;
- bool m_joined;
-
- Sync::SyncSocket *m_sock;
- uint64_t m_session;
- shared_ptr<ndn::SecRuleRelative> m_dataRule;
-
- InviteListDialog* m_inviteListDialog;
- shared_ptr<ValidatorInvitation> m_invitationValidator;
-
- boost::recursive_mutex m_msgMutex;
- boost::recursive_mutex m_sceneMutex;
- QList<QString> m_zombieList;
- int m_zombieIndex;
-
- //ymj
- ChatroomInfo::TrustModel m_trustModel;
+ DigestTreeScene* m_scene;
+ TrustTreeScene* m_trustScene;
+ QStringListModel* m_rosterModel;
};
} // namespace chronos
diff --git a/src/controller.cpp b/src/controller.cpp
index d99b7a6..b52c188 100644
--- a/src/controller.cpp
+++ b/src/controller.cpp
@@ -19,6 +19,7 @@
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include <ndn-cxx/util/random.hpp>
+#include "invitation.hpp"
#include "cryptopp.hpp"
#include "config.pb.h"
#include "endorse-info.pb.h"
@@ -547,9 +548,9 @@
connect(chatDialog, SIGNAL(rosterChanged(const chronos::ChatroomInfo&)),
this, SLOT(onRosterChanged(const chronos::ChatroomInfo&)));
connect(this, SIGNAL(localPrefixUpdated(const QString&)),
- chatDialog, SLOT(onLocalPrefixUpdated(const QString&)));
+ chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&)));
connect(this, SIGNAL(localPrefixConfigured(const QString&)),
- chatDialog, SLOT(onLocalPrefixUpdated(const QString&)));
+ chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&)));
QAction* chatAction = new QAction(chatroomName, this);
m_chatActionList[chatroomName.toStdString()] = chatAction;
@@ -558,7 +559,8 @@
QAction* closeAction = new QAction(chatroomName, this);
m_closeActionList[chatroomName.toStdString()] = closeAction;
- connect(closeAction, SIGNAL(triggered()), chatDialog, SLOT(onClose()));
+ connect(closeAction, SIGNAL(triggered()),
+ chatDialog, SLOT(shutdown()));
updateMenu();
}
@@ -734,7 +736,7 @@
{
while (!m_chatDialogList.empty()) {
ChatDialogList::const_iterator it = m_chatDialogList.begin();
- onRemoveChatDialog(QString::fromStdString(it->first));
+ it->second->shutdown();
}
if (m_invitationListenerId != 0)
@@ -775,9 +777,16 @@
// std::cout << "start chat room localprefix: " << m_localPrefix.toUri() << std::endl;
shared_ptr<IdentityCertificate> idCert
= m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(m_identity));
+
+ Name chatPrefix;
+ chatPrefix.append(m_identity).append("CHRONOCHAT-DATA").append(chatroomName.toStdString());
+
ChatDialog* chatDialog
- = new ChatDialog(&m_contactManager, m_face, *idCert, chatroomPrefix
- , m_localPrefix, m_nick, secured);
+ = new ChatDialog(chatroomPrefix,
+ chatPrefix,
+ m_localPrefix,
+ chatroomName.toStdString(),
+ m_nick);
addChatDialog(chatroomName, chatDialog);
chatDialog->show();
@@ -845,9 +854,18 @@
//but let's use the default one for now.
shared_ptr<IdentityCertificate> idCert
= m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(m_identity));
+
+ Name chatPrefix;
+ chatPrefix.append(m_identity).append("CHRONOCHAT-DATA").append(invitation.getChatroom());
+
ChatDialog* chatDialog
- = new ChatDialog(&m_contactManager, m_face, *idCert,
- chatroomPrefix, m_localPrefix, m_nick, true);
+ = new ChatDialog(chatroomPrefix,
+ chatPrefix,
+ m_localPrefix,
+ invitation.getChatroom(),
+ m_nick,
+ true);
+
chatDialog->addSyncAnchor(invitation);
addChatDialog(QString::fromStdString(invitation.getChatroom()), chatDialog);
diff --git a/src/digest-tree-scene.cpp b/src/digest-tree-scene.cpp
index 07e5dea..e7adba9 100644
--- a/src/digest-tree-scene.cpp
+++ b/src/digest-tree-scene.cpp
@@ -24,55 +24,52 @@
namespace chronos {
static const double Pi = 3.14159265358979323846264338327950288419717;
+static const int NODE_SIZE = 40;
//DisplayUserPtr DisplayUserNullPtr;
DigestTreeScene::DigestTreeScene(QWidget *parent)
: QGraphicsScene(parent)
{
- previouslyUpdatedUser = DisplayUserNullPtr;
+ m_previouslyUpdatedUser = DisplayUserNullPtr;
}
void
-DigestTreeScene::processUpdate(const std::vector<Sync::MissingDataInfo> &v, QString digest)
+DigestTreeScene::processSyncUpdate(const std::vector<chronos::NodeInfo>& nodeInfos,
+ const QString& digest)
{
- int n = v.size();
- bool rePlot = false;
- for (int i = 0; i < n; i++) {
- QString routablePrefix(v[i].prefix.c_str());
- QString prefix = trimRoutablePrefix(routablePrefix);
+ m_rootDigest = digest;
- Roster_iterator it = m_roster.find(prefix);
+ bool rePlot = false;
+
+ // Update roster info
+ for (int i = 0; i < nodeInfos.size(); i++) {
+ Roster_iterator it = m_roster.find(nodeInfos[i].sessionPrefix);
if (it == m_roster.end()) {
- // std::cout << "processUpdate v[" << i << "]: " << prefix.toStdString() << std::endl;
rePlot = true;
+
DisplayUserPtr p(new DisplayUser());
- time_t tempTime = ::time(0) + 1;
- p->setReceived(tempTime);
- p->setPrefix(prefix);
- p->setSeq(v[i].high);
+ p->setPrefix(nodeInfos[i].sessionPrefix);
+ p->setSeq(nodeInfos[i].seqNo);
m_roster.insert(p->getPrefix(), p);
}
else {
- it.value()->setSeq(v[i].high);
+ it.value()->setSeq(nodeInfos[i].seqNo);
}
}
- if (rePlot) {
- plot(digest);
- QTimer::singleShot(2100, this, SLOT(emitReplot()));
- }
+ if (rePlot)
+ // If new nodes exist, we need to re-arrange node
+ plot(m_rootDigest);
else {
- for (int i = 0; i < n; i++) {
- QString routablePrefix(v[i].prefix.c_str());
- QString prefix = trimRoutablePrefix(routablePrefix);
-
- Roster_iterator it = m_roster.find(prefix);
+ // No new node, update seqNo & digest
+ for (int 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().getSeq());
+ std::string s = boost::lexical_cast<std::string>(p->getSeqNo());
item->setPlainText(s.c_str());
QRectF textBR = item->boundingRect();
QRectF rectBR = rectItem->boundingRect();
@@ -80,14 +77,57 @@
rectBR.y() + (rectBR.height() - textBR.height())/2);
}
}
- m_rootDigest->setPlainText(digest);
+ m_displayRootDigest->setPlainText(digest);
}
}
void
-DigestTreeScene::emitReplot()
+DigestTreeScene::updateNick(QString sessionPrefix, QString nick)
{
- emit replot();
+ Roster_iterator it = m_roster.find(sessionPrefix);
+ if (it != m_roster.end()) {
+ DisplayUserPtr p = it.value();
+ if (nick != p->getNick()) {
+ p->setNick(nick);
+ QGraphicsTextItem *nickItem = p->getNickTextItem();
+ QGraphicsRectItem *nickRectItem = p->getNickRectItem();
+ nickItem->setPlainText(p->getNick());
+ QRectF rectBR = nickRectItem->boundingRect();
+ QRectF nickBR = nickItem->boundingRect();
+ nickItem->setPos(rectBR.x() + (rectBR.width() - nickBR.width())/2, rectBR.y() + 5);
+ }
+ }
+}
+
+void
+DigestTreeScene::messageReceived(QString sessionPrefix)
+{
+ Roster_iterator it = m_roster.find(sessionPrefix);
+ if (it != m_roster.end()) {
+ DisplayUserPtr p = it.value();
+
+ reDrawNode(p, Qt::red);
+
+ if (m_previouslyUpdatedUser != DisplayUserNullPtr && m_previouslyUpdatedUser != p) {
+ reDrawNode(m_previouslyUpdatedUser, Qt::darkBlue);
+ }
+
+ m_previouslyUpdatedUser = p;
+ }
+}
+
+void
+DigestTreeScene::clearAll()
+{
+ clear();
+ m_roster.clear();
+}
+
+void
+DigestTreeScene::removeNode(const QString sessionPrefix)
+{
+ m_roster.remove(sessionPrefix);
+ plot(m_rootDigest);
}
QStringList
@@ -105,117 +145,36 @@
return rosterList;
}
-void
-DigestTreeScene::msgReceived(QString routablePrefix, QString nick)
+QStringList
+DigestTreeScene::getRosterPrefixList()
{
- QString prefix = trimRoutablePrefix(routablePrefix);
- Roster_iterator it = m_roster.find(prefix);
- // std::cout << "msgReceived prefix: " << prefix.toStdString() << std::endl;
- if (it != m_roster.end()) {
- // std::cout << "Updating for prefix = " << prefix.toStdString() <<
- // " nick = " << nick.toStdString() << std::endl;
- DisplayUserPtr p = it.value();
- p->setReceived(::time(0) + 1);
- if (nick != p->getNick()) {
- // std::cout << "old nick = " << p->getNick().toStdString() << std::endl;
- p->setNick(nick);
- QGraphicsTextItem *nickItem = p->getNickTextItem();
- QGraphicsRectItem *nickRectItem = p->getNickRectItem();
- nickItem->setPlainText(p->getNick());
- QRectF rectBR = nickRectItem->boundingRect();
- QRectF nickBR = nickItem->boundingRect();
- nickItem->setPos(rectBR.x() + (rectBR.width() - nickBR.width())/2, rectBR.y() + 5);
- emit rosterChanged(QStringList());
- }
-
- reDrawNode(p, Qt::red);
-
- if (previouslyUpdatedUser != DisplayUserNullPtr && previouslyUpdatedUser != p) {
- reDrawNode(previouslyUpdatedUser, Qt::darkBlue);
- }
-
- previouslyUpdatedUser = p;
- }
-}
-
-void
-DigestTreeScene::clearAll()
-{
- clear();
- m_roster.clear();
-}
-
-bool
-DigestTreeScene::removeNode(const QString prefix)
-{
- int removedCount = m_roster.remove(prefix);
- return (removedCount > 0);
-}
-
-void
-DigestTreeScene::plot(QString digest)
-{
-#ifdef _DEBUG
- std::cout << "Plotting at time: " << ::time(NULL) << std::endl;
-#endif
- clear();
-
- int nodeSize = 40;
-
- int siblingDistance = 100, levelDistance = 100;
- std::auto_ptr<TreeLayout> layout(new OneLevelTreeLayout());
- layout->setSiblingDistance(siblingDistance);
- layout->setLevelDistance(levelDistance);
-
- // do some cleaning, get rid of stale member info
- Roster_iterator it = m_roster.begin();
- QStringList staleUserList;
- while (it != m_roster.end()) {
+ QStringList prefixList;
+ RosterIterator it(m_roster);
+ while (it.hasNext()) {
+ it.next();
DisplayUserPtr p = it.value();
if (p != DisplayUserNullPtr) {
- time_t now = ::time(NULL);
- if (now - p->getReceived() >= FRESHNESS) {
-#ifdef _DEBUG
- std::cout << "Removing user: " << p->getNick().toStdString() << std::endl;
- std::cout << "now - last = " << now - p->getReceived() << std::endl;
-#endif
- staleUserList << p->getNick();
- p = DisplayUserNullPtr;
- it = m_roster.erase(it);
- }
- else {
- if (!m_currentPrefix.startsWith("/private/local") &&
- p->getPrefix().startsWith("/private/local")) {
-#ifdef _DEBUG
- std::cout << "erasing: " << p->getPrefix().toStdString() << std::endl;
-#endif
- staleUserList << p->getNick();
- p = DisplayUserNullPtr;
- it = m_roster.erase(it);
- continue;
- }
- ++it;
- }
- }
- else {
- it = m_roster.erase(it);
+ prefixList << "- " + p->getPrefix();
}
}
+ return prefixList;
+}
- // for simpicity here, whenever we replot, we also redo the roster list
- emit rosterChanged(staleUserList);
+void
+DigestTreeScene::plot(QString rootDigest)
+{
+ clear();
- int n = m_roster.size();
+ shared_ptr<TreeLayout> layout(new OneLevelTreeLayout());
+ layout->setSiblingDistance(100);
+ layout->setLevelDistance(100);
- std::vector<TreeLayout::Coordinate> childNodesCo(n);
-
+ std::vector<TreeLayout::Coordinate> childNodesCo(m_roster.size());
layout->setOneLevelLayout(childNodesCo);
+ plotEdge(childNodesCo, NODE_SIZE);
+ plotNode(childNodesCo, rootDigest, NODE_SIZE);
- plotEdge(childNodesCo, nodeSize);
- plotNode(childNodesCo, digest, nodeSize);
-
- previouslyUpdatedUser = DisplayUserNullPtr;
-
+ m_previouslyUpdatedUser = DisplayUserNullPtr;
}
void
@@ -266,7 +225,7 @@
digestItem->setFont(QFont("Cursive", 12, QFont::Bold));
digestItem->setPos(- 4.5 * nodeSize + (12 * nodeSize - digestBoundingRect.width()) / 2,
- nodeSize + 5);
- m_rootDigest = digestItem;
+ m_displayRootDigest = digestItem;
// plot child nodes
for (int i = 0; i < n; i++) {
@@ -288,7 +247,7 @@
QBrush(Qt::lightGray));
p->setInnerRectItem(innerRectItem);
- std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
+ std::string s = boost::lexical_cast<std::string>(p->getSeqNo());
QGraphicsTextItem *seqItem = addText(s.c_str());
seqItem->setFont(QFont("Cursive", 12, QFont::Bold));
QRectF seqBoundingRect = seqItem->boundingRect();
@@ -317,7 +276,7 @@
QGraphicsRectItem *innerItem = p->getInnerRectItem();
innerItem->setBrush(QBrush(Qt::lightGray));
QGraphicsTextItem *seqTextItem = p->getSeqTextItem();
- std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
+ std::string s = boost::lexical_cast<std::string>(p->getSeqNo());
seqTextItem->setPlainText(s.c_str());
QRectF textBR = seqTextItem->boundingRect();
QRectF innerBR = innerItem->boundingRect();
@@ -325,26 +284,6 @@
innerBR.y() + (innerBR.height() - textBR.height())/2);
}
-QString
-DigestTreeScene::trimRoutablePrefix(QString prefix)
-{
- bool encaped = false;
- ndn::Name prefixName(prefix.toStdString());
-
- size_t offset = 0;
- for (ndn::Name::const_iterator it = prefixName.begin(); it != prefixName.end(); it++, offset++) {
- if (it->toUri() == "%F0.") {
- encaped = true;
- break;
- }
- }
-
- if (!encaped)
- return prefix;
- else
- return QString(prefixName.getSubName(offset+1).toUri().c_str());
-}
-
} // namespace chronos
#if WAF
diff --git a/src/digest-tree-scene.hpp b/src/digest-tree-scene.hpp
index 138f7f4..51847dc 100644
--- a/src/digest-tree-scene.hpp
+++ b/src/digest-tree-scene.hpp
@@ -18,8 +18,8 @@
#ifndef Q_MOC_RUN
#include "tree-layout.hpp"
-#include <sync-seq-no.h>
-#include <sync-logic.h>
+#include "chat-dialog-backend.hpp"
+#include <Leaf.hpp>
#include <ctime>
#include <vector>
#include <boost/shared_ptr.hpp>
@@ -49,44 +49,29 @@
DigestTreeScene(QWidget *parent = 0);
void
- processUpdate(const std::vector<Sync::MissingDataInfo>& v, QString digest);
+ processSyncUpdate(const std::vector<chronos::NodeInfo>& nodeInfos,
+ const QString& digest);
void
- msgReceived(QString prefix, QString nick);
+ updateNick(QString sessionPrefix, QString nick);
+
+ void
+ messageReceived(QString sessionPrefix);
void
clearAll();
- bool
- removeNode(const QString prefix);
-
void
- plot(QString digest);
+ removeNode(const QString sessionPrefix);
QStringList
getRosterList();
- void
- setCurrentPrefix(QString prefix)
- {
- m_currentPrefix = prefix;
- }
-
- QMap<QString, DisplayUserPtr> getRosterFull()
- {
- return m_roster;
- }
-
-signals:
- void
- replot();
+ QStringList
+ getRosterPrefixList();
void
- rosterChanged(QStringList);
-
-private slots:
- void
- emitReplot();
+ plot(QString rootDigest);
private:
void
@@ -98,29 +83,25 @@
void
reDrawNode(DisplayUserPtr p, QColor rimColor);
- QString
- trimRoutablePrefix(QString prefix);
-
private:
Roster m_roster;
- QGraphicsTextItem* m_rootDigest;
- DisplayUserPtr previouslyUpdatedUser;
- QString m_currentPrefix;
+
+ QString m_rootDigest;
+ QGraphicsTextItem* m_displayRootDigest;
+
+ DisplayUserPtr m_previouslyUpdatedUser;
};
class User
{
public:
User()
- :m_received(::time(NULL))
{
}
- User(QString n, QString p, QString c)
+ User(QString n, QString p)
: m_nick(n)
, m_prefix(p)
- , m_chatroom(c)
- , m_received(::time(NULL))
{
}
@@ -137,29 +118,11 @@
}
void
- setChatroom(QString chatroom)
- {
- m_chatroom = chatroom;
- }
-
- void
- setSeq(Sync::SeqNo seq)
+ setSeq(chronosync::SeqNo seq)
{
m_seq = seq;
}
- void
- setReceived(time_t t)
- {
- m_received = t;
- }
-
- void
- setOriginPrefix(QString originPrefix)
- {
- m_originPrefix = originPrefix;
- }
-
QString
getNick()
{
@@ -171,34 +134,16 @@
return m_prefix;
}
- QString getChatroom()
- {
- return m_chatroom;
- }
-
- QString getOriginPrefix()
- {
- return m_originPrefix;
- }
-
- Sync::SeqNo
+ chronosync::SeqNo
getSeqNo()
{
return m_seq;
}
- time_t getReceived()
- {
- return m_received;
- }
-
private:
QString m_nick;
QString m_prefix;
- QString m_chatroom;
- QString m_originPrefix;
- Sync::SeqNo m_seq;
- time_t m_received;
+ chronosync::SeqNo m_seq;
};
class DisplayUser : public User
@@ -211,8 +156,8 @@
{
}
- DisplayUser(QString n, QString p , QString c)
- : User(n, p, c)
+ DisplayUser(QString n, QString p)
+ : User(n, p)
, m_seqTextItem(NULL)
, m_nickTextItem(NULL)
, m_rimRectItem(NULL)