TinkerCell Core 1.0
TinkerCell's Core library providing all basic functionalities
ItemHandle.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 COPYWRITE.TXT
00006 
00007 This is one of the main classes in Tinkercell
00008 This file defines the ItemFamily, NodeFamily, and ConnectionFamily classes.
00009 Each item in Tinkercell has an associated family.
00010 
00011 ****************************************************************************/
00012 #include "ConsoleWindow.h"
00013 #include "NetworkHandle.h"
00014 #include "GraphicsScene.h"
00015 #include "TextGraphicsItem.h"
00016 #include "NodeGraphicsItem.h"
00017 #include "ConnectionGraphicsItem.h"
00018 #include "Tool.h"
00019 #include "ItemHandle.h"
00020 #include "UndoCommands.h"
00021 #include <QRegExp>
00022 
00023 namespace Tinkercell
00024 {
00025         /********************************
00026         GLOBAL FUNCTIONS
00027         ********************************/
00028 
00029         QString RemoveDisallowedCharactersFromName(const QString& s)
00030         {
00031                 QRegExp regex("[^0-9a-zA-z_\\.]");
00032                 QString s2 = s;
00033                 s2.replace(regex,"_");
00034                 if (s2.length() > 0 && s2[0].isNumber())
00035                         s2 = QString("_") + s2;
00036                 s2.replace("^","_");
00037                 s2.replace("\\","_");
00038                 s2.replace("[","_");
00039                 s2.replace("]","_");
00040                 return s2;
00041         }
00042 
00043         ItemHandle * getHandle(QGraphicsItem * item)
00044         {
00045                 if (!item/* || MainWindow::invalidPointers.contains((void*)item)*/) return 0;
00046 
00047                 item = getGraphicsItem(item);
00048 
00049                 NodeGraphicsItem * node = NodeGraphicsItem::cast(item);
00050                 if (node)
00051                         return (node->handle());
00052 
00053                 ConnectionGraphicsItem * connection = ConnectionGraphicsItem::cast(item);
00054                 if (connection)
00055                         return (connection->handle());
00056 
00057                 TextGraphicsItem * textItem = TextGraphicsItem::cast(item);
00058                 if (textItem)
00059                         return (textItem->handle());
00060 
00061                 ControlPoint * cp = ControlPoint::cast(item);
00062                 if (cp)
00063                 {
00064                         return (cp->handle());
00065                 }
00066                 return 0;
00067         }
00068         
00069         QList<ItemHandle*> getHandle(const QList<QGraphicsItem*>& items, bool includeNull)
00070         {
00071                 QList<ItemHandle*> list;
00072                 ItemHandle * h = 0;
00073                 for (int i=0; i < items.size(); ++i)
00074                 {
00075                         h = getHandle(items[i]);
00076                         if (includeNull || (h && !list.contains(h)))
00077                                 list << h;
00078                 }
00079                 return list;
00080         }
00081 
00082         void setHandle(QGraphicsItem * item, ItemHandle * handle)
00083         {
00084                 if (!item/* || MainWindow::invalidPointers.contains((void*)item)*/) return;
00085 
00086                 item = getGraphicsItem(item);
00087                 
00088                 NodeGraphicsItem * node = NodeGraphicsItem::cast(item);
00089                 if (node)
00090                 {
00091                         node->setHandle(handle);
00092                         return;
00093                 }
00094 
00095                 ConnectionGraphicsItem * connection = ConnectionGraphicsItem::cast(item);
00096                 if (connection)
00097                 {
00098                         connection->setHandle(handle);
00099                         return;
00100                 }
00101 
00102                 TextGraphicsItem * textItem = TextGraphicsItem::cast(item);
00103                 if (textItem)
00104                 {
00105                         textItem->setHandle(handle);
00106                         return;
00107                 }
00108         }
00109 
00110     /**********************************
00111         ITEM DATA
00112         **********************************/
00113         ItemData::ItemData()
00114         {
00115             numericalData.clear();
00116             textData.clear();
00117         }
00118 
00119     ItemData::ItemData(const ItemData& copy)
00120     {
00121         QList<QString> keys = copy.numericalData.keys();
00122         for (int i=0; i < keys.size(); ++i)
00123             numericalData[ keys[i] ] = DataTable<qreal>(copy.numericalData[ keys[i] ]);
00124 
00125         keys = copy.textData.keys();
00126         for (int i=0; i < keys.size(); ++i)
00127             textData[ keys[i] ] = DataTable<QString>(copy.textData[ keys[i] ]);
00128     }
00129 
00130     ItemData& ItemData::operator = (const ItemData& copy)
00131     {
00132         numericalData = copy.numericalData;
00133         textData = copy.textData;
00134         return (*this);
00135     }
00136 
00137         /**********************************
00138         ITEM HANDLE
00139         **********************************/
00140 
00141         ItemHandle::~ItemHandle()
00142         {
00143         if (parent)
00144                         parent->children.removeAll(this);
00145 
00146                 parent = 0;
00147                 if (data)
00148                 {
00149             delete data;
00150                         data = 0;
00151                 }
00152 
00153                 tools.clear();
00154 
00155                 QList<QGraphicsItem*> list = graphicsItems;
00156                 graphicsItems.clear();
00157 
00158                 for (int i=0; i < list.size(); ++i)
00159                         if (list[i] && !MainWindow::invalidPointers.contains((void*)list[i]))
00160                         {
00161                                 setHandle(list[i],0);
00162                                 MainWindow::invalidPointers[ (void*)list[i] ] = true;
00163                                 delete list[i];
00164                         }
00165 
00166                 for (int i=0; i < children.size(); ++i)
00167                 {
00168                         if (children[i] && !MainWindow::invalidPointers.contains((void*)children[i]))
00169                         {
00170                                 children[i]->parent = 0;
00171                                 MainWindow::invalidPointers[ (void*)children[i] ] = true;
00172                                 delete children[i];
00173                         }
00174                 }
00175                 
00176                 children.clear();
00177         }
00178         ItemHandle::ItemHandle(const QString& s) : QObject()
00179         {
00180                 network = 0;
00181                 parent = 0;
00182                 name = s;
00183                 type = 0;
00184                 data = new ItemData;
00185         }
00186 
00187         ItemHandle::ItemHandle(const ItemHandle& copy) : QObject()
00188         {
00189                 network = copy.network;
00190                 type = copy.type;
00191                 name = copy.name;
00192                 tools += copy.tools;
00193                 if (copy.data)
00194                         data = new ItemData(*(copy.data));
00195                 else
00196                         data = 0;
00197                 parent = 0;
00198                 setParent(copy.parent,false);
00199                 
00200         }
00201 
00203         ItemHandle& ItemHandle::operator = (const ItemHandle& copy)
00204         {
00205                 if (data)
00206                         delete data;
00207                 data = 0;
00208                 
00209                 for (int i=0; i < graphicsItems.size(); ++i)
00210                         if (getHandle(graphicsItems[i]) == this)
00211                                 setHandle(graphicsItems[i],0);
00212 
00213                 type = copy.type;
00214                 name = copy.name;
00215                 tools += copy.tools;
00216 
00217                 if (copy.data)
00218                         data = new ItemData(*(copy.data));
00219 
00220                 setParent(copy.parent,false);
00221                 
00222                 return *this;
00223         }
00224 
00225         void ItemHandle::copyDataTablesFrom(ItemHandle * copy)
00226         {
00227                 if (copy && copy->data)
00228                 {
00229                         if (data)
00230                                 delete data;
00231                         data = new ItemData(*(copy->data));
00232                 }
00233         }
00234 
00235         ItemHandle * ItemHandle::clone() const
00236         {
00237                 return new ItemHandle(*this);
00238         }
00239         
00240         ItemFamily* ItemHandle::family() const
00241         {
00242                 return 0;
00243         }
00244         
00245         void ItemHandle::setFamily(ItemFamily*, bool)
00246         {
00247         }
00248 
00249         void ItemHandle::rename(const QString& s)
00250         {
00251                 if (network)
00252                         network->rename(this,s);
00253         }
00254         
00255         void ItemHandle::changeData(const QString& hashstring0, const DataTable<qreal>* newdata)
00256         {
00257                 if (!newdata) return;
00258                 
00259                 if (!data) data = new ItemData;
00260                 
00261                 QString hashstring = hashstring0.toLower();
00262                 
00263                 if (network)
00264                 {
00265                         if (name.isEmpty())
00266                                 network->changeData( hashstring + QString(" changed"), this, hashstring, newdata);
00267                         else
00268                                 network->changeData( name + QString("'s ") + hashstring + QString(" changed"), this, hashstring, newdata);
00269                 }
00270                 else
00271                         data->numericalData[hashstring] = (*newdata);
00272         }
00273         
00274         void ItemHandle::changeData(const QString& hashstring0, const DataTable<QString>* newdata)
00275         {
00276                 if (!newdata) return;
00277                 
00278                 if (!data) data = new ItemData;
00279                 
00280                 QString hashstring = hashstring0.toLower();
00281                 
00282                 if (network)
00283                 {
00284                         if (name.isEmpty())
00285                                 network->changeData( hashstring + QString(" changed"), this, hashstring, newdata);
00286                         else
00287                                 network->changeData( name + QString("'s ") + hashstring + QString(" changed"), this, hashstring, newdata);
00288                 }
00289                 else
00290                         data->textData[hashstring] = (*newdata);                        
00291         }
00292 
00293         void ItemHandle::setParent(ItemHandle * p, bool useCommand)
00294         {
00295                 if (useCommand && network)
00296                 {
00297                         network->setParentHandle(this,p);
00298                 }
00299                 else
00300                 {
00301                         if (parent)
00302                         {
00303                                 parent->children.removeAll(this);
00304                         }
00305                         parent = p;
00306                         if (p && !p->children.contains(this))
00307                         {
00308                                 p->children.append(this);
00309                         }
00310                 }
00311         }
00312 
00313         bool ItemHandle::isChildOf(ItemHandle * handle) const
00314         {
00315                 if (!handle) return 0;
00316 
00317                 ItemHandle * p = parent;
00318 
00319                 while (p)
00320                 {
00321                         if (p == handle) return true;
00322                         p = p->parent;
00323                 }
00324                 return false;
00325         }
00326         
00327         int ItemHandle::depth() const
00328         {
00329                 int n = 0;
00330                 ItemHandle * p = parent;
00331 
00332                 while (p)
00333                 {
00334                         p = p->parent;
00335                         ++n;
00336                 }
00337                 return n;
00338         }
00339 
00340         QString ItemHandle::fullName(const QString& sep) const
00341         {
00342                 ItemHandle * p = parent;
00343                 QString name = this->name;
00344                 while (p != 0)
00345                 {
00346                         if (!p->name.isEmpty())
00347                                 name = p->name + sep + name;
00348                         p = p->parent;
00349                 }
00350                 if (name.isEmpty())
00351                         name = QString("_");
00352                 return name;
00353         }
00354 
00355         bool ItemHandle::isA(const ItemFamily* name) const
00356         {
00357                 return (family() && family()->isA(name));
00358         }
00359 
00360         bool ItemHandle::isA(const QString& name) const
00361         {
00362                 return (family() && family()->isA(name));
00363         }
00364 
00365         ItemHandle* ItemHandle::root(const QString& name) const
00366         {
00367                 ItemHandle * p = const_cast<ItemHandle*>(this);
00368                 ItemHandle * q = 0;
00369                 while (p)
00370                 {
00371                         if (name.isEmpty() || p->isA(name))
00372                                 q = p;
00373                         p = p->parent;
00374                 }
00375                 if (q && (name.isEmpty() || q->isA(name)))
00376                         return q;
00377                 return 0;
00378         }
00379 
00380         ItemHandle* ItemHandle::parentOfFamily(const QString& family) const
00381         {
00382                 ItemHandle * p = parent;
00383                 while (p)
00384                 {
00385                         if (p->isA(family)) return p;
00386                         p = p->parent;
00387                 }
00388                 return 0;
00389         }
00390         
00391         QStringList ItemHandle::numericalDataNames() const
00392         {
00393                 if (data)
00394                         return data->numericalData.keys();
00395                 return QStringList();
00396         }
00397         
00398         QStringList ItemHandle::textDataNames() const
00399         {
00400                 if (data)
00401                         return data->textData.keys();
00402                 return QStringList();
00403         }
00404 
00405         bool ItemHandle::hasNumericalData(const QString& name) const
00406         {
00407                 return (data && data->numericalData.contains(name.toLower()));
00408         }
00409 
00410         bool ItemHandle::hasTextData(const QString& name) const
00411         {
00412                 return (data && data->textData.contains(name.toLower()));
00413         }
00414 
00415         QList<QGraphicsItem*> ItemHandle::allGraphicsItems() const
00416         {
00417                 QList<QGraphicsItem*> list = graphicsItems;
00418                 QList<ItemHandle*> handles = children;
00419                 for (int i=0; i < handles.size(); ++i)
00420                 {
00421                         if (handles[i])
00422                         {
00423                                 for (int j=0; j < handles[i]->children.size(); ++j)
00424                                         if (!handles.contains(handles[i]->children[j]))
00425                                                 handles << handles[i]->children[j];
00426                                 for (int j=0; j < handles[i]->graphicsItems.size(); ++j)
00427                                         if (!list.contains(handles[i]->graphicsItems[j]))
00428                                                 list << handles[i]->graphicsItems[j];
00429                         }
00430                 }
00431                 return list;
00432         }
00433 
00434         qreal ItemHandle::numericalData(const QString& name0, int row, int column) const
00435         {
00436                 QString name = name0.toLower();
00437                 if (data && data->numericalData.contains(name))
00438                 {
00439                         return data->numericalData[name].at(row,column);
00440                 }
00441                 return 0.0;
00442         }
00443 
00444         qreal ItemHandle::numericalData(const QString& name0, const QString& row, const QString& column) const
00445         {
00446                 QString name = name0.toLower();
00447 
00448                 if (data && data->numericalData.contains(name))
00449                 {
00450                         if (!row.isEmpty() && !column.isEmpty())
00451                                 return data->numericalData[name].at(row,column);
00452                                 
00453                         if (row.isEmpty() && column.isEmpty())
00454                                 return data->numericalData[name].at(0,0);
00455                         else
00456                                 if (row.isEmpty())
00457                                         return data->numericalData[name].at(0,column);
00458                                 else
00459                                 if (column.isEmpty())
00460                                         return data->numericalData[name].at(row,0);
00461                 }
00462                 return 0.0;
00463         }
00464 
00465         QString ItemHandle::textData(const QString& name0, int row, int column) const
00466         {
00467                 QString name = name0.toLower();
00468 
00469                 if (data && data->textData.contains(name))
00470                 {
00471                         return data->textData[name].at(row,column);
00472                 }
00473                 return QString();
00474         }
00475 
00476         QString ItemHandle::textData(const QString& name0, const QString& row, const QString& column) const
00477         {
00478                 QString name = name0.toLower();
00479                                 
00480                 if (data && data->textData.contains(name))
00481                 {
00482                         if (!row.isEmpty() && !column.isEmpty())
00483                                 return data->textData[name].at(row,column);
00484                                 
00485                         if (row.isEmpty() && column.isEmpty())
00486                                 return data->textData[name].at(0,0);
00487                         else
00488                                 if (row.isEmpty())
00489                                         return data->textData[name].at(0,column);
00490                                 else
00491                                 if (column.isEmpty())
00492                                         return data->textData[name].at(row,0);
00493                 }
00494                 return QString();
00495         }
00496 
00497         qreal& ItemHandle::numericalData(const QString& name0, int row, int column)
00498         {
00499                 if (!data) data = new ItemData;
00500                 QString name = name0.toLower();
00501 
00502                 if (!data->numericalData.contains(name))
00503                 {
00504                         data->numericalData[name] = DataTable<qreal>();
00505                 }
00506 
00507                 return data->numericalData[name].value(row,column);
00508         }
00509 
00510         qreal& ItemHandle::numericalData(const QString& name0, const QString& row, const QString& column)
00511         {
00512                 if (!data) data = new ItemData;
00513                 QString name = name0.toLower();
00514 
00515                 if (!data->numericalData.contains(name))
00516                 {
00517                         data->numericalData[name] = DataTable<qreal>();
00518                 }
00519                                 
00520                 if (row.isEmpty() && column.isEmpty())
00521                         return data->numericalData[name].value(0,0);
00522                 else
00523                         if (row.isEmpty())
00524                                 return data->numericalData[name].value(0,column);
00525                         else
00526                         if (column.isEmpty())
00527                                 return data->numericalData[name].value(row,0);
00528 
00529                 return data->numericalData[name].value(row,column);
00530         }
00531 
00532         QString& ItemHandle::textData(const QString& name0, int row, int column)
00533         {
00534                 if (!data) data = new ItemData;
00535                 QString name = name0.toLower();
00536 
00537                 if (!data->textData.contains(name))
00538                 {
00539                         data->textData[name] = DataTable<QString>();
00540                 }
00541 
00542                 return data->textData[name].value(row,column);
00543         }
00544 
00545         QString& ItemHandle::textData(const QString& name0, const QString& row, const QString& column)
00546         {
00547                 if (!data) data = new ItemData;
00548                 QString name = name0.toLower();
00549 
00550                 if (!data->textData.contains(name))
00551                 {
00552                         data->textData[name] = DataTable<QString>();
00553                 }
00554                 
00555                 if (row.isEmpty() && column.isEmpty())
00556                         return data->textData[name].value(0,0);
00557                 else
00558                         if (row.isEmpty())
00559                                 return data->textData[name].value(0,column);
00560                         else
00561                         if (column.isEmpty())
00562                                 return data->textData[name].value(row,0);
00563 
00564                 return data->textData[name].value(row,column);
00565         }
00566 
00567         DataTable<qreal>& ItemHandle::numericalDataTable(const QString& name0)
00568         {
00569                 if (!data) data = new ItemData;
00570                 QString name = name0.toLower();
00571 
00572                 if (!data->numericalData.contains(name))
00573                 {
00574                         data->numericalData[name] = DataTable<qreal>();
00575                 }
00576 
00577                 return data->numericalData[name];
00578         }
00579 
00580         DataTable<QString>& ItemHandle::textDataTable(const QString& name0)
00581         {
00582                 if (!data) data = new ItemData;
00583                 QString name = name0.toLower();
00584 
00585                 if (!data->textData.contains(name))
00586                 {
00587                         data->textData[name] = DataTable<QString>();
00588                 }
00589 
00590                 return data->textData[name];
00591         }
00592 
00593         QList<ItemHandle*> ItemHandle::allChildren() const
00594         {
00595                 QList<ItemHandle*> handles = children;
00596                 for (int i=0; i < handles.size(); ++i)
00597                 {
00598                         if (handles[i])
00599                         {
00600                                 for (int j=0; j < handles[i]->children.size(); ++j)
00601                                         if (handles[i]->children[j] && !handles.contains(handles[i]->children[j]))
00602                                                 handles << handles[i]->children[j];
00603                         }
00604                 }
00605                 return handles;
00606         }
00607 
00608         /**********************************
00609         PART HANDLE
00610         **********************************/
00611 
00612         NodeHandle * NodeHandle::cast(ItemHandle * item)
00613         {
00614                 if (item && item->type == NodeHandle::TYPE)
00615                         return static_cast<NodeHandle*>(item);
00616                 return 0;
00617         }
00618 
00619         QList<NodeHandle*> NodeHandle::cast(const QList<ItemHandle*>& items)
00620         {
00621                 QList<NodeHandle*> nodes;
00622                 
00623                 for (int i=0; i < items.size(); ++i)
00624                         if (items[i] && items[i]->type == NodeHandle::TYPE)
00625                                 nodes << static_cast<NodeHandle*>(items[i]);
00626                 return nodes;
00627         }
00628 
00629         NodeHandle::NodeHandle(const QString& s, NodeFamily * family) : ItemHandle(s)
00630         {
00631                 nodeFamily = family;
00632                 type = NodeHandle::TYPE;
00633         }
00634 
00635         NodeHandle::NodeHandle(NodeFamily * family, NodeGraphicsItem * item) : ItemHandle()
00636         {
00637                 type = NodeHandle::TYPE;
00638                 nodeFamily = family;
00639                 if (item)
00640                 {
00641                         graphicsItems += item;
00642                         item->setHandle(this);
00643                 }
00644         }
00645         
00646         NodeHandle::NodeHandle(NodeFamily * family, const QString& s) : ItemHandle(s)
00647         {
00648                 nodeFamily = family;
00649                 type = NodeHandle::TYPE;
00650         }
00651 
00652         void NodeHandle::setFamily(ItemFamily * p, bool useCommand)
00653         {
00654                 if (nodeFamily == p) return;
00655 
00656                 if (useCommand && network)
00657                 {
00658                         ItemHandle * item = const_cast<NodeHandle*>(this);
00659                         network->setHandleFamily(item,p);
00660                 }
00661                 else
00662                 {
00663                         if (!p)
00664                                 nodeFamily = 0;
00665                         else
00666                         {
00667                                 NodeFamily * itemFamily = NodeFamily::cast(p);
00668                                 if (itemFamily)
00669                                         nodeFamily = itemFamily;
00670                         }
00671                 }
00672         }
00673 
00674         ItemFamily* NodeHandle::family() const
00675         {
00676                 return nodeFamily;
00677         }
00678 
00679         NodeHandle::NodeHandle(const NodeHandle & copy) : ItemHandle(copy)
00680         {
00681                 nodeFamily = copy.nodeFamily;
00682         }
00683 
00684         NodeHandle& NodeHandle::operator = (const NodeHandle& copy)
00685         {
00686             ItemHandle::operator=(copy);
00687             nodeFamily = copy.nodeFamily;
00688                 return *this;
00689         }
00690 
00691         ItemHandle * NodeHandle::clone() const
00692         {
00693                 return (new NodeHandle(*this));
00694         }
00695 
00696         QList<ConnectionHandle*> NodeHandle::connections() const
00697         {
00698                 QList<ConnectionHandle*> list;
00699 
00700                 if (graphicsItems.size() > 0)
00701                 {
00702                         QList<ConnectionGraphicsItem*> connections;
00703                         NodeGraphicsItem * node = 0;
00704                         for (int i=0; i < graphicsItems.size(); ++i)
00705                         {
00706                                 node = NodeGraphicsItem::cast(graphicsItems[i]);
00707                                 if (node)
00708                                 {
00709                                         connections = node->connections();
00710                                         for (int j=0; j < connections.size(); ++j)
00711                                                 if (connections[j] && connections[j]->handle() &&
00712                                                         connections[j]->handle()->type == ConnectionHandle::TYPE)
00713                                                         list << static_cast<ConnectionHandle*>(connections[j]->handle());
00714                                 }
00715                         }
00716                 }
00717                 return list;
00718         }
00719 
00720         /************************************
00721         CONNECTION HANDLE
00722         *************************************/
00723 
00724         ConnectionHandle * ConnectionHandle::cast(ItemHandle * item)
00725         {
00726                 if (item && item->type == ConnectionHandle::TYPE)
00727                         return static_cast<ConnectionHandle*>(item);
00728                 return 0;
00729         }
00730         
00731         QList<ConnectionHandle*> ConnectionHandle::cast(const QList<ItemHandle*>& items)
00732         {
00733                 QList<ConnectionHandle*> nodes;
00734                 
00735                 for (int i=0; i < items.size(); ++i)
00736                         if (items[i] && items[i]->type == ConnectionHandle::TYPE)
00737                                 nodes << static_cast<ConnectionHandle*>(items[i]);
00738                 return nodes;
00739         }
00740 
00741         ConnectionHandle::ConnectionHandle(const QString& s, ConnectionFamily * family) : ItemHandle(s)
00742         {
00743                 type = ConnectionHandle::TYPE;
00744                 parent = 0;
00745                 connectionFamily = family;
00746         }
00747         
00748 
00749         ConnectionHandle::ConnectionHandle(ConnectionFamily * family, const QString& s) : ItemHandle(s)
00750         {
00751                 type = ConnectionHandle::TYPE;
00752                 connectionFamily = family;
00753         }
00754 
00755         ConnectionHandle::ConnectionHandle(ConnectionFamily * family, ConnectionGraphicsItem * item) : ItemHandle()
00756         {
00757                 type = ConnectionHandle::TYPE;
00758                 connectionFamily = family;
00759                 if (item)
00760                 {
00761                         graphicsItems += item;
00762                         item->setHandle(this);
00763                 }
00764         }
00765         
00766         void ConnectionHandle::setFamily(ItemFamily * p, bool useCommand)
00767         {       
00768                 if (connectionFamily == p) return;
00769 
00770                 if (useCommand && network)
00771                 {
00772                         ItemHandle * item = const_cast<ConnectionHandle*>(this);
00773                         network->setHandleFamily(item,p);
00774                 }
00775                 else
00776                 {
00777                         if (!p)
00778                                 connectionFamily = 0;
00779                         else
00780                         {
00781                                 ConnectionFamily * itemFamily = ConnectionFamily::cast(p);
00782                                 if (itemFamily)
00783                                         this->connectionFamily = itemFamily;
00784                         }
00785                 }
00786         }
00787 
00788         ConnectionHandle::ConnectionHandle(const ConnectionHandle & copy) : ItemHandle(copy)
00789         {
00790                 connectionFamily = copy.connectionFamily;
00791                 nodesWithRoles = copy.nodesWithRoles;
00792         }
00793 
00794         ConnectionHandle& ConnectionHandle::operator = (const ConnectionHandle& copy)
00795         {
00796             ItemHandle::operator=(copy);
00797             connectionFamily = copy.connectionFamily;
00798                 nodesWithRoles = copy.nodesWithRoles;
00799                 return *this;
00800         }
00801 
00802         ItemHandle * ConnectionHandle::clone() const
00803         {
00804                 return (new ConnectionHandle(*this));
00805         }
00806 
00807         ItemFamily* ConnectionHandle::family() const
00808         {
00809                 return connectionFamily;
00810         }
00811 
00812         QList<NodeHandle*> ConnectionHandle::nodes(int role) const
00813         {
00814                 QList<NodeHandle*> nodeslist;
00815 
00816                 if (graphicsItems.size() > 0)
00817                 {
00818                         if (role == -1 ) return nodesIn();
00819                         if (role == 1 ) return nodesOut();
00820                         for (int j=0; j < graphicsItems.size(); ++j)
00821                         {
00822                                 ConnectionGraphicsItem * connection;
00823                                 QList<NodeGraphicsItem*> nodes;
00824                                 connection = ConnectionGraphicsItem::cast(graphicsItems[j]);
00825                                 if (connection)
00826                                 {
00827                                         nodes = connection->nodes();
00828                                         for (int i=0; i < nodes.size(); ++i)
00829                                         {
00830                                                 if (nodes[i] && nodes[i]->handle() &&
00831                                                         nodes[i]->handle()->type == NodeHandle::TYPE)
00832                                                         nodeslist << static_cast<NodeHandle*>(nodes[i]->handle());
00833                                         }
00834                                 }
00835                         }
00836                 }
00837                 else
00838                 {
00839                         for (int i=0; i < nodesWithRoles.size(); ++i)
00840                                 if (nodesWithRoles[i].first && (role == 0 || nodesWithRoles[i].second == role))
00841                                         nodeslist << nodesWithRoles[i].first;
00842                 }
00843                 return nodeslist;
00844         }
00845 
00846         QList<NodeHandle*> ConnectionHandle::nodesIn() const
00847         {
00848                 QList<NodeHandle*> nodesList;
00849                 if (graphicsItems.size() > 0)
00850                 {
00851                         ConnectionGraphicsItem * connection;
00852                         QList<NodeGraphicsItem*> nodesDisconnected, nodesIn, nodesOut;
00853                         for (int j=0; j < graphicsItems.size(); ++j)
00854                         {
00855                                 connection = ConnectionGraphicsItem::cast(graphicsItems[j]);
00856                                 if (connection && !connection->isModifier())
00857                                 {
00858                                         nodesIn = connection->nodesWithoutArrows();
00859                                         nodesOut = connection->nodesWithArrows();
00860                                         nodesDisconnected = connection->nodesDisconnected();
00861 
00862                                         bool ok = false;
00863                                         for (int i=0; i < nodesOut.size(); ++i)
00864                                         {
00865                                                 if (nodesOut[i] && nodesOut[i]->handle())
00866                                                 {
00867                                                         ok = true;
00868                                                         break;
00869                                                 }
00870                                         }
00871 
00872                                         if (!ok) continue;
00873 
00874                                         for (int i=0; i < nodesIn.size(); ++i)
00875                                         {
00876                                                 if (nodesIn[i] && !nodesDisconnected.contains(nodesIn[i]) &&
00877                                                         nodesIn[i]->handle() &&
00878                                                         nodesIn[i]->handle()->type == NodeHandle::TYPE)
00879                                                         nodesList << static_cast<NodeHandle*>(nodesIn[i]->handle());
00880                                         }
00881                                 }
00882                         }
00883                 }
00884                 else
00885                 {
00886                         nodesList = nodes(-1);
00887                 }       
00888                 return nodesList;
00889         }
00890 
00891         QList<NodeHandle*> ConnectionHandle::nodesOut() const
00892         {
00893                 QList<NodeHandle*> nodesList;
00894                 if (graphicsItems.size() > 0)
00895                 {
00896                         QList<NodeGraphicsItem*> nodesIn, nodesOut, nodesDisconnected;
00897                         ConnectionGraphicsItem * connection;
00898                         for (int j=0; j < graphicsItems.size(); ++j)
00899                         {
00900                                 connection = ConnectionGraphicsItem::cast(graphicsItems[j]);
00901                                 if (connection && !connection->isModifier())
00902                                 {
00903                                         nodesIn = connection->nodesWithoutArrows();
00904                                         nodesOut = connection->nodesWithArrows();
00905                                         nodesDisconnected = connection->nodesDisconnected();
00906 
00907                                         bool ok = false;
00908                                         for (int i=0; i < nodesIn.size(); ++i)
00909                                         {
00910                                                 if (nodesIn[i] && nodesIn[i]->handle())
00911                                                 {
00912                                                         ok = true;
00913                                                         break;
00914                                                 }
00915                                         }
00916 
00917                                         if (!ok) continue;
00918 
00919                                         for (int i=0; i < nodesOut.size(); ++i)
00920                                         {
00921                                                 if (nodesOut[i] && !nodesDisconnected.contains(nodesOut[i]) &&
00922                                                         nodesOut[i]->handle() &&
00923                                                         nodesOut[i]->handle()->type == NodeHandle::TYPE)
00924                                                         nodesList << static_cast<NodeHandle*>(nodesOut[i]->handle());
00925                                         }
00926                                 }
00927                         }
00928                 }
00929                 else
00930                 {
00931                         nodesList = nodes(1);
00932                 }
00933                 return nodesList;
00934         }
00935         
00936         void ConnectionHandle::addNode(NodeHandle * h, int role)
00937         {
00938                 if (h)
00939                         nodesWithRoles << QPair<NodeHandle*,int>(h,role);
00940         }
00941         
00942         void ConnectionHandle::clearNodes()
00943         {
00944                 nodesWithRoles.clear();
00945         }
00946 
00947         QList<ItemFamily*> ConnectionHandle::findValidChildFamilies() const
00948         {
00949                 QList<ItemFamily*> list;
00950                 ConnectionFamily * connection = ConnectionFamily::cast(family());
00951                 if (connection)
00952                         list = connection->findValidChildFamilies(nodes());
00953                 return list;
00954         }
00955 
00956 }
00957 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines