/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: John Abraham * Contributions: Eugene Kalishenko (Open Source and Linux Laboratory http://dev.osll.ru/) * Dmitrii Shakshin (Open Source and Linux Laboratory http://dev.osll.ru/) */ #include "animnode.h" #include "animresource.h" #include "animatorview.h" #include NS_LOG_COMPONENT_DEFINE ("AnimNode"); namespace netanim { AnimNodeMgr * pAnimNodeMgr = 0; AnimNode::AnimNode (uint32_t nodeId, uint32_t nodeSysId, qreal x, qreal y, QString nodeDescription): m_nodeDescription (0), m_nodeId (nodeId), m_nodeSysId (nodeSysId), m_x (x), m_y (y), m_showNodeId (true), m_showNodeSysId (false), m_resourceId (-1), m_showNodeTrajectory (false), m_showBatteryCapcity (false) { //setVisible (false); setZValue (ANIMNODE_ZVALUE); m_r = 255; m_g = 0; m_b = 0; if (nodeDescription == "") { nodeDescription = QString::number (nodeId); } m_nodeDescription = new QGraphicsTextItem (nodeDescription); m_nodeDescription->setFlag (QGraphicsItem::ItemIgnoresTransformations); setFlag (QGraphicsItem::ItemIsSelectable); } AnimNode::~AnimNode () { if (m_nodeDescription) { delete m_nodeDescription; } } void AnimNode::showNodeId (bool show) { m_showNodeId = show; m_nodeDescription->setVisible (m_showNodeId); } QColor generateColor (size_t index, uint8_t alpha = 0) { static const size_t colors[] = { Qt::blue, Qt::magenta, Qt::darkCyan, Qt::darkYellow, Qt::darkRed, Qt::darkMagenta, Qt::darkGreen, Qt::darkBlue, Qt::black, Qt::darkGray, Qt::lightGray }; static const size_t COUNT = sizeof (colors) / sizeof (size_t); QColor result; if (index < COUNT) result = QColor (Qt::GlobalColor (colors[index])); else { result = QColor (Qt::GlobalColor (colors[index % COUNT])); const int step = 256 * 3 % COUNT; result.setRed ((result.red () + step * index) % 255); result.setGreen ((result.blue () + step * index) % 255); result.setBlue (((int)result.green () - step * index) % 255); } if (alpha) result.setAlpha (alpha); return result; } void AnimNode::showNodeSysId (bool show) { if (show) { m_lastColor = this->getColor (); int r, g, b, a; m_lastColor.getRgb(&r, &g, &b, &a); const QColor &color = generateColor (m_nodeSysId, a); color.getRgb (&r, &g, &b, &a); setColor (static_cast (r), static_cast (g), static_cast (b), static_cast (a)); } else { if(m_showNodeSysId) { int r, g, b, a; m_lastColor.getRgb (&r, &g, &b, &a); setColor (r, g, b, a); } } m_showNodeSysId = show; m_nodeDescription->setPlainText (QString::number (m_nodeId) + (m_showNodeSysId ? QString(" SysId:") + QString::number (m_nodeSysId): QString())); } bool AnimNode::isVisibleNodeSysId() const { return m_showNodeSysId; } void AnimNode::updateNodeSysId (uint32_t sysId, bool show) { m_nodeSysId = sysId; //m_nodeSysIdDescription->setPlainText ("sysId: " + QString::number (sysId)); showNodeSysId (show); } void AnimNode::updateBatteryCapacityImage (bool show) { m_showBatteryCapcity = show; QString batteryCapacityImagePath(":/resources/battery_icon_"); bool result = false; CounterType_t counterType; uint32_t counterId = AnimNodeMgr::getInstance ()->getCounterIdForName ("RemainingEnergy", result, counterType); if (!result) { return; } result = false; qreal capacity = getDoubleCounterValue (counterId, result); if (!result) { return; } if (capacity > 0.75) batteryCapacityImagePath += "4"; else if (capacity > 0.5) batteryCapacityImagePath += "3"; else if (capacity > 0.25) batteryCapacityImagePath += "2"; else if (capacity >= 0) batteryCapacityImagePath += "1"; else batteryCapacityImagePath += "0"; // NS_LOG_DEBUG ("Capacity:" << batteryCapacityImagePath.toAscii().data()); batteryCapacityImagePath += ".png"; if(show) { m_batteryPixmap = QPixmap (batteryCapacityImagePath); } if (!show) { m_batteryPixmap = QPixmap (); } } uint32_t AnimNode::getUint32CounterValue (uint32_t counterId, bool & result) { result = false; if (m_counterIdToValuesUint32.find (counterId) == m_counterIdToValuesUint32.end ()) return -1; result = true; return m_counterIdToValuesUint32[counterId]; } qreal AnimNode::getDoubleCounterValue (uint32_t counterId, bool & result) { result = false; if (m_counterIdToValuesDouble.find (counterId) == m_counterIdToValuesDouble.end ()) return -1; result = true; return m_counterIdToValuesDouble[counterId]; } void AnimNode::updateCounter (uint32_t counterId, qreal counterValue, CounterType_t counterType) { if (counterType == DOUBLE_COUNTER) { m_counterIdToValuesDouble[counterId] = counterValue; } if (counterType == UINT32_COUNTER) { m_counterIdToValuesUint32[counterId] = counterValue; } } int AnimNode::getResourceId () { return m_resourceId; } void AnimNode::setResource (int resourceId) { m_resourceId = resourceId; QString resourcePath = AnimResourceManager::getInstance ()->get (resourceId); //NS_LOG_DEBUG ("Res:" << resourcePath.toAscii ().data ()); QPixmap pix; if (resourcePath.endsWith (".png")) pix = QPixmap (resourcePath, "png"); else if (resourcePath.endsWith (".svg")) pix = QPixmap (resourcePath, "svg"); setPixmap (pix); update (); } void AnimNode::setColor (uint8_t r, uint8_t g, uint8_t b, uint8_t alpha) { m_r = r; m_g = g; m_b = b; m_alpha = alpha; ResizeableItem::setColor (r, g, b, alpha); update (); } QColor AnimNode::getColor () { QColor c (m_r, m_g, m_b, 255); return c; } qreal AnimNode::getWidth () { return m_width; } qreal AnimNode::getX () { return m_x; } qreal AnimNode::getY () { return m_y; } void AnimNode::setPos (qreal x, qreal y) { m_x = x; m_y = y; QGraphicsItem::setPos (x, y); } void AnimNode::setX (qreal x) { m_x = x; } bool AnimNode::getShowNodeTrajectory () { return m_showNodeTrajectory; } void AnimNode::setShowNodeTrajectory (bool showNodeTrajectory) { m_showNodeTrajectory = showNodeTrajectory; } void AnimNode::setY (qreal y) { m_y = y; } uint32_t AnimNode::getNodeId () { return m_nodeId; } uint32_t AnimNode::getNodeSysId () { return m_nodeSysId; } QGraphicsTextItem * AnimNode::getDescription () { return m_nodeDescription; } QPointF AnimNode::getCenter () { //return sceneBoundingRect ().center (); return QPointF (m_x, m_y); } void AnimNode::setNodeDescription (QString description) { m_nodeDescription->setPlainText (description); } void AnimNode::paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { ResizeableItem::paint (painter, option, widget); if (!m_batteryPixmap.isNull ()) { updateBatteryCapacityImage (m_showBatteryCapcity); QPointF bottomLeft = sceneBoundingRect ().bottomLeft (); //NS_LOG_DEBUG ("Pix Width:" << m_batteryPixmap->width()); bottomLeft = QPointF (-1, 1); painter->save (); painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing | QPainter::NonCosmeticDefaultPen, true); painter->scale (0.5, 1); painter->drawPixmap (bottomLeft.x (), bottomLeft.y (), 5, 5, m_batteryPixmap); painter->restore (); } } void AnimNode::mouseMoveEvent (QGraphicsSceneMouseEvent *event) { ResizeableItem::mouseMoveEvent (event); if (m_nodeDescription) { m_nodeDescription->setPos (sceneBoundingRect ().bottomRight ()); update (); } } AnimNode::Ipv4Set_t AnimNode::getIpv4Addresses () { return m_ipv4Set; } AnimNode::Ipv6Set_t AnimNode::getIpv6Addresses () { return m_ipv6Set; } AnimNode::MacVector_t AnimNode::getMacAddresses () { return m_macVector; } void AnimNode::addIpv4Address (QString ip) { m_ipv4Set.insert (ip); } void AnimNode::addIpv6Address (QString ip) { m_ipv6Set.insert (ip); } void AnimNode::addMacAddress (QString mac) { m_macVector.push_back (mac); } bool AnimNode::hasIpv4 (QString ip) { bool result = false; QStringList quads = ip.split ("."); if (quads.count () == 4) { if (quads.at (3) == "255") return true; for (Ipv4Set_t::const_iterator i = m_ipv4Set.begin (); i != m_ipv4Set.end (); ++i) { if (*i == ip) { //QDEBUG (ip); return true; } } } return result; } bool AnimNode::hasMac (QString mac) { bool result = false; QStringList bytes = mac.split (":"); if (bytes.count () == 6) { for (MacVector_t::const_iterator i = m_macVector.begin (); i != m_macVector.end (); ++i) { if (*i == mac) { return true; } } } return result; } AnimNodeMgr::AnimNodeMgr (): m_minX (0), m_minY (0), m_maxX (0), m_maxY (0) { } AnimNodeMgr * AnimNodeMgr::getInstance () { if (!pAnimNodeMgr) { pAnimNodeMgr = new AnimNodeMgr; } return pAnimNodeMgr; } AnimNode * AnimNodeMgr::add (uint32_t nodeId, uint32_t nodeSysId, qreal x, qreal y, QString nodeDescription) { if (m_nodes.find (nodeId) != m_nodes.end ()) { //NS_FATAL_ERROR ("NodeId:" << nodeId << " Already exists"); } QPixmap pix (":/resources/ns3logo2.png","png"); AnimNode * node = new AnimNode (nodeId, nodeSysId, x, y, nodeDescription); node->setPos (x, y); //node->setPixmap (pix); m_nodes[nodeId] = node; m_minX = qMin (m_minX, x); m_minY = qMin (m_minY, y); m_maxX = qMax (m_maxX, x); m_maxY = qMax (m_maxY, y); return node; } void AnimNodeMgr::setSize (qreal width, qreal height) { for (NodeIdAnimNodeMap_t::const_iterator i = m_nodes.begin (); i != m_nodes.end (); ++i) { AnimNode * animNode = i->second; animNode->setSize (width, height); } } void AnimNodeMgr::showRemainingBatteryCapacity (bool show) { for (NodeIdAnimNodeMap_t::const_iterator i = m_nodes.begin (); i != m_nodes.end (); ++i) { AnimNode * animNode = i->second; animNode->updateBatteryCapacityImage (show); } } AnimNode * AnimNodeMgr::getNode (uint32_t nodeId) { return m_nodes[nodeId]; } uint32_t AnimNodeMgr::getCount () { return m_nodes.size (); } QPointF AnimNodeMgr::getMinPoint () { return QPointF (m_minX, m_minY); } QPointF AnimNodeMgr::getMaxPoint () { qreal m = qMax (m_maxX, m_maxY); return QPointF (m, m); } void AnimNodeMgr::systemReset () { m_nodes.clear (); m_minX = 0; m_minY = 0; m_maxX = 0; m_maxY = 0; m_counterIdToNamesDouble.clear (); m_counterIdToNamesUint32.clear (); } void AnimNodeMgr::addIpv4Address (uint32_t nodeId, QString ip) { getNode (nodeId)->addIpv4Address (ip); } void AnimNodeMgr::addIpv6Address (uint32_t nodeId, QString ip) { getNode (nodeId)->addIpv6Address (ip); } void AnimNodeMgr::addMacAddress (uint32_t nodeId, QString mac) { getNode (nodeId)->addMacAddress (mac); } void AnimNodeMgr::showNodeId (bool show) { for (NodeIdAnimNodeMap_t::const_iterator i = m_nodes.begin (); i != m_nodes.end (); ++i) { AnimNode * animNode = i->second; animNode->showNodeId (show); } } void AnimNodeMgr::showNodeSysId (bool show) { for (NodeIdAnimNodeMap_t::const_iterator i = m_nodes.begin (); i != m_nodes.end (); ++i) { AnimNode * animNode = i->second; animNode->showNodeSysId (show); } } AnimNodeMgr::TimePosVector_t AnimNodeMgr::getPositions (uint32_t nodeId) { return m_nodePositions[nodeId]; } void AnimNodeMgr::addAPosition (uint32_t nodeId, qreal t, QPointF pos) { if (m_nodePositions.find (nodeId) == m_nodePositions.end ()) { TimePosVector_t posVector; m_nodePositions[nodeId] = posVector; } TimePosVector_t & pv = m_nodePositions[nodeId]; TimePosition_t tp; tp.p = pos; tp.t = t; pv.push_back (tp); } void AnimNodeMgr::addNodeCounterUint32 (uint32_t counterId, QString counterName) { m_counterIdToNamesUint32[counterId] = counterName; } void AnimNodeMgr::addNodeCounterDouble (uint32_t counterId, QString counterName) { m_counterIdToNamesDouble[counterId] = counterName; } void AnimNodeMgr::updateNodeCounter (uint32_t nodeId, uint32_t counterId, qreal counterValue) { AnimNode * animNode = getNode (nodeId); AnimNode::CounterType_t ct; bool counterFound = false; for (CounterIdName_t::const_iterator i = m_counterIdToNamesDouble.begin (); i != m_counterIdToNamesDouble.end (); ++i) { if (counterId == i->first) { ct = AnimNode::DOUBLE_COUNTER; counterFound = true; break; } } if (!counterFound) { for (CounterIdName_t::const_iterator i = m_counterIdToNamesUint32.begin (); i != m_counterIdToNamesUint32.end (); ++i) { if (counterId == i->first) { ct = AnimNode::UINT32_COUNTER; counterFound = true; break; } } } animNode->updateCounter (counterId, counterValue, ct); } AnimNodeMgr::CounterIdName_t AnimNodeMgr::getUint32CounterNames () { return m_counterIdToNamesUint32; } AnimNodeMgr::CounterIdName_t AnimNodeMgr::getDoubleCounterNames () { return m_counterIdToNamesDouble; } uint32_t AnimNodeMgr::getCounterIdForName (QString counterName, bool &result, AnimNode::CounterType_t & counterType) { result = false; for (CounterIdName_t::const_iterator i = m_counterIdToNamesDouble.begin (); i != m_counterIdToNamesDouble.end (); ++i) { QString n = i->second; if (n == counterName) { result = true; counterType = AnimNode::DOUBLE_COUNTER; return i->first; } } for (CounterIdName_t::const_iterator i = m_counterIdToNamesUint32.begin (); i != m_counterIdToNamesUint32.end (); ++i) { QString n = i->second; if (n == counterName) { result = true; counterType = AnimNode::UINT32_COUNTER; return i->first; } } return -1; } }