Monitor
node.cpp
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
00004 ** All rights reserved.
00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
00006 **
00007 ** This file is part of the examples of the Qt Toolkit.
00008 **
00009 ** $QT_BEGIN_LICENSE:BSD$
00010 ** You may use this file under the terms of the BSD license as follows:
00011 **
00012 ** "Redistribution and use in source and binary forms, with or without
00013 ** modification, are permitted provided that the following conditions are
00014 ** met:
00015 **   * Redistributions of source code must retain the above copyright
00016 **     notice, this list of conditions and the following disclaimer.
00017 **   * Redistributions in binary form must reproduce the above copyright
00018 **     notice, this list of conditions and the following disclaimer in
00019 **     the documentation and/or other materials provided with the
00020 **     distribution.
00021 **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
00022 **     the names of its contributors may be used to endorse or promote
00023 **     products derived from this software without specific prior written
00024 **     permission.
00025 **
00026 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00030 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
00037 ** $QT_END_LICENSE$
00038 **
00039 ****************************************************************************/
00040 
00041 #include <QGraphicsScene>
00042 #include <QGraphicsSceneMouseEvent>
00043 #include <QPainter>
00044 #include <QStyleOption>
00045 #include <arpa/inet.h>
00046 #include <netinet/in.h>
00047 
00048 #include "edge.h"
00049 #include "node.h"
00050 #include "graphwidget.h"
00051 
00052 
00060 Node::Node(GraphWidget *graphWidget, bool _center, uint32_t _ip_addr, node* _node)
00061     : graph(graphWidget)
00062 {
00063     setFlag(ItemIsMovable);
00064     setFlag(ItemSendsGeometryChanges);
00065     setCacheMode(DeviceCoordinateCache);
00066     setZValue(-1);
00067     center = _center;
00068 
00069     struct in_addr theAddr;
00070     theAddr.s_addr = ntohl(_ip_addr);
00071     char * temp = inet_ntoa(theAddr);
00072     int p1,p2,p3,p4;
00073     sscanf(temp, "%d.%d.%d.%d", &p1, &p2, &p3, &p4);
00074     ip_addr_string = QString("%0").arg(p4);
00075 
00076     ip_addr = _ip_addr;
00077     active = true;
00078     myNode = _node;
00079 }
00080 
00085 void Node::addEdge(Edge *edge)
00086 {
00087     edgeList << edge;
00088     edge->adjust();
00089 }
00090 
00095 node* Node::getNodePointer()
00096 {
00097     return myNode;
00098 }
00099 
00104 QList<Edge *> Node::edges() const
00105 {
00106     return edgeList;
00107 }
00108 
00113 uint32_t Node::getIpAddr() const
00114 {
00115     return ip_addr;
00116 }
00117 
00122 bool Node::isActive() const
00123 {
00124     return active;
00125 }
00126 
00130 void Node::setInactive()
00131 {
00132     active = false;
00133 }
00134 
00138 void Node::setActive()
00139 {
00140     active = true;
00141 }
00142 
00147 void Node::calculateForces(bool doPhysics)
00148 {
00149     if (doPhysics) {
00150         fprintf(stderr, "doPhysics was TRUE\n");
00151     } else {
00152         fprintf(stderr, "doPhysics was FALSE\n");
00153     }
00154     if (!scene() || scene()->mouseGrabberItem() == this) {
00155         newPos = pos();
00156         return;
00157     }
00158 
00159     
00160     if (doPhysics) {
00161         // Sum up all forces pushing this item away
00162         qreal xvel = 0;
00163         qreal yvel = 0;
00164         foreach (QGraphicsItem *item, scene()->items()) {
00165             Node *node = qgraphicsitem_cast<Node *>(item);
00166             if (!node)
00167                 continue;
00168 
00169             QPointF vec = mapToItem(node, 0, 0);
00170             qreal dx = vec.x();
00171             qreal dy = vec.y();
00172             double l = 2.0 * (dx * dx + dy * dy);
00173             if (l > 0) {
00174                 xvel += (dx * 1500.0) / l;
00175                 yvel += (dy * 1500.0) / l;
00176             }
00177         }
00178 
00179         
00180         // Now subtract all forces pulling items together
00181         double weight = (edgeList.size() + 1) * 10;
00182         foreach (Edge *edge, edgeList) {
00183             QPointF vec;
00184             if (edge->sourceNode() == this)
00185                 vec = mapToItem(edge->destNode(), 0, 0);
00186             else
00187                 vec = mapToItem(edge->sourceNode(), 0, 0);
00188 
00189             xvel -= vec.x() / weight;
00190             yvel -= vec.y() / weight;
00191         }
00192 
00193         
00194         if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1)
00195             xvel = yvel = 0;
00196 
00197         QRectF sceneRect = scene()->sceneRect();
00198         newPos = pos() + QPointF(xvel, yvel);
00199         newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10));
00200         newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10));
00201     }
00202 }
00203 
00207 bool Node::advance()
00208 {
00209     if (newPos == pos())
00210         return false;
00211 
00212     setPos(newPos);
00213     return true;
00214 }
00215 
00220 QRectF Node::boundingRect() const
00221 {
00222     qreal adjust = 2;
00223     return QRectF(-10 - adjust, -10 - adjust,
00224                   130 + adjust, 30 + adjust);
00225 }
00226 
00231 QPainterPath Node::shape() const
00232 {
00233     QPainterPath path;
00234     path.addEllipse(-10, -10, 20, 20);
00235     return path;
00236 }
00237 
00243 void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
00244 {
00245     painter->setPen(Qt::NoPen);
00246     painter->setBrush(Qt::darkGray);
00247     painter->drawEllipse(-7, -7, 20, 20);
00248 
00249     QRadialGradient gradient(-3, -3, 10);
00250     if (option->state & QStyle::State_Sunken) {
00251         gradient.setCenter(3, 3);
00252         gradient.setFocalPoint(3, 3);
00253         if (center) {
00254             gradient.setColorAt(1, QColor(Qt::red).light(120));
00255             gradient.setColorAt(0, QColor(Qt::darkRed).light(120));
00256         }
00257         else {
00258             gradient.setColorAt(1, QColor(Qt::yellow).light(120));
00259             gradient.setColorAt(0, QColor(Qt::darkYellow).light(120));
00260         }
00261     } else {
00262         if (center) {
00263             gradient.setColorAt(1, Qt::darkRed);
00264             gradient.setColorAt(0, Qt::red);
00265         }
00266         else {
00267             gradient.setColorAt(1, Qt::darkYellow);
00268             gradient.setColorAt(0, Qt::yellow);
00269         }
00270     }
00271 
00272     /*if(ip_addr == graph->getSelectedIP())
00273     {
00274         gradient.setColorAt(1, Qt::darkCyan);
00275         gradient.setColorAt(0, Qt::red);
00276     }*/
00277     //Mac instead of IP
00278     if(macEqual(this->getNodePointer()->mac_addr, graph->getSourceMac()))
00279     {
00280         gradient.setColorAt(1, Qt::darkCyan);
00281         gradient.setColorAt(0, Qt::red);
00282     }
00283     else if(macEqual(this->getNodePointer()->mac_addr, graph->getDestinationMac()))
00284     {
00285         gradient.setColorAt(1, Qt::darkMagenta);
00286         gradient.setColorAt(0, Qt::green);
00287     }
00288     else
00289     {
00290         gradient.setColorAt(1, Qt::darkYellow);
00291         gradient.setColorAt(0, Qt::yellow);
00292     }
00293 
00294     painter->setBrush(gradient);
00295     painter->setPen(QPen(Qt::black, 0));
00296     painter->drawEllipse(-10, -10, 20, 20);
00297 
00298     painter->drawText(QPointF(10,0), getIpAddrQString());
00299 
00300 
00301     //char buffer[2];
00302     //sprintf(buffer, "%02x", myNode->mac_addr.addr[5]);
00303 
00304     //painter->drawText(QPointF(10,0), buffer);
00305 
00306 }
00307 
00314 QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
00315 {
00316     switch (change) {
00317     case ItemPositionHasChanged:
00318         foreach (Edge *edge, edgeList)
00319             edge->adjust();
00320         graph->itemMoved();
00321         break;
00322     default:
00323         break;
00324     };
00325 
00326     return QGraphicsItem::itemChange(change, value);
00327 }
00328 
00333 void Node::mousePressEvent(QGraphicsSceneMouseEvent *event)
00334 {
00335     //update();
00336     if (event->modifiers() == Qt::ShiftModifier)
00337     {
00338         //SET THE DEST NODE STUFF HERE
00339         printf("\n\n\n\n\nSHIFT WAS PRESSED!!\n\n\n\n\n");
00340         graph->setDestinationMac(this->getNodePointer()->mac_addr);
00341         this->graph->updateNodesAndEdges();
00342     }
00343     else
00344     {
00345         QGraphicsItem::mousePressEvent(event);
00346         graph->setSelectedIP(ip_addr);
00347 
00348         /*Transition to using this.*/
00349         graph->setSourceMac(this->getNodePointer()->mac_addr);
00350 
00351         this->graph->updateNodesAndEdges();
00352 
00353         //this->graph->getMainWindow()->updateList();
00354     }
00355 
00356     //Check here if both Src and Dest are selected and tell the comm model
00357 }
00358 
00363 void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
00364 {
00365     update();
00366     QGraphicsItem::mouseReleaseEvent(event);
00367 }
00368 
00373 QPointF Node::getPosition()
00374 {
00375     return newPos;
00376 }
00377 
00381 QString Node::getIpAddrQString() const
00382 {
00383     return ip_addr_string;
00384 }
00385 
00390 void Node::settPosition(QPointF * np) {
00391     newPos.setX(np->x());
00392     newPos.setY(np->y());
00393 }
 All Classes Functions