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 "graphwidget.h" 00042 #include "edge.h" 00043 #include "node.h" 00044 #include "point.h" 00045 00046 #include <QtGui> 00047 #include <arpa/inet.h> 00048 #include <netinet/in.h> 00049 00050 #include <math.h> 00051 00057 GraphWidget::GraphWidget(QWidget *parent, CommModel *comModel) 00058 : QGraphicsView(parent), timerId(0) 00059 { 00060 QGraphicsScene *scene = new QGraphicsScene(this); 00061 scenex = scene; 00062 scene->setItemIndexMethod(QGraphicsScene::NoIndex); 00063 scene->setSceneRect(-250, -220, 625, 500); 00064 setScene(scene); 00065 setCacheMode(CacheBackground); 00066 setViewportUpdateMode(BoundingRectViewportUpdate); 00067 setRenderHint(QPainter::Antialiasing); 00068 setTransformationAnchor(AnchorUnderMouse); 00069 scale(qreal(0.8), qreal(0.8)); 00070 this->comm = comModel; 00071 sourceSet = false; 00072 destSet = false; 00073 } 00074 00079 MainWindow * GraphWidget::getMainWindow() 00080 { 00081 return mainWindow; 00082 } 00083 00088 void GraphWidget::setMainWindow(MainWindow * _mainWindow) 00089 { 00090 mainWindow = _mainWindow; 00091 } 00092 00096 void GraphWidget::itemMoved() 00097 { 00098 if (!timerId) 00099 timerId = startTimer(1000 / 25); 00100 } 00101 00108 bool GraphWidget::sameMacAddr(node* n1, node* n2) 00109 { 00110 for(int i = 0; i < 6; i++) 00111 { 00112 if(n1->mac_addr.addr[i] != n2->mac_addr.addr[i]) 00113 return false; 00114 } 00115 return true; 00116 } 00117 00123 bool GraphWidget::checkIp(uint32_t ip_addr) 00124 { 00125 foreach (Node * n, allNodes) 00126 { 00127 if (n->getIpAddr() == ip_addr) 00128 { 00129 n->setActive(); 00130 return true; 00131 } 00132 } 00133 return false; 00134 } 00135 00141 bool GraphWidget::checkMac(node* nx) 00142 { 00143 foreach (Node * n, allNodes) 00144 { 00145 //if (n->getIpAddr() == ip_addr) 00146 if(sameMacAddr(nx, n->getNodePointer())) 00147 { 00148 n->setActive(); 00149 return true; 00150 } 00151 } 00152 return false; 00153 } 00154 00160 Node * GraphWidget::getNode(node * n) 00161 { 00162 foreach (Node * nx, allNodes) 00163 { 00164 /*When we get Mac Addresses working, use the next line instead of the IP one.*/ 00165 if(sameMacAddr(nx->getNodePointer(), n)) 00166 //if (nx->getIpAddr() == n->ip_addr) 00167 { 00168 perror("getNode: found the node based on mac address.\n"); 00169 return nx; 00170 } 00171 } 00172 perror("getNode: couldn't find the node based on mac address.\n"); 00173 return NULL; 00174 } 00175 00182 bool GraphWidget::hasEdge(Node * n, node * nb) 00183 { 00184 Node * neighbor = getNode(nb); 00185 foreach (Edge * e, n->edges()) 00186 { 00187 if (n == e->sourceNode() && neighbor == e->destNode()) 00188 { 00189 return true; 00190 } 00191 } 00192 return false; 00193 } 00194 00199 void GraphWidget::updateGraph(std::vector<node *> nodes) 00200 { 00201 if (sourceSet && destSet) 00202 { 00203 std::vector<node *> prefPath = comm->get_preferred_path(); 00204 if (!prefPath.empty()) 00205 { 00206 this->highlightPath(prefPath); 00207 } 00208 } 00209 00210 foreach (node * n, nodes) 00211 { 00212 if(!(checkMac(n))) 00213 //if (!(checkIp(n->ip_addr))) 00214 { 00215 Node * temp = new Node(this, false, n->ip_addr, n); 00216 //delete n; 00217 allNodes << temp; 00218 scenex->addItem(temp); 00219 temp->setY(rand()%200); 00220 temp->setX(rand()%200); 00221 00222 } 00223 } 00224 00225 foreach (node * n, nodes) 00226 { 00227 Node * curnode = getNode(n); 00228 struct in_addr theaddr; 00229 theaddr.s_addr = curnode->getIpAddr(); //curNode can't be NULL! 00230 00231 fprintf(stderr, "ip_addr is: %s\n\n", inet_ntoa(theaddr)); 00232 std::vector<node *> neighbors = comm->get_neighbors(n); 00233 fprintf(stderr, "Its past\n\n", inet_ntoa(theaddr)); 00234 foreach (node * nb, neighbors) 00235 { 00236 //WE SHOULDN'T USE IP FOR ANYTHING. We need to use Mac Address 00237 if (/*nb->ip_addr!=0 &&*/ !(hasEdge(curnode, nb))) 00238 { 00239 Node * neighbor = getNode(nb); 00240 //if(neighbor != NULL) 00241 scenex->addItem(new Edge(curnode, neighbor, comm, mainWindow, false)); // <- This crashes shit. neighbor is null. 00242 } 00243 } 00244 } 00245 00246 00247 foreach (Node * n, allNodes) 00248 { 00249 bool found = false; 00250 foreach (node * nx, nodes) 00251 { 00252 //if (nx->ip_addr == n->getIpAddr()) 00253 if(sameMacAddr(nx, n->getNodePointer())) 00254 { 00255 found = true; 00256 } 00257 } 00258 if (!found) 00259 { 00260 n->setInactive(); 00261 } 00262 } 00263 00264 foreach (Node * n, allNodes) 00265 { 00266 if (!(n->isActive())) 00267 { 00268 foreach (Edge * e, n->edges()) 00269 { 00270 scenex->removeItem(e); 00271 } 00272 } 00273 else 00274 { 00275 foreach (Edge * e, n->edges()) 00276 { 00277 node * nx = n->getNodePointer(); 00278 std::vector<node *> neighbors = comm->get_neighbors(nx); 00279 00280 if (e->sourceNode() == n) 00281 { 00282 Node * other = e->destNode(); 00283 00284 bool found = false; 00285 foreach (node * nb, neighbors) 00286 { 00287 //if (nb->ip_addr == other->getIpAddr()) 00288 if(sameMacAddr(nb, other->getNodePointer())) 00289 { 00290 found = true; 00291 } 00292 } 00293 00294 if (!found) 00295 { 00296 scenex->removeItem(e); 00297 } 00298 } 00299 } 00300 } 00301 } 00302 00303 if (! _doPhysics) { 00304 plotNodes(); 00305 } 00306 00307 } 00308 00313 void GraphWidget::timerEvent(QTimerEvent *event) 00314 { 00315 Q_UNUSED(event); 00316 00317 QList<Node *> nodes; 00318 foreach (QGraphicsItem *item, scene()->items()) { 00319 if (Node *node = qgraphicsitem_cast<Node *>(item)) 00320 nodes << node; 00321 } 00322 00323 foreach (Node *node, nodes) 00324 node->calculateForces(_doPhysics); 00325 00326 bool itemsMoved = false; 00327 foreach (Node *node, nodes) { 00328 if (node->advance()) 00329 itemsMoved = true; 00330 } 00331 00332 /*if (!itemsMoved) { 00333 killTimer(timerId); 00334 timerId = 0; 00335 }*/ 00336 bool move = false; 00337 for (int i = 0; i < allNodes.size() && !move; i++) 00338 { 00339 Node * n = allNodes[i]; 00340 for (int j = 0; j < n->edges().size() && !move; j++) 00341 { 00342 Edge * e = n->edges()[j]; 00343 if (e->tooShort()) 00344 { 00345 move = true; 00346 } 00347 } 00348 } 00349 if (!move) 00350 { 00351 killTimer(timerId); 00352 timerId = 0; 00353 } 00354 } 00355 00356 00363 void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect) 00364 { 00365 Q_UNUSED(rect); 00366 00367 // Shadow 00368 QRectF sceneRect = this->sceneRect(); 00369 /*QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height()); 00370 QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5); 00371 if (rightShadow.intersects(rect) || rightShadow.contains(rect)) 00372 painter->fillRect(rightShadow, Qt::darkGray); 00373 if (bottomShadow.intersects(rect) || bottomShadow.contains(rect)) 00374 painter->fillRect(bottomShadow, Qt::darkGray);*/ 00375 00376 // Fill 00377 /* 00378 QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight()); 00379 gradient.setColorAt(0, Qt::white); 00380 gradient.setColorAt(1, Qt::lightGray); 00381 painter->fillRect(rect.intersect(sceneRect), gradient); 00382 painter->setBrush(Qt::NoBrush); 00383 painter->drawRect(sceneRect); 00384 */ 00385 00386 // Text 00387 QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4, 00388 sceneRect.width() - 4, sceneRect.height() - 4); 00389 QString message(tr("")); 00390 00391 QFont font = painter->font(); 00392 font.setBold(true); 00393 font.setPointSize(14); 00394 painter->setFont(font); 00395 painter->setPen(Qt::lightGray); 00396 painter->drawText(textRect.translated(2, 2), message); 00397 painter->setPen(Qt::black); 00398 painter->drawText(textRect, message); 00399 /* 00400 foreach(Node* n, allNodes) 00401 { 00402 struct in_addr theAddr; 00403 theAddr.s_addr = n->getIpAddr(); 00404 char *stringrepofIpAddress = inet_ntoa(theAddr); 00405 00406 painter->drawText(n->getPosition(), QString("%0").arg(stringrepofIpAddress)); 00407 }*/ 00408 00409 } 00410 /* 00411 void GraphWidget::scaleView(qreal scaleFactor) 00412 { 00413 qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width(); 00414 if (factor < 0.07 || factor > 100) 00415 return; 00416 00417 scale(scaleFactor, scaleFactor); 00418 } 00419 */ 00420 00425 void GraphWidget::setSelectedIP(uint32_t newIP) 00426 { 00427 selectedIP = newIP; 00428 } 00429 00430 uint32_t GraphWidget::getSelectedIP() 00431 { 00432 return selectedIP; 00433 } 00434 00439 void GraphWidget::setSourceMac(mac_t newMac) 00440 { 00441 foreach (node *n, comm->get_all_nodes()) 00442 { 00443 if (Node::macEqual(n->mac_addr, newMac)) 00444 { 00445 this->comm->set_ocu_machine(n); 00446 } 00447 } 00448 sourceMac = newMac; 00449 sourceSet = true; 00450 } 00451 00456 void GraphWidget::setDestinationMac(mac_t newMac) 00457 { 00458 foreach (node *n, comm->get_all_nodes()) 00459 { 00460 if (Node::macEqual(n->mac_addr, newMac)) 00461 { 00462 this->comm->set_target(n); 00463 } 00464 } 00465 destMac = newMac; 00466 destSet = true; 00467 } 00468 00473 mac_t GraphWidget::getDestinationMac() 00474 { 00475 return destMac; 00476 } 00477 00482 mac_t GraphWidget::getSourceMac() 00483 { 00484 return sourceMac; 00485 } 00486 00487 00491 void GraphWidget::updateNodesAndEdges() 00492 { 00493 /*if (sourceSet && destSet) 00494 { 00495 std::vector<node *> prefPath = comm->get_preferred_path(); 00496 if (!prefPath.empty()) 00497 { 00498 this->highlightPath(prefPath); 00499 } 00500 }*/ 00501 00502 QList<Node *>::const_iterator stlIter; 00503 for( stlIter = allNodes.begin(); stlIter != allNodes.end(); ++stlIter ) 00504 //for(std::vector<Node *>::iterator it = graph->allNodes.begin(); it != allNodes.end(); ++it) 00505 { 00506 Node *cur = (*stlIter); 00507 cur->update(); 00508 00509 foreach (Edge* e, cur->edges()) 00510 { 00511 e->update(); 00512 } 00513 } 00514 00515 mainWindow->updateList(); 00516 00517 if (!_doPhysics) { 00518 plotNodes(); 00519 } 00520 } 00521 00522 00526 void GraphWidget::plotNodes () { 00527 Point *center = mkpt(0, 0); 00528 00529 // std::vector<node*> nodes = commy->get_all_nodes(); 00530 00531 // get graphical nodes 00532 QList<Node *> nodes; 00533 foreach (QGraphicsItem *item, scene()->items()) { 00534 if (Node *node = qgraphicsitem_cast<Node *>(item)) 00535 nodes << node; 00536 } 00537 00538 // get points vector 00539 std::vector<Point*> *points = getNPointsOnCircle(center, CIRCLE_RADIUS, nodes.size()); // <-- define a radius size 00540 00541 int index = 0; 00542 foreach (Node *node, nodes) { 00543 Point * posPoint = points->at(index); 00544 fprintf(stderr, "new pos for node at index: %d -> (%d, %d)\n", index, posPoint->xval, posPoint->yval); 00545 node->setPos(posPoint->xval, posPoint->yval); 00546 // node->newPos(posPoint->xval, posPoint->yval); 00547 QPointF * qp = new QPointF(posPoint->xval, posPoint->yval); 00548 node->settPosition(qp); 00549 index++; 00550 } 00551 00552 this->scenex->update(this->sceneRect()); 00553 } 00554 00562 std::vector<Point*> *getNPointsOnCircle(Point *center, int radius, int numNodes) { 00563 00564 double alpha = PI * 2 / numNodes; 00565 std::vector<Point*> *points = new std::vector<Point*>(); 00566 00567 int i = -1; 00568 while (++i < numNodes) { 00569 double theta = alpha * i; 00570 Point *currPoint = mkpt (int(cos(theta)*radius),int(sin(theta)*radius)); 00571 currPoint = add (center, currPoint); 00572 points->push_back (currPoint); 00573 00574 } 00575 00576 return points; 00577 } 00578 00583 void GraphWidget::setDoPhysics(bool val) { 00584 _doPhysics = val; 00585 } 00586 00591 bool GraphWidget::getDoPhysics() { 00592 return _doPhysics; 00593 } 00594 00599 void GraphWidget::highlightPath(std::vector<node *> path) { 00600 // insert comm model call to get list 00601 //std::vector<node *> path = new std::vector<node *>(); // REPLACE WITH REAL SHIT. 00602 00603 for (int i = 0; i < path.size() - 1; i++) { 00604 Node * n1 = getNode(path[i]); 00605 Node * n2 = getNode(path[i+1]); 00606 00607 scenex->addItem(new Edge(n1, n2, comm, mainWindow, true)); 00608 } 00609 }