]> AND Private Git Repository - blast.git/blobdiff - BoxItem.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
changed sources to stimulis
[blast.git] / BoxItem.cpp
index 77e9533be3c44d7fd729bb678d8718ad51e74b1e..ae15002120d4596156879144c449e905b5dcc3f4 100644 (file)
 #include "ReferenceBlock.h"
 #include "ParametersWindow.h"
 #include "BlockParameter.h"
 #include "ReferenceBlock.h"
 #include "ParametersWindow.h"
 #include "BlockParameter.h"
+#include "Graph.h"
 
 
 BoxItem::BoxItem(AbstractBlock *_refBlock,
                      Dispatcher *_dispatcher,
 
 
 BoxItem::BoxItem(AbstractBlock *_refBlock,
                      Dispatcher *_dispatcher,
-                     Parameters *_params, GroupItem *parent) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params, parent) {
+                     Parameters *_params, GroupItem *parent, int _lock, SpanType _span, Position _position) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params, _lock, parent) {
 
   /*  NOTE :
      _refBlock : mandatory a FunctionalBlock or a GroupBlock
   */
 
   /*  NOTE :
      _refBlock : mandatory a FunctionalBlock or a GroupBlock
   */
-  if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
+  if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));  
+
+  span = _span;
+  position = _position;
 
   childGroupItem = NULL;
   //boxWidth = params->defaultBlockWidth;
 
   childGroupItem = NULL;
   //boxWidth = params->defaultBlockWidth;
@@ -30,18 +34,175 @@ BoxItem::BoxItem(AbstractBlock *_refBlock,
   selected = false;
 
   setZValue(100);
   selected = false;
 
   setZValue(100);
-  setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
+  QGraphicsItem::GraphicsItemFlags flags = QGraphicsItem::ItemIsSelectable;
+  if (!isPositionLock()) {
+    flags |= QGraphicsItem::ItemIsMovable;
+    cout << "item " << qPrintable(refBlock->getName()) << "is movable" << endl;
+  }
+  if (!isDimensionLock()) {
+    flags |= QGraphicsItem::ItemSendsGeometryChanges;
+    cout << "item " << qPrintable(refBlock->getName()) << "is resizable" << endl;
+  }
+  setFlags(flags);
+
+  bool freeBorder[4]; // 0 = east, 1 = north, 2 = west, 3 = south
+  Parameters::Direction dirs[4];
+  for(int i=0;i<4;i++) {
+    freeBorder[i] = true;
+  }
+  dirs[0] = Parameters::East;
+  dirs[1] = Parameters::North;
+  dirs[2] = Parameters::West;
+  dirs[3] = Parameters::South;
+
+
+  if (position == Top) {
+    freeBorder[1] = false;
+  }
+  if (position == Bottom) {
+    freeBorder[3] = false;
+  }
+  if (position == Left) {
+    freeBorder[2] = false;
+  }
+  if (position == Right) {
+    freeBorder[0] = false;
+  }
+  if (span == HSpan) {
+    freeBorder[2] = false;
+    freeBorder[0] = false;
+  }
+  if (span == VSpan) {
+    freeBorder[1] = false;
+    freeBorder[3] = false;
+  }
+  Parameters::Direction dIn = Parameters::West;
+  Parameters::Direction dOut = Parameters::East;
+  Parameters::Direction dBi = Parameters::South;
+  if (freeBorder[2] == false) {
+    int i=3;
+    while (freeBorder[i] == false) {
+      i = (i+1)%4;
+    }
+    dIn = dirs[i];
+  }
+  if (freeBorder[0] == false) {
+    int i=1;
+    while (freeBorder[i] == false) {
+      i = (i+1)%4;
+    }
+    dOut = dirs[i];
+  }
+  if (freeBorder[3] == false) {
+    int i=0;
+    while (freeBorder[i] == false) {
+      i = (i+1)%4;
+    }
+    dBi = dirs[i];
+  }
 
 
-  initInterfaces();
-  updateGeometry();
-  resetInterfacesPosition();
-  QPointF initPos = QPointF(0.0,0.0) - originPoint;
+  createInterfaceItems(dIn,dOut,dBi);
+  updateGeometry(Creation);
+
+  // position the item
+  int groupWidth = getScene()->getGroupItem()->getWidth();
+  int groupHeight = getScene()->getGroupItem()->getHeight();
+  double xx = 0.0,yy = 0.0;
+  if ((position == BoxItem::Left) || (position == BoxItem::TopLeft) || (position == BoxItem::BottomLeft)) {
+    xx = 0;
+    if ((span == VSpan) || (position == BoxItem::TopLeft)) {
+      yy = 0;
+    }
+    else if (position == BoxItem::BottomLeft) {
+      yy = groupHeight-totalHeight;
+    }
+    else {
+      yy = (groupHeight-totalHeight)/2.0;
+    }
+  }
+  else if ((position == BoxItem::Right) || (position == BoxItem::TopRight) || (position == BoxItem::BottomRight)) {
+    xx = groupWidth-totalWidth;
+    if (xx < 0) xx = 0;
+    if ((span == VSpan) || (position == BoxItem::TopRight)) {
+      yy = 0;
+    }
+    else if (position == BoxItem::BottomRight) {
+      yy = groupHeight-totalHeight;
+    }
+    else {
+      yy = (groupHeight-totalHeight)/2.0;
+    }
+  }
+  else if ((position == BoxItem::Top) || (position == BoxItem::TopLeft) || (position == BoxItem::TopRight)) {
+    yy = 0;
+    if ((span == HSpan) || (position == BoxItem::TopLeft)) {
+      xx = 0;
+    }
+    else if (position == BoxItem::TopRight) {
+      xx = groupWidth-totalWidth;
+    }
+    else {
+      xx = (groupWidth-totalWidth)/2.0;
+    }    
+  }
+  else if ((position == BoxItem::Bottom) || (position == BoxItem::BottomLeft) || (position == BoxItem::BottomRight)) {
+    yy = groupHeight-totalHeight;
+    if ((span == HSpan) || (position == BoxItem::BottomLeft)) {
+      xx = 0;
+    }
+    else if (position == BoxItem::BottomRight) {
+      xx = groupWidth-totalWidth;
+    }
+    else {
+      xx = (groupWidth-totalWidth)/2.0;
+    }    
+  }
+  else {
+    int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
+    xx = (groupWidth-totalWidth)/2.0;
+    if (xx < marginConn) xx = marginConn;
+    yy = (groupHeight-totalHeight)/2.0;
+    if (yy < marginConn) yy = marginConn;
+  }
+  cout << "setting raw pos to " << xx << "," << yy << endl;
+  QPointF initPos(xx,yy);
+  initPos = initPos-originPoint;
   setPos(initPos);
   setPos(initPos);
+  cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
+  cout << "pos in group: " << x() << "," << y() << endl;
+}
+
+BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent, int _lock, SpanType _span, Position _position) throw(Exception) : AbstractBoxItem(_dispatcher, _params, _lock, parent) {
+
+  span = _span;
+  position = _position;
+
+  refBlock = NULL;
+  childGroupItem = NULL;
+  currentBorder = NoBorder;
+  selected = false;
+
+  setZValue(100);
+  QGraphicsItem::GraphicsItemFlags flags = QGraphicsItem::ItemIsSelectable;
+  if (!isPositionLock()) {
+    flags |= QGraphicsItem::ItemIsMovable;
+  }
+  if (!isDimensionLock()) {
+    flags |= QGraphicsItem::ItemSendsGeometryChanges;
+  }
+  setFlags(flags);
+
+  boxWidth = params->defaultBlockWidth;
+  boxHeight = params->defaultBlockHeight;
+  //initInterfaces();
+  //updateGeometry(InterfaceMove);
+  //resetInterfacesPosition();
+  //QPointF initPos = QPointF(0.0,0.0) - originPoint;
+  //setPos(initPos);
   //cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
   //cout << "pos in group: " << x() << "," << y() << endl;
 }
 
   //cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
   //cout << "pos in group: " << x() << "," << y() << endl;
 }
 
-
 BoxItem::~BoxItem() {
 }
 
 BoxItem::~BoxItem() {
 }
 
@@ -90,19 +251,22 @@ void BoxItem::updateMinimumSize() {
   int ifaceHeight = 0;
 
   foreach(InterfaceItem* iface, interfaces) {
   int ifaceHeight = 0;
 
   foreach(InterfaceItem* iface, interfaces) {
-    ifaceWidth = iface->getNameWidth();
-    ifaceHeight = iface->getNameHeight();
-    if (iface->getOrientation() == Parameters::South) {
-      if (ifaceWidth > maxSouth) maxSouth = ifaceWidth;
-    }
-    else if (iface->getOrientation() == Parameters::North) {
-      if (ifaceWidth > maxNorth) maxNorth = ifaceWidth;
-    }
-    else if (iface->getOrientation() == Parameters::East) {
-      if (ifaceWidth > maxEast) maxEast = ifaceWidth;
-    }
-    else if (iface->getOrientation() == Parameters::West) {
-      if (ifaceWidth > maxWest) maxWest = ifaceWidth;
+
+    if (iface->visible) {
+      ifaceWidth = iface->getNameWidth();
+      ifaceHeight = iface->getNameHeight();
+      if (iface->getOrientation() == Parameters::South) {
+        if (ifaceWidth > maxSouth) maxSouth = ifaceWidth;
+      }
+      else if (iface->getOrientation() == Parameters::North) {
+        if (ifaceWidth > maxNorth) maxNorth = ifaceWidth;
+      }
+      else if (iface->getOrientation() == Parameters::East) {
+        if (ifaceWidth > maxEast) maxEast = ifaceWidth;
+      }
+      else if (iface->getOrientation() == Parameters::West) {
+        if (ifaceWidth > maxWest) maxWest = ifaceWidth;
+      }
     }
   }
 
     }
   }
 
@@ -130,32 +294,58 @@ bool BoxItem::updateGeometry(ChangeType type) {
   //cout << "current pos of block: " << currentPosition.x() << "," << currentPosition.y() << endl;
   QPointF oldOrigin = originPoint;
   QSize oldSize(totalWidth,totalHeight);
   //cout << "current pos of block: " << currentPosition.x() << "," << currentPosition.y() << endl;
   QPointF oldOrigin = originPoint;
   QSize oldSize(totalWidth,totalHeight);
-
   bool boxSizeChanged = false;
 
   bool boxSizeChanged = false;
 
-  if ((type == Resize) || (type == InterfaceMove)) {
-    updateMinimumSize();
-  }
+  // whatever the change, the minimum size may have changed
+  updateMinimumSize();
+
+  int groupWidth = getScene()->getGroupItem()->getWidth();
+  int groupHeight = getScene()->getGroupItem()->getHeight();
+
+  cout << "minimum box size is " << minimumBoxWidth << "x" << minimumBoxHeight << endl;
+  cout << "group size is " << groupWidth << "x" << groupHeight << endl;
+
+  if (type == Creation) {
 
 
-  if (type == Resize) {
-    prepareGeometryChange();
-    updateInterfacesAndConnections();
     boxSizeChanged = true;
     boxSizeChanged = true;
-  }
-  if (boxWidth < minimumBoxWidth) {
     boxWidth = minimumBoxWidth;
     boxWidth = minimumBoxWidth;
-    boxSizeChanged = true;
-  }
-  if (boxHeight < minimumBoxHeight) {
     boxHeight = minimumBoxHeight;
     boxHeight = minimumBoxHeight;
-     boxSizeChanged = true;
+    /* reset and update interfaces positions
+     * in case of spanning, the interface are positionned
+     * only on free borders.
+     */
+    resetInterfaceItemsPosition();
+    /* must test if the GroupItem must be resized */
+    if ((span == HSpan) && (boxWidth < groupWidth)) {
+      boxWidth = groupWidth; // no interfaces in east/west (done in constructor)
+    }
+    else if ((span == VSpan) && (boxHeight < groupHeight)) {
+      boxHeight = groupHeight;
+    }
+  }
+  else if (type == Resize) {
+    // resize implies to move interfaces and to update connections
+    boxSizeChanged = true;
+    updateInterfaceAndConnectionItems();
   }
   }
-  if (boxSizeChanged) {
-    updateInterfacesAndConnections();
+  else if (type == InterfaceMove) {
+    // if an interface moves, it may change the box size
+    if (boxWidth < minimumBoxWidth) {
+      boxWidth = minimumBoxWidth;
+      boxSizeChanged = true;
+      updateInterfaceAndConnectionItems();
+    }
+    if (boxHeight < minimumBoxHeight) {
+      boxHeight = minimumBoxHeight;
+      boxSizeChanged = true;
+      updateInterfaceAndConnectionItems();
+    }
   }
 
   }
 
+  // update total size
   double x = 0.0;
   double y = 0.0;
   double x = 0.0;
   double y = 0.0;
+
   totalWidth = boxWidth;
   totalHeight = boxHeight;
 
   totalWidth = boxWidth;
   totalHeight = boxHeight;
 
@@ -176,6 +366,9 @@ bool BoxItem::updateGeometry(ChangeType type) {
   QSizeF newSize(totalWidth,totalHeight);
   originPoint.setX(x);
   originPoint.setY(y);
   QSizeF newSize(totalWidth,totalHeight);
   originPoint.setX(x);
   originPoint.setY(y);
+  cout << "change orig pos of " << qPrintable(refBlock->getName()) << "to " << x << "," << y << endl;
+  cout << "box size is " << boxWidth << "x" << boxHeight << endl;
+  cout << "total size is " << totalWidth << "x" << totalHeight << endl;
 
   if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
     prepareGeometryChange();
 
   if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
     prepareGeometryChange();
@@ -184,40 +377,71 @@ bool BoxItem::updateGeometry(ChangeType type) {
   return false;
 }
 
   return false;
 }
 
+void BoxItem::nameChanged() {
+  
+  QFontMetrics fmId(params->defaultBlockFont);
+  nameWidth = fmId.width(refBlock->getName());
+  nameHeight = fmId.height();
+  
+  if (updateGeometry(InterfaceMove)) {
+    //cout << "must recompute group item geometry" << endl;
+    (getScene()->getGroupItem())->updateShape();
+  }
+  // force the update in case of size has not changed
+  update();
+}
+
 void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
 
   if(params->editState == Parameters::EditBlockMove) {
 void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
 
   if(params->editState == Parameters::EditBlockMove) {
+
+    if (isPositionLock()) return;
     QPointF absPos = currentPosition + originPoint;
     int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
     int gapX = event->scenePos().x() - cursorPosition.x();
     int gapY = event->scenePos().y() - cursorPosition.y();
     QPointF absPos = currentPosition + originPoint;
     int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
     int gapX = event->scenePos().x() - cursorPosition.x();
     int gapY = event->scenePos().y() - cursorPosition.y();
+    // update cursor position
+    cursorPosition = event->scenePos();
 
     //cout << "block abs. pos: " << absPos.x() << "," << absPos.y() << " | ";
     //cout << "block current. pos: " << currentPosition.x() << "," << currentPosition.y() << " | ";
 
 
     //cout << "block abs. pos: " << absPos.x() << "," << absPos.y() << " | ";
     //cout << "block current. pos: " << currentPosition.x() << "," << currentPosition.y() << " | ";
 
-    if (absPos.x()+gapX < marginConn) {
+    if ((position == Left) || (position == Right)) {
+      gapX = 0;
+    }
+    else if ((gapX < 0) && (absPos.x() == marginConn)) {
+      gapX = 0;
+    }
+    else if (absPos.x()+gapX < marginConn) {
       gapX = marginConn-absPos.x();
     }
       gapX = marginConn-absPos.x();
     }
-    if (absPos.y()+gapY < marginConn) {
+    if ((position == Top) || (position == Bottom)) {
+      gapY = 0;
+    }
+    else if ((gapY < 0) && (absPos.y() == marginConn)) {
+      gapY = 0;
+    }
+    else if (absPos.y()+gapY < marginConn) {
       gapY = marginConn-absPos.y();
     }
     //cout << "gap: " << gapX << "," << gapY << endl;
       gapY = marginConn-absPos.y();
     }
     //cout << "gap: " << gapX << "," << gapY << endl;
-    QPointF gap(gapX,gapY);
-    currentPosition = currentPosition+gap;
-    setPos(currentPosition);
-    // update all connections from/to this block
-    foreach(ConnectionItem *item, getScene()->getConnectionItems()){
-      if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
-        item->setPathes();
+    if ((gapX != 0) || (gapY != 0)) {
+      QPointF gap(gapX,gapY);
+      currentPosition = currentPosition+gap;
+      setPos(currentPosition);
+      // update all connections from/to this block
+      foreach(ConnectionItem *item, getScene()->getConnectionItems()){
+        if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
+          item->setPath();
+        }
       }
       }
+      // udpate the groupitem
+      (getScene()->getGroupItem())->updateShape();
     }
     }
-    cursorPosition = event->scenePos();
-
-    // udpate the groupitem
-    (getScene()->getGroupItem())->updateShape();
   }
   else if(params->editState == Parameters::EditBlockResize) {
 
   }
   else if(params->editState == Parameters::EditBlockResize) {
 
+    if (isDimensionLock()) return;
     int gapX = event->scenePos().x() - cursorPosition.x();
     int gapY = event->scenePos().y() - cursorPosition.y();
     //cout << "gap: " << gapX << "," << gapY << endl;
     int gapX = event->scenePos().x() - cursorPosition.x();
     int gapY = event->scenePos().y() - cursorPosition.y();
     //cout << "gap: " << gapX << "," << gapY << endl;
@@ -243,12 +467,21 @@ void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
       }
       break;
     }
       }
       break;
     }
+    case Title:
+      cout << "abnormal case while resizing block" << endl;
+      break;
+    case BorderWest:
+      cout << "abnormal case while resizing block" << endl;
+      break;
+    case BorderNorth:
+      cout << "abnormal case while resizing block" << endl;
+      break;
     case NoBorder:
       cout << "abnormal case while resizing block" << endl;
       break;
     }
     // recompute the geometry of the block and possibly the group item
     case NoBorder:
       cout << "abnormal case while resizing block" << endl;
       break;
     }
     // recompute the geometry of the block and possibly the group item
-    if (updateGeometry()) {
+    if (updateGeometry(Resize)) {
       (getScene()->getGroupItem())->updateShape();
     }
 
       (getScene()->getGroupItem())->updateShape();
     }
 
@@ -256,16 +489,16 @@ void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
   }
   else if(params->editState == Parameters::EditInterfaceMove) {
     prepareGeometryChange();
   }
   else if(params->editState == Parameters::EditInterfaceMove) {
     prepareGeometryChange();
-    deplaceInterface(event->pos());
+    moveInterfaceItemTo(event->pos());
     // recompute the geometry of the block
     // recompute the geometry of the block
-    if (updateGeometry()) {
-      cout << "must recompute group item geometry" << endl;
+    if (updateGeometry(InterfaceMove)) {
+      //cout << "must recompute group item geometry" << endl;
       (getScene()->getGroupItem())->updateShape();
     }
     // update connection from/to the selected interface
     foreach(ConnectionItem *item, getScene()->getConnectionItems()){
       if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
       (getScene()->getGroupItem())->updateShape();
     }
     // update connection from/to the selected interface
     foreach(ConnectionItem *item, getScene()->getConnectionItems()){
       if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
-        item->setPathes();
+        item->setPath();
       }
     }    
   }
       }
     }    
   }
@@ -283,10 +516,10 @@ void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
 
   int mode = getScene()->getEditionMode();
 
 
   int mode = getScene()->getEditionMode();
 
-  dispatcher->setCurrentGroupWidget(getScene()->getGroupWindow());
+  dispatcher->setCurrentGroupWidget(Dispatcher::Design, getScene()->getGroupWidget());
 
   if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) {
 
   if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) {
-    InterfaceItem *inter = getInterfaceFromCursor(x,y);
+    InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
     if (inter != NULL) {
 
       if (params->editState == Parameters::EditNoOperation) {
     if (inter != NULL) {
 
       if (params->editState == Parameters::EditNoOperation) {
@@ -305,9 +538,9 @@ void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
     }
   }
   else if (mode == GroupScene::ItemEdition) {
     }
   }
   else if (mode == GroupScene::ItemEdition) {
-    setZValue(zValue()+100);
+    //setZValue(zValue()+100);
     if (params->cursorState == Parameters::CursorOnInterface) {
     if (params->cursorState == Parameters::CursorOnInterface) {
-      InterfaceItem *inter = getInterfaceFromCursor(x,y);
+      InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
       if (inter != NULL) {
         if (inter == currentInterface) {
            params->setEditState(Parameters::EditInterfaceDeselect);
       if (inter != NULL) {
         if (inter == currentInterface) {
            params->setEditState(Parameters::EditInterfaceDeselect);
@@ -327,16 +560,23 @@ void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
       update();
     }
     else if (params->cursorState == Parameters::CursorOnBorder) {
       update();
     }
     else if (params->cursorState == Parameters::CursorOnBorder) {
-      setFlag(ItemIsMovable, false);
-      cursorPosition = event->scenePos();
-      params->setEditState(Parameters::EditBlockResize);
+      if (isDimensionLock()) {
+        if ((position == Bottom)||(position == Right)) {
+          event->ignore();
+        }
+      }
+      else {
+        setFlag(ItemIsMovable, false);
+        cursorPosition = event->scenePos();
+        params->setEditState(Parameters::EditBlockResize);
+      }
     }
   }
 }
 
 void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent  *event) {
 
     }
   }
 }
 
 void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent  *event) {
 
-  setZValue(zValue()-100);
+  //setZValue(zValue()-100);
 
   int mode = getScene()->getEditionMode();
 
 
   int mode = getScene()->getEditionMode();
 
@@ -357,15 +597,18 @@ void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent  *event) {
     else if (params->editState == Parameters::EditCloseConnection) {
       InterfaceItem* iface1 = getScene()->getSelectedInterface(1);
       InterfaceItem* iface2 = getScene()->getSelectedInterface(2);
     else if (params->editState == Parameters::EditCloseConnection) {
       InterfaceItem* iface1 = getScene()->getSelectedInterface(1);
       InterfaceItem* iface2 = getScene()->getSelectedInterface(2);
-      bool ok = dispatcher->connect(iface1,iface2);
+      bool ok = dispatcher->createConnection(Dispatcher::Design, iface1,iface2);
       if (ok) {
         iface1->selected = false;
       if (ok) {
         iface1->selected = false;
-        // no update needed since the whole scene will be repainted
+        update(iface1->boundingRect());
+        iface2->selected = false;
+        update(iface2->boundingRect());        
         getScene()->setSelectedInterface(1,NULL);
         getScene()->setSelectedInterface(2,NULL);
         params->setEditState(Parameters::EditNoOperation);
       }
       else {
         getScene()->setSelectedInterface(1,NULL);
         getScene()->setSelectedInterface(2,NULL);
         params->setEditState(Parameters::EditNoOperation);
       }
       else {
+        //QMessageBox::warning(NULL,"Error","Cannot connect selected interfaces", QMessageBox::Ok);
         getScene()->setSelectedInterface(2,NULL);
         params->setEditState(Parameters::EditStartConnection);
       }
         getScene()->setSelectedInterface(2,NULL);
         params->setEditState(Parameters::EditStartConnection);
       }
@@ -382,14 +625,14 @@ void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent  *event) {
 
 void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
 
 
 void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
 
-  QPointF pos = event->pos();
-  qreal x = pos.x();
-  qreal y = pos.y();
+  QPointF evPos = event->pos();
+  qreal x = evPos.x();
+  qreal y = evPos.y();
   currentBorder = NoBorder;
   int mode = getScene()->getEditionMode();
 
   if (mode == GroupScene::AddConnection) {
   currentBorder = NoBorder;
   int mode = getScene()->getEditionMode();
 
   if (mode == GroupScene::AddConnection) {
-    InterfaceItem* iface = getInterfaceFromCursor(x,y);
+    InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
     if (iface != NULL) {
       params->cursorState = Parameters::CursorOnInterface;
       setCursor(Qt::PointingHandCursor);
     if (iface != NULL) {
       params->cursorState = Parameters::CursorOnInterface;
       setCursor(Qt::PointingHandCursor);
@@ -403,7 +646,7 @@ void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
     int marginE = 5;
     int marginS = 5;
 
     int marginE = 5;
     int marginS = 5;
 
-    InterfaceItem* iface = getInterfaceFromCursor(x,y);
+    InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
     if (iface != NULL) {
       params->cursorState = Parameters::CursorOnInterface;
       setCursor(Qt::PointingHandCursor);
     if (iface != NULL) {
       params->cursorState = Parameters::CursorOnInterface;
       setCursor(Qt::PointingHandCursor);
@@ -445,55 +688,126 @@ void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
       }
     }
   }
       }
     }
   }
-  QGraphicsItem::hoverMoveEvent(event);
+  if (params->cursorState == Parameters::CursorOnBorder) {
+    if (isDimensionLock()) {
+      if ((position == Bottom)||(position == Right)) {
+        event->setPos(evPos+pos());
+        getScene()->getGroupItem()->hoverMoveEvent(event);
+      }
+    }
+  }
 }
 
 
 }
 
 
-void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
-
+void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {  
+  
   QMenu menu;
   QMenu menu;
-  QAction* removeAction = menu.addAction("Remove");
-  QAction* duplicateAction = menu.addAction("Duplicate");
-  QAction* renameAction = menu.addAction("Rename");
-  QAction* connectToGroup = NULL;
-  QAction* disconnectFromGroup = NULL;
+  QAction* titleAction = NULL;
+  QAction* removeAction = NULL;
+  QAction* duplicateAction = NULL;
+  QAction* renameAction = NULL;
+  QAction* connectToGroup = NULL;  
   QAction* showProperties = NULL;
   QAction* cloneInterface = NULL;
   QAction* openWindow = NULL;
   QAction* showProperties = NULL;
   QAction* cloneInterface = NULL;
   QAction* openWindow = NULL;
-  QAction* showRstClkInter = NULL;
+  QAction* showRstClkIface = NULL;
+  QAction* showWishboneIface = NULL;
   QAction* showParameters = NULL;
   QAction* showParameters = NULL;
+  QAction* showPatterns = NULL;
+  QAction* showModifier = NULL;
+  QAction* removeModifier = NULL;
+  QAction* generateVHDL = NULL;
 
 
-  InterfaceItem* ifaceItem = getInterfaceFromCursor(event->pos().x(), event->pos().y());
+  InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y());
+  // menu for interface
   if( ifaceItem != NULL){
   if( ifaceItem != NULL){
+
+    titleAction = menu.addAction("Interface operations");
+    titleAction->setEnabled(false);
+    menu.addSeparator();
+
+
     showProperties = menu.addAction("Show properties");
     showProperties = menu.addAction("Show properties");
+    renameAction = menu.addAction("Rename");
 
     ConnectedInterface* iface = ifaceItem->refInter;
 
     ConnectedInterface* iface = ifaceItem->refInter;
+    ConnectedInterface* ifaceGroup = NULL;
+    bool canRemove = true;
+
     if ((iface->getDirection() == AbstractInterface::Input) && (iface->getConnectedFrom() == NULL)) {
         connectToGroup = menu.addAction("Connect to group input");
     }
     if ((iface->getDirection() == AbstractInterface::Input) && (iface->getConnectedFrom() == NULL)) {
         connectToGroup = menu.addAction("Connect to group input");
     }
-    else if ((iface->getDirection() == AbstractInterface::Output) && (!iface->isConnectedTo())) {
+    else if ((iface->getDirection() == AbstractInterface::Output) && (iface->getConnectionToParentGroup() == NULL)) {
       connectToGroup = menu.addAction("Connect to group output");
     }
       connectToGroup = menu.addAction("Connect to group output");
     }
-    else if ((iface->getConnectionFromParentGroup() != NULL) || (iface->getConnectionToParentGroup() != NULL)) {
-      disconnectFromGroup = menu.addAction("Disconnect from group");
+    else if (iface->getConnectionFromParentGroup() != NULL) {
+      ifaceGroup = iface->getConnectionFromParentGroup();     
+      if (ifaceGroup->isConnectedFrom()) {        
+        canRemove = false;
+      }
+    }
+    else if (iface->getConnectionToParentGroup() != NULL) {
+      ifaceGroup = iface->getConnectionToParentGroup();      
+      if (ifaceGroup->isConnectedTo()) {
+        canRemove = false;
+      }
     }
 
     if (iface->isFunctionalInterface()) {
       FunctionalInterface* fi = AI_TO_FUN(ifaceItem->refInter);
       ReferenceInterface* ri = (ReferenceInterface*)(fi->getReference());
       if(ri->getMultiplicity() == -1 || ri->getMultiplicity() > 1){
     }
 
     if (iface->isFunctionalInterface()) {
       FunctionalInterface* fi = AI_TO_FUN(ifaceItem->refInter);
       ReferenceInterface* ri = (ReferenceInterface*)(fi->getReference());
       if(ri->getMultiplicity() == -1 || ri->getMultiplicity() > 1){
-        cloneInterface = menu.addAction("Clone interface");
+        cloneInterface = menu.addAction("Duplicate");
+        if ((canRemove) && (fi->getInterfaceMultiplicity() > 1)) {
+          removeAction = menu.addAction("Remove");
+        }
+      }      
+    }
+    if (iface->getAssociatedIface() != NULL) {
+      if (iface->getDirection() == AbstractInterface::Output) {
+        showPatterns = menu.addAction("Show output pattern");
+      }
+      else if (iface->getDirection() == AbstractInterface::Input) {
+        showPatterns = menu.addAction("Show input pattern");
+      }
+    }    
+
+    if (iface->getAssociatedIface() != NULL) {
+      ConnectedInterface* assoIface = AI_TO_CON(iface->getAssociatedIface());
+      if (assoIface->getInputModifier() != NULL) {
+        removeModifier = menu.addAction("Remove input modifier");
+      }
+      if (assoIface->getInputModifier() != NULL) {
+        showModifier = menu.addAction("Show input modifier parameters");
       }
     }
       }
     }
+
   }
   }
-  if(refBlock->isGroupBlock()){
-    openWindow = menu.addAction("Open/show group window");
-  } else {
-    showRstClkInter = menu.addAction("Show reset/clock interfaces");
-    showRstClkInter->setCheckable(true);
-    showRstClkInter->setChecked(rstClkVisible);
+  // menu for blocks (group or func)
+  else {
+    titleAction = menu.addAction("Block operations");
+    titleAction->setEnabled(false);
+    menu.addSeparator();
+
+    if (refBlock->nbParameters() > 0) {
+      showParameters = menu.addAction("Show parameters");
+    }
+    renameAction = menu.addAction("Rename");
 
 
-    showParameters = menu.addAction("Show parameters");
+    if(refBlock->isGroupBlock()){
+      openWindow = menu.addAction("Open/show group window");
+    }
+    else {
+      duplicateAction = menu.addAction("Duplicate");
+      showRstClkIface = menu.addAction("Show reset/clock interfaces");
+      showRstClkIface->setCheckable(true);
+      showRstClkIface->setChecked(rstClkVisible);
+      showWishboneIface = menu.addAction("Show wishbone interfaces");
+      showWishboneIface->setCheckable(true);
+      showWishboneIface->setChecked(wishboneVisible);
+    }
+    removeAction = menu.addAction("Remove");
+    generateVHDL = menu.addAction("Generate VHDL");
   }
 
   QAction* selectedAction = NULL;
   }
 
   QAction* selectedAction = NULL;
@@ -502,38 +816,208 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
   if(selectedAction == NULL) return ;
 
   if (selectedAction == removeAction) {
   if(selectedAction == NULL) return ;
 
   if (selectedAction == removeAction) {
-    dispatcher->removeBlock(this);
+    if(ifaceItem != NULL) {
+     dispatcher->removeFunctionalInterface(Dispatcher::Design, ifaceItem);
+    }
+    else {
+      dispatcher->removeBoxItem(Dispatcher::Design, this);
+    }
   }
   else if (selectedAction == duplicateAction) {
   }
   else if (selectedAction == duplicateAction) {
-    dispatcher->duplicateBlock(this);
+    dispatcher->duplicateBoxItem(Dispatcher::Design, this);
   }
   else if(selectedAction == renameAction){
   }
   else if(selectedAction == renameAction){
-    if(ifaceItem != NULL)
-      dispatcher->rename(ifaceItem);
-    else
-      dispatcher->rename(this);
+    if(ifaceItem != NULL) {
+      dispatcher->renameInterface(Dispatcher::Design, ifaceItem);
+    }
+    else {
+      if (refBlock->isFunctionalBlock()) {          
+        dispatcher->renameFunctionalBlock(Dispatcher::Design, this);
+      }
+      else if (refBlock->isGroupBlock()) {        
+        dispatcher->renameGroupBlock(Dispatcher::Design, childGroupItem);
+      }
+    }   
   }
   else if(selectedAction == showProperties){
   }
   else if(selectedAction == showProperties){
-    dispatcher->showProperties(ifaceItem);
+    dispatcher->showProperties(Dispatcher::Design, ifaceItem);
   }
   else if (selectedAction == connectToGroup){
   }
   else if (selectedAction == connectToGroup){
-    dispatcher->connectInterToGroup(ifaceItem);
-  }
-  else if (selectedAction == disconnectFromGroup) {
-    dispatcher->disconnectInterFromGroup(ifaceItem);
+    dispatcher->connectInterToGroup(Dispatcher::Design, ifaceItem);
   }
   else if (selectedAction == cloneInterface){
   }
   else if (selectedAction == cloneInterface){
-    dispatcher->duplicateInterface(ifaceItem);
+    dispatcher->duplicateInterfaceItem(Dispatcher::Design, ifaceItem);
   }
   else if (selectedAction == openWindow){
   }
   else if (selectedAction == openWindow){
-    dispatcher->showRaiseWindow(this);
+    dispatcher->showRaiseWindow(Dispatcher::Design, this);
   }
   }
-  else if(selectedAction == showRstClkInter){
-    dispatcher->showRstClkInter(this);
+  else if(selectedAction == showRstClkIface) {
+    dispatcher->showRstClkIface(Dispatcher::Design, this);
   }
   }
-  else if(selectedAction == showParameters){
+  else if(selectedAction == showWishboneIface) {
+    dispatcher->showWishboneIface(Dispatcher::Design, this);
+  }
+  else if(selectedAction == showParameters) {    
     new ParametersWindow(refBlock, params, NULL);
   }
     new ParametersWindow(refBlock, params, NULL);
   }
+  else if(selectedAction == showPatterns) {    
+    dispatcher->showPatterns(Dispatcher::Design, ifaceItem);
+  }
+  else if(selectedAction == removeModifier) {
+    dispatcher->removeModifier(Dispatcher::Design, ifaceItem);
+  }
+  else if(selectedAction == showModifier) {
+    dispatcher->showModifier(Dispatcher::Design, ifaceItem);
+  }
+  else if(selectedAction == generateVHDL) {
+    dispatcher->generateBlockVHDL(Dispatcher::Design, this);
+  }
+
+}
+
+void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) {
+
+  bool ok = false;
+
+  int id = funcElement.attribute("id","none").toInt(&ok);
+  if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+  QString refXml = funcElement.attribute("ref_xml","none");
+  if(refXml == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+  QString refMd5 = funcElement.attribute("ref_md5","none");
+  if(refMd5 == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+  cout << "ref md5 : " << refMd5.toStdString() << "\nref xml : " << refXml.toStdString() << endl;
+
+  QString name = funcElement.attribute("name","none");
+  if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+  QStringList positionStr = funcElement.attribute("position","none").split(",");
+  if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
+  int posX = positionStr.at(0).toInt(&ok);
+  if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+  int posY = positionStr.at(1).toInt(&ok);
+  if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+  QStringList dimensionStr = funcElement.attribute("dimension","none").split(",");
+  if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
+  int dimX = dimensionStr.at(0).toInt(&ok);
+  if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+  int dimY = dimensionStr.at(1).toInt(&ok);
+  if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+  
+  ReferenceBlock *referenceMd5 = NULL;
+  ReferenceBlock *referenceXml = NULL;
+  ReferenceBlock *reference = NULL;
+  if(refMd5 != "none") {
+    referenceMd5 = params->searchBlockByMd5(refMd5);
+  }
+  if(refXml != "none"){
+    referenceXml = params->searchBlockByXml(refXml);
+  }
+  if ((referenceMd5 == NULL) && (referenceXml == NULL)) {
+    throw(Exception(PROJECTFILE_CORRUPTED));
+  }
+  if (referenceMd5 != referenceXml) {
+    reference = referenceXml;
+  }
+  else {
+    reference = referenceMd5;
+  }
+  
+  GroupBlock* parentGroupBlock = AB_TO_GRP(((GroupItem *)parentItem())->getRefBlock());
+  FunctionalBlock* functionalBlock = params->getGraph()->createFunctionalBlock(parentGroupBlock, reference);
+  /* NB: addFunctionalBlock creates all interfaces from the reference, which is annoying when
+    reading bif_iface tags. Thus interface are all removed.
+  */
+  functionalBlock->setName(name);
+  setRefBlock(functionalBlock);
+  params->blockToItem.insert(functionalBlock,this);
+
+  setPos(posX,posY);
+  setDimension(dimX,dimY);
+  setId(id);
+
+
+  QDomNodeList blockParamNodes = funcElement.elementsByTagName("bif_parameter");
+  // setting parameters value
+  for(int i=0; i<blockParamNodes.length(); i++){
+    QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement();
+
+    QString name = currentBlockParamNode.attribute("name","none");
+    if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+    QString value = currentBlockParamNode.attribute("value","none");
+    if(value == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+    BlockParameter *blockParam = NULL;
+    blockParam = functionalBlock->getParameterFromName(name);
+    if (blockParam == NULL) throw(Exception(PROJECTFILE_CORRUPTED));
+    blockParam->setValue(value);
+  }  
+
+  // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars
+  functionalBlock->removeAllInterfaces();
+  QDomNodeList interfaceNodes = funcElement.elementsByTagName("bif_iface");
+  // setting interfaces (user name, and for multiplicity>1 may be create some new ones)
+  for(int i=0; i<interfaceNodes.length(); i++) {
+
+    QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
+
+    QString name = currentInterfaceNode.attribute("name","none");
+    if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+    QString refName = currentInterfaceNode.attribute("ref_name","none");
+    if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+    ReferenceInterface* refInter = AI_TO_REF(reference->getIfaceFromName(refName));
+    cout << "creating iface from reference named " << qPrintable(refName) << endl;
+    FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter);
+    functionalInterface->setName(name);
+    functionalBlock->addInterface(functionalInterface);
+    
+    // searching for control interface
+    QString ctlRefName = refName+"_enb";
+    ReferenceInterface* ctlRefIface = AI_TO_REF(reference->getIfaceFromName(ctlRefName));
+    
+    if (ctlRefIface != NULL) {
+      cout << "found a control iface:" << qPrintable(ctlRefName) << endl;
+      FunctionalInterface *ctlIface = new FunctionalInterface(functionalBlock,ctlRefIface);      
+      if (! ctlIface->setAssociatedIface(functionalInterface)) {
+        throw(Exception(PROJECTFILE_CORRUPTED));
+      }      
+      ctlIface->setName(name+"_enb");
+      functionalBlock->addInterface(ctlIface);
+    }    
+  }
+  
+  // creating InterfaceItem
+  createInterfaceItems();
+  // setting them with saved values
+  for(int i=0; i<interfaceNodes.length(); i++){
+
+    QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
+
+    int id = currentInterfaceNode.attribute("id","none").toInt(&ok);
+    if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+    QString name = currentInterfaceNode.attribute("name","none");
+    if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+    QString orientationStr = currentInterfaceNode.attribute("orientation","none");
+    int orientation = InterfaceItem::getIntOrientation(orientationStr);
+    if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));
+
+    double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);
+    if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+    InterfaceItem *interfaceItem = searchInterfaceItemByName(name);
+    interfaceItem->setId(id);
+    interfaceItem->setOrientation(orientation);
+    interfaceItem->setPositionRatio(position);
+  }
+  updateGeometry(Resize);
 }
 
 void BoxItem::save(QXmlStreamWriter &writer) {
 }
 
 void BoxItem::save(QXmlStreamWriter &writer) {
@@ -544,7 +1028,7 @@ void BoxItem::save(QXmlStreamWriter &writer) {
     writer.writeAttribute("ref_xml", ((FunctionalBlock*)refBlock)->getReferenceXmlFile());
     writer.writeAttribute("ref_md5", ((FunctionalBlock*)refBlock)->getReferenceHashMd5());
     writer.writeAttribute("name",refBlock->getName());
     writer.writeAttribute("ref_xml", ((FunctionalBlock*)refBlock)->getReferenceXmlFile());
     writer.writeAttribute("ref_md5", ((FunctionalBlock*)refBlock)->getReferenceHashMd5());
     writer.writeAttribute("name",refBlock->getName());
-    QString attrPos = QString::number(pos().x()).append(",").append(QString::number(pos().y()));
+    QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
     writer.writeAttribute("position",attrPos);
     QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
     writer.writeAttribute("dimension",attrDim);
     writer.writeAttribute("position",attrPos);
     QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
     writer.writeAttribute("dimension",attrDim);
@@ -585,7 +1069,7 @@ void BoxItem::save(QXmlStreamWriter &writer) {
 
     writer.writeAttribute("id",QString::number(id));
     writer.writeAttribute("inside_group",QString::number(childGroupItem->getId()));
 
     writer.writeAttribute("id",QString::number(id));
     writer.writeAttribute("inside_group",QString::number(childGroupItem->getId()));
-    QString attrPos = QString::number(pos().x()).append(",").append(QString::number(pos().y()));
+    QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
     writer.writeAttribute("position",attrPos);
     QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
     writer.writeAttribute("dimension",attrDim);
     writer.writeAttribute("position",attrPos);
     QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
     writer.writeAttribute("dimension",attrDim);
@@ -628,7 +1112,7 @@ QDataStream &operator <<(QDataStream &out, BoxItem &b) {
   for(int i=0; i<b.getInterfaces().length(); i++){
     InterfaceItem *inter = b.getInterfaces().at(i);
     toWrite << inter->getId();
   for(int i=0; i<b.getInterfaces().length(); i++){
     InterfaceItem *inter = b.getInterfaces().at(i);
     toWrite << inter->getId();
-    toWrite << inter->getName();
+    //toWrite << inter->getName();
     toWrite << inter->getPositionRatio();
     toWrite << inter->getOrientation();
   }
     toWrite << inter->getPositionRatio();
     toWrite << inter->getOrientation();
   }
@@ -638,8 +1122,7 @@ QDataStream &operator <<(QDataStream &out, BoxItem &b) {
   return out;
 }
 
   return out;
 }
 
-QDataStream &operator >>(QDataStream &in, BoxItem &b)
-{
+QDataStream &operator >>(QDataStream &in, BoxItem &b) {
 
   in.setVersion(QDataStream::Qt_4_8);
 
 
   in.setVersion(QDataStream::Qt_4_8);
 
@@ -669,8 +1152,7 @@ QDataStream &operator >>(QDataStream &in, BoxItem &b)
     in >> positionRatio;
     in >> orientation;
 
     in >> positionRatio;
     in >> orientation;
 
-    inter->setId(id);
-    inter->setName(name);
+    inter->setId(id);    
     inter->setPositionRatio(positionRatio);
     inter->setOrientation(orientation);
     inter->updatePosition();
     inter->setPositionRatio(positionRatio);
     inter->setOrientation(orientation);
     inter->updatePosition();