1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation;
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 * Author: John Abraham <john.abraham.in@gmail.com>
17 * Contributions: Eugene Kalishenko <ydginster@gmail.com> (Open Source and Linux Laboratory http://dev.osll.ru/)
18 * Dmitrii Shakshin <d.shakshin@gmail.com> (Open Source and Linux Laboratory http://dev.osll.ru/)
19 */
20
21 #include "animnode.h"
22 #include "animresource.h"
23 #include "animatorview.h"
24 #include <QColor>
25
26 NS_LOG_COMPONENT_DEFINE ("AnimNode");
27 namespace netanim
28 {
29
30 AnimNodeMgr * pAnimNodeMgr = 0;
31
AnimNode(uint32_t nodeId,uint32_t nodeSysId,qreal x,qreal y,QString nodeDescription)32 AnimNode::AnimNode (uint32_t nodeId, uint32_t nodeSysId, qreal x, qreal y, QString nodeDescription):
33 m_nodeDescription (0),
34 m_nodeId (nodeId),
35 m_nodeSysId (nodeSysId),
36 m_x (x),
37 m_y (y),
38 m_showNodeId (true),
39 m_showNodeSysId (false),
40 m_resourceId (-1),
41 m_showNodeTrajectory (false),
42 m_showBatteryCapcity (false)
43 {
44 //setVisible (false);
45 setZValue (ANIMNODE_ZVALUE);
46 m_r = 255;
47 m_g = 0;
48 m_b = 0;
49 if (nodeDescription == "")
50 {
51 nodeDescription = QString::number (nodeId);
52 }
53 m_nodeDescription = new QGraphicsTextItem (nodeDescription);
54 m_nodeDescription->setFlag (QGraphicsItem::ItemIgnoresTransformations);
55 setFlag (QGraphicsItem::ItemIsSelectable);
56 }
57
~AnimNode()58 AnimNode::~AnimNode ()
59 {
60 if (m_nodeDescription)
61 {
62 delete m_nodeDescription;
63 }
64 }
65
66 void
showNodeId(bool show)67 AnimNode::showNodeId (bool show)
68 {
69 m_showNodeId = show;
70 m_nodeDescription->setVisible (m_showNodeId);
71 }
72
73 QColor
generateColor(size_t index,uint8_t alpha=0)74 generateColor (size_t index, uint8_t alpha = 0)
75 {
76
77 static const size_t colors[] =
78 { Qt::blue, Qt::magenta, Qt::darkCyan, Qt::darkYellow, Qt::darkRed, Qt::darkMagenta, Qt::darkGreen, Qt::darkBlue,
79 Qt::black, Qt::darkGray, Qt::lightGray };
80 static const size_t COUNT = sizeof (colors) / sizeof (size_t);
81 QColor result;
82
83 if (index < COUNT)
84 result = QColor (Qt::GlobalColor (colors[index]));
85 else
86 {
87 result = QColor (Qt::GlobalColor (colors[index % COUNT]));
88 const int step = 256 * 3 % COUNT;
89
90 result.setRed ((result.red () + step * index) % 255);
91 result.setGreen ((result.blue () + step * index) % 255);
92 result.setBlue (((int)result.green () - step * index) % 255);
93 }
94 if (alpha)
95 result.setAlpha (alpha);
96
97 return result;
98 }
99
100
101 void
showNodeSysId(bool show)102 AnimNode::showNodeSysId (bool show)
103 {
104 if (show)
105 {
106 m_lastColor = this->getColor ();
107 int r, g, b, a;
108 m_lastColor.getRgb(&r, &g, &b, &a);
109 const QColor &color = generateColor (m_nodeSysId, a);
110 color.getRgb (&r, &g, &b, &a);
111 setColor (static_cast<uint8_t> (r), static_cast<uint8_t> (g), static_cast<uint8_t> (b), static_cast<uint8_t> (a));
112 }
113 else
114 {
115 if(m_showNodeSysId)
116 {
117 int r, g, b, a;
118 m_lastColor.getRgb (&r, &g, &b, &a);
119 setColor (r, g, b, a);
120 }
121 }
122 m_showNodeSysId = show;
123 m_nodeDescription->setPlainText (QString::number (m_nodeId) + (m_showNodeSysId ? QString(" SysId:") +
124 QString::number (m_nodeSysId): QString()));
125 }
126
127 bool
isVisibleNodeSysId() const128 AnimNode::isVisibleNodeSysId() const
129 {
130 return m_showNodeSysId;
131 }
132
133 void
updateNodeSysId(uint32_t sysId,bool show)134 AnimNode::updateNodeSysId (uint32_t sysId, bool show)
135 {
136 m_nodeSysId = sysId;
137 //m_nodeSysIdDescription->setPlainText ("sysId: " + QString::number (sysId));
138 showNodeSysId (show);
139 }
140
141 void
updateBatteryCapacityImage(bool show)142 AnimNode::updateBatteryCapacityImage (bool show)
143 {
144
145 m_showBatteryCapcity = show;
146 QString batteryCapacityImagePath(":/resources/battery_icon_");
147 bool result = false;
148 CounterType_t counterType;
149 uint32_t counterId = AnimNodeMgr::getInstance ()->getCounterIdForName ("RemainingEnergy", result, counterType);
150 if (!result)
151 {
152 return;
153 }
154
155 result = false;
156 qreal capacity = getDoubleCounterValue (counterId, result);
157 if (!result)
158 {
159 return;
160 }
161
162 if (capacity > 0.75) batteryCapacityImagePath += "4";
163 else if (capacity > 0.5) batteryCapacityImagePath += "3";
164 else if (capacity > 0.25) batteryCapacityImagePath += "2";
165 else if (capacity >= 0) batteryCapacityImagePath += "1";
166 else batteryCapacityImagePath += "0";
167 // NS_LOG_DEBUG ("Capacity:" << batteryCapacityImagePath.toAscii().data());
168
169 batteryCapacityImagePath += ".png";
170 if(show)
171 {
172 m_batteryPixmap = QPixmap (batteryCapacityImagePath);
173 }
174 if (!show)
175 {
176 m_batteryPixmap = QPixmap ();
177 }
178
179 }
180
181
182
183
184 uint32_t
getUint32CounterValue(uint32_t counterId,bool & result)185 AnimNode::getUint32CounterValue (uint32_t counterId, bool & result)
186 {
187 result = false;
188 if (m_counterIdToValuesUint32.find (counterId) == m_counterIdToValuesUint32.end ())
189 return -1;
190 result = true;
191 return m_counterIdToValuesUint32[counterId];
192 }
193
194
195
196
197 qreal
getDoubleCounterValue(uint32_t counterId,bool & result)198 AnimNode::getDoubleCounterValue (uint32_t counterId, bool & result)
199 {
200 result = false;
201 if (m_counterIdToValuesDouble.find (counterId) == m_counterIdToValuesDouble.end ())
202 return -1;
203 result = true;
204 return m_counterIdToValuesDouble[counterId];
205 }
206
207 void
updateCounter(uint32_t counterId,qreal counterValue,CounterType_t counterType)208 AnimNode::updateCounter (uint32_t counterId, qreal counterValue, CounterType_t counterType)
209 {
210 if (counterType == DOUBLE_COUNTER)
211 {
212 m_counterIdToValuesDouble[counterId] = counterValue;
213 }
214
215 if (counterType == UINT32_COUNTER)
216 {
217 m_counterIdToValuesUint32[counterId] = counterValue;
218 }
219 }
220
221
222
223 int
getResourceId()224 AnimNode::getResourceId ()
225 {
226 return m_resourceId;
227 }
228
229
230 void
setResource(int resourceId)231 AnimNode::setResource (int resourceId)
232 {
233 m_resourceId = resourceId;
234 QString resourcePath = AnimResourceManager::getInstance ()->get (resourceId);
235 //NS_LOG_DEBUG ("Res:" << resourcePath.toAscii ().data ());
236 QPixmap pix;
237 if (resourcePath.endsWith (".png"))
238 pix = QPixmap (resourcePath, "png");
239 else if (resourcePath.endsWith (".svg"))
240 pix = QPixmap (resourcePath, "svg");
241 setPixmap (pix);
242 update ();
243 }
244
245 void
setColor(uint8_t r,uint8_t g,uint8_t b,uint8_t alpha)246 AnimNode::setColor (uint8_t r, uint8_t g, uint8_t b, uint8_t alpha)
247 {
248 m_r = r;
249 m_g = g;
250 m_b = b;
251 m_alpha = alpha;
252 ResizeableItem::setColor (r, g, b, alpha);
253 update ();
254 }
255
256 QColor
getColor()257 AnimNode::getColor ()
258 {
259 QColor c (m_r, m_g, m_b, 255);
260 return c;
261 }
262
263 qreal
getWidth()264 AnimNode::getWidth ()
265 {
266 return m_width;
267 }
268
269
270
271 qreal
getX()272 AnimNode::getX ()
273 {
274 return m_x;
275 }
276
277 qreal
getY()278 AnimNode::getY ()
279 {
280 return m_y;
281 }
282
283
284 void
setPos(qreal x,qreal y)285 AnimNode::setPos (qreal x, qreal y)
286 {
287 m_x = x;
288 m_y = y;
289 QGraphicsItem::setPos (x, y);
290 }
291
292 void
setX(qreal x)293 AnimNode::setX (qreal x)
294 {
295 m_x = x;
296 }
297
298
299 bool
getShowNodeTrajectory()300 AnimNode::getShowNodeTrajectory ()
301 {
302 return m_showNodeTrajectory;
303 }
304
305 void
setShowNodeTrajectory(bool showNodeTrajectory)306 AnimNode::setShowNodeTrajectory (bool showNodeTrajectory)
307 {
308 m_showNodeTrajectory = showNodeTrajectory;
309 }
310
311
312 void
setY(qreal y)313 AnimNode::setY (qreal y)
314 {
315 m_y = y;
316 }
317
318 uint32_t
getNodeId()319 AnimNode::getNodeId ()
320 {
321 return m_nodeId;
322 }
323
324 uint32_t
getNodeSysId()325 AnimNode::getNodeSysId ()
326 {
327 return m_nodeSysId;
328 }
329
330 QGraphicsTextItem *
getDescription()331 AnimNode::getDescription ()
332 {
333 return m_nodeDescription;
334 }
335
getCenter()336 QPointF AnimNode::getCenter ()
337 {
338 //return sceneBoundingRect ().center ();
339 return QPointF (m_x, m_y);
340 }
setNodeDescription(QString description)341 void AnimNode::setNodeDescription (QString description)
342 {
343 m_nodeDescription->setPlainText (description);
344 }
345
paint(QPainter * painter,const QStyleOptionGraphicsItem * option,QWidget * widget)346 void AnimNode::paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
347 {
348 ResizeableItem::paint (painter, option, widget);
349 if (!m_batteryPixmap.isNull ())
350 {
351 updateBatteryCapacityImage (m_showBatteryCapcity);
352 QPointF bottomLeft = sceneBoundingRect ().bottomLeft ();
353 //NS_LOG_DEBUG ("Pix Width:" << m_batteryPixmap->width());
354 bottomLeft = QPointF (-1, 1);
355 painter->save ();
356 painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing | QPainter::NonCosmeticDefaultPen, true); painter->scale (0.5, 1);
357 painter->drawPixmap (bottomLeft.x (), bottomLeft.y (), 5, 5, m_batteryPixmap);
358
359 painter->restore ();
360 }
361 }
362
363
mouseMoveEvent(QGraphicsSceneMouseEvent * event)364 void AnimNode::mouseMoveEvent (QGraphicsSceneMouseEvent *event)
365 {
366 ResizeableItem::mouseMoveEvent (event);
367 if (m_nodeDescription)
368 {
369 m_nodeDescription->setPos (sceneBoundingRect ().bottomRight ());
370 update ();
371 }
372 }
373
374 AnimNode::Ipv4Set_t
getIpv4Addresses()375 AnimNode::getIpv4Addresses ()
376 {
377 return m_ipv4Set;
378 }
379
380 AnimNode::Ipv6Set_t
getIpv6Addresses()381 AnimNode::getIpv6Addresses ()
382 {
383 return m_ipv6Set;
384 }
385
386 AnimNode::MacVector_t
getMacAddresses()387 AnimNode::getMacAddresses ()
388 {
389 return m_macVector;
390 }
391
392 void
addIpv4Address(QString ip)393 AnimNode::addIpv4Address (QString ip)
394 {
395 m_ipv4Set.insert (ip);
396 }
397
398 void
addIpv6Address(QString ip)399 AnimNode::addIpv6Address (QString ip)
400 {
401 m_ipv6Set.insert (ip);
402 }
403
404 void
addMacAddress(QString mac)405 AnimNode::addMacAddress (QString mac)
406 {
407 m_macVector.push_back (mac);
408 }
409
410 bool
hasIpv4(QString ip)411 AnimNode::hasIpv4 (QString ip)
412 {
413 bool result = false;
414 QStringList quads = ip.split (".");
415 if (quads.count () == 4)
416 {
417 if (quads.at (3) == "255")
418 return true;
419 for (Ipv4Set_t::const_iterator i = m_ipv4Set.begin ();
420 i != m_ipv4Set.end ();
421 ++i)
422 {
423 if (*i == ip)
424 {
425 //QDEBUG (ip);
426 return true;
427 }
428 }
429 }
430
431 return result;
432 }
433
434
435 bool
hasMac(QString mac)436 AnimNode::hasMac (QString mac)
437 {
438 bool result = false;
439 QStringList bytes = mac.split (":");
440 if (bytes.count () == 6)
441 {
442 for (MacVector_t::const_iterator i = m_macVector.begin ();
443 i != m_macVector.end ();
444 ++i)
445 {
446 if (*i == mac)
447 {
448 return true;
449 }
450 }
451 }
452
453 return result;
454 }
455
456
AnimNodeMgr()457 AnimNodeMgr::AnimNodeMgr ():
458 m_minX (0),
459 m_minY (0),
460 m_maxX (0),
461 m_maxY (0)
462 {
463
464 }
465
getInstance()466 AnimNodeMgr * AnimNodeMgr::getInstance ()
467 {
468 if (!pAnimNodeMgr)
469 {
470 pAnimNodeMgr = new AnimNodeMgr;
471 }
472 return pAnimNodeMgr;
473 }
474
475
add(uint32_t nodeId,uint32_t nodeSysId,qreal x,qreal y,QString nodeDescription)476 AnimNode * AnimNodeMgr::add (uint32_t nodeId, uint32_t nodeSysId, qreal x, qreal y, QString nodeDescription)
477 {
478 if (m_nodes.find (nodeId) != m_nodes.end ())
479 {
480 //NS_FATAL_ERROR ("NodeId:" << nodeId << " Already exists");
481 }
482 QPixmap pix (":/resources/ns3logo2.png","png");
483 AnimNode * node = new AnimNode (nodeId, nodeSysId, x, y, nodeDescription);
484 node->setPos (x, y);
485 //node->setPixmap (pix);
486 m_nodes[nodeId] = node;
487 m_minX = qMin (m_minX, x);
488 m_minY = qMin (m_minY, y);
489 m_maxX = qMax (m_maxX, x);
490 m_maxY = qMax (m_maxY, y);
491
492 return node;
493 }
494
495
496 void
setSize(qreal width,qreal height)497 AnimNodeMgr::setSize (qreal width, qreal height)
498 {
499 for (NodeIdAnimNodeMap_t::const_iterator i = m_nodes.begin ();
500 i != m_nodes.end ();
501 ++i)
502 {
503 AnimNode * animNode = i->second;
504 animNode->setSize (width, height);
505 }
506 }
507
508
509 void
showRemainingBatteryCapacity(bool show)510 AnimNodeMgr::showRemainingBatteryCapacity (bool show)
511 {
512 for (NodeIdAnimNodeMap_t::const_iterator i = m_nodes.begin ();
513 i != m_nodes.end ();
514 ++i)
515 {
516 AnimNode * animNode = i->second;
517 animNode->updateBatteryCapacityImage (show);
518 }
519 }
520
getNode(uint32_t nodeId)521 AnimNode * AnimNodeMgr::getNode (uint32_t nodeId)
522 {
523 return m_nodes[nodeId];
524 }
525
526 uint32_t
getCount()527 AnimNodeMgr::getCount ()
528 {
529 return m_nodes.size ();
530 }
531
532
533 QPointF
getMinPoint()534 AnimNodeMgr::getMinPoint ()
535 {
536 return QPointF (m_minX, m_minY);
537 }
538
539 QPointF
getMaxPoint()540 AnimNodeMgr::getMaxPoint ()
541 {
542 qreal m = qMax (m_maxX, m_maxY);
543 return QPointF (m, m);
544 }
545
546
547 void
systemReset()548 AnimNodeMgr::systemReset ()
549 {
550 m_nodes.clear ();
551 m_minX = 0;
552 m_minY = 0;
553 m_maxX = 0;
554 m_maxY = 0;
555 m_counterIdToNamesDouble.clear ();
556 m_counterIdToNamesUint32.clear ();
557 }
558
559
560 void
addIpv4Address(uint32_t nodeId,QString ip)561 AnimNodeMgr::addIpv4Address (uint32_t nodeId, QString ip)
562 {
563 getNode (nodeId)->addIpv4Address (ip);
564 }
565
566 void
addIpv6Address(uint32_t nodeId,QString ip)567 AnimNodeMgr::addIpv6Address (uint32_t nodeId, QString ip)
568 {
569 getNode (nodeId)->addIpv6Address (ip);
570 }
571
572 void
addMacAddress(uint32_t nodeId,QString mac)573 AnimNodeMgr::addMacAddress (uint32_t nodeId, QString mac)
574 {
575 getNode (nodeId)->addMacAddress (mac);
576 }
577
578 void
showNodeId(bool show)579 AnimNodeMgr::showNodeId (bool show)
580 {
581 for (NodeIdAnimNodeMap_t::const_iterator i = m_nodes.begin ();
582 i != m_nodes.end ();
583 ++i)
584 {
585 AnimNode * animNode = i->second;
586 animNode->showNodeId (show);
587 }
588
589 }
590
591 void
showNodeSysId(bool show)592 AnimNodeMgr::showNodeSysId (bool show)
593 {
594 for (NodeIdAnimNodeMap_t::const_iterator i = m_nodes.begin ();
595 i != m_nodes.end ();
596 ++i)
597 {
598 AnimNode * animNode = i->second;
599 animNode->showNodeSysId (show);
600 }
601 }
602
603
604 AnimNodeMgr::TimePosVector_t
getPositions(uint32_t nodeId)605 AnimNodeMgr::getPositions (uint32_t nodeId)
606 {
607 return m_nodePositions[nodeId];
608 }
609
610 void
addAPosition(uint32_t nodeId,qreal t,QPointF pos)611 AnimNodeMgr::addAPosition (uint32_t nodeId, qreal t, QPointF pos)
612 {
613 if (m_nodePositions.find (nodeId) == m_nodePositions.end ())
614 {
615 TimePosVector_t posVector;
616 m_nodePositions[nodeId] = posVector;
617 }
618 TimePosVector_t & pv = m_nodePositions[nodeId];
619 TimePosition_t tp;
620 tp.p = pos;
621 tp.t = t;
622 pv.push_back (tp);
623 }
624
625
626 void
addNodeCounterUint32(uint32_t counterId,QString counterName)627 AnimNodeMgr::addNodeCounterUint32 (uint32_t counterId, QString counterName)
628 {
629 m_counterIdToNamesUint32[counterId] = counterName;
630 }
631
632 void
addNodeCounterDouble(uint32_t counterId,QString counterName)633 AnimNodeMgr::addNodeCounterDouble (uint32_t counterId, QString counterName)
634 {
635 m_counterIdToNamesDouble[counterId] = counterName;
636 }
637
638 void
updateNodeCounter(uint32_t nodeId,uint32_t counterId,qreal counterValue)639 AnimNodeMgr::updateNodeCounter (uint32_t nodeId, uint32_t counterId, qreal counterValue)
640 {
641 AnimNode * animNode = getNode (nodeId);
642 AnimNode::CounterType_t ct;
643 bool counterFound = false;
644 for (CounterIdName_t::const_iterator i = m_counterIdToNamesDouble.begin ();
645 i != m_counterIdToNamesDouble.end ();
646 ++i)
647 {
648 if (counterId == i->first)
649 {
650 ct = AnimNode::DOUBLE_COUNTER;
651 counterFound = true;
652 break;
653 }
654 }
655 if (!counterFound)
656 {
657 for (CounterIdName_t::const_iterator i = m_counterIdToNamesUint32.begin ();
658 i != m_counterIdToNamesUint32.end ();
659 ++i)
660 {
661 if (counterId == i->first)
662 {
663 ct = AnimNode::UINT32_COUNTER;
664 counterFound = true;
665 break;
666 }
667 }
668 }
669 animNode->updateCounter (counterId, counterValue, ct);
670 }
671
672
673 AnimNodeMgr::CounterIdName_t
getUint32CounterNames()674 AnimNodeMgr::getUint32CounterNames ()
675 {
676 return m_counterIdToNamesUint32;
677 }
678
679 AnimNodeMgr::CounterIdName_t
getDoubleCounterNames()680 AnimNodeMgr::getDoubleCounterNames ()
681 {
682 return m_counterIdToNamesDouble;
683 }
684
685
686
687 uint32_t
getCounterIdForName(QString counterName,bool & result,AnimNode::CounterType_t & counterType)688 AnimNodeMgr::getCounterIdForName (QString counterName, bool &result, AnimNode::CounterType_t & counterType)
689 {
690 result = false;
691 for (CounterIdName_t::const_iterator i = m_counterIdToNamesDouble.begin ();
692 i != m_counterIdToNamesDouble.end ();
693 ++i)
694 {
695 QString n = i->second;
696 if (n == counterName)
697 {
698 result = true;
699 counterType = AnimNode::DOUBLE_COUNTER;
700 return i->first;
701 }
702 }
703 for (CounterIdName_t::const_iterator i = m_counterIdToNamesUint32.begin ();
704 i != m_counterIdToNamesUint32.end ();
705 ++i)
706 {
707 QString n = i->second;
708 if (n == counterName)
709 {
710 result = true;
711 counterType = AnimNode::UINT32_COUNTER;
712 return i->first;
713 }
714 }
715 return -1;
716 }
717
718
719
720 }
721
722