blob: 0dd7a1040b0b6b822cf59bc67e5d8f39460c1bcb [file] [log] [blame]
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -07001#include "digesttreescene.h"
2#include <QtGui>
3#include "ogdf/basic/Array.h"
4#include "ogdf/basic/Graph_d.h"
5#include "ogdf/tree/TreeLayout.h"
6#include <vector>
7#include <iostream>
8#include <assert.h>
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -07009#include <boost/lexical_cast.hpp>
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -070010
11static const double Pi = 3.14159265358979323846264338327950288419717;
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -070012
Zhenkai Zhud13acd02012-06-04 15:25:20 -070013static void
14testDraw(DigestTreeScene * scene)
15{
16 std::string prefix[5] = {"/ndn/1", "/ndn/2", "/ndn/3", "/ndn/4", "/ndn/5"};
17 std::string nick[5] = {"tom", "jerry", "jason", "michael", "hurry"};
18 std::vector<Sync::MissingDataInfo> v;
19 for (int i = 0; i < 5; i++)
20 {
21 Sync::MissingDataInfo mdi = {prefix[i], Sync::SeqNo(0), Sync::SeqNo(i * (2 << i) )};
22 v.push_back(mdi);
23 }
24
25 scene->processUpdate(v, "12341234@!#%!@");
26
27 for (int i = 0; i < 5; i++)
28 {
29 scene-> msgReceived(prefix[i].c_str(), nick[i].c_str());
30 }
31}
32
33DigestTreeScene::DisplayUserPtr DigestTreeScene::DisplayUserNullPtr;
34
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -070035DigestTreeScene::DigestTreeScene(QWidget *parent)
36 : QGraphicsScene(parent)
37{
Zhenkai Zhud13acd02012-06-04 15:25:20 -070038 previouslyUpdatedUser = DisplayUserNullPtr;
Zhenkai Zhu82a62752012-06-04 17:11:04 -070039// testDraw(this);
Zhenkai Zhu6fcdee42012-05-30 17:02:49 -070040}
41
42void
Zhenkai Zhu82a62752012-06-04 17:11:04 -070043DigestTreeScene::processUpdate(const std::vector<Sync::MissingDataInfo> &v, QString digest)
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -070044{
45 int n = v.size();
46 bool rePlot = false;
47 for (int i = 0; i < n; i++)
48 {
49 Roster_iterator it = m_roster.find(v[i].prefix.c_str());
50 if (it == m_roster.end()) {
51 rePlot = true;
52 DisplayUserPtr p(new DisplayUser());
53 p->setPrefix(v[i].prefix.c_str());
54 p->setSeq(v[i].high);
55 m_roster.insert(p->getPrefix(), p);
56 }
57 }
58
59 if (rePlot)
60 {
61 plot(digest);
62 }
63 else
64 {
65 for (int i = 0; i < n; i++)
66 {
67 Roster_iterator it = m_roster.find(v[i].prefix.c_str());
68 if (it != m_roster.end()) {
69 DisplayUserPtr p = it.value();
70 QGraphicsTextItem *item = p->getSeqTextItem();
Zhenkai Zhud13acd02012-06-04 15:25:20 -070071 QGraphicsRectItem *rectItem = p->getInnerRectItem();
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -070072 std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
73 item->setPlainText(s.c_str());
Zhenkai Zhud13acd02012-06-04 15:25:20 -070074 QRectF textBR = item->boundingRect();
75 QRectF rectBR = rectItem->boundingRect();
76 item->setPos(rectBR.x() + (rectBR.width() - textBR.width())/2, rectBR.y() + (rectBR.height() - textBR.height())/2);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -070077 }
78 }
79 m_rootDigest->setPlainText(digest);
80 }
81}
82
83void
84DigestTreeScene::msgReceived(QString prefix, QString nick)
85{
86 Roster_iterator it = m_roster.find(prefix);
87 if (it != m_roster.end())
88 {
89 DisplayUserPtr p = it.value();
90 if (nick != p->getNick()) {
91 p->setNick(nick);
92 QGraphicsTextItem *nickItem = p->getNickTextItem();
Zhenkai Zhud13acd02012-06-04 15:25:20 -070093 QGraphicsRectItem *nickRectItem = p->getNickRectItem();
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -070094 nickItem->setPlainText(p->getNick());
Zhenkai Zhud13acd02012-06-04 15:25:20 -070095 QRectF rectBR = nickRectItem->boundingRect();
96 QRectF nickBR = nickItem->boundingRect();
97 nickItem->setPos(rectBR.x() + (rectBR.width() - nickBR.width())/2, rectBR.y() + 5);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -070098 }
Zhenkai Zhud13acd02012-06-04 15:25:20 -070099
100 reDrawNode(p, Qt::red);
101
102 if (previouslyUpdatedUser != DisplayUserNullPtr)
103 {
104 reDrawNode(previouslyUpdatedUser, Qt::darkBlue);
105 }
106
107 previouslyUpdatedUser = p;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700108 }
109}
110
111void
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700112DigestTreeScene::clearAll()
113{
114 clear();
115 m_graph.clear();
116 m_roster.clear();
117}
118
119void
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700120DigestTreeScene::plot(QString digest)
121{
Zhenkai Zhu6fcdee42012-05-30 17:02:49 -0700122 clear();
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700123 m_graph.clear();
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700124 int n = m_roster.size();
125 ogdf::node root = m_graph.newNode();
126 int rootIndex = root->index();
127 for (int i = 0; i < n; i++) {
128 ogdf::node leaf = m_graph.newNode();
129 m_graph.newEdge(root, leaf);
130 }
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700131 ogdf::GraphAttributes GA(m_graph);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700132
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700133 int nodeSize = 40;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700134 int siblingDistance = 100, levelDistance = 100;
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700135 ogdf::TreeLayout layout;
136 layout.siblingDistance(siblingDistance);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700137 layout.levelDistance(levelDistance);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700138 layout.callSortByPositions(GA, m_graph);
139
140 int width = GA.boundingBox().width();
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700141 int height = GA.boundingBox().height();
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700142 //setSceneRect(QRect(- (width + nodeSize) / 2, - 50, width + nodeSize, height + nodeSize));
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700143 GA.setAllWidth(nodeSize);
144 GA.setAllHeight(nodeSize);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700145
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700146 plotEdge(GA);
147 plotNode(GA, rootIndex, digest);
148
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700149 previouslyUpdatedUser = DisplayUserNullPtr;
150
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700151}
152
153void
154DigestTreeScene::plotEdge(ogdf::GraphAttributes &GA)
155{
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700156 ogdf::edge e;
157 forall_edges(e, m_graph) {
158 ogdf::node source = e->source();
159 ogdf::node target = e->target();
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700160 int nodeSize = GA.width(target);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700161 int x1 = GA.x(source), y1 = -GA.y(source);
162 int x2 = GA.x(target), y2 = -GA.y(target);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700163 QPointF src(x1 + nodeSize/2, y1 + nodeSize/2);
164 QPointF dest(x2 + nodeSize/2, y2 + nodeSize/2);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700165 QLineF line(src, dest);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700166 double angle = ::acos(line.dx() / line.length());
167
168 double arrowSize = 10;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700169 QPointF sourceArrowP0 = src + QPointF((nodeSize/2 + 10) * line.dx() / line.length(), (nodeSize/2 +10) * line.dy() / line.length());
170 QPointF sourceArrowP1 = sourceArrowP0 + QPointF(cos(angle + Pi / 3 - Pi/2) * arrowSize,
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700171 sin(angle + Pi / 3 - Pi/2) * arrowSize);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700172 QPointF sourceArrowP2 = sourceArrowP0 + QPointF(cos(angle + Pi - Pi / 3 - Pi/2) * arrowSize,
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700173 sin(angle + Pi - Pi / 3 - Pi/2) * arrowSize);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700174
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700175 addLine(QLineF(sourceArrowP0, dest), QPen(Qt::black));
176 addPolygon(QPolygonF() << sourceArrowP0<< sourceArrowP1 << sourceArrowP2, QPen(Qt::black), QBrush(Qt::black));
177 }
178}
179
180void
181DigestTreeScene::plotNode(ogdf::GraphAttributes &GA, int rootIndex, QString digest)
182{
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700183 ogdf::node n;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700184 RosterIterator it(m_roster);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700185 forall_nodes(n, m_graph) {
186 double x = GA.x(n);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700187 double y = -GA.y(n);
188 double w = GA.width(n);
189 double h = GA.height(n);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700190 int rim = 3;
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700191 QRectF boundingRect(x, y, w, h);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700192 QRectF innerBoundingRect(x + rim, y + rim, w - rim * 2, h - rim * 2);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700193
194 if (n->index() == rootIndex)
195 {
196 addRect(boundingRect, QPen(Qt::black), QBrush(Qt::darkRed));
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700197 addRect(innerBoundingRect, QPen(Qt::black), QBrush(Qt::lightGray));
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700198
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700199 QRectF digestRect(x - w, y - h, 3 * w, 30);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700200 addRect(digestRect, QPen(Qt::darkCyan), QBrush(Qt::darkCyan));
201 QGraphicsTextItem *digestItem = addText(digest);
202 QRectF digestBoundingRect = digestItem->boundingRect();
203 digestItem->setDefaultTextColor(Qt::white);
204 digestItem->setFont(QFont("Cursive", 12, QFont::Bold));
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700205 digestItem->setPos(x - w + (3 * w - digestBoundingRect.width()) / 2, y - h + 5);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700206 m_rootDigest = digestItem;
207 }
208 else
209 {
210 if (it.hasNext())
211 {
212 it.next();
213 }
214 else
215 {
216 abort();
217 }
218 DisplayUserPtr p = it.value();
219 QGraphicsRectItem *rectItem = addRect(boundingRect, QPen(Qt::black), QBrush(Qt::darkBlue));
220 p->setRimRectItem(rectItem);
221
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700222 QGraphicsRectItem *innerRectItem = addRect(innerBoundingRect, QPen(Qt::black), QBrush(Qt::lightGray));
223 p->setInnerRectItem(innerRectItem);
224
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700225 std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
226 QGraphicsTextItem *seqItem = addText(s.c_str());
227 seqItem->setFont(QFont("Cursive", 12, QFont::Bold));
228 QRectF seqBoundingRect = seqItem->boundingRect();
229 seqItem->setPos(x + w / 2 - seqBoundingRect.width() / 2, y + h / 2 - seqBoundingRect.height() / 2);
230 p->setSeqTextItem(seqItem);
231
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700232 QRectF textRect(x - w / 2, y + h, 2 * w, 30);
233 QGraphicsRectItem *nickRectItem = addRect(textRect, QPen(Qt::darkCyan), QBrush(Qt::darkCyan));
234 p->setNickRectItem(nickRectItem);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700235 QGraphicsTextItem *nickItem = addText(p->getNick());
236 QRectF textBoundingRect = nickItem->boundingRect();
237 nickItem->setDefaultTextColor(Qt::white);
238 nickItem->setFont(QFont("Cursive", 12, QFont::Bold));
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700239 nickItem->setPos(x + w / 2 - textBoundingRect.width() / 2, y + h + 5);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700240 p->setNickTextItem(nickItem);
241 }
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700242
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700243 }
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700244}
245
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700246void
247DigestTreeScene::reDrawNode(DisplayUserPtr p, QColor rimColor)
248{
249 QGraphicsRectItem *rimItem = p->getRimRectItem();
250 rimItem->setBrush(QBrush(rimColor));
251 QGraphicsRectItem *innerItem = p->getInnerRectItem();
252 innerItem->setBrush(QBrush(Qt::lightGray));
253 QGraphicsTextItem *seqTextItem = p->getSeqTextItem();
254 std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
255 seqTextItem->setPlainText(s.c_str());
256 QRectF textBR = seqTextItem->boundingRect();
257 QRectF innerBR = innerItem->boundingRect();
258 seqTextItem->setPos(innerBR.x() + (innerBR.width() - textBR.width())/2, innerBR.y() + (innerBR.height() - textBR.height())/2);
259}
260