blob: 2d2f631a99681a9495581e3370dd59a603b2562d [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
13DigestTreeScene::DigestTreeScene(QWidget *parent)
14 : QGraphicsScene(parent)
15{
Zhenkai Zhu6fcdee42012-05-30 17:02:49 -070016}
17
18void
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -070019DigestTreeScene::processUpdate(std::vector<Sync::MissingDataInfo> &v, QString digest)
20{
21 int n = v.size();
22 bool rePlot = false;
23 for (int i = 0; i < n; i++)
24 {
25 Roster_iterator it = m_roster.find(v[i].prefix.c_str());
26 if (it == m_roster.end()) {
27 rePlot = true;
28 DisplayUserPtr p(new DisplayUser());
29 p->setPrefix(v[i].prefix.c_str());
30 p->setSeq(v[i].high);
31 m_roster.insert(p->getPrefix(), p);
32 }
33 }
34
35 if (rePlot)
36 {
37 plot(digest);
38 }
39 else
40 {
41 for (int i = 0; i < n; i++)
42 {
43 Roster_iterator it = m_roster.find(v[i].prefix.c_str());
44 if (it != m_roster.end()) {
45 DisplayUserPtr p = it.value();
46 QGraphicsTextItem *item = p->getSeqTextItem();
47 std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
48 item->setPlainText(s.c_str());
49 }
50 }
51 m_rootDigest->setPlainText(digest);
52 }
53}
54
55void
56DigestTreeScene::msgReceived(QString prefix, QString nick)
57{
58 Roster_iterator it = m_roster.find(prefix);
59 if (it != m_roster.end())
60 {
61 DisplayUserPtr p = it.value();
62 if (nick != p->getNick()) {
63 p->setNick(nick);
64 QGraphicsTextItem *nickItem = p->getNickTextItem();
65 nickItem->setPlainText(p->getNick());
66 }
67 QGraphicsRectItem *rimItem = p->getRimRectItem();
68 rimItem->setBrush(QBrush(Qt::red));
69 }
70}
71
72void
73DigestTreeScene::plot(QString digest)
74{
Zhenkai Zhu6fcdee42012-05-30 17:02:49 -070075 clear();
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -070076 m_graph.clear();
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -070077 int n = m_roster.size();
78 ogdf::node root = m_graph.newNode();
79 int rootIndex = root->index();
80 for (int i = 0; i < n; i++) {
81 ogdf::node leaf = m_graph.newNode();
82 m_graph.newEdge(root, leaf);
83 }
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -070084 ogdf::GraphAttributes GA(m_graph);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -070085
86 int nodeSize = 50;
87 int siblingDistance = 100, levelDistance = 100;
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -070088 ogdf::TreeLayout layout;
89 layout.siblingDistance(siblingDistance);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -070090 layout.levelDistance(levelDistance);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -070091 layout.callSortByPositions(GA, m_graph);
92
93 int width = GA.boundingBox().width();
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -070094 int height = GA.boundingBox().height();
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -070095 setSceneRect(QRect(- (width + nodeSize) / 2, - 40, width + nodeSize, height + nodeSize));
96 GA.setAllWidth(nodeSize);
97 GA.setAllHeight(nodeSize);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -070098
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -070099 plotEdge(GA);
100 plotNode(GA, rootIndex, digest);
101
102}
103
104void
105DigestTreeScene::plotEdge(ogdf::GraphAttributes &GA)
106{
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700107 ogdf::edge e;
108 forall_edges(e, m_graph) {
109 ogdf::node source = e->source();
110 ogdf::node target = e->target();
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700111 int nodeSize = GA.width(target);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700112 int x1 = GA.x(source), y1 = -GA.y(source);
113 int x2 = GA.x(target), y2 = -GA.y(target);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700114 QPointF src(x1 + nodeSize/2, y1 + nodeSize/2);
115 QPointF dest(x2 + nodeSize/2, y2 + nodeSize/2);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700116 QLineF line(src, dest);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700117 double angle = ::acos(line.dx() / line.length());
118
119 double arrowSize = 10;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700120 QPointF sourceArrowP0 = src + QPointF((nodeSize/2 + 10) * line.dx() / line.length(), (nodeSize/2 +10) * line.dy() / line.length());
121 QPointF sourceArrowP1 = sourceArrowP0 + QPointF(cos(angle + Pi / 3 - Pi/2) * arrowSize,
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700122 sin(angle + Pi / 3 - Pi/2) * arrowSize);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700123 QPointF sourceArrowP2 = sourceArrowP0 + QPointF(cos(angle + Pi - Pi / 3 - Pi/2) * arrowSize,
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700124 sin(angle + Pi - Pi / 3 - Pi/2) * arrowSize);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700125
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700126 addLine(QLineF(sourceArrowP0, dest), QPen(Qt::black));
127 addPolygon(QPolygonF() << sourceArrowP0<< sourceArrowP1 << sourceArrowP2, QPen(Qt::black), QBrush(Qt::black));
128 }
129}
130
131void
132DigestTreeScene::plotNode(ogdf::GraphAttributes &GA, int rootIndex, QString digest)
133{
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700134 ogdf::node n;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700135 RosterIterator it(m_roster);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700136 forall_nodes(n, m_graph) {
137 double x = GA.x(n);
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700138 double y = -GA.y(n);
139 double w = GA.width(n);
140 double h = GA.height(n);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700141 int rim = 3;
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700142 QRectF boundingRect(x, y, w, h);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700143 QRectF innerBoundingRect(x + rim, y + rim, w - rim * 2, h - rim * 2);
144 addRect(innerBoundingRect, QPen(Qt::black), QBrush(Qt::lightGray));
145
146 if (n->index() == rootIndex)
147 {
148 addRect(boundingRect, QPen(Qt::black), QBrush(Qt::darkRed));
149
150 QRectF digestRect(x - w / 2, y - h - 5, 2 * w, 30);
151 addRect(digestRect, QPen(Qt::darkCyan), QBrush(Qt::darkCyan));
152 QGraphicsTextItem *digestItem = addText(digest);
153 QRectF digestBoundingRect = digestItem->boundingRect();
154 digestItem->setDefaultTextColor(Qt::white);
155 digestItem->setFont(QFont("Cursive", 12, QFont::Bold));
156 digestItem->setPos(x + w / 2 - digestBoundingRect.width() / 2, y - h - 15);
157 m_rootDigest = digestItem;
158 }
159 else
160 {
161 if (it.hasNext())
162 {
163 it.next();
164 }
165 else
166 {
167 abort();
168 }
169 DisplayUserPtr p = it.value();
170 QGraphicsRectItem *rectItem = addRect(boundingRect, QPen(Qt::black), QBrush(Qt::darkBlue));
171 p->setRimRectItem(rectItem);
172
173 std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
174 QGraphicsTextItem *seqItem = addText(s.c_str());
175 seqItem->setFont(QFont("Cursive", 12, QFont::Bold));
176 QRectF seqBoundingRect = seqItem->boundingRect();
177 seqItem->setPos(x + w / 2 - seqBoundingRect.width() / 2, y + h / 2 - seqBoundingRect.height() / 2);
178 p->setSeqTextItem(seqItem);
179
180 QRectF textRect(x - w / 2, y + h + 10, 2 * w, 30);
181 addRect(textRect, QPen(Qt::darkCyan), QBrush(Qt::darkCyan));
182 QGraphicsTextItem *nickItem = addText(p->getNick());
183 QRectF textBoundingRect = nickItem->boundingRect();
184 nickItem->setDefaultTextColor(Qt::white);
185 nickItem->setFont(QFont("Cursive", 12, QFont::Bold));
186 nickItem->setPos(x + w / 2 - textBoundingRect.width() / 2, y + h + 15);
187 p->setNickTextItem(nickItem);
188 }
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700189 }
Zhenkai Zhuf474a0a2012-05-30 15:06:29 -0700190}
191