TinkerCell Core 1.0
TinkerCell's Core library providing all basic functionalities
UndoCommands.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 This file contains a collection of commands that perform simple operations that can be redone and undone.
00008 
00009 ****************************************************************************/
00010 #include <iostream>
00011 #include "NodeGraphicsItem.h"
00012 #include "fileIO/NodeGraphicsReader.h"
00013 #include "ConnectionGraphicsItem.h"
00014 #include "TextGraphicsItem.h"
00015 #include "Tool.h"
00016 #include "GraphicsScene.h"
00017 #include "TextEditor.h"
00018 #include "NetworkHandle.h"
00019 #include "UndoCommands.h"
00020 #include "ConsoleWindow.h"
00021 #include "GlobalSettings.h"
00022 #include <QRegExp>
00023 #include <QStringList>
00024 #include <QDebug>
00025 
00026 namespace Tinkercell
00027 {
00028 
00029         MoveCommand::MoveCommand(GraphicsScene * scene, const QList<QGraphicsItem *>& items, const QList<QPointF>& amounts)
00030                 : QUndoCommand(QObject::tr("items moved by ..."))
00031         {
00032                 graphicsScene = scene;
00033                 graphicsItems.clear();
00034 
00035                 change.clear();
00036                 graphicsItems.clear();
00037 
00038                 ConnectionGraphicsItem * connection = 0;
00039                 NodeGraphicsItem * node = 0;
00040                 
00041                 for (int i=0; i < items.size() && i < amounts.size(); ++i)
00042                         if (items[i] && !amounts[i].isNull())
00043                         {
00044                                 if ((connection = ConnectionGraphicsItem::cast(items[i])))
00045                                 {
00046                                         QList<QGraphicsItem*> cps = connection->controlPointsAsGraphicsItems();
00047                                         for (int j=0; j < cps.size(); ++j)
00048                                         {
00049                                                 if (!graphicsItems.contains(cps[j]))
00050                                                 {
00051                                                         graphicsItems += cps[j];
00052                                                         change += amounts[i];
00053                                                 }
00054                                         }
00055                                 }
00056                                 else
00057                                 {
00058                                         if (!graphicsItems.contains(items[i]))
00059                                         {
00060                                                 graphicsItems += items[i];
00061                                                 change += amounts[i];
00062                                         }
00063 
00064                                         if ((node = NodeGraphicsItem::cast(items[i])))
00065                                         {
00066                                                 QVector<NodeGraphicsItem::ControlPoint*> cps = node->boundaryControlPoints;
00067                                                 for (int j=0; j < cps.size(); ++j)
00068                                                 {
00069                                                         if (!graphicsItems.contains(cps[j]))
00070                                                         {
00071                                                                 graphicsItems += cps[j];
00072                                                                 change += amounts[i];
00073                                                         }
00074                                                 }
00075                                         }
00076                                 }
00077                         }
00078         }
00079 
00080         MoveCommand::MoveCommand(GraphicsScene * scene, const QList<QGraphicsItem*>& items, const QPointF& amount)
00081                 : QUndoCommand(QObject::tr("items moved by (") + QString::number(amount.x()) + QObject::tr(",") + QString::number(amount.y()) + QObject::tr(")"))
00082         {
00083                 graphicsScene = scene;
00084                 change.clear();
00085                 ConnectionGraphicsItem * connection = 0;
00086                 NodeGraphicsItem * node = 0;
00087                 for (int i=0; i < items.size(); ++i)
00088                         if (items[i] && !amount.isNull())
00089                         {
00090                                 if ((connection = ConnectionGraphicsItem::cast(items[i])))
00091                                 {
00092                                         QList<QGraphicsItem*> cps = connection->controlPointsAsGraphicsItems();
00093                                         for (int j=0; j < cps.size(); ++j)
00094                                         {
00095                                                 if (!graphicsItems.contains(cps[j]))
00096                                                 {
00097                                                         graphicsItems += cps[j];
00098                                                         change += amount;
00099                                                 }
00100                                         }
00101                                 }
00102                                 else
00103                                 {
00104                                         if (!graphicsItems.contains(items[i]))
00105                                         {
00106                                                 graphicsItems += items[i];
00107                                                 change += amount;
00108                                         }
00109                                         if ((node = NodeGraphicsItem::cast(items[i])))
00110                                         {
00111                                                 QVector<NodeGraphicsItem::ControlPoint*> cps = node->boundaryControlPoints;
00112                                                 for (int j=0; j < cps.size(); ++j)
00113                                                 {
00114                                                         if (!graphicsItems.contains(cps[j]))
00115                                                         {
00116                                                                 graphicsItems += cps[j];
00117                                                                 change += amount;
00118                                                         }
00119                                                 }
00120                                         }
00121                                 }
00122                         }
00123         }
00124 
00125         MoveCommand::MoveCommand(GraphicsScene * scene, QGraphicsItem * item, const QPointF& amount)
00126                 : QUndoCommand(QObject::tr("items moved by (") + QString::number(amount.x()) + QObject::tr(",") + QString::number(amount.y()) + QObject::tr(")"))
00127         {
00128                 graphicsScene = scene;
00129                 graphicsItems.clear();
00130                 change.clear();
00131                 ConnectionGraphicsItem * connection = 0;
00132                 NodeGraphicsItem * node = 0;
00133                 
00134                 if (item && !amount.isNull())
00135                 {
00136                         if ((connection = ConnectionGraphicsItem::cast(item)))
00137                         {
00138                                 QList<QGraphicsItem*> cps = connection->controlPointsAsGraphicsItems();
00139                                 for (int j=0; j < cps.size(); ++j)
00140                                 {
00141                                         if (!graphicsItems.contains(cps[j]))
00142                                         {
00143                                                 graphicsItems += cps[j];
00144                                                 change += amount;
00145                                         }
00146                                 }
00147                         }
00148                         else
00149                         {
00150                                 if (!graphicsItems.contains(item))
00151                                 {
00152                                         graphicsItems += item;
00153                                         change += amount;
00154                                 }
00155                                 if ((node = NodeGraphicsItem::cast(item)))
00156                                 {
00157                                         QVector<NodeGraphicsItem::ControlPoint*> cps = node->boundaryControlPoints;
00158                                         for (int j=0; j < cps.size(); ++j)
00159                                         {
00160                                                 if (!graphicsItems.contains(cps[j]))
00161                                                 {
00162                                                         graphicsItems += cps[j];
00163                                                         change += amount;
00164                                                 }
00165                                         }
00166                                 }
00167                         }
00168                 }
00169         }
00170 
00171         void MoveCommand::refreshAllConnectionIn(const QList<QGraphicsItem*>& moving)
00172         {
00173                 QList<ConnectionGraphicsItem*> connections;
00174                 ConnectionGraphicsItem::ControlPoint* cgp = 0;
00175                 for (int i=0; i < moving.size(); ++i)
00176                         if ((cgp = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(moving[i]))
00177                                 && cgp->connectionItem
00178                                 && !connections.contains(cgp->connectionItem))
00179                                 connections += cgp->connectionItem;
00180                         else
00181                         {
00182                                 QList<QGraphicsItem*> children = moving[i]->childItems();
00183                                 for (int i=0; i < children.size(); ++i)
00184                                         if ((cgp = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(children[i]))
00185                                                 && cgp->connectionItem
00186                                                 && !connections.contains(cgp->connectionItem))
00187                                                 connections += cgp->connectionItem;
00188                         }
00189 
00190                         for (int i=0; i < connections.size(); ++i)
00191                                 connections[i]->refresh();
00192         }
00193 
00194         void MoveCommand::redo()
00195         {
00196                 QList<ControlPoint*> controlPoints;
00197                 ConnectionGraphicsItem::ControlPoint * ccp = 0;
00198                 NodeGraphicsItem::ControlPoint * pcp = 0;
00199                 QGraphicsItem * parent = 0;
00200                 for (int i=0; i<graphicsItems.size() && i<change.size(); ++i)
00201                         if (graphicsItems[i])
00202                         {
00203                                 parent = graphicsItems[i]->parentItem();
00204                                 graphicsItems[i]->setParentItem(0);
00205 
00206                                 graphicsItems[i]->moveBy(change[i].x(),change[i].y());
00207                                 if ((ccp = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(graphicsItems[i])))
00208                                         controlPoints += ccp;
00209                                 else
00210                                         if ((pcp = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(graphicsItems[i])) &&
00211                                                 !graphicsItems.contains(pcp->nodeItem))
00212                                                 controlPoints += pcp;
00213 
00214                                 graphicsItems[i]->setParentItem(parent);
00215                         }
00216                 for (int i=0; i < controlPoints.size(); ++i)
00217                 {
00218                         controlPoints[i]->sideEffect();
00219                 }
00220                 refreshAllConnectionIn(graphicsItems);
00221         }
00222 
00223         void MoveCommand::undo()
00224         {
00225                 QList<ControlPoint*> controlPoints;
00226                 ConnectionGraphicsItem::ControlPoint * ccp = 0;
00227                 NodeGraphicsItem::ControlPoint * pcp = 0;
00228                 QGraphicsItem * parent = 0;
00229                 for (int i=0; i<graphicsItems.size() && i<change.size(); ++i)
00230                         if (graphicsItems[i])
00231                         {
00232                                 parent = graphicsItems[i]->parentItem();
00233                                 graphicsItems[i]->setParentItem(0);
00234 
00235                                 graphicsItems[i]->moveBy(-change[i].x(), -change[i].y());
00236                                 if ((ccp = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(graphicsItems[i])))
00237                                         controlPoints += ccp;
00238                                 else
00239                                         if ((pcp = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(graphicsItems[i])) &&
00240                                                 !graphicsItems.contains(pcp->nodeItem))
00241                                                 controlPoints += pcp;
00242 
00243                                 graphicsItems[i]->setParentItem(parent);
00244                         }
00245                         for (int i=0; i < controlPoints.size(); ++i)
00246                         {
00247                                 controlPoints[i]->sideEffect();
00248                         }
00249                         refreshAllConnectionIn(graphicsItems);
00250         }
00251         
00252         InsertHandlesCommand::~InsertHandlesCommand()
00253         {
00254                 for (int i=0; i < items.size(); ++i)
00255                         if (items[i] && !MainWindow::invalidPointers.contains((void*)items[i]))
00256                         {
00257                                 MainWindow::invalidPointers[ (void*)items[i] ] = true;
00258                                 delete items[i];
00259                                 items[i] = 0;
00260                         }
00261                 if (renameCommand)
00262                         delete renameCommand;
00263         }
00264 
00265         InsertHandlesCommand::InsertHandlesCommand(TextEditor * textEditor, const QList<ItemHandle*> & list, bool rename)
00266         {
00267                 QStringList s;
00268                 ItemHandle * h = 0;
00269                 for (int i=0; i < list.size(); ++i)
00270                         if (h = list[i])
00271                                 s << h->name;
00272                 setText(s.join(QObject::tr(",")) + QObject::tr(" added"));
00273                 this->textEditor = textEditor;
00274                 checkNames = rename;
00275                 network = 0;
00276                 if (textEditor)
00277                         network = textEditor->network;
00278                 items = list;
00279                 renameCommand = 0;
00280         }
00281 
00282         InsertHandlesCommand::InsertHandlesCommand(TextEditor * textEditor, ItemHandle * h, bool rename)
00283         {
00284                 checkNames = rename;
00285                 if (h)
00286                         setText(h->name + QObject::tr(" added"));
00287                 else
00288                         setText(QObject::tr("items added"));
00289                 this->textEditor = textEditor;
00290                 network = 0;
00291                 if (textEditor)
00292                         network = textEditor->network;
00293                 items << h;
00294                 renameCommand = 0;
00295         }
00296 
00297         void InsertHandlesCommand::redo()
00298         {
00299                 if (MainWindow::invalidPointers.contains(textEditor))
00300                 {
00301                         textEditor = 0;
00302                 }
00303 
00304                 if (textEditor && textEditor->network == network)
00305                 {
00306                         network->showTextEditor(textEditor);
00307                         QStringList oldNames, newNames, usedNames;
00308                         QList<ItemHandle*> nameChangeHandles = network->handles();
00309                         QString s0,s1;
00310                         bool isNum;
00311                         
00312                         QList<ItemHandle*>& list = textEditor->items();
00313                         
00314                         //while (parentHandles.size() < items.size()) parentHandles += 0;
00315                         
00316                         for (int i=0; i < items.size(); ++i)
00317                         {
00318                                 if (items[i] && !list.contains(items[i]))
00319                                 {
00320                                         s0 = items[i]->fullName();
00321                                         if (parentHandles.size() > i && !MainWindow::invalidPointers.contains(parentHandles[i]))
00322                                                 items[i]->setParent(parentHandles[i],false);
00323                                         else
00324                                                 if (textEditor->localHandle())
00325                                                 {
00326                                                         bool onlyThisWindow = true;
00327                                                         for (int j=0; j < items[i]->graphicsItems.size(); ++j)
00328                                                                 if (items[i]->graphicsItems[j])
00329                                                                 {
00330                                                                         onlyThisWindow = false;
00331                                                                         break;
00332                                                                 }
00333                                                         if (onlyThisWindow)
00334                                                                 items[i]->setParent(textEditor->localHandle(),false);
00335                                                 }
00336 
00337                                         items[i]->network = textEditor->network;
00338                                         list << items[i];
00339                                         if (!renameCommand && !nameChangeHandles.contains(items[i]))
00340                                         {
00341                                                 s1 = textEditor->network->makeUnique(items[i],usedNames);
00342                                                 usedNames << s1;
00343                                                 nameChangeHandles << items[i];
00344                                                 
00345                                                 if (s0 != s1)
00346                                                 {
00347                                                         oldNames << s0;
00348                                                         newNames << s1;
00349                                                 }
00350                                         }
00351                                 }
00352                         }
00353                         
00354                         if (!renameCommand && !newNames.isEmpty())
00355                         {
00356                                 QList<ItemHandle*> allHandles;
00357                                 for (int i=0; i < items.size(); ++i)
00358                                         if (items[i])
00359                                                 allHandles << items[i] << items[i]->allChildren();
00360                                         
00361                                 renameCommand = new RenameCommand(QString("rename"),textEditor->network,allHandles,oldNames,newNames);
00362                         }
00363                         
00364                         if (renameCommand && checkNames)
00365                                 renameCommand->redo();
00366                 }
00367         }
00368 
00369         void InsertHandlesCommand::undo()
00370         {
00371                 if (MainWindow::invalidPointers.contains(textEditor) && network)
00372                 {
00373                         textEditor = 0;
00374                 }
00375                 
00376                 if (textEditor)
00377                 {
00378                         //network->showTextEditor(textEditor);
00379 
00380                         QList<ItemHandle*>& list = textEditor->items();
00381                         for (int i=0; i < items.size(); ++i)
00382                                 if (items[i] && list.contains(items[i]))
00383                                 {
00384                                         items[i]->network = 0;
00385                                         list.removeAll(items[i]);
00386                                 }
00387                         
00388                         while (parentHandles.size() < items.size()) parentHandles += 0;
00389                         
00390                         for (int i=0; i < items.size(); ++i)
00391                                 if (items[i])
00392                                 {
00393                                         parentHandles[i] = items[i]->parent;
00394                                         items[i]->setParent(0,false);
00395                                 }
00396                         
00397                         if (renameCommand && checkNames)
00398                                 renameCommand->undo();
00399                 }
00400         }
00401 
00402         RemoveHandlesCommand::RemoveHandlesCommand(TextEditor * editor, const QList<ItemHandle*> & list, bool update) : changeDataCommand(0)
00403         {
00404                 QStringList s;
00405                 ItemHandle * h = 0;
00406                 updateData = update;
00407                 for (int i=0; i < list.size(); ++i)
00408                         if (h = list[i])
00409                                 s << h->name;
00410                 setText(s.join(QObject::tr(",")) + QObject::tr(" removed"));
00411                 textEditor = editor;
00412                 network = 0;
00413                 if (editor)
00414                         network = editor->network;
00415                 items = list;
00416         }
00417 
00418         RemoveHandlesCommand::RemoveHandlesCommand(TextEditor * editor, ItemHandle * h, bool update): changeDataCommand(0)
00419         {
00420                 if (h)
00421                         setText(h->name + QObject::tr(" removed"));
00422                 else
00423                         setText(QObject::tr("items removed"));
00424                 textEditor = editor;
00425                 network = 0;
00426                 updateData = update;
00427                 if (editor)
00428                         network = editor->network;
00429                 items << h;
00430         }
00431 
00432         void RemoveHandlesCommand::undo()
00433         {
00434                 if (MainWindow::invalidPointers.contains(textEditor) && network)
00435                 {
00436                         textEditor = 0;
00437                 }
00438                 
00439                 if (textEditor && textEditor->network == network)
00440                 {
00441                         network->showTextEditor(textEditor);
00442 
00443                         QList<ItemHandle*>& list = textEditor->items();
00444                         for (int i=0; i < items.size(); ++i)
00445                                 if (items[i] && !list.contains(items[i]))
00446                                 {
00447                                         if (parentHandles.size() > i && !MainWindow::invalidPointers.contains(parentHandles[i]))
00448                                         {
00449                                                 items[i]->setParent(parentHandles[i],false);
00450                                         }
00451                                         items[i]->network = textEditor->network;
00452                                         list << items[i];
00453                                 }
00454                         
00455                         if (changeDataCommand)
00456                                 changeDataCommand->redo();
00457                         
00458                 }
00459         }
00460 
00461         void RemoveHandlesCommand::redo()
00462         {
00463                 if (MainWindow::invalidPointers.contains(textEditor) && network)
00464                 {
00465                         textEditor = 0;
00466                 }
00467                 
00468                 if (textEditor)
00469                 {
00470                         //network->showTextEditor(textEditor);                          
00471                         QList<ItemHandle*>& list = textEditor->items();
00472                         
00473                         while (parentHandles.size() < items.size()) parentHandles += 0;
00474                         
00475                         for (int i=0; i < items.size(); ++i)
00476                                 if (items[i] && list.contains(items[i]))
00477                                 {
00478                                         parentHandles[i] = items[i]->parent;
00479                                         items[i]->setParent(0,false);
00480 
00481                                         items[i]->network = 0;
00482                                         list.removeAll(items[i]);
00483                                 }
00484                         
00485                         bool firstTime = (changeDataCommand == 0);
00486 
00487                         if (firstTime)
00488                         {
00489                                 QList< DataTable<qreal>* > oldData1, newData1;
00490                                 QList< DataTable<QString>* > oldData2, newData2;
00491 
00492                                 bool emptyHandle;
00493                                 QStringList namesToKill;
00494                                 for (int i=0; i < items.size(); ++i)
00495                                         if (items[i])
00496                                         {
00497                                                 emptyHandle = true;                             
00498                                                 for (int j=0; j < items[i]->graphicsItems.size(); ++j)
00499                                                         if (items[i]->graphicsItems[j] && 
00500                                                                 items[i]->graphicsItems[j]->scene() &&
00501                                                                 static_cast<GraphicsScene*>(items[i]->graphicsItems[j]->scene())->networkWindow->isVisible())
00502                                                         {
00503                                                                 emptyHandle = false;
00504                                                                 break;
00505                                                         }
00506                                                 if (emptyHandle)
00507                                                         namesToKill << items[i]->fullName();
00508                                         }
00509 
00510                                 QList<ItemHandle*> affectedHandles = textEditor->items();
00511 
00512                                 for (int i=0; i < affectedHandles.size(); ++i)
00513                                 if (!items.contains(affectedHandles[i]))
00514                                 {
00515                                         QList<QString> keys1 = affectedHandles[i]->numericalDataNames();
00516                                         QList<QString> keys2 = affectedHandles[i]->textDataNames();
00517 
00518                                         for (int j=0; j < keys1.size(); ++j)
00519                                                 oldData1 += new DataTable<qreal>(affectedHandles[i]->numericalDataTable( keys1[j] ));
00520 
00521                                         for (int j=0; j < keys2.size(); ++j)
00522                                                 oldData2 += new DataTable<QString>(affectedHandles[i]->textDataTable( keys2[j] ));
00523                                 }
00524 
00525                                 DataTable<qreal> * nDat = 0;
00526                                 DataTable<QString> * sDat = 0;
00527 
00528                                 for (int i=0; i < affectedHandles.size(); ++i) //change all the handle data
00529                                 if (!items.contains(affectedHandles[i]))
00530                                 {
00531                                         bool affected = false;
00532                                         for (int i2=0; i2 < namesToKill.size(); ++i2)
00533                                         {
00534                                                 QString oldname(namesToKill[i2]);
00535 
00536                                                 QRegExp regexp1(QString("^") + oldname + QString("$")),  //just old name
00537                                                         regexp2(QString("^") + oldname + QString("([^A-Za-z0-9_])")),  //oldname+(!letter/num)
00538                                                         regexp3(QString("([^A-Za-z0-9_.])") + oldname + QString("$")), //(!letter/num)+oldname
00539                                                         regexp4(QString("([^A-Za-z0-9_.])") + oldname + QString("([^A-Za-z0-9_])")); //(!letter/num)+oldname+(!letter/num)
00540 
00541                                                 QList< QString > keys = affectedHandles[i]->numericalDataNames();
00542                                                 for (int j=0; j < keys.size(); ++j)  //go through each numeric data
00543                                                 {
00544                                                         affected = false;
00545                                                         nDat = &(affectedHandles[i]->numericalDataTable( keys[j] ));
00546                                                         for (int k=0; k < nDat->rows(); ++k)
00547                                                         {
00548                                                                 if (nDat->rowName(k).contains(regexp1) || nDat->rowName(k).contains(regexp2) ||
00549                                                                         nDat->rowName(k).contains(regexp3) || nDat->rowName(k).contains(regexp4))
00550                                                                 {
00551                                                                         nDat->removeRow(k);
00552                                                                         --k;
00553                                                                         affected = true;
00554                                                                 }
00555                                                         }
00556                                                         for (int k=0; k < nDat->columns(); ++k)
00557                                                         {
00558                                                                 if (nDat->columnName(k).contains(regexp1) || nDat->columnName(k).contains(regexp2) ||
00559                                                                         nDat->columnName(k).contains(regexp3) || nDat->columnName(k).contains(regexp4))
00560                                                                 {
00561                                                                         nDat->removeColumn(k);
00562                                                                         --k;
00563                                                                         affected = true;
00564                                                                 }
00565                                                         }
00566                                                 }
00567 
00568                                                 keys = affectedHandles[i]->textDataNames();
00569 
00570                                                 for (int j=0; j < keys.size(); ++j)  //go through each text data
00571                                                 {
00572                                                         affected = false;
00573                                                         sDat = &(affectedHandles[i]->textDataTable( keys[j] ));
00574                                                         for (int k=0; k < sDat->rows(); ++k)
00575                                                         {
00576                                                                 if (sDat->rowName(k).contains(regexp1) || sDat->rowName(k).contains(regexp2) ||
00577                                                                         sDat->rowName(k).contains(regexp3) || sDat->rowName(k).contains(regexp4))
00578                                                                 {
00579                                                                         sDat->removeRow(k);
00580                                                                         --k;
00581                                                                         affected = true;
00582                                                                 }
00583                                                         }
00584                                                         for (int k=0; k < sDat->columns(); ++k)
00585                                                         {
00586                                                                 if (sDat->columnName(k).contains(regexp1) || sDat->columnName(k).contains(regexp2) ||
00587                                                                         sDat->columnName(k).contains(regexp3) || sDat->columnName(k).contains(regexp4))
00588                                                                 {
00589                                                                         sDat->removeColumn(k);
00590                                                                         --k;
00591                                                                         affected = true;
00592                                                                 }
00593                                                         }
00594 
00595                                                         QString newname("1.0");
00596                                                         for (int k=0; k < sDat->rows(); ++k) //substitute each value in the table
00597                                                                 for (int l=0; l < sDat->columns(); ++l)
00598                                                                 {
00599                                                                         QString & target = sDat->value(k,l);// = QString("0");
00600 
00601                                                                         int n = regexp1.indexIn(target);
00602                                                                         if (n != -1)
00603                                                                         {
00604                                                                                 target = newname;
00605                                                                                 //target.replace(oldname,newname);
00606                                                                                 //n = regexp1.indexIn(target);
00607                                                                                 affected = true;
00608                                                                         }
00609                                                                         n = regexp2.indexIn(target);
00610                                                                         if (n != -1)
00611                                                                         {
00612                                                                                 target = newname;
00613                                                                                 //target.replace(regexp2,newname+QString("\\1"));
00614                                                                                 //n = regexp2.indexIn(target);
00615                                                                                 affected = true;
00616                                                                         }
00617                                                                         n = regexp3.indexIn(target);
00618                                                                         if (n != -1)
00619                                                                         {
00620                                                                                 target = newname;
00621                                                                                 //target.replace(regexp3,QString("\\1")+newname);
00622                                                                                 //n = regexp3.indexIn(target);
00623                                                                                 affected = true;
00624                                                                         }
00625                                                                         n = regexp4.indexIn(target);
00626                                                                         if (n != -1)
00627                                                                         {
00628                                                                                 target = newname;
00629                                                                                 //n = regexp4.indexIn(target);
00630                                                                                 affected = true;
00631                                                                         }
00632                                                                 }
00633                                                 }
00634                                         }
00635                                 }
00636                                 for (int i=0; i < affectedHandles.size(); ++i)
00637                                 if (!items.contains(affectedHandles[i]))
00638                                 {
00639                                         QList<QString> keys1 = affectedHandles[i]->numericalDataNames();
00640                                         QList<QString> keys2 = affectedHandles[i]->textDataNames();
00641 
00642                                         for (int j=0; j < keys1.size(); ++j)
00643                                                 newData1 += &(affectedHandles[i]->numericalDataTable( keys1[j] ));
00644 
00645                                         for (int j=0; j < keys2.size(); ++j)
00646                                                 newData2 += &(affectedHandles[i]->textDataTable( keys2[j] ));
00647                                 }
00648                                 changeDataCommand = new Change2DataCommand<qreal,QString>(QString(""), newData1, oldData1, newData2, oldData2);
00649                                 for (int i=0; i < oldData1.size(); ++i)
00650                                         if (oldData1[i])
00651                                                 delete oldData1[i];
00652                                 for (int i=0; i < oldData2.size(); ++i)
00653                                         if (oldData2[i])
00654                                                 delete oldData2[i];
00655                         }
00656                         else
00657                         {
00658                                 if (changeDataCommand)
00659                                         changeDataCommand->undo();
00660                         }
00661                         
00662                 }
00663         }
00664 
00665         InsertGraphicsCommand::InsertGraphicsCommand(const QString& name, GraphicsScene * scene, QGraphicsItem * item, bool checkNames)
00666                 : QUndoCommand(name), checkNames(checkNames)
00667         {
00668                 graphicsScene = scene;
00669                 network = 0;
00670                 if (scene)
00671                         network = scene->network;
00672                 graphicsItems.clear();
00673                 
00674                 item = getGraphicsItem(item);
00675                 if (!NodeGraphicsItem::cast(item) &&
00676                         !TextGraphicsItem::cast(item) &&
00677                         !ConnectionGraphicsItem::cast(item))
00678                         item = 0;
00679 
00680                 ConnectionGraphicsItem * connection = ConnectionGraphicsItem::cast(item);
00681                 if (connection)
00682                 {
00683                         QList<NodeGraphicsItem*> nodes = connection->nodes();
00684                         for (int i=0; i < nodes.size(); ++i)
00685                                 if (nodes[i] && !(nodes[i]->scene() == scene))
00686                                 {
00687                                         graphicsItems += nodes[i];
00688                                         parentGraphicsItems += NodeGraphicsItem::cast(nodes[i]->parentItem());
00689                                         handles += getHandle(nodes[i]);
00690                                 }
00691                         
00692                         QList<ArrowHeadItem*> arrows = connection->arrowHeads();
00693                         for (int i=0; i < arrows.size(); ++i)
00694                                 if (arrows[i] && !(arrows[i]->scene() == scene))
00695                                 {
00696                                         graphicsItems += arrows[i];
00697                                         parentGraphicsItems += NodeGraphicsItem::cast(arrows[i]->parentItem());
00698                                         handles += getHandle(arrows[i]);
00699                                 }
00700                 }
00701                 
00702                 if (item)
00703                 {
00704                         graphicsItems += item;
00705                         handles.clear();
00706                         handles += getHandle(item);
00707                 }
00708                 renameCommand = 0;
00709         }
00710 
00711         InsertGraphicsCommand::InsertGraphicsCommand(const QString& name, GraphicsScene * scene, const QList<QGraphicsItem*>& items, bool checkNames)
00712                 : QUndoCommand(name), checkNames(checkNames)
00713         {
00714                 graphicsScene = scene;
00715                 network = 0;
00716                 if (scene)
00717                         network = scene->network;
00718                 handles.clear();
00719                 QGraphicsItem * item;
00720                 ConnectionGraphicsItem * connection;
00721                 for (int i=0; i < items.size(); ++i)
00722                         if ((item = getGraphicsItem(items[i])) && !graphicsItems.contains(item) &&
00723                                         (NodeGraphicsItem::cast(items[i]) || TextGraphicsItem::cast(items[i]) || ConnectionGraphicsItem::cast(items[i])))
00724                         {
00725                                 connection = ConnectionGraphicsItem::cast(item);
00726                                 if (connection)
00727                                 {
00728                                         QList<NodeGraphicsItem*> nodes = connection->nodes();
00729                                         for (int j=0; j < nodes.size(); ++j)
00730                                                 if (nodes[j] && !(nodes[j]->scene() == scene || items.contains(nodes[j])))
00731                                                 {
00732                                                         graphicsItems += nodes[j];
00733                                                         parentGraphicsItems += NodeGraphicsItem::cast(nodes[j]->parentItem());
00734                                                         handles += getHandle(nodes[j]);
00735                                                 }
00736                                                 
00737                                         QList<ArrowHeadItem*> arrows = connection->arrowHeads();
00738                                         for (int j=0; j < arrows.size(); ++j)
00739                                                 if (arrows[j] && !(items.contains(arrows[j]) || arrows[j]->scene() == scene))
00740                                                 {
00741                                                         graphicsItems += arrows[j];
00742                                                         parentGraphicsItems += NodeGraphicsItem::cast(arrows[j]->parentItem()); 
00743                                                         handles += getHandle(arrows[j]);
00744                                                 }
00745                                 }
00746                                 graphicsItems += item;
00747                                 parentGraphicsItems += NodeGraphicsItem::cast(item->parentItem());      
00748                                 handles += getHandle(item);
00749                         }
00750                 
00751                 renameCommand = 0;
00752         }
00753 
00754         void InsertGraphicsCommand::redo()
00755         {
00756                 QList<ConnectionGraphicsItem*> connections;
00757                 ConnectionGraphicsItem * connection;
00758                 bool isNum;
00759                 
00760                 if (MainWindow::invalidPointers.contains(graphicsScene))
00761                 {
00762                         graphicsScene = 0;
00763                 }
00764                 
00765                 if (graphicsScene && graphicsScene->network == network)
00766                 {
00767                         //network->showScene(graphicsScene);
00768                         QStringList newNames, oldNames, usedNames;
00769                         QList<ItemHandle*> nameChangeHandles = network->handles();
00770                         QString s0,s1;
00771                         
00772                         for (int i=0; i<graphicsItems.size(); ++i)
00773                         {
00774                                 if (graphicsItems[i] && graphicsItems[i]->scene() != graphicsScene)
00775                                 {
00776                                         if (graphicsItems[i]->scene())
00777                                                 graphicsItems[i]->scene()->removeItem(graphicsItems[i]);
00778                                         graphicsScene->addItem(graphicsItems[i]);
00779                                         if ((connection = ConnectionGraphicsItem::cast(graphicsItems[i])))
00780                                         {
00781                                                 connections << connection;
00782                                         }
00783 
00784                                         if (parentGraphicsItems.size() > i &&
00785                                                 parentGraphicsItems[i] &&
00786                                                 NodeGraphicsItem::cast(parentGraphicsItems[i]) &&
00787                                                 parentGraphicsItems[i]->scene() == graphicsScene)
00788                                                 graphicsItems[i]->setParentItem(parentGraphicsItems[i]);
00789                                                 
00790                                         if (handles.size() > i)
00791                                         {
00792                                                 setHandle(graphicsItems[i],handles[i]);
00793                                                 if (handles[i])
00794                                                 {
00795                                                         s0 = handles[i]->fullName();
00796 
00797                                                         if (parentHandles.size() > i && !MainWindow::invalidPointers.contains(parentHandles[i]))
00798                                                                 handles[i]->setParent(parentHandles[i],false);
00799                                                         else
00800                                                                 if (graphicsScene->localHandle())
00801                                                                 {
00802                                                                         bool onlyThisScene = true;
00803                                                                         for (int j=0; j < handles[i]->graphicsItems.size(); ++j)
00804                                                                                 if (handles[i]->graphicsItems[j] && 
00805                                                                                         !graphicsItems.contains(handles[i]->graphicsItems[j]) &&
00806                                                                                          handles[i]->graphicsItems[j]->scene() != graphicsScene)
00807                                                                                 {
00808                                                                                         onlyThisScene = false;
00809                                                                                 }
00810                                                                         if (onlyThisScene)
00811                                                                                 handles[i]->setParent(graphicsScene->localHandle(),false);
00812                                                                 }
00813                                                         
00814                                                         handles[i]->network = network;
00815                                                         
00816                                                         if (!renameCommand && !nameChangeHandles.contains(handles[i]))
00817                                                         {
00818                                                                 s1 = graphicsScene->network->makeUnique(handles[i],usedNames);
00819                                                                 usedNames << s1;
00820                                                                 nameChangeHandles << handles[i];
00821                                                                 
00822                                                                 if (s0 != s1)
00823                                                                 {
00824                                                                         oldNames << s0;
00825                                                                         newNames << s1;
00826                                                                 }
00827                                                         }
00828                                                 }
00829                                         }
00830                                 }
00831                         }
00832                         
00833                         if (!renameCommand && !newNames.isEmpty())
00834                         {
00835                                 QList<ItemHandle*> allHandles;
00836                                 for (int i=0; i < handles.size(); ++i)
00837                                         if (handles[i])
00838                                                 allHandles << handles[i] << handles[i]->allChildren();
00839                                         
00840                                 renameCommand = new RenameCommand(QString("rename"),graphicsScene->network,allHandles,oldNames,newNames,false);
00841                         }
00842                         
00843                         if (renameCommand && checkNames)
00844                                 renameCommand->redo();
00845                 }
00846 
00847                 for (int i=0; i < connections.size(); ++i)
00848                 {
00849                         connection = connections[i];
00850                         QList<QGraphicsItem*> arrows = connection->arrowHeadsAsGraphicsItems();
00851                         for (int j=0; j < arrows.size(); ++j)
00852                                 if (arrows[j] && arrows[j]->scene() != graphicsScene)
00853                                 {
00854                                         if (arrows[j]->scene())
00855                                                 arrows[j]->scene()->removeItem(arrows[j]);
00856                                         graphicsScene->addItem(arrows[j]);
00857                                 }
00858                         connection->refresh();
00859                         connection->setControlPointsVisible(false);
00860                 }
00861         }
00862 
00863         void InsertGraphicsCommand::undo()
00864         {
00865                 if (MainWindow::invalidPointers.contains(graphicsScene) && network)
00866                 {
00867                         graphicsScene = 0;
00868                 }
00869                 
00870                 ConnectionGraphicsItem * connection = 0;
00871                 if (graphicsScene && graphicsScene->network == network)
00872                 {
00873                         //network->showScene(graphicsScene);
00874                         bool emptyHandle;
00875                         for (int i=0; i<graphicsItems.size(); ++i)
00876                         {
00877                                 if (graphicsItems[i] && graphicsItems[i]->scene() == graphicsScene)
00878                                 {
00879                                         while (parentGraphicsItems.size() <= i) parentGraphicsItems << 0;
00880                                         while (handles.size() <= i) handles << 0;
00881                                         
00882                                         parentGraphicsItems[i] = NodeGraphicsItem::cast(graphicsItems[i]->parentItem());
00883 
00884                                         if (handles[i] != getHandle(graphicsItems[i]))
00885                                         {
00886                                                 if (handles[i])
00887                                                         handles << handles[i];
00888                                                 handles[i] = getHandle(graphicsItems[i]);
00889                                         }
00890 
00891                                         graphicsItems[i]->setParentItem(0);
00892                                         graphicsScene->removeItem(graphicsItems[i]);
00893 
00894                                         if ((connection = ConnectionGraphicsItem::cast(graphicsItems[i])))
00895                                         {
00896                                                 QList<QGraphicsItem*> arrows = connection->arrowHeadsAsGraphicsItems();
00897                                                 for (int j=0; j < arrows.size(); ++j)
00898                                                         if (arrows[j] && arrows[j]->scene())
00899                                                                 arrows[j]->scene()->removeItem(arrows[j]);
00900                                         }
00901                                         
00902                                         if (handles[i] && !handles[i]->parent)
00903                                         {
00904                                                 setHandle(graphicsItems[i],0);
00905                                                 emptyHandle = true;                             
00906                                                 for (int j=0; j < handles[i]->graphicsItems.size(); ++j)
00907                                                         if (handles[i]->graphicsItems[j] && 
00908                                                                 handles[i]->graphicsItems[j]->scene() &&
00909                                                                 static_cast<GraphicsScene*>(handles[i]->graphicsItems[j]->scene())->networkWindow->isVisible())
00910                                                         {
00911                                                                 emptyHandle = false;
00912                                                                 break;
00913                                                         }
00914                                                 if (emptyHandle)
00915                                                         handles[i]->network = 0;
00916                                         }
00917                                 }
00918                         }
00919                         
00920                         while (parentHandles.size() < handles.size()) parentHandles += 0;
00921                         
00922                         for (int i=0; i < handles.size(); ++i)
00923                                 if (handles[i])
00924                                 {
00925                                         parentHandles[i] = handles[i]->parent;
00926                                         emptyHandle = true;                             
00927                                                 for (int j=0; j < handles[i]->graphicsItems.size(); ++j)
00928                                                         if (handles[i]->graphicsItems[j] && 
00929                                                                 handles[i]->graphicsItems[j]->scene() &&
00930                                                                 static_cast<GraphicsScene*>(handles[i]->graphicsItems[j]->scene())->networkWindow->isVisible())
00931                                                         {
00932                                                                 emptyHandle = false;
00933                                                                 break;
00934                                                         }
00935                                         if (emptyHandle)
00936                                                 handles[i]->setParent(0,false);
00937                                 }
00938                         
00939                         if (renameCommand && checkNames)
00940                                 renameCommand->undo();
00941                 }
00942         }
00943         
00944         InsertGraphicsCommand::~InsertGraphicsCommand()
00945         {
00946                 ItemHandle * handle = 0;
00947                 
00948                 QList<QGraphicsItem*> list;
00949                 for (int i=0; i < graphicsItems.size(); ++i)
00950                         if (!MainWindow::invalidPointers.contains((void*)graphicsItems[i]) &&
00951                                 (       NodeGraphicsItem::cast(graphicsItems[i]) || 
00952                                         TextGraphicsItem::cast(graphicsItems[i]) || 
00953                                         ConnectionGraphicsItem::cast(graphicsItems[i])))
00954                                 list << graphicsItems[i];
00955 
00956                 graphicsItems.clear();
00957 
00958                 for (int i=0; i < list.size(); ++i)
00959                 {
00960                         if (list[i] && !MainWindow::invalidPointers.contains((void*)list[i]))
00961                         {
00962                                 if ((handle = getHandle(list[i])) &&
00963                                         !handles.contains(handle))
00964                                 {
00965                                         handles += handle;
00966                                         list[i] = 0;
00967                                 }
00968                         }
00969                 }
00970                 
00971                 for (int i=0; i < handles.size(); ++i)
00972                 {
00973                         if (!MainWindow::invalidPointers.contains( (void*)handles[i]) && 
00974                                 handles[i] &&
00975                                 !handles[i]->parent && 
00976                                 handles[i]->graphicsItems.isEmpty())
00977                         {
00978                             MainWindow::invalidPointers[ (void*) handles[i] ] = true;
00979                             delete handles[i];
00980                         }
00981                 }
00982                 handles.clear();
00983 
00984         ConnectionGraphicsItem * connection;
00985         NodeGraphicsItem * node;
00986 
00987                 for (int i=0; i < list.size(); ++i)
00988                 {
00989                         if (list[i] && !MainWindow::invalidPointers.contains((void*)list[i]))
00990                         {
00991                             if (list[i]->parentItem())
00992                                         list[i]->setParentItem(0);
00993 
00994                                 if (list[i]->scene())
00995                                         list[i]->scene()->removeItem(list[i]);
00996                                 
00997                                 MainWindow::invalidPointers[ (void*) list[i] ] = true;
00998                                 
00999                                 QList<QGraphicsItem *> childItems = list[i]->childItems();
01000                                 for (int j=0; j < childItems.size(); ++j)
01001                                         if (childItems[j])
01002                                                 childItems[j]->setParentItem(0);
01003                                 delete list[i];
01004                         }
01005                 }
01006                 
01007                 if (renameCommand)
01008                         delete renameCommand;
01009         }
01010 
01011         RemoveGraphicsCommand::RemoveGraphicsCommand(const QString& name, QGraphicsItem * item, bool update)
01012                 : QUndoCommand(name), changeDataCommand(0), updateData(update)
01013         {
01014                 item = getGraphicsItem(item);
01015                 graphicsItems.append( item );
01016                 
01017                 if (item)
01018                         itemParents.append(item->parentItem());
01019                 else
01020                         itemParents.append(0);
01021         }
01022 
01023         RemoveGraphicsCommand::RemoveGraphicsCommand(const QString& name, const QList<QGraphicsItem*>& items, bool update)
01024                 : QUndoCommand(name), changeDataCommand(0), updateData(update)
01025         {
01026                 QGraphicsItem * item;
01027                 NodeGraphicsItem * node;
01028                 
01029                 for (int i=0; i < items.size(); ++i)
01030                         if ( (item = getGraphicsItem(items[i]) ) )
01031                         {
01032                                 graphicsItems.append(item);
01033                                 itemParents.append(item->parentItem());
01034                         }
01035         }
01036 
01037         void RemoveGraphicsCommand::redo()
01038         {
01039                 graphicsScenes.clear();
01040                 itemHandles.clear();
01041                 NodeGraphicsItem * node;
01042                 GraphicsScene * scene;
01043                 ItemHandle * h;
01044                 
01045                 ConnectionGraphicsItem * connection;
01046                 for (int i=0; i < graphicsItems.size(); ++i)
01047                         if (connection = ConnectionGraphicsItem::cast(graphicsItems[i]))
01048                         {
01049                                 for (int j=0; j < connection->curveSegments.size(); ++j)
01050                                 {
01051                                         if (connection->curveSegments[j].arrowStart && !graphicsItems.contains(connection->curveSegments[j].arrowStart))
01052                                                 graphicsItems += (connection->curveSegments[j].arrowStart);
01053                                         if (connection->curveSegments[j].arrowEnd && !graphicsItems.contains(connection->curveSegments[j].arrowStart))
01054                                                 graphicsItems += (connection->curveSegments[j].arrowEnd);
01055                                 }
01056                                 if (connection->centerRegionItem && !graphicsItems.contains(connection->centerRegionItem))
01057                                         graphicsItems += connection->centerRegionItem;
01058                         }
01059                 
01060                 for (int i=0; i<graphicsItems.size(); ++i)
01061                 {
01062                         scene = 0;
01063                         if (graphicsItems[i])           
01064                                 scene = static_cast<GraphicsScene*>(graphicsItems[i]->scene());
01065 
01066                         graphicsScenes += scene;
01067                         
01068                         h = getHandle(graphicsItems[i]);
01069                         
01070                         /*if (scene && scene->network && h)
01071                         {
01072                                 QList<GraphicsScene*> otherScenes = scene->network->scenes();
01073                                 for (int j=0; j < otherScenes.size(); ++j)
01074                                 {
01075                                         if (otherScenes[j] != scene && otherScenes[j]->localHandle() == h)
01076                                         {
01077                                                 QList<QGraphicsItem*> items = otherScenes[j]->items();
01078                                                 QList<QGraphicsItem*> gitems;
01079                                                 QGraphicsItem * item;
01080                                                 for (int k=0; k < items.size(); ++k)
01081                                                 {
01082                                                         item = getGraphicsItem(items[k]);
01083                                                         if (!gitems.contains(item))
01084                                                                 gitems << item;
01085                                                 }
01086                                                 graphicsItems << gitems;
01087                                         }
01088                                 }
01089                         }*/
01090 
01091                         itemHandles += h;
01092                         node = NodeGraphicsItem::cast(graphicsItems[i]);
01093                         if (node)
01094                         {
01095                                 QList<ConnectionGraphicsItem*> connections = node->connections();
01096                                 for (int j=0; j < connections.size(); ++j)
01097                                         if (connections[j] && 
01098                                                 connections[j]->scene() == node->scene() && 
01099                                                 !graphicsItems.contains(connections[j]))
01100                                         {
01101                                                 graphicsItems += connections[j];
01102                                                 itemParents.append(connections[j]->parentItem());
01103                                         }
01104                         }
01105                 }
01106 
01107                 bool emptyHandle;
01108 
01109                 for (int i=0; i<graphicsItems.size(); ++i)
01110                 {
01111                         if (graphicsItems[i] && graphicsScenes[i])
01112                         {
01113                                 if (graphicsItems[i]->scene() == graphicsScenes[i])
01114                                         graphicsScenes[i]->removeItem(graphicsItems[i]);
01115 
01116                                 NodeGraphicsItem * node = NodeGraphicsItem::cast(graphicsItems[i]);
01117                                 if (node)
01118                                 {
01119                                         node->setBoundingBoxVisible(false);
01120                                 }
01121                                 else
01122                                 {
01123                                         connection = ConnectionGraphicsItem::cast(graphicsItems[i]);
01124                                         if (connection)
01125                                         {
01126                                                 connection->setControlPointsVisible(false);
01127                                                 /*QList<ConnectionGraphicsItem::ControlPoint*> cps = connection->controlPoints(true);
01128                                                 for (int j=0; j < cps.size(); ++j)
01129                                                         if (cps[j])
01130                                                                 cps[j]->connectionItem = 0;*/
01131                                         }
01132                                 }
01133                         }
01134 
01135                         setHandle(graphicsItems[i],0);
01136                 }
01137 
01138                 bool firstTime = (changeDataCommand == 0);
01139 
01140                 if (firstTime)
01141                 {
01142                         QList< DataTable<qreal>* > oldData1, newData1;
01143                         QList< DataTable<QString>* > oldData2, newData2;
01144                         QList<ItemHandle*> visited;
01145 
01146                         bool exists = false;
01147                         QStringList namesToKill;
01148                         for (int i=0; i < itemHandles.size(); ++i)
01149                                 if (itemHandles[i] && !visited.contains(itemHandles[i]))
01150                                 {
01151                                         visited << itemHandles[i];
01152                                         exists = false;
01153                                         for (int j=0; j < itemHandles[i]->graphicsItems.size(); ++j)
01154                                                 if (itemHandles[i]->graphicsItems[j] && 
01155                                                         itemHandles[i]->graphicsItems[j]->scene() &&
01156                                                         static_cast<GraphicsScene*>(itemHandles[i]->graphicsItems[j]->scene())->networkWindow->isVisible())
01157                                                 {
01158                                                         h = (static_cast<GraphicsScene*>(itemHandles[i]->graphicsItems[j]->scene()))->localHandle();
01159                                                         if (!h || !itemHandles.contains(h))
01160                                                         {
01161                                                                 exists = true;
01162                                                                 break;
01163                                                         }
01164                                                 }
01165                                         if (!exists)
01166                                                 namesToKill << itemHandles[i]->fullName();
01167                                 }
01168 
01169                         QList<NetworkHandle*> networkHandles;
01170                         for (int i=0; i < graphicsScenes.size(); ++i)
01171                                 if (graphicsScenes[i] && graphicsScenes[i]->network && !networkHandles.contains(graphicsScenes[i]->network))
01172                                 {
01173                                         networkHandles += graphicsScenes[i]->network;
01174                                         affectedHandles += graphicsScenes[i]->network->handles();
01175                                 }
01176 
01177                         for (int i=0; i < affectedHandles.size(); ++i)
01178                                 if (!visited.contains(affectedHandles[i]))
01179                                 {
01180                                         QList<QString> keys1 = affectedHandles[i]->numericalDataNames();
01181                                         QList<QString> keys2 = affectedHandles[i]->textDataNames();
01182 
01183                                         for (int j=0; j < keys1.size(); ++j)
01184                                                 oldData1 += new DataTable<qreal>(affectedHandles[i]->numericalDataTable( keys1[j] ));
01185 
01186                                         for (int j=0; j < keys2.size(); ++j)
01187                                                 oldData2 += new DataTable<QString>(affectedHandles[i]->textDataTable( keys2[j] ));
01188                                 }
01189 
01190                         DataTable<qreal> * nDat = 0;
01191                         DataTable<QString> * sDat = 0;
01192 
01193                         for (int i=0; i < affectedHandles.size(); ++i) //change all the handle data
01194                         if (!visited.contains(affectedHandles[i]))
01195                         {
01196                                 bool affected = false;
01197                                 for (int i2=0; i2 < namesToKill.size(); ++i2)
01198                                 {
01199                                         QString oldname(namesToKill[i2]);
01200 
01201                                         QRegExp regexp1(QString("^") + oldname + QString("$")),  //just old name
01202                                                 regexp2(QString("^") + oldname + QString("([^A-Za-z0-9_])")),  //oldname+(!letter/num)
01203                                                 regexp3(QString("([^A-Za-z0-9_.])") + oldname + QString("$")), //(!letter/num)+oldname
01204                                                 regexp4(QString("([^A-Za-z0-9_.])") + oldname + QString("([^A-Za-z0-9_])")); //(!letter/num)+oldname+(!letter/num)
01205 
01206                                         QList< QString > keys = affectedHandles[i]->numericalDataNames();
01207                                         for (int j=0; j < keys.size(); ++j)  //go through each numeric data
01208                                         {
01209                                                 affected = false;
01210                                                 nDat = &(affectedHandles[i]->numericalDataTable( keys[j] ));
01211                                                 for (int k=0; k < nDat->rows(); ++k)
01212                                                 {
01213                                                         if (nDat->rowName(k).contains(regexp1) || nDat->rowName(k).contains(regexp2) ||
01214                                                                 nDat->rowName(k).contains(regexp3) || nDat->rowName(k).contains(regexp4))
01215                                                         {
01216                                                                 nDat->removeRow(k);
01217                                                                 --k;
01218                                                                 affected = true;
01219                                                         }
01220                                                 }
01221                                                 for (int k=0; k < nDat->columns(); ++k)
01222                                                 {
01223                                                         if (nDat->columnName(k).contains(regexp1) || nDat->columnName(k).contains(regexp2) ||
01224                                                                 nDat->columnName(k).contains(regexp3) || nDat->columnName(k).contains(regexp4))
01225                                                         {
01226                                                                 nDat->removeColumn(k);
01227                                                                 --k;
01228                                                                 affected = true;
01229                                                         }
01230                                                 }
01231                                         }
01232 
01233                                         keys = affectedHandles[i]->textDataNames();
01234 
01235                                         for (int j=0; j < keys.size(); ++j)  //go through each text data
01236                                         {
01237                                                 affected = false;
01238                                                 sDat = &(affectedHandles[i]->textDataTable( keys[j] ));
01239                                                 for (int k=0; k < sDat->rows(); ++k)
01240                                                 {
01241                                                         if (sDat->rowName(k).contains(regexp1) || sDat->rowName(k).contains(regexp2) ||
01242                                                                 sDat->rowName(k).contains(regexp3) || sDat->rowName(k).contains(regexp4))
01243                                                         {
01244                                                                 sDat->removeRow(k);
01245                                                                 --k;
01246                                                                 affected = true;
01247                                                         }
01248                                                 }
01249                                                 for (int k=0; k < sDat->columns(); ++k)
01250                                                 {
01251                                                         if (sDat->columnName(k).contains(regexp1) || sDat->columnName(k).contains(regexp2) ||
01252                                                                 sDat->columnName(k).contains(regexp3) || sDat->columnName(k).contains(regexp4))
01253                                                         {
01254                                                                 sDat->removeColumn(k);
01255                                                                 --k;
01256                                                                 affected = true;
01257                                                         }
01258                                                 }
01259 
01260                                                 QString newname("1.0");
01261                                                 for (int k=0; k < sDat->rows(); ++k) //substitute each value in the table
01262                                                         for (int l=0; l < sDat->columns(); ++l)
01263                                                         {
01264                                                                 QString & target = sDat->value(k,l);// = QString("0");
01265 
01266                                                                 int n = regexp1.indexIn(target);
01267                                                                 if (n != -1)
01268                                                                 {
01269                                                                         target = newname;
01270                                                                         //target.replace(oldname,newname);
01271                                                                         //n = regexp1.indexIn(target);
01272                                                                         affected = true;
01273                                                                 }
01274                                                                 n = regexp2.indexIn(target);
01275                                                                 if (n != -1)
01276                                                                 {
01277                                                                         target = newname;
01278                                                                         //target.replace(regexp2,newname+QString("\\1"));
01279                                                                         //n = regexp2.indexIn(target);
01280                                                                         affected = true;
01281                                                                 }
01282                                                                 n = regexp3.indexIn(target);
01283                                                                 if (n != -1)
01284                                                                 {
01285                                                                         target = newname;
01286                                                                         //target.replace(regexp3,QString("\\1")+newname);
01287                                                                         //n = regexp3.indexIn(target);
01288                                                                         affected = true;
01289                                                                 }
01290                                                                 n = regexp4.indexIn(target);
01291                                                                 if (n != -1)
01292                                                                 {
01293                                                                         target = newname;
01294                                                                         //n = regexp4.indexIn(target);
01295                                                                         affected = true;
01296                                                                 }
01297                                                         }
01298                                         }
01299                                 }
01300                         }
01301 
01302                         for (int i=0; i < affectedHandles.size(); ++i)
01303                         if (!visited.contains(affectedHandles[i]))
01304                         {
01305                                 QList<QString> keys1 = affectedHandles[i]->numericalDataNames();
01306                                 QList<QString> keys2 = affectedHandles[i]->textDataNames();
01307 
01308                                 for (int j=0; j < keys1.size(); ++j)
01309                                         newData1 += &(affectedHandles[i]->numericalDataTable( keys1[j] ));
01310 
01311                                 for (int j=0; j < keys2.size(); ++j)
01312                                         newData2 += &(affectedHandles[i]->textDataTable( keys2[j] ));
01313                         }
01314                         changeDataCommand = new Change2DataCommand<qreal,QString>(QString(""), newData1, oldData1, newData2, oldData2);
01315                         for (int i=0; i < oldData1.size(); ++i)
01316                                 if (oldData1[i])
01317                                         delete oldData1[i];
01318                         for (int i=0; i < oldData2.size(); ++i)
01319                                 if (oldData2[i])
01320                                         delete oldData2[i];
01321                 }
01322                 else
01323                 {
01324                         if (changeDataCommand)
01325                                 changeDataCommand->undo();
01326                 }
01327 
01328                 while (parentHandles.size() < itemHandles.size()) parentHandles += 0;
01329                 
01330                 for (int i=0; i < itemHandles.size(); ++i)
01331                         if (itemHandles[i] && (itemHandles.indexOf(itemHandles[i]) == i))
01332                         {
01333                                 parentHandles[i] = itemHandles[i]->parent;
01334                                 emptyHandle = true;                             
01335                                 for (int j=0; j < itemHandles[i]->graphicsItems.size(); ++j)
01336                                         if (itemHandles[i]->graphicsItems[j] && 
01337                                                 itemHandles[i]->graphicsItems[j]->scene() &&
01338                                                 static_cast<GraphicsScene*>(itemHandles[i]->graphicsItems[j]->scene())->networkWindow->isVisible())
01339                                         {
01340                                                 emptyHandle = false;
01341                                                 break;
01342                                         }
01343                                 if (emptyHandle)
01344                                 {
01345                                         itemHandles[i]->network = 0;
01346                                         for (int j=0; j < itemHandles[i]->children.size(); ++j)
01347                                                 if (itemHandles[i]->children[j])
01348                                                         itemHandles[i]->children[j]->parent = 0;
01349                                         itemHandles[i]->setParent(0,false);
01350                                 }
01351                         }
01352         }
01353 
01354         void RemoveGraphicsCommand::undo()
01355         {
01356                 QList<ConnectionGraphicsItem*> connections;
01357                 ConnectionGraphicsItem * connection;
01358 
01359                 for (int i=0; i<graphicsItems.size() && i<graphicsScenes.size(); ++i)
01360                         if (graphicsItems[i] && graphicsScenes[i])
01361                         {
01362                                 if (graphicsItems[i]->scene() != graphicsScenes[i])
01363                                         graphicsScenes[i]->addItem(graphicsItems[i]);
01364 
01365                                 NodeGraphicsItem * node = NodeGraphicsItem::cast(graphicsItems[i]);
01366                                 if (node)
01367                                 {
01368                                         node->setBoundingBoxVisible(false);
01369                                 }
01370                                 else
01371                                 {
01372                                         connection = ConnectionGraphicsItem::cast(graphicsItems[i]);
01373                                         if (connection)
01374                                         {
01375                                                 connections << connection;
01376                                         }
01377                                 }
01378 
01379                                 if (itemHandles.size() > i && itemHandles[i])
01380                                 {
01381                                         if (parentHandles.size() > i && 
01382                                                 (itemHandles.indexOf(itemHandles[i]) == i) &&
01383                                                 !MainWindow::invalidPointers.contains(itemHandles[i]) && 
01384                                                 !itemHandles[i]->parent)
01385                                                 itemHandles[i]->setParent(parentHandles[i],false);
01386                                 
01387                                         itemHandles[i]->network = graphicsScenes[i]->network;
01388                                         setHandle(graphicsItems[i],itemHandles[i]);
01389 
01390                                         if ((itemHandles.indexOf(itemHandles[i]) == i))
01391                                                 for (int j=0; j < itemHandles[i]->children.size(); ++j)
01392                                                         if (itemHandles[i]->children[j])
01393                                                                 itemHandles[i]->children[j]->parent = itemHandles[i];
01394 
01395                                 }
01396                                 if (itemParents.size() > i && itemParents[i] != 0)
01397                                 {
01398                                         graphicsItems[i]->setParentItem(itemParents[i]);
01399                                 }
01400                         }
01401 
01402                 for (int i=0; i < connections.size(); ++i)
01403                 {
01404                         connections[i]->refresh();
01405                         connections[i]->setControlPointsVisible(false);
01406                 }
01407 
01408                 if (changeDataCommand)
01409                         changeDataCommand->redo();
01410         }
01411 
01412 
01413         ChangeBrushCommand::ChangeBrushCommand(const QString& name, QGraphicsItem * item, const QBrush& to)
01414                 : QUndoCommand(name)
01415         {
01416                 graphicsItems.clear();
01417                 oldBrush.clear();
01418                 newBrush.clear();
01419 
01420                 QAbstractGraphicsShapeItem * aitem = qgraphicsitem_cast<QAbstractGraphicsShapeItem*>(item);
01421                 NodeGraphicsItem::Shape * shape = qgraphicsitem_cast<NodeGraphicsItem::Shape*>(item);
01422                 ConnectionGraphicsItem * connection = ConnectionGraphicsItem::cast(item);
01423                 ControlPoint * controlPoint = qgraphicsitem_cast<ControlPoint*>(item);
01424                 if (controlPoint == 0) controlPoint = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(item);
01425                 if (controlPoint == 0) controlPoint = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(item);
01426                 if (shape != 0)
01427                 {
01428                         graphicsItems.append(shape);
01429                         oldBrush.append(shape->defaultBrush);
01430                 }
01431                 else
01432                         if (connection != 0)
01433                         {
01434                                 graphicsItems.append(connection);
01435                                 oldBrush.append(QBrush(connection->defaultPen.color()));
01436                         }
01437                         else
01438                                 if (controlPoint != 0)
01439                                 {
01440                                         graphicsItems.append(controlPoint);
01441                                         oldBrush.append(controlPoint->defaultBrush);
01442                                 }
01443                                 else
01444                                         if (aitem != 0)
01445                                         {
01446                                                 graphicsItems.append(aitem);
01447                                                 oldBrush.append(aitem->brush());
01448                                         }
01449 
01450                                         newBrush.append(to);
01451         }
01452 
01453         ChangeBrushCommand::ChangeBrushCommand(const QString& name, const QList<QGraphicsItem*>& items, const QList<QBrush>& to)
01454                 : QUndoCommand(name)
01455         {
01456                 newBrush.clear();
01457                 for (int i=0; i < items.size(); ++i)
01458                 {
01459                         QAbstractGraphicsShapeItem * aitem = qgraphicsitem_cast<QAbstractGraphicsShapeItem*>(items[i]);
01460                         NodeGraphicsItem::Shape * shape = qgraphicsitem_cast<NodeGraphicsItem::Shape*>(items[i]);
01461                         ConnectionGraphicsItem * connection = ConnectionGraphicsItem::cast(items[i]);
01462                         ControlPoint * controlPoint = qgraphicsitem_cast<ControlPoint*>(items[i]);
01463                         if (controlPoint == 0) controlPoint = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(items[i]);
01464                         if (controlPoint == 0) controlPoint = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(items[i]);
01465                         if (shape != 0)
01466                         {
01467                                 graphicsItems.append(shape);
01468                                 oldBrush.append(shape->defaultBrush);
01469                         }
01470                         else
01471                                 if (connection != 0)
01472                                 {
01473                                         graphicsItems.append(connection);
01474                                         oldBrush.append(QBrush(connection->defaultPen.color()));
01475                                 }
01476                                 else
01477                                         if (controlPoint != 0)
01478                                         {
01479                                                 graphicsItems.append(controlPoint);
01480                                                 oldBrush.append(controlPoint->defaultBrush);
01481                                         }
01482                                         else
01483                                                 if (aitem != 0)
01484                                                 {
01485                                                         graphicsItems.append(aitem);
01486                                                         oldBrush.append(aitem->brush());
01487                                                 }
01488                 }
01489                 newBrush = to;
01490         }
01491         void ChangeBrushCommand::redo()
01492         {
01493                 for (int i=0; i < graphicsItems.size() && i < newBrush.size() && i < oldBrush.size(); ++i)
01494                 {
01495                         QAbstractGraphicsShapeItem * aitem = qgraphicsitem_cast<QAbstractGraphicsShapeItem*>(graphicsItems[i]);
01496                         NodeGraphicsItem::Shape * shape = qgraphicsitem_cast<NodeGraphicsItem::Shape*>(graphicsItems[i]);
01497                         ConnectionGraphicsItem * connection = ConnectionGraphicsItem::cast(graphicsItems[i]);
01498                         ControlPoint * controlPoint = qgraphicsitem_cast<ControlPoint*>(graphicsItems[i]);
01499                         if (controlPoint == 0) controlPoint = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(graphicsItems[i]);
01500                         if (controlPoint == 0) controlPoint = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(graphicsItems[i]);
01501                         if (shape != 0)
01502                                 shape->setBrush( shape->defaultBrush = newBrush[i] );
01503                         else
01504                                 if (connection != 0)
01505                                         connection->setPen( connection->defaultPen = QPen(newBrush[i], connection->defaultPen.widthF()) );
01506                                         //connection->setBrush( connection->defaultBrush = newBrush[i] );
01507                                 else
01508                                         if (controlPoint != 0)
01509                                                 controlPoint->setBrush( controlPoint->defaultBrush = newBrush[i] );
01510                                         else
01511                                                 if (aitem != 0)
01512                                                         aitem->setBrush(newBrush[i]);
01513                 }
01514         }
01515         void ChangeBrushCommand::undo()
01516         {
01517                 for (int i=0; i < graphicsItems.size() && i < oldBrush.size() && i < newBrush.size(); ++i)
01518                 {
01519                         QAbstractGraphicsShapeItem * aitem = qgraphicsitem_cast<QAbstractGraphicsShapeItem*>(graphicsItems[i]);
01520                         NodeGraphicsItem::Shape * shape = qgraphicsitem_cast<NodeGraphicsItem::Shape*>(graphicsItems[i]);
01521                         ConnectionGraphicsItem * connection = ConnectionGraphicsItem::cast(graphicsItems[i]);
01522                         ControlPoint * controlPoint = qgraphicsitem_cast<ControlPoint*>(graphicsItems[i]);
01523                         if (controlPoint == 0) controlPoint = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(graphicsItems[i]);
01524                         if (controlPoint == 0) controlPoint = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(graphicsItems[i]);
01525                         if (shape != 0)
01526                                 shape->setBrush( shape->defaultBrush = oldBrush[i] );
01527                         else
01528                                 if (connection != 0)
01529                                         connection->setPen( connection->defaultPen = QPen(oldBrush[i], connection->defaultPen.widthF()) );
01530                                         //connection->setBrush( connection->defaultBrush = oldBrush[i] );
01531                                 else
01532                                         if (controlPoint != 0)
01533                                                 controlPoint->setBrush( controlPoint->defaultBrush = oldBrush[i] );
01534                                         else
01535                                                 if (aitem != 0)
01536                                                         aitem->setBrush(oldBrush[i]);
01537                 }
01538         }
01539 
01540         ChangePenCommand::ChangePenCommand(const QString& name, QGraphicsItem * item, const QPen& to)
01541                 : QUndoCommand(name)
01542         {
01543                 graphicsItems.clear();
01544                 oldPen.clear();
01545                 newPen.clear();
01546                 QAbstractGraphicsShapeItem * aitem = qgraphicsitem_cast<QAbstractGraphicsShapeItem*>(item);
01547                 NodeGraphicsItem::Shape * shape = qgraphicsitem_cast<NodeGraphicsItem::Shape*>(item);
01548                 ConnectionGraphicsItem * connection = ConnectionGraphicsItem::cast(item);
01549                 ControlPoint * controlPoint = qgraphicsitem_cast<ControlPoint*>(item);
01550                 if (controlPoint == 0) controlPoint = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(item);
01551                 if (controlPoint == 0) controlPoint = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(item);
01552                 TextGraphicsItem * textItem = qgraphicsitem_cast<TextGraphicsItem*>(item);
01553                 if (shape != 0)
01554                 {
01555                         graphicsItems.append(shape);
01556                         oldPen.append(shape->defaultPen);
01557                 }
01558                 else
01559                         if (connection != 0)
01560                         {
01561                                 graphicsItems.append(connection);
01562                                 oldPen.append(connection->defaultPen);
01563                         }
01564                         else
01565                                 if (controlPoint != 0)
01566                                 {
01567                                         graphicsItems.append(controlPoint);
01568                                         oldPen.append(controlPoint->defaultPen);
01569                                 }
01570                                 else
01571                                         if (textItem != 0)
01572                                         {
01573                                                 graphicsItems.append(textItem);
01574                                                 oldPen.append(QPen(textItem->defaultTextColor()));
01575                                         }
01576                                         else
01577                                                 if (aitem != 0)
01578                                                 {
01579                                                         graphicsItems.append(aitem);
01580                                                         oldPen.append(aitem->pen());
01581                                                 }
01582 
01583                                                 newPen.append(to);
01584         }
01585 
01586         ChangePenCommand::ChangePenCommand(const QString& name, const QList<QGraphicsItem*>& items, const QList<QPen>& to)
01587                 : QUndoCommand(name)
01588         {
01589                 newPen.clear();
01590                 for (int i=0; i < items.size(); ++i)
01591                 {
01592                         QAbstractGraphicsShapeItem * aitem = qgraphicsitem_cast<QAbstractGraphicsShapeItem*>(items[i]);
01593                         NodeGraphicsItem::Shape * shape = qgraphicsitem_cast<NodeGraphicsItem::Shape*>(items[i]);
01594                         ConnectionGraphicsItem * connection = ConnectionGraphicsItem::cast(items[i]);
01595                         ControlPoint * controlPoint = qgraphicsitem_cast<ControlPoint*>(items[i]);
01596                         if (controlPoint == 0) controlPoint = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(items[i]);
01597                         if (controlPoint == 0) controlPoint = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(items[i]);
01598                         TextGraphicsItem * textItem = qgraphicsitem_cast<TextGraphicsItem*>(items[i]);
01599                         if (shape != 0)
01600                         {
01601                                 graphicsItems.append(shape);
01602                                 oldPen.append(shape->defaultPen);
01603                         }
01604                         else
01605                                 if (connection != 0)
01606                                 {
01607                                         graphicsItems.append(connection);
01608                                         oldPen.append(connection->defaultPen);
01609                                 }
01610                                 else
01611                                         if (controlPoint != 0)
01612                                         {
01613                                                 graphicsItems.append(controlPoint);
01614                                                 oldPen.append(controlPoint->defaultPen);
01615                                         }
01616                                         else
01617                                                 if (textItem != 0)
01618                                                 {
01619                                                         graphicsItems.append(textItem);
01620                                                         oldPen.append(QPen(textItem->defaultTextColor()));
01621                                                 }
01622                                                 else
01623                                                         if (aitem != 0)
01624                                                         {
01625                                                                 graphicsItems.append(aitem);
01626                                                                 oldPen.append(aitem->pen());
01627                                                         }
01628                 }
01629                 newPen = to;
01630         }
01631         void ChangePenCommand::redo()
01632         {
01633                 for (int i=0; i < graphicsItems.size() && i < oldPen.size() && i < newPen.size(); ++i)
01634                 {
01635                         QAbstractGraphicsShapeItem * aitem = qgraphicsitem_cast<QAbstractGraphicsShapeItem*>(graphicsItems[i]);
01636                         NodeGraphicsItem::Shape * shape = qgraphicsitem_cast<NodeGraphicsItem::Shape*>(graphicsItems[i]);
01637                         ConnectionGraphicsItem * connection = ConnectionGraphicsItem::cast(graphicsItems[i]);
01638                         ControlPoint * controlPoint = qgraphicsitem_cast<ControlPoint*>(graphicsItems[i]);
01639                         if (controlPoint == 0) controlPoint = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(graphicsItems[i]);
01640                         if (controlPoint == 0) controlPoint = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(graphicsItems[i]);
01641                         TextGraphicsItem * textItem = qgraphicsitem_cast<TextGraphicsItem*>(graphicsItems[i]);
01642                         if (shape != 0)
01643                                 shape->setPen( shape->defaultPen = newPen[i] );
01644                         else
01645                                 if (connection != 0)
01646                                 {
01647                                         connection->setPen( connection->defaultPen = newPen[i] );
01648                                         connection->refresh();
01649                                 }
01650                                 else
01651                                         if (controlPoint != 0)
01652                                                 controlPoint->setPen( controlPoint->defaultPen = newPen[i] );
01653                                         else
01654                                                 if (textItem != 0)
01655                                                         textItem->setDefaultTextColor( newPen[i].color() );
01656                                                 else
01657                                                         if (aitem != 0)
01658                                                                 aitem->setPen(newPen[i]);
01659                 }
01660         }
01661 
01662         void ChangePenCommand::undo()
01663         {
01664                 for (int i=0; i < graphicsItems.size() && i < oldPen.size() && i < newPen.size(); ++i)
01665                 {
01666                         QAbstractGraphicsShapeItem * aitem = qgraphicsitem_cast<QAbstractGraphicsShapeItem*>(graphicsItems[i]);
01667                         NodeGraphicsItem::Shape * shape = qgraphicsitem_cast<NodeGraphicsItem::Shape*>(graphicsItems[i]);
01668                         ConnectionGraphicsItem * connection = ConnectionGraphicsItem::cast(graphicsItems[i]);
01669                         ControlPoint * controlPoint = qgraphicsitem_cast<ControlPoint*>(graphicsItems[i]);
01670                         TextGraphicsItem * textItem = qgraphicsitem_cast<TextGraphicsItem*>(graphicsItems[i]);
01671                         if (controlPoint == 0) controlPoint = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(graphicsItems[i]);
01672                         if (controlPoint == 0) controlPoint = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(graphicsItems[i]);
01673                         if (shape != 0)
01674                                 shape->setPen( shape->defaultPen = oldPen[i] );
01675                         else
01676                                 if (connection != 0)
01677                                 {
01678                                         connection->setPen( connection->defaultPen = oldPen[i] );
01679                                         connection->refresh();
01680                                 }
01681                                 else
01682                                         if (controlPoint != 0)
01683                                                 controlPoint->setPen( controlPoint->defaultPen = oldPen[i] );
01684                                         else
01685                                                 if (textItem != 0)
01686                                                         textItem->setDefaultTextColor( oldPen[i].color() );
01687                                                 else
01688                                                         if (aitem != 0)
01689                                                                 aitem->setPen(oldPen[i]);
01690                 }
01691         }
01692         
01693         ChangeBrushAndPenCommand::~ChangeBrushAndPenCommand()
01694         {
01695                 if (changeBrushCommand)
01696                         delete changeBrushCommand;
01697 
01698                 if (changePenCommand)
01699                         delete changePenCommand;
01700         }
01701 
01702         ChangeBrushAndPenCommand::ChangeBrushAndPenCommand(const QString& name, QGraphicsItem * item, const QBrush& brush, const QPen& pen)
01703                 : QUndoCommand(name)
01704         {
01705                 changeBrushCommand = new ChangeBrushCommand(name,item,brush);
01706                 changePenCommand = new ChangePenCommand(name,item,pen);
01707         }
01708 
01709         ChangeBrushAndPenCommand::ChangeBrushAndPenCommand(const QString& name, const QList<QGraphicsItem*>& items, const QList<QBrush>& brushes, const QList<QPen>& pens)
01710                 : QUndoCommand(name)
01711         {
01712                 changeBrushCommand = new ChangeBrushCommand(name,items,brushes);
01713                 changePenCommand = new ChangePenCommand(name,items,pens);
01714         }
01715 
01716         void ChangeBrushAndPenCommand::redo()
01717         {
01718                 if (changeBrushCommand)
01719                         changeBrushCommand->redo();
01720                         
01721                 if (changePenCommand)
01722                         changePenCommand->redo();
01723         }
01724 
01725         void ChangeBrushAndPenCommand::undo()
01726         {
01727                 if (changeBrushCommand)
01728                         changeBrushCommand->undo();
01729                         
01730                 if (changePenCommand)
01731                         changePenCommand->undo();
01732         }
01733 
01734         TransformCommand::TransformCommand(const QString& name, QGraphicsScene * scene, QGraphicsItem * item,
01735                 const QPointF& sizeChange, qreal changeInAngle,
01736                 bool VFlip, bool HFlip)
01737                 : QUndoCommand(name)
01738         {
01739                 graphicsScene = scene;
01740                 graphicsItems.append(item);
01741                 sizeFactor.clear();
01742                 angleChange.clear();
01743 
01744                 sizeFactor.append(sizeChange);
01745                 angleChange.append(changeInAngle);
01746                 vFlip.append(VFlip);
01747                 hFlip.append(HFlip);
01748         }
01749 
01750         TransformCommand::TransformCommand(const QString& name, QGraphicsScene * scene, const QList<QGraphicsItem *>& items,
01751                 const QList<QPointF>& sizeChange, const QList<qreal>& changeInAngle,
01752                 const QList<bool>& VFlip, const QList<bool>& HFlip)
01753                 : QUndoCommand(name)
01754         {
01755                 graphicsScene = scene;
01756                 graphicsItems = items;
01757 
01758                 sizeFactor = sizeChange;
01759                 angleChange = changeInAngle;
01760                 vFlip = VFlip;
01761                 hFlip = HFlip;
01762         }
01763 
01764         void TransformCommand::redo()
01765         {
01766                 for (int i=0; i < graphicsItems.size(); ++i)
01767 
01768                         if (graphicsItems[i])
01769                         {
01770                                 QTransform t = graphicsItems[i]->transform();
01771                                 
01772                                 if (sizeFactor.size() > i && !sizeFactor[i].isNull())
01773                                 {
01774                                         QTransform scale(sizeFactor[i].x(), 0, 0, sizeFactor[i].y(), 0, 0);
01775                                         t = (t * scale);
01776                                 }
01777 
01778                                 if (hFlip.size() > i && hFlip[i])
01779                                 {
01780                                         QTransform scale(-1.0, 0, 0, 1.0, 0, 0);
01781                                         t = (t * scale);
01782                                 }
01783 
01784                                 if (vFlip.size() > i && vFlip[i])
01785                                 {
01786                                         QTransform scale(1.0, 0, 0, -1.0, 0, 0);
01787                                         t = (t * scale);
01788                                 }
01789                                 
01790                                 if (angleChange.size() > i && angleChange[i] != 0.0)
01791                                 {
01792                                         double sinx = sin(angleChange[i] * 3.14159/180.0),
01793                                                    cosx = cos(angleChange[i] * 3.14159/180.0);
01794                                         QTransform rotate(cosx, sinx, -sinx, cosx, 0, 0);
01795                                         t = (t * rotate);
01796                                 }
01797                                 
01798                                 graphicsItems[i]->setTransform(t);
01799 
01800                                 NodeGraphicsItem * node = NodeGraphicsItem::cast(graphicsItems[i]);
01801                                 if (node)
01802                                 {
01803                                         node->adjustBoundaryControlPoints();
01804                                 }
01805                         }
01806         }
01807 
01808         void TransformCommand::undo()
01809         {
01810                 for (int i=0; i < graphicsItems.size(); ++i)
01811 
01812                         if (graphicsItems[i])
01813                         {
01814                                 QTransform t = graphicsItems[i]->transform();
01815                                 
01816                                 if (sizeFactor.size() > i && !sizeFactor[i].isNull())
01817                                 {
01818                                         QTransform scale(1.0/sizeFactor[i].x(), 0, 0, 1.0/sizeFactor[i].y(), 0, 0);
01819                                         t = (t * scale);
01820                                 }
01821                                 
01822                                 if (hFlip.size() > i && hFlip[i])
01823                                 {
01824                                         QTransform scale(-1.0, 0, 0, 1.0, 0, 0);
01825                                         t = (t * scale);
01826                                 }
01827 
01828                                 if (vFlip.size() > i && vFlip[i])
01829                                 {
01830                                         QTransform scale(1.0, 0, 0, -1.0, 0, 0);
01831                                         t = (t * scale);
01832                                 }
01833 
01834                                 if (angleChange.size() > i && angleChange[i] != 0.0)
01835                                 {
01836                                         double sinx = sin(-angleChange[i] * 3.14159/180.0),
01837                                                    cosx = cos(-angleChange[i] * 3.14159/180.0);
01838                                         QTransform rotate(cosx, sinx, -sinx, cosx, 0, 0);
01839                                         t = (t * rotate);
01840                                 }
01841                                 
01842                                 graphicsItems[i]->setTransform(t);
01843 
01844                                 NodeGraphicsItem * node = NodeGraphicsItem::cast(graphicsItems[i]);
01845                                 if (node)
01846                                 {
01847                                         node->adjustBoundaryControlPoints();
01848                                 }
01849                         }
01850         }
01851 
01852         ChangeZCommand::ChangeZCommand(const QString& name, QGraphicsScene * scene, QGraphicsItem * item, double to)
01853                 : QUndoCommand(name)
01854         {
01855                 graphicsScene = scene;
01856                 graphicsItems.clear();
01857                 oldZ.clear();
01858                 newZ.clear();
01859                 if (item != 0)
01860                 {
01861                         graphicsItems.append(item->topLevelItem());
01862                         oldZ.append(item->zValue());
01863                         newZ.append(to);
01864                 }
01865         }
01866 
01867         ChangeZCommand::ChangeZCommand(const QString& name, QGraphicsScene * scene, const QList<QGraphicsItem*>& items, const QList<double>& to)
01868                 : QUndoCommand(name)
01869         {
01870                 graphicsScene = scene;
01871                 newZ.clear();
01872                 for (int i=0; i < items.size(); ++i)
01873                 {
01874                         QGraphicsItem * aitem = (items[i]);
01875                         if (aitem != 0)
01876                         {
01877                                 graphicsItems.append(aitem->topLevelItem());
01878                                 oldZ.append(aitem->zValue());
01879                         }
01880                 }
01881                 newZ = to;
01882         }
01883 
01884         void ChangeZCommand::redo()
01885         {
01886                 for (int i=0; i < graphicsItems.size() && i < newZ.size(); ++i)
01887                 {
01888                         if (graphicsItems[i] != 0)
01889                         {
01890                                 graphicsItems[i]->setZValue(newZ[i]);
01891                         }
01892                 }
01893         }
01894 
01895         void ChangeZCommand::undo()
01896         {
01897                 for (int i=0; i < graphicsItems.size() && i < oldZ.size(); ++i)
01898                 {
01899                         if (graphicsItems[i] != 0)
01900                         {
01901                                 graphicsItems[i]->setZValue(oldZ[i]);
01902                         }
01903                 }
01904         }
01905 
01906         ChangeParentCommand::ChangeParentCommand(const QString& name, QGraphicsScene * scene, QGraphicsItem * item, QGraphicsItem * newParent)
01907                 : QUndoCommand(name)
01908         {
01909                 this->scene = scene;
01910                 graphicsItems.clear();
01911                 oldParents.clear();
01912                 newParents.clear();
01913                 if (item != 0)
01914                 {
01915                         graphicsItems.append(item);
01916                         oldParents.append(item->parentItem());
01917                         newParents.append(newParent);
01918                 }
01919         }
01920 
01921         ChangeParentCommand::ChangeParentCommand(const QString& name, QGraphicsScene * scene, const QList<QGraphicsItem*>& items, const QList<QGraphicsItem*>& to)
01922                 : QUndoCommand(name)
01923         {
01924                 this->scene = scene;
01925                 oldParents.clear();
01926                 newParents.clear();
01927                 for (int i=0; i < items.size(); ++i)
01928                 {
01929                         QGraphicsItem * aitem = (items[i]);
01930                         if (aitem != 0)
01931                         {
01932                                 graphicsItems.append(aitem);
01933                                 oldParents.append(aitem->parentItem());
01934                         }
01935                 }
01936                 newParents = to;
01937         }
01938 
01939         void ChangeParentCommand::redo()
01940         {
01941                 if (scene == 0) return;
01942 
01943                 for (int i=0; i < graphicsItems.size() && i < newParents.size(); ++i)
01944                 {
01945                         if (graphicsItems[i] != 0)
01946                         {
01947                                 QPointF pos = graphicsItems[i]->scenePos();
01948                                 if (newParents[i] == 0)
01949                                 {
01950                                         graphicsItems[i]->setParentItem(0);
01951                                         if (graphicsItems[i]->scene() != scene)
01952                                                 scene->addItem(graphicsItems[i]);
01953                                         graphicsItems[i]->setPos(pos);
01954                                 }
01955                                 else
01956                                 {
01957                                         graphicsItems[i]->setParentItem(newParents[i]);
01958                                         graphicsItems[i]->setPos( newParents[i]->mapFromScene(pos) );
01959                                 }
01960                         }
01961                 }
01962         }
01963 
01964         void ChangeParentCommand::undo()
01965         {
01966                 if (scene == 0) return;
01967 
01968                 for (int i=0; i < graphicsItems.size() && i < oldParents.size(); ++i)
01969                 {
01970                         if (graphicsItems[i] != 0)
01971                         {
01972                                 QPointF pos = graphicsItems[i]->scenePos();
01973                                 if (oldParents[i] == 0)
01974                                 {
01975                                         graphicsItems[i]->setParentItem(0);
01976                                         if (graphicsItems[i]->scene() != scene)
01977                                                 scene->addItem(graphicsItems[i]);
01978                                         graphicsItems[i]->setPos(pos);
01979                                 }
01980                                 else
01981                                 {
01982                                         graphicsItems[i]->setParentItem(oldParents[i]);
01983                                         graphicsItems[i]->setPos( oldParents[i]->mapFromScene(pos) );
01984                                 }
01985                         }
01986                 }
01987         }
01988 
01989         RenameCommand::RenameCommand(const QString& name, NetworkHandle * net, ItemHandle * handle, const QString& newname, bool forceUnique)
01990                 : QUndoCommand(name), changeDataCommand(0), network(net), makeUnique(forceUnique)
01991         {
01992                 if (net)
01993                         allhandles = net->handles();
01994 
01995                 handles.clear();
01996                 oldNames.clear();
01997                 newNames.clear();
01998                 QString s;
01999 
02000                 if (handle)
02001                 {
02002                         handles += handle;
02003                         oldNames += handle->fullName();
02004                         
02005                         if (net && makeUnique)
02006                         {
02007                                 s = handle->name;
02008                                 handle->name = newname;
02009                                 if (handle->parent)
02010                                         handle->name.remove(handle->parent->fullName() + QObject::tr("."));
02011                                 newNames += net->makeUnique(handle);
02012                                 handle->name = s;
02013                         }
02014                         else
02015                                 newNames += newname;
02016                 }
02017         }
02018 
02019         RenameCommand::RenameCommand(const QString& name, NetworkHandle * net, const QList<ItemHandle*>& allItems, const QString& oldname, const QString& newname, bool forceUnique)
02020                 : QUndoCommand(name), changeDataCommand(0), network(net), makeUnique(forceUnique)
02021         {
02022                 allhandles = allItems;
02023                 
02024                 for (int i=0; i < allhandles.size(); ++i)
02025                         if (allhandles[i])
02026                         {
02027                                 QList<ItemHandle*> & children = allhandles[i]->children;
02028                                 for (int j=0; j < children.size(); ++j)
02029                                         if (children[j] && !allhandles.contains(children[j]))
02030                                                 allhandles << children[j];
02031                         }
02032                 
02033                 handles.clear();
02034                 oldNames.clear();
02035                 newNames.clear();
02036 
02037                 oldNames += oldname;
02038                 if (net && makeUnique)
02039                         newNames += net->makeUnique(newname);
02040                 else
02041                         newNames += newname;
02042         }
02043         
02044         RenameCommand::RenameCommand(const QString& name, NetworkHandle * net, const QString& oldname, const QString& newname, bool forceUnique)
02045                 : QUndoCommand(name), changeDataCommand(0), network(net), makeUnique(forceUnique)
02046         {
02047                 if (net)
02048                         this->allhandles = net->handles();
02049 
02050                 handles.clear();
02051                 oldNames.clear();
02052                 newNames.clear();
02053 
02054                 oldNames += oldname;
02055                 if (net && makeUnique)
02056                         newNames += net->makeUnique(newname);
02057                 else
02058                         newNames += newname;
02059         }
02060         
02061         RenameCommand::RenameCommand(const QString& name, NetworkHandle * net, const QList<ItemHandle*>& allItems, const QList<QString>& oldname, const QList<QString>& newname, bool forceUnique)
02062                 : QUndoCommand(name), changeDataCommand(0), network(net), makeUnique(forceUnique)
02063         {
02064                 allhandles = allItems;
02065                 for (int i=0; i < allhandles.size(); ++i)
02066                         if (allhandles[i])
02067                         {
02068                                 QList<ItemHandle*> & children = allhandles[i]->children;
02069                                 for (int j=0; j < children.size(); ++j)
02070                                         if (children[j] && !allhandles.contains(children[j]))
02071                                                 allhandles << children[j];
02072                         }
02073                 
02074                 handles.clear();
02075                 oldNames.clear();
02076                 newNames.clear();
02077 
02078                 oldNames << oldname;
02079                 if (net && makeUnique)
02080                         newNames << net->makeUnique(newname);
02081                 else
02082                         newNames << newname;
02083         }
02084         
02085         RenameCommand::RenameCommand(const QString& name, NetworkHandle * net, const QList<QString>& oldname, const QList<QString>& newname, bool forceUnique)
02086                 : QUndoCommand(name), changeDataCommand(0), network(net), makeUnique(forceUnique)
02087         {
02088                 if (net)
02089                         this->allhandles = net->handles();
02090                 handles.clear();
02091                 oldNames.clear();
02092                 newNames.clear();
02093                 
02094                 oldNames << oldname;
02095                 if (net && makeUnique)
02096                         newNames << net->makeUnique(newname);
02097                 else
02098                         newNames << newname;
02099         }
02100 
02101         RenameCommand::RenameCommand(const QString& name, NetworkHandle * net, const QList<ItemHandle*>& allItems, ItemHandle * handle, const QString& newname, bool forceUnique)
02102                 : QUndoCommand(name), changeDataCommand(0), network(net), makeUnique(forceUnique)
02103         {
02104                 allhandles = allItems;
02105                 for (int i=0; i < allhandles.size(); ++i)
02106                         if (allhandles[i])
02107                         {
02108                                 QList<ItemHandle*> & children = allhandles[i]->children;
02109                                 for (int j=0; j < children.size(); ++j)
02110                                         if (children[j] && !allhandles.contains(children[j]))
02111                                                 allhandles << children[j];
02112                         }
02113 
02114                 handles.clear();
02115                 oldNames.clear();
02116                 newNames.clear();
02117 
02118                 ItemHandle * handle1;
02119                 QStringList allNames;
02120                 QString s;
02121                 for (int i=0; i < allItems.size(); ++i)
02122                         if ((handle1 = (allItems[i])) && (handle != handle1))
02123                         {
02124                                 allNames << handle1->fullName();
02125                                 allNames << handle1->fullName(QObject::tr("_"));
02126                         }
02127 
02128                 if (handle)
02129                 {
02130                         handles += handle;
02131                         oldNames += handle->fullName();
02132                         if (net && makeUnique)
02133                         {
02134                                 s = handle->name;
02135                                 handle->name = newname;
02136                                 if (handle->parent)
02137                                         handle->name.remove(handle->parent->fullName() + QObject::tr("."));
02138                                 newNames += net->makeUnique(handle);
02139                                 handle->name = s;
02140                         }
02141                         else
02142                                 newNames += newname;
02143                 }
02144         }
02145 
02146         RenameCommand::RenameCommand(const QString& name, NetworkHandle * net, const QList<ItemHandle*>& items, const QList<QString>& newnames, bool forceUnique)
02147                 : QUndoCommand(name), changeDataCommand(0), network(net), makeUnique(forceUnique)
02148         {
02149                 if (net)
02150                         this->allhandles = net->handles();
02151                 handles.clear();
02152                 oldNames.clear();
02153                 newNames.clear();
02154 
02155                 ItemHandle * handle;
02156                 QStringList allNames;
02157                 QString s;
02158 
02159                 for (int i=0; i < allhandles.size(); ++i)
02160                         if ((handle = (allhandles[i])) && !items.contains(handle))
02161                         {
02162                                 allNames << handle->fullName();
02163                                 allNames << handle->fullName(QObject::tr("_"));
02164                         }
02165 
02166                 for (int i=0; i < items.size() && i < newnames.size() ; ++i)
02167                 {
02168                         handle = items[i];
02169                         if (handle)
02170                         {
02171                                 handles += handle;
02172                                 oldNames += handle->fullName();
02173                                 
02174                                 if (net && makeUnique)
02175                                 {
02176                                         s = handle->name;
02177                                         handle->name = newnames[i];
02178                                         if (handle->parent)
02179                                                 handle->name.remove(handle->parent->fullName() + QObject::tr("."));
02180                                         newNames += net->makeUnique(handle,newNames);
02181                                         handle->name = s;
02182                                 }
02183                                 else
02184                                         newNames += newnames[i];
02185                         }
02186                 }
02187         }
02188 
02189         RenameCommand::RenameCommand(const QString& name, NetworkHandle * net, const QList<ItemHandle*>& allItems, const QList<ItemHandle*>& items, const QList<QString>& newnames, bool forceUnique)
02190                 : QUndoCommand(name), changeDataCommand(0), network(net), makeUnique(forceUnique)
02191         {
02192                 allhandles = allItems;
02193                 for (int i=0; i < allhandles.size(); ++i)
02194                         if (allhandles[i])
02195                         {
02196                                 QList<ItemHandle*> & children = allhandles[i]->children;
02197                                 for (int j=0; j < children.size(); ++j)
02198                                         if (children[j] && !allhandles.contains(children[j]))
02199                                                 allhandles << children[j];
02200                         }
02201 
02202                 handles.clear();
02203                 oldNames.clear();
02204                 newNames.clear();
02205                 ItemHandle * handle;
02206                 QString s;
02207 
02208                 for (int i=0; i < items.size() && i < newnames.size() ; ++i)
02209                 {
02210                         handle = (items[i]);
02211                         if (handle)
02212                         {
02213                                 handles += handle;
02214                                 oldNames += handle->fullName();
02215                                 if (net && makeUnique)
02216                                 {
02217                                         s = handle->name;
02218                                         handle->name = newnames[i];
02219                                         if (handle->parent)
02220                                                 handle->name.remove(handle->parent->fullName() + QObject::tr("."));
02221                                         newNames += net->makeUnique(handle,newNames);
02222                                         handle->name = s;
02223                                 }
02224                                 else
02225                                         newNames += newnames[i];
02226                         }
02227                 }
02228         }
02229 
02230         void RenameCommand::addColumns(DataTable<double>& dat, int k, const QString& name)
02231         {
02232                 if (dat.hasColumn(name))
02233                 {
02234                         int rows = dat.rows();
02235                         for (int i=0; i < rows; ++i)
02236                                 dat(i,name) += dat(i,k);
02237                 }
02238         }
02239 
02240         void RenameCommand::substituteString(QString& target, const QString& oldname,const QString& newname0)
02241         {
02242                 if (oldname == newname0) return;
02243                 QString newname = newname0;
02244                 newname.replace(QRegExp("[^A-Za-z0-9_]"),QString("_@@@_"));
02245 
02246                 QRegExp regexp1(QString("^") + oldname + QString("$")),  //just old name
02247                         regexp2(QString("^") + oldname + QString("([^A-Za-z0-9_])")),  //oldname+(!letter/num)
02248                         regexp3(QString("([^A-Za-z0-9_\\.])") + oldname + QString("$")), //(!letter/num)+oldname
02249                         regexp4(QString("([^A-Za-z0-9_\\.])") + oldname + QString("([^A-Za-z0-9_])")); //(!letter/num)+oldname+(!letter/num)
02250                 int n = regexp1.indexIn(target);
02251                 while (n != -1)
02252                 {
02253                         target.replace(oldname,newname);
02254                         n = regexp1.indexIn(target);
02255                 }
02256                 n = regexp2.indexIn(target);
02257                 while (n != -1)
02258                 {
02259                         target.replace(regexp2,newname+QString("\\1"));
02260                         n = regexp2.indexIn(target);
02261                 }
02262                 n = regexp3.indexIn(target);
02263                 while (n != -1)
02264                 {
02265                         target.replace(regexp3,QString("\\1")+newname);
02266                         n = regexp3.indexIn(target);
02267                 }
02268                 n = regexp4.indexIn(target);
02269                 while (n != -1)
02270                 {
02271                         target.replace(regexp4,QString("\\1")+newname+QString("\\2"));
02272                         n = regexp4.indexIn(target);
02273                 }
02274                 target.replace(newname,newname0);
02275         }
02276 
02277         void RenameCommand::findReplaceAllHandleData(QList<ItemHandle*>& handles,const QString& oldname,const QString& newname)
02278         {
02279                 if (oldname.isEmpty()) return; //impossible
02280 
02281                 DataTable<qreal> * nDat = 0;
02282                 DataTable<QString> * sDat = 0;
02283 
02284                 for (int i=0; i < handles.size(); ++i)
02285                 {
02286                         if (handles[i])  //go through each handles num data and text data
02287                         {
02288                                 for (int j=0; j < handles[i]->children.size(); ++j)
02289                                         if (!handles.contains(handles[i]->children[j]))
02290                                                 handles += handles[i]->children[j];
02291                         
02292                                 QString s1, s2;
02293                                 s1 = newname;
02294                                 if (!handles[i]->name.isEmpty() && s1.startsWith(handles[i]->fullName()))
02295                                 {
02296                                         s1.replace(handles[i]->fullName() + QObject::tr("."), QObject::tr(""));
02297                                         s1.replace(handles[i]->fullName() + QObject::tr("_"), QObject::tr(""));                                 
02298                                 }
02299 
02300                                 QList< QString > keys = handles[i]->numericalDataNames();
02301                                 for (int j=0; j < keys.size(); ++j)  //go through each num data
02302                                 {
02303                                         nDat = &(handles[i]->numericalDataTable( keys[j] ));
02304                                         for (int k=0; k < nDat->rows(); ++k)
02305                                         {
02306                                                 /*if (nDat->rowName(k).contains(oldname))
02307                                                 {
02308                                                         s2 = nDat->rowName(k);
02309                                                         substituteString(s2,oldname,newname);
02310                                                         s2 = RemoveDisallowedCharactersFromName(s2);
02311                                                         if (s2 != nDat->rowName(k))
02312                                                         {
02313                                                                 if (!nDat->hasRow(s2))
02314                                                                         nDat->setRowName(k,RemoveDisallowedCharactersFromName(s2));
02315                                                                 else
02316                                                                         nDat->removeRow(k);
02317                                                         }
02318                                                 }*/
02319 
02320                                                 if ((handles[i]->name.isEmpty() && nDat->rowName(k) == oldname) ||
02321                                                          ((handles[i]->fullName() + QObject::tr(".") + nDat->rowName(k)) == oldname ||
02322                                                                 (handles[i]->fullName() + QObject::tr("_") + nDat->rowName(k)) == oldname)
02323                                                         )
02324                                                 {
02325                                                         nDat->setRowName(k,s1);
02326                                                 }
02327                                         }
02328                                         for (int k=0; k < nDat->columns(); ++k)
02329                                         {
02330                                                 if (nDat->columnName(k) == oldname)
02331                                                 {
02332                                                         if (nDat->hasColumn(newname))
02333                                                         {
02334                                                                 if (nDat->columnName(k) != newname)
02335                                                                 {
02336                                                                         addColumns(*nDat, k, newname);
02337                                                                         nDat->removeColumn(k);
02338                                                                 }
02339                                                         }
02340                                                         else
02341                                                                 nDat->setColumnName(k,newname);
02342                                                 }
02343                                                 else
02344                                                         if (nDat->columnName(k).contains(oldname))
02345                                                         {
02346                                                                 s2 = nDat->columnName(k);
02347                                                                 substituteString(s2,oldname,newname);
02348                                                                 s2 = RemoveDisallowedCharactersFromName(s2);
02349                                                                 if (s2 != nDat->columnName(k))
02350                                                                 {
02351                                                                         if (nDat->hasColumn(s2))
02352                                                                         {
02353                                                                                 if (nDat->columnName(k) != s2)
02354                                                                                 {
02355                                                                                         addColumns(*nDat, k, s2);
02356                                                                                         nDat->removeColumn(k);
02357                                                                                 }
02358                                                                         }
02359                                                                         else
02360                                                                                 nDat->setColumnName(k,s2);
02361                                                                 }
02362                                                         }
02363                                         }
02364                                 }
02365                                 keys = handles[i]->textDataNames();
02366                                 for (int j=0; j < keys.size(); ++j)  //go through each text data
02367                                 {
02368                                         sDat = &(handles[i]->textDataTable (keys[j]));
02369                                         for (int k=0; k < sDat->rows(); ++k)
02370                                         {
02371                                                 /*if (sDat->rowName(k).contains(oldname))
02372                                                 {
02373                                                         s2 = sDat->rowName(k);
02374                                                         substituteString(s2,oldname,newname);
02375                                                         s2 = RemoveDisallowedCharactersFromName(s2);
02376                                                         if (s2 != sDat->rowName(k))
02377                                                         {
02378                                                                 if (!sDat->hasRow(s2))
02379                                                                         sDat->setRowName(k,s2);
02380                                                                 else
02381                                                                         sDat->removeRow(k);
02382                                                         }
02383                                                 }*/
02384 
02385                                                 if ((handles[i]->name.isEmpty() && sDat->rowName(k) == oldname) ||
02386                                                         ((handles[i]->fullName() + QObject::tr(".") + sDat->rowName(k)) == oldname ||
02387                                                          (handles[i]->fullName() + QObject::tr("_") + sDat->rowName(k)) == oldname)
02388                                                          )
02389                                                 {
02390                                                         if (!sDat->hasColumn(s2))
02391                                                                 sDat->setRowName(k,s1);
02392                                                         else
02393                                                                 sDat->removeColumn(k);
02394                                                 }
02395                                         }
02396                                         for (int k=0; k < sDat->columns(); ++k)
02397                                         {
02398                                                 if (sDat->columnName(k) == oldname)
02399                                                         sDat->setColumnName(k,newname);
02400                                                 else
02401                                                         if (sDat->columnName(k).contains(oldname))
02402                                                         {
02403                                                                 s2 = sDat->columnName(k);
02404                                                                 substituteString(s2,oldname,newname);
02405                                                                 s2 = RemoveDisallowedCharactersFromName(s2);
02406                                                                 if (s2 != sDat->columnName(k))
02407                                                                 {
02408                                                                         if (!sDat->hasColumn(s2))
02409                                                                                 sDat->setColumnName(k,s2);
02410                                                                         else
02411                                                                                 sDat->removeColumn(k);
02412                                                                 }
02413                                                         }
02414                                         }
02415                                         for (int k=0; k < sDat->rows(); ++k) //substitute each value in the table
02416                                                 for (int l=0; l < sDat->columns(); ++l)
02417                                                 {
02418                                                         if (sDat->value(k,l).contains(oldname))
02419                                                         {
02420                                                                 substituteString(sDat->value(k,l),oldname,newname);
02421                                                         }
02422                                                 }
02423                                 }
02424                         }
02425                 }
02426         }
02427 
02428         RenameCommand::~RenameCommand()
02429         {
02430                 if (changeDataCommand)
02431             delete changeDataCommand;
02432                 changeDataCommand = 0;
02433         }
02434 
02435         void RenameCommand::redo()
02436         {
02437                 bool firstTime = (changeDataCommand == 0);
02438                 QList< DataTable<qreal>* > oldData1, newData1;
02439                 QList< DataTable<QString>* > oldData2, newData2;
02440 
02441                 if (firstTime)
02442                 {
02443                         for (int i=0; i < allhandles.size(); ++i)
02444                                 if (allhandles[i])
02445                                 {
02446                                         QList<QString> keys1 = allhandles[i]->numericalDataNames();
02447                                         QList<QString> keys2 = allhandles[i]->textDataNames();
02448 
02449                                         for (int j=0; j < keys1.size(); ++j)
02450                                                 oldData1 += new DataTable<qreal>(allhandles[i]->numericalDataTable( keys1[j] ));
02451 
02452                                         for (int j=0; j < keys2.size(); ++j)
02453                                                 oldData2 += new DataTable<QString>(allhandles[i]->textDataTable( keys2[j] ));
02454                                 }
02455                 }
02456                 
02457                 QRegExp regexp("\\.([^\\.]+)$");
02458 
02459                 if (firstTime)
02460                 {
02461                         for (int i=0; i < oldNames.size() && i < newNames.size(); ++i)
02462                         {
02463                                 if (firstTime)
02464                                         findReplaceAllHandleData(allhandles,oldNames[i],newNames[i]);
02465 
02466                                 if (handles.size() == 0)
02467                                         for (int j=0; j < allhandles.size(); ++j)
02468                                                 if (allhandles[j] && allhandles[j]->fullName() == oldNames[i])
02469                                                 {
02470                                                         oldItemNames << QPair<ItemHandle*,QString>(allhandles[j],allhandles[j]->name);
02471 
02472                                                         regexp.indexIn(newNames[i]);
02473                                                         for (int k=0; k < allhandles[j]->graphicsItems.size(); ++k)
02474                                                         {
02475                                                                 TextGraphicsItem * textItem = qgraphicsitem_cast<TextGraphicsItem*>(allhandles[j]->graphicsItems[k]);
02476                                                                 if (textItem)
02477                                                                 {
02478                                                                         if (textItem->toPlainText() == allhandles[j]->name)
02479                                                                         {
02480                                                                                 oldTextItemsNames << QPair<TextGraphicsItem*,QString>(textItem,allhandles[j]->name);
02481 
02482                                                                                 if (regexp.numCaptures() > 0 && !regexp.cap(1).isEmpty())
02483                                                                                 {
02484                                                                                         textItem->setPlainText(regexp.cap(1));
02485                                                                                         newTextItemsNames << QPair<TextGraphicsItem*,QString>(textItem,regexp.cap(1));
02486                                                                                 }
02487                                                                                 else
02488                                                                                 {
02489                                                                                         textItem->setPlainText(newNames[i]);
02490                                                                                         newTextItemsNames << QPair<TextGraphicsItem*,QString>(textItem,newNames[i]);
02491                                                                                 }
02492                                                                         }
02493                                                                 }
02494                                                                 else
02495                                                                 if (allhandles[j]->graphicsItems[k])
02496                                                                 {
02497                                                                         allhandles[j]->graphicsItems[k]->update();
02498                                                                 }
02499                                                         }
02500                                                         if (regexp.numCaptures() > 0 && !regexp.cap(1).isEmpty())
02501                                                                 allhandles[j]->name = RemoveDisallowedCharactersFromName(regexp.cap(1));
02502                                                         else
02503                                                                 allhandles[j]->name = RemoveDisallowedCharactersFromName(newNames[i]);
02504 
02505                                                         newItemNames << QPair<ItemHandle*,QString>(allhandles[j],allhandles[j]->name);
02506                                                 }
02507                         }
02508 
02509 
02510                         for (int i=0; i < allhandles.size(); ++i)
02511                                 if (allhandles[i])
02512                                 {
02513                                         QList<QString> keys1 = allhandles[i]->numericalDataNames();
02514                                         QList<QString> keys2 = allhandles[i]->textDataNames();
02515 
02516                                         for (int j=0; j < keys1.size(); ++j)
02517                                                 newData1 += &(allhandles[i]->numericalDataTable( keys1[j] ));
02518 
02519                                         for (int j=0; j < keys2.size(); ++j)
02520                                                 newData2 += &(allhandles[i]->textDataTable( keys2[j] ));
02521                                 }
02522                                 changeDataCommand = new Change2DataCommand<qreal,QString>(QString(""), newData1, oldData1, newData2, oldData2);
02523                                 for (int i=0; i < oldData1.size(); ++i)
02524                                         if (oldData1[i])
02525                                                 delete oldData1[i];
02526                                 for (int i=0; i < oldData2.size(); ++i)
02527                                         if (oldData2[i])
02528                                                 delete oldData2[i];
02529 
02530                         for (int i=0; i < handles.size() && i < newNames.size(); ++i)
02531                         {
02532                                 ItemHandle * handle = handles[i];
02533                                 if (handle)
02534                                 {
02535                                         regexp.indexIn(newNames[i]);
02536                                         for (int j=0; j < handle->graphicsItems.size(); ++j)
02537                                         {
02538                                                 TextGraphicsItem * textItem = qgraphicsitem_cast<TextGraphicsItem*>(handle->graphicsItems[j]);
02539                                                 if (textItem)
02540                                                 {
02541                                                         if (textItem->toPlainText() == handle->name)
02542                                                         {
02543                                                                 oldTextItemsNames << QPair<TextGraphicsItem*,QString>(textItem,handle->name);
02544 
02545                                                                 if (regexp.numCaptures() > 0 && !regexp.cap(1).isEmpty())
02546                                                                 {
02547                                                                         textItem->setPlainText(regexp.cap(1));
02548                                                                         newTextItemsNames << QPair<TextGraphicsItem*,QString>(textItem,regexp.cap(1));
02549                                                                 }
02550                                                                 else
02551                                                                 {
02552                                                                         textItem->setPlainText(newNames[i]);
02553                                                                         newTextItemsNames << QPair<TextGraphicsItem*,QString>(textItem,newNames[i]);
02554                                                                 }
02555 
02556                                                         }
02557                                                 }
02558                                         }
02559 
02560                                         oldItemNames << QPair<ItemHandle*,QString>(handle,handle->name);
02561 
02562                                         if (regexp.numCaptures() > 0 && !regexp.cap(1).isEmpty())
02563                                                 handle->name = RemoveDisallowedCharactersFromName(regexp.cap(1));
02564                                         else
02565                                                 handle->name = RemoveDisallowedCharactersFromName(newNames[i]);
02566 
02567                                         newItemNames << QPair<ItemHandle*,QString>(handle,handle->name);
02568                                 }
02569                         }
02570                 }
02571                 else
02572                 {
02573                         for (int i=0; i < newItemNames.size(); ++i)
02574                                 if (newItemNames[i].first)
02575                                         newItemNames[i].first->name = RemoveDisallowedCharactersFromName(newItemNames[i].second);
02576 
02577                         for (int i=0; i < newTextItemsNames.size(); ++i)
02578                                 if (newTextItemsNames[i].first)
02579                                         newTextItemsNames[i].first->setPlainText(newTextItemsNames[i].second);
02580 
02581                         if (changeDataCommand)
02582                                 changeDataCommand->undo();
02583                 }
02584                 
02585                 NodeGraphicsItem * node;
02586                 ConnectionGraphicsItem * connection;
02587                 TextGraphicsItem * text;
02588                 int k;
02589 
02590                 for (int i=0; i < allhandles.size(); ++i)
02591                 if (allhandles[i])
02592                 {
02593                         QList<QGraphicsItem*> & items2 = allhandles[i]->graphicsItems;
02594                         for (int j=0; j < items2.size(); ++j)
02595                                 if (node = NodeGraphicsItem::cast(items2[j]))
02596                                 {
02597                                         if ((k = oldNames.indexOf(node->groupID)) >= 0 && newNames.size() > k)
02598                                         {
02599                                                 regexp.indexIn(newNames[k]);
02600                                                 if (regexp.numCaptures() > 0 && !regexp.cap(1).isEmpty())
02601                                                         node->groupID = regexp.cap(1);
02602                                                 else                                            
02603                                                         node->groupID = newNames[k];
02604                                         }
02605                                 }
02606                                 else
02607                                 if (connection = ConnectionGraphicsItem::cast(items2[j]))
02608                                 {
02609                                         if ((k = oldNames.indexOf(connection->groupID)) >= 0 && newNames.size() > k)
02610                                         {
02611                                                 regexp.indexIn(newNames[k]);
02612                                                 if (regexp.numCaptures() > 0 && !regexp.cap(1).isEmpty())
02613                                                         connection->groupID = regexp.cap(1);
02614                                                 else                                            
02615                                                         connection->groupID = newNames[k];
02616                                         }
02617                                 }
02618                                 else
02619                                 if (text = TextGraphicsItem::cast(items2[j]))
02620                                 {
02621                                         if ((k = oldNames.indexOf(text->groupID)) >= 0 && newNames.size() > k)
02622                                         {
02623                                                 regexp.indexIn(newNames[k]);
02624                                                 if (regexp.numCaptures() > 0 && !regexp.cap(1).isEmpty())
02625                                                         text->groupID = regexp.cap(1);
02626                                                 else                                            
02627                                                         text->groupID = newNames[k];
02628                                         }
02629                                 }
02630                 }
02631                 /*if (network)
02632                 {
02633                         QList<TextEditor*> editors = network->editors();
02634                         for (int i=0; i < editors.size(); ++i)
02635                                 if (editors[i])
02636                                         for (int j=0; j < oldNames.size() && j < newNames.size(); ++j)
02637                                                 editors[i]->replace(oldNames[j],newNames[j]);
02638                 }*/
02639         }
02640 
02641         void RenameCommand::undo()
02642         {
02643                 for (int i=0; i < oldItemNames.size(); ++i)
02644                                 if (oldItemNames[i].first)
02645                                         oldItemNames[i].first->name = RemoveDisallowedCharactersFromName(oldItemNames[i].second);
02646 
02647                 for (int i=0; i < oldTextItemsNames.size(); ++i)
02648                         if (oldTextItemsNames[i].first)
02649                                 oldTextItemsNames[i].first->setPlainText(oldTextItemsNames[i].second);
02650 
02651                 if (changeDataCommand)
02652                 {
02653                     changeDataCommand->redo();
02654                 }
02655                 
02656                 NodeGraphicsItem * node;
02657                 ConnectionGraphicsItem * connection;
02658                 TextGraphicsItem * text;
02659                 int k;
02660                 
02661                 QRegExp regexp("\\.([^\\.]+)$");
02662                 for (int i=0; i < allhandles.size(); ++i)
02663                 {
02664                         QList<QGraphicsItem*> & items2 = allhandles[i]->graphicsItems;
02665                         for (int j=0; j < items2.size(); ++j)
02666                                 if (node = NodeGraphicsItem::cast(items2[j]))
02667                                 {
02668                                         if ((k = newNames.indexOf(node->groupID)) >= 0 && oldNames.size() > k)
02669                                         {
02670                                                 node->groupID = oldNames[k];
02671                                                 regexp.indexIn(oldNames[k]);
02672                                                 if (regexp.numCaptures() > 0 && !regexp.cap(1).isEmpty())
02673                                                         node->groupID = regexp.cap(1);
02674                                                 else                                            
02675                                                         node->groupID = oldNames[k];
02676                                         }
02677                                 }
02678                                 else
02679                                 if (connection = ConnectionGraphicsItem::cast(items2[j]))
02680                                 {
02681                                         if ((k = newNames.indexOf(connection->groupID)) >= 0 && oldNames.size() > k)
02682                                         {
02683                                                 connection->groupID = oldNames[k];
02684                                                 regexp.indexIn(oldNames[k]);
02685                                                 if (regexp.numCaptures() > 0 && !regexp.cap(1).isEmpty())
02686                                                         connection->groupID = regexp.cap(1);
02687                                                 else                                            
02688                                                         connection->groupID = oldNames[k];
02689                                         }
02690                                 }
02691                                 else
02692                                 if (text = TextGraphicsItem::cast(items2[j]))
02693                                 {
02694                                         if ((k = newNames.indexOf(text->groupID)) >= 0 && oldNames.size() > k)
02695                                         {
02696                                                 regexp.indexIn(oldNames[k]);
02697                                                 if (regexp.numCaptures() > 0 && !regexp.cap(1).isEmpty())
02698                                                         text->groupID = regexp.cap(1);
02699                                                 else                                            
02700                                                         text->groupID = oldNames[k];
02701                                         }
02702                                 }
02703                 }
02704                 
02705                 /*if (network)
02706                 {
02707                         QList<TextEditor*> editors = network->editors();
02708                         for (int i=0; i < editors.size(); ++i)
02709                                 if (editors[i])
02710                                         for (int j=0; j < oldNames.size() && j < newNames.size(); ++j)
02711                                                 editors[i]->replace(newNames[j],oldNames[j]);
02712                 }*/     
02713         }
02714 
02715         CompositeCommand::CompositeCommand(const QString& name, const QList<QUndoCommand*>& list, const QList<QUndoCommand*>& noDelete)
02716                 : QUndoCommand(name)
02717         {
02718                 commands = list;
02719                 doNotDelete = noDelete;
02720 
02721                 for (int i=0; i < noDelete.size(); ++i)
02722                         if (!list.contains(noDelete[i]))
02723                                 commands += noDelete[i];
02724         }
02725 
02726         CompositeCommand::CompositeCommand(const QString& name, QUndoCommand* cmd1, QUndoCommand* cmd2, bool deleteCommand)
02727                 : QUndoCommand(name)
02728         {
02729                 commands += cmd1;
02730                 commands += cmd2;
02731                 if (!deleteCommand)
02732                 {
02733                         doNotDelete += cmd1;
02734                         doNotDelete += cmd2;
02735                 }
02736         }
02737         CompositeCommand::~CompositeCommand()
02738         {
02739                 for (int i=0; i < commands.size(); ++i)
02740                         if (commands[i] && !doNotDelete.contains(commands[i]) && !MainWindow::invalidPointers.contains(commands[i]))
02741                         {
02742                                 MainWindow::invalidPointers[ (void*)commands[i] ] = true;
02743                                 delete commands[i];
02744                         }
02745         }
02746         void CompositeCommand::redo()
02747         {
02748                 for (int i=0; i < commands.size(); ++i)
02749                 {
02750                         if (commands[i])
02751                                 commands[i]->redo();
02752                 }
02753         }
02754         void CompositeCommand::undo()
02755         {
02756                 for (int i=commands.size()-1; i >= 0; --i)
02757                 {
02758                         if (commands[i])
02759                                 commands[i]->undo();
02760                 }
02761         }
02762 
02763         ReverseUndoCommand::ReverseUndoCommand(const QString& name, QUndoCommand* cmd, bool deleteCmd)
02764                 : QUndoCommand(name), command(cmd), deleteCommand(deleteCmd)
02765         {
02766         }
02767         ReverseUndoCommand::~ReverseUndoCommand()
02768         {
02769                 if (command && deleteCommand && !MainWindow::invalidPointers.contains(command)) 
02770                 {
02771                         delete command;
02772                         MainWindow::invalidPointers[ (void*)command ] = true;
02773                 }
02774         }
02775         void ReverseUndoCommand::redo()
02776         {
02777                 if (command) command->undo();
02778         }
02779         void ReverseUndoCommand::undo()
02780         {
02781                 if (command) command->redo();
02782         }
02783 
02784         ReplaceNodeGraphicsCommand::ReplaceNodeGraphicsCommand(const QString& text,NodeGraphicsItem* node,const QString& filename,bool transform)
02785                 : QUndoCommand(text), transform(transform)
02786         {
02787                 if (node && !qgraphicsitem_cast<ToolGraphicsItem*>(node->topLevelItem()))
02788                 {
02789                         targetNodes += node;
02790                         NodeGraphicsItem copy1(*node);
02791                         oldNodes += copy1;
02792 
02793                         NodeGraphicsItem copy2(*node);
02794                         loadFromFile(&copy2,filename);
02795                         newNodes += copy2;
02796                 }
02797         }
02798 
02799         ReplaceNodeGraphicsCommand::ReplaceNodeGraphicsCommand(const QString& text,const QList<NodeGraphicsItem*>& nodes,const QList<QString>& filenames, bool transform)
02800                 : QUndoCommand(text), transform(transform)
02801         {
02802                 for (int i=0; i < nodes.size() && i < filenames.size(); ++i)
02803                 {
02804                         NodeGraphicsItem * node = nodes[i];
02805                         QString filename = filenames[i];
02806                         if (node && !qgraphicsitem_cast<ToolGraphicsItem*>(node->topLevelItem()))
02807                         {
02808                                 targetNodes += node;
02809                                 NodeGraphicsItem copy1(*node);
02810                                 setHandle(&copy1,0);
02811                                 oldNodes += copy1;
02812 
02813                                 NodeGraphicsItem copy2(*node);
02814                                 setHandle(&copy2,0);
02815                                 loadFromFile(&copy2,filename);
02816                                 newNodes += copy2;
02817                         }
02818                 }
02819         }
02820 
02821         ReplaceNodeGraphicsCommand::~ReplaceNodeGraphicsCommand()
02822         {
02823                 for (int i=0; i < itemsToDelete.size(); ++i)
02824                         if (itemsToDelete[i] && !MainWindow::invalidPointers.contains( (void*)itemsToDelete[i]))
02825                         {
02826                                 if (itemsToDelete[i]->scene())
02827                                         itemsToDelete[i]->scene()->removeItem(itemsToDelete[i]);
02828                                 
02829                                 MainWindow::invalidPointers[ (void*)itemsToDelete[i] ] = true;
02830                                 delete itemsToDelete[i];
02831                         }
02832         }
02833 
02834         void ReplaceNodeGraphicsCommand::redo()
02835         {
02836                 for (int i=0; i < targetNodes.size(); ++i)
02837                 {
02838                         if (targetNodes[i])
02839                         {
02840                                 for (int j=0; j < targetNodes[i]->shapes.size(); ++j)
02841                                         if (!itemsToDelete.contains(targetNodes[i]->shapes[j]) && targetNodes[i]->shapes[j])
02842                                         {
02843                                                 itemsToDelete << targetNodes[i]->shapes[j];
02844                                         }
02845 
02846                                         for (int j=0; j < targetNodes[i]->controlPoints.size(); ++j)
02847                                                 if (!itemsToDelete.contains(targetNodes[i]->controlPoints[j]) && targetNodes[i]->controlPoints[j])
02848                                                 {
02849                                                         itemsToDelete << targetNodes[i]->controlPoints[j];
02850                                                 }
02851 
02852                                                 for (int j=0; j < targetNodes[i]->boundaryControlPoints.size(); ++j)
02853                                                         if (!itemsToDelete.contains(targetNodes[i]->boundaryControlPoints[j]) && targetNodes[i]->boundaryControlPoints[j])
02854                                                         {
02855                                                                 itemsToDelete << targetNodes[i]->boundaryControlPoints[j];
02856                                                         }
02857 
02858                                 targetNodes[i]->shapes.clear();
02859                                 targetNodes[i]->controlPoints.clear();
02860                                 targetNodes[i]->boundaryControlPoints.clear();
02861 
02862                                 (*targetNodes[i]) = newNodes[i];
02863                                 ArrowHeadItem * arrow = ArrowHeadItem::cast(targetNodes[i]);
02864                                 if (arrow)
02865                                 {
02866                                         if (arrow->connectionItem)
02867                                                 arrow->connectionItem->refresh(false);
02868                                 }
02869                         }
02870                 }
02871                 for (int i=0; i < itemsToDelete.size(); ++i)
02872                         if (itemsToDelete[i] && itemsToDelete[i]->scene())
02873                                 itemsToDelete[i]->scene()->removeItem(itemsToDelete[i]);
02874         }
02875         void ReplaceNodeGraphicsCommand::undo()
02876         {
02877                 for (int i=0; i < targetNodes.size(); ++i)
02878                 {
02879                         if (targetNodes[i])
02880                         {
02881                                 for (int j=0; j < targetNodes[i]->shapes.size(); ++j)
02882                                         if (!itemsToDelete.contains(targetNodes[i]->shapes[j]) && targetNodes[i]->shapes[j])
02883                                         {
02884                                                 itemsToDelete << targetNodes[i]->shapes[j];
02885                                         }
02886 
02887                                         for (int j=0; j < targetNodes[i]->controlPoints.size(); ++j)
02888                                                 if (!itemsToDelete.contains(targetNodes[i]->controlPoints[j]) && targetNodes[i]->controlPoints[j])
02889                                                 {
02890                                                         itemsToDelete << targetNodes[i]->controlPoints[j];
02891                                                 }
02892 
02893                                                 for (int j=0; j < targetNodes[i]->boundaryControlPoints.size(); ++j)
02894                                                         if (!itemsToDelete.contains(targetNodes[i]->boundaryControlPoints[j]) && targetNodes[i]->boundaryControlPoints[j])
02895                                                         {
02896                                                                 itemsToDelete << targetNodes[i]->boundaryControlPoints[j];
02897                                                         }
02898 
02899                                 targetNodes[i]->shapes.clear();
02900                                 targetNodes[i]->controlPoints.clear();
02901                                 targetNodes[i]->boundaryControlPoints.clear();
02902 
02903                                 (*targetNodes[i]) = oldNodes[i];
02904                                 ArrowHeadItem * arrow = ArrowHeadItem::cast(targetNodes[i]);
02905                                 if (arrow)
02906                                 {
02907                                         if (arrow->connectionItem)
02908                                                 arrow->connectionItem->refresh();
02909                                 }
02910                         }
02911                 }
02912                 for (int i=0; i < itemsToDelete.size(); ++i)
02913                         if (itemsToDelete[i] && itemsToDelete[i]->scene())
02914                                 itemsToDelete[i]->scene()->removeItem(itemsToDelete[i]);
02915         }
02916         void ReplaceNodeGraphicsCommand::loadFromFile(NodeGraphicsItem* node,const QString& fileName)
02917         {
02918                 if (!node) return;
02919 
02920                 QFile file (fileName);
02921 
02922                 QString  home = GlobalSettings::homeDir(),
02923                                 temp = GlobalSettings::tempDir(),
02924                                 current = QDir::currentPath(),
02925                                 appDir = QCoreApplication::applicationDirPath();
02926 
02927                 QString name[] = {  
02928                         fileName,
02929                         home + QObject::tr("/") + fileName,
02930                         temp + QObject::tr("/") + fileName,
02931                         current + QObject::tr("/") + fileName,
02932                         appDir + QObject::tr("/") + fileName,
02933                 };
02934 
02935                 for (int i=0; i < 5; ++i)
02936                 {
02937                         file.setFileName(name[i]);
02938                         if (file.exists())
02939                                 break;
02940                 }
02941 
02942                 if (!file.open(QFile::ReadOnly | QFile::Text))
02943                 {
02944                         return;
02945                 }
02946 
02947                 node->setParentItem(0);
02948 
02949                 QPointF p = node->scenePos();
02950                 QTransform t0 = node->sceneTransform();
02951                 QTransform t1(t0.m11(),t0.m12(),0,t0.m21(),t0.m22(),0,0,0,1);
02952 
02953                 node->setBoundingBoxVisible(false);
02954                 node->clear();
02955                 node->setPos(QPointF());
02956                 node->resetTransform();
02957                 
02958                 NodeGraphicsReader reader;
02959                 reader.readNodeGraphics(node,&file);
02960                 node->normalize();
02961 
02962                 node->setPos(p);
02963                 
02964                 if (transform)
02965                 {
02966                         node->setTransform(t1);
02967                 }
02968                 else
02969                 {
02970                         QRectF rect = node->boundingRect();
02971                         QTransform t(node->defaultSize.width()/rect.width(), 0, 0, node->defaultSize.height()/rect.height(), 0, 0);
02972                         node->setTransform(t);
02973                 }
02974 
02975                 //node->setParentItem(parent);
02976         }
02977 
02978         AssignHandleCommand::AssignHandleCommand(const QString& text, const QList<QGraphicsItem*>& items, QList<ItemHandle*>& handles)
02979                 : QUndoCommand(text)
02980         {
02981                 ItemHandle * handle = 0;
02982 
02983                 for (int i=0; i < items.size() && i < handles.size(); ++i)
02984                         if (items[i])
02985                         {
02986                                 graphicsItems += items[i];
02987 
02988                                 handle = getHandle(items[i]);
02989 
02990                                 oldHandles += handle;
02991                                 newHandles += handles[i];
02992 
02993                                 oldItemHandles += QPair< QGraphicsItem*, ItemHandle* >(items[i], handle);
02994                                 newItemHandles += QPair< QGraphicsItem*, ItemHandle* >(items[i], handles[i]);
02995                         }
02996         }
02997 
02998         AssignHandleCommand::AssignHandleCommand(const QString& text, const QList<QGraphicsItem*>& items, ItemHandle* newHandle)
02999                 : QUndoCommand(text)
03000         {
03001 
03002                 ItemHandle * handle = 0;
03003                 for (int i=0; i < items.size(); ++i)
03004                         if (items[i])
03005                         {
03006                                 graphicsItems += items[i];
03007                                 handle = getHandle(items[i]);
03008 
03009                                 oldHandles += handle;
03010                                 newHandles += newHandle;
03011 
03012                                 oldItemHandles += QPair< QGraphicsItem*, ItemHandle* >( items[i], handle );
03013                                 newItemHandles += QPair< QGraphicsItem*, ItemHandle* >( items[i], newHandle );
03014                         }
03015 
03016         }
03017 
03018         AssignHandleCommand::AssignHandleCommand(const QString& text, QGraphicsItem* item, ItemHandle* newHandle)
03019                 : QUndoCommand(text)
03020         {
03021                 graphicsItems += item;
03022                 ItemHandle * handle = getHandle(item);
03023 
03024                 oldHandles += handle;
03025                 newHandles += newHandle;
03026 
03027                 oldItemHandles += QPair< QGraphicsItem*, ItemHandle* >( item, handle );
03028                 newItemHandles += QPair< QGraphicsItem*, ItemHandle* >( item, newHandle );
03029         }
03030 
03031         void AssignHandleCommand::redo()
03032         {
03033                 TextGraphicsItem* textItem = 0;
03034                 ItemHandle * handle = 0;
03035                 for (int i=0; i < newItemHandles.size(); ++i)
03036                 {
03037                         if (newItemHandles[i].first)
03038                         {
03039                                 handle = getHandle(newItemHandles[i].first);
03040                                 if ((textItem = qgraphicsitem_cast<TextGraphicsItem*>(newItemHandles[i].first)) &&
03041                                         handle && textItem->toPlainText() == handle->name &&
03042                                         newItemHandles[i].second)
03043                                         textItem->setPlainText(newItemHandles[i].second->name);
03044                                 setHandle(newItemHandles[i].first, newItemHandles[i].second);
03045                         }
03046                 }
03047         }
03048 
03049         void AssignHandleCommand::undo()
03050         {
03051                 TextGraphicsItem* textItem = 0;
03052                 ItemHandle * handle = 0;
03053                 for (int i=0; i < oldItemHandles.size(); ++i)
03054                 {
03055                         if (oldItemHandles[i].first)
03056                         {
03057                                 handle = getHandle(oldItemHandles[i].first);
03058                                 if ((textItem = qgraphicsitem_cast<TextGraphicsItem*>(oldItemHandles[i].first)) &&
03059                                         handle && textItem->toPlainText() == handle->name &&
03060                                         oldItemHandles[i].second)
03061                                         textItem->setPlainText(oldItemHandles[i].second->name);
03062                                 setHandle(oldItemHandles[i].first, oldItemHandles[i].second);
03063                         }
03064                 }
03065         }
03066 
03067         AssignHandleCommand::~AssignHandleCommand()
03068         {
03069                 oldHandles << newHandles;
03070                 for (int i=0; i < oldHandles.size(); ++i)
03071                         if (oldHandles[i] && !MainWindow::invalidPointers.contains( (void*)oldHandles[i]))
03072                         {
03073                                 bool pointedTo = false;
03074                                 for (int j=0; j < oldHandles[i]->graphicsItems.size(); ++j)
03075                                         if (getHandle(oldHandles[i]->graphicsItems[j]) == oldHandles[i])
03076                                         {
03077                                                 pointedTo = true;
03078                                                 break;
03079                                         }
03080                                         if (!pointedTo)
03081                                         {
03082                                                 for (int j=0; j < oldHandles.size(); ++j)
03083                                                         if (i != j && oldHandles[j] == oldHandles[i])
03084                                                                 oldHandles[j] = 0;
03085 
03086                                                 oldHandles[i]->graphicsItems.clear();
03087                                                 
03088                                                 MainWindow::invalidPointers[ (void*)oldHandles[i] ] = true;
03089                                                 delete oldHandles[i];
03090                                                 oldHandles[i] = 0;
03091                                         }
03092                         }
03093         }
03094 
03095         MergeHandlesCommand::MergeHandlesCommand(const QString& text, const QList<ItemHandle*>& allHandles, const QList<ItemHandle*>& handles) :
03096                 QUndoCommand(text)
03097         {
03098                 init(0,allHandles,handles);
03099         }
03100 
03101         MergeHandlesCommand::MergeHandlesCommand(const QString& text, NetworkHandle * net, const QList<ItemHandle*>& handles) :
03102                 QUndoCommand(text)
03103         {
03104                 init(net, net->handles(), handles);
03105         }
03106 
03107         void MergeHandlesCommand::init(NetworkHandle * net, const QList<ItemHandle*>& allItems, const QList<ItemHandle*>& handles)
03108         {
03109                 newHandle = 0;
03110                 setFamilyCommand = 0;
03111                 oldHandles = handles;
03112                 
03113                 QStringList oldNames, newNames;
03114                 ItemFamily * lowestFamily = 0, * family = 0;
03115 
03116                 if (handles.size() > 0)
03117                 {
03118                         for (int i=0; i < handles.size(); ++i)
03119                                 if (handles[i])
03120                                 {
03121                                         newHandle = handles[i];
03122                                         oldHandles.removeAll(newHandle);
03123                                         break;
03124                                 }
03125                 }
03126 
03127                 for (int i =0; i < handles.size(); ++i)
03128                         if (handles[i])
03129                         {
03130                                 if (handles[i] != newHandle)
03131                                         oldNames << handles[i]->fullName();
03132                                 family = handles[i]->family();
03133                                 if (family && (!lowestFamily || family->depth() > lowestFamily->depth()))
03134                                         lowestFamily = family;
03135                         }
03136 
03137                 if (lowestFamily)
03138                 {
03139                         QList<ItemFamily*> families;
03140                         while (families.size() < handles.size())
03141                                 families << lowestFamily;
03142                         setFamilyCommand = new SetHandleFamilyCommand(QObject::tr("set families to lowest"), handles, families);
03143                 }
03144 
03145                 if (newHandle)
03146                         for (int i=0; i < oldNames.size(); ++i)
03147                                 newNames << newHandle->fullName();
03148 
03149                 QList<ItemHandle*> allHandles = allItems;
03150 
03151                 for (int i=0; i < handles.size(); ++i)
03152                         allHandles.removeAll(handles[i]);
03153 
03154                 allHandles << newHandle;
03155 
03156                 renameCommand = 0;
03157                 changeDataCommand = 0;
03158 
03159                 if (newHandle)
03160                 {
03161                         QStringList list, keys;
03162                         QList<NumericalDataTable*> newNumericTables, oldNumericTables;
03163                         QList<TextDataTable*> newTextTables, oldTextTables;
03164                         NumericalDataTable* nDat;
03165                         TextDataTable* sDat;
03166 
03167                         for (int i=0; i < handles.size(); ++i)
03168                                 if (handles[i])
03169                                 {
03170                                         list = handles[i]->numericalDataNames();
03171                                         for (int j=0; j < list.size(); ++j)
03172                                                 if (!keys.contains(list[j]))
03173                                                         keys << list[j];
03174                                 }
03175                         
03176                         for (int j=0; j < keys.size(); ++j)
03177                         {
03178                                 oldNumericTables << &(newHandle->numericalDataTable(keys[j]));
03179                                 nDat = new NumericalDataTable(newHandle->numericalDataTable(keys[j]));
03180                                 newNumericTables << nDat;
03181 
03182                                 for (int i=0; i < handles.size(); ++i)
03183                                         if (handles[i] && handles[i]->hasNumericalData(keys[j]))
03184                                         {
03185                                                 NumericalDataTable & dat = handles[i]->numericalDataTable(keys[j]);
03186                                                 for (int r=0; r < dat.rows(); ++r)
03187                                                         if (!nDat->hasRow(dat.rowName(r)))
03188                                                                 for (int c=0; c < dat.columns(); ++c)
03189                                                                         nDat->value(dat.rowName(r), c) = dat.value(r,c);
03190                                         }
03191                         }
03192                         
03193                         keys.clear();
03194                         for (int i=0; i < handles.size(); ++i)
03195                                 if (handles[i])
03196                                 {
03197                                         list = handles[i]->textDataNames();
03198                                         for (int j=0; j < list.size(); ++j)
03199                                                 if (!keys.contains(list[j]))
03200                                                         keys << list[j];
03201                                 }
03202                         
03203                         for (int j=0; j < keys.size(); ++j)
03204                         {
03205                                 oldTextTables << &(newHandle->textDataTable(keys[j]));
03206                                 sDat = new TextDataTable(newHandle->textDataTable(keys[j]));
03207                                 newTextTables << sDat;
03208 
03209                                 for (int i=0; i < handles.size(); ++i)
03210                                         if (handles[i] && handles[i]->hasTextData(keys[j]))
03211                                         {
03212                                                 TextDataTable & dat = handles[i]->textDataTable(keys[j]);
03213                                                 for (int r=0; r < dat.rows(); ++r)
03214                                                         if (!sDat->hasRow(dat.rowName(r)))
03215                                                                 for (int c=0; c < dat.columns(); ++c)
03216                                                                         sDat->value(dat.rowName(r), dat.columnName(c)) = dat.value(r,c);
03217                                         }
03218                         }
03219                         
03220                         changeDataCommand = new Change2DataCommand<qreal,QString>(QString(""), oldNumericTables, newNumericTables, oldTextTables, newTextTables);
03221 
03222                         for (int i=0; i < newNumericTables.size(); ++i)
03223                                 delete newNumericTables[i];
03224                         
03225                         for (int i=0; i < newTextTables.size(); ++i)
03226                                 delete newTextTables[i];
03227                         
03228                         renameCommand = new RenameCommand(QString("rename"),net,allHandles,oldNames,newNames,false);
03229                 }
03230         }
03231 
03232         MergeHandlesCommand::~MergeHandlesCommand()
03233         {
03234                 if (renameCommand)
03235                         delete renameCommand;
03236                 
03237                 if (changeDataCommand)
03238                         delete changeDataCommand;
03239 
03240                 if (setFamilyCommand)
03241                         delete setFamilyCommand;
03242         }
03243 
03244         void MergeHandlesCommand::redo()
03245         {
03246                 if (newHandle == 0) return;
03247 
03248                 allChildren.clear();
03249                 allGraphicsItems.clear();
03250 
03251                 for (int i=0; i < oldHandles.size(); ++i)
03252                         if (oldHandles[i])
03253                         {
03254                                 oldParents[ oldHandles[i] ] = oldHandles[i]->parent;
03255                                 oldHandles[i]->setParent(0,false);
03256                                 
03257                                 oldChildren[ oldHandles[i] ] = oldHandles[i]->children;
03258                                 allChildren << oldHandles[i]->children;
03259 
03260                                 oldGraphicsItems[ oldHandles[i] ] = oldHandles[i]->graphicsItems;
03261                                 allGraphicsItems << oldHandles[i]->graphicsItems;
03262                         }
03263 
03264                 for (int i=0; i < allChildren.size(); ++i)
03265                         if (allChildren[i])
03266                                 allChildren[i]->setParent(newHandle,false);
03267 
03268                 TextGraphicsItem * textItem = 0;
03269                 ItemHandle * handle = 0;
03270                         
03271                 for (int i=0; i < allGraphicsItems.size(); ++i)
03272                         if (allGraphicsItems[i])
03273                         {
03274                                 handle = getHandle(allGraphicsItems[i]);
03275 
03276                                 if (    handle &&
03277                                                 (textItem = qgraphicsitem_cast<TextGraphicsItem*>(allGraphicsItems[i])) &&
03278                                                 (textItem->toPlainText() == handle->name || textItem->toPlainText() == handle->fullName()) )
03279                                                 textItem->setPlainText(newHandle->name);
03280 
03281                                 setHandle(allGraphicsItems[i],newHandle);
03282                         }
03283 
03284                 if (changeDataCommand)
03285                         changeDataCommand->redo();
03286 
03287                 if (renameCommand)
03288                         renameCommand->redo();
03289 
03290                 if (setFamilyCommand)
03291                         setFamilyCommand->redo();
03292         }
03293 
03294         void MergeHandlesCommand::undo()
03295         {
03296                 if (newHandle == 0) return;
03297 
03298                 if (renameCommand)
03299                         renameCommand->undo();
03300 
03301                 if (changeDataCommand)
03302                         changeDataCommand->redo();
03303 
03304                 if (setFamilyCommand)
03305                         setFamilyCommand->undo();
03306 
03307                 QList<ItemHandle*> keyHandles = oldChildren.keys();
03308                 for (int i=0; i < keyHandles.size(); ++i)
03309                         if (keyHandles[i])
03310                         {
03311                                 QList<ItemHandle*> children = oldChildren[ keyHandles[i] ];
03312                                 for (int j=0; j < children.size(); ++j)
03313                                         if (children[j])
03314                                                 children[j]->setParent(keyHandles[i],false);
03315                         }
03316                 
03317                 keyHandles = oldParents.keys();
03318                 for (int i=0; i < keyHandles.size(); ++i)
03319                         if (keyHandles[i])
03320                         {
03321                                 keyHandles[i]->setParent( oldParents[ keyHandles[i] ], false );
03322                         }
03323 
03324                 TextGraphicsItem * textItem = 0;
03325                 ItemHandle * handle = 0;
03326 
03327                 keyHandles = oldGraphicsItems.keys();
03328 
03329                 for (int i=0; i < keyHandles.size(); ++i)
03330                         if (keyHandles[i])
03331                         {
03332                                 QList<QGraphicsItem*> items = oldGraphicsItems[ keyHandles[i] ];
03333                                 for (int j=0; j < items.size(); ++j)
03334                                         if (items[j])
03335                                         {
03336                                                 handle = getHandle(items[j]);
03337 
03338                                                 if (    handle &&
03339                                                                 (textItem = qgraphicsitem_cast<TextGraphicsItem*>(items[j])) &&
03340                                                                 (textItem->toPlainText() == handle->name || textItem->toPlainText() == handle->fullName()) )
03341                                                                 textItem->setPlainText(keyHandles[i]->name);
03342 
03343                                                 setHandle(items[j],keyHandles[i]);
03344                                         }
03345                         }
03346         }
03347 
03348         SetParentHandleCommand::SetParentHandleCommand(const QString& name, NetworkHandle * net, ItemHandle * child, ItemHandle * parent)
03349                 : QUndoCommand(name)
03350         {
03351                 this->net = net;
03352                 children += child;
03353                 newParents += parent;
03354                 oldParents += child->parent;
03355                 renameCommand = 0;
03356         }
03357 
03358         SetParentHandleCommand::SetParentHandleCommand(const QString& name, NetworkHandle * net, const QList<ItemHandle*>& childlist, const QList<ItemHandle*>& parents)
03359                 : QUndoCommand(name)
03360         {
03361                 this->net = net;
03362                 
03363                 for (int i=0; i < childlist.size() && i < parents.size(); ++i)
03364                         if (childlist[i] && !children.contains(childlist[i]))
03365                         {
03366                                 children += childlist[i];
03367                                 newParents += parents[i];
03368                                 if (childlist[i])
03369                                         oldParents += childlist[i]->parent;
03370                                 else
03371                                         oldParents += 0;
03372                         }
03373                 renameCommand = 0;
03374         }
03375 
03376         SetParentHandleCommand::SetParentHandleCommand(const QString& name, NetworkHandle * net, const QList<ItemHandle*>& childlist, ItemHandle * parent)
03377                 : QUndoCommand(name)
03378         {
03379                 this->net = net;
03380                 
03381                 for (int i=0; i < childlist.size(); ++i)
03382                         if (childlist[i] && !children.contains(childlist[i]))
03383                         {
03384                                 children += childlist[i];
03385                                 newParents += parent;
03386                                 if (childlist[i])
03387                                         oldParents += childlist[i]->parent;
03388                                 else
03389                                         oldParents += 0;
03390                         }
03391                 renameCommand = 0;
03392         }
03393 
03394         SetParentHandleCommand::~SetParentHandleCommand()
03395         {
03396                 if (renameCommand)
03397                         delete renameCommand;
03398                 /*for (int i=0; i < children.size(); ++i)
03399                         if (children[i] && !MainWindow::invalidPointers.contains((void*)children[i]))
03400                         {
03401                                 delete children[i];
03402                                 MainWindow::invalidPointers[ (void*)children[i] ] = true;
03403                                 children[i] = 0;
03404                         }*/
03405         }
03406 
03407         void SetParentHandleCommand::redo()
03408         {
03409                 if (!renameCommand && net)
03410                 {
03411                         QList<QString> newNames, oldNames;
03412                         QStringList allNames;
03413                         QString s0, s1;
03414                         
03415                         for (int i=0; i < children.size() && i < newParents.size() && i < oldParents.size(); ++i)
03416                                 if (children[i] && newParents[i] != oldParents[i])
03417                                 {
03418                                         if (children[i] != newParents[i] && !children[i]->isChildOf(newParents[i]))
03419                                         {
03420                                                 children[i]->setParent(newParents[i],false);
03421                                                 s1 = net->makeUnique(children[i],allNames);                                             
03422                                                 children[i]->setParent(oldParents[i],false);
03423                                                 s0 = children[i]->fullName();
03424                                                 if (s0 != s1)
03425                                                 {
03426                                                         oldNames += s0;
03427                                                         newNames += s1;
03428                                                 }
03429                                                 allNames += s1;
03430                                         }
03431                                 }
03432                         renameCommand = new RenameCommand(QString("rename"),net,oldNames,newNames);
03433                 }
03434 
03435                 if (renameCommand)
03436                         renameCommand->redo();
03437                 
03438                 for (int i=0; i < children.size() && i < newParents.size() && i < oldParents.size(); ++i)
03439                         if (children[i] && newParents[i] != oldParents[i])
03440                         {
03441                                 if (children[i] != newParents[i] && !children[i]->isChildOf(newParents[i]))
03442                                 {
03443                                         children[i]->setParent(newParents[i],false);
03444                                 }
03445                         }
03446         }
03447 
03448         void SetParentHandleCommand::undo()
03449         {
03450                 if (renameCommand)
03451                         renameCommand->undo();
03452                         
03453                 for (int i=0; i < children.size() && i < newParents.size() && i < oldParents.size(); ++i)
03454                         if (children[i] && newParents[i] != oldParents[i])
03455                         {
03456                                 if (children[i] != oldParents[i] && !children[i]->isChildOf(oldParents[i]))
03457                                 {
03458                                         children[i]->setParent(oldParents[i],false);
03459                                 }
03460                         }
03461         }
03462 
03463         SetGraphicsSceneVisibilityCommand::SetGraphicsSceneVisibilityCommand(const QString& name, const QList<QGraphicsItem*>& list, const QList<bool>& values)
03464                 : QUndoCommand(name)
03465         {
03466                 ConnectionGraphicsItem * connection;
03467                 NodeGraphicsItem * node;
03468                 for (int i=0; i < list.size() && i < values.size(); ++i)
03469                 {
03470                         if (list[i] && list[i]->isVisible() != values[i])
03471                         {
03472                                 items << list[i];
03473                                 before << list[i]->isVisible();
03474                                 if (connection = ConnectionGraphicsItem::cast(list[i]))
03475                                 {
03476                                         QList<QGraphicsItem*> list2 = connection->controlPointsAsGraphicsItems();
03477                                         list2 << connection->arrowHeadsAsGraphicsItems();
03478                                         if (connection->centerRegionItem)
03479                                                 list2 << connection->centerRegionItem;
03480                                         for (int j=0; j < list2.size(); ++j)
03481                                                 if (list2[j] && list[i]->isVisible() == list2[j]->isVisible())
03482                                                 {
03483                                                         items << list2[j];
03484                                                         before << list[i]->isVisible();
03485                                                 }
03486                                 }
03487                                 else
03488                                 if (node = NodeGraphicsItem::cast(list[i]))
03489                                 {
03490                                         QList<ControlPoint*> list2 = node->allControlPoints();
03491                                         for (int j=0; j < list2.size(); ++j)
03492                                                 if (list2[j] && list[i]->isVisible() == list2[j]->isVisible())
03493                                                 {
03494                                                         items << list2[j];
03495                                                         before << list[i]->isVisible();
03496                                                 }
03497                                 }
03498                         }
03499                 }
03500         }
03501 
03502         SetGraphicsSceneVisibilityCommand::SetGraphicsSceneVisibilityCommand(const QString& name, QGraphicsItem* item, bool value)
03503                 : QUndoCommand(name)
03504         {
03505                 if (item && item->isVisible() != value)
03506                 {
03507                         ConnectionGraphicsItem * connection;
03508                         NodeGraphicsItem * node;
03509                         
03510                         items << item;
03511                         before << item->isVisible();
03512                         
03513                         if (connection = ConnectionGraphicsItem::cast(item))
03514                         {
03515                                 QList<QGraphicsItem*> list2 = connection->controlPointsAsGraphicsItems();
03516                                 list2 << connection->arrowHeadsAsGraphicsItems();
03517                                 if (connection->centerRegionItem)
03518                                         list2 << connection->centerRegionItem;
03519                                 for (int j=0; j < list2.size(); ++j)
03520                                         if (list2[j] && item->isVisible() == list2[j]->isVisible())
03521                                         {
03522                                                 items << list2[j];
03523                                                 before << item->isVisible();
03524                                         }
03525                         }
03526                         else
03527                         if (node = NodeGraphicsItem::cast(item))
03528                         {
03529                                 QList<ControlPoint*> list2 = node->allControlPoints();
03530                                 for (int j=0; j < list2.size(); ++j)
03531                                         if (list2[j] && item->isVisible() == list2[j]->isVisible())
03532                                         {
03533                                                 items << list2[j];
03534                                                 before << item->isVisible();
03535                                         }
03536                         }
03537                 }
03538         }
03539 
03540         SetGraphicsSceneVisibilityCommand::SetGraphicsSceneVisibilityCommand(const QString& name, const QList<QGraphicsItem*>& list, bool value)
03541                 : QUndoCommand(name)
03542         {
03543                 ConnectionGraphicsItem * connection;
03544                 NodeGraphicsItem * node;
03545                 for (int i=0; i < list.size(); ++i)
03546                 {
03547                         if (list[i] && list[i]->isVisible() != value)
03548                         {
03549                                 items << list[i];
03550                                 before << list[i]->isVisible();
03551                                 
03552                                 if (connection = ConnectionGraphicsItem::cast(list[i]))
03553                                 {
03554                                         QList<QGraphicsItem*> list2 = connection->controlPointsAsGraphicsItems();
03555                                         list2 << connection->arrowHeadsAsGraphicsItems();
03556                                         if (connection->centerRegionItem)
03557                                                 list2 << connection->centerRegionItem;
03558                                         for (int j=0; j < list2.size(); ++j)
03559                                                 if (list2[j] && list[i]->isVisible() == list2[j]->isVisible())
03560                                                 {
03561                                                         items << list2[j];
03562                                                         before << list[i]->isVisible();
03563                                                 }
03564                                 }
03565                                 else
03566                                 if (node = NodeGraphicsItem::cast(list[i]))
03567                                 {
03568                                         QList<ControlPoint*> list2 = node->allControlPoints();
03569                                         for (int j=0; j < list2.size(); ++j)
03570                                                 if (list2[j] && list[i]->isVisible() == list2[j]->isVisible())
03571                                                 {
03572                                                         items << list2[j];
03573                                                         before << list[i]->isVisible();
03574                                                 }
03575                                 }
03576                         }
03577                 }
03578         }
03579 
03580         void SetGraphicsSceneVisibilityCommand::redo()
03581         {
03582                 for (int i=0; i < items.size() && i < before.size(); ++i)
03583                 {
03584                         items[i]->setVisible(!before[i]);
03585                 }
03586         }
03587 
03588         void SetGraphicsSceneVisibilityCommand::undo()
03589         {
03590                 for (int i=0; i < items.size() && i < before.size(); ++i)
03591                 {
03592                         items[i]->setVisible(before[i]);
03593                 }
03594         }
03595         
03596         SetHandleFamilyCommand::SetHandleFamilyCommand(const QString& name, const QList<ItemHandle*>& items, const QList<ItemFamily*>& families) 
03597                 : QUndoCommand(name)
03598         {
03599                 for (int i=0; i < items.size() && i < families.size(); ++i)
03600                         if (items[i])
03601                         {
03602                                 handles << items[i];
03603                                 oldFamily << items[i]->family();
03604                                 newFamily << families[i];
03605                         }
03606         }
03607         
03608         SetHandleFamilyCommand::SetHandleFamilyCommand(const QString& name, ItemHandle* item, ItemFamily* family)
03609         {
03610                 if (item)
03611                 {
03612                         handles << item;
03613                         oldFamily << item->family();
03614                         newFamily << family;
03615                 }
03616         }
03617         
03618         void SetHandleFamilyCommand::redo()
03619         {
03620                 for (int i=0; i < handles.size() && i < newFamily.size(); ++i)
03621                         if (handles[i])                 
03622                                 handles[i]->setFamily(newFamily[i],false);
03623         }
03624         
03625         void SetHandleFamilyCommand::undo()
03626         {
03627                 for (int i=0; i < handles.size() && i < oldFamily.size(); ++i)
03628                         if (handles[i])                 
03629                                 handles[i]->setFamily(oldFamily[i],false);
03630         }
03631         
03632                 RemoveCurveSegmentCommand::RemoveCurveSegmentCommand(
03633                 const QString& name, GraphicsScene * scene,
03634                 ConnectionGraphicsItem::ControlPoint* item)
03635                 : QUndoCommand(name)
03636         {
03637                 curveSegments.clear();
03638                 graphicsScene = scene;
03639                 connectionItem = item->connectionItem;
03640                 if (connectionItem == 0 || connectionItem->curveSegments.size() < 2) return;
03641                 
03642                 QList<ArrowHeadItem*> arrowHeads = connectionItem->arrowHeads();
03643                 int only_in_node = -1, only_out_node = -1;
03644                 for (int i=0; i < arrowHeads.size(); ++i)
03645                 {
03646                         if (arrowHeads[i] == 0)
03647                         {
03648                                 if (only_in_node == -1)
03649                                         only_in_node = i;
03650                                 else
03651                                 {
03652                                         only_in_node = -1;
03653                                         break;
03654                                 }
03655                         }
03656                 }
03657                 for (int i=0; i < arrowHeads.size(); ++i)
03658                 {
03659                         if (arrowHeads[i] != 0)
03660                         {
03661                                 if (only_out_node == -1)
03662                                         only_out_node = i;
03663                                 else
03664                                 {
03665                                         only_out_node = -1;
03666                                         break;
03667                                 }
03668                         }
03669                 }
03670 
03671                 for (int i=0; i < connectionItem->curveSegments.size(); ++i)
03672                 {
03673                         for (int j=0; j < connectionItem->curveSegments[i].size(); ++j)
03674                         {
03675                                 if (connectionItem->curveSegments[i][j] != 0 && connectionItem->curveSegments[i][j] == item)
03676                                 {
03677                                         if (i != only_in_node && i != only_out_node)
03678                                         {
03679                                                 curveSegments.append(connectionItem->curveSegments[i]);
03680                                                 if (connectionItem->curveSegments[i][0])
03681                                                         parentsAtStart.append(connectionItem->curveSegments[i][0]->parentItem());
03682                                                 else
03683                                                         parentsAtStart.append(0);
03684                                                 if (connectionItem->curveSegments[i].last())
03685                                                         parentsAtEnd.append(connectionItem->curveSegments[i].last()->parentItem());
03686                                                 else
03687                                                         parentsAtEnd.append(0);
03688                                         }
03689                                         break;
03690                                 }
03691                         }
03692                 }
03693         }
03694 
03695         RemoveCurveSegmentCommand::RemoveCurveSegmentCommand(
03696                 const QString& name, GraphicsScene * scene,
03697                 ConnectionGraphicsItem* connection,
03698                 QList<ConnectionGraphicsItem::ControlPoint*> items)
03699                 : QUndoCommand(name)
03700         {
03701                 curveSegments.clear();
03702                 graphicsScene = scene;
03703                 connectionItem = connection;
03704                 if (connectionItem == 0 || connectionItem->curveSegments.size() < 2) return;
03705 
03706                 bool done = false;
03707                 for (int i=0; i < connectionItem->curveSegments.size(); ++i)
03708                 {
03709                         done = false;
03710                         for (int j=0; j < connectionItem->curveSegments[i].size(); ++j)
03711                         {
03712                                 for (int k = 0; k < items.size(); ++k)
03713                                 {
03714                                         if (connectionItem->curveSegments[i][j] != 0 && connectionItem->curveSegments[i][j] == items[k])
03715                                         {
03716                                                 curveSegments.append(connectionItem->curveSegments[i]);
03717                                                 if (connectionItem->curveSegments[i][0])
03718                                                         parentsAtStart.append(connectionItem->curveSegments[i][0]->parentItem());
03719                                                 else
03720                                                         parentsAtStart.append(0);
03721                                                 if (connectionItem->curveSegments[i].last())
03722                                                         parentsAtEnd.append(connectionItem->curveSegments[i].last()->parentItem());
03723                                                 else
03724                                                         parentsAtEnd.append(0);
03725                                                 done = true;
03726                                                 break;
03727                                         }
03728                                 }
03729                                 if (done) break;
03730                         }
03731                 }
03732         }
03733 
03734         void RemoveCurveSegmentCommand::undo()
03735         {
03736                 if (connectionItem == 0) return;
03737 
03738                 if (connectionItem->curveSegments.size() == 1 && connectionItem->curveSegments.size() >= 4
03739                         && curveSegments.size() > 0 && curveSegments[0].at(3) != 0
03740                         && connectionItem->curveSegments[0][3]->scene() != 0)
03741                 {
03742                         connectionItem->curveSegments[0][3]->setParentItem(0);
03743                         connectionItem->curveSegments[0][3]->scene()->removeItem(connectionItem->curveSegments[0][3]);
03744                         connectionItem->curveSegments[0][3] = curveSegments[0].at(3);
03745                 }
03746                 for (int i=0; i < curveSegments.size(); ++i)
03747                 {
03748                         if (curveSegments[i][0] && parentsAtStart.size() > i && parentsAtStart[i] &&
03749                                 !MainWindow::invalidPointers.contains((void*)parentsAtStart[i]))
03750                                 curveSegments[i][0]->setParentItem(parentsAtStart[i]);
03751                         if (curveSegments[i].last() && parentsAtEnd.size() > i && parentsAtEnd[i] &&
03752                                 !MainWindow::invalidPointers.contains((void*)parentsAtEnd[i]))
03753                                 curveSegments[i].last()->setParentItem(parentsAtEnd[i]);
03754 
03755                         connectionItem->curveSegments.append(curveSegments[i]);
03756                         for (int j=0; j < curveSegments[i].size(); ++j)
03757                                 if (curveSegments[i][j] != 0)
03758                                         curveSegments[i][j]->setVisible( connectionItem->controlPointsVisible );
03759                         if (curveSegments[i].arrowStart)
03760                                 curveSegments[i].arrowStart->setVisible(true);
03761                         if (curveSegments[i].arrowEnd)
03762                                 curveSegments[i].arrowEnd->setVisible(true);
03763                 }
03764                 connectionItem->refresh();
03765         }
03766 
03767         void RemoveCurveSegmentCommand::redo()
03768         {
03769                 if (connectionItem == 0) return;
03770                 int k;
03771                 for (int i=0; i < curveSegments.size(); ++i)
03772                 {
03773                         k = connectionItem->curveSegments.indexOf(curveSegments[i]);
03774                         if (k >=0 && k < connectionItem->curveSegments.size())
03775                                 connectionItem->curveSegments.removeAt(k);
03776                         for (int j=0; j < curveSegments[i].size(); ++j)
03777                                 if (curveSegments[i][j] != 0)
03778                                 {
03779                                         curveSegments[i][j]->setVisible(false);
03780                                         if (curveSegments[i][j]->parentItem())
03781                                                 curveSegments[i][j]->setParentItem(0);
03782                                 }
03783                         if (curveSegments[i].arrowStart)
03784                                 curveSegments[i].arrowStart->setVisible(false);
03785                         if (curveSegments[i].arrowEnd)
03786                                 curveSegments[i].arrowEnd->setVisible(false);
03787                 }
03788                 if (connectionItem->curveSegments.size() == 1 && connectionItem->curveSegments.size() >= 4
03789                         && curveSegments.size() > 0 && curveSegments[0].at(0) != 0)
03790                 {
03791                         connectionItem->curveSegments[0][3] = new ConnectionGraphicsItem::ControlPoint(*connectionItem->curveSegments[0][3]);
03792                         connectionItem->curveSegments[0][3]->setParentItem(curveSegments[0].at(0)->parentItem());
03793                 }
03794                 connectionItem->refresh();
03795         }
03796 
03797         AddCurveSegmentCommand::AddCurveSegmentCommand(
03798                 const QString& name, GraphicsScene * scene,
03799                 ConnectionGraphicsItem* connection,
03800                 ConnectionGraphicsItem::CurveSegment& item)
03801                 : QUndoCommand(name)
03802         {
03803                 undone = false;
03804                 curveSegments.clear();
03805                 graphicsScene = scene;
03806                 connectionItem = connection;
03807                 if (connectionItem == 0) return;
03808                 curveSegments.append(item);
03809         }
03810 
03811         AddCurveSegmentCommand::AddCurveSegmentCommand(
03812                 const QString& name, GraphicsScene * scene,
03813                 ConnectionGraphicsItem* connection,
03814                 QList<ConnectionGraphicsItem::CurveSegment> items)
03815                 : QUndoCommand(name)
03816         {
03817                 undone = false;
03818                 curveSegments.clear();
03819                 graphicsScene = scene;
03820                 connectionItem = connection;
03821                 if (connectionItem == 0) return;
03822                 curveSegments << items;
03823         }
03824 
03825         void AddCurveSegmentCommand::redo()
03826         {
03827                 if (connectionItem == 0) return;
03828 
03829                 for (int i=0; i < curveSegments.size(); ++i)
03830                 {
03831                         connectionItem->curveSegments.append(curveSegments[i]);
03832 
03833                         if (curveSegments[i].arrowStart)
03834                                 curveSegments[i].arrowStart->setVisible(true);
03835                         if (curveSegments[i].arrowEnd)
03836                                 curveSegments[i].arrowEnd->setVisible(true);
03837                 }
03838                 connectionItem->refresh();
03839                 
03840                 undone = false;
03841         }
03842 
03843         void AddCurveSegmentCommand::undo()
03844         {
03845                 if (connectionItem == 0) return;
03846                 int k;
03847                 for (int i=0; i < curveSegments.size(); ++i)
03848                 {
03849                         k = connectionItem->curveSegments.indexOf(curveSegments[i]);
03850                         if (k >=0 && k < connectionItem->curveSegments.size())
03851                                 connectionItem->curveSegments.removeAt(k);
03852 
03853                         if (curveSegments[i].arrowStart)
03854                                 curveSegments[i].arrowStart->setVisible(false);
03855                         if (curveSegments[i].arrowEnd)
03856                                 curveSegments[i].arrowEnd->setVisible(false);
03857                 }
03858                 connectionItem->refresh();
03859                 
03860                 undone = true;
03861         }
03862 
03863         AddCurveSegmentCommand::~AddCurveSegmentCommand()
03864         {
03865                 if (!undone) return;
03866 
03867                 for (int i=0; i < curveSegments.size(); ++i)
03868                 {
03869                         for (int j=0; j < curveSegments[i].size(); ++j)
03870                                 if (curveSegments[i][j] && 
03871                                         !curveSegments[i][j]->connectionItem)
03872                                 {
03873                                         curveSegments[i][j]->setParentItem(0);
03874                                         delete curveSegments[i][j];
03875                                 }
03876                                 if (curveSegments[i].arrowStart && 
03877                                         !curveSegments[i].arrowStart->connectionItem &&
03878                                         !MainWindow::invalidPointers.contains((void*)curveSegments[i].arrowStart))
03879                                 {
03880                                         curveSegments[i].arrowStart->setParentItem(0);
03881                                         delete curveSegments[i].arrowStart;
03882                                         MainWindow::invalidPointers[ (void*)curveSegments[i].arrowStart ] = true;
03883                                         curveSegments[i].arrowStart = 0;
03884                                 }
03885                                 if (curveSegments[i].arrowEnd && 
03886                                         !curveSegments[i].arrowEnd->connectionItem &&
03887                                         !MainWindow::invalidPointers.contains((void*)curveSegments[i].arrowEnd))
03888                                 {
03889                                         curveSegments[i].arrowEnd->setParentItem(0);
03890                                         delete curveSegments[i].arrowEnd;
03891                                         MainWindow::invalidPointers[ (void*)curveSegments[i].arrowEnd ] = true;
03892                                         curveSegments[i].arrowEnd = 0;
03893                                 }
03894                 }
03895         }
03896         
03897                 AddControlPointCommand::AddControlPointCommand(
03898                 const QString& name, GraphicsScene * scene,
03899                 ConnectionGraphicsItem::ControlPoint* item)
03900                 : QUndoCommand(name)
03901         {
03902                 graphicsScene = scene;
03903                 graphicsItems.clear();
03904                 graphicsItems += item;
03905                 undone = false;
03906         }
03907 
03908         AddControlPointCommand::AddControlPointCommand(
03909                 const QString& name, GraphicsScene * scene,
03910                 QList<ConnectionGraphicsItem::ControlPoint*> items)
03911                 : QUndoCommand(name)
03912         {
03913                 graphicsScene = scene;
03914                 graphicsItems = items;
03915                 undone = false;
03916         }
03917 
03918         void AddControlPointCommand::redo()
03919         {
03920                 QList<ConnectionGraphicsItem::ControlPoint*> controlPointItems = graphicsItems;
03921                 graphicsItems.clear();
03922 
03923                 for (int k=0; k < controlPointItems.size(); k+=3)
03924 
03925                         if (controlPointItems[k] && graphicsScene && controlPointItems[k]->connectionItem)
03926                         {
03927                                 ConnectionGraphicsItem::ControlPoint* controlPoint = controlPointItems[k];
03928                                 ConnectionGraphicsItem * item = controlPoint->connectionItem;
03929 
03930                                 QPointF loc = controlPoint->scenePos();
03931                                 qreal dist = -1;
03932                                 int k1 = 0, k2 = 0;
03933                                 QPointF p0,p1;
03934 
03935                                 for (int i=0; i < item->curveSegments.size(); ++i)
03936                                         for (int j=0; j < item->curveSegments[i].size(); ++j)
03937                                         {
03938                                                 if (item->curveSegments[i][j])
03939                                                 {
03940                                                         p0 = item->curveSegments[i][j]->scenePos();
03941 
03942                                                         if (j > 0 && j < (item->curveSegments[i].size()-1))
03943                                                                 p0 =  (item->curveSegments[i][j+1]->scenePos() + item->curveSegments[i][j-1]->scenePos() + p0)/3.0;
03944                                                         else
03945                                                         {
03946                                                                 if (j > 0)
03947                                                                         p0 =  (item->curveSegments[i][j-1]->scenePos() + p0)/2.0;
03948                                                                 else
03949                                                                         if (j < (item->curveSegments[i].size()-1))
03950                                                                                 p0 =  (item->curveSegments[i][j+1]->scenePos() + p0)/2.0;
03951                                                         }
03952 
03953                                                         qreal dist2 = (p0.x() - loc.x())*(p0.x() - loc.x()) +
03954                                                                 (p0.y() - loc.y())*(p0.y() - loc.y());
03955                                                         if (dist < 0 || (dist > dist2))
03956                                                         {
03957                                                                 dist = dist2;
03958                                                                 k1 = i;
03959                                                                 if ((j+1) < item->curveSegments[i].size())
03960                                                                         k2 = j;
03961                                                                 else
03962                                                                         k2 = j - 1;
03963                                                         }
03964                                                 }
03965 
03966                                                 if (item->lineType == ConnectionGraphicsItem::line)
03967                                                         j += 2;
03968                                         }
03969 
03970                                         //controlPoint->graphicsItem = item;
03971                                         while (item->curveSegments.size() <= k1) item->curveSegments.append(ConnectionGraphicsItem::CurveSegment());
03972 
03973                                         if (item->curveSegments[k1].size() < k2) k2 = item->curveSegments[k1].size();
03974 
03975                                         if (graphicsScene)
03976                                         {
03977                                                 ConnectionGraphicsItem::ControlPoint * cp1, * cp2;
03978 
03979                                                 if (controlPointItems.size() > k+2)
03980                                                 {
03981                                                         cp1 = controlPointItems[k+1];
03982                                                         cp2 = controlPointItems[k+2];
03983                                                 }
03984                                                 else
03985                                                 {
03986                                                         cp1 = new ConnectionGraphicsItem::ControlPoint(item);
03987                                                         cp2 = new ConnectionGraphicsItem::ControlPoint(item);
03988                                                 }
03989 
03990                                                 qreal dx1 = 50.0;
03991                                                 //qreal dx2 = 25.0;
03992                                                 int d1 = -1, d2 = 1;
03993                                                 if (k2 % 3 == 0) { d1 = -2; d2 = -1; }
03994                                                 if (k2 % 3 == 1) { d1 = -1; d2 = 1; }
03995                                                 if (k2 % 3 == 2) { d1 = 1; d2 = 2; }
03996 
03997                                                 //if (item->curveSegments[k1].size() <= k2)
03998                                                 //{
03999                                                 cp1->setPos( QPointF(controlPoint->pos().x()+d1*dx1, controlPoint->pos().y() ) );
04000                                                 cp2->setPos( QPointF(controlPoint->pos().x()+d2*dx1, controlPoint->pos().y() ) );
04001                                                 /*}
04002                                                 else
04003                                                 {
04004                                                 qreal slopeAtCp = item->slopeAtPoint(controlPoint->pos());
04005                                                 if (slopeAtCp == 0) slopeAtCp = 0.001;
04006                                                 QPointF pos1 = QPointF(controlPoint->pos().x() + d1*dx2, controlPoint->pos().y() + d1*dx2*slopeAtCp),
04007                                                 pos2 = QPointF(controlPoint->pos().x() + d2*dx2, controlPoint->pos().y() + d2*dx2*slopeAtCp);
04008                                                 cp1->setPos( QPointF(0.4*pos1.x() + 0.6*controlPoint->pos().x(), 0.4*pos1.y() + 0.6*controlPoint->pos().y()) );
04009                                                 cp2->setPos( QPointF(0.4*pos2.x() + 0.6*controlPoint->pos().x(), 0.4*pos2.y() + 0.6*controlPoint->pos().y()) );
04010                                                 }*/
04011 
04012                                                 graphicsScene->addItem(controlPoint);
04013                                                 graphicsScene->addItem(cp1);
04014                                                 graphicsScene->addItem(cp2);
04015 
04016                                                 controlPoint->setZValue(item->zValue()+0.02);
04017                                                 cp1->setZValue(controlPoint->zValue());
04018                                                 cp2->setZValue(controlPoint->zValue());
04019 
04020                                                 if (item->curveSegments[k1].size() < 4)
04021                                                 {
04022                                                         ConnectionGraphicsItem::ControlPoint * cp3 = new ConnectionGraphicsItem::ControlPoint(item);
04023                                                         cp3->setPos( QPointF(controlPoint->pos().x(), controlPoint->pos().y()) );
04024                                                         graphicsScene->addItem(cp3);
04025                                                         cp3->setZValue(controlPoint->zValue());
04026 
04027                                                         item->curveSegments[k1].insert(0,cp1);
04028                                                         item->curveSegments[k1].insert(0,cp2);
04029                                                         item->curveSegments[k1].insert(0,cp3);
04030                                                         item->curveSegments[k1].insert(0,controlPoint);
04031 
04032                                                         listK1 << k1 << k1 << k1;
04033                                                         listK2 << 0 << 0 << 0 << 0;
04034 
04035                                                         graphicsItems << cp1 << cp2 << cp3 << controlPoint;
04036                                                 }
04037                                                 else
04038                                                 {
04039                                                         listK1 << k1 << k1 << k1;
04040                                                         listK2 << (k2+1) << (k2+1)<< (k2+1);
04041 
04042                                                         if (k2 % 3 == 0)
04043                                                         {
04044                                                                 item->curveSegments[k1].insert(k2+1,controlPoint);
04045                                                                 item->curveSegments[k1].insert(k2+1,cp2);
04046                                                                 item->curveSegments[k1].insert(k2+1,cp1);
04047                                                                 graphicsItems << controlPoint << cp2 << cp1;
04048                                                         }
04049                                                         else
04050                                                                 if (k2 % 3 == 1)
04051                                                                 {
04052                                                                         item->curveSegments[k1].insert(k2+1,cp2);
04053                                                                         item->curveSegments[k1].insert(k2+1,controlPoint);
04054                                                                         item->curveSegments[k1].insert(k2+1,cp1);
04055                                                                         graphicsItems << cp2 << controlPoint << cp1;
04056                                                                 }
04057                                                                 else
04058                                                                 {
04059                                                                         item->curveSegments[k1].insert(k2+1,cp2);
04060                                                                         item->curveSegments[k1].insert(k2+1,cp1);
04061                                                                         item->curveSegments[k1].insert(k2+1,controlPoint);
04062                                                                         graphicsItems << cp2 << cp1 << controlPoint;
04063                                                                 }
04064                                                 }
04065                                         }
04066                                         item->setControlPointsVisible(true);
04067                                         item->refresh();
04068                         }
04069                         
04070                         undone = false;
04071         }
04072 
04073         void AddControlPointCommand::undo()
04074         {
04075                 for (int i=0; i < graphicsItems.size(); ++i)
04076                 {
04077                         if (graphicsItems[i] && graphicsItems[i]->connectionItem && graphicsScene)
04078                         {
04079                                 ConnectionGraphicsItem * item = graphicsItems[i]->connectionItem;
04080                                 if (listK1[i] >= 0 && listK1[i] < item->curveSegments.size())
04081                                 {
04082                                         int k = item->curveSegments[ listK1[i] ].indexOf(graphicsItems[i]);
04083                                         item->curveSegments[ listK1[i] ].remove(k);
04084                                 }
04085 
04086                                 if (graphicsScene)
04087                                 {
04088                                         graphicsItems[i]->setParentItem(0);
04089                                         graphicsScene->removeItem(graphicsItems[i]);
04090                                 }
04091 
04092                                 if (graphicsItems[i]->scene())
04093                                 {
04094                                         graphicsItems[i]->setParentItem(0);
04095                                         graphicsItems[i]->scene()->removeItem(graphicsItems[i]);
04096                                 }
04097 
04098                                 item->refresh();
04099                         }
04100                 }
04101                 
04102                 undone = true;
04103         }
04104 
04105         AddControlPointCommand::~AddControlPointCommand()
04106         {
04107                 if (!undone) return;
04108 
04109                 for (int i=0; i < graphicsItems.size(); ++i)
04110                 {
04111                         if (graphicsItems[i])
04112                         {
04113                                 graphicsItems[i]->setParentItem(0);
04114                                 delete graphicsItems[i];
04115                         }
04116                 }
04117         }
04118 
04119         RemoveControlPointCommand::RemoveControlPointCommand(
04120                 const QString& name, GraphicsScene * scene,
04121                 ConnectionGraphicsItem::ControlPoint* item)
04122                 : QUndoCommand(name)
04123         {
04124                 graphicsScene = scene;
04125                 graphicsItems.clear();
04126                 graphicsItems += item;
04127         }
04128 
04129         RemoveControlPointCommand::RemoveControlPointCommand(
04130                 const QString& name, GraphicsScene * scene,
04131                 QList<ConnectionGraphicsItem::ControlPoint*> items)
04132                 : QUndoCommand(name)
04133         {
04134                 graphicsScene = scene;
04135                 graphicsItems = items;
04136         }
04137 
04138         void RemoveControlPointCommand::undo()
04139         {
04140                 for (int i=0; i < graphicsItems.size(); ++i)
04141 
04142                         if (graphicsItems[i] && graphicsItems[i]->connectionItem && graphicsScene)
04143                         {
04144                                 ConnectionGraphicsItem * item = graphicsItems[i]->connectionItem;
04145                                 if (listK1[i] >= 0 && listK1[i] < item->curveSegments.size() && listK2[i]  >= 0 && listK2[i] < item->curveSegments[ listK1[i] ].size() )
04146                                 {
04147                                         item->curveSegments[ listK1[i] ].insert(listK2[i],graphicsItems[i]);
04148                                         graphicsScene->addItem(graphicsItems[i]);
04149                                 }
04150                                 item->refresh();
04151                         }
04152         }
04153 
04154         void RemoveControlPointCommand::redo()
04155         {
04156                 QList<ConnectionGraphicsItem::ControlPoint*> controlPointItems = graphicsItems;
04157                 graphicsItems.clear();
04158 
04159                 for (int i=0; i < controlPointItems.size(); ++i)
04160 
04161                         if (controlPointItems[i] && controlPointItems[i]->connectionItem  && graphicsScene)
04162                         {
04163                                 ConnectionGraphicsItem::ControlPoint * controlPoint = controlPointItems[i];
04164                                 ConnectionGraphicsItem * item = controlPointItems[i]->connectionItem;
04165 
04166                                 for (int i=0; i < item->curveSegments.size(); ++i)
04167                                 {
04168                                         int index = -1;
04169                                         for (int j=3; j < item->curveSegments[i].size()-3; j+=3)
04170                                         {
04171                                                 if (item->curveSegments[i][j] == controlPoint ||
04172                                                         item->curveSegments[i][j-1] == controlPoint ||
04173                                                         item->curveSegments[i][j+1] == controlPoint)
04174                                                 {
04175 
04176                                                         index = j;
04177                                                         break;
04178                                                 }
04179                                         }
04180                                         if (index > -1)
04181                                         {
04182                                                 graphicsItems << item->curveSegments[i][index-1]
04183                                                 << item->curveSegments[i][index]
04184                                                 << item->curveSegments[i][index+1];
04185 
04186                                                 listK1 << i << i << i;
04187                                                 listK2 << (index-1) << index << (index+1);
04188 
04189                                                 item->curveSegments[i][index-1]->setParentItem(0);
04190                                                 item->curveSegments[i][index]->setParentItem(0);
04191                                                 item->curveSegments[i][index+1]->setParentItem(0);
04192                                                 graphicsScene->removeItem(item->curveSegments[i][index-1]);
04193                                                 graphicsScene->removeItem(item->curveSegments[i][index]);
04194                                                 graphicsScene->removeItem(item->curveSegments[i][index+1]);
04195 
04196                                                 item->curveSegments[i].remove(index-1,3);
04197                                                 //item->refresh();
04198 
04199                                                 break;
04200                                         }
04201                                 }
04202                                 item->refresh();
04203                         }
04204         }
04205         
04206         ReplaceConnectedNodeCommand::ReplaceConnectedNodeCommand(const QString& name, ConnectionGraphicsItem * c, NodeGraphicsItem * a, NodeGraphicsItem * b)
04207                 : QUndoCommand(name), connection(c), oldNode(a), newNode(b)
04208         {
04209         }
04210         void ReplaceConnectedNodeCommand::redo()
04211         {
04212                 if (connection && oldNode && newNode && oldNode != newNode)
04213                 {
04214                         connection->replaceNode(oldNode,newNode);
04215                         connection->refresh();
04216                 }
04217         }
04218         
04219         void ReplaceConnectedNodeCommand::undo()
04220         {
04221                 if (connection && oldNode && newNode && oldNode != newNode)
04222                 {
04223                         connection->replaceNode(newNode,oldNode);
04224                         connection->refresh();
04225                 }
04226         }
04227         
04228         void LineTypeChanged::undo()
04229         {
04230                 for (int i=0; i < list.size(); ++i)
04231                 {
04232                         ConnectionGraphicsItem * connectionPtr = list[i];
04233                         if (connectionPtr)
04234                         {
04235                                 if (!straight)
04236                                         connectionPtr->lineType = ConnectionGraphicsItem::line;
04237                                 else
04238                                         connectionPtr->lineType = ConnectionGraphicsItem::bezier;
04239                                 connectionPtr->refresh();
04240                         }
04241                 }
04242         }
04243 
04244         void LineTypeChanged::redo()
04245         {
04246                 for (int i=0; i < list.size(); ++i)
04247                 {
04248                         ConnectionGraphicsItem * connectionPtr = list[i];
04249                         if (connectionPtr)
04250                         {
04251                                 if (straight)
04252                                         connectionPtr->lineType = ConnectionGraphicsItem::line;
04253                                 else
04254                                         connectionPtr->lineType = ConnectionGraphicsItem::bezier;
04255                                 connectionPtr->refresh();
04256                         }
04257                 }
04258         }
04259 
04260         void ChangeArrowHeadDistance::undo()
04261         {
04262                 for (int i=0; i < list.size() && i < dists.size(); ++i)
04263                 {
04264                         ConnectionGraphicsItem * connectionPtr = list[i];
04265                         if (connectionPtr)
04266                         {
04267                                 connectionPtr->arrowHeadDistance -= dists[i];
04268                                 connectionPtr->refresh();
04269                         }
04270                 }
04271         }
04272 
04273         void ChangeArrowHeadDistance::redo()
04274         {
04275                 for (int i=0; i < list.size() && i < dists.size(); ++i)
04276                 {
04277                         ConnectionGraphicsItem * connectionPtr = list[i];
04278                         if (connectionPtr)
04279                         {
04280                                 connectionPtr->arrowHeadDistance += dists[i];
04281                                 connectionPtr->refresh();
04282                         }
04283                 }
04284         }
04285 }
04286 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines