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