![]() |
TinkerCell Core 1.0
TinkerCell's Core library providing all basic functionalities
|
00001 /**************************************************************************** 00002 00003 Copyright (c) 2008 Deepak Chandran 00004 Contact: Deepak Chandran (dchandran1@gmail.com) 00005 See COPYRIGHT.TXT 00006 00007 One of the main classes in Tinkercell. 00008 00009 There are two classes defined in this file: ControlPoint and NodeGraphicsItem 00010 00011 The NodeGraphicsItem is a group made up of Shapes. Each Shape is a polygon item. 00012 Each shape has a default color. The purpose of the default color is to allow plugins 00013 to change color temporarily and then revert back to the default. 00014 00015 ControlPoint is a drawable item that is used by NodeGraphicsItem and ConnectionGraphicsItem 00016 to draw movable points. 00017 00018 ****************************************************************************/ 00019 #include <QFont> 00020 #include "ConsoleWindow.h" 00021 #include "GraphicsScene.h" 00022 #include "MainWindow.h" 00023 #include "ConnectionGraphicsItem.h" 00024 #include "NodeGraphicsItem.h" 00025 #include "ItemHandle.h" 00026 #include "UndoCommands.h" 00027 #include "fileIO/NodeGraphicsReader.h" 00028 #include "Tool.h" 00029 00030 namespace Tinkercell 00031 { 00032 const QString NodeGraphicsItem::CLASSNAME = QString("NodeGraphicsItem"); 00033 00034 ItemHandle * NodeGraphicsItem::handle() const 00035 { 00036 return itemHandle; 00037 } 00038 00039 void NodeGraphicsItem::setHandle(ItemHandle * handle) 00040 { 00041 if (handle != 0 && !handle->graphicsItems.contains(this)) 00042 { 00043 handle->graphicsItems += this; 00044 } 00045 00046 if (itemHandle) 00047 { 00048 if (itemHandle != handle) 00049 { 00050 itemHandle->graphicsItems.removeAll(this); 00051 itemHandle = handle; 00052 } 00053 } 00054 else 00055 { 00056 itemHandle = handle; 00057 } 00058 } 00059 00060 ItemHandle * NodeGraphicsItem::ControlPoint::handle() const 00061 { 00062 /*if (nodeItem) 00063 return nodeItem->handle();*/ 00064 return 0; 00065 } 00066 00067 void NodeGraphicsItem::ControlPoint::setHandle(ItemHandle * h) 00068 { 00069 if (nodeItem) 00070 nodeItem->setHandle(h); 00071 } 00072 00074 NodeGraphicsItem::NodeGraphicsItem(QGraphicsItem * parent) : 00075 QGraphicsItemGroup (parent), itemHandle(0), boundingBoxItem(0) 00076 { 00077 setCacheMode(QGraphicsItem::DeviceCoordinateCache); 00078 setFlag(QGraphicsItem::ItemIsMovable, false); 00079 setFlag(QGraphicsItem::ItemIsSelectable, false); 00080 00081 className = NodeGraphicsItem::CLASSNAME; 00082 00083 ControlPoint * topleft = new ControlPoint(this); 00084 topleft->setPos( boundingRect().topLeft() ); 00085 topleft->setVisible(false); 00086 topleft->scale(0.75,0.75); 00087 topleft->setPen(topleft->defaultPen = QPen(QColor(255,100,100),2.0)); 00088 topleft->setBrush(topleft->defaultBrush = QBrush(QColor(255,255,255,255))); 00089 00090 ControlPoint * bottomright = new ControlPoint(this); 00091 bottomright->setPos( boundingRect().bottomRight() ); 00092 bottomright->setVisible(false); 00093 bottomright->scale(0.75,0.75); 00094 bottomright->setPen(bottomright->defaultPen = QPen(QColor(255,100,100),2.0)); 00095 bottomright->setBrush(bottomright->defaultBrush = QBrush(QColor(255,255,255,255))); 00096 00097 bottomright->shapeType = topleft->shapeType = ControlPoint::square; 00098 boundaryControlPoints << topleft << bottomright; 00099 00100 boundingBoxItem = new QGraphicsRectItem(this); 00101 boundingBoxItem->setPen(QPen(QColor(255,100,100),getPenWidthForBoundingRect(),Qt::DashLine)); 00102 boundingBoxItem->setBrush(Qt::NoBrush); 00103 boundingBoxItem->setVisible(false); 00104 boundingBoxItem->setPos(0,0); 00105 boundingBoxItem->setRect(boundingRect()); 00106 00107 setBoundingBoxVisible(false); 00108 } 00109 00110 NodeGraphicsItem::NodeGraphicsItem(const QString & filename,QGraphicsItem * parent) : 00111 QGraphicsItemGroup (parent), itemHandle(0), boundingBoxItem(0) 00112 { 00113 setCacheMode(QGraphicsItem::DeviceCoordinateCache); 00114 setFlag(QGraphicsItem::ItemIsMovable, false); 00115 setFlag(QGraphicsItem::ItemIsSelectable, false); 00116 00117 className = NodeGraphicsItem::CLASSNAME; 00118 00119 ControlPoint * topleft = new ControlPoint(this); 00120 topleft->setPos( boundingRect().topLeft() ); 00121 topleft->setVisible(false); 00122 topleft->scale(0.75,0.75); 00123 topleft->setPen(topleft->defaultPen = QPen(QColor(255,100,100),2.0)); 00124 topleft->setBrush(topleft->defaultBrush = QBrush(QColor(255,255,255,255))); 00125 00126 ControlPoint * bottomright = new ControlPoint(this); 00127 bottomright->setPos( boundingRect().bottomRight() ); 00128 bottomright->setVisible(false); 00129 bottomright->scale(0.75,0.75); 00130 bottomright->setPen(bottomright->defaultPen = QPen(QColor(255,100,100),2.0)); 00131 bottomright->setBrush(bottomright->defaultBrush = QBrush(QColor(255,255,255,255))); 00132 00133 bottomright->shapeType = topleft->shapeType = ControlPoint::square; 00134 boundaryControlPoints << topleft << bottomright; 00135 00136 boundingBoxItem = new QGraphicsRectItem(this); 00137 boundingBoxItem->setPen(QPen(QColor(255,100,100),getPenWidthForBoundingRect(),Qt::DashLine)); 00138 boundingBoxItem->setBrush(Qt::NoBrush); 00139 boundingBoxItem->setVisible(false); 00140 boundingBoxItem->setPos(0,0); 00141 boundingBoxItem->setRect(boundingRect()); 00142 00143 setBoundingBoxVisible(false); 00144 00145 NodeGraphicsReader reader; 00146 reader.readXml(this, filename); 00147 normalize(); 00148 scale(defaultSize.width()/boundingRect().width(),defaultSize.height()/boundingRect().height()); 00149 } 00150 00152 void NodeGraphicsItem::resetToDefaults() 00153 { 00154 resetPen(); 00155 resetBrush(); 00156 resetTransform(); 00157 scale(defaultSize.width()/boundingRect().width(),defaultSize.height()/boundingRect().height()); 00158 adjustBoundaryControlPoints(); 00159 } 00160 00162 void NodeGraphicsItem::adjustBoundaryControlPoints() 00163 { 00164 if (boundaryControlPoints.size() == 2 00165 && boundaryControlPoints[0] 00166 && boundaryControlPoints[1]) 00167 { 00168 if (scene() && (boundaryControlPoints[0]->scene() != scene())) 00169 (static_cast<GraphicsScene*>(scene()))->addItem(boundaryControlPoints[0]); 00170 00171 if (scene() && (boundaryControlPoints[1]->scene() != scene())) 00172 (static_cast<GraphicsScene*>(scene()))->addItem(boundaryControlPoints[1]); 00173 00174 QRectF bounds = sceneBoundingRect(); 00175 QPointF p1 = boundaryControlPoints[0]->scenePos(), 00176 p2 = boundaryControlPoints[1]->scenePos(); 00177 if ( p1.rx() == 0 || p2.rx() == 0 || p1.ry() == 0 || p2.ry() == 0 || 00178 ( (p1.rx() - bounds.left())*(p1.rx() - bounds.left()) < 00179 (p1.rx() - bounds.right())*(p1.rx() - bounds.right()) ) ) 00180 { 00181 p1.rx() = bounds.left(); 00182 p2.rx() = bounds.right(); 00183 } 00184 00185 if ( p1.rx() == 0 || p2.rx() == 0 || p1.ry() == 0 || p2.ry() == 0 || 00186 ((p1.ry() - bounds.top())*(p1.ry() - bounds.top()) < 00187 (p1.ry() - bounds.bottom())*(p1.ry() - bounds.bottom()) ) ) 00188 { 00189 p1.ry() = bounds.top(); 00190 p2.ry() = bounds.bottom(); 00191 } 00192 00193 boundaryControlPoints[0]->setPos(p1); 00194 boundaryControlPoints[1]->setPos(p2); 00195 00196 boundaryControlPoints[0]->setZValue(zValue() + 0.1); 00197 boundaryControlPoints[1]->setZValue(zValue() + 0.1); 00198 } 00199 if (boundingBoxItem) 00200 { 00201 if (boundingBoxItem->parentItem() != this) 00202 addToGroup(boundingBoxItem); 00203 boundingBoxItem->setPos(0,0); 00204 boundingBoxItem->setRect(boundingRect()); 00205 } 00206 } 00207 00209 void NodeGraphicsItem::setBoundingBoxVisible(bool visible, bool controlPoints) 00210 { 00211 QGraphicsScene * s = scene(); 00212 adjustBoundaryControlPoints(); 00213 for (int i=0; i < boundaryControlPoints.size(); ++i) 00214 if (boundaryControlPoints[i]) 00215 { 00216 if (s && boundaryControlPoints[i]->scene() != s) 00217 (static_cast<GraphicsScene*>(s))->addItem(boundaryControlPoints[i]); 00218 00219 boundaryControlPoints[i]->setVisible(controlPoints && visible); 00220 //boundaryControlPoints[i]->setZValue(zValue() + 0.1); 00221 } 00222 if (boundingBoxItem) 00223 { 00224 if (boundingBoxItem->parentItem() != this) 00225 addToGroup(boundingBoxItem); 00226 boundingBoxItem->setZValue(zValue() + 0.1); 00227 boundingBoxItem->setVisible(visible); 00228 boundingBoxItem->setPos(0,0); 00229 boundingBoxItem->setRect(boundingRect()); 00230 } 00231 } 00232 00233 void NodeGraphicsItem::showBoundingBox(bool controlPoints) 00234 { 00235 setBoundingBoxVisible(true,controlPoints); 00236 } 00237 00238 void NodeGraphicsItem::hideBoundingBox(bool controlPoints) 00239 { 00240 setBoundingBoxVisible(true,controlPoints); 00241 } 00242 00244 NodeGraphicsItem::NodeGraphicsItem(const NodeGraphicsItem& copy) : 00245 QGraphicsItemGroup (0) , itemHandle(0), boundingBoxItem(0) 00246 { 00247 setFlag(QGraphicsItem::ItemIsMovable, false); 00248 setFlag(QGraphicsItem::ItemIsSelectable, false); 00249 setVisible(copy.isVisible()); 00250 00251 QTransform t0 = copy.sceneTransform(); 00252 QTransform t1(t0.m11(),t0.m12(),0,t0.m21(),t0.m22(),0,0,0,1); 00253 setPos(copy.scenePos()); 00254 00255 #if QT_VERSION > 0x040600 00256 setTransform(t1); 00257 #endif 00258 00260 className = copy.className; 00261 groupID = copy.groupID; 00262 itemHandle = copy.itemHandle; 00263 name = copy.name; 00264 defaultSize = copy.defaultSize; 00265 00266 if (itemHandle) 00267 setHandle(itemHandle); 00268 00270 for (int i=0; i < copy.controlPoints.size(); ++i) 00271 if (copy.controlPoints[i]) 00272 addControlPoint(new NodeGraphicsItem::ControlPoint(*copy.controlPoints[i])); 00273 00274 for (int i=0; i < copy.shapes.size(); ++i) 00275 if (copy.shapes[i]) 00276 { 00277 Shape * newShape = new Shape(*copy.shapes[i]); 00278 for (int j=0; j < newShape->controlPoints.size(); ++j) 00279 for (int k=0; k < copy.controlPoints.size(); ++k) 00280 if (newShape->controlPoints[j] == copy.controlPoints[k]) 00281 { 00282 newShape->controlPoints[j] = controlPoints[k]; 00283 } 00284 addShape(newShape); 00285 } 00286 00287 refresh(); 00288 00289 #if QT_VERSION < 0x040600 00290 setTransform(t1); 00291 #endif 00292 00293 ControlPoint * topleft = new ControlPoint(this); 00294 topleft->setPos( copy.sceneBoundingRect().topLeft() ); 00295 topleft->setVisible(false); 00296 topleft->scale(0.75,0.75); 00297 topleft->setPen(topleft->defaultPen = QPen(QColor(255,100,100),2.0)); 00298 topleft->setBrush(topleft->defaultBrush = QBrush(QColor(255,255,255,255))); 00299 00300 ControlPoint * bottomright = new ControlPoint(this); 00301 bottomright->setPos( copy.sceneBoundingRect().bottomRight() ); 00302 bottomright->setVisible(false); 00303 bottomright->scale(0.75,0.75); 00304 bottomright->setPen(bottomright->defaultPen = QPen(QColor(255,100,100),2.0)); 00305 bottomright->setBrush(bottomright->defaultBrush = QBrush(QColor(255,255,255,255))); 00306 00307 bottomright->shapeType = topleft->shapeType = ControlPoint::square; 00308 boundaryControlPoints << topleft << bottomright; 00309 00310 boundingBoxItem = new QGraphicsRectItem(this); 00311 boundingBoxItem->setPen(QPen(QColor(255,100,100),getPenWidthForBoundingRect(),Qt::DashLine)); 00312 boundingBoxItem->setBrush(Qt::NoBrush); 00313 boundingBoxItem->setVisible(false); 00314 boundingBoxItem->setPos(0,0); 00315 boundingBoxItem->setRect(boundingRect()); 00316 00317 setBoundingBoxVisible(false); 00318 } 00319 00320 qreal NodeGraphicsItem::getPenWidthForBoundingRect() 00321 { 00322 qreal w = (1000.0/((sceneBoundingRect().width() + sceneBoundingRect().height()))); 00323 if (w > 1.0) w = 1.0; 00324 return w; 00325 } 00326 00328 NodeGraphicsItem* NodeGraphicsItem::clone() const 00329 { 00330 NodeGraphicsItem* node = new NodeGraphicsItem(*this); 00331 //node->className = NodeGraphicsItem::CLASSNAME; 00332 return node; 00333 } 00334 00336 NodeGraphicsItem& NodeGraphicsItem::operator = (const NodeGraphicsItem& copy) 00337 { 00338 clear(); 00339 name = copy.name; 00340 //className = copy.className; 00341 defaultSize = copy.defaultSize; 00342 /*QList<QGraphicsItem*> children = childItems(); 00343 for (int i=0; i < children.size(); ++i) 00344 removeFromGroup(children[i]);*/ 00345 00347 QGraphicsItem * parent = parentItem(); 00348 setParentItem(0); 00349 setBoundingBoxVisible(false); 00350 00351 #if QT_VERSION < 0x040600 00352 resetTransform(); 00353 #endif 00354 00355 setPos(copy.scenePos()); 00356 00357 for (int i=0; i < copy.controlPoints.size(); ++i) 00358 if (copy.controlPoints[i]) 00359 addControlPoint(new NodeGraphicsItem::ControlPoint(*copy.controlPoints[i])); 00360 00361 for (int i=0; i < copy.shapes.size(); ++i) 00362 if (copy.shapes[i]) 00363 { 00364 Shape * newShape = new Shape(*copy.shapes[i]); 00365 for (int j=0; j < newShape->controlPoints.size(); ++j) 00366 for (int k=0; k < copy.controlPoints.size(); ++k) 00367 if (newShape->controlPoints[j] == copy.controlPoints[k]) 00368 { 00369 newShape->controlPoints[j] = controlPoints[k]; 00370 } 00371 addShape(newShape); 00372 } 00373 00374 refresh(); 00375 00376 #if QT_VERSION < 0x040600 00377 QTransform t0 = copy.sceneTransform(); 00378 QTransform t1(t0.m11(),t0.m12(),0,t0.m21(),t0.m22(),0,0,0,1); 00379 setTransform(t1); 00380 #endif 00381 00382 for (int i=0; i < boundaryControlPoints.size(); ++i) 00383 if (boundaryControlPoints[i] && !MainWindow::invalidPointers.contains(boundaryControlPoints[i])) 00384 { 00385 boundaryControlPoints[i]->nodeItem = 0; 00386 if (!boundaryControlPoints[i]->scene()) 00387 { 00388 delete boundaryControlPoints[i]; 00389 MainWindow::invalidPointers[ (void*)(boundaryControlPoints[i]) ] = true; 00390 } 00391 boundaryControlPoints[i] = 0; 00392 } 00393 boundaryControlPoints.clear(); 00394 00395 ControlPoint * topleft = new ControlPoint(this); 00396 topleft->setPos( copy.sceneBoundingRect().topLeft() ); 00397 topleft->setVisible(false); 00398 topleft->scale(0.75,0.75); 00399 topleft->setPen(topleft->defaultPen = QPen(QColor(255,100,100),2.0)); 00400 topleft->setBrush(topleft->defaultBrush = QBrush(QColor(255,255,255,255))); 00401 00402 ControlPoint * bottomright = new ControlPoint(this); 00403 bottomright->setPos( copy.sceneBoundingRect().bottomRight() ); 00404 bottomright->setVisible(false); 00405 bottomright->scale(0.75,0.75); 00406 bottomright->setPen(bottomright->defaultPen = QPen(QColor(255,100,100),2.0)); 00407 bottomright->setBrush(bottomright->defaultBrush = QBrush(QColor(255,255,255,255))); 00408 00409 bottomright->shapeType = topleft->shapeType = ControlPoint::square; 00410 boundaryControlPoints << topleft << bottomright; 00411 00412 boundingBoxItem = new QGraphicsRectItem(this); 00413 boundingBoxItem->setPen(QPen(QColor(255,100,100),getPenWidthForBoundingRect(),Qt::DashLine)); 00414 boundingBoxItem->setBrush(Qt::NoBrush); 00415 boundingBoxItem->setVisible(false); 00416 boundingBoxItem->setPos(0,0); 00417 boundingBoxItem->setRect(boundingRect()); 00418 00419 setParentItem(parent); 00420 /*QPointF center = sceneBoundingRect().center(); 00421 for (int i=0; i < children.size(); ++i) 00422 if (children[i]) 00423 { 00424 children[i]->setPos( center ); 00425 addToGroup(children[i]); 00426 }*/ 00427 00428 return *this; 00429 } 00430 00432 NodeGraphicsItem::~NodeGraphicsItem() 00433 { 00434 clear(); 00435 00436 QList<QGraphicsItem*> children = this->childItems(); 00437 00438 for (int i=0; i < children.size(); ++i) 00439 if (children[i]) 00440 children[i]->setParentItem(0); 00441 00442 for (int i=0; i < boundaryControlPoints.size(); ++i) 00443 if (boundaryControlPoints[i] && !MainWindow::invalidPointers.contains((void*)boundaryControlPoints[i])) 00444 { 00445 boundaryControlPoints[i]->nodeItem = 0; 00446 if (boundaryControlPoints[i]->scene()) 00447 boundaryControlPoints[i]->scene()->removeItem(boundaryControlPoints[i]); 00448 00449 delete boundaryControlPoints[i]; 00450 MainWindow::invalidPointers[ (void*)boundaryControlPoints[i] ] = true; 00451 00452 boundaryControlPoints[i] = 0; 00453 } 00454 00455 if (boundingBoxItem && !MainWindow::invalidPointers.contains((void*)(boundingBoxItem))) 00456 { 00457 removeFromGroup(boundingBoxItem); 00458 if (boundingBoxItem->scene()) 00459 boundingBoxItem->scene()->removeItem(boundingBoxItem); 00460 delete boundingBoxItem; 00461 MainWindow::invalidPointers[ (void*)(boundingBoxItem) ] = true; 00462 boundingBoxItem = 0; 00463 } 00464 00465 if (!itemHandle) return; 00466 setHandle(0); 00467 } 00468 00470 bool NodeGraphicsItem::isValid() const 00471 { 00472 return shapes.size() > 0; 00473 } 00474 00476 void NodeGraphicsItem::setBoundingRect(const QPointF& p1, const QPointF& p2) 00477 { 00478 if (boundaryControlPoints.size() < 2 || 00479 !boundaryControlPoints[0] || 00480 !boundaryControlPoints[1]) 00481 return; 00482 00483 boundaryControlPoints[0]->setPos(p1); 00484 boundaryControlPoints[1]->setPos(p2); 00485 00486 adjustToBoundaryControlPoints(); 00487 } 00488 00489 void NodeGraphicsItem::adjustToBoundaryControlPoints() 00490 { 00491 if (boundaryControlPoints.size() < 2 || 00492 !boundaryControlPoints[0] || 00493 !boundaryControlPoints[1]) 00494 return; 00495 00496 if (scene() && (boundaryControlPoints[0]->scene() != scene())) 00497 (static_cast<GraphicsScene*>(scene()))->addItem(boundaryControlPoints[0]); 00498 00499 if (scene() && (boundaryControlPoints[1]->scene() != scene())) 00500 (static_cast<GraphicsScene*>(scene()))->addItem(boundaryControlPoints[1]); 00501 00502 boundaryControlPoints[0]->setZValue(zValue() + 0.1); 00503 boundaryControlPoints[1]->setZValue(zValue() + 0.1); 00504 00505 QRectF bounds = sceneBoundingRect(); 00506 00507 QPointF p1 = boundaryControlPoints[0]->scenePos(), 00508 p2 = boundaryControlPoints[1]->scenePos(); 00509 00510 if (p1.rx() > p2.rx()) 00511 { 00512 double x = p1.rx(); 00513 p1.rx() = p2.rx(); 00514 p2.rx() = x; 00515 } 00516 00517 if (p1.ry() > p2.ry()) 00518 { 00519 double y = p1.ry(); 00520 p1.ry() = p2.ry(); 00521 p2.ry() = y; 00522 } 00523 00524 if (p1.x() == p2.x()) p2.rx() += 1; //prevent 0 width/height 00525 if (p1.y() == p2.y()) p2.ry() += 1; 00526 00527 QRectF rect = QRectF(p1,p2); 00528 00529 00530 if (rect.center().isNull() || sceneTransform().isRotating()) //the boundary points are not correct 00531 { 00532 adjustBoundaryControlPoints(); 00533 } 00534 else 00535 if (bounds != rect) 00536 { 00537 QPointF p = rect.center() - scenePos(); 00538 moveBy(p.x(),p.y()); 00539 scale(rect.width()/bounds.width(), 00540 rect.height()/bounds.height()); 00541 if (boundingBoxItem) 00542 { 00543 QPen pen = boundingBoxItem->pen(); 00544 qreal w = getPenWidthForBoundingRect(); 00545 pen.setWidthF(w); 00546 boundingBoxItem->setPen(pen); 00547 } 00548 } 00549 } 00550 00552 void NodeGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget) 00553 { 00554 if ((boundaryControlPoints.size() == 2) 00555 && !sceneTransform().isRotating() 00556 && boundaryControlPoints[0] && boundaryControlPoints[0]->isVisible() 00557 && boundaryControlPoints[1] && boundaryControlPoints[1]->isVisible() ) 00558 { 00559 adjustToBoundaryControlPoints(); 00560 //painter->setPen(QPen(boundaryControlPoints[0]->defaultPen.color(),1.0)); 00561 //painter->drawRoundRect(boundingRect()); 00562 //painter->drawRect(boundingRect()); 00563 } 00564 00565 QGraphicsItemGroup::paint(painter,option,widget); 00566 } 00567 00569 NodeGraphicsItem::ControlPoint::ControlPoint(NodeGraphicsItem * image_ptr, QGraphicsItem * parent) : 00570 Tinkercell::ControlPoint(parent) 00571 { 00572 nodeItem = image_ptr; 00573 setPen(defaultPen = QPen( QColor(100,100,255) )); 00574 setBrush(defaultBrush = QBrush( QColor(0,0,255,10)) ); 00575 setRect(QRectF(-10,-10,20,20)); 00576 setZValue(10); 00577 } 00578 00580 void NodeGraphicsItem::ControlPoint::sideEffect() 00581 { 00582 if (nodeItem && nodeItem->scene()) 00583 { 00584 for (int i=0; i < nodeItem->boundaryControlPoints.size(); ++i) 00585 if (nodeItem->boundaryControlPoints[i] == this) 00586 { 00587 nodeItem->adjustToBoundaryControlPoints(); 00588 break; 00589 } 00590 } 00591 } 00592 00594 NodeGraphicsItem::ControlPoint::ControlPoint(const ControlPoint& copy) : Tinkercell::ControlPoint(copy.parentItem()) 00595 { 00596 nodeItem = copy.nodeItem; 00597 setPos(copy.pos()); 00598 setRect(copy.rect()); 00599 setPen(defaultPen = copy.defaultPen); 00600 setBrush(defaultBrush = copy.defaultBrush); 00601 //setTransform(copy.transform()); 00602 } 00603 00605 Tinkercell::ControlPoint* NodeGraphicsItem::ControlPoint::clone() const 00606 { 00607 return new NodeGraphicsItem::ControlPoint(*this); 00608 } 00609 00611 NodeGraphicsItem::ControlPoint::~ControlPoint() 00612 { 00613 if (nodeItem) 00614 { 00615 for (int i=0; i < nodeItem->controlPoints.size(); ++i) 00616 if (nodeItem->controlPoints[i] == this) 00617 nodeItem->controlPoints[i] = 0; 00618 for (int i=0; i < nodeItem->boundaryControlPoints.size(); ++i) 00619 if (nodeItem->boundaryControlPoints[i] == this) 00620 nodeItem->boundaryControlPoints[i] = 0; 00621 nodeItem = 0; 00622 } 00623 } 00624 00626 NodeGraphicsItem::ControlPoint& NodeGraphicsItem::ControlPoint::operator =(const ControlPoint& copy) 00627 { 00628 nodeItem = copy.nodeItem; 00629 setPos(copy.pos()); 00630 setRect(copy.rect()); 00631 setPen(defaultPen = copy.defaultPen); 00632 setBrush(defaultBrush = copy.defaultBrush); 00633 setTransform(copy.transform()); 00634 defaultSize = copy.defaultSize; 00635 return *this; 00636 } 00637 00639 void NodeGraphicsItem::ControlPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget) 00640 { 00641 if (nodeItem && nodeItem->scene() == scene() && nodeItem->isVisible()) 00642 Tinkercell::ControlPoint::paint(painter,option,widget); 00643 } 00644 00645 00647 void NodeGraphicsItem::setBrush(const QBrush& newBrush) 00648 { 00649 for (int i=0; i < shapes.size(); ++i) 00650 { 00651 if (shapes[i])// && shapes[i]->contains(point)) 00652 { 00653 shapes[i]->setBrush(newBrush); 00654 } 00655 } 00656 } 00657 00659 void NodeGraphicsItem::setPen(const QPen& newPen) 00660 { 00661 for (int i=0; i < shapes.size(); ++i) 00662 { 00663 if (shapes[i])// && shapes[i]->contains(point)) 00664 { 00665 shapes[i]->setPen(newPen); 00666 } 00667 } 00668 } 00669 00671 void NodeGraphicsItem::resetBrush() 00672 { 00673 for (int i=0; i < shapes.size(); ++i) 00674 { 00675 if (shapes[i])// && shapes[i]->contains(point)) 00676 { 00677 shapes[i]->setBrush(shapes[i]->defaultBrush); 00678 } 00679 } 00680 } 00681 00683 void NodeGraphicsItem::resetPen() 00684 { 00685 for (int i=0; i < shapes.size(); ++i) 00686 { 00687 if (shapes[i])// && shapes[i]->contains(point)) 00688 { 00689 shapes[i]->setPen(shapes[i]->defaultPen); 00690 } 00691 } 00692 } 00693 00695 void NodeGraphicsItem::setAlpha(int value) 00696 { 00697 for (int i=0; i < shapes.size(); ++i) 00698 { 00699 if (shapes[i]) 00700 { 00701 QPen pen = shapes[i]->pen(); 00702 QColor col1 = pen.color(); 00703 col1.setAlpha(value); 00704 pen.setColor(col1); 00705 shapes[i]->setPen(pen); 00706 00707 QBrush brush = shapes[i]->brush(); 00708 QColor col2 = brush.color(); 00709 col2.setAlpha(value); 00710 brush.setColor(col2); 00711 if(brush.gradient()) 00712 { 00713 QGradient g(*brush.gradient()); 00714 QGradientStops stops = brush.gradient()->stops(); 00715 for (int i=0; i < stops.size(); ++i) 00716 stops[i].second.setAlpha(value); 00717 g.setStops(stops); 00718 brush = QBrush(g); 00719 } 00720 00721 shapes[i]->setBrush(brush); 00722 } 00723 } 00724 } 00725 00727 NodeGraphicsItem::Shape::Shape(NodeGraphicsItem * idrawable_ptr, QGraphicsItem * parent, QGraphicsScene * scene) : 00728 QGraphicsPolygonItem(parent, scene) 00729 { 00730 negative = false; 00731 nodeItem = idrawable_ptr; 00732 setPen(defaultPen = QPen(QColor(100,100,100))); 00733 setBrush(defaultBrush = QBrush(QColor(100,100,255,50))); 00734 } 00736 NodeGraphicsItem::Shape::Shape(const Shape& copy): QGraphicsPolygonItem(copy.parentItem(), copy.scene()) 00737 { 00738 negative = copy.negative; 00739 setPos(copy.pos()); 00740 defaultPen = copy.defaultPen; 00741 defaultBrush = copy.defaultBrush; 00742 setBrush(defaultBrush); 00743 setPen(defaultPen); 00744 nodeItem = copy.nodeItem; 00745 controlPoints = copy.controlPoints; 00746 parameters = copy.parameters; 00747 types = copy.types; 00748 gradientPoints = copy.gradientPoints; 00749 polygon = copy.polygon; 00750 } 00751 00753 NodeGraphicsItem::Shape& NodeGraphicsItem::Shape::operator = (const Shape& copy) 00754 { 00755 negative = copy.negative; 00756 setPos(copy.pos()); 00757 nodeItem = copy.nodeItem; 00758 controlPoints = copy.controlPoints; 00759 parameters = copy.parameters; 00760 types = copy.types; 00761 gradientPoints = copy.gradientPoints; 00762 polygon = copy.polygon; 00763 setPen(defaultPen = copy.defaultPen); 00764 setBrush(defaultBrush = copy.defaultBrush); 00765 setTransform(copy.transform()); 00766 return *this; 00767 } 00768 00770 /* void NodeGraphicsItem::Shape::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget) 00771 { 00772 painter->setRenderHint(QPainter::Antialiasing); 00773 QGraphicsPolygonItem::paint(painter,option,widget); 00774 }*/ 00780 void NodeGraphicsItem::Shape::refresh() 00781 { 00782 if (controlPoints.size() < 2) return; 00783 00784 int i = 0, j = 1, k = 0, pts = controlPoints.size(), ops = types.size(), params = parameters.size(); 00785 00786 QPainterPath path; 00787 path.moveTo(QPointF(controlPoints[0]->scenePos().x(),controlPoints[0]->scenePos().y())); 00788 00789 while (j < pts && i < ops) 00790 { 00791 switch(types[i]) 00792 { 00793 case arc: 00794 { 00795 if (pts > j && params > (k+1)) 00796 { 00797 qreal start = parameters[k], span = parameters[k+1]; 00798 qreal w = (controlPoints[j]->scenePos().x()-controlPoints[j-1]->scenePos().x()), 00799 h = (controlPoints[j]->scenePos().y()-controlPoints[j-1]->scenePos().y()); 00800 path.arcMoveTo(QRectF(controlPoints[j-1]->scenePos().x(),controlPoints[j-1]->scenePos().y(),w,h),start); 00801 path.arcTo(QRectF(controlPoints[j-1]->scenePos().x(),controlPoints[j-1]->scenePos().y(),w,h),start,span); 00802 path.moveTo(controlPoints[j]->scenePos().x(),controlPoints[j]->scenePos().y()); 00803 } 00804 j += 2; 00805 k += 2; 00806 } 00807 break; 00808 case line: 00809 { 00810 path.lineTo(QPointF(controlPoints[j]->scenePos().x(),controlPoints[j]->scenePos().y())); 00811 ++j; 00812 } 00813 break; 00814 case bezier: 00815 { 00816 if (controlPoints.size() > (j+2)) 00817 path.cubicTo(QPointF(controlPoints[j]->scenePos().x(),controlPoints[j]->scenePos().y()), 00818 QPointF(controlPoints[j+1]->scenePos().x(),controlPoints[j+1]->scenePos().y()), 00819 QPointF(controlPoints[j+2]->scenePos().x(),controlPoints[j+2]->scenePos().y())); 00820 j += 3; 00821 } 00822 break; 00823 case rectangle: 00824 { 00825 if (pts > j && params > k) 00826 { 00827 QRectF rect(controlPoints[j-1]->scenePos(),controlPoints[j]->scenePos()); 00828 path.addRoundedRect(rect,parameters[k],parameters[k]); 00829 } 00830 ++j; 00831 ++k; 00832 } 00833 break; 00834 } 00835 ++i; 00836 } 00837 path.closeSubpath(); 00838 this->path = path; 00839 polygon = path.toFillPolygon(); 00840 setPolygon(polygon); 00841 setFlag(QGraphicsItem::ItemIsMovable, false); 00842 setFlag(QGraphicsItem::ItemIsSelectable, false); 00843 recomputeBoundingRect(); 00844 } 00846 QRectF NodeGraphicsItem::Shape::boundingRect() const 00847 { 00848 //return boundingRectangle; 00849 return QGraphicsPolygonItem::boundingRect();//.adjusted(-pen().widthF(),-pen().widthF(),2.0*pen().widthF(),2.0*pen().widthF()); 00850 } 00851 00853 bool NodeGraphicsItem::Shape::isClosed() const 00854 { 00855 if (controlPoints.size() < 2) return false; 00856 00857 if (types.contains(rectangle) || types.contains(arc)) return true; 00858 00859 return (controlPoints.first() == controlPoints.last()); 00860 } 00861 00863 QPainterPath NodeGraphicsItem::Shape::shape() const 00864 { 00865 return path; 00866 } 00867 00869 void NodeGraphicsItem::addControlPoint(ControlPoint * control) 00870 { 00871 if (control) 00872 { 00873 control->nodeItem = this; 00874 controlPoints.push_back(control); 00875 } 00876 } 00878 void NodeGraphicsItem::Shape::recomputeBoundingRect() 00879 { 00880 qreal minx = 0, maxx = 0, miny = 0, maxy = 0; 00881 for (int i=0; i < controlPoints.size(); ++i) 00882 { 00883 if (i == 0) 00884 { 00885 minx = controlPoints[i]->x() - controlPoints[i]->rect().width(); 00886 maxx = controlPoints[i]->x() + controlPoints[i]->rect().width(); 00887 miny = controlPoints[i]->y() - controlPoints[i]->rect().height(); 00888 maxy = controlPoints[i]->y() + controlPoints[i]->rect().height(); 00889 } 00890 else 00891 { 00892 if (controlPoints[i]->x() - controlPoints[i]->rect().width() < minx) 00893 minx = controlPoints[i]->x() - controlPoints[i]->rect().width(); 00894 if (controlPoints[i]->x() + controlPoints[i]->rect().width() > maxx) 00895 maxx = controlPoints[i]->x() + controlPoints[i]->rect().width(); 00896 if (controlPoints[i]->y() - controlPoints[i]->rect().height() < miny) 00897 miny = controlPoints[i]->y() - controlPoints[i]->rect().height(); 00898 if (controlPoints[i]->y() + controlPoints[i]->rect().height() > maxy) 00899 maxy = controlPoints[i]->y() + controlPoints[i]->rect().height(); 00900 } 00901 } 00902 00903 boundingRectangle.setLeft(minx); 00904 boundingRectangle.setTop(miny); 00905 boundingRectangle.setRight(maxx); 00906 boundingRectangle.setBottom(maxy); 00907 } 00909 void NodeGraphicsItem::recomputeBoundingRect() 00910 { 00911 /*qreal minx = 0, maxx = 0, miny = 0, maxy = 0; 00912 for (int i=0; i < controlPoints.size(); ++i) 00913 { 00914 if (i == 0) 00915 { 00916 minx = controlPoints[i]->x() - controlPoints[i]->rect().width(); 00917 maxx = controlPoints[i]->x() + controlPoints[i]->rect().width(); 00918 miny = controlPoints[i]->y() - controlPoints[i]->rect().height(); 00919 maxy = controlPoints[i]->y() + controlPoints[i]->rect().height(); 00920 } 00921 else 00922 { 00923 if (controlPoints[i]->x() - controlPoints[i]->rect().width() < minx) 00924 minx = controlPoints[i]->x() - controlPoints[i]->rect().width(); 00925 if (controlPoints[i]->x() + controlPoints[i]->rect().width() > maxx) 00926 maxx = controlPoints[i]->x() + controlPoints[i]->rect().width(); 00927 if (controlPoints[i]->y() - controlPoints[i]->rect().height() < miny) 00928 miny = controlPoints[i]->y() - controlPoints[i]->rect().height(); 00929 if (controlPoints[i]->y() + controlPoints[i]->rect().height() > maxy) 00930 maxy = controlPoints[i]->y() + controlPoints[i]->rect().height(); 00931 } 00932 } 00933 00934 boundingRectangle.setLeft(minx); 00935 boundingRectangle.setTop(miny); 00936 boundingRectangle.setRight(maxx); 00937 boundingRectangle.setBottom(maxy); 00938 00939 for (int i=0; i < boundaryControlPoints.size(); ++i) 00940 if (boundaryControlPoints[i]) 00941 { 00942 if (i==0) 00943 boundaryControlPoints[i]->setPos(minx,miny); 00944 else 00945 boundaryControlPoints[i]->setPos(maxx,maxy); 00946 }*/ 00947 00948 boundingRectangle = QRectF(0,0,0,0); 00949 for (int i=0; i < shapes.size(); ++i) 00950 { 00951 if (shapes[i]) 00952 boundingRectangle = boundingRectangle.unite(shapes[i]->boundingRect()); 00953 } 00954 } 00955 00957 QRectF NodeGraphicsItem::boundingRect() const 00958 { 00959 return boundingRectangle; 00960 //return QGraphicsItemGroup::boundingRect(); 00961 } 00962 00964 QPolygonF NodeGraphicsItem::polygon() const 00965 { 00966 QPolygonF polygon; 00967 for (int i=0; i < shapes.size(); ++i) 00968 if (shapes[i]) 00969 polygon = polygon.united(shapes[i]->polygon); 00970 return polygon; 00971 } 00973 QPainterPath NodeGraphicsItem::shape() const 00974 { 00975 QPainterPath path; 00976 for (int i=0; i < shapes.size(); ++i) 00977 if (shapes[i]) 00978 path = path.united(shapes[i]->mapToParent(shapes[i]->shape())); 00979 return path; 00980 } 00982 void NodeGraphicsItem::addShape(Shape* shape) 00983 { 00984 if (shape) 00985 { 00986 shape->nodeItem = this; 00987 shapes.push_back(shape); 00988 } 00989 } 00991 void NodeGraphicsItem::removeControlPoint(ControlPoint * control) 00992 { 00993 if (control) 00994 { 00995 if (controlPoints.contains(control)) 00996 controlPoints.remove( controlPoints.indexOf(control) ); 00997 for (int i=shapes.size()-1; i >= 0; --i) 00998 if (shapes[i] && 00999 !MainWindow::invalidPointers.contains(shapes[i]) && 01000 shapes[i]->controlPoints.contains(control)) 01001 { 01002 removeFromGroup(shapes[i]); 01003 delete shapes[i]; 01004 shapes.remove(i); 01005 MainWindow::invalidPointers[ (void*)(shapes[i]) ] = true; 01006 } 01007 refresh(); 01008 } 01009 } 01011 void NodeGraphicsItem::removeShape(Shape* shape) 01012 { 01013 if (shape && !MainWindow::invalidPointers.contains(shape)) 01014 { 01015 if (shapes.contains(shape)) 01016 { 01017 shapes.remove( shapes.indexOf(shape)); 01018 removeFromGroup(shape); 01019 delete shape; 01020 MainWindow::invalidPointers[ (void*)shape ] = true; 01021 } 01022 refresh(); 01023 } 01024 } 01025 01031 void NodeGraphicsItem::refresh() 01032 { 01033 for (int i=0; i < shapes.size(); ++i) 01034 { 01035 if (shapes[i]) 01036 { 01037 removeFromGroup(shapes[i]); 01038 shapes[i]->refresh(); 01039 shapes[i]->setZValue(i); 01040 addToGroup(shapes[i]); 01041 } 01042 else 01043 shapes.remove(i); 01044 } 01045 recomputeBoundingRect(); 01046 01047 if (boundingBoxItem) 01048 { 01049 boundingBoxItem->setPen(QPen(QColor(255,100,100),getPenWidthForBoundingRect(),Qt::DashLine)); 01050 boundingBoxItem->setBrush(Qt::NoBrush); 01051 boundingBoxItem->setVisible(false); 01052 boundingBoxItem->setPos(0,0); 01053 boundingBoxItem->setRect(boundingRect()); 01054 } 01055 } 01056 01060 void NodeGraphicsItem::clear() 01061 { 01062 for (int i=0; i < shapes.size(); ++i) 01063 { 01064 if (shapes[i] && !MainWindow::invalidPointers.contains( (void*)shapes[i])) 01065 { 01066 removeFromGroup(shapes[i]); 01067 if (shapes[i]->scene()) 01068 shapes[i]->scene()->removeItem(shapes[i]); 01069 delete shapes[i]; 01070 MainWindow::invalidPointers[ (void*)shapes[i] ] = true; 01071 01072 shapes[i] = 0; 01073 } 01074 } 01075 01076 for (int i=0; i < controlPoints.size(); ++i) 01077 { 01078 if (controlPoints[i] && !MainWindow::invalidPointers.contains((void*)controlPoints[i])) 01079 { 01080 removeFromGroup(controlPoints[i]); 01081 if (controlPoints[i]->scene()) 01082 controlPoints[i]->scene()->removeItem(controlPoints[i]); 01083 delete controlPoints[i]; 01084 MainWindow::invalidPointers[ (void*)controlPoints[i] ] = true; 01085 01086 controlPoints[i] = 0; 01087 } 01088 } 01089 shapes.clear(); 01090 controlPoints.clear(); 01091 } 01095 void NodeGraphicsItem::normalize() 01096 { 01097 qreal minx = -1, maxx = -1, miny = -1, maxy = -1; 01098 for (int i=0; i < controlPoints.size(); ++i) 01099 if (controlPoints[i] != 0) 01100 { 01101 QPointF point = controlPoints[i]->pos(); 01102 if (maxx < 0 || maxx < point.x()) maxx = point.x(); 01103 if (maxy < 0 || maxy < point.y()) maxy = point.y(); 01104 if (minx < 0 || minx > point.x()) minx = point.x(); 01105 if (miny < 0 || miny > point.y()) miny = point.y(); 01106 } 01107 QPointF center( (minx + maxx)/2, (miny + maxy)/2 ); 01108 for (int i=0; i < controlPoints.size(); ++i) 01109 if (controlPoints[i] != 0) 01110 { 01111 QPointF point = controlPoints[i]->pos(); 01112 controlPoints[i]->setPos( point - center ); 01113 } 01114 01115 for (int i=0; i < shapes.size(); ++i) 01116 if (shapes[i] != 0) 01117 { 01118 Shape * shape = shapes[i]; 01119 shape->gradientPoints.first -= center; 01120 shape->gradientPoints.second -= center; 01121 QPointF start = shape->gradientPoints.first; 01122 QPointF stop = shape->gradientPoints.second; 01123 QBrush brush = shape->brush(); 01124 if (brush.gradient() != 0) 01125 { 01126 QGradient * oldGradient = new QGradient(*brush.gradient()); 01127 if (oldGradient->type() == QGradient::LinearGradient) 01128 { 01129 QLinearGradient gradient(start,stop); 01130 gradient.setStops(oldGradient->stops()); 01131 shape->setBrush(gradient); 01132 } 01133 else 01134 if (oldGradient->type() == QGradient::RadialGradient) 01135 { 01136 QRadialGradient gradient(start, 01137 sqrt( (stop.y()-start.y())*(stop.y()-start.y()) + 01138 (stop.x()-start.x())*(stop.x()-start.x()))); 01139 gradient.setStops(oldGradient->stops()); 01140 shape->setBrush(gradient); 01141 } 01142 else 01143 { 01144 QGradient gradient; 01145 gradient.setStops(oldGradient->stops()); 01146 shape->setBrush(gradient); 01147 } 01148 delete oldGradient; 01149 } 01150 shape->defaultBrush = shape->brush(); 01151 } 01152 // shapes[i]->translate(-center.x(), -center.y()); 01153 refresh(); 01154 } 01155 01157 NodeGraphicsItem * NodeGraphicsItem::topLevelNodeItem(QGraphicsItem* item,bool includeControlPoints) 01158 { 01159 NodeGraphicsItem * idptr = 0, * idptr2 = 0; 01160 NodeGraphicsItem::ControlPoint * cp = 0; 01161 01162 QGraphicsItem * p = item; 01163 01164 while (p) 01165 { 01166 idptr = NodeGraphicsItem::cast(p); 01167 01168 if (!idptr && includeControlPoints) 01169 { 01170 cp = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(p); 01171 if (cp && cp->nodeItem) 01172 idptr = cp->nodeItem; 01173 } 01174 01175 if (idptr != 0) idptr2 = idptr; 01176 01177 if (p != p->parentItem()) 01178 p = p->parentItem(); 01179 else 01180 break; 01181 } 01182 01183 return idptr2; 01184 } 01185 01187 QList<ConnectionGraphicsItem*> NodeGraphicsItem::connections() const 01188 { 01189 QList<ConnectionGraphicsItem*> connections; 01190 QList<QGraphicsItem*> children = childItems(); 01191 QGraphicsScene * scene = this->scene(); 01192 for (int i=0; i < children.size(); ++i) 01193 { 01194 ConnectionGraphicsItem::ControlPoint * cp = 01195 qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(children[i]); 01196 if (cp && cp->connectionItem) 01197 connections += cp->connectionItem; 01198 } 01199 return connections; 01200 } 01201 01203 QList<NodeGraphicsItem*> NodeGraphicsItem::connectedNodes() const 01204 { 01205 QList<ConnectionGraphicsItem*> cs = connections(); 01206 QList<NodeGraphicsItem*> nodes, list; 01207 01208 for (int i=0; i < cs.size(); ++i) 01209 { 01210 nodes = cs[i]->nodes(); 01211 for (int j=0; j < nodes.size(); ++j) 01212 if (!list.contains(nodes[j]) && nodes[j] != this) 01213 list += nodes[j]; 01214 } 01215 return list; 01216 } 01217 01218 01220 QList<ConnectionGraphicsItem*> NodeGraphicsItem::connectionsWithArrows() const 01221 { 01222 QList<ConnectionGraphicsItem*> connections; 01223 QList<QGraphicsItem*> children = this->childItems(); 01224 QGraphicsScene * scene = this->scene(); 01225 for (int i=0; i < children.size(); ++i) 01226 { 01227 ConnectionGraphicsItem::ControlPoint * cp = 01228 qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(children[i]); 01229 if (cp && cp->connectionItem 01230 && (cp->connectionItem->nodesWithArrows().contains(const_cast<NodeGraphicsItem*>(this)))) 01231 connections += cp->connectionItem; 01232 } 01233 return connections; 01234 } 01235 01237 QList<ConnectionGraphicsItem*> NodeGraphicsItem::connectionsWithoutArrows() const 01238 { 01239 QList<ConnectionGraphicsItem*> connections; 01240 QList<QGraphicsItem*> children = this->childItems(); 01241 QGraphicsScene * scene = this->scene(); 01242 for (int i=0; i < children.size(); ++i) 01243 { 01244 ConnectionGraphicsItem::ControlPoint * cp = 01245 qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(children[i]); 01246 if (cp && cp->connectionItem 01247 && !(cp->connectionItem->nodesWithArrows().contains(const_cast<NodeGraphicsItem*>(this)))) 01248 connections += cp->connectionItem; 01249 } 01250 return connections; 01251 } 01252 01254 QList<ConnectionGraphicsItem*> NodeGraphicsItem::connectionsDisconnected() const 01255 { 01256 QList<ConnectionGraphicsItem*> connections; 01257 QList<QGraphicsItem*> children = this->childItems(); 01258 QGraphicsScene * scene = this->scene(); 01259 for (int i=0; i < children.size(); ++i) 01260 { 01261 ConnectionGraphicsItem::ControlPoint * cp = 01262 qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(children[i]); 01263 if (cp && cp->connectionItem 01264 && (cp->connectionItem->nodesDisconnected().contains(const_cast<NodeGraphicsItem*>(this)))) 01265 connections += cp->connectionItem; 01266 } 01267 return connections; 01268 } 01269 01271 QList<QGraphicsItem*> NodeGraphicsItem::connectionsAsGraphicsItems() const 01272 { 01273 QList<QGraphicsItem*> connections; 01274 QList<QGraphicsItem*> children = this->childItems(); 01275 QGraphicsScene * scene = this->scene(); 01276 for (int i=0; i < children.size(); ++i) 01277 { 01278 ConnectionGraphicsItem::ControlPoint * cp = 01279 qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(children[i]); 01280 if (cp && cp->connectionItem) 01281 connections += cp->connectionItem; 01282 } 01283 return connections; 01284 } 01285 01286 QList<NodeGraphicsItem*> NodeGraphicsItem::nodesAdjacent() const 01287 { 01288 QList<NodeGraphicsItem*> nodes; 01289 01290 QGraphicsScene * scene = this->scene(); 01291 01292 if (!scene) return nodes; 01293 01294 QRectF rect = this->sceneBoundingRect(); 01295 rect.adjust( -rect.width()/10.0, -rect.height()/10.0, rect.width()/10.0, rect.height()/10.0 ); 01296 01297 QList<QGraphicsItem*> items = scene->items(rect); 01298 01299 NodeGraphicsItem * node; 01300 for (int i=0; i < items.size(); ++i) 01301 if ((node = topLevelNodeItem(items[i])) && node != this && !nodes.contains(node)) 01302 nodes << node; 01303 01304 return nodes; 01305 } 01306 01307 QList<NodeGraphicsItem*> NodeGraphicsItem::nodesToLeft() const 01308 { 01309 QList<NodeGraphicsItem*> nodes; 01310 01311 QGraphicsScene * scene = this->scene(); 01312 01313 if (!scene) return nodes; 01314 01315 QRectF rect; 01316 QPointF p; 01317 QList<QGraphicsItem*> items; 01318 NodeGraphicsItem * node1 = const_cast<NodeGraphicsItem*>(this); 01319 NodeGraphicsItem * node2 = 0; 01320 01321 while (node1) 01322 { 01323 rect = node1->sceneBoundingRect(); 01324 p = QPointF(rect.left() - 1.0, rect.center().y()); 01325 items = scene->items(p); 01326 01327 node1 = 0; 01328 for (int i=0; i < items.size(); ++i) 01329 if ((node2 = topLevelNodeItem(items[i])) && node2 != this && !nodes.contains(node2)) 01330 { 01331 node1 = node2; 01332 break; 01333 } 01334 if (node1) 01335 nodes << node1; 01336 } 01337 01338 return nodes; 01339 } 01340 01341 QList<NodeGraphicsItem*> NodeGraphicsItem::nodesToRight() const 01342 { 01343 QList<NodeGraphicsItem*> nodes; 01344 01345 QGraphicsScene * scene = this->scene(); 01346 01347 if (!scene) return nodes; 01348 01349 QRectF rect; 01350 QPointF p; 01351 QList<QGraphicsItem*> items; 01352 NodeGraphicsItem * node1 = const_cast<NodeGraphicsItem*>(this); 01353 NodeGraphicsItem * node2 = 0; 01354 01355 while (node1) 01356 { 01357 rect = node1->sceneBoundingRect(); 01358 p = QPointF(rect.right() + 1.0, rect.center().y()); 01359 items = scene->items(p); 01360 01361 node1 = 0; 01362 for (int i=0; i < items.size(); ++i) 01363 if ((node2 = topLevelNodeItem(items[i])) && node2 != this && !nodes.contains(node2)) 01364 { 01365 node1 = node2; 01366 break; 01367 } 01368 if (node1) 01369 nodes << node1; 01370 } 01371 01372 return nodes; 01373 } 01374 01375 QList<NodeGraphicsItem*> NodeGraphicsItem::nodesAbove() const 01376 { 01377 QList<NodeGraphicsItem*> nodes; 01378 01379 QGraphicsScene * scene = this->scene(); 01380 01381 if (!scene) return nodes; 01382 01383 QRectF rect; 01384 QPointF p; 01385 QList<QGraphicsItem*> items; 01386 NodeGraphicsItem * node1 = const_cast<NodeGraphicsItem*>(this); 01387 NodeGraphicsItem * node2 = 0; 01388 01389 while (node1) 01390 { 01391 rect = node1->sceneBoundingRect(); 01392 p = QPointF(rect.center().x(), rect.top() - 1.0); 01393 items = scene->items(p); 01394 01395 node1 = 0; 01396 for (int i=0; i < items.size(); ++i) 01397 if ((node2 = topLevelNodeItem(items[i])) && node2 != this && !nodes.contains(node2)) 01398 { 01399 node1 = node2; 01400 break; 01401 } 01402 if (node1) 01403 nodes << node1; 01404 } 01405 01406 return nodes; 01407 } 01408 01409 QList<NodeGraphicsItem*> NodeGraphicsItem::nodesBelow() const 01410 { 01411 QList<NodeGraphicsItem*> nodes; 01412 01413 QGraphicsScene * scene = this->scene(); 01414 01415 if (!scene) return nodes; 01416 01417 QRectF rect; 01418 QPointF p; 01419 QList<QGraphicsItem*> items; 01420 NodeGraphicsItem * node1 = const_cast<NodeGraphicsItem*>(this); 01421 NodeGraphicsItem * node2 = 0; 01422 01423 while (node1) 01424 { 01425 rect = node1->sceneBoundingRect(); 01426 p = QPointF(rect.center().x(), rect.bottom() + 1.0); 01427 items = scene->items(p); 01428 01429 node1 = 0; 01430 for (int i=0; i < items.size(); ++i) 01431 if ((node2 = topLevelNodeItem(items[i])) && node2 != this && !nodes.contains(node2)) 01432 { 01433 node1 = node2; 01434 break; 01435 } 01436 if (node1) 01437 nodes << node1; 01438 } 01439 01440 return nodes; 01441 } 01442 01443 QList<NodeGraphicsItem*> NodeGraphicsItem::nodesUpstream() const 01444 { 01445 QList<NodeGraphicsItem*> nodes; 01446 01447 QGraphicsScene * scene = this->scene(); 01448 01449 if (!scene) return nodes; 01450 01451 QRectF rect; 01452 QPointF p; 01453 QList<ConnectionGraphicsItem*> clist; 01454 QList<NodeGraphicsItem*> nlist; 01455 NodeGraphicsItem * node1 = const_cast<NodeGraphicsItem*>(this); 01456 01457 while (node1) 01458 { 01459 clist = node1->connectionsWithArrows(); 01460 01461 node1 = 0; 01462 for (int i=0; i < clist.size(); ++i) 01463 if (clist[i]) 01464 { 01465 nlist = clist[i]->nodesWithoutArrows(); 01466 for (int j=0; j < nlist.size(); ++j) 01467 if (nlist[j]) 01468 { 01469 node1 = nlist[j]; 01470 break; 01471 } 01472 if (node1) 01473 break; 01474 } 01475 if (node1 && node1 != this && !nodes.contains(node1)) 01476 nodes << node1; 01477 else 01478 node1 = 0; 01479 } 01480 01481 return nodes; 01482 } 01483 01484 QList<NodeGraphicsItem*> NodeGraphicsItem::nodesDownstream() const 01485 { 01486 QList<NodeGraphicsItem*> nodes; 01487 01488 QGraphicsScene * scene = this->scene(); 01489 01490 if (!scene) return nodes; 01491 01492 QRectF rect; 01493 QPointF p; 01494 QList<ConnectionGraphicsItem*> clist; 01495 QList<NodeGraphicsItem*> nlist; 01496 NodeGraphicsItem * node1 = const_cast<NodeGraphicsItem*>(this); 01497 01498 while (node1) 01499 { 01500 clist = node1->connectionsWithoutArrows(); 01501 01502 node1 = 0; 01503 for (int i=0; i < clist.size(); ++i) 01504 if (clist[i]) 01505 { 01506 nlist = clist[i]->nodesWithArrows(); 01507 for (int j=0; j < nlist.size(); ++j) 01508 if (nlist[j]) 01509 { 01510 node1 = nlist[j]; 01511 break; 01512 } 01513 if (node1) 01514 break; 01515 } 01516 if (node1 && node1 != this && !nodes.contains(node1)) 01517 nodes << node1; 01518 else 01519 node1 = 0; 01520 } 01521 01522 return nodes; 01523 } 01524 01525 NodeGraphicsItem::Shape * NodeGraphicsItem::longestShape() const 01526 { 01527 NodeGraphicsItem::Shape * shape = 0; 01528 for (int i=0; i < shapes.size(); ++i) 01529 if (!shape || shapes[i]->boundingRect().width() > shape->boundingRect().width()) 01530 shape = shapes[i]; 01531 01532 return shape; 01533 } 01534 01535 NodeGraphicsItem::Shape * NodeGraphicsItem::tallestShape() const 01536 { 01537 NodeGraphicsItem::Shape * shape = 0; 01538 for (int i=0; i < shapes.size(); ++i) 01539 if (!shape || shapes[i]->boundingRect().height() > shape->boundingRect().height()) 01540 shape = shapes[i]; 01541 01542 return shape; 01543 } 01544 01545 NodeGraphicsItem::Shape * NodeGraphicsItem::leftMostShape() const 01546 { 01547 NodeGraphicsItem::Shape * shape = 0; 01548 for (int i=0; i < shapes.size(); ++i) 01549 if (!shape || shapes[i]->boundingRect().left() < shape->boundingRect().left()) 01550 shape = shapes[i]; 01551 01552 return shape; 01553 } 01554 01555 NodeGraphicsItem::Shape * NodeGraphicsItem::rightMostShape() const 01556 { 01557 NodeGraphicsItem::Shape * shape = 0; 01558 for (int i=0; i < shapes.size(); ++i) 01559 if (!shape || shapes[i]->boundingRect().right() > shape->boundingRect().right()) 01560 shape = shapes[i]; 01561 01562 return shape; 01563 } 01564 01565 NodeGraphicsItem::Shape * NodeGraphicsItem::topMostShape() const 01566 { 01567 NodeGraphicsItem::Shape * shape = 0; 01568 for (int i=0; i < shapes.size(); ++i) 01569 if (!shape || shapes[i]->boundingRect().top() < shape->boundingRect().top()) 01570 shape = shapes[i]; 01571 01572 return shape; 01573 } 01574 01575 NodeGraphicsItem::Shape * NodeGraphicsItem::bottomMostShape() const 01576 { 01577 NodeGraphicsItem::Shape * shape = 0; 01578 for (int i=0; i < shapes.size(); ++i) 01579 if (!shape || shapes[i]->boundingRect().bottom() > shape->boundingRect().bottom()) 01580 shape = shapes[i]; 01581 01582 return shape; 01583 } 01584 01585 QList<Tinkercell::ControlPoint*> NodeGraphicsItem::allControlPoints() const 01586 { 01587 QList<Tinkercell::ControlPoint*> list; 01588 01589 for (int i=0; i < controlPoints.size(); ++i) 01590 list << controlPoints[i]; 01591 01592 for (int i=0; i < boundaryControlPoints.size(); ++i) 01593 list << boundaryControlPoints[i]; 01594 01595 return list; 01596 } 01597 01598 NodeGraphicsItem* NodeGraphicsItem::cast(QGraphicsItem * q) 01599 { 01600 //if (MainWindow::invalidPointers.contains( (void*)q )) return 0; 01601 01602 if (!q || ToolGraphicsItem::cast(q->topLevelItem())) return 0; 01603 01604 NodeGraphicsItem * node = qgraphicsitem_cast<NodeGraphicsItem*>(q); 01605 if (!node) 01606 node = qgraphicsitem_cast<ArrowHeadItem*>(q); 01607 01608 return node; 01609 } 01610 01611 QList<NodeGraphicsItem*> NodeGraphicsItem::cast(const QList<QGraphicsItem*>& list) 01612 { 01613 QList<NodeGraphicsItem*> nodes; 01614 NodeGraphicsItem* q; 01615 for (int i=0; i < list.size(); ++i) 01616 if (!MainWindow::invalidPointers.contains( (void*)(list[i]) ) && 01617 ( (q = qgraphicsitem_cast<NodeGraphicsItem*>(list[i])) || (q = qgraphicsitem_cast<ArrowHeadItem*>(list[i])) ) 01618 ) 01619 nodes << q; 01620 return nodes; 01621 } 01622 } 01623