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