TinkerCell Core 1.0
TinkerCell's Core library providing all basic functionalities
NodeGraphicsItem.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines