/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include #include "edge.h" #include "node.h" #include "graphwidget.h" /** Constructor for Creating a new graphical ndoe @param graphWidget the widget it is placed on @param _center the center of this graphical node @param _ip_addre the ip address of this node @param _node the model node that this graphical node represents */ Node::Node(GraphWidget *graphWidget, bool _center, uint32_t _ip_addr, node* _node) : graph(graphWidget) { setFlag(ItemIsMovable); setFlag(ItemSendsGeometryChanges); setCacheMode(DeviceCoordinateCache); setZValue(-1); center = _center; struct in_addr theAddr; theAddr.s_addr = ntohl(_ip_addr); char * temp = inet_ntoa(theAddr); int p1,p2,p3,p4; sscanf(temp, "%d.%d.%d.%d", &p1, &p2, &p3, &p4); ip_addr_string = QString("%0").arg(p4); ip_addr = _ip_addr; active = true; myNode = _node; } /** adds and edge to this node @param edge the edge used to connect this node to another node */ void Node::addEdge(Edge *edge) { edgeList << edge; edge->adjust(); } /** Gets the model node @return model node that it's representing */ node* Node::getNodePointer() { return myNode; } /** Gets the list of edges @return QList with all of this graphical node's edges */ QList Node::edges() const { return edgeList; } /** Gets the ip address of the model node @return the ip address of the model node */ uint32_t Node::getIpAddr() const { return ip_addr; } /** Gets the active state of this node @return true if active */ bool Node::isActive() const { return active; } /** Sets the node as inactive */ void Node::setInactive() { active = false; } /** Sets as active */ void Node::setActive() { active = true; } /** Calcualtes the forces, when physics are enabled @param doPhysics whether or not do enable physics */ void Node::calculateForces(bool doPhysics) { if (doPhysics) { fprintf(stderr, "doPhysics was TRUE\n"); } else { fprintf(stderr, "doPhysics was FALSE\n"); } if (!scene() || scene()->mouseGrabberItem() == this) { newPos = pos(); return; } if (doPhysics) { // Sum up all forces pushing this item away qreal xvel = 0; qreal yvel = 0; foreach (QGraphicsItem *item, scene()->items()) { Node *node = qgraphicsitem_cast(item); if (!node) continue; QPointF vec = mapToItem(node, 0, 0); qreal dx = vec.x(); qreal dy = vec.y(); double l = 2.0 * (dx * dx + dy * dy); if (l > 0) { xvel += (dx * 1500.0) / l; yvel += (dy * 1500.0) / l; } } // Now subtract all forces pulling items together double weight = (edgeList.size() + 1) * 10; foreach (Edge *edge, edgeList) { QPointF vec; if (edge->sourceNode() == this) vec = mapToItem(edge->destNode(), 0, 0); else vec = mapToItem(edge->sourceNode(), 0, 0); xvel -= vec.x() / weight; yvel -= vec.y() / weight; } if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1) xvel = yvel = 0; QRectF sceneRect = scene()->sceneRect(); newPos = pos() + QPointF(xvel, yvel); newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10)); newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10)); } } /** Updates the position of this node */ bool Node::advance() { if (newPos == pos()) return false; setPos(newPos); return true; } /** Gets the bounding rectangle of this node @return the bounding rectangle of this node */ QRectF Node::boundingRect() const { qreal adjust = 2; return QRectF(-10 - adjust, -10 - adjust, 130 + adjust, 30 + adjust); } /** Gets the path used to draw this node @return the path used to draw this node */ QPainterPath Node::shape() const { QPainterPath path; path.addEllipse(-10, -10, 20, 20); return path; } /** Paints the grpahical node using the painter @param painter used to paint this graphical node @param option options for painting this node */ void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) { painter->setPen(Qt::NoPen); painter->setBrush(Qt::darkGray); painter->drawEllipse(-7, -7, 20, 20); QRadialGradient gradient(-3, -3, 10); if (option->state & QStyle::State_Sunken) { gradient.setCenter(3, 3); gradient.setFocalPoint(3, 3); if (center) { gradient.setColorAt(1, QColor(Qt::red).light(120)); gradient.setColorAt(0, QColor(Qt::darkRed).light(120)); } else { gradient.setColorAt(1, QColor(Qt::yellow).light(120)); gradient.setColorAt(0, QColor(Qt::darkYellow).light(120)); } } else { if (center) { gradient.setColorAt(1, Qt::darkRed); gradient.setColorAt(0, Qt::red); } else { gradient.setColorAt(1, Qt::darkYellow); gradient.setColorAt(0, Qt::yellow); } } /*if(ip_addr == graph->getSelectedIP()) { gradient.setColorAt(1, Qt::darkCyan); gradient.setColorAt(0, Qt::red); }*/ //Mac instead of IP if(macEqual(this->getNodePointer()->mac_addr, graph->getSourceMac())) { gradient.setColorAt(1, Qt::darkCyan); gradient.setColorAt(0, Qt::red); } else if(macEqual(this->getNodePointer()->mac_addr, graph->getDestinationMac())) { gradient.setColorAt(1, Qt::darkMagenta); gradient.setColorAt(0, Qt::green); } else { gradient.setColorAt(1, Qt::darkYellow); gradient.setColorAt(0, Qt::yellow); } painter->setBrush(gradient); painter->setPen(QPen(Qt::black, 0)); painter->drawEllipse(-10, -10, 20, 20); painter->drawText(QPointF(10,0), getIpAddrQString()); //char buffer[2]; //sprintf(buffer, "%02x", myNode->mac_addr.addr[5]); //painter->drawText(QPointF(10,0), buffer); } /** Gets the change variant @param change the graphical item change @param value the address of the change @return QVariant of the chang */ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value) { switch (change) { case ItemPositionHasChanged: foreach (Edge *edge, edgeList) edge->adjust(); graph->itemMoved(); break; default: break; }; return QGraphicsItem::itemChange(change, value); } /** Handles mouse presses @param event the mouse press event */ void Node::mousePressEvent(QGraphicsSceneMouseEvent *event) { //update(); if (event->modifiers() == Qt::ShiftModifier) { //SET THE DEST NODE STUFF HERE printf("\n\n\n\n\nSHIFT WAS PRESSED!!\n\n\n\n\n"); graph->setDestinationMac(this->getNodePointer()->mac_addr); this->graph->updateNodesAndEdges(); } else { QGraphicsItem::mousePressEvent(event); graph->setSelectedIP(ip_addr); /*Transition to using this.*/ graph->setSourceMac(this->getNodePointer()->mac_addr); this->graph->updateNodesAndEdges(); //this->graph->getMainWindow()->updateList(); } //Check here if both Src and Dest are selected and tell the comm model } /** Handles the mouse release event @param event the mouse release event */ void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { update(); QGraphicsItem::mouseReleaseEvent(event); } /** Gets the new position of this node @return the new postion of this node */ QPointF Node::getPosition() { return newPos; } /** Gets the String representation of this nodes ip address */ QString Node::getIpAddrQString() const { return ip_addr_string; } /** Sets the position of this node @param np the new position */ void Node::settPosition(QPointF * np) { newPos.setX(np->x()); newPos.setY(np->y()); }