Monitor
|
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 }