discovery: Add hierarchical model for chatroom invitation
Change-Id: I19e74745a5998fe075a373357df542fef317ae5f
diff --git a/src/chat-dialog-backend.cpp b/src/chat-dialog-backend.cpp
index 354b9bd..801db7d 100644
--- a/src/chat-dialog-backend.cpp
+++ b/src/chat-dialog-backend.cpp
@@ -25,7 +25,8 @@
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.
+static const ndn::Name::Component ROUTING_HINT_SEPARATOR =
+ ndn::name::Component::fromEscapedString("%F0%2E");
static const int IDENTITY_OFFSET = -3;
ChatDialogBackend::ChatDialogBackend(const Name& chatroomPrefix,
@@ -446,7 +447,7 @@
m_routableUserChatPrefix = m_userChatPrefix;
else
m_routableUserChatPrefix.append(m_localRoutingPrefix)
- .append(ROUTING_HINT_SEPARATOR, 2)
+ .append(ROUTING_HINT_SEPARATOR)
.append(m_userChatPrefix);
emit chatPrefixChanged(m_routableUserChatPrefix);
diff --git a/src/chat-dialog.cpp b/src/chat-dialog.cpp
index e993294..3f6070e 100644
--- a/src/chat-dialog.cpp
+++ b/src/chat-dialog.cpp
@@ -24,7 +24,8 @@
namespace chronochat {
static const Name PRIVATE_PREFIX("/private/local");
-static const uint8_t ROUTING_HINT_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.
+static const ndn::Name::Component ROUTING_HINT_SEPARATOR =
+ ndn::name::Component::fromEscapedString("%F0%2E");
ChatDialog::ChatDialog(const Name& chatroomPrefix,
const Name& userChatPrefix,
@@ -68,7 +69,7 @@
routablePrefix = userChatPrefix;
else
routablePrefix.append(routingPrefix)
- .append(ROUTING_HINT_SEPARATOR, 2)
+ .append(ROUTING_HINT_SEPARATOR)
.append(userChatPrefix);
updateLabels(routablePrefix);
diff --git a/src/chatroom-discovery-backend.cpp b/src/chatroom-discovery-backend.cpp
index e7ed3ea..933a2f1 100644
--- a/src/chatroom-discovery-backend.cpp
+++ b/src/chatroom-discovery-backend.cpp
@@ -21,7 +21,8 @@
static const time::milliseconds FRESHNESS_PERIOD(60000);
static const time::seconds REFRESH_INTERVAL(60);
static const time::seconds HELLO_INTERVAL(60);
-static const uint8_t ROUTING_HINT_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.
+static const ndn::Name::Component ROUTING_HINT_SEPARATOR =
+ ndn::name::Component::fromEscapedString("%F0%2E");
// a count enforced when a manager himself find another one publish chatroom data
static const int MAXIMUM_COUNT = 3;
static const int IDENTITY_OFFSET = -1;
@@ -249,7 +250,7 @@
temp = m_userDiscoveryPrefix;
else
temp.append(m_routingPrefix)
- .append(ROUTING_HINT_SEPARATOR, 2)
+ .append(ROUTING_HINT_SEPARATOR)
.append(m_userDiscoveryPrefix);
Name routableIdentity = m_routableUserDiscoveryPrefix.getPrefix(IDENTITY_OFFSET);
@@ -432,7 +433,7 @@
{
auto chatroom = m_chatroomList.find(Name::Component(chatroomName.toStdString()));
if (chatroom != m_chatroomList.end())
- emit chatroomInfoReady(chatroom->second.info);
+ emit chatroomInfoReady(chatroom->second.info, chatroom->second.isParticipant);
}
void
diff --git a/src/chatroom-discovery-backend.hpp b/src/chatroom-discovery-backend.hpp
index fe5e211..986c3a1 100644
--- a/src/chatroom-discovery-backend.hpp
+++ b/src/chatroom-discovery-backend.hpp
@@ -119,9 +119,10 @@
* @brief send chatroom info to front end
*
* @param info the chatroom info request by front end
+ * @param isParticipant if the user is a participant of the chatroom
*/
void
- chatroomInfoReady(const ChatroomInfo& info);
+ chatroomInfoReady(const ChatroomInfo& info, bool isParticipant);
public slots:
diff --git a/src/controller-backend.cpp b/src/controller-backend.cpp
index 804716b..217228e 100644
--- a/src/controller-backend.cpp
+++ b/src/controller-backend.cpp
@@ -28,7 +28,9 @@
using ndn::OnInterestValidationFailed;
-static const uint8_t ROUTING_PREFIX_SEPARATOR[2] = {0xF0, 0x2E};
+static const ndn::Name::Component ROUTING_HINT_SEPARATOR =
+ ndn::name::Component::fromEscapedString("%F0%2E");
+static const int MAXIMUM_REQUEST = 3;
ControllerBackend::ControllerBackend(QObject* parent)
: QThread(parent)
@@ -92,13 +94,16 @@
QMutexLocker locker(&m_mutex);
Name invitationPrefix;
+ Name requestPrefix;
Name routingPrefix = getInvitationRoutingPrefix();
size_t offset = 0;
if (!routingPrefix.isPrefixOf(m_identity)) {
- invitationPrefix.append(routingPrefix).append(ROUTING_PREFIX_SEPARATOR, 2);
+ invitationPrefix.append(routingPrefix).append(ROUTING_HINT_SEPARATOR);
+ requestPrefix.append(routingPrefix).append(ROUTING_HINT_SEPARATOR);
offset = routingPrefix.size() + 1;
}
invitationPrefix.append(m_identity).append("CHRONOCHAT-INVITATION");
+ requestPrefix.append(m_identity).append("CHRONOCHAT-INVITATION-REQUEST");
const ndn::RegisteredPrefixId* invitationListenerId =
m_face.setInterestFilter(invitationPrefix,
@@ -115,6 +120,19 @@
m_invitationListenerId = invitationListenerId;
+ const ndn::RegisteredPrefixId* requestListenerId =
+ m_face.setInterestFilter(requestPrefix,
+ bind(&ControllerBackend::onInvitationRequestInterest,
+ this, _1, _2, offset),
+ [] (const Name& prefix, const std::string& failInfo) {});
+
+ if (m_requestListenerId != 0) {
+ m_face.unregisterPrefix(m_requestListenerId,
+ []{},
+ [] (const std::string& failInfo) {});
+ }
+
+ m_requestListenerId = requestListenerId;
}
ndn::Name
@@ -164,21 +182,45 @@
}
void
-ControllerBackend::onInvitationRegisterFailed(const Name& prefix, const string& failInfo)
+ControllerBackend::onInvitationRegisterFailed(const Name& prefix, const std::string& failInfo)
{
// _LOG_DEBUG("ControllerBackend::onInvitationRegisterFailed: " << failInfo);
}
void
+ControllerBackend::onInvitationRequestInterest(const ndn::Name& prefix,
+ const ndn::Interest& interest,
+ size_t routingPrefixOffset)
+{
+ shared_ptr<const Data> data = m_ims.find(interest);
+ if (data != nullptr) {
+ m_face.put(*data);
+ return;
+ }
+ Name interestName = interest.getName();
+ size_t i;
+ for (i = 0; i < interestName.size(); i++)
+ if (interestName.at(i) == Name::Component("CHRONOCHAT-INVITATION-REQUEST"))
+ break;
+ if (i < interestName.size()) {
+ string chatroom = interestName.at(i+1).toUri();
+ string alias = interestName.getSubName(i+2).getPrefix(-1).toUri();
+ emit invitationRequestReceived(QString::fromStdString(alias),
+ QString::fromStdString(chatroom),
+ interestName);
+ }
+}
+
+void
ControllerBackend::onInvitationValidated(const shared_ptr<const Interest>& interest)
{
Invitation invitation(interest->getName());
// Should be obtained via a method of ContactManager.
string alias = invitation.getInviterCertificate().getPublicKeyName().getPrefix(-1).toUri();
- emit invitaionValidated(QString::fromStdString(alias),
- QString::fromStdString(invitation.getChatroom()),
- interest->getName());
+ emit invitationValidated(QString::fromStdString(alias),
+ QString::fromStdString(invitation.getChatroom()),
+ interest->getName());
}
void
@@ -238,6 +280,36 @@
}
}
+void
+ControllerBackend::onRequestResponse(const Interest& interest, Data& data)
+{
+ size_t i;
+ Name interestName = interest.getName();
+ for (i = 0; i < interestName.size(); i++) {
+ if (interestName.at(i) == Name::Component("CHRONOCHAT-INVITATION-REQUEST"))
+ break;
+ }
+ Name::Component chatroomName = interestName.at(i+1);
+ Block contentBlock = data.getContent();
+ int res = ndn::readNonNegativeInteger(contentBlock);
+ // if data is true,
+ if (res == 1)
+ emit startChatroom(QString::fromStdString(chatroomName.toUri()), false);
+ else
+ emit invitationRequestResult("You are rejected to enter chatroom: " + chatroomName.toUri());
+}
+
+void
+ControllerBackend::onRequestTimeout(const Interest& interest, int& resendTimes)
+{
+ if (resendTimes < MAXIMUM_REQUEST)
+ m_face.expressInterest(interest,
+ bind(&ControllerBackend::onRequestResponse, this, _1, _2),
+ bind(&ControllerBackend::onRequestTimeout, this, _1, resendTimes + 1));
+ else
+ emit invitationRequestResult("Invitation request times out.");
+}
+
// public slots:
void
ControllerBackend::shutdown()
@@ -321,7 +393,7 @@
else {
Name wrappedName;
wrappedName.append(invitationRoutingPrefix)
- .append(ROUTING_PREFIX_SEPARATOR, 2)
+ .append(ROUTING_HINT_SEPARATOR)
.append(response->getName());
// _LOG_DEBUG("onInvitationResponded: prepare reply " << wrappedName);
@@ -339,6 +411,41 @@
}
void
+ControllerBackend::onInvitationRequestResponded(const ndn::Name& invitationResponseName,
+ bool accepted)
+{
+ shared_ptr<Data> response = make_shared<Data>(invitationResponseName);
+ if (accepted)
+ response->setContent(ndn::nonNegativeIntegerBlock(tlv::Content, 1));
+ else
+ response->setContent(ndn::nonNegativeIntegerBlock(tlv::Content, 0));
+
+ m_keyChain.signByIdentity(*response, m_identity);
+ m_ims.insert(*response);
+ m_face.put(*response);
+}
+
+void
+ControllerBackend::onSendInvitationRequest(const QString& chatroomName, const QString& prefix)
+{
+ if (prefix.length() == 0)
+ return;
+ Name interestName = getInvitationRoutingPrefix();
+ interestName.append(ROUTING_HINT_SEPARATOR).append(prefix.toStdString());
+ interestName.append("CHRONOCHAT-INVITATION-REQUEST");
+ interestName.append(chatroomName.toStdString());
+ interestName.append(m_identity);
+ interestName.appendTimestamp();
+ Interest interest(interestName);
+ interest.setInterestLifetime(time::milliseconds(10000));
+ interest.setMustBeFresh(true);
+ interest.getNonce();
+ m_face.expressInterest(interest,
+ bind(&ControllerBackend::onRequestResponse, this, _1, _2),
+ bind(&ControllerBackend::onRequestTimeout, this, _1, 0));
+}
+
+void
ControllerBackend::onContactIdListReady(const QStringList& list)
{
ContactList contactList;
diff --git a/src/controller-backend.hpp b/src/controller-backend.hpp
index be6c499..a449aa4 100644
--- a/src/controller-backend.hpp
+++ b/src/controller-backend.hpp
@@ -10,6 +10,7 @@
#ifndef CHRONOCHAT_CONTROLLER_BACKEND_HPP
#define CHRONOCHAT_CONTROLLER_BACKEND_HPP
+#include <QString>
#include <QThread>
#include <QStringList>
#include <QMutex>
@@ -20,6 +21,7 @@
#include "invitation.hpp"
#include "validator-invitation.hpp"
#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/util/in-memory-storage-persistent.hpp>
#endif
namespace chronochat {
@@ -61,6 +63,10 @@
size_t routingPrefixOffset);
void
+ onInvitationRequestInterest(const ndn::Name& prefix, const ndn::Interest& interest,
+ size_t routingPrefixOffset);
+
+ void
onInvitationRegisterFailed(const Name& prefix, const std::string& failInfo);
void
@@ -79,6 +85,12 @@
void
updateLocalPrefix(const Name& localPrefix);
+ void
+ onRequestResponse(const Interest& interest, Data& data);
+
+ void
+ onRequestTimeout(const Interest& interest, int& resendTimes);
+
signals:
void
identityUpdated(const QString& identity);
@@ -87,11 +99,20 @@
localPrefixUpdated(const QString& localPrefix);
void
- invitaionValidated(QString alias, QString chatroom, ndn::Name invitationINterest);
+ invitationValidated(QString alias, QString chatroom, ndn::Name invitationINterest);
+
+ void
+ invitationRequestReceived(QString alias, QString chatroom, ndn::Name invitationRequestInterest);
void
startChatroomOnInvitation(chronochat::Invitation invitation, bool secured);
+ void
+ startChatroom(const QString& chatroomName, bool secured);
+
+ void
+ invitationRequestResult(const std::string& msg);
+
public slots:
void
shutdown();
@@ -111,6 +132,12 @@
void
onInvitationResponded(const ndn::Name& invitationName, bool accepted);
+ void
+ onInvitationRequestResponded(const ndn::Name& invitationName, bool accepted);
+
+ void
+ onSendInvitationRequest(const QString& chatroomName, const QString& prefix);
+
private slots:
void
onContactIdListReady(const QStringList& list);
@@ -131,11 +158,14 @@
// RegisteredPrefixId
const ndn::RegisteredPrefixId* m_invitationListenerId;
+ const ndn::RegisteredPrefixId* m_requestListenerId;
// ChatRoomList
QStringList m_chatDialogList;
QMutex m_mutex;
+
+ ndn::util::InMemoryStoragePersistent m_ims;
};
} // namespace chronochat
diff --git a/src/controller.cpp b/src/controller.cpp
index dce0b03..b660597 100644
--- a/src/controller.cpp
+++ b/src/controller.cpp
@@ -48,6 +48,7 @@
, m_startChatDialog(new StartChatDialog(this))
, m_profileEditor(new ProfileEditor(this))
, m_invitationDialog(new InvitationDialog(this))
+ , m_invitationRequestDialog(new InvitationRequestDialog(this))
, m_contactPanel(new ContactPanel(this))
, m_browseContactDialog(new BrowseContactDialog(this))
, m_addContactPanel(new AddContactPanel(this))
@@ -98,6 +99,10 @@
connect(m_invitationDialog, SIGNAL(invitationResponded(const ndn::Name&, bool)),
&m_backend, SLOT(onInvitationResponded(const ndn::Name&, bool)));
+ // Connection to InvitationRequestDialog
+ connect(m_invitationRequestDialog, SIGNAL(invitationRequestResponded(const ndn::Name&, bool)),
+ &m_backend, SLOT(onInvitationRequestResponded(const ndn::Name&, bool)));
+
// Connection to AddContactPanel
connect(m_addContactPanel, SIGNAL(fetchInfo(const QString&)),
m_backend.getContactManager(), SLOT(onFetchContactInfo(const QString&)));
@@ -170,8 +175,15 @@
m_settingDialog, SLOT(onLocalPrefixUpdated(const QString&)));
// on invitation validated:
- connect(&m_backend, SIGNAL(invitaionValidated(QString, QString, ndn::Name)),
+ connect(&m_backend, SIGNAL(invitationValidated(QString, QString, ndn::Name)),
m_invitationDialog, SLOT(onInvitationReceived(QString, QString, ndn::Name)));
+ connect(&m_backend, SIGNAL(startChatroom(const QString&, bool)),
+ this, SLOT(onStartChatroom(const QString&, bool)));
+
+ // on invitation request received
+ connect(&m_backend, SIGNAL(invitationRequestReceived(QString, QString, ndn::Name)),
+ m_invitationRequestDialog, SLOT(onInvitationRequestReceived(QString, QString,
+ ndn::Name)));
// on invitation accepted:
connect(&m_backend, SIGNAL(startChatroomOnInvitation(chronochat::Invitation, bool)),
@@ -211,10 +223,14 @@
m_discoveryPanel, SLOT(onIdentityUpdated(const QString&)));
connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomListReady(const QStringList&)),
m_discoveryPanel, SLOT(onChatroomListReady(const QStringList&)));
- connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomInfoReady(const ChatroomInfo&)),
- m_discoveryPanel, SLOT(onChatroomInfoReady(const ChatroomInfo&)));
+ connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomInfoReady(const ChatroomInfo&, bool)),
+ m_discoveryPanel, SLOT(onChatroomInfoReady(const ChatroomInfo&, bool)));
connect(m_discoveryPanel, SIGNAL(startChatroom(const QString&, bool)),
this, SLOT(onStartChatroom(const QString&, bool)));
+ connect(m_discoveryPanel, SIGNAL(sendInvitationRequest(const QString&, const QString&)),
+ &m_backend, SLOT(onSendInvitationRequest(const QString&, const QString&)));
+ connect(&m_backend, SIGNAL(invitationRequestResult(const std::string&)),
+ m_discoveryPanel, SLOT(onInvitationRequestResult(const std::string&)));
m_chatroomDiscoveryBackend->start();
diff --git a/src/controller.hpp b/src/controller.hpp
index 2b80932..fdce4cd 100644
--- a/src/controller.hpp
+++ b/src/controller.hpp
@@ -20,6 +20,7 @@
#include "start-chat-dialog.hpp"
#include "profile-editor.hpp"
#include "invitation-dialog.hpp"
+#include "invitation-request-dialog.hpp"
#include "contact-panel.hpp"
#include "browse-contact-dialog.hpp"
#include "add-contact-panel.hpp"
@@ -220,6 +221,7 @@
StartChatDialog* m_startChatDialog;
ProfileEditor* m_profileEditor;
InvitationDialog* m_invitationDialog;
+ InvitationRequestDialog* m_invitationRequestDialog;
ContactPanel* m_contactPanel;
BrowseContactDialog* m_browseContactDialog;
AddContactPanel* m_addContactPanel;
diff --git a/src/discovery-panel.cpp b/src/discovery-panel.cpp
index cbc98e0..20e36ab 100644
--- a/src/discovery-panel.cpp
+++ b/src/discovery-panel.cpp
@@ -13,6 +13,7 @@
#include <QItemSelectionModel>
#include <QModelIndex>
+#include <QMessageBox>
#ifndef Q_MOC_RUN
#endif
@@ -21,7 +22,8 @@
namespace chronochat {
static const time::seconds REFRESH_INTERVAL(60);
-static const uint8_t ROUTING_HINT_SEPARATOR[2] = {0xF0, 0x2E};
+static const ndn::Name::Component ROUTING_HINT_SEPARATOR =
+ ndn::name::Component::fromEscapedString("%F0%2E");
DiscoveryPanel::DiscoveryPanel(QWidget *parent)
: QDialog(parent)
@@ -43,6 +45,12 @@
SLOT(onSelectedParticipantChanged(const QItemSelection &, const QItemSelection &)));
connect(ui->join, SIGNAL(clicked()),
this, SLOT(onJoinClicked()));
+ connect(ui->requestInvitation, SIGNAL(clicked()),
+ this, SLOT(onRequestInvitation()));
+
+ ui->join->setEnabled(false);
+ ui->requestInvitation->setEnabled(false);
+ ui->InChatroomWarning->clear();
}
DiscoveryPanel::~DiscoveryPanel()
@@ -73,6 +81,9 @@
m_chatroom.clear();
m_chatroomListModel->setStringList(m_chatroomList);
+ ui->join->setEnabled(false);
+ ui->requestInvitation->setEnabled(false);
+ ui->InChatroomWarning->clear();
}
// public slots
@@ -90,7 +101,7 @@
}
void
-DiscoveryPanel::onChatroomInfoReady(const ChatroomInfo& info)
+DiscoveryPanel::onChatroomInfoReady(const ChatroomInfo& info, bool isParticipant)
{
ui->NameData->setText(QString::fromStdString(info.getName().toUri()));
ui->NameSpaceData->setText(QString::fromStdString(info.getSyncPrefix().toUri()));
@@ -124,10 +135,16 @@
ui->requestInvitation->setEnabled(false);
}
}
+ ui->InChatroomWarning->clear();
+ if (isParticipant) {
+ ui->join->setEnabled(false);
+ ui->requestInvitation->setEnabled(false);
+ ui->InChatroomWarning->setText(QString("You are already in this chatroom"));
+ }
std::list<Name>roster = info.getParticipants();
m_rosterList.clear();
- Name::Component routingHint = Name::Component(ROUTING_HINT_SEPARATOR, 2);
+ Name::Component routingHint = Name::Component(ROUTING_HINT_SEPARATOR);
for (const auto& participant : roster) {
size_t i;
for (i = 0; i < participant.size(); ++i) {
@@ -196,6 +213,19 @@
emit startChatroom(m_chatroom, false);
}
+void
+DiscoveryPanel::onRequestInvitation()
+{
+ emit sendInvitationRequest(m_chatroom, m_participant);
+}
+
+void
+DiscoveryPanel::onInvitationRequestResult(const std::string& message)
+{
+ QMessageBox::information(this, tr("Chatroom Discovery"),
+ tr(message.c_str()));
+}
+
} // namespace chronochat
#if WAF
diff --git a/src/discovery-panel.hpp b/src/discovery-panel.hpp
index 1776d37..f15906b 100644
--- a/src/discovery-panel.hpp
+++ b/src/discovery-panel.hpp
@@ -72,6 +72,17 @@
void
startChatroom(const QString& chatroomName, bool secured);
+ /**
+ * @brief send request for invitation to a chatroom
+ *
+ * This function will be called if request invitation button is clicked.
+ *
+ * @param chatroomName the chatroom to join
+ * @param identity the person that the user send the request to
+ */
+ void
+ sendInvitationRequest(const QString& chatroomName, const QString& identity);
+
public slots:
/**
* @brief reset the panel when identity is updated
@@ -92,9 +103,10 @@
* @brief print the chatroom info on the panel
*
* @param info chatroom info get from discovery backend
+ * @param isParticipant if the user is a participant of the chatroom
*/
void
- onChatroomInfoReady(const ChatroomInfo& info);
+ onChatroomInfoReady(const ChatroomInfo& info, bool isParticipant);
private slots:
void
@@ -108,6 +120,12 @@
void
onJoinClicked();
+ void
+ onRequestInvitation();
+
+ void
+ onInvitationRequestResult(const std::string& message);
+
private:
Ui::DiscoveryPanel* ui;
diff --git a/src/discovery-panel.ui b/src/discovery-panel.ui
index def8138..b7307d6 100644
--- a/src/discovery-panel.ui
+++ b/src/discovery-panel.ui
@@ -59,139 +59,145 @@
<attribute name="title">
<string>General</string>
</attribute>
- <layout class="QVBoxLayout" name="verticalLayout_7">
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
- <layout class="QVBoxLayout" name="verticalLayout_6" stretch="2">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <layout class="QVBoxLayout" name="verticalLayout">
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="35,100">
+ <property name="spacing">
+ <number>-1</number>
+ </property>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout" stretch="35,100">
- <property name="spacing">
- <number>-1</number>
+ <widget class="QLabel" name="NameSpaceLabel">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
</property>
- <item>
- <widget class="QLabel" name="NameSpaceLabel">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string>Sync Prefix</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="NameSpaceData">
- <property name="font">
- <font>
- <family>Lucida Grande</family>
- </font>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
+ <property name="text">
+ <string>Sync Prefix</string>
+ </property>
+ </widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="35,100">
- <item>
- <widget class="QLabel" name="NameLabel">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string>Name</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="NameData">
- <property name="font">
- <font>
- <family>Lucida Grande</family>
- </font>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
+ <widget class="QLineEdit" name="NameSpaceData">
+ <property name="font">
+ <font>
+ <family>Lucida Grande</family>
+ </font>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="35,100">
+ <item>
+ <widget class="QLabel" name="NameLabel">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="35,100">
- <item>
- <widget class="QLabel" name="TrustModel">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string>Trust Model</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="TrustModelData">
- <property name="font">
- <font>
- <family>Lucida Grande</family>
- </font>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
+ <widget class="QLineEdit" name="NameData">
+ <property name="font">
+ <font>
+ <family>Lucida Grande</family>
+ </font>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="35,100">
+ <item>
+ <widget class="QLabel" name="TrustModel">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Trust Model</string>
+ </property>
+ </widget>
</item>
<item>
- <layout class="QVBoxLayout" name="verticalLayout_3">
+ <widget class="QLineEdit" name="TrustModelData">
+ <property name="font">
+ <font>
+ <family>Lucida Grande</family>
+ </font>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0">
+ <item>
+ <widget class="QListView" name="RosterList">
+ <property name="contextMenuPolicy">
+ <enum>Qt::PreventContextMenu</enum>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="InChatroomWarning">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
- <widget class="QListView" name="RosterList">
- <property name="contextMenuPolicy">
- <enum>Qt::PreventContextMenu</enum>
- </property>
- <property name="acceptDrops">
- <bool>false</bool>
- </property>
- <property name="editTriggers">
- <set>QAbstractItemView::NoEditTriggers</set>
- </property>
+ <widget class="QPushButton" name="join">
+ <property name="text">
+ <string>Join</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <item>
- <widget class="QPushButton" name="join">
- <property name="text">
- <string>Join</string>
- </property>
- <property name="autoDefault">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="requestInvitation">
- <property name="text">
- <string>Request Invitation</string>
- </property>
- <property name="autoDefault">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
+ <widget class="QPushButton" name="requestInvitation">
+ <property name="text">
+ <string>Request Invitation</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
</item>
</layout>
</item>
diff --git a/src/invitation-request-dialog.cpp b/src/invitation-request-dialog.cpp
new file mode 100644
index 0000000..47b63f1
--- /dev/null
+++ b/src/invitation-request-dialog.cpp
@@ -0,0 +1,71 @@
+/* -*- 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: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ * Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "invitation-request-dialog.hpp"
+#include "ui_invitation-request-dialog.h"
+
+namespace chronochat {
+
+InvitationRequestDialog::InvitationRequestDialog(QWidget* parent)
+ : QDialog(parent)
+ , ui(new Ui::InvitationRequestDialog)
+{
+ ui->setupUi(this);
+
+ connect(ui->okButton, SIGNAL(clicked()),
+ this, SLOT(onOkClicked()));
+ connect(ui->cancelButton, SIGNAL(clicked()),
+ this, SLOT(onCancelClicked()));
+}
+
+InvitationRequestDialog::~InvitationRequestDialog()
+{
+ delete ui;
+}
+
+void
+InvitationRequestDialog::onInvitationRequestReceived(QString alias, QString chatroom,
+ Name interestName)
+{
+ m_invitationInterest = interestName;
+
+ QString msg = QString("%1\n request your invitation to chatroom\n %2 ").arg(alias).arg(chatroom);
+ ui->msgLabel->setText(msg);
+
+ show();
+ raise();
+}
+
+void
+InvitationRequestDialog::onOkClicked()
+{
+ emit invitationRequestResponded(m_invitationInterest, true);
+ this->close();
+
+ ui->msgLabel->clear();
+ m_invitationInterest.clear();
+}
+
+void
+InvitationRequestDialog::onCancelClicked()
+{
+ emit invitationRequestResponded(m_invitationInterest, false);
+ this->close();
+
+ ui->msgLabel->clear();
+ m_invitationInterest.clear();
+}
+
+} // namespace chronochat
+
+#if WAF
+#include "invitation-request-dialog.moc"
+// #include "invitation-request-dialog.cpp.moc"
+#endif
diff --git a/src/invitation-request-dialog.hpp b/src/invitation-request-dialog.hpp
new file mode 100644
index 0000000..bd2bd1d
--- /dev/null
+++ b/src/invitation-request-dialog.hpp
@@ -0,0 +1,59 @@
+/* -*- 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: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ * Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef CHRONOS_INVITATION_REQUEST_DIALOG_HPP
+#define CHRONOS_INVITATION_REQUEST_DIALOG_HPP
+
+#include <QDialog>
+
+#ifndef Q_MOC_RUN
+#include "common.hpp"
+#endif
+
+namespace Ui {
+class InvitationRequestDialog;
+}
+
+namespace chronochat{
+
+class InvitationRequestDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit
+ InvitationRequestDialog(QWidget* parent = 0);
+
+ ~InvitationRequestDialog();
+
+signals:
+ void
+ invitationRequestResponded(const ndn::Name& invitationName, bool accepted);
+
+public slots:
+ void
+ onInvitationRequestReceived(QString alias, QString chatroom, ndn::Name invitationInterest);
+
+private slots:
+ void
+ onOkClicked();
+
+ void
+ onCancelClicked();
+
+
+private:
+ Ui::InvitationRequestDialog* ui;
+ ndn::Name m_invitationInterest;
+};
+
+} // namespace chronochat
+
+#endif // CHRONOS_INVITATION_REQUEST_DIALOG_HPP
diff --git a/src/invitation-request-dialog.ui b/src/invitation-request-dialog.ui
new file mode 100644
index 0000000..f2051ee
--- /dev/null
+++ b/src/invitation-request-dialog.ui
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>InvitationRequestDialog</class>
+ <widget class="QDialog" name="InvitationRequestDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>414</width>
+ <height>150</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="5,1">
+ <property name="leftMargin">
+ <number>10</number>
+ </property>
+ <property name="topMargin">
+ <number>10</number>
+ </property>
+ <property name="rightMargin">
+ <number>10</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="msgLabel">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="buttonLayout" stretch="1,1">
+ <property name="spacing">
+ <number>-1</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="cancelButton">
+ <property name="text">
+ <string>Reject</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton">
+ <property name="text">
+ <string>Accept</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>