TinkerCell Core 1.0
TinkerCell's Core library providing all basic functionalities
GraphicsScene.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 defines the GraphicsScene class where all the drawing takes place.
00008 In addition to drawing , the GraphicsScene provides serveral signals and functions
00009 that is useful for plugins, eg. move, insert, delete, changeData, etc.
00010 
00011 ****************************************************************************/
00012 #include "CloneItems.h"
00013 #include "DataTable.h"
00014 #include "NetworkHandle.h"
00015 #include "NetworkWindow.h"
00016 #include "MainWindow.h"
00017 #include "NodeGraphicsItem.h"
00018 #include "fileIO/NodeGraphicsReader.h"
00019 #include "ConnectionGraphicsItem.h"
00020 #include "TextGraphicsItem.h"
00021 #include "ItemHandle.h"
00022 #include "Tool.h"
00023 #include "UndoCommands.h"
00024 #include "ConsoleWindow.h"
00025 #include "CloneItems.h"
00026 #include "SymbolsTable.h"
00027 #include "HistoryWindow.h"
00028 #include "GraphicsView.h"
00029 #include "GraphicsScene.h"
00030 #include <QRegExp>
00031 
00032 namespace Tinkercell
00033 {
00034         bool GraphicsScene::USE_DEFAULT_BEHAVIOR = true;
00035 
00036         int GraphicsScene::GRID = 0;
00037 
00038         QPen GraphicsScene::SelectionRectanglePen = Qt::NoPen;
00039 
00040         QBrush GraphicsScene::SelectionRectangleBrush = QBrush(QColor(0,132,255,50));
00041 
00042         QBrush GraphicsScene::BackgroundBrush = Qt::NoBrush; //QBrush(Qt::lightGray,Qt::CrossPattern);
00043         
00044         QColor GraphicsScene::BackgroundColor(QColor(255,255,255,255));
00045 
00046         QPen GraphicsScene::GridPen = QPen(Qt::lightGray,2);
00047 
00048         QBrush GraphicsScene::ForegroundBrush = Qt::NoBrush; //QBrush(Qt::lightGray,Qt::CrossPattern);
00049         
00050         QBrush GraphicsScene::ToolTipBackgroundBrush = QBrush(QColor(36,28,28,125));
00051         
00052         QBrush GraphicsScene::ToolTipTextBrush = QBrush(QColor(255,255,255,255));
00053 
00054         qreal GraphicsScene::MIN_DRAG_DISTANCE = 2.0;
00055 
00059         QRectF GraphicsScene::visibleRegion() const
00060         {
00061                 QGraphicsView * view = 0;
00062                 
00063                 QList<QGraphicsView*> list = views();
00064         
00065                 if (list.size() > 0)
00066                         view = list[0];
00067 
00068                 if (view)
00069                 {
00070                         QRect rect = view->viewport()->rect();
00071                         return QRectF(view->mapToScene(rect.topLeft()),view->mapToScene(rect.bottomRight()));
00072                 }
00073 
00074                 return QRect();
00075         }
00076 
00082         QPointF& GraphicsScene::lastPoint()
00083         {
00084                 return clickedPoint;
00085         }
00086 
00092         QPoint& GraphicsScene::lastScreenPoint()
00093         {
00094                 return clickedScreenPoint;
00095         }
00096 
00102         QList<QGraphicsItem*>& GraphicsScene::selected()
00103         {
00104                 return selectedItems;
00105         }
00106 
00107 
00113         QRectF GraphicsScene::selectedRect()
00114         {
00115                 QRectF rect;
00116                 for (int i=0; i < selectedItems.size(); ++i)
00117                         if (selectedItems[i] != 0)
00118                                 rect = rect.united(selectedItems[i]->topLevelItem()->sceneBoundingRect());
00119                 return rect;
00120         }
00126         QList<QGraphicsItem*>& GraphicsScene::moving()
00127         {
00128                 return movingItems;
00129         }
00130 
00132         GraphicsScene::GraphicsScene(NetworkHandle * net) : QGraphicsScene(0), networkWindow(0), network(net)
00133         {
00134                 gridSz = GRID;
00135                 mouseDown = false;
00136                 contextMenuJustActivated = false;
00137                 _useDefaultBehavior = USE_DEFAULT_BEHAVIOR;
00138                 setFocus();
00139                 //setItemIndexMethod(NoIndex);
00140 
00141                 contextItemsMenu = 0;
00142                 contextScreenMenu = 0;
00143                 setSceneRect(0,0,10000,10000);
00144 
00145                 lastZ = 1.0;
00146 
00147                 setBackgroundBrush(BackgroundBrush);
00148                 setForegroundBrush(ForegroundBrush);
00149                 selectionRect.setBrush(SelectionRectangleBrush);
00150                 selectionRect.setPen(SelectionRectanglePen);
00151 
00152                 addItem(&selectionRect);
00153 
00154                 selectionRect.setVisible(false);
00155                 movingItemsGroup = 0;
00156         }
00158         GraphicsScene::~GraphicsScene()
00159         {
00160                 if (!toolTips.isEmpty()) hideToolTips();
00161                 visibleTools.clear();
00162                 selectedItems.clear();
00163                 movingItems.clear();
00164                 if (movingItemsGroup)
00165                 {
00166                         destroyItemGroup(movingItemsGroup);
00167                         movingItemsGroup = 0;
00168                 }
00169                 select(0);
00170                 if (GraphicsScene::copiedFromScene == this)
00171                         GraphicsScene::copiedFromScene = 0;
00172                 
00173                 QList<QGraphicsItem *> allitems = items();
00174                 for (int i=0; i < allitems.size(); ++i)
00175                         removeItem(allitems[i]);
00176                 
00177                 /*      
00178                 QList<ItemHandle*> handles = network->handles();
00179                 
00180                 for (int i=0; i < handles.size(); ++i)
00181                 {
00182                         QList<QGraphicsItem*> & items = handles[i]->graphicsItems;
00183                         for (int j=0; j < items.size(); ++j)
00184                                 if (items[j]->scene() == this)
00185                                         removeItem(items[j]);
00186                 }
00187                 
00188                 removeItem(&selectionRect);
00189                 QList<QGraphicsItem *> allitems1 = items();
00190                 QList<QGraphicsItem *> allitems2;
00191 
00192                 for (int i=0; i < allitems1.size(); ++i)
00193                 {
00194                         if (allitems1[i] && ConnectionGraphicsItem::cast(allitems1[i]) && !allitems1[i]->parentItem())
00195                         {
00196                                 allitems2 << allitems1[i];
00197                         }
00198                 }
00199 
00200                 qDeleteAll(allitems2);
00201                 allitems1 = items();
00202                 allitems2.clear();
00203 
00204                 for (int i=0; i < allitems1.size(); ++i)
00205                 {
00206                         if (allitems1[i] && NodeGraphicsItem::cast(allitems1[i]) && !allitems1[i]->parentItem())
00207                         {
00208                                 allitems2 << allitems1[i];
00209                         }
00210                 }
00211 
00212                 qDeleteAll(allitems2);
00213                 allitems1 = items();
00214                 allitems2.clear();
00215 
00216                 for (int i=0; i < allitems1.size(); ++i)
00217                 {
00218                         if (allitems1[i] && TextGraphicsItem::cast(allitems1[i]) && !allitems1[i]->parentItem())
00219                         {
00220                                 allitems2 << allitems1[i];
00221                         }
00222                 }
00223 
00224                 qDeleteAll(allitems2);
00225                 allitems1 = items();
00226                 allitems2.clear();
00227 
00228                 for (int i=0; i < allitems1.size(); ++i)
00229                 {
00230                         if (allitems1[i] && !allitems1[i]->parentItem() && !ToolGraphicsItem::cast(allitems1[i]))
00231                         {
00232                                 allitems2 << allitems1[i];
00233                         }
00234                 }
00235 
00236                 qDeleteAll(allitems2);*/
00237         }
00242         void GraphicsScene::clearSelection()
00243         {
00244                 if (!toolTips.isEmpty()) hideToolTips();
00245                 
00246                 for (int i=0; i < selectedItems.size(); ++i)
00247                         if (TextGraphicsItem::cast(selectedItems[i]))
00248                         {
00249                                 TextGraphicsItem * textItem = TextGraphicsItem::cast(selectedItems[i]);
00250                                 textItem->showBorder(false);
00251                                 textItem->setSelected(false);
00252                                 textItem->setTextInteractionFlags(Qt::NoTextInteraction);
00253                         }
00254                 
00255                 selectedItems.clear();
00256                 if (movingItemsGroup)
00257                 {
00258                         destroyItemGroup(movingItemsGroup);
00259                         movingItemsGroup = 0;
00260                 }
00261                 movingItems.clear();
00262                 emit itemsSelected(this,selectedItems,QPointF(),Qt::NoModifier);
00263                 hideGraphicalTools();
00264         }
00270         void GraphicsScene::addItem(QGraphicsItem * item)
00271         {
00272                 if (!item || item->scene() == this) return;
00273                 QGraphicsScene::addItem(item);
00274 
00275                 item->setVisible( item->isVisible() );
00276 
00277                 if (item->zValue())
00278                 {
00279                         item->setZValue(item->zValue());
00280                         if (item->zValue() > lastZ)
00281                                 lastZ = item->zValue();
00282                 }
00283                 else
00284                 {
00285                         item->setZValue(lastZ);
00286                         lastZ += 1.0;
00287                 }
00288 
00289                 QGraphicsItem * item2 = getGraphicsItem(item);
00290 
00291                 if (!item2) return;
00292 
00293                 QPointF p = item2->scenePos();
00294                 if (p.rx() > this->width() || p.ry() > this->height())
00295                 {
00296                         setSceneRect(0,0,this->width()*2, this->height()*2);
00297                 }
00298                 if (p.rx() < 0 || p.ry() < 0)
00299                 {
00300                         QPointF dp;
00301                         if (p.rx() < 0) dp.rx() = - p.rx() + item2->boundingRect().width()/2.0 ;
00302                         if (p.ry() < 0) dp.ry() = - p.ry() + item2->boundingRect().height()/2.0 ;
00303 
00304                         move(item2,dp);
00305                 }
00306 
00307                 snapToGrid(item2);
00308         }
00313         qreal GraphicsScene::ZValue()
00314         {
00315                 return lastZ;
00316         }
00322         void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
00323         {
00324                 if (contextMenuJustActivated)
00325                 {
00326                         contextMenuJustActivated = false;
00327                         if (movingItemsGroup)
00328                         {
00329                                 destroyItemGroup(movingItemsGroup);
00330                                 movingItemsGroup = 0;
00331                         }
00332                         movingItems.clear();
00333                         //deselect();
00334                         return;
00335                 }
00336                 
00337                 for (int i=0; i < selectedItems.size(); ++i)
00338                         if (TextGraphicsItem::cast(selectedItems[i]))
00339                         {
00340                                 TextGraphicsItem * textItem = TextGraphicsItem::cast(selectedItems[i]);
00341                                 textItem->showBorder(false);
00342                                 textItem->setSelected(false);
00343                                 textItem->setTextInteractionFlags(Qt::NoTextInteraction);
00344                         }
00345                 
00346                 if (!toolTips.isEmpty()) hideToolTips();
00347 
00348                 clickedScreenPoint = mouseEvent->screenPos();
00349                 clickedPoint = mouseEvent->scenePos();
00350                 clickedButton = mouseEvent->button();
00351                 mouseDown = true;
00352 
00353                 QGraphicsItem * item = 0;
00354                 ToolGraphicsItem * gitem = 0;
00355 
00356                 QGraphicsItem * p = itemAt(clickedPoint);
00357 
00358                 if (p)
00359                         gitem = ToolGraphicsItem::cast(p->topLevelItem());
00360 
00361                 if (!gitem)
00362                 {
00363                         p = 0;//getGraphicsItem(p);
00364                         //if (!p || p->sceneBoundingRect().width() > 100 || p->sceneBoundingRect().height() > 100)
00365                         {
00366                                 QList<QGraphicsItem*> ps = items(QRectF(clickedPoint.rx()-10.0,clickedPoint.ry()-10.0,20.0,20.0));
00367                                 if (!ps.isEmpty())
00368                                 {
00369                                         for (int i=0; i < ps.size(); ++i)
00370                                         {
00371                                                 if (i > 0 && p && ps[i] && (ps[i]->sceneBoundingRect().width() > 80 || ps[i]->sceneBoundingRect().height() > 80))
00372                                                         break;
00373 
00374                                                 p = getGraphicsItem(ps[i]);
00375 
00376                                                 if (p && !TextGraphicsItem::cast(p))
00377                                                         break;
00378                                         }
00379                                 }
00380                         }
00381 
00382                         item = p;
00383                 }
00384 
00385                 if (movingItemsGroup)
00386                 {
00387                         destroyItemGroup(movingItemsGroup);
00388                         movingItemsGroup = 0;
00389                 }
00390                 movingItems.clear();
00391 
00392                 if (gitem && _useDefaultBehavior)
00393                 {
00394                         if (mouseEvent->button() == Qt::LeftButton)
00395                         {
00396                                 if (gitem->tool)
00397                                 {
00398                                         gitem->select();
00399                                         mouseDown = false;
00400                                 }
00401                                 //emit toolSelected(this,gitem,clickedPoint,mouseEvent->modifiers());
00402                         }
00403                 }
00404                 else
00405                         if (item && _useDefaultBehavior)
00406                         {
00407                                 if (mouseEvent->button())// == Qt::LeftButton)
00408                                 {
00409                                         if (!selectedItems.contains(item) && !selectedItems.contains(item->parentItem()) && !selectedItems.contains(item->topLevelItem()))
00410                                         {
00411                                                 if (!(mouseEvent->modifiers() == Qt::ShiftModifier || mouseEvent->modifiers() == Qt::ControlModifier))
00412                                                         selectedItems.clear();
00413 
00414                                                 selectedItems.append(item);
00415                                         }
00416                                         else
00417                                         {
00418                                                 if (mouseEvent->modifiers() == Qt::ControlModifier)// || mouseEvent->modifiers() == Qt::ShiftModifier)
00419                                                 {
00420                                                         if (item->parentItem() != 0 && item->parentItem() != item)
00421                                                         {
00422                                                                 selectedItems.removeAll(item->parentItem());
00423                                                                 QList<QGraphicsItem*> childs = item->parentItem()->childItems();
00424                                                                 for (int i = 0; i < childs.size(); ++i)
00425                                                                         selectedItems.removeAll(childs[i]);
00426                                                         }
00427                                                         else
00428                                                                 selectedItems.removeAll(item);
00429                                                 }
00430                                         }
00431                                 }
00432 
00433                                 if (selectedItems.size() > 0)
00434                                 {
00435                                         ArrowHeadItem * arrow;
00436                                         QGraphicsItem * topLevelItem;
00437                                         NodeGraphicsItem::ControlPoint * ncp;
00438                                         ConnectionGraphicsItem::ControlPoint * ccp;
00439                                         for (QList<QGraphicsItem*>::const_iterator i = selectedItems.constBegin(); i != selectedItems.constEnd(); ++i)
00440                                                 if (*i && *i != &selectionRect)
00441                                                         if (topLevelItem = (*i)->topLevelItem())
00442                                                         {
00443                                                                 arrow = ArrowHeadItem::cast(topLevelItem);
00444                                                                 if (!arrow)// || selectedItems.contains(arrow->connectionItem))
00445                                                                         movingItems.append(topLevelItem);
00446                                                                 
00447                                                                 if (ncp = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(topLevelItem))
00448                                                                 {
00449                                                                         if (ncp->nodeItem && ncp->nodeItem->handle())
00450                                                                         {
00451                                                                                 QRectF rect = ncp->sceneBoundingRect();
00452                                                                                 QList<QGraphicsItem*> & ngraphics = ncp->nodeItem->handle()->graphicsItems;
00453                                                                                 for (int j=0; j < ngraphics.size(); ++j)
00454                                                                                         if ( ngraphics[j]->scene() == this &&
00455                                                                                                  TextGraphicsItem::cast(ngraphics[j]) &&  
00456                                                                                                  !movingItems.contains(ngraphics[j]) &&
00457                                                                                                  (
00458                                                                                                         fabs(ngraphics[j]->scenePos().x() - rect.center().x()) < 1.5*rect.width() ||
00459                                                                                                         fabs(ngraphics[j]->scenePos().y() - rect.center().y()) < 1.5*rect.height()
00460                                                                                                 ))
00461                                                                                                 {
00462                                                                                                         movingItems += ngraphics[j];
00463                                                                                                 }
00464                                                                         }
00465                                                                 }
00466                                                                 if (ccp = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(topLevelItem))
00467                                                                 {
00468                                                                         if (ccp->connectionItem && 
00469                                                                                 (ccp->connectionItem->centerPoint()->scenePos() == ccp->connectionItem->centerLocation()) &&
00470                                                                                 (ccp->connectionItem->centerPoint() == ccp) && 
00471                                                                                 ccp->connectionItem->handle())
00472                                                                         {
00473                                                                                 QRectF rect = ccp->sceneBoundingRect();
00474                                                                                 rect.adjust(-20,-20,20,20);
00475                                                                                 QList<QGraphicsItem*> & ngraphics = ccp->connectionItem->handle()->graphicsItems;
00476                                                                                 for (int j=0; j < ngraphics.size(); ++j)
00477                                                                                         if ( ngraphics[j]->scene() == this &&
00478                                                                                                   TextGraphicsItem::cast(ngraphics[j]) &&  
00479                                                                                                   !movingItems.contains(ngraphics[j]) &&
00480                                                                                                  (
00481                                                                                                         fabs(ngraphics[j]->scenePos().x() - rect.center().x()) < rect.width() ||
00482                                                                                                         fabs(ngraphics[j]->scenePos().y() - rect.center().y()) < rect.height()
00483                                                                                                 ))
00484                                                                                                 {
00485                                                                                                         movingItems += ngraphics[j];
00486                                                                                                 }
00487                                                                         }
00488                                                                 }
00489                                                         }
00490 
00491                                                 if (mouseEvent->button())// == Qt::LeftButton)
00492                                                 {
00493                                                         if (selectedItems.size() == 1 && TextGraphicsItem::cast(selectedItems[0]) && !mouseEvent->modifiers())
00494                                                         {
00495                                                                 TextGraphicsItem * textItem = TextGraphicsItem::cast(selectedItems[0]);
00496                                                                 textItem->showBorder(true);
00497                                                                 textItem->setSelected(true);
00498                                                                 textItem->setTextInteractionFlags(Qt::TextEditorInteraction);
00499                                                                 QTextCursor c = textItem->textCursor();
00500                                                                 c.movePosition(QTextCursor::EndOfLine);
00501                                                                 c.movePosition(QTextCursor::StartOfLine,QTextCursor::KeepAnchor);
00502                                                                 textItem->setTextCursor(c);
00503                                                         }
00504                                                         emit itemsSelected(this, selectedItems,clickedPoint,mouseEvent->modifiers());
00505                                                         showGraphicalTools();
00506                                                 }
00507                                                 
00508                                                 selectConnections(clickedPoint);
00509                                                 
00510                                                 if (movingItems.size() > 0)
00511                                                 {
00512                                                         movingItemsGroup = createItemGroup(movingItems);
00513                                                         movingItemsGroup->setZValue(lastZ);
00514                                                 }
00515                                 }
00516                         }
00517                         else
00518                         {
00519                                 if (_useDefaultBehavior && !(mouseEvent->modifiers() == Qt::ShiftModifier || mouseEvent->modifiers() == Qt::ControlModifier))
00520                                 {
00521                                         selectedItems.clear();
00522                                 }
00523 
00524                                 emit mousePressed(this, clickedPoint, clickedButton, mouseEvent->modifiers());
00525                                 if (mouseEvent->button() == Qt::LeftButton)
00526                                 {
00527                                         emit itemsSelected(this, selectedItems,clickedPoint,mouseEvent->modifiers());
00528                                         showGraphicalTools();
00529                                 }
00530 
00531                                 selectionRect.setZValue(lastZ);
00532                         }
00533                 if (clickedButton == Qt::RightButton)
00534                 {
00535                         emit sceneRightClick(this, item, clickedPoint, mouseEvent->modifiers());
00536                 }
00537                 QGraphicsScene::mousePressEvent(mouseEvent);
00538         }
00539 
00545         void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
00546         {
00547                 if (contextMenuJustActivated)
00548                 {
00549                         contextMenuJustActivated = false;
00550                         if (movingItemsGroup)
00551                         {
00552                                 destroyItemGroup(movingItemsGroup);
00553                                 movingItemsGroup = 0;
00554                         }
00555                         movingItems.clear();
00556                         //deselect();
00557                         return;
00558                 }
00559 
00560                 QPointF point1 = mouseEvent->scenePos(), point0 = mouseEvent->lastScenePos();
00561                 QPointF change = QPointF(point1.x()-point0.x(),point1.y()-point0.y());
00562                 
00563                 //if (!toolTips.isEmpty() && ((change.x()*change.x() + change.y()*change.y()) > MIN_DRAG_DISTANCE*20.0))
00564                         //hideToolTips();
00565 
00566                 if (_useDefaultBehavior)
00567                 {
00568                         if (movingItems.size() > 0 && movingItemsGroup != 0)
00569                         {
00570                                 movingItemsGroup->moveBy(change.x(),change.y());
00571                         }
00572                         else
00573                         {
00574                                 if (mouseDown && clickedButton == Qt::LeftButton)
00575                                         //if (mouseEvent->modifiers() == 0 || selectionRect.isVisible())
00576                                 {
00577                                         if (!selectionRect.isVisible())
00578                                                 selectionRect.setVisible(true);
00579                                         qreal x,y,w,h;
00580                                         if (clickedPoint.rx() > point1.rx())
00581                                         {
00582                                                 x = point1.rx();
00583                                                 w = clickedPoint.rx() - point1.rx();
00584                                         }
00585                                         else
00586                                         {
00587                                                 x = clickedPoint.rx();
00588                                                 w = point1.rx() - clickedPoint.rx();
00589                                         }
00590                                         if (clickedPoint.ry() > point1.ry())
00591                                         {
00592                                                 y = point1.ry();
00593                                                 h = clickedPoint.ry() - point1.ry();
00594                                         }
00595                                         else
00596                                         {
00597                                                 y = clickedPoint.ry();
00598                                                 h = point1.ry() - clickedPoint.ry();
00599                                         }
00600                                         selectionRect.setRect(x,y,w,h);
00601                                 }
00602                         }
00603                 }
00604 
00605                 QSize sz(1,1);
00606                 if (mainWindow())
00607                 {
00608                         QCursor cursor = mainWindow()->cursor();
00609                         if (!cursor.pixmap().isNull())
00610                                 sz = cursor.pixmap().size();
00611                 }
00612                 QList<QGraphicsItem*> itemList = items(QRectF(point1,sz));
00613                 QGraphicsItem * item = 0;
00614 
00615                 for (int i=0; i < itemList.size(); ++i)
00616                         if (itemList[i]->topLevelItem() != movingItemsGroup)
00617                         {
00618                                 item = itemList[i]->topLevelItem();
00619                                 break;
00620                         }
00621                 
00622                 MoveCommand::refreshAllConnectionIn(movingItems);
00623                         
00624                 emit mouseMoved(this, item, point1, clickedButton, mouseEvent->modifiers(), movingItems);
00625 
00626                 if (item)
00627                         emit mouseOnTopOf(this, item, point1, mouseEvent->modifiers(), movingItems);
00628                 
00629                 QGraphicsScene::mouseMoveEvent(mouseEvent);
00630         }
00636         void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
00637         {
00638                 if (contextMenuJustActivated)
00639                 {
00640                         contextMenuJustActivated = false;
00641                         if (movingItemsGroup)
00642                         {
00643                                 destroyItemGroup(movingItemsGroup);
00644                                 movingItemsGroup = 0;
00645                         }
00646                         movingItems.clear();
00647                         //deselect();
00648                         return;
00649                 }
00650 
00651                 mouseDown = false;
00652 
00653                 QPointF point1 = mouseEvent->scenePos(), point0 = clickedPoint;
00654                 QPointF change = QPointF(point1.x()-point0.x(),point1.y()-point0.y());
00655 
00656                 if (_useDefaultBehavior && movingItems.size() > 0 && movingItemsGroup)
00657                 {
00658                         if (movingItemsGroup)
00659                         {
00660                                 movingItemsGroup->moveBy(-change.x(),-change.y());
00661                                 destroyItemGroup(movingItemsGroup);
00662                                 movingItemsGroup = 0;
00663                                 if (gridSz > 0)
00664                                 {
00665                                         change.rx() = gridSz * (int)(change.rx() / (double)gridSz + 0.5);
00666                                         change.ry() = gridSz * (int)(change.ry() / (double)gridSz + 0.5);
00667                                 }
00668                         }
00669 
00670                         if ((change.x()*change.x() + change.y()*change.y()) > MIN_DRAG_DISTANCE/2.0)
00671                         {
00672                                 move(movingItems,change);
00673                         }
00674                         
00675                         movingItems.clear();
00676                 }
00677                 else
00678                 {
00679                         if (_useDefaultBehavior && selectionRect.isVisible())
00680                         {
00681                                 QRectF rect = selectionRect.rect();
00682                                 selectionRect.setVisible(false);
00683 
00684                                 qreal x1 = std::min(rect.left(),rect.right()),
00685                                         x2 = std::max(rect.left(),rect.right()),
00686                                         y1 = std::min(rect.bottom(),rect.top()),
00687                                         y2 = std::max(rect.bottom(),rect.top());
00688 
00689                                 QList<QGraphicsItem*> itemsInRect = items(QRectF(x1,y1,x2-x1,y2-y1),Qt::ContainsItemShape);
00690                                 QList<QGraphicsItem*> itemsIntersected = items(QRectF(x1,y1,x2-x1,y2-y1),Qt::IntersectsItemShape);
00691                                 for (int i=0; i < itemsIntersected.size(); ++i)
00692                                         if (ConnectionGraphicsItem::cast(itemsIntersected[i]))
00693                                                 itemsInRect.append(itemsIntersected[i]);
00694 
00695                                 QGraphicsItem* item = 0;
00696                                 for (int i=0; i < itemsInRect.size(); ++i)
00697                                         if (itemsInRect[i] != &selectionRect &&
00698                                                 (item = getGraphicsItem(itemsInRect[i]))
00699                                                 )
00700                                         {
00701                                                 if (item && itemsInRect[i] == item)
00702                                                         if (!selectedItems.contains(item))
00703                                                                 selectedItems.append(item);
00704                                                         else
00705                                                                 if (mouseEvent->modifiers() == Qt::ShiftModifier)
00706                                                                         selectedItems.removeAll(item);
00707                                         }
00708                                 emit itemsSelected(this, selectedItems,point1,mouseEvent->modifiers());
00709                                 showGraphicalTools();
00710                         }
00711                         if ((change.x()*change.x() + change.y()*change.y()) > MIN_DRAG_DISTANCE)
00712                                 emit mouseDragged(this, point0, point1, clickedButton, mouseEvent->modifiers());
00713                         else
00714                                 emit mouseReleased(this, clickedPoint, clickedButton, mouseEvent->modifiers());
00715                 }
00716                 clickedButton = Qt::NoButton;
00717                 selectionRect.setVisible(false);
00718                 QGraphicsScene::mouseReleaseEvent(mouseEvent);
00719         }
00725         void GraphicsScene::mouseDoubleClickEvent ( QGraphicsSceneMouseEvent * mouseEvent )
00726         {
00727                 if (!toolTips.isEmpty()) hideToolTips();
00728 
00729                 QPointF point1 = mouseEvent->scenePos();
00730                 QGraphicsItem * p = itemAt(clickedPoint);
00731                 if (!p || p->sceneBoundingRect().width() > 500 || p->sceneBoundingRect().height() > 500)
00732                 {
00733                         QList<QGraphicsItem*> ps = items(QRectF(clickedPoint.rx()-20.0,clickedPoint.ry()-20.0,40.0,40.0));
00734                         if (!ps.isEmpty()) p = ps[0];
00735                 }
00736                 emit mouseDoubleClicked(this, point1, getGraphicsItem(p) , mouseEvent->button(), mouseEvent->modifiers());
00737                 QGraphicsScene::mouseDoubleClickEvent(mouseEvent);
00738         }
00739         
00745         void GraphicsScene::contextMenuEvent ( QGraphicsSceneContextMenuEvent * mouseEvent )
00746         {
00747                 if (!toolTips.isEmpty()) hideToolTips();
00748 
00749                 clickedButton = Qt::RightButton;
00750 
00751                 if (_useDefaultBehavior)
00752                 {
00753                         if (selectedItems.size() > 0)
00754                         {
00755                                 populateContextMenu();
00756                                 if (contextItemsMenu)
00757                                 {
00758                                         contextMenuJustActivated = true;
00759                                         contextItemsMenu->exec(mouseEvent->screenPos());
00760                                 }
00761                         }
00762                         else
00763                         {
00764                                 if (contextScreenMenu)
00765                                 {
00766                                         contextScreenMenu->exec(mouseEvent->screenPos());
00767                                 }
00768                         }
00769                 }
00770                 else
00771                 {
00772                         if (selectedItems.size() == 1 && TextGraphicsItem::cast(selectedItems[0]))
00773                         {
00774                                 TextGraphicsItem * textItem = TextGraphicsItem::cast(selectedItems[0]);
00775                                 textItem->showBorder(false);
00776                                 textItem->setSelected(false);
00777                                 textItem->setTextInteractionFlags(Qt::NoTextInteraction);
00778                         }
00779                         emit escapeSignal(network->mainWindow->currentNetworkWindow);
00780                 }
00781         }
00785         void GraphicsScene::zoom(qreal scaleFactor)
00786         {
00787                 if (!toolTips.isEmpty()) hideToolTips();
00788 
00789                 QList<QGraphicsView*> list = views();
00790                 
00791                 if (!list.isEmpty() && list[0])
00792                 {
00793                         QGraphicsView * view = list[0];
00794                         qreal factor = view->matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
00795                         if (!(factor < 0.07 || factor > 100))
00796                                 view->scale(scaleFactor, scaleFactor);
00797                 }
00798                 scaleGraphicalTools();
00799         }
00803         void GraphicsScene::zoomIn()
00804         {
00805                 zoom(1.2);
00806         }
00810         void GraphicsScene::zoomOut()
00811         {
00812                 zoom(0.8);
00813         }
00814 
00820         void GraphicsScene::centerOn(const QPointF& point)  const
00821         {
00822                 QList<QGraphicsView*> list = views();
00823                 
00824                 for (int i=0; i < list.size(); ++i)
00825                 {
00826                         QGraphicsView * view = list[i];
00827                         if (view)
00828                                 view->centerOn(point);
00829                 }
00830         }
00836         void GraphicsScene::keyPressEvent (QKeyEvent * keyEvent)
00837         {
00838                 if (!toolTips.isEmpty()) hideToolTips();
00839 
00840                 if (!keyEvent) return;
00841                 keyEvent->setAccepted(false);
00842 
00843                 emit keyPressed(this, keyEvent);
00844                 
00845                 int key = keyEvent->key();
00846 
00847                 if (_useDefaultBehavior)
00848                 {               
00849                         if (selectedItems.size() == 1 && TextGraphicsItem::cast(selectedItems[0]))
00850                         {
00851                                 QGraphicsScene::keyPressEvent(keyEvent);
00852                                 if (!(key == Qt::Key_Escape || 
00853                                           ((key == Qt::Key_Return || key == Qt::Key_Enter) && (keyEvent->modifiers() != 0)))
00854                                           )
00855                                         keyEvent->accept();
00856                         }
00857                         else
00858                         for (int i=0; i < selectedItems.size(); ++i)
00859                                 if (TextGraphicsItem::cast(selectedItems[i]))
00860                                 {
00861                                         TextGraphicsItem * textItem = TextGraphicsItem::cast(selectedItems[i]);
00862                                         textItem->showBorder(false);
00863                                         textItem->setSelected(false);
00864                                         textItem->setTextInteractionFlags(Qt::NoTextInteraction);
00865                                 }
00866                 }
00867 
00868                 if (keyEvent->isAccepted())
00869                 {
00870                         return;
00871                 }
00872 
00873                 if (keyEvent->matches(QKeySequence::Undo))
00874                 {
00875                         if (network)
00876                                 network->undo();
00877                         keyEvent->accept();
00878                         return;
00879                 }
00880 
00881                 if (keyEvent->matches(QKeySequence::Redo))
00882                 {
00883                         if (network)
00884                                 network->redo();
00885                         keyEvent->accept();
00886                         return;
00887                 }
00888 
00889                 if (_useDefaultBehavior)
00890                 {
00891                         if (keyEvent->matches(QKeySequence::Copy))
00892                         {
00893                                 copy();
00894                                 keyEvent->accept();
00895                                 return;
00896                         }
00897 
00898                         if (keyEvent->matches(QKeySequence::Cut))
00899                         {
00900                                 cut();
00901                                 keyEvent->accept();
00902                                 return;
00903                         }
00904 
00905                         if (keyEvent->matches(QKeySequence::Paste))
00906                         {
00907                                 paste();
00908                                 keyEvent->accept();
00909                                 return;
00910                         }
00911 
00912                         if (keyEvent->matches(QKeySequence::SelectAll))
00913                         {
00914                                 selectAll();
00915                                 keyEvent->accept();
00916                                 return;
00917                         }
00918                 }
00919 
00920                 if (key == Qt::Key_Escape || key == Qt::Key_Space)
00921                 {
00922                         emit escapeSignal(network->mainWindow->currentNetworkWindow);
00923                         keyEvent->accept();
00924                 }
00925 
00926                 if ((key == Qt::Key_Plus || key == Qt::Key_Equal || key == Qt::Key_Underscore || key == Qt::Key_Minus)
00927                         && (selectedItems.isEmpty() || (keyEvent->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier))))
00928                 {
00929                         if (key == Qt::Key_Plus || key == Qt::Key_Equal)
00930                         {
00931                                 zoom(qreal(1.2));
00932                                 keyEvent->accept();
00933                         }
00934                         else
00935                                 if (key == Qt::Key_Underscore || key == Qt::Key_Minus)
00936                                 {
00937                                         zoom(1/qreal(1.2));
00938                                         keyEvent->accept();
00939                                 }
00940                 }
00941 
00942                 if (_useDefaultBehavior)
00943                 {
00944                                 if (key == Qt::Key_Delete || key == Qt::Key_Backspace)
00945                                 {
00946                                         if (selectedItems.size() > 0)
00947                                         {
00948                                                 if (movingItemsGroup)
00949                                                 {
00950                                                         destroyItemGroup(movingItemsGroup);
00951                                                         movingItemsGroup = 0;
00952                                                 }
00953                                                 movingItems.clear();
00954                                                 remove(tr("items deleted"), selectedItems);
00955                                                 selectedItems.clear();
00956                                                 keyEvent->accept();
00957                                         }
00958                                 }
00959                                 else
00960                                 {
00961                                         if (!selectedItems.isEmpty() &&
00962                                                 (key == Qt::Key_Up || key == Qt::Key_Down ||
00963                                                 key == Qt::Key_Left || key == Qt::Key_Right))
00964                                         {
00965                                                 qreal dx = 1;
00966                                                 if (keyEvent->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier))
00967                                                         dx = 20;
00968                                                 QPointF change;
00969                                                 if (keyEvent->key() == Qt::Key_Up) change = QPointF(0,-dx);
00970                                                 if (keyEvent->key() == Qt::Key_Down) change = QPointF(0,dx);
00971                                                 if (keyEvent->key() == Qt::Key_Left) change = QPointF(-dx,0);
00972                                                 if (keyEvent->key() == Qt::Key_Right) change = QPointF(dx,0);
00973 
00974                                                 if (gridSz > 0)
00975                                                 {
00976                                                         change.rx() = gridSz * (int)(change.rx() / (double)gridSz + 0.5);
00977                                                         change.ry() = gridSz * (int)(change.ry() / (double)gridSz + 0.5);
00978                                                 }
00979 
00980                                                 move(selectedItems,change);
00981 
00982                                                 keyEvent->accept();
00983                                         }
00984                                         else
00985                                                 QGraphicsScene::keyPressEvent(keyEvent);
00986                                 }
00987                 }
00988         }
00994         void GraphicsScene::keyReleaseEvent (QKeyEvent * keyEvent)
00995         {
00996                 emit keyReleased(this, keyEvent);
00997                 QGraphicsScene::keyReleaseEvent(keyEvent);
00998         }
00999 
01001         void GraphicsScene::select(QGraphicsItem* item)
01002         {
01003                 if (item != 0 && !selectedItems.contains(item))
01004                 {
01005                         selectedItems += item;
01006                         if (!movingItems.contains(item))
01007                                 movingItems += item;
01008                 }
01009                 if (item != 0)
01010                         emit itemsSelected(this, selectedItems, item->scenePos() , Qt::NoModifier);
01011                 else
01012                         emit itemsSelected(this, selectedItems, QPointF() , Qt::NoModifier);
01013 
01014                 showGraphicalTools();
01015         }
01016 
01018         void GraphicsScene::select(const QList<QGraphicsItem*>& items)
01019         {
01020                 for (int i=0; i < items.size(); ++i)
01021                 {
01022                         QGraphicsItem* item = items[i];
01023                         if (item != 0 && !selectedItems.contains(item))
01024                         {
01025                                 selectedItems += item;
01026                                 if (!movingItems.contains(item))
01027                                         movingItems += item;
01028                         }
01029                 }
01030                 
01031                 emit itemsSelected(this, selectedItems, QPointF() , Qt::NoModifier);
01032                 showGraphicalTools();
01033         }
01034 
01036         void GraphicsScene::deselect(QGraphicsItem* item)
01037         {
01038                 if (TextGraphicsItem::cast(item))
01039                 {
01040                         TextGraphicsItem * textItem = TextGraphicsItem::cast(item);
01041                         textItem->showBorder(false);
01042                         textItem->setSelected(false);
01043                         textItem->setTextInteractionFlags(Qt::NoTextInteraction);
01044                 }
01045                 if (selectedItems.contains(item))
01046                 {
01047                         selectedItems.removeAll(item);
01048                         emit itemsSelected(this, selectedItems, item->scenePos() , Qt::NoModifier);
01049                         showGraphicalTools();
01050                 }
01051         }
01052 
01054         void GraphicsScene::deselect()
01055         {
01056                 for (int i=0; i < selectedItems.size(); ++i)
01057                         if (TextGraphicsItem::cast(selectedItems[i]))
01058                         {
01059                                 TextGraphicsItem * textItem = TextGraphicsItem::cast(selectedItems[i]);
01060                                 textItem->showBorder(false);
01061                                 textItem->setSelected(false);
01062                                 textItem->setTextInteractionFlags(Qt::NoTextInteraction);
01063                         }
01064                 selectedItems.clear();
01065                 movingItems.clear();
01066                 if (movingItemsGroup)
01067                 {
01068                         destroyItemGroup(movingItemsGroup);
01069                         movingItemsGroup = 0;
01070                 }
01071                 emit itemsSelected(this, selectedItems, QPointF() , Qt::NoModifier);
01072                 hideGraphicalTools();
01073         }
01074         
01076         void GraphicsScene::fitInView(const QRectF& rect) const
01077         {
01078                 QList<QGraphicsView*> list = views();
01079                 for (int i=0; i < list.size(); ++i)
01080                         if (list[i])
01081                         {
01082                                 list[i]->fitInView(rect,Qt::KeepAspectRatio);
01083                         }
01084         }
01085         
01086         QRect GraphicsScene::mapToWidget(QRectF rect) const
01087         {
01088                 if (!network || !network->mainWindow) return QRect();
01089                 
01090                 if (rect.isNull())
01091                         rect = this->visibleRegion();
01092 
01093                 QList<QGraphicsView*> list = views();
01094                 
01095                 for (int i=0; i < list.size(); ++i)
01096                         if (list[i] && list[i]->isVisible())
01097                         {
01098                                 QPointF p1 = rect.topLeft(), p2 = rect.bottomRight();
01099                                 
01100                                 QPoint pp1 = list[i]->mapFromScene( QPoint((int)p1.x(), (int)p1.y()) ), 
01101                                                         pp2 = list[i]->mapFromScene( QPoint((int)p2.x(), (int)p1.y()) );
01102                                 
01103                                 pp1 = network->mainWindow->mapToGlobal(pp1);
01104                                 pp2 = network->mainWindow->mapToGlobal(pp2);
01105                                 
01106                                 return QRect(pp1,pp2);
01107                         }
01108                 
01109                 return QRect();
01110         }
01111 
01113         void GraphicsScene::fitAll() const
01114         {
01115                 if (!networkWindow) return;
01116                 QRectF rect;//rect = itemsBoundingRect();
01117                 QPointF topLeft(0,0), bottomRight(0,0);
01118                 QGraphicsItem * parent;
01119                 QList<QGraphicsItem*> allItems = items();
01120                 for (int i=0; i < allItems.size(); ++i)
01121                 {
01122                         parent = NodeGraphicsItem::cast(allItems[i]);
01123                         if (!parent)
01124                                 parent = TextGraphicsItem::cast(allItems[i]);
01125                         if (!parent)
01126                                 parent = ConnectionGraphicsItem::cast(allItems[i]);
01127                         if (parent)
01128                         {
01129                                 rect = parent->sceneBoundingRect();
01130                                 if (topLeft.x() == 0 || rect.left() < topLeft.x()) topLeft.rx() = rect.left();
01131                                 if (bottomRight.x() == 0 || rect.right() > bottomRight.x()) bottomRight.rx() = rect.right();
01132 
01133                                 if (topLeft.y() == 0 || rect.top() < topLeft.y()) topLeft.ry() = rect.top();
01134                                 if (bottomRight.y() == 0 || rect.bottom() > bottomRight.y()) bottomRight.ry() = rect.bottom();
01135                         }
01136                 }
01137 
01138         rect = QRectF(topLeft, bottomRight);
01139 
01140         QList<QGraphicsView*> list = views();
01141         for (int i=0; i < list.size(); ++i)
01142                 if (list[i])
01143                     {
01144                         list[i]->fitInView(rect,Qt::KeepAspectRatio);
01145                                 list[i]->centerOn(rect.center());
01146                         }
01147         }
01148 
01150         void GraphicsScene::move(QGraphicsItem * item, const QPointF& distance)
01151         {
01152                 if (!item) return;
01153 
01154                 QPointF change = distance;
01155                 if (gridSz > 0)
01156                 {
01157                         change.rx() = gridSz * (int)(change.rx() / (double)gridSz + 0.5);
01158                         change.ry() = gridSz * (int)(change.ry() / (double)gridSz + 0.5);
01159                 }
01160 
01161                 QList<QPointF> dists;
01162                 QList<QGraphicsItem*> items;
01163                 items += item;
01164                 dists += change;
01165                 
01166                 QList<QUndoCommand*> commands;
01167                 emit itemsAboutToBeMoved(this,items,dists,commands);
01168 
01169                 QUndoCommand * command = new MoveCommand(this,item,distance);
01170                 
01171                 if (!commands.isEmpty())
01172                 {
01173                         QString name = QObject::tr("items moved by (") + QString::number(distance.x()) + QObject::tr(",") + QString::number(distance.y()) + QObject::tr(")");
01174                         commands << command;
01175                         command = new CompositeCommand(name,commands);
01176                 }
01177 
01178                 if (network)
01179                         network->history.push(command);
01180                 else
01181                 {
01182                         command->redo();
01183                         delete command;
01184                 }
01185                 
01186                 NodeGraphicsItem::ControlPoint * nodePoint;
01187                 ConnectionGraphicsItem::ControlPoint * connectionPoint;
01188                 for (int i=0; i < items.size(); ++i)
01189                 {
01190                         nodePoint = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(items[i]);
01191                         if (nodePoint && !items.contains(nodePoint->nodeItem))
01192                         {
01193                                 items += nodePoint->nodeItem;
01194                                 dists += QPointF(0,0);
01195                         }
01196                         else
01197                         {
01198                                 connectionPoint = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(items[i]);
01199                                 if (connectionPoint && !items.contains(connectionPoint->connectionItem))
01200                                 {
01201                                         items += connectionPoint->connectionItem;
01202                                         dists += QPointF(0,0);
01203                                 }
01204                         }
01205                 }
01206                 emit itemsMoved(this,items,dists);
01207 
01208                 QPointF p = item->scenePos();
01209                 if (p.rx() > this->width() || p.ry() > this->height())
01210                 {
01211                         setSceneRect(0,0,this->width()*2, this->height()*2);
01212                 }
01213         }
01214 
01216         void GraphicsScene::move(const QList<QGraphicsItem*>& items0, const QPointF& distance0)
01217         {
01218                 QList<QGraphicsItem*> items = items0;
01219                 QPointF distance = distance0;
01220                 
01221                 QPointF change = distance;
01222                 if (gridSz > 0)
01223                 {
01224                         change.rx() = gridSz * (int)(change.rx() / (double)gridSz + 0.5);
01225                         change.ry() = gridSz * (int)(change.ry() / (double)gridSz + 0.5);
01226                 }
01227                 
01228                 QList<QPointF> dists;
01229                 while (dists.size() < items.size()) dists << change;
01230 
01231                 QList<QUndoCommand*> commands;
01232                 
01233                 emit itemsAboutToBeMoved(this,items,dists,commands);
01234 
01235                 QUndoCommand * command = new MoveCommand(this,items, distance);
01236                 
01237                 if (!commands.isEmpty())
01238                 {
01239                         QString name = QObject::tr("items moved by (") + QString::number(distance.x()) + QObject::tr(",") + QString::number(distance.y()) + QObject::tr(")");
01240                         commands << command;
01241                         command = new CompositeCommand(name,commands);
01242                 }
01243 
01244                 if (network)
01245                         network->history.push(command);
01246                 else
01247                 {
01248                         command->redo();
01249                         delete command;
01250                 }
01251                 
01252                 NodeGraphicsItem::ControlPoint * nodePoint;
01253                 ConnectionGraphicsItem::ControlPoint * connectionPoint;
01254                 for (int i=0; i < items.size(); ++i)
01255                 {
01256                         nodePoint = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(items[i]);
01257                         if (nodePoint && !items.contains(nodePoint->nodeItem))
01258                         {
01259                                 items += nodePoint->nodeItem;
01260                                 dists += QPointF(0,0);
01261                         }
01262                         else
01263                         {
01264                                 connectionPoint = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(items[i]);
01265                                 if (connectionPoint && !items.contains(connectionPoint->connectionItem))
01266                                 {
01267                                         items += connectionPoint->connectionItem;
01268                                         dists += QPointF(0,0);
01269                                 }
01270                         }
01271                 }
01272                 emit itemsMoved(this,items,dists);
01273 
01274                 QPointF p;
01275                 for (int i=0; i < items.size(); ++i)
01276                         if (items[i])
01277                         {
01278                                 QPointF p = items[i]->scenePos();
01279                                 if (p.rx() > this->width() || p.ry() > this->height())
01280                                 {
01281                                         setSceneRect(0,0,this->width()*2, this->height()*2);
01282                                         return;
01283                                 }
01284                         }
01285 
01286         }
01288         void GraphicsScene::move(const QList<QGraphicsItem*>& items0, const QList<QPointF>& distance)
01289         {
01290                 QList<QGraphicsItem*> items = items0;
01291                 QList<QPointF> dists = distance;
01292 
01293                 if (gridSz > 0)
01294                 {
01295                         for (int i=0; i < dists.size(); ++i)
01296                         {
01297                                 dists[i].rx() = gridSz * (int)(dists[i].rx() / (double)gridSz + 0.5);
01298                                 dists[i].ry() = gridSz * (int)(dists[i].ry() / (double)gridSz + 0.5);
01299                         }
01300                 }
01301 
01302                 QList<QUndoCommand*> commands;
01303                 emit itemsAboutToBeMoved(this,items,dists,commands);
01304 
01305                 QUndoCommand * command = new MoveCommand(this,items, distance);
01306                 
01307                 if (!commands.isEmpty())
01308                 {
01309                         QString name = QObject::tr("items moved by ...");
01310                         commands << command;
01311                         command = new CompositeCommand(name,commands);
01312                 }
01313 
01314                 if (network)
01315                         network->history.push(command);
01316                 else
01317                 {
01318                         command->redo();
01319                         delete command;
01320                 }
01321 
01322                 while (dists.size() < items.size()) dists << QPointF();
01323 
01324                 NodeGraphicsItem::ControlPoint * nodePoint;
01325                 ConnectionGraphicsItem::ControlPoint * connectionPoint;
01326                 for (int i=0; i < items.size(); ++i)
01327                 {
01328                         nodePoint = qgraphicsitem_cast<NodeGraphicsItem::ControlPoint*>(items[i]);
01329                         if (nodePoint && !items.contains(nodePoint->nodeItem))
01330                         {
01331                                 items += nodePoint->nodeItem;
01332                                 dists += QPointF(0,0);
01333                         }
01334                         else
01335                         {
01336                                 connectionPoint = qgraphicsitem_cast<ConnectionGraphicsItem::ControlPoint*>(items[i]);
01337                                 if (connectionPoint && !items.contains(connectionPoint->connectionItem))
01338                                 {
01339                                         items += connectionPoint->connectionItem;
01340                                         dists += QPointF(0,0);
01341                                 }
01342                         }
01343                 }
01344                 emit itemsMoved(this,items,dists);
01345 
01346                 QPointF p;
01347                 for (int i=0; i < items.size(); ++i)
01348                         if (items[i])
01349                         {
01350                                 QPointF p = items[i]->scenePos();
01351                                 if (p.rx() > this->width() || p.ry() > this->height())
01352                                 {
01353                                         setSceneRect(0,0,this->width()*2, this->height()*2);
01354                                         return;
01355                                 }
01356                         }
01357         }
01358 
01359         void GraphicsScene::insert(const QString& name, QGraphicsItem * item, InsertType type)
01360         {
01361                 if (!network) return;
01362                 
01363                 QList<ItemHandle*> handles;
01364                 QList<QGraphicsItem*> items;
01365                 items.append(item);
01366 
01367                 ItemHandle* handle = getHandle(item);
01368                 if (handle)
01369                         handles += handle;
01370 
01371                 QList<QUndoCommand*> commands;
01372                 emit itemsAboutToBeInserted(this,items,handles,commands,type);
01373                 
01374                 QUndoCommand * command = new InsertGraphicsCommand(name, this, items);
01375                 
01376                 if (!commands.isEmpty())
01377                 {
01378                         commands << command;
01379                         command = new CompositeCommand(name,commands);
01380                 }
01381                 
01382                 network->history.push(command);
01383                 emit itemsInserted(this,items,handles,type);
01384                 network->symbolsTable.update();
01385         }
01386 
01388         void GraphicsScene::insert(const QString& name, const QList<QGraphicsItem*>& items, InsertType type)
01389         {
01390                 if (!network) return;
01391                 QList<ItemHandle*> handles;
01392                 QList<QGraphicsItem*> allItems = items;
01393 
01394                 ItemHandle * handle;
01395 
01396                 for (int i=0; i < items.size(); ++i)
01397                 {
01398                         handle = getHandle(items[i]);
01399                         if (handle && !handles.contains(handle))
01400                         {
01401                                 handles += handle;
01402                         }
01403                 }
01404 
01405                 QList<QUndoCommand*> commands;
01406                 emit itemsAboutToBeInserted(this,allItems,handles,commands, type);
01407 
01408                 QUndoCommand * command = new InsertGraphicsCommand(name, this, allItems);
01409                 
01410                 if (!commands.isEmpty())
01411                 {
01412                         commands << command;
01413                         command = new CompositeCommand(name,commands);
01414                 }
01415 
01416                 network->history.push(command);
01417 
01418                 emit itemsInserted(this,allItems,handles, type);
01419                 network->symbolsTable.update();
01420         }
01422         void GraphicsScene::remove(const QString& name, QGraphicsItem * item)
01423         {
01424                 if (!network) return;
01425                 
01426                 ItemHandle * handle = getHandle(item);
01427 
01428                 QList<QGraphicsItem*> allitems;
01429                 QList<QGraphicsItem*> items2;
01430 
01431                 QList<ItemHandle*> handles;
01432                 allitems << item;
01433 
01434                 if (handle)
01435                 {
01436                         handles << handle;
01437                         QList<ItemHandle*> handles2 = handle->allChildren();
01438                         for (int j=0; j < handles2.size(); ++j)
01439                                 if (handles2[j])
01440                                         allitems << handles2[j]->allGraphicsItems();
01441                 }
01442 
01443                 QList<QUndoCommand*> commands;          
01444                 emit itemsAboutToBeRemoved(this,allitems,handles,commands);
01445 
01446                 QUndoCommand * command = new RemoveGraphicsCommand(name, allitems);
01447                 
01448                 if (!commands.isEmpty())
01449                 {
01450                         commands << command;
01451                         command = new CompositeCommand(name,commands);
01452                 }
01453 
01454                 network->history.push(command);
01455                 deselect();
01456                 emit itemsRemoved(this,allitems,handles);
01457                 network->symbolsTable.update();
01458         }
01460         void GraphicsScene::remove(const QString& name, const QList<QGraphicsItem*>& items)
01461         {
01462                 if (!network) return;
01463 
01464                 QList<QGraphicsItem*> allitems, items2;
01465 
01466                 QList<ItemHandle*> handles, handles2;
01467                 ItemHandle * handle = 0;
01468 
01469                 for (int i=0; i < items.size(); ++i)
01470                         if (items[i])
01471                         {
01472                                 handle = getHandle(items[i]);
01473                                 allitems << items[i];
01474 
01475                                 if (handle)
01476                                 {
01477                                         handles << handle;
01478                                         handles2 = handle->allChildren();
01479                                         for (int j=0; j < handles2.size(); ++j)
01480                                                 if (handles2[j])
01481                                                         allitems << handles2[j]->allGraphicsItems();
01482                                 }
01483                         }
01484 
01485                 QList<QUndoCommand*> commands;          
01486                 emit itemsAboutToBeRemoved(this,allitems,handles,commands);
01487 
01488                 QUndoCommand * command = new RemoveGraphicsCommand(name, allitems);
01489                 
01490                 if (!commands.isEmpty())
01491                 {
01492                         commands << command;
01493                         command = new CompositeCommand(name,commands);
01494                 }
01495 
01496                 network->history.push(command);
01497                 deselect();
01498                 emit itemsRemoved(this,allitems, handles);
01499                 network->symbolsTable.update();
01500         }
01502         void GraphicsScene::setBrush(const QString& name, QGraphicsItem * item, const QBrush& to)
01503         {
01504                 QUndoCommand * command = new ChangeBrushCommand(name, item, to);
01505 
01506                 if (network)
01507                         network->history.push(command);
01508                 else
01509                 {
01510                         command->redo();
01511                         delete command;
01512                 }
01513 
01514                 QList<QGraphicsItem*> list;
01515                 list += item;
01516                 emit colorChanged(this,list);
01517         }
01519         void GraphicsScene::setBrush(const QString& name, const QList<QGraphicsItem*>& items, const QList<QBrush>& to)
01520         {
01521                 QUndoCommand * command = new ChangeBrushCommand(name, items, to);
01522 
01523                 if (network)
01524                         network->history.push(command);
01525                 else
01526                 {
01527                         command->redo();
01528                         delete command;
01529                 }
01530 
01531                 emit colorChanged(this,items);
01532         }
01534         void GraphicsScene::setPen(const QString& name, QGraphicsItem * item, const QPen& to)
01535         {       
01536                 QUndoCommand * command = new ChangePenCommand(name, item, to);
01537 
01538                 if (network)
01539                         network->history.push(command);
01540                 else
01541                 {
01542                         command->redo();
01543                         delete command;
01544                 }
01545 
01546                 QList<QGraphicsItem*> list;
01547                 list += item;
01548                 emit colorChanged(this,list);
01549         }
01551         void GraphicsScene::setPen(const QString& name, const QList<QGraphicsItem*>& items, const QList<QPen>& to)
01552         {
01553                 QUndoCommand * command = new ChangePenCommand(name, items, to);
01554 
01555                 if (network)
01556                         network->history.push(command);
01557                 else
01558                 {
01559                         command->redo();
01560                         delete command;
01561                 }
01562 
01563                 emit colorChanged(this,items);
01564         }
01565 
01567         void GraphicsScene::setBrushAndPen(const QString& name, QGraphicsItem * item, const QBrush& newBrush, const QPen& newPen)
01568         {
01569                 QUndoCommand * command = new ChangeBrushAndPenCommand(name, item, newBrush, newPen);
01570 
01571                 if (network)
01572                         network->history.push(command);
01573                 else
01574                 {
01575                         command->redo();
01576                         delete command;
01577                 }
01578 
01579                 QList<QGraphicsItem*> list;
01580                 list += item;
01581                 emit colorChanged(this,list);
01582         }
01584         void GraphicsScene::setBrushAndPen(const QString& name, const QList<QGraphicsItem*>& items, const QList<QBrush>& newBrushes, const QList<QPen>& newPens)
01585         {
01586                 QUndoCommand * command = new ChangeBrushAndPenCommand(name, items, newBrushes, newPens);
01587 
01588                 if (network)
01589                         network->history.push(command);
01590                 else
01591                 {
01592                         command->redo();
01593                         delete command;
01594                 }
01595 
01596                 emit colorChanged(this,items);
01597         }
01598 
01600         void GraphicsScene::setParentItem(const QString& name, QGraphicsItem* item, QGraphicsItem* newParent)
01601         {
01602                 QUndoCommand * command = new ChangeParentCommand(name, this, item, newParent);
01603 
01604                 if (network)
01605                         network->history.push(command);
01606                 else
01607                 {
01608                         command->redo();
01609                         delete command;
01610                 }
01611 
01612                 QList<QGraphicsItem*> items, newParents;
01613                 items += item;
01614                 newParents += newParent;
01615                 emit parentItemChanged(this,items,newParents);
01616         }
01618         void GraphicsScene::setParentItem(const QString& name, const QList<QGraphicsItem*>& items, QGraphicsItem* newParent)
01619         {
01620                 QList<QGraphicsItem*> newParents;
01621                 for (int i=0; i < items.size(); ++i)
01622                         newParents += newParent;
01623 
01624                 QUndoCommand * command = new ChangeParentCommand(name, this, items, newParents);
01625 
01626                 if (network)
01627                         network->history.push(command);
01628                 else
01629                 {
01630                         command->redo();
01631                         delete command;
01632                 }
01633 
01634                 emit parentItemChanged(this,items,newParents);
01635         }
01637         void GraphicsScene::setParentItem(const QString& name, const QList<QGraphicsItem*>& items, const QList<QGraphicsItem*>& newParents)
01638         {
01639                 QUndoCommand * command = new ChangeParentCommand(name, this, items, newParents);
01640 
01641                 if (network)
01642                         network->history.push(command);
01643                 else
01644                 {
01645                         command->redo();
01646                         delete command;
01647                 }
01648 
01649                 emit parentItemChanged(this,items,newParents);
01650         }
01651 
01653         void GraphicsScene::setZValue(const QString& name, QGraphicsItem * item, double to)
01654         {
01655                 QUndoCommand * command = new ChangeZCommand(name, this, item, to);
01656 
01657                 if (network)
01658                         network->history.push(command);
01659                 else
01660                 {
01661                         command->redo();
01662                         delete command;
01663                 }
01664         }
01665 
01667         void GraphicsScene::setZValue(const QString& name, const QList<QGraphicsItem*>& items, const QList<double>& to)
01668         {
01669                 QUndoCommand * command = new ChangeZCommand(name, this, items, to);
01670 
01671                 if (network)
01672                         network->history.push(command);
01673                 else
01674                 {
01675                         command->redo();
01676                         delete command;
01677                 }
01678 
01679         }
01680 
01682         void GraphicsScene::transform(const QString& name, QGraphicsItem * item,
01683                 const QPointF& sizechange,
01684                 qreal anglechange,
01685                 bool VFlip, bool HFlip)
01686         {
01687 
01688                 QUndoCommand * command = new TransformCommand(name, this, item,
01689                         sizechange,
01690                         anglechange,
01691                         VFlip, HFlip);
01692                 if (network)
01693                         network->history.push(command);
01694                 else
01695                 {
01696                         command->redo();
01697                         delete command;
01698                 }
01699         }
01701         void GraphicsScene::transform(const QString& name, const QList<QGraphicsItem*>& items,
01702                 const QList<QPointF>& sizechange,
01703                 const QList<qreal>& anglechange,
01704                 const QList<bool>& VFlip,
01705                 const QList<bool>& HFlip)
01706         {
01707 
01708                 QUndoCommand * command = new TransformCommand(name, this, items,
01709                         sizechange,
01710                         anglechange,
01711                         VFlip, HFlip);
01712 
01713                 if (network)
01714                         network->history.push(command);
01715                 else
01716                 {
01717                         command->redo();
01718                         delete command;
01719                 }
01720         }
01721 
01723         void GraphicsScene::print(QPaintDevice * printer, const QRectF& region)
01724         {
01725                 if (!network) return;
01726                 
01727                 QPainter painter(printer);
01728                 //painter.setBackgroundMode(Qt::OpaqueMode);
01729                 painter.setBackground(QBrush(Qt::white));
01730                 //painter.setRenderHints(QPainter::Antialiasing | QPainter::NonCosmeticDefaultPen | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
01731                 painter.setRenderHint(QPainter::Antialiasing);
01732                 if (region.isNull())
01733                         render(&painter, QRectF(), itemsBoundingRect());
01734                 else
01735                         render(&painter, QRectF(), region);
01736 
01737                 //QList<QGraphicsView*> list = views();         
01738                 //if (list.isEmpty() || !list[0]) return;
01739 
01740                 /*
01741                 painter.fillRect(rect,QBrush(Qt::white));
01742                 QGraphicsView * view = list[0];
01743                 QPointF p1 = view->mapFromScene(region.topLeft()),
01744                                 p2 = view->mapFromScene(region.bottomRight());
01745                 view->render(&painter,QRectF(p1,p2));*/
01746         }
01747 
01748         void GraphicsScene::clearStaticItems()
01749         {
01750                 ConnectionGraphicsItem * connection = 0;
01751                 QList<QGraphicsItem*> list = duplicateItems;
01752 
01753                 for (int i=0; i < list.size(); ++i)
01754                         if ((connection = ConnectionGraphicsItem::cast(list[i])))
01755                         {
01756                                 QList<ArrowHeadItem*> arrowHeads = connection->arrowHeads();
01757                                 for (int j=0; j < arrowHeads.size(); ++j)
01758                                 {
01759                                         duplicateItems.removeAll(arrowHeads[j]);
01760                                 }
01761                                 duplicateItems.removeAll(connection->centerRegionItem);
01762                         }
01763 
01764         for (int i=0; i < duplicateItems.size(); ++i)
01765             if (duplicateItems[i])
01766                 delete duplicateItems[i];
01767 
01768         duplicateItems.clear();
01769         }
01770 
01771         void GraphicsScene::copy()
01772         {
01773                 QList<QGraphicsItem*> items = selectedItems;
01774 
01775                 if (items.size() < 1) return;
01776 
01777                 clearStaticItems();
01778 
01779                 QList<ItemHandle*> allNewHandles;
01780                 GraphicsScene::duplicateItems = cloneGraphicsItems(items,allNewHandles);
01781 
01782                 emit copyItems(this,duplicateItems,allNewHandles);
01783                 
01784                 deselect();
01785 
01786                 TextGraphicsItem* textItem = 0;
01787                 QClipboard * clipboard = QApplication::clipboard();
01788                 if (clipboard)
01789                 {
01790                         if (items.size() == 1 && (textItem = TextGraphicsItem::cast(items[0])))
01791                         {
01792                                 clipboard->setText( textItem->toPlainText() );
01793                         }
01794                         else
01795                         {
01796                                 QRectF rect(0,0,0,0);
01797                                 
01798                                 for (int i=0; i < items.size(); ++i)
01799                                         rect = rect.united(items[i]->sceneBoundingRect());
01800                                 
01801                                 int w = 800;
01802                                 int h = (int)(rect.height() * w/rect.width());
01803                                 QImage image(w,h,QImage::Format_ARGB32);
01804                                 image.fill( QColor(Qt::white).rgb() );
01805                                 print(&image,rect);
01806                                 clipboard->setImage(image);
01807                         }
01808                 }
01809                 
01810                 select(items);
01811                 GraphicsScene::copiedFromScene = this;
01812         }
01813 
01814         void GraphicsScene::cut()
01815         {
01816                 GraphicsScene * scene = this;
01817 
01818                 QList<QGraphicsItem*> items = scene->selected();
01819 
01820                 if (items.size() < 1) return;
01821 
01822                 TextGraphicsItem* textItem = 0;
01823                 QClipboard * clipboard = QApplication::clipboard();
01824 
01825                 if (clipboard && !clipboard->text().isEmpty() && items.size() == 1 && (textItem = TextGraphicsItem::cast(items[0])))
01826                 {
01827                         clipboard->setText( textItem->toPlainText() );
01828                 }
01829 
01830                 clearStaticItems();
01831 
01832                 QList<ItemHandle*> allNewHandles;
01833 
01834                 GraphicsScene::duplicateItems = cloneGraphicsItems(items,allNewHandles);
01835 
01836                 emit copyItems(this,duplicateItems,allNewHandles);
01837 
01838                 scene->remove(tr("cut items"),scene->selected());
01839 
01840                 GraphicsScene::copiedFromScene = scene;
01841         }
01842 
01843         void GraphicsScene::removeSelected()
01844         {
01845                 if (selectedItems.size() < 1) return;
01846 
01847                 remove(tr("items deleted"),selectedItems);
01848 
01849                 selectedItems.clear();
01850 
01851                 select(0);
01852         }
01853 
01854         void GraphicsScene::selectAll()
01855         {
01856                 GraphicsScene * scene = this;
01857 
01858                 QList<QGraphicsItem*> list;
01859                 QList<QGraphicsItem*> items = scene->items();
01860 
01861                 for (int i=0; i < items.size(); ++i)
01862                 {
01863                         QGraphicsItem * g = getGraphicsItem(items[i]);
01864                         if (g && ControlPoint::cast(g) == 0 && ToolGraphicsItem::cast(g->topLevelItem()) == 0)
01865                                 list += g;
01866                 }
01867 
01868                 scene->select(list);
01869         }
01870 
01871         void GraphicsScene::paste()
01872         {
01873                 if (!network) return;
01874 
01875                 TextGraphicsItem* textItem = 0;
01876                 QClipboard * clipboard = QApplication::clipboard();
01877                 if (clipboard && !clipboard->text().isEmpty() && selectedItems.size() == 1 && (textItem = TextGraphicsItem::cast(selectedItems[0])))
01878                 {
01879                         textItem->setPlainText( textItem->toPlainText() + clipboard->text() );
01880                         return;
01881                 }
01882 
01883                 QList<QGraphicsItem*> items = duplicateItems;
01884 
01885                 QString name;
01886                 QList<ItemHandle*> handles;
01887                 QList<QGraphicsItem*> moveitems;
01888                 ConnectionGraphicsItem * connection = 0;
01889 
01890                 if (items.size() < 1) return;
01891 
01892                 for (int i=0; i < duplicateItems.size(); ++i)
01893                 {
01894                         if ((connection = ConnectionGraphicsItem::cast(duplicateItems[i])))
01895                         {
01896                                 if (copiedFromScene != this)
01897                                 {
01898                                         QList<NodeGraphicsItem*> allNodes = connection->nodes();
01899                                         for (int j=0; j < allNodes.size(); ++j)
01900                                                 if (allNodes[j] && !duplicateItems.contains(allNodes[j]))
01901                                                 {
01902                                                         items.removeAll(connection);
01903                                                         delete connection;
01904                                                         break;
01905                                                 }
01906                                 }
01907                         }
01908                 }
01909 
01910                 QList<ItemHandle*> allNewHandles;
01911                 
01912                 GraphicsScene::duplicateItems = cloneGraphicsItems(items,allNewHandles);
01913                 
01914                 emit copyItems(this,duplicateItems,allNewHandles);
01915 
01916                 QList<QUndoCommand*> commands;
01917 
01918                 QPointF center;
01919                 int n = 0;
01920                 for (int i=0; i < items.size(); ++i)
01921                         if (items[i])
01922                         {
01923                                 if ((connection = ConnectionGraphicsItem::cast(items[i])))
01924                                 {
01925                                         QList<ConnectionGraphicsItem::ControlPoint*> cps = connection->controlPoints();
01926                                         for (int j=0; j < cps.size(); ++j)
01927                                         {
01928                                                 moveitems += cps[j];
01929                                                 center += cps[j]->scenePos();
01930                                                 ++n;
01931                                         }
01932                                 }
01933                                 else
01934                                 {
01935                                         moveitems += items[i];
01936                                         center += items[i]->scenePos();
01937                                         ++n;
01938                                 }
01939                         }
01940 
01941                 if (n > 1)
01942                         center /= n;
01943 
01944                 if (!lastPoint().isNull())
01945                 {
01946                         commands << new MoveCommand(this,moveitems,lastPoint() - center);
01947                         lastPoint() += QPointF(10.0,10.0);
01948                 }
01949 
01950                 QStringList allItems (network->symbolsTable.uniqueHandlesWithDot.keys());
01951                 allItems << network->symbolsTable.uniqueHandlesWithUnderscore.keys()
01952                                  << network->symbolsTable.uniqueDataWithDot.keys()
01953                                  << network->symbolsTable.uniqueDataWithUnderscore.keys();
01954                 QList<ItemHandle*> itemsToRename;
01955                 QList<QString> newNames;
01956                 ItemHandle *handle1;
01957                 for (int i=0; i < items.size(); ++i)
01958                 {
01959                         handle1 = getHandle(items[i]);
01960                         if (handle1 && !handles.contains(handle1))
01961                         {
01962                                 handles << handle1;
01963                                 handles << handle1->allChildren();
01964                         }
01965                 }
01966 
01967                 emit itemsAboutToBeInserted(this,items,handles,commands,PASTED);
01968 
01969                 for (int i=0; i < handles.size(); ++i)
01970                 {
01971                         handle1 = handles[i];
01972                         if (!handle1->parent || !handles.contains(handle1->parent))
01973                         {
01974                                 QString name0 = handle1->fullName();
01975                                 name = name0;
01976 
01977                                 while (name0.size() > 1 && name0[name0.length()-1].isNumber())
01978                                         name0.chop(1);
01979 
01980                                 bool unique = false;
01981                                 int c = 1;
01982                                 while (!unique)
01983                                 {
01984                                         unique = true;
01985                                         for (int j=0; j < allItems.size(); ++j)
01986                                         {
01987                                                 if (allItems[j] == name)
01988                                                 {
01989                                                         unique = false;
01990                                                         break;
01991                                                 }
01992                                         }
01993                                         if (!unique)
01994                                         {
01995                                                 name = name0 + QString::number(c);
01996                                                 ++c;
01997                                         }
01998                                 }
01999                                 allItems << name;
02000                                 itemsToRename << handles[i];
02001                                 newNames << name;
02002                         }
02003                 }
02004 
02005                 commands << new RenameCommand(tr("items renamed after pasting"),network,handles,itemsToRename,newNames);
02006                 commands << new InsertGraphicsCommand(tr("paste items"),this,items);
02007                 
02008                 clearSelection();
02009 
02010                 QUndoCommand * compositeCommand = new CompositeCommand(tr("paste items"),commands);
02011 
02012                 network->push(compositeCommand);
02013 
02014         emit itemsInserted(this,items,handles,PASTED);
02015         network->symbolsTable.update();
02016                 select(items);
02017         }
02018 
02019         void GraphicsScene::find(const QStringList& textlist)
02020         {
02021                 for (int i=0; i < textlist.size(); ++i)
02022                         find(textlist[i],false);
02023         }
02024 
02025         void GraphicsScene::find(const QString& text, bool clearSelected)
02026         {
02027                 if (!network || text.isNull() || text.isEmpty()) return;
02028                 
02029                 SymbolsTable * symbolsTable = &network->symbolsTable;
02030                 NodeGraphicsItem* node = 0;
02031                 ConnectionGraphicsItem* connection = 0;
02032 
02033                 if (symbolsTable->uniqueHandlesWithDot.contains(text) ||
02034                         symbolsTable->uniqueHandlesWithUnderscore.contains(text) ||
02035                         symbolsTable->uniqueDataWithDot.contains(text) || 
02036                         symbolsTable->uniqueDataWithUnderscore.contains(text))
02037                 {
02038                         ItemHandle * handle = 0;
02039                         if (symbolsTable->uniqueHandlesWithDot.contains(text))
02040                                 handle = symbolsTable->uniqueHandlesWithDot[text];
02041                         else
02042                         if (symbolsTable->uniqueHandlesWithUnderscore.contains(text))
02043                                 handle = symbolsTable->uniqueHandlesWithUnderscore[text];
02044                         else
02045                         if (symbolsTable->uniqueDataWithDot.contains(text))
02046                                 handle = symbolsTable->uniqueDataWithDot[text].first;
02047                         else
02048                         if (symbolsTable->uniqueDataWithUnderscore.contains(text))
02049                                 handle = symbolsTable->uniqueDataWithUnderscore[text].first;
02050                                 
02051                         if (!handle) return;
02052 
02053                         bool alreadySelected = true;
02054                         for (int i=0; i < handle->graphicsItems.size(); ++i)
02055                                 if (handle->graphicsItems[i])
02056                                         if (!selectedItems.contains(handle->graphicsItems[i]))
02057                                         {
02058                                                 alreadySelected = false;
02059                                                 break;
02060                                         }
02061                                 if (!alreadySelected)
02062                                 {
02063                                         if (clearSelected)
02064                                                 selectedItems.clear();
02065 
02066                                         for (int j=0; j < handle->graphicsItems.size(); ++j)
02067                                                 if (handle->graphicsItems[j])
02068                                                         if (!selectedItems.contains(handle->graphicsItems[j]))
02069                                                                 selectedItems += handle->graphicsItems[j];
02070 
02071                                         QPointF p(0,0);
02072                                         for (int j=0; j < handle->graphicsItems.size(); ++j)
02073                                                 p += handle->graphicsItems[j]->sceneBoundingRect().center();
02074 
02075                                         p /= handle->graphicsItems.size();
02076                                         if (clearSelected)
02077                                                 centerOn(p);
02078 
02079                                         emit itemsSelected(this,selectedItems,QPointF(),Qt::NoModifier);
02080                                         showGraphicalTools();
02081                                         return;
02082                                 }
02083                 }
02084                 
02085                 if (symbolsTable->nonuniqueHandles.contains(text) ||
02086                         symbolsTable->nonuniqueData.contains(text))
02087                 {
02088 
02089                         if (clearSelected)
02090                                 selectedItems.clear();
02091 
02092                         QList<ItemHandle*> items;
02093                         
02094                         if (symbolsTable->nonuniqueHandles.contains(text))
02095                         {
02096                                 items = symbolsTable->nonuniqueHandles.values(text);
02097                         }
02098                         
02099                         if (symbolsTable->nonuniqueData.contains(text))
02100                         {
02101                                 QList< QPair<ItemHandle*,QString> > pairs = symbolsTable->nonuniqueData.values(text);
02102                                 for (int i=0; i < pairs.size(); ++i)
02103                                         items << pairs[i].first;
02104                         }
02105                         
02106                         for (int i=0; i < items.size(); ++i)
02107                         {
02108                                 ItemHandle * handle = items[i];                         
02109                                 if (!handle) continue;
02110 
02111                                 bool alreadySelected = true;
02112                                 for (int i=0; i < handle->graphicsItems.size(); ++i)
02113                                         if (handle->graphicsItems[i])
02114                                                 if (!selectedItems.contains(handle->graphicsItems[i]))
02115                                                 {
02116                                                         alreadySelected = false;
02117                                                         break;
02118                                                 }
02119                                 if (!alreadySelected)
02120                                         selectedItems += handle->graphicsItems;
02121                         }
02122                         
02123                         QPointF p(0,0);
02124                         for (int j=0; j < selectedItems.size(); ++j)
02125                                 p += selectedItems[j]->scenePos();
02126                         p /= selectedItems.size();
02127                         emit itemsSelected(this,selectedItems,QPointF(),Qt::NoModifier);
02128                         showGraphicalTools();
02129                 }
02130         }
02131 
02132         QList<QGraphicsItem*> GraphicsScene::duplicateItems;
02133         GraphicsScene* GraphicsScene::copiedFromScene;
02134 
02135         void GraphicsScene::enableGrid(int sz)
02136         {
02137                 setGridSize(sz);
02138         }
02139 
02140         void GraphicsScene::disableGrid()
02141         {
02142                 setGridSize(0);
02143         }
02144 
02145         void GraphicsScene::setGridSize(int sz)
02146         {
02147                 gridSz = sz;
02148         }
02149 
02150         int GraphicsScene::gridSize() const
02151         {
02152                 return gridSz;
02153         }
02154 
02155         void GraphicsScene::snapToGrid(QGraphicsItem * item)
02156         {
02157                 if (!item || gridSz < 1) return;
02158 
02159                 ControlPoint * cp = ControlPoint::cast(item);
02160 
02161                 if (cp)
02162                 {
02163                         QPointF p1 = cp->scenePos();
02164 
02165                         p1.rx() = gridSz * (int)(p1.rx() / (double)gridSz + 0.5);
02166                         p1.ry() = gridSz * (int)(p1.ry() / (double)gridSz + 0.5);
02167 
02168                         cp->setPos(p1);
02169 
02170                         return;
02171                 }
02172 
02173                 NodeGraphicsItem * node = NodeGraphicsItem::cast(item);
02174 
02175                 if (node)
02176                 {
02177                         QPointF p1 = node->sceneBoundingRect().topLeft();
02178                         QPointF p2 = node->sceneBoundingRect().bottomRight();
02179 
02180                         p1.rx() = gridSz * (int)(p1.rx() / (double)gridSz + 0.5);
02181                         p1.ry() = gridSz * (int)(p1.ry() / (double)gridSz + 0.5);
02182                         p2.rx() = gridSz * (int)(p2.rx() / (double)gridSz + 0.5);
02183                         p2.ry() = gridSz * (int)(p2.ry() / (double)gridSz + 0.5);
02184 
02185                         if (p2.rx() == p1.rx()) p2.rx() += gridSz;
02186                         if (p2.ry() == p1.ry()) p2.ry() += gridSz;
02187 
02188                         node->setBoundingRect(p1,p2);
02189                 }
02190         }
02191 
02192         void GraphicsScene::drawBackground( QPainter* painter, const QRectF & rect)
02193         {
02194                 if (gridSz < 1) return;
02195 
02196                 painter->setPen(GridPen);
02197                 qreal left = rect.left(), right = rect.right(),
02198                           top = rect.top(), bottom = rect.bottom();
02199                 QPointF p1,p2;
02200 
02201                 p1.rx() = left;
02202                 p1.ry() = top;
02203                 p2.rx() = left;
02204                 p2.ry() = bottom;
02205 
02206                 left = gridSz * (int)(left/gridSz);
02207 
02208                 for (qreal x = left; x < right; x += gridSz)
02209                 {
02210                         p1.rx() = p2.rx() = x;
02211                         painter->drawLine(p1,p2);
02212                 }
02213 
02214                 p1.rx() = left;
02215                 p1.ry() = top;
02216                 p2.rx() = right;
02217                 p2.ry() = top;
02218 
02219                 top = gridSz * (int)(top/gridSz);
02220 
02221                 for (qreal y = top; y < bottom; y += gridSz)
02222                 {
02223                         p1.ry() = p2.ry() = y;
02224                         painter->drawLine(p1,p2);
02225                 }
02226         }
02227         
02228         MainWindow * GraphicsScene::mainWindow() const
02229         {
02230                 if (network)
02231                         return network->mainWindow;
02232                 return 0;
02233         }
02234         
02235         ConsoleWindow * GraphicsScene::console() const
02236         {
02237                 if (network && network->mainWindow)
02238                         return network->mainWindow->console();
02239                 return 0;
02240         }
02241         
02242         ItemHandle * GraphicsScene::localHandle() const
02243         {
02244                 if (networkWindow)
02245                         return networkWindow->handle;
02246                 return 0;
02247         }
02248         
02249         ItemHandle * GraphicsScene::globalHandle() const
02250         {
02251                 if (network)
02252                         return network->globalHandle();
02253                 return 0;
02254         }
02255         
02256         void GraphicsScene::selectConnections(const QPointF& point)
02257         {
02258                 ConnectionGraphicsItem * connection = 0;
02259                 NodeGraphicsItem * node = 0;
02260 
02261                 for (int i=movingItems.size()-1; i >= 0; --i)
02262                         if (movingItems[i] != 0)
02263                         {
02264                                 if ((connection = ConnectionGraphicsItem::topLevelConnectionItem(movingItems[i])))
02265                                 {
02266                                         movingItems.removeAt(i);
02267 
02268                                         for (int i=0; i < connection->curveSegments.size(); ++i)
02269                                         {
02270                                                 if (connection->curveSegments[i].arrowStart)
02271                                                         movingItems.removeAll(connection->curveSegments[i].arrowStart);
02272                                                 if (connection->curveSegments[i].arrowEnd)
02273                                                         movingItems.removeAll(connection->curveSegments[i].arrowEnd);
02274                                         }
02275 
02276                                         QList<ConnectionGraphicsItem::ControlPoint*> list = connection->controlPoints();
02277 
02278                                         bool noControlsSelected = true;
02279                                         bool controlPointsExist = false;
02280                                         for (int i=0; i < list.size(); ++i)
02281                                         {
02282                                                 if (!controlPointsExist && list[i] && list[i]->isVisible() && !list[i]->parentItem())
02283                                                         controlPointsExist = true;
02284                                                 
02285                                                 if (list[i] && list[i]->isVisible() && list[i]->sceneBoundingRect().contains(point))
02286                                                 {
02287                                                         if (!movingItems.contains(list[i]) && list[i]->scene() == this)
02288                                                                 movingItems += list[i];
02289                                                         noControlsSelected = false;
02290                                                         //break;
02291                                                 }
02292                                         }
02293 
02294                                         if (noControlsSelected)
02295                                         {
02296                                                 //connection->setControlPointsVisible(true);
02297 
02298                                                 for (int i=0; i < list.size(); ++i)
02299                                                         if (!movingItems.contains(list[i]) && list[i]->scene() == this)
02300                                                                 movingItems += list[i];
02301 
02302                                                 ItemHandle * handle = connection->handle();
02303                                                 if (handle && controlPointsExist)
02304                                                         for (int i=0; i < handle->graphicsItems.size(); ++i)
02305                                                         {
02306                                                                 if (TextGraphicsItem::cast(handle->graphicsItems[i])
02307                                                                         && !movingItems.contains(handle->graphicsItems[i])
02308                                                                         && handle->graphicsItems[i]->scene() == this)
02309                                                                         movingItems += handle->graphicsItems[i];
02310                                                         }
02311                                         }
02312                                 }
02313                                 else
02314                                 {
02315                                         if (ArrowHeadItem::cast(movingItems[i]))
02316                                         {
02317                                                 movingItems.removeAll(node);
02318                                         }
02319                                 }
02320                         }
02321         }
02322         
02323         void GraphicsScene::setBackground(const QPixmap& image) const
02324         {
02325                 QList<QGraphicsView*> list = views();
02326                 GraphicsView * view;
02327                 for (int i=0; i < list.size(); ++i)
02328                         if (list[i])
02329                         {
02330                                 view = static_cast<GraphicsView*>(list[i]);
02331                                 view->background = image;
02332                         }
02333         }
02334         
02335         void GraphicsScene::setForeground(const QPixmap& image) const
02336         {
02337                 QList<QGraphicsView*> list = views();
02338                 GraphicsView * view;
02339                 for (int i=0; i < list.size(); ++i)
02340                         if (list[i])
02341                         {
02342                                 view = static_cast<GraphicsView*>(list[i]);
02343                                 view->foreground = image;
02344                         }
02345         }
02346         
02347         void GraphicsScene::popOut()
02348         {
02349                 if (networkWindow)
02350                         networkWindow->popOut();
02351         }
02352         
02353         void GraphicsScene::popIn()
02354         {
02355                 if (networkWindow)
02356                         networkWindow->popIn();
02357         }
02358         
02359         void GraphicsScene::hideGraphicalTools()
02360         {
02361                 for (int i=0; i < visibleTools.size(); ++i)
02362                 {
02363                         ToolGraphicsItem * tool = visibleTools[i];
02364                         if (tool && tool->tool)
02365                         {
02366                                 if (tool->scene())
02367                                 {
02368                                         tool->scene()->removeItem(tool);
02369                                 }
02370                                 tool->visible(false);
02371                                 tool->deselect();
02372                         }
02373                 }
02374                 visibleTools.clear();
02375         }
02376 
02377         void GraphicsScene::showGraphicalTools()
02378         {
02379                 hideGraphicalTools();
02380 
02381                 ItemHandle * itemHandle = 0;
02382                 Tool * tool;
02383                 for (int i=0; i < selectedItems.size(); ++i)
02384                 {
02385                         if (itemHandle = getHandle(selectedItems[i]))
02386                         {
02387                                 for (int j=0; j < itemHandle->tools.size(); ++j)
02388                                 {
02389                                         tool = itemHandle->tools[j];
02390                                         if (tool && !tool->graphicsItems.isEmpty())
02391                                                 for (int k=0; k < tool->graphicsItems.size(); ++k)
02392                                                 {
02393                                                         if (!visibleTools.contains(tool->graphicsItems[k]))
02394                                                                 visibleTools += tool->graphicsItems[k];
02395                                                 }
02396                                 }
02397                         }
02398                 }
02399                 
02400                 scaleGraphicalTools();
02401         }
02402 
02403         void GraphicsScene::scaleGraphicalTools()
02404         {
02405                 qreal scalex = 1, scaley = 1;
02406                 QRectF viewport = this->visibleRegion();
02407                 scalex = viewport.width();
02408                 scaley = viewport.height();
02409                 qreal maxx = viewport.right() - 0.05*scalex,
02410                           miny = viewport.top() + 0.05*scaley,
02411                           w = 0;
02412 
02413                 for (int i=0; i < visibleTools.size(); ++i)
02414                 {
02415                         ToolGraphicsItem * tool = visibleTools[i];
02416                         if (tool)
02417                         {
02418                                 if (tool->scene() != this)
02419                                 {
02420                                         if (tool->parentItem())
02421                                                 tool->setParentItem(0);
02422 
02423                                         if (tool->scene() != 0)
02424                                                 tool->scene()->removeItem(tool);
02425 
02426                                         addItem(tool);
02427                                 }
02428 
02429                                 tool->visible(true);
02430                                 tool->setZValue(ZValue()+0.1);
02431                                 
02432                                 QRectF bounds = tool->sceneBoundingRect();
02433                                 tool->resetTransform();
02434                                 
02435                                 qreal ratio = bounds.height()/bounds.width();
02436                                 qreal scale = (scaley + scalex)/2.0;
02437                                 
02438                                 tool->scale(0.001*(scale),0.001*(scale));
02439 
02440                                 tool->setPos(QPointF(maxx,miny));
02441                                 bounds = tool->sceneBoundingRect();
02442 
02443                                 if (tool->isVisible() && visibleTools.size() > 1)
02444                                 {
02445                                         if (bounds.height() < 500.0)
02446                                                 miny += bounds.height() * 1.5;
02447 
02448                                         if (bounds.width() > w && bounds.width() < 500) w = bounds.width();
02449 
02450                                         if (miny > viewport.bottom() - 50.0)
02451                                         {
02452                                                 miny = viewport.top() + 0.05*scale;
02453                                                 maxx -= w * 1.5;
02454                                         }
02455                                 }
02456                         }
02457                 }
02458         }
02459         
02460         void GraphicsScene::populateContextMenu()
02461         {
02462                 static QList<QAction*> separators, actions;
02463                 
02464                 if (!contextItemsMenu) return;
02465 
02466                 Tool * tool = 0;
02467                 QHash<QString,QAction*> hash;
02468                 QList<QAction*> list;
02469                 
02470                 for (int i=0; i < actions.size(); ++i)
02471                         if (actions[i])
02472                                 contextItemsMenu->removeAction(actions[i]);
02473                 
02474                 for (int i=0; i < separators.size(); ++i)
02475                         if (separators[i])
02476                                 contextItemsMenu->removeAction(separators[i]);
02477 
02478                 actions.clear();
02479                 
02480                 ItemHandle * handle = 0;
02481                 QList<Tool*> visited;
02482                 
02483                 for (int i=0; i < selectedItems.size(); ++i)
02484                         if (handle = getHandle(selectedItems[i]))
02485                         {
02486                                 for (int j=0; j < handle->tools.size(); ++j)
02487                                         if ((tool = handle->tools[j]) && !visited.contains(tool) && !tool->actionsGroup.actions().isEmpty())
02488                                         {
02489                                                 visited << tool;
02490                                                 list = tool->actionsGroup.actions();
02491                                                 for (int k=0; k < list.size(); ++k)
02492                                                         hash.insertMulti(tool->category,list[k]);
02493                                         }
02494                         }
02495 
02496                 QStringList keys = hash.keys();
02497                 
02498                 for (int i=0; i < keys.size(); ++i)
02499                 {
02500                         if (separators.size() > i)
02501                                 contextItemsMenu->addAction(separators[i]);
02502                         else
02503                                 separators << contextItemsMenu->addSeparator(); 
02504                         
02505                         list = hash.values(keys[i]);
02506                         for (int j=0; j < list.size(); ++j)
02507                         {
02508                                 contextItemsMenu->addAction(list[j]);
02509                                 actions << list[j];
02510                         }
02511                 }
02512         }
02513         
02514         void GraphicsScene::showToolTip(QPointF p, const QString & text)
02515         {
02516                 QGraphicsSimpleTextItem * textItem = new QGraphicsSimpleTextItem(text);
02517                 textItem->setPen(Qt::NoPen);
02518                 textItem->setBrush(ToolTipTextBrush);
02519                 
02520                 QRectF viewport = this->visibleRegion();
02521                 qreal scale = 0.002 * (viewport.width());               
02522                 textItem->scale(scale,scale);
02523                 QGraphicsScene::addItem(textItem);
02524                 textItem->setPos(p);
02525                 
02526                 QGraphicsRectItem * rectItem = new QGraphicsRectItem;
02527                 rectItem->setPen(Qt::NoPen);
02528                 rectItem->setBrush(ToolTipBackgroundBrush);             
02529                 QGraphicsScene::addItem(rectItem);
02530                 rectItem->setRect(textItem->sceneBoundingRect().adjusted(-5,-5,10,10));
02531                 
02532                 rectItem->setZValue(lastZ + 1.0);
02533                 textItem->setZValue(lastZ + 2.0);
02534                 
02535                 toolTips << rectItem << textItem;
02536         }
02537 
02538         void GraphicsScene::hideToolTips()
02539         {
02540                 if (toolTips.isEmpty()) return;
02541                 
02542                 for (int i=0; i < toolTips.size(); ++i)
02543                         removeItem(toolTips[i]);
02544                 qDeleteAll(toolTips);
02545                 toolTips.clear();
02546         }
02547         
02548         void GraphicsScene::useDefaultBehavior(bool b)
02549         {
02550                 _useDefaultBehavior = b;
02551                 //clickedButton = Qt::NoButton;
02552                 //clickedPoint = QPointF();
02553         }
02554         
02555         bool GraphicsScene::useDefaultBehavior() const
02556         {
02557                 return _useDefaultBehavior;
02558         }
02559 }
02560 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines