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: Dmitrii Shakshin <d.shakshin@gmail.com> (Open Source and Linux Laboratory http://dev.osll.ru/)
18  *                Makhtar Diouf <makhtar.diouf@gmail.com>
19  */
20 
21 
22 #include "animatorscene.h"
23 #include "animatorview.h"
24 #include "animatormode.h"
25 #include "animpropertybrowser.h"
26 #include "logqt.h"
27 
28 namespace netanim
29 {
30 
31 NS_LOG_COMPONENT_DEFINE ("AnimatorScene");
32 AnimatorScene * pAnimatorScene = 0;
33 
AnimatorScene()34 AnimatorScene::AnimatorScene ():
35   QGraphicsScene (0, 0, ANIMATORSCENE_USERAREA_WIDTH, ANIMATORSCENE_USERAREA_WIDTH),
36   m_backgroundImage (0),
37   m_enableMousePositionLabel (false)
38 {
39   m_mousePositionLabel = new QLabel ("");
40   m_mousePositionLabel->setSizePolicy (QSizePolicy::Minimum, QSizePolicy::Minimum);
41   m_mousePositionProxyWidget = addWidget (m_mousePositionLabel, Qt::ToolTip);
42   m_mousePositionProxyWidget->setFlag (QGraphicsItem::ItemIgnoresTransformations);
43   m_nGridLines = GRID_LINES_DEFAULT;
44   m_showGrid = true;
45 
46   m_sceneInfoText = new QGraphicsSimpleTextItem;
47   m_sceneInfoText->setFlag(QGraphicsItem::ItemIgnoresTransformations);
48   addItem(m_sceneInfoText);
49 
50   initGridCoordinates ();
51 }
52 
53 
54 AnimatorScene *
getInstance()55 AnimatorScene::getInstance ()
56 {
57   if (!pAnimatorScene)
58     {
59       pAnimatorScene = new AnimatorScene;
60     }
61   return pAnimatorScene;
62 }
63 
64 void
systemReset()65 AnimatorScene::systemReset ()
66 {
67   purgeNodeTrajectories ();
68   purgeAnimatedPackets ();
69   purgeAnimatedNodes ();
70   purgeAnimatedLinks ();
71   resetInterfaceTexts ();
72   setSceneRect (0, 0, ANIMATORSCENE_USERAREA_WIDTH, ANIMATORSCENE_USERAREA_WIDTH);
73   resetGrid ();
74   if (m_backgroundImage)
75     {
76       removeItem (m_backgroundImage);
77       delete (m_backgroundImage);
78       m_backgroundImage = 0;
79     }
80 }
81 
testSlot()82 void AnimatorScene::testSlot ()
83 {
84 
85 }
86 
87 void
setSimulationBoundaries(QPointF minPoint,QPointF maxPoint)88 AnimatorScene::setSimulationBoundaries (QPointF minPoint, QPointF maxPoint)
89 {
90   m_minPoint = minPoint;
91   m_maxPoint = maxPoint;
92   qreal boundaryWidth = m_maxPoint.x () * 0.1;
93   qreal boundaryHeight = m_maxPoint.y () * 0.2;
94   qreal boundary = qMax (boundaryWidth, boundaryHeight);
95 
96   m_sceneMinPoint = QPointF (m_minPoint.x () - boundary, m_minPoint.y () - boundary);
97   m_sceneMaxPoint = QPointF (m_maxPoint.x () + boundary, m_maxPoint.y () + boundary);
98 
99   // Make it square
100   qreal minimum = qMin (m_sceneMinPoint.x (), m_sceneMinPoint.y ());
101   m_sceneMinPoint = QPointF (minimum, minimum);
102   qreal maximum = qMax (m_sceneMaxPoint.x (), m_sceneMaxPoint.y ());
103   m_sceneMaxPoint = QPointF (maximum, maximum);
104   if ((m_sceneMaxPoint.x () == 0) && (m_sceneMaxPoint.y () == 0))
105     {
106       m_sceneMaxPoint = QPointF (1, 1);
107     }
108 
109   setSceneRect (QRectF (m_sceneMinPoint, m_sceneMaxPoint));
110 }
111 
112 void
enableMousePositionLabel(bool enable)113 AnimatorScene::enableMousePositionLabel (bool enable)
114 {
115   m_enableMousePositionLabel = enable;
116 }
117 
118 
119 void
setBackgroundX(qreal x)120 AnimatorScene::setBackgroundX (qreal x)
121 {
122   if (!m_backgroundImage)
123     return;
124   m_backgroundImage->setX(x);
125 }
126 
127 void
setBackgroundY(qreal y)128 AnimatorScene::setBackgroundY (qreal y)
129 {
130   if (!m_backgroundImage)
131     return;
132   m_backgroundImage->setY(y);
133 }
134 
setScale(QGraphicsPixmapItem * img,qreal x,qreal y)135 void AnimatorScene::setScale (QGraphicsPixmapItem* img, qreal x, qreal y)
136 {
137   img->setTransform (QTransform::fromScale (x, y), true);
138 }
139 
140 void
setBackgroundScaleX(qreal x)141 AnimatorScene::setBackgroundScaleX (qreal x)
142 {
143   if (!m_backgroundImage)
144     return;
145   //m_backgroundImage->setTransform (m_originalBackgroundTransform);
146   setScale (m_backgroundImage, x, 1);
147 }
148 
149 
150 void
setBackgroundScaleY(qreal y)151 AnimatorScene::setBackgroundScaleY (qreal y)
152 {
153   if (!m_backgroundImage)
154     return;
155   //m_backgroundImage->setTransform (m_originalBackgroundTransform);
156   setScale (m_backgroundImage, 1, y);
157 }
158 
159 void
setBackgroundOpacity(qreal opacity)160 AnimatorScene::setBackgroundOpacity (qreal opacity)
161 {
162   if (!m_backgroundImage)
163     return;
164   m_backgroundImage->setOpacity (opacity);
165 }
166 
167 QGraphicsPixmapItem *
getBackgroundImage()168 AnimatorScene::getBackgroundImage ()
169 {
170   return m_backgroundImage;
171 }
172 
173 void
setBackgroundImage(QString fileName,qreal x,qreal y,qreal scaleX,qreal scaleY,qreal opacity)174 AnimatorScene::setBackgroundImage (QString fileName, qreal x, qreal y, qreal scaleX, qreal scaleY, qreal opacity)
175 {
176 
177   QPixmap pix (fileName);
178   if (pix.isNull ())
179     {
180       AnimatorMode::getInstance ()->showPopup ("Failed to load background image:" + fileName);
181       return;
182     }
183   if (m_backgroundImage)
184     {
185       removeItem (m_backgroundImage);
186       delete m_backgroundImage;
187       m_backgroundImage = 0;
188     }
189   m_backgroundImage = new QGraphicsPixmapItem;
190   m_backgroundImage->setPixmap (pix);
191   addItem (m_backgroundImage);
192   m_backgroundImage->setPos (x, y);
193   m_backgroundImage->setFlags (QGraphicsItem::ItemIsMovable|QGraphicsItem::ItemIsSelectable);
194   m_originalBackgroundTransform = m_backgroundImage->transform ();
195   setScale (m_backgroundImage, scaleX, scaleY); // scale (scaleX, scaleY);
196   m_backgroundImage->setZValue (ANIMBACKGROUND_ZVALUE);
197   m_backgroundImage->setOpacity (opacity);
198 
199 }
200 
201 void
setSceneInfoText(QString text,bool show)202 AnimatorScene::setSceneInfoText(QString text, bool show)
203 {
204     m_sceneInfoText->setText (text);
205     m_sceneInfoText->setVisible (show);
206     QFontMetrics fm (font ());
207     QRectF r = sceneRect ();
208     QPointF pos = QPointF ((sceneRect ().width () - fm.width (text))/2, r.center ().y ());
209     m_sceneInfoText->setPos (pos);
210 }
211 
212 
213 
214 void
setShowNodeTrajectory(AnimNode * animNode)215 AnimatorScene::setShowNodeTrajectory (AnimNode *animNode)
216 {
217   uint32_t nodeId = animNode->getNodeId ();
218   if (m_nodeTrajectory.find (nodeId) == m_nodeTrajectory.end ())
219     {
220       QPainterPath path;
221       AnimNodeMgr::TimePosVector_t positions =  AnimNodeMgr::getInstance ()->getPositions (animNode->getNodeId ());
222       for (AnimNodeMgr::TimePosVector_t::const_iterator i = positions.begin ();
223           i != positions.end ();
224           ++i)
225         {
226           TimePosition_t tp = *i;
227           QPointF pt = tp.p;
228           path.moveTo (pt);
229           break;
230         }
231 
232 
233       positions =  AnimNodeMgr::getInstance ()->getPositions (animNode->getNodeId ());
234       for (AnimNodeMgr::TimePosVector_t::const_iterator i = positions.begin ();
235           i != positions.end ();
236           ++i)
237         {
238           TimePosition_t tp = *i;
239           QPointF pt = tp.p;
240           path.lineTo (pt);
241         }
242       QGraphicsPathItem * pathItem = addPath (path);
243       QPen pen;
244       pen.setCosmetic (true);
245       pathItem->setPen (pen);
246       m_nodeTrajectory[nodeId] = pathItem;
247     }
248   m_nodeTrajectory[nodeId]->setVisible (animNode->getShowNodeTrajectory ());
249 }
250 
251 void
addWirelessCircle(QRectF r)252 AnimatorScene::addWirelessCircle (QRectF r)
253 {
254   //NS_LOG_DEBUG ("WirelessCircles Rect:" << r);
255   if (r.width() == 0)
256     return;
257   AnimWirelessCircles * w = new AnimWirelessCircles ();
258   QPen p = w->pen ();
259   p.setCosmetic (true);
260   p.setColor (QColor (0, 0, 255, 50));
261   w->setPen (p);
262   w->setRect (r);
263   addItem (w);
264   m_animatedWirelessCircles.push_back (w);
265 }
266 
267 void
purgeAnimatedNodes()268 AnimatorScene::purgeAnimatedNodes ()
269 {
270   for (QVector <AnimNode*>::const_iterator i = m_animatedNodes.begin ();
271       i != m_animatedNodes.end ();
272       ++i)
273     {
274       AnimNode * animNode = *i;
275       animNode->setVisible (false);
276       QGraphicsTextItem * ti = animNode->getDescription ();
277       removeItem (animNode);
278       removeItem (ti);
279       delete animNode;
280     }
281   m_animatedNodes.clear ();
282   AnimNodeMgr::getInstance ()->systemReset ();
283 
284 }
285 
286 void
purgeNodeTrajectories()287 AnimatorScene::purgeNodeTrajectories ()
288 {
289   for (NodeTrajectoryMap_t::const_iterator i = m_nodeTrajectory.begin ();
290        i != m_nodeTrajectory.end ();
291        ++i)
292     {
293       i->second->setVisible (false);
294       removeItem (i->second);
295     }
296   m_nodeTrajectory.clear ();
297 }
298 
299 void
purgeAnimatedLinks()300 AnimatorScene::purgeAnimatedLinks ()
301 {
302 
303   for (QVector <AnimLink *>::const_iterator i = m_animatedLinks.begin ();
304       i != m_animatedLinks.end ();
305       ++i)
306     {
307       AnimLink * animLink = *i;
308       animLink->setVisible (false);
309       removeItem (animLink);
310       delete animLink;
311 
312     }
313   m_animatedLinks.clear ();
314   LinkManager::getInstance ()->systemReset ();
315 
316 }
317 
318 
319 void
showAnimatedPackets(bool show)320 AnimatorScene::showAnimatedPackets (bool show)
321 {
322   for (std::map <AnimPacket *, AnimPacket *>::const_iterator i = m_wirelessAnimatedPackets.begin ();
323       i != m_wirelessAnimatedPackets.end ();
324       ++i)
325     {
326       AnimPacket * p = i->first;
327       p->setVisible (show);
328     }
329   for (std::map <AnimPacket *, AnimPacket *>::const_iterator i = m_wiredAnimatedPackets.begin ();
330       i != m_wiredAnimatedPackets.end ();
331       ++i)
332     {
333       AnimPacket * p = i->first;
334       p->setVisible (show);
335     }
336 
337   for (QVector <AnimWirelessCircles *>::const_iterator i = m_animatedWirelessCircles.begin ();
338       i != m_animatedWirelessCircles.end ();
339       ++i)
340     {
341       AnimWirelessCircles * w = *i;
342       w->setVisible (show);
343     }
344 }
345 
346 
347 void
purgeWirelessPackets()348 AnimatorScene::purgeWirelessPackets ()
349 {
350   for (std::map <AnimPacket *, AnimPacket *>::const_iterator i = m_wirelessAnimatedPackets.begin ();
351       i != m_wirelessAnimatedPackets.end ();
352       ++i)
353     {
354       AnimPacket * p = i->first;
355       p->setVisible (false);
356       removeItem (p->getInfoTextItem ());
357       removeItem (p);
358       delete p;
359     }
360   m_wirelessAnimatedPackets.clear ();
361   for (QVector <AnimWirelessCircles *>::const_iterator i = m_animatedWirelessCircles.begin ();
362       i != m_animatedWirelessCircles.end ();
363       ++i)
364     {
365       AnimWirelessCircles * w = *i;
366       w->setVisible (false);
367       removeItem (w);
368       delete w;
369     }
370   m_animatedWirelessCircles.clear ();
371 
372 }
373 void
purgeAnimatedPackets()374 AnimatorScene::purgeAnimatedPackets ()
375 {
376   for (std::map <AnimPacket *, AnimPacket *>::const_iterator i = m_wiredAnimatedPackets.begin ();
377       i != m_wiredAnimatedPackets.end ();
378       ++i)
379     {
380       AnimPacket * p = i->first;
381       p->setVisible (false);
382       removeItem (p->getInfoTextItem ());
383       removeItem (p);
384       delete p;
385     }
386   m_wiredAnimatedPackets.clear ();
387   for (std::map <AnimPacket *, AnimPacket *>::const_iterator i = m_wirelessAnimatedPackets.begin ();
388       i != m_wirelessAnimatedPackets.end ();
389       ++i)
390     {
391       AnimPacket * p = i->first;
392       p->setVisible (false);
393       removeItem (p->getInfoTextItem ());
394       removeItem (p);
395       delete p;
396     }
397   m_wirelessAnimatedPackets.clear ();
398 
399   for (QVector <AnimWirelessCircles *>::const_iterator i = m_animatedWirelessCircles.begin ();
400       i != m_animatedWirelessCircles.end ();
401       ++i)
402     {
403       AnimWirelessCircles * w = *i;
404       w->setVisible (false);
405       removeItem (w);
406       delete w;
407     }
408   m_animatedWirelessCircles.clear ();
409 }
410 
411 void
addLink(AnimLink * animLink)412 AnimatorScene::addLink (AnimLink *animLink)
413 {
414   addItem (animLink);
415   m_animatedLinks.push_back (animLink);
416 }
417 
418 void
addNode(AnimNode * animNode)419 AnimatorScene::addNode (AnimNode *animNode)
420 {
421   addItem (animNode);
422   m_animatedNodes.push_back (animNode);
423   animNode->setPos (animNode->getX (), animNode->getY ());
424   addItem (animNode->getDescription ());
425   animNode->getDescription ()->setPos (animNode->sceneBoundingRect ().bottomRight ());
426 }
427 
428 void
addWirelessPacket(AnimPacket * p)429 AnimatorScene::addWirelessPacket (AnimPacket *p)
430 {
431   addItem (p);
432   //p->getInfoTextItem ()->setPos (p->boundingRect ().bottomLeft ());
433   m_wirelessAnimatedPackets[p] = p;
434 }
435 
436 
437 void
removeWiredPacket(AnimPacket * p)438 AnimatorScene::removeWiredPacket (AnimPacket *p)
439 {
440   m_wiredAnimatedPackets.erase (p);
441   p->setVisible (false);
442   removeItem (p);
443 }
444 
445 
446 void
removeWirelessPacket(AnimPacket * p)447 AnimatorScene::removeWirelessPacket (AnimPacket *p)
448 {
449   p->setVisible (false);
450   m_wirelessAnimatedPackets.erase (p);
451   removeItem (p);
452 }
453 
454 
455 void
addWiredPacket(AnimPacket * p)456 AnimatorScene::addWiredPacket (AnimPacket *p)
457 {
458   addItem (p);
459   //p->getInfoTextItem ()->setPos (p->boundingRect ().bottomLeft ());
460   m_wiredAnimatedPackets[p] = p;
461 }
462 
463 
464 void
setMousePositionLabel(QPointF pos)465 AnimatorScene::setMousePositionLabel (QPointF pos)
466 {
467 
468   //QString string = "    (" + QString::number (qRound (pos.x ())) + "," + QString::number (qRound (pos.y ())) + ")";
469   QString string = "    (" + QString::number ( (pos.x ())) + "," + QString::number ( (pos.y ())) + ")";
470 
471   m_mousePositionLabel->setText (string);
472   m_mousePositionProxyWidget->setPos (pos.x (), pos.y ());
473   m_mousePositionLabel->adjustSize ();
474 
475 }
476 
477 void
showMousePositionLabel(bool show)478 AnimatorScene::showMousePositionLabel (bool show)
479 {
480   m_mousePositionProxyWidget->setVisible (show);
481 }
482 
483 
484 void
mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event)485 AnimatorScene::mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event)
486 {
487   QList <QGraphicsItem *> list = items (event->scenePos ());
488   foreach (QGraphicsItem * i, list)
489     {
490       if (i->type () == ANIMNODE_TYPE)
491         {
492 
493           AnimNode * animNode = qgraphicsitem_cast <AnimNode *> (i);
494           if (animNode)
495             {
496               AnimPropertyBroswer::getInstance ()->setCurrentNodeId (animNode->getNodeId ());
497               AnimatorMode::getInstance ()->openPropertyBroswer ();
498               break;
499             }
500         }
501     }
502 }
503 
504 void
mouseMoveEvent(QGraphicsSceneMouseEvent * event)505 AnimatorScene::mouseMoveEvent (QGraphicsSceneMouseEvent *event)
506 {
507   if (m_enableMousePositionLabel)
508     {
509       QPointF scenePos = event->scenePos ();
510     //   QString s = "Mouse:" + QString::number (event->scenePos ().x ()) + "," + QString::number (event->scenePos ().y ());
511     //   qDebug (s.toAscii ().data ());
512       setMousePositionLabel (scenePos);
513       if ((scenePos.x () < 0) ||
514           (scenePos.y () < 0))
515         {
516           showMousePositionLabel (false);
517         }
518       else
519         {
520           showMousePositionLabel (true);
521         }
522     }
523   return QGraphicsScene::mouseMoveEvent (event);
524 }
525 
526 
527 QVector <QGraphicsSimpleTextItem *>
getGridCoordinatesItems()528 AnimatorScene::getGridCoordinatesItems ()
529 {
530   return m_gridCoordinates;
531 }
532 
533 
534 void
initGridCoordinates()535 AnimatorScene::initGridCoordinates ()
536 {
537   for (int i = 0; i < m_gridCoordinates.size (); ++i)
538     {
539       QGraphicsSimpleTextItem * item = m_gridCoordinates[i];
540       removeItem (item);
541       delete item;
542     }
543   m_gridCoordinates.clear ();
544   for (int i = 0; i < 9; i++) // only 9 coordinates will be marked
545     {
546       QGraphicsSimpleTextItem * item = new QGraphicsSimpleTextItem;
547       item->setFlag (QGraphicsItem::ItemIgnoresTransformations);
548       m_gridCoordinates.push_back (item);
549       addItem (item);
550 
551     }
552   markGridCoordinates ();
553 
554 }
555 
556 void
markGridCoordinates()557 AnimatorScene::markGridCoordinates ()
558 {
559   QRectF simulationRect (m_minPoint, m_maxPoint);
560   if ((simulationRect.width () == 0) && (simulationRect.height () == 0))
561     return;
562   int i = 0;
563   for (qreal x = 0; x <= simulationRect.right () ; x = x + (simulationRect.right ()/2))
564     for (qreal y = 0; y <= simulationRect.bottom () ; y = y + (simulationRect.bottom ()/2))
565       {
566         if (i == 9)
567           return;
568         QString text = QString::number (x, 'f', 1)
569                        + ","
570                        + QString::number (y, 'f', 1);
571         m_gridCoordinates[i]->setText (text);
572         m_gridCoordinates[i]->setPos (QPointF (x, y));
573         m_gridCoordinates[i]->setVisible (m_showGrid);
574         i++;
575       }
576 
577 }
578 
579 void
addGrid()580 AnimatorScene::addGrid ()
581 {
582   m_showGrid = true;
583   qreal maximum = qMax (m_maxPoint.x (), m_maxPoint.y ());
584   QRectF gridRect (QPointF (0, 0), QPointF (maximum, maximum));
585   qreal xStep = (gridRect.right ())/ (m_nGridLines-1);
586   qreal yStep = (gridRect.bottom ())/ (m_nGridLines-1);
587   //xStep = ceil (xStep);
588   //yStep = ceil (yStep);
589   QPen pen (QColor (100, 100, 155, 125));
590   pen.setCosmetic (true);
591 
592   // draw horizontal grid
593   qreal y = 0;
594   qreal x = 0;
595   for (int c = 0; c < m_nGridLines; ++c, y += yStep)
596     {
597       m_gridLines.push_back (addLine (0, y, gridRect.right (), y, pen));
598     }
599   // now draw vertical grid
600   for (int c = 0; c < m_nGridLines; ++c, x += xStep)
601     {
602       m_gridLines.push_back (addLine (x, 0, x,  gridRect.bottom (), pen));
603     }
604   initGridCoordinates ();
605   markGridCoordinates ();
606 
607 
608 }
609 
610 QRectF
getBoundaryRect()611 AnimatorScene::getBoundaryRect ()
612 {
613   return QRectF (m_sceneMinPoint, m_sceneMaxPoint);
614 }
615 
616 void
setGridLinesCount(int nGridLines)617 AnimatorScene::setGridLinesCount (int nGridLines)
618 {
619   m_nGridLines = nGridLines;
620   bool showGrid = m_showGrid;
621   resetGrid ();
622   m_showGrid = showGrid;
623   if (m_showGrid)
624     {
625       addGrid ();
626     }
627   update ();
628 }
629 
630 void
resetGrid()631 AnimatorScene::resetGrid ()
632 {
633   m_showGrid = false;
634   for (LineItemVector_t::const_iterator i = m_gridLines.begin ();
635       i != m_gridLines.end ();
636       ++i)
637     {
638 
639       removeItem (*i);
640       delete (*i);
641     }
642   m_gridLines.clear ();
643 
644   for (GridCoordinatesVector_t::const_iterator i = m_gridCoordinates.begin ();
645       i != m_gridCoordinates.end ();
646       ++i)
647     {
648       removeItem (*i);
649       delete (*i);
650     }
651   m_gridCoordinates.clear ();
652 }
653 
654 
655 void
setShowInterfaceTexts(bool showIp,bool showMac)656 AnimatorScene::setShowInterfaceTexts (bool showIp, bool showMac)
657 {
658   resetInterfaceTexts ();
659   m_showIpInterfaceTexts = showIp;
660   m_showMacInterfaceTexts = showMac;
661   if (!m_showIpInterfaceTexts && !m_showMacInterfaceTexts)
662     {
663       return;
664     }
665   if (!m_interfaceATexts.size ())
666     {
667       for (LinkManager::NodeIdAnimLinkVectorMap_t::const_iterator i = LinkManager::getInstance ()->getLinks ()->begin ();
668           i != LinkManager::getInstance ()->getLinks ()->end ();
669           ++i)
670         {
671 
672           LinkManager::AnimLinkVector_t linkVector = i->second;
673 
674           for (LinkManager::AnimLinkVector_t::const_iterator j = linkVector.begin ();
675               j != linkVector.end ();
676               ++j)
677             {
678               AnimLink * animLink = *j;
679 
680               QString pointADescription = animLink->getInterfaceADescription ();
681               QPointF pointApos = animLink->getInterfacePosA ();
682               AnimInterfaceText * interfaceAText = new AnimInterfaceText (pointADescription);
683               interfaceAText->setPos (pointApos);
684               addItem (interfaceAText);
685               m_interfaceATexts.push_back (interfaceAText);
686               interfaceAText->setMode (m_showIpInterfaceTexts, m_showMacInterfaceTexts);
687 
688               QString pointBDescription = animLink->getInterfaceBDescription ();
689               if (pointBDescription == "")
690                 {
691                   continue;
692                 }
693               QPointF pointBpos = animLink->getInterfacePosB ();
694               AnimInterfaceText * interfaceBText = new AnimInterfaceText (pointBDescription, true);
695               interfaceBText->setMode (m_showIpInterfaceTexts, m_showMacInterfaceTexts);
696               addItem (interfaceBText);
697               interfaceBText->setPos (pointBpos);
698               m_interfaceBTexts.push_back (interfaceBText);
699             }
700         }
701       update ();
702       removeInterfaceTextCollision ();
703       return;
704     }
705   QPen pen;
706   pen.setCosmetic (true);
707   for (AnimInterfaceTextVector_t::const_iterator i = m_interfaceATexts.begin ();
708       i != m_interfaceATexts.end ();
709       ++i)
710     {
711       AnimInterfaceText * interfaceText = *i;
712       interfaceText->setMode (m_showIpInterfaceTexts, m_showMacInterfaceTexts);
713       QGraphicsLineItem * l = interfaceText->getLine ();
714       l->setPen (pen);
715       if (l)
716         {
717           l->setVisible (showIp || showMac);
718         }
719       interfaceText->setVisible (showIp || showMac);
720     }
721   for (AnimInterfaceTextVector_t::const_iterator i = m_interfaceBTexts.begin ();
722       i != m_interfaceBTexts.end ();
723       ++i)
724     {
725       AnimInterfaceText * interfaceText = *i;
726       interfaceText->setMode (m_showIpInterfaceTexts, m_showMacInterfaceTexts);
727       QGraphicsLineItem * l = interfaceText->getLine ();
728       l->setPen (pen);
729       if (l)
730         {
731           l->setVisible (showIp || showMac);
732         }
733       interfaceText->setVisible (showIp || showMac);
734     }
735   removeInterfaceTextCollision ();
736   update ();
737 }
738 
739 
740 QList <QGraphicsItem *>
getInterfaceTextCollisionList(AnimInterfaceText * text)741 AnimatorScene::getInterfaceTextCollisionList (AnimInterfaceText * text)
742 {
743   QList <QGraphicsItem *> l = text->collidingItems ();
744   QList <QGraphicsItem *> collidingList;
745   for (QList <QGraphicsItem *>::const_iterator i = l.begin ();
746        i != l.end ();
747        ++i)
748     {
749       QGraphicsItem * item = *i;
750       if (item->type () == (ANIMINTERFACE_TEXT_TYPE))
751         {
752           collidingList.append (item);
753         }
754     }
755   return collidingList;
756 }
757 
758 
759 void
repositionInterfaceText(AnimInterfaceText * textItem)760 AnimatorScene::repositionInterfaceText (AnimInterfaceText *textItem)
761 {
762   bool isRight = textItem->pos ().x () > (sceneRect ().width ()/2);
763   QPointF oldPos = textItem->pos ();
764   QFontMetrics fm (font ());
765   QPointF newPos;
766   if (!isRight)
767     {
768       textItem->setLeftAligned (false);
769       qreal y = m_leftTop + 1.5 * fm.height ()/AnimatorView::getInstance ()->transform ().m11 ();
770       newPos = QPointF (-fm.width (textItem->getText ())/AnimatorView::getInstance ()->transform ().m11 (), y);
771       m_leftTop = newPos.y ();
772     }
773   else
774     {
775       textItem->setLeftAligned (true);
776       qreal y = m_rightTop + 1.5 * fm.height ()/AnimatorView::getInstance ()->transform ().m11 ();
777       newPos = QPointF (m_maxPoint.x () + fm.width (textItem->getText ())/AnimatorView::getInstance ()->transform ().m11 (), y);
778       m_rightTop = newPos.y ();
779     }
780   textItem->setPos (newPos);
781   QLineF l (oldPos, newPos);
782   if (textItem->setLine (l))
783     {
784       addItem (textItem->getLine ());
785     }
786 
787 }
788 
789 void
resetInterfaceTexts()790 AnimatorScene::resetInterfaceTexts ()
791 {
792   resetInterfaceTextTop ();
793   for (AnimInterfaceTextVector_t::const_iterator i = m_interfaceATexts.begin ();
794       i != m_interfaceATexts.end ();
795       ++i)
796     {
797       AnimInterfaceText * text = *i;
798       QGraphicsLineItem * l = text->getLine ();
799       if (l)
800         {
801           removeItem (l);
802         }
803       removeItem (*i);
804       delete (*i);
805     }
806   m_interfaceATexts.clear ();
807   for (AnimInterfaceTextVector_t::const_iterator i = m_interfaceBTexts.begin ();
808       i != m_interfaceBTexts.end ();
809       ++i)
810     {
811       AnimInterfaceText * text = *i;
812       QGraphicsLineItem * l = text->getLine ();
813       if (l)
814         {
815           removeItem (l);
816         }
817       removeItem (*i);
818       delete (*i);
819     }
820   m_interfaceBTexts.clear ();
821   update ();
822 }
823 
824 void
resetInterfaceTextTop()825 AnimatorScene::resetInterfaceTextTop ()
826 {
827   m_leftTop = 0;
828   m_rightTop = 0;
829 }
830 
831 void
removeInterfaceTextCollision()832 AnimatorScene::removeInterfaceTextCollision ()
833 {
834 
835   for (AnimInterfaceTextVector_t::iterator i = m_interfaceATexts.begin ();
836       i != m_interfaceATexts.end ();
837       ++i)
838     {
839       AnimInterfaceText * text = *i;
840       QList <QGraphicsItem *> collidingList = getInterfaceTextCollisionList (text);
841       //qDebug (collidingList.count (), "CL count");
842       //NS_LOG_DEBUG ("Colliding List:" << collidingList.count());
843 
844       //NS_LOG_DEBUG ("Colliding List S:" << collidingList.size());
845       if (collidingList.count ())
846         {
847           repositionInterfaceText (text);
848         }
849 
850     }
851   for (AnimInterfaceTextVector_t::iterator i = m_interfaceBTexts.begin ();
852       i != m_interfaceBTexts.end ();
853       ++i)
854     {
855       AnimInterfaceText * text = *i;
856       QList <QGraphicsItem *> collidingList = getInterfaceTextCollisionList (text);
857       //qDebug (collidingList.count (), "CL count");
858       if (collidingList.count ())
859         {
860           repositionInterfaceText (text);
861         }
862     }
863 
864 }
865 
866 
AnimInterfaceText(QString description,bool leftAligned)867 AnimInterfaceText::AnimInterfaceText (QString description, bool leftAligned):QGraphicsTextItem (description),
868   m_leftAligned (leftAligned),
869   m_line (0)
870 {
871   setFlag (QGraphicsItem::ItemIgnoresTransformations);
872   setZValue (ANIMINTERFACE_TEXT_TYPE);
873 }
874 
~AnimInterfaceText()875 AnimInterfaceText::~AnimInterfaceText ()
876 {
877   if (m_line)
878     {
879       delete m_line;
880     }
881 }
882 
883 void
setLeftAligned(bool leftAligned)884 AnimInterfaceText::setLeftAligned (bool leftAligned)
885 {
886   m_leftAligned = leftAligned;
887 }
888 
889 QPainterPath
shape() const890 AnimInterfaceText::shape () const
891 {
892   QPainterPath p;
893   QFontMetrics fm (font ());
894   QRectF r (0, 0, fm.width (getText ())/AnimatorView::getInstance ()->transform ().m11 (),
895            fm.height ()/AnimatorView::getInstance ()->transform ().m11 ());
896   p.addRect (r);
897   return p;
898 }
899 
900 QString
getText() const901 AnimInterfaceText::getText () const
902 {
903   QStringList parts = toPlainText ().split ('~');
904   if (m_mode == AnimInterfaceText::IPV4)
905     {
906       return parts.at (0);
907     }
908   if (m_mode == AnimInterfaceText::MAC)
909     {
910       if (parts.length () != 2)
911         {
912           return "";
913         }
914       return parts.at (1);
915     }
916   return toPlainText ();
917 }
918 
919 
920 void
paint(QPainter * painter,const QStyleOptionGraphicsItem * option,QWidget * widget)921 AnimInterfaceText::paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
922 {
923 
924   Q_UNUSED (option)
925   Q_UNUSED (widget)
926   if (m_leftAligned)
927     {
928       QFontMetrics fm = painter->fontMetrics ();
929       QPointF leftAlignPoint = QPointF (-fm.width (getText ()), 0);
930       painter->save ();
931       painter->translate (leftAlignPoint);
932       painter->drawText (QPointF (0, 0), getText ());
933       //QGraphicsTextItem::paint (painter, option, widget);
934       painter->restore ();
935     }
936   else
937     {
938       //QGraphicsTextItem::paint (painter, option, widget);
939       painter->drawText (QPointF (0, 0), getText ());
940 
941     }
942 }
943 
944 bool
setLine(QLineF l)945 AnimInterfaceText::setLine (QLineF l)
946 {
947   bool newLine = false;
948   if (!m_line)
949     {
950       m_line = new QGraphicsLineItem;
951       newLine = true;
952     }
953   QPen p;
954   p.setCosmetic (true);
955   p.setColor (QColor (0, 0, 255, 50));
956   m_line->setPen (p);
957   m_line->setLine (l);
958   return newLine;
959 }
960 
961 QGraphicsLineItem *
getLine()962 AnimInterfaceText::getLine ()
963 {
964   return m_line;
965 }
966 
967 void
setMode(bool showIpv4,bool showMac)968 AnimInterfaceText::setMode (bool showIpv4, bool showMac)
969 {
970   if (!showIpv4 && !showMac)
971     {
972       m_mode = AnimInterfaceText::NONE;
973     }
974   if (showIpv4 && !showMac)
975     {
976       m_mode = AnimInterfaceText::IPV4;
977     }
978   if (!showIpv4 && showMac)
979     {
980       m_mode = AnimInterfaceText::MAC;
981     }
982   if (showIpv4 && showMac)
983     {
984       m_mode = AnimInterfaceText::BOTH;
985     }
986 }
987 
988 
989 
990 } // namespace netanim
991