gui: Display the trust tree
Change-Id: Id48227b0f2e903905d7c8eb9795d038d6562794c
diff --git a/src/chat-dialog.cpp b/src/chat-dialog.cpp
index baa9f78..061c74f 100644
--- a/src/chat-dialog.cpp
+++ b/src/chat-dialog.cpp
@@ -24,6 +24,7 @@
#include <ndn-cpp-dev/util/random.hpp>
#include <cryptopp/hex.h>
#include <cryptopp/files.h>
+#include <queue>
#include "logging.h"
#endif
@@ -71,13 +72,17 @@
qRegisterMetaType<size_t>("size_t");
m_scene = new DigestTreeScene(this);
+ m_trustScene = new TrustTreeScene(this);
m_rosterModel = new QStringListModel(this);
m_timer = new QTimer(this);
ui->setupUi(this);
- ui->treeViewer->setScene(m_scene);
+ ui->syncTreeViewer->setScene(m_scene);
m_scene->setSceneRect(m_scene->itemsBoundingRect());
- ui->treeViewer->hide();
+ 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);
@@ -89,8 +94,10 @@
connect(ui->lineEdit, SIGNAL(returnPressed()),
this, SLOT(onReturnPressed()));
- connect(ui->treeButton, SIGNAL(pressed()),
- this, SLOT(onTreeButtonPressed()));
+ connect(ui->syncTreeButton, SIGNAL(pressed()),
+ 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)),
@@ -120,6 +127,8 @@
"==", "\\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&)),
@@ -159,6 +168,7 @@
_LOG_DEBUG("Add sync anchor from invation");
// 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);
@@ -308,8 +318,8 @@
QTimer::singleShot(600, this, SLOT(sendJoin()));
m_timer->start(FRESHNESS * 1000);
- disableTreeDisplay();
- QTimer::singleShot(2200, this, SLOT(enableTreeDisplay()));
+ disableSyncTreeDisplay();
+ QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
}
void
@@ -411,6 +421,7 @@
{
// Add invitee certificate as trust anchor.
m_sock->addParticipant(inviteeCert);
+ plotTrustTree();
// Ask invitee for IntroCertificate.
Name inviteeNameSpace = IdentityCertificate::certificateNameToPublicKeyName(inviteeCert.getName()).getPrefix(-1);
@@ -492,7 +503,7 @@
Chronos::IntroCertListMsg msg;
- vector<Name>::const_iterator it = certNameList.begin();
+ vector<Name>::const_iterator it = certNameList.begin();
vector<Name>::const_iterator end = certNameList.end();
for(; it != end; it++)
{
@@ -568,10 +579,10 @@
}
}
-void ChatDialog::disableTreeDisplay()
+void ChatDialog::disableSyncTreeDisplay()
{
- ui->treeButton->setEnabled(false);
- ui->treeViewer->hide();
+ ui->syncTreeButton->setEnabled(false);
+ ui->syncTreeViewer->hide();
fitView();
}
@@ -775,7 +786,11 @@
boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
QRectF rect = m_scene->itemsBoundingRect();
m_scene->setSceneRect(rect);
- ui->treeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
+ ui->syncTreeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
+
+ QRectF trustRect = m_trustScene->itemsBoundingRect();
+ m_trustScene->setSceneRect(trustRect);
+ ui->trustTreeViewer->fitInView(m_trustScene->itemsBoundingRect(), Qt::KeepAspectRatio);
}
void
@@ -818,6 +833,94 @@
reap();
}
+void
+ChatDialog::getTree(TrustTreeNodeList& nodeList)
+{
+ typedef map<Name, shared_ptr<TrustTreeNode> > NodeMap;
+
+ vector<Name> certNameList;
+ NodeMap nodeMap;
+
+ m_sock->getIntroCertNames(certNameList);
+
+ vector<Name>::const_iterator it = certNameList.begin();
+ vector<Name>::const_iterator end = certNameList.end();
+ for(; it != 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();
+ TrustTreeNodeList::iterator eeIt = introducees.begin();
+ TrustTreeNodeList::iterator eeEnd = introducees.end();
+
+ for(; eeIt != eeEnd; eeIt++)
+ {
+ _LOG_DEBUG("introducee: " << (*eeIt)->name() << " visited: " << 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();
+ }
+}
// public slots:
void
@@ -865,8 +968,8 @@
usleep(100000);
QTimer::singleShot(600, this, SLOT(sendJoin()));
m_timer->start(FRESHNESS * 1000);
- disableTreeDisplay();
- QTimer::singleShot(2200, this, SLOT(enableTreeDisplay()));
+ disableSyncTreeDisplay();
+ QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
}
else
initializeSync();
@@ -922,17 +1025,34 @@
}
void
-ChatDialog::onTreeButtonPressed()
+ChatDialog::onSyncTreeButtonPressed()
{
- if (ui->treeViewer->isVisible())
+ if (ui->syncTreeViewer->isVisible())
{
- ui->treeViewer->hide();
- ui->treeButton->setText("Show ChronoSync Tree");
+ ui->syncTreeViewer->hide();
+ ui->syncTreeButton->setText("Show ChronoSync Tree");
}
else
{
- ui->treeViewer->show();
- ui->treeButton->setText("Hide ChronoSync Tree");
+ ui->syncTreeViewer->show();
+ ui->syncTreeButton->setText("Hide ChronoSync Tree");
+ }
+
+ fitView();
+}
+
+void
+ChatDialog::onTrustTreeButtonPressed()
+{
+ if (ui->trustTreeViewer->isVisible())
+ {
+ ui->trustTreeViewer->hide();
+ ui->trustTreeButton->setText("Show Trust Tree");
+ }
+ else
+ {
+ ui->trustTreeViewer->show();
+ ui->trustTreeButton->setText("Hide Trust Tree");
}
fitView();
@@ -965,9 +1085,7 @@
if (!isHistory)
{
// update the tree view
- std::string stdStrName = data->getName().toUri();
- std::string stdStrNameWithoutSeq = stdStrName.substr(0, stdStrName.find_last_of('/'));
- std::string prefix = stdStrNameWithoutSeq.substr(0, stdStrNameWithoutSeq.find_last_of('/'));
+ std::string prefix = data->getName().getPrefix(-2).toUri();
_LOG_DEBUG("<<< updating scene for" << prefix << ": " << msg.from());
if (msg.type() == SyncDemo::ChatMessage::LEAVE)
{
@@ -1051,6 +1169,7 @@
msg.set_from(nick);
appendMessage(msg);
}
+ plotTrustTree();
}
void
@@ -1108,9 +1227,9 @@
_LOG_DEBUG("Sync REMOVE signal sent");
}
-void ChatDialog::enableTreeDisplay()
+void ChatDialog::enableSyncTreeDisplay()
{
- ui->treeButton->setEnabled(true);
+ ui->syncTreeButton->setEnabled(true);
// treeViewer->show();
// fitView();
}
@@ -1185,6 +1304,7 @@
innerData.wireDecode(data->getContent().blockFromValue());
Sync::IntroCertificate introCert(innerData);
m_sock->addParticipant(introCert);
+ plotTrustTree();
}
void
@@ -1194,7 +1314,6 @@
}
-
#if WAF
#include "chat-dialog.moc"
#include "chat-dialog.cpp.moc"
diff --git a/src/chat-dialog.h b/src/chat-dialog.h
index 0ddbc85..c95aabf 100644
--- a/src/chat-dialog.h
+++ b/src/chat-dialog.h
@@ -28,12 +28,13 @@
#include "contact.h"
#include "chatbuf.pb.h"
#include "intro-cert-list.pb.h"
-#include "digesttreescene.h"
+#include "digest-tree-scene.h"
+#include "trust-tree-scene.h"
+#include "trust-tree-node.h"
#include <sync-socket.h>
#include <sync-seq-no.h>
#include <ndn-cpp-dev/security/key-chain.hpp>
#include "validator-invitation.h"
-
#include <boost/thread/locks.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/thread.hpp>
@@ -162,7 +163,7 @@
sendMsg(SyncDemo::ChatMessage &msg);
void
- disableTreeDisplay();
+ disableSyncTreeDisplay();
void
appendMessage(const SyncDemo::ChatMessage msg, bool isHistory = false);
@@ -197,6 +198,12 @@
void
summonReaper();
+ void
+ getTree(TrustTreeNodeList& nodeList);
+
+ void
+ plotTrustTree();
+
signals:
void
processData(const ndn::shared_ptr<const ndn::Data>& data, bool show, bool isHistory);
@@ -248,7 +255,10 @@
onReturnPressed();
void
- onTreeButtonPressed();
+ onSyncTreeButtonPressed();
+
+ void
+ onTrustTreeButtonPressed();
void
onProcessData(const ndn::shared_ptr<const ndn::Data>& data,
@@ -276,7 +286,7 @@
sendLeave();
void
- enableTreeDisplay();
+ enableSyncTreeDisplay();
void
reap();
@@ -324,6 +334,7 @@
ndn::Name m_localChatPrefix;
std::string m_nick;
DigestTreeScene *m_scene;
+ TrustTreeScene *m_trustScene;
QStringListModel *m_rosterModel;
QTimer* m_timer;
diff --git a/src/chat-dialog.ui b/src/chat-dialog.ui
index 2d174c0..1473eeb 100644
--- a/src/chat-dialog.ui
+++ b/src/chat-dialog.ui
@@ -13,15 +13,9 @@
<property name="windowTitle">
<string>ChronoChat -- Powered By ChronoSync</string>
</property>
- <layout class="QVBoxLayout">
- <property name="spacing">
- <number>6</number>
- </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="spacing">
- <number>-1</number>
- </property>
+ <layout class="QHBoxLayout" name="firstLayout">
<item>
<layout class="QVBoxLayout" name="infoLayout">
<item>
@@ -58,17 +52,32 @@
</spacer>
</item>
<item>
- <layout class="QVBoxLayout" name="buttonLayout">
- <property name="sizeConstraint">
- <enum>QLayout::SetFixedSize</enum>
- </property>
+ <layout class="QVBoxLayout" name="treeButtonLayout">
<item>
- <widget class="QPushButton" name="inviteButton">
+ <widget class="QPushButton" name="trustTreeButton">
<property name="enabled">
<bool>false</bool>
</property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>200</width>
+ <height>16777215</height>
+ </size>
+ </property>
<property name="text">
- <string>Invite</string>
+ <string>Show Trust Tree</string>
</property>
<property name="autoDefault">
<bool>false</bool>
@@ -76,19 +85,19 @@
</widget>
</item>
<item>
- <widget class="QPushButton" name="treeButton">
+ <widget class="QPushButton" name="syncTreeButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
- <width>200</width>
+ <width>0</width>
<height>0</height>
</size>
</property>
@@ -104,6 +113,9 @@
<property name="text">
<string>Show ChronoSync Tree</string>
</property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
</widget>
</item>
</layout>
@@ -111,11 +123,14 @@
</layout>
</item>
<item>
- <layout class="QHBoxLayout" name="chatLayout_2">
+ <layout class="QHBoxLayout" name="secondLayout" stretch="1,6">
+ <property name="leftMargin">
+ <number>5</number>
+ </property>
<item>
<widget class="QListView" name="listView">
<property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -146,13 +161,24 @@
</widget>
</item>
<item>
- <layout class="QVBoxLayout" name="messageLayout">
+ <layout class="QVBoxLayout" name="viewerLayout">
<item>
- <widget class="QGraphicsView" name="treeViewer">
- <property name="focusPolicy">
- <enum>Qt::NoFocus</enum>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="treeViewLayout">
+ <item>
+ <widget class="QGraphicsView" name="syncTreeViewer">
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGraphicsView" name="trustTreeViewer">
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
<item>
<widget class="QTextEdit" name="textEdit">
@@ -164,19 +190,54 @@
</property>
</widget>
</item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="thirdLayout" stretch="1,6">
+ <property name="spacing">
+ <number>10</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="inviteButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Invite</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="inputLayout">
<item>
- <layout class="QHBoxLayout" name="inputLayout">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Message:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="lineEdit"/>
- </item>
- </layout>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Message:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit"/>
</item>
</layout>
</item>
diff --git a/src/controller.cpp b/src/controller.cpp
index 43e79a4..9904a64 100644
--- a/src/controller.cpp
+++ b/src/controller.cpp
@@ -647,8 +647,10 @@
delete m_startChatDialog;
delete m_profileEditor;
delete m_invitationDialog;
+ delete m_browseContactDialog;
delete m_addContactPanel;
- // TODO: clean up all the dialog.
+
+ m_face->shutdown();
QApplication::quit();
}
diff --git a/src/digesttreescene.cpp b/src/digest-tree-scene.cpp
similarity index 89%
rename from src/digesttreescene.cpp
rename to src/digest-tree-scene.cpp
index c2aa865..14f95bd 100644
--- a/src/digesttreescene.cpp
+++ b/src/digest-tree-scene.cpp
@@ -9,7 +9,7 @@
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
-#include "digesttreescene.h"
+#include "digest-tree-scene.h"
#include <QtGui>
@@ -108,31 +108,32 @@
{
Roster_iterator it = m_roster.find(prefix);
if (it != m_roster.end())
- {
- std::cout << "Updating for prefix = " << prefix.toStdString() << " nick = " << nick.toStdString() << std::endl;
- DisplayUserPtr p = it.value();
- p->setReceived(time(NULL));
- 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);
- }
+ std::cout << "Updating for prefix = " << prefix.toStdString() << " nick = " << nick.toStdString() << std::endl;
+ DisplayUserPtr p = it.value();
+ p->setReceived(time(NULL));
+ 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());
+ }
- previouslyUpdatedUser = p;
- }
+ reDrawNode(p, Qt::red);
+
+ if (previouslyUpdatedUser != DisplayUserNullPtr && previouslyUpdatedUser != p)
+ {
+ reDrawNode(previouslyUpdatedUser, Qt::darkBlue);
+ }
+
+ previouslyUpdatedUser = p;
+ }
}
void
@@ -325,6 +326,6 @@
}
#if WAF
-#include "digesttreescene.moc"
-#include "digesttreescene.cpp.moc"
+#include "digest-tree-scene.moc"
+#include "digest-tree-scene.cpp.moc"
#endif
diff --git a/src/digesttreescene.h b/src/digest-tree-scene.h
similarity index 96%
rename from src/digesttreescene.h
rename to src/digest-tree-scene.h
index 9f1c63f..6ac6b1c 100644
--- a/src/digesttreescene.h
+++ b/src/digest-tree-scene.h
@@ -9,16 +9,15 @@
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
-#ifndef DIGESTTREESCENE_H
-#define DIGESTTREESCENE_H
-
-#include "treelayout.h"
+#ifndef DIGEST_TREE_SCENE_H
+#define DIGEST_TREE_SCENE_H
#include <QtGui/QGraphicsScene>
#include <QColor>
#include <QMap>
#ifndef Q_MOC_RUN
+#include "tree-layout.h"
#include <sync-seq-no.h>
#include <sync-logic.h>
#include <ctime>
@@ -122,4 +121,4 @@
QGraphicsRectItem *m_nickRectItem;
};
-#endif
+#endif // DIGEST_TREE_SCENE_H
diff --git a/src/tree-layout.cpp b/src/tree-layout.cpp
new file mode 100644
index 0000000..7fba509
--- /dev/null
+++ b/src/tree-layout.cpp
@@ -0,0 +1,71 @@
+/* -*- 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: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "tree-layout.h"
+
+#include <iostream>
+
+void
+OneLevelTreeLayout::setOneLevelLayout(std::vector<Coordinate> &childNodesCo)
+{
+ if (childNodesCo.empty())
+ {
+ return;
+ }
+ double y = getLevelDistance();
+ double sd = getSiblingDistance();
+ int n = childNodesCo.size();
+ double x = - (n - 1) * sd / 2;
+ for (int i = 0; i < n; i++)
+ {
+ childNodesCo[i].x = x;
+ childNodesCo[i].y = y;
+ x += sd;
+ }
+}
+
+void
+MultipleLevelTreeLayout::setMultipleLevelTreeLayout(TrustTreeNodeList& nodeList)
+{
+ if(nodeList.empty())
+ return;
+
+ double ld = getLevelDistance();
+ double sd = getSiblingDistance();
+
+ std::map<int, double> layerSpan;
+
+ TrustTreeNodeList::iterator it = nodeList.begin();
+ TrustTreeNodeList::iterator end = nodeList.end();
+ for(; it != end; it++)
+ {
+ int layer = (*it)->level();
+ (*it)->y = layer * ld;
+ (*it)->x = layerSpan[layer];
+ layerSpan[layer] += sd;
+ }
+
+ std::map<int, double>::iterator layerIt = layerSpan.begin();
+ std::map<int, double>::iterator layerEnd = layerSpan.end();
+ for(; layerIt != layerEnd; layerIt++)
+ {
+ double shift = (layerIt->second - sd) / 2;
+ layerIt->second = shift;
+ }
+
+ it = nodeList.begin();
+ end = nodeList.end();
+ for(; it != end; it++)
+ {
+ (*it)->x -= layerSpan[(*it)->level()];
+ }
+}
diff --git a/src/treelayout.h b/src/tree-layout.h
similarity index 71%
rename from src/treelayout.h
rename to src/tree-layout.h
index 4942f62..99e8cca 100644
--- a/src/treelayout.h
+++ b/src/tree-layout.h
@@ -7,11 +7,14 @@
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * Yingdi Yu <yingdi@cs.ucla.edu>
*/
-#ifndef TREELAYOUT_H
-#define TREELAYOUT_H
+#ifndef TREE_LAYOUT_H
+#define TREE_LAYOUT_H
+
#include <vector>
+#include "trust-tree-node.h"
class TreeLayout
{
@@ -33,11 +36,20 @@
int m_levelDistance;
};
-class OneLevelTreeLayout: public TreeLayout
+class OneLevelTreeLayout : public TreeLayout
{
public:
OneLevelTreeLayout(){}
virtual void setOneLevelLayout(std::vector<Coordinate> &childNodesCo);
virtual ~OneLevelTreeLayout(){}
};
-#endif
+
+class MultipleLevelTreeLayout : public TreeLayout
+{
+public:
+ MultipleLevelTreeLayout(){}
+ virtual ~MultipleLevelTreeLayout(){}
+ virtual void setMultipleLevelTreeLayout(TrustTreeNodeList& nodeList);
+};
+
+#endif // TREE_LAYOUT_H
diff --git a/src/treelayout.cpp b/src/treelayout.cpp
deleted file mode 100644
index c1fecf3..0000000
--- a/src/treelayout.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- 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: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#include "treelayout.h"
-
-void
-OneLevelTreeLayout::setOneLevelLayout(std::vector<Coordinate> &childNodesCo)
-{
- if (childNodesCo.empty())
- {
- return;
- }
- double y = getLevelDistance();
- double sd = getSiblingDistance();
- int n = childNodesCo.size();
- double x = - (n - 1) * sd / 2;
- for (int i = 0; i < n; i++)
- {
- childNodesCo[i].x = x;
- childNodesCo[i].y = y;
- x += sd;
- }
-}
diff --git a/src/trust-tree-node.h b/src/trust-tree-node.h
new file mode 100644
index 0000000..c080672
--- /dev/null
+++ b/src/trust-tree-node.h
@@ -0,0 +1,112 @@
+/* -*- 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>
+ */
+
+#ifndef TRUST_TREE_NODE_H
+#define TRUST_TREE_NODE_H
+
+#include <vector>
+#include <ndn-cpp-dev/name.hpp>
+
+class TrustTreeNode;
+
+typedef std::vector<ndn::shared_ptr<TrustTreeNode> > TrustTreeNodeList;
+
+class TrustTreeNode
+{
+public:
+ TrustTreeNode()
+ : m_level(-1)
+ , m_visited(false)
+ {}
+
+ TrustTreeNode(const ndn::Name& name)
+ : m_name(name)
+ , m_level(-1)
+ , m_visited(false)
+ {}
+
+ ~TrustTreeNode()
+ {}
+
+ const ndn::Name&
+ name()
+ {
+ return m_name;
+ }
+
+ void
+ addIntroducee(const ndn::shared_ptr<TrustTreeNode>& introducee)
+ {
+ m_introducees.push_back(introducee);
+ }
+
+ TrustTreeNodeList&
+ getIntroducees()
+ {
+ return m_introducees;
+ }
+
+ void
+ addIntroducer(const ndn::shared_ptr<TrustTreeNode>& introducer)
+ {
+ m_introducers.push_back(introducer);
+ }
+
+ TrustTreeNodeList&
+ getIntroducers()
+ {
+ return m_introducers;
+ }
+
+ void
+ setLevel(int level)
+ {
+ m_level = level;
+ }
+
+ int
+ level()
+ {
+ return m_level;
+ }
+
+ void
+ setVisited()
+ {
+ m_visited = true;
+ }
+
+ void
+ resetVisited()
+ {
+ m_visited = false;
+ }
+
+ bool
+ visited()
+ {
+ return m_visited;
+ }
+
+public:
+ double x;
+ double y;
+
+private:
+ ndn::Name m_name;
+ TrustTreeNodeList m_introducees;
+ TrustTreeNodeList m_introducers;
+ int m_level;
+ bool m_visited;
+};
+
+
+
+#endif // TRUST_TREE_NODE_H
diff --git a/src/trust-tree-scene.cpp b/src/trust-tree-scene.cpp
new file mode 100644
index 0000000..c62d82f
--- /dev/null
+++ b/src/trust-tree-scene.cpp
@@ -0,0 +1,117 @@
+/* -*- 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 "trust-tree-scene.h"
+
+#include <QtGui>
+
+#ifndef Q_MOC_RUN
+#include <vector>
+#include <iostream>
+#include <assert.h>
+#include <boost/lexical_cast.hpp>
+#include <memory>
+#endif
+
+static const double Pi = 3.14159265358979323846264338327950288419717;
+
+TrustTreeScene::TrustTreeScene(QWidget *parent)
+ : QGraphicsScene(parent)
+{}
+
+void
+TrustTreeScene::plotTrustTree(TrustTreeNodeList& nodeList)
+{
+ clear();
+
+ int nodeSize = 40;
+ int siblingDistance = 100, levelDistance = 100;
+
+ boost::shared_ptr<MultipleLevelTreeLayout> layout(new MultipleLevelTreeLayout());
+ layout->setSiblingDistance(siblingDistance);
+ layout->setLevelDistance(levelDistance);
+ layout->setMultipleLevelTreeLayout(nodeList);
+
+ plotEdge(nodeList, nodeSize);
+ plotNode(nodeList, nodeSize);
+}
+
+void
+TrustTreeScene::plotEdge(const TrustTreeNodeList& nodeList, int nodeSize)
+{
+ TrustTreeNodeList::const_iterator it = nodeList.begin();
+ TrustTreeNodeList::const_iterator end = nodeList.end();
+ for(; it != end; it++)
+ {
+ TrustTreeNodeList& introducees = (*it)->getIntroducees();
+ TrustTreeNodeList::iterator eeIt = introducees.begin();
+ TrustTreeNodeList::iterator eeEnd = introducees.end();
+
+ for(; eeIt != eeEnd; eeIt++)
+ {
+ if((*it)->level() >= (*eeIt)->level())
+ continue;
+
+ double x1 = (*it)->x;
+ double y1 = (*it)->y;
+ double x2 = (*eeIt)->x;
+ double y2 = (*eeIt)->y;
+
+ QPointF src(x1 + nodeSize/2, y1 + nodeSize/2);
+ QPointF dest(x2 + nodeSize/2, y2 + nodeSize/2);
+ QLineF line(src, dest);
+ double angle = ::acos(line.dx() / line.length());
+
+ double arrowSize = 10;
+ QPointF endP0 = src + QPointF((nodeSize/2) * line.dx() / line.dy(), nodeSize/2);
+ QPointF sourceArrowP0 = dest + QPointF((-nodeSize/2) * line.dx() / line.dy(), -nodeSize/2);
+ QPointF sourceArrowP1 = sourceArrowP0 + QPointF(-cos(angle - Pi / 6) * arrowSize,
+ -sin(angle - Pi / 6) * arrowSize);
+ QPointF sourceArrowP2 = sourceArrowP0 + QPointF(-cos(angle + Pi / 6) * arrowSize,
+ -sin(angle + Pi / 6) * arrowSize);
+
+ addLine(QLineF(sourceArrowP0, endP0), QPen(Qt::black));
+ addPolygon(QPolygonF() << sourceArrowP0 << sourceArrowP1 << sourceArrowP2, QPen(Qt::black), QBrush(Qt::black));
+ }
+ }
+}
+
+void
+TrustTreeScene::plotNode(const TrustTreeNodeList& nodeList, int nodeSize)
+{
+ int rim = 3;
+
+ // plot nodes
+ TrustTreeNodeList::const_iterator it = nodeList.begin();
+ TrustTreeNodeList::const_iterator end = nodeList.end();
+ for(; it != end; it++)
+ {
+ double x = (*it)->x;
+ double y = (*it)->y;
+ QRectF boundingRect(x, y, nodeSize, nodeSize);
+ QRectF innerBoundingRect(x + rim, y + rim, nodeSize - rim * 2, nodeSize - rim * 2);
+ addRect(boundingRect, QPen(Qt::black), QBrush(Qt::darkBlue));
+ addRect(innerBoundingRect, QPen(Qt::black), QBrush(Qt::lightGray));
+
+ QRectF textRect(x - nodeSize / 2, y + nodeSize, 2 * nodeSize, 30);
+ addRect(textRect, QPen(Qt::darkCyan), QBrush(Qt::darkCyan));
+ QGraphicsTextItem *nickItem = addText(QString::fromStdString((*it)->name().toUri()));
+ QRectF textBoundingRect = nickItem->boundingRect();
+ nickItem->setDefaultTextColor(Qt::white);
+ nickItem->setFont(QFont("Cursive", 8, QFont::Bold));
+ nickItem->setPos(x - nodeSize / 2 + 10, y + nodeSize + 5);
+ }
+
+}
+
+#if WAF
+#include "trust-tree-scene.moc"
+#include "trust-tree-scene.cpp.moc"
+#endif
diff --git a/src/trust-tree-scene.h b/src/trust-tree-scene.h
new file mode 100644
index 0000000..59fdd8c
--- /dev/null
+++ b/src/trust-tree-scene.h
@@ -0,0 +1,42 @@
+/* -*- 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>
+ */
+
+#ifndef TRUST_TREE_SCENE_H
+#define TRUST_TREE_SCENE_H
+
+
+
+#include <QtGui/QGraphicsScene>
+#include <QColor>
+#include <QMap>
+
+#ifndef Q_MOC_RUN
+#include <vector>
+#include "trust-tree-node.h"
+#include "tree-layout.h"
+#endif
+
+class QGraphicsTextItem;
+
+class TrustTreeScene : public QGraphicsScene
+{
+ Q_OBJECT
+
+public:
+ TrustTreeScene(QWidget *parent = 0);
+
+ void plotTrustTree(TrustTreeNodeList& nodeList);
+
+private:
+ void plotEdge(const TrustTreeNodeList& nodeList, int nodeSize);
+ void plotNode(const TrustTreeNodeList& nodeList, int nodeSize);
+};
+
+#endif // TRUST_TREE_SCENE_H