From: stephane Domas <stephane.domas@univ-fcomte.fr>
Date: Thu, 27 Apr 2017 21:25:12 +0000 (+0200)
Subject: insert/move/remove block/groups/interface done. Next to fo: loading project file
X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/commitdiff_plain/f311fbc3e1436bf248c54225f0743cfa671c4bd7?ds=sidebyside

insert/move/remove block/groups/interface done. Next to fo: loading project file
---

diff --git a/AbstractBlock.h b/AbstractBlock.h
index 2c89cbf..19209b7 100644
--- a/AbstractBlock.h
+++ b/AbstractBlock.h
@@ -25,6 +25,7 @@ public:
 
   // getters
   inline QString getName() { return name; }
+  inline int nbParameters() { return params.size(); }
   inline QList<BlockParameter *> getParameters() { return params; }
   inline QList<AbstractInterface*> getInputs() { return inputs; }
   inline QList<AbstractInterface*> getOutputs() { return outputs; }
diff --git a/BoxItem.cpp b/BoxItem.cpp
index 0b1cd03..237c7ee 100644
--- a/BoxItem.cpp
+++ b/BoxItem.cpp
@@ -285,7 +285,7 @@ void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
 
   int mode = getScene()->getEditionMode();
 
-  dispatcher->setCurrentGroupWidget(getScene()->getGroupWindow());
+  dispatcher->setCurrentGroupWidget(getScene()->getGroupWidget());
 
   if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) {
     InterfaceItem *inter = getInterfaceFromCursor(x,y);
@@ -368,6 +368,7 @@ void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent  *event) {
         params->setEditState(Parameters::EditNoOperation);
       }
       else {
+        //QMessageBox::warning(NULL,"Error","Cannot connect selected interfaces", QMessageBox::Ok);
         getScene()->setSelectedInterface(2,NULL);
         params->setEditState(Parameters::EditStartConnection);
       }
@@ -454,9 +455,10 @@ void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
 void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
 
   QMenu menu;
-  QAction* removeAction = menu.addAction("Remove");
-  QAction* duplicateAction = menu.addAction("Duplicate");
-  QAction* renameAction = menu.addAction("Rename");
+  QAction* titleAction = NULL;
+  QAction* removeAction = NULL;
+  QAction* duplicateAction = NULL;
+  QAction* renameAction = NULL;
   QAction* connectToGroup = NULL;
   QAction* disconnectFromGroup = NULL;
   QAction* showProperties = NULL;
@@ -466,48 +468,81 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
   QAction* showParameters = NULL;
 
   InterfaceItem* ifaceItem = getInterfaceFromCursor(event->pos().x(), event->pos().y());
+  // menu for interface
   if( ifaceItem != NULL){
+
+    titleAction = menu.addAction("Interface operations");
+    titleAction->setEnabled(false);
+    menu.addSeparator();
+
+
     showProperties = menu.addAction("Show properties");
+    renameAction = menu.addAction("Rename");
 
     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");
     }
-    else if ((iface->getDirection() == AbstractInterface::Output) && (!iface->isConnectedTo())) {
+    else if ((iface->getDirection() == AbstractInterface::Output) && (iface->getConnectionToParentGroup() == NULL)) {
       connectToGroup = menu.addAction("Connect to group output");
     }
     else if (iface->getConnectionFromParentGroup() != NULL) {
       ifaceGroup = iface->getConnectionFromParentGroup();
-      if ((!ifaceGroup->isConnectedFrom()) || (!ifaceGroup->isConnectedTo())) {
+      //if ((!ifaceGroup->isConnectedFrom()) || (!ifaceGroup->isConnectedTo())) {
+      if (!ifaceGroup->isConnectedFrom()) {
         disconnectFromGroup = menu.addAction("Disconnect from group");
       }
+      else {
+        canRemove = false;
+      }
     }
     else if (iface->getConnectionToParentGroup() != NULL) {
       ifaceGroup = iface->getConnectionToParentGroup();
-      if ((!ifaceGroup->isConnectedFrom()) || (!ifaceGroup->isConnectedTo())) {
+      //if ((!ifaceGroup->isConnectedFrom()) || (!ifaceGroup->isConnectedTo())) {
+      if (!ifaceGroup->isConnectedTo()) {
         disconnectFromGroup = menu.addAction("Disconnect from group");
       }
+      else {
+        canRemove = false;
+      }
     }
 
     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(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");
+      showRstClkInter = menu.addAction("Show reset/clock interfaces");
+      showRstClkInter->setCheckable(true);
+      showRstClkInter->setChecked(rstClkVisible);
+    }
+    removeAction = menu.addAction("Remove");
   }
 
   QAction* selectedAction = NULL;
@@ -516,16 +551,21 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
   if(selectedAction == NULL) return ;
 
   if (selectedAction == removeAction) {
-    dispatcher->removeBlock(this);
+    if(ifaceItem != NULL) {
+     dispatcher->removeBlockInterface(ifaceItem);
+    }
+    else {
+      dispatcher->removeBlock(this);
+    }
   }
   else if (selectedAction == duplicateAction) {
     dispatcher->duplicateBlock(this);
   }
   else if(selectedAction == renameAction){
     if(ifaceItem != NULL)
-      dispatcher->rename(ifaceItem);
+      dispatcher->renameInterface(ifaceItem);
     else
-      dispatcher->rename(this);
+      dispatcher->renameBlockOrGroup(this);
   }
   else if(selectedAction == showProperties){
     dispatcher->showProperties(ifaceItem);
diff --git a/ConnectionItem.cpp b/ConnectionItem.cpp
index b6d99a5..eaf46c2 100644
--- a/ConnectionItem.cpp
+++ b/ConnectionItem.cpp
@@ -727,13 +727,37 @@ void ConnectionItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
 }
 
 void ConnectionItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
-  QMenu menu;
-  QAction* removeAction = menu.addAction("Remove");
-  QAction * selectedAction= menu.exec(event->screenPos());
+  /* have to check if the connection can be removed.
+     If the from or to InterfaceItem is owned by a group item, and this item
+     is both connected to and from, thus it is impossible to remove this connection
+   */
+  bool canRemove = true;
+  InterfaceItem* groupIfaceItem = NULL;
+  if (fromInterfaceItem->getOwner()->isGroupItem()) {
+    groupIfaceItem = fromInterfaceItem;
+  }
+  else if (toInterfaceItem->getOwner()->isGroupItem()) {
+    groupIfaceItem = toInterfaceItem;
+  }
+
+  if (groupIfaceItem != NULL) {
+    ConnectedInterface* ref = groupIfaceItem->refInter;
+    if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
+      canRemove = false;
+    }
+  }
 
-  if(selectedAction == removeAction){
-    dispatcher->removeConnection(this);
-    dispatcher->removeUselessGroupInterfaces();
+  if (canRemove) {
+    QMenu menu;
+    QAction* titleAction = menu.addAction("Connection operations");
+    titleAction->setEnabled(false);
+    menu.addSeparator();
+    QAction* removeAction = menu.addAction("Remove");
+    QAction * selectedAction= menu.exec(event->screenPos());
+
+    if(selectedAction == removeAction){
+      dispatcher->removeConnection(this);
+    }
   }
 }
 
diff --git a/ConnectionItem.h b/ConnectionItem.h
index 867e811..6370c90 100644
--- a/ConnectionItem.h
+++ b/ConnectionItem.h
@@ -10,6 +10,7 @@
 class Dispatcher;
 class Parameters;
 class InterfaceItem;
+class GroupScene;
 
 using namespace std;
 using namespace Qt;
@@ -51,6 +52,7 @@ public:
 
   void prepareChange();
 
+  inline GroupScene* getScene() { return (GroupScene*)(scene()); }
   inline InterfaceItem* getToInterfaceItem(){ return toInterfaceItem; }
   inline void setToInterfaceItem(InterfaceItem *iface){ toInterfaceItem = iface; }
   inline InterfaceItem* getFromInterfaceItem(){ return fromInterfaceItem; }
diff --git a/Dispatcher.cpp b/Dispatcher.cpp
index 810396e..b191651 100644
--- a/Dispatcher.cpp
+++ b/Dispatcher.cpp
@@ -179,10 +179,14 @@ void Dispatcher::changeConnectionMode(int mode){
   */
 }
 
-void Dispatcher::rename(AbstractBoxItem *item){
+void Dispatcher::renameBlockOrGroup(AbstractBoxItem *item){
+  static QString fctName = "Dispatcher::renameBlockOrGroup()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
 
   bool ok;
-  QString text = QInputDialog::getText(NULL, "Rename an element",
+  QString text = QInputDialog::getText(NULL, "Rename an block/group",
                                        "New name:", QLineEdit::Normal,
                                        item->getRefBlock()->getName(), &ok);
 
@@ -204,12 +208,17 @@ void Dispatcher::rename(AbstractBoxItem *item){
       QMessageBox::warning(NULL,"Error in given name",
                            "the element name must be shorter than 30 characters and can't be empty!",
                            QMessageBox::Ok);
-      rename(item);
+      renameBlockOrGroup(item);
     }
   }
 }
 
-void Dispatcher::rename(InterfaceItem *item){
+void Dispatcher::renameInterface(InterfaceItem *item) {
+  static QString fctName = "Dispatcher::renameInterface()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
   bool ok;
   QString text = QInputDialog::getText(NULL, "Rename an interface",
                                        "New name:", QLineEdit::Normal,
@@ -232,13 +241,17 @@ void Dispatcher::rename(InterfaceItem *item){
     QMessageBox::warning(NULL,"Error in given name",
                          "the interface name must be shorter than 30 characters and can't be empty!",
                          QMessageBox::Ok);
-    rename(item);
+    renameInterface(item);
   }
 }
 
 void Dispatcher::duplicateBlock(BoxItem *item){
+  static QString fctName = "Dispatcher::duplicateBlock()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
 
-  GroupScene *scene = params->getCurrentScene();
+  GroupScene *scene = item->getScene();
   AbstractBlock* block = item->getRefBlock();  
   AbstractBlock *newBlock;
 
@@ -255,7 +268,12 @@ void Dispatcher::duplicateBlock(BoxItem *item){
   }
 }
 
-void Dispatcher::duplicateInterface(InterfaceItem *item){
+void Dispatcher::duplicateInterface(InterfaceItem *item) {
+  static QString fctName = "Dispatcher::duplicateInterface()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
   AbstractInterface *refI = item->refInter;
   if (! refI->isFunctionalInterface()) return;
 
@@ -277,14 +295,25 @@ void Dispatcher::duplicateInterface(InterfaceItem *item){
 
 
 void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
+  static QString fctName = "Dispatcher::addBlock()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
 
   GroupScene *scene = searchSceneById(idScene);
-  FunctionalBlock* newOne = params->addFunctionalBlock(idCategory, idBlock);  
+  ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
+  GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
+  FunctionalBlock* newOne = params->getGraph()->addFunctionalBlock(group, ref);
   scene->createBlockItem(newOne);
+  params->unsaveModif = true;
 }
 
 
 GroupWidget *Dispatcher::createTopScene(){
+  static QString fctName = "Dispatcher::createTopScene()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
 
   // creating the model part of the group
   Graph* graph = params->createGraph();
@@ -314,7 +343,32 @@ GroupWidget *Dispatcher::createTopScene(){
   return topGroup;
 }
 
+void Dispatcher::addNewEmptyGroup(GroupScene* scene) {
+  static QString fctName = "Dispatcher::addNewEmptyGroup();";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
+  // getting the parent block in the graph
+  GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
+  cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
+  GroupBlock* groupBlock = params->getGraph()->createChildBlock(parent);
+  cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
+  // creating the BlockItem in the scene
+  BoxItem* newItem = scene->createBlockItem(groupBlock);
+
+  params->unsaveModif = true;
+
+  GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
+  child->show();
+
+}
+
 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
+  static QString fctName = "Dispatcher::createChildScene()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
 
   // getting back the goup block already created
   GroupBlock* groupBlock = NULL;
@@ -337,21 +391,51 @@ GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *up
   return group;
 }
 
-void Dispatcher::showRaiseWindow(AbstractBoxItem *item) {
-  GroupWidget* win = item->getScene()->getGroupWindow();
-  if (win->isTopGroup()) {
-    mainWindow->show();
-    mainWindow->raise();
+void Dispatcher::destroyScene(GroupScene *scene) {
+  foreach(GroupScene* s, scene->getChildrenScene()) {
+    destroyScene(s);
+  }
+
+  if (scene->getNbChildScene() == 0) {
+    // remove scene from the parent list
+    scene->getParentScene()->removeChildScene(scene);
+    // destroy the GroupWidget
+    groupList.removeAll(scene->getGroupWidget());
+    scene->getGroupWidget()->deleteLater();
   }
   else {
-    win->show();
-    win->raise();
+    cerr << "Abnormal case when destroying a scene" << endl;
+  }
+}
+
+void Dispatcher::showRaiseWindow(BoxItem *item) {
+  static QString fctName = "Dispatcher::showRaiseWindow()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
+  cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
+  GroupItem* child = item->getChildGroupItem();
+  if (child == NULL) {
+    cerr << "abnormal case: child group item is null " << endl;
+    return;
   }
+
+  GroupWidget* win = child->getScene()->getGroupWidget();
+
+  win->showNormal();
+  win->raise();
+  win->activateWindow();
+
   currentGroup = win;
   params->setCurrentScene(currentGroup->getScene());
 }
 
 void Dispatcher::showRstClkInter(AbstractBoxItem *item) {
+  static QString fctName = "Dispatcher::showRstClkInter()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
 
   item->setRstClkVisible(!item->isRstClkVisible());
   item->resetInterfacesPosition();
@@ -360,6 +444,11 @@ void Dispatcher::showRstClkInter(AbstractBoxItem *item) {
 }
 
 void Dispatcher::addNewFullGroup() {
+  static QString fctName = "Dispatcher::addNewFullGroup()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
 
 #ifdef DEBUG_INCLFUN
 
@@ -515,88 +604,162 @@ void Dispatcher::addNewFullGroup() {
 #endif
 }
 
-void Dispatcher::removeBlock(AbstractBoxItem *item) {
-
-#ifdef DEBUG_INCLFUN
-
-  GroupScene *scene = params->getCurrentScene();
-  AbstractBlock* block = item->getRefBlock();
-  if (block->isReferenceBlock()) return;
-
-  GroupBlock* group = (GroupBlock*)item->getParentItem()->getRefBlock();
+void Dispatcher::removeBlock(BoxItem *item) {
+  static QString fctName = "Dispatcher::removeBlock()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
 
-  removeConnections(item);
+  /* a BoxItem (group of func) can be removed only if none of its
+     interfaces is connected to a group interface that is itself
+     connected to another one.
+  */
+  bool canRemove = true;
 
-  //récupérer l'objet
-  group->removeBlock(block);
+  foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
+    foreach(ConnectionItem* conn, ifaceItem->connections) {
+      InterfaceItem* other = NULL;
+      if (conn->getFromInterfaceItem() == ifaceItem) {
+        other = conn->getToInterfaceItem();
+      }
+      else {
+        other = conn->getFromInterfaceItem();
+      }
 
-  //remove the associated window
-  if(block->isGroupBlock()){
-    foreach(QWidget *window, params->windows){
-      if(!window->inherits("MainWindow")){
-        if(((GroupWidget*)window)->getScene()->getGroupItem()->getRefBlock() == block){
-          params->removeWindow(window);
-          delete window;
+      if (other->getOwner()->isGroupItem()) {
+        ConnectedInterface* ref = other->refInter;
+        if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
+          canRemove = false;
         }
       }
     }
   }
+  if (!canRemove) {
+    QMessageBox::warning(NULL,"Forbidden operation",
+                         "The block has at least one connection to a group interface that is totally connected.",
+                         QMessageBox::Ok);
+    return;
+  }
 
-  delete block;
+  QString msg = "";
+  if (item->getRefBlock()->isFunctionalBlock()) {
+    msg = "Removing block ";
+  }
+  else {
+     msg = "Removing group ";
+  }
+  msg += item->getRefBlock()->getName();
+  msg += " and all its connections.\n\nAre you sure ?";
 
-  //supprimer l'item de la scène
-  cout << "dispatcher : remove item of scene " << params->currentWindow << endl;
-  ((GroupItem *)scene->getGroupItem())->removeBlockItem(item);
-  scene->removeItem(item);
-  scene->removeBlockItem(item);
-  delete item;
+  int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
+  if (ret == QMessageBox::Cancel) {
+    return;
+  }
+  removeAllBlockConnections(item);
 
-  ((GroupItem *)scene->getGroupItem())->updateShape();
+  if (item->getRefBlock()->isFunctionalBlock()) {
+    FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
+    GroupBlock* group = AB_TO_GRP(block->getParent());
+    item->getScene()->removeBlockItem(item);
+    params->getGraph()->removeFunctionalBlock(block,group);
+  }
+  else if (item->getRefBlock()->isGroupBlock()) {
 
-  params->updateToolbar();
-  params->unsaveModif = true;
+    GroupBlock* group = AB_TO_GRP(item->getRefBlock());
 
-#endif
+    // remove all child scenes recursively
+    GroupItem* subgroup = item->getChildGroupItem();
+    destroyScene(subgroup->getScene());
+    // remove the BoxItem
+    item->getScene()->removeBlockItem(item);
+    // remove the group from the graph
+    params->getGraph()->removeGroupBlock(group);
+  }
 }
 
-void Dispatcher::removeAllBlockConnections(AbstractBoxItem *block) {
+void Dispatcher::removeAllBlockConnections(BoxItem *item) {
+  static QString fctName = "Dispatcher::removeAllBlockConnection()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
 
-  GroupScene* scene = block->getScene();
-  // supprimer les connections associées au bloc
-  foreach (ConnectionItem *conn, scene->getConnectionItems()) {
-    if(conn->getToInterfaceItem()->owner == block || conn->getFromInterfaceItem()->owner == block){
+  foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
+    foreach(ConnectionItem* conn, ifaceItem->connections) {
       removeConnection(conn);
     }
   }
-  scene->getGroupItem()->updateInterfacesAndConnections();
 }
 
 void Dispatcher::removeConnection(ConnectionItem *conn) {
+  static QString fctName = "Dispatcher::removeConnection()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  InterfaceItem* fromIfaceItem = conn->getFromInterfaceItem();
+  InterfaceItem* toIfaceItem = conn->getToInterfaceItem();
 
-  GroupScene *scene = params->getCurrentScene();
-  GroupItem* currentGroup = scene->getGroupItem();
+#ifdef DEBUG
+  cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
+#endif
+
+  InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem
+  GroupItem* groupItem = NULL;
 
-  conn->getFromInterfaceItem()->unconnectTo(conn->getToInterfaceItem());  
+  if (fromIfaceItem->getOwner()->isGroupItem()) {
+    groupIfaceItem = fromIfaceItem;
+    groupItem = toIfaceItem->getOwner()->getScene()->getGroupItem();
+  }
+  else if (toIfaceItem->getOwner()->isGroupItem()) {
+    groupIfaceItem = toIfaceItem;
+    groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
+  }
+  else {
+    groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
+  }
 
-  scene->removeConnectionItem(conn);
-  delete conn;
+  // removing the connection from graph
+#ifdef DEBUG
+  cout << "removing connections from graph ..." ;
+#endif
+  ConnectedInterface *fromInter = fromIfaceItem->refInter;
+  ConnectedInterface *toInter = toIfaceItem->refInter;
+  if (fromInter->getDirection() == AbstractInterface::InOut) {
+    fromInter->clearConnectedTo();
+    fromInter->clearConnectedFrom();
+    toInter->clearConnectedTo();
+    toInter->clearConnectedFrom();
+  }
+  else {
+    fromInter->removeConnectedTo(toInter);
+    toInter->clearConnectedFrom();
+  }
+#ifdef DEBUG
+  cout << "done." << endl ;
+#endif
 
-  currentGroup->updateInterfacesAndConnections();
-  params->unsaveModif = true;
-}
+  // removing the connection from scene
+#ifdef DEBUG
+  cout << "removing connections from scene ..." ;
+#endif
+  fromIfaceItem->removeConnectionItem(conn);
+  toIfaceItem->removeConnectionItem(conn);
+  groupItem->getScene()->removeConnectionItem(conn);
 
-void Dispatcher::removeUselessGroupInterfaces() {
+#ifdef DEBUG
+  cout << "done." << endl ;
+#endif
 
-  GroupScene *scene = params->getCurrentScene();
-  GroupItem* currentGroup = scene->getGroupItem();
+  if (groupIfaceItem != NULL) {
+    ConnectedInterface* groupInter = groupIfaceItem->refInter;
+    groupItem->removeInterface(groupIfaceItem);
 
-  foreach(InterfaceItem *inter, currentGroup->getInterfaces()) {
-    if(inter->refInter->getConnectedTo().length() == 0) {
-      // NB : remove from view also remove from model
-      currentGroup->removeInterface(inter);           
+    BoxItem* parent2Item = groupItem->getParentItem();
+    if (parent2Item != NULL) {
+      InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
+      parent2Item->removeInterface(group2IfaceItem);
     }
+    groupInter->getOwner()->removeInterface(groupInter);
   }
-  scene->updateConnectionItemsShape();
 }
 
 void Dispatcher::showBlocksLibrary(){
@@ -691,7 +854,7 @@ void Dispatcher::disconnectInterFromGroup(InterfaceItem *item) {
 
   if (refInter->getDirection() == AbstractInterface::Output) {
     groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
-    refInter->clearConnectedTo();
+    refInter->removeConnectedTo(groupInter);
     groupInter->clearConnectedFrom();
   }
   else if (refInter->getDirection() == AbstractInterface::Input) {
@@ -768,6 +931,28 @@ void Dispatcher::disconnectInterFromGroup(InterfaceItem *item) {
 #endif
 
 }
+void Dispatcher::removeBlockInterface(InterfaceItem *item) {
+  static QString fctName = "Dispatcher::removeBlockInterface()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
+  /* first, remove all connections from item
+     NB:  if there is a connection to a group interface, then this
+     method should not be called if the group interface is also
+     connected to another interface. Normally, this is not possible
+     because such a check is done when creating the contextual menu
+     that allows to remove an interface.
+   */
+  foreach(ConnectionItem* conn, item->connections) {
+    removeConnection(conn);
+  }
+
+  ConnectedInterface* ref = item->refInter;
+  item->getOwner()->removeInterface(item);
+  FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
+  fun->removeInterface(ref);
+}
 
 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
   static QString fctName = "Dispatcher::removeGroupInterface()";
diff --git a/Dispatcher.h b/Dispatcher.h
index fa77360..fd61087 100644
--- a/Dispatcher.h
+++ b/Dispatcher.h
@@ -37,13 +37,14 @@ public:
   void unselectAllItems(int direction=0);
   void setCurrentGroupWidget(GroupWidget *win);
   void changeConnectionMode(int mode = -1);
-  void rename(AbstractBoxItem* item);
-  void rename(InterfaceItem* item);
+
+
   GroupWidget* createTopScene();
   GroupWidget* createChildScene(GroupWidget* parentWidget, BoxItem* upperItemOfGroupItem = NULL);
-  void showRaiseWindow(AbstractBoxItem *item);
+  void destroyScene(GroupScene* scene);
+  void showRaiseWindow(BoxItem *item);
   void showRstClkInter(AbstractBoxItem *item);
-  void addNewEmptyGroup();
+  void addNewEmptyGroup(GroupScene *scene);
   void addNewFullGroup();  
 
   inline GroupWidget* getCurrentGroup() { return currentGroup; }
@@ -58,21 +59,64 @@ public slots:
   GroupItem* searchGroupItemById(int id);
   InterfaceItem* searchInterfaceItemById(int id);
 
-  void removeBlock(AbstractBoxItem* item);
+  // block ops
+  void addBlock(int idCategory, int idBlock, int idScene);
+  void removeBlock(BoxItem* item);
   void duplicateBlock(BoxItem* item);
+  void renameBlockOrGroup(AbstractBoxItem* item);
+
+  // interface ops
+  /*!
+   * \brief connectInterToGroup
+   * \param item item is always owned by a BoxItem
+   *
+   * This method is called only when the user right clicks on an InterfaceItem (that belongs
+   * to a BoxItem and if it is NOT connected to an InterfaceItem of the GroupItem) and chooses
+   * connect to group in the contextual menu.
+   * Thus, parameter item is always owned by a BoxItem
+   */
+  void connectInterToGroup(InterfaceItem* item);
+  /*!
+   * \brief disconnectInterFromGroup
+   * \param item item is always owned by a BoxItem
+   *
+   * This method is called only when the user right clicks on an InterfaceItem (that belongs
+   * to a BoxItem and if it IS connected to an InterfaceItem of the GroupItem) and chooses
+   * disconnect from group in the contextual menu.
+   * Thus, parameter item is always owned by a BoxItem
+   */
+  void disconnectInterFromGroup(InterfaceItem* item);
+  /*!
+   * \brief removeBlockInterface
+   * \param item item is always owned by a BoxItem
+   *
+   * This method is called only when the user right clicks on an InterfaceItem (that belongs
+   * to a BoxItem and has a multiplicity > 1) and chooses remove in the contextual menu.
+   * Thus, parameter item is always owned by a BoxItem
+   */
+  void removeBlockInterface(InterfaceItem* item);
+  /*!
+   * \brief removeGroupInterface
+   * \param item item is always owned by a GroupItem
+   *
+   * This method is called only when the user right clicks on an InterfaceItem (that belongs
+   * to a GroupItem and if it is connected only to an inner interface) and chooses remove in the contextual menu.
+   * Thus, parameter item is always owned by a GroupItem
+   */
+  void removeGroupInterface(InterfaceItem* item);
   void duplicateInterface(InterfaceItem* item);
-  void addBlock(int idCategory, int idBlock, int idScene);
+  void showProperties(InterfaceItem *inter);
+  void renameInterface(InterfaceItem* item);
+
+  // connection ops
   ConnectionItem *addConnection(InterfaceItem *input, InterfaceItem *output);
-  void removeAllBlockConnections(AbstractBoxItem *block);
+  void removeAllBlockConnections(BoxItem *item);
   void removeConnection(ConnectionItem *conn);
-  void removeUselessGroupInterfaces();
+
+
+  // others
   void showBlocksLibrary();
-  void showProperties(InterfaceItem *inter);
-  void connectInterToGroup(InterfaceItem* item);
-  void disconnectInterFromGroup(InterfaceItem* item);
-  void removeGroupInterface(InterfaceItem* item);
 
-  void addConnection();
 
   void closeCurrentProject();
 
diff --git a/FunctionalInterface.cpp b/FunctionalInterface.cpp
index cc9f765..bce7ca1 100644
--- a/FunctionalInterface.cpp
+++ b/FunctionalInterface.cpp
@@ -65,10 +65,10 @@ int FunctionalInterface::getInterfaceMultiplicity() {
     return -1;
   }
   else if ( reference->getMultiplicity() == -1) {
-    return ifaceCount+1;
+    return ifaceCount;
   }
-  else if ( reference->getMultiplicity() > ifaceCount) {
-    return ifaceCount+1;
+  else if ( ifaceCount < reference->getMultiplicity()) {
+    return ifaceCount;
   }
   return -1;
 }
@@ -82,7 +82,7 @@ AbstractInterface *FunctionalInterface::clone() {
   inter->setPurpose(purpose);
   inter->setLevel(level);  
   inter->connectFrom(NULL);
-  inter->setName(reference->getName()+"_"+QString::number(id));
+  inter->setName(reference->getName()+"_"+QString::number(id+1));
   return inter;
 }
 
diff --git a/Graph.cpp b/Graph.cpp
index 1c87123..8cd0f99 100644
--- a/Graph.cpp
+++ b/Graph.cpp
@@ -29,3 +29,13 @@ FunctionalBlock* Graph::addFunctionalBlock(GroupBlock* group, ReferenceBlock* re
 
   return newBlock;
 }
+
+bool Graph::removeFunctionalBlock(FunctionalBlock* block, GroupBlock *group) {
+  group->removeBlock(block);
+}
+
+bool Graph::removeGroupBlock(GroupBlock *group) {
+  group->removeAllBlocks();
+  GroupBlock* parent = AB_TO_GRP(group->getParent());
+  parent->removeBlock(group);
+}
diff --git a/Graph.h b/Graph.h
index 7f34682..723e8eb 100644
--- a/Graph.h
+++ b/Graph.h
@@ -26,6 +26,8 @@ public:
 
   GroupBlock* createChildBlock(GroupBlock* parent);
   FunctionalBlock* addFunctionalBlock(GroupBlock *group, ReferenceBlock *ref);
+  bool removeFunctionalBlock(FunctionalBlock* block, GroupBlock *group);
+  bool removeGroupBlock(GroupBlock *group);
 
 private:  
   GroupBlock* topGroup;
diff --git a/GroupBlock.cpp b/GroupBlock.cpp
index 4ec7f6b..74ec197 100644
--- a/GroupBlock.cpp
+++ b/GroupBlock.cpp
@@ -40,9 +40,22 @@ void GroupBlock::setParent(AbstractBlock *_parent) {
     topGroup = false;
   }
 }
+void GroupBlock::removeAllBlocks() {
+  foreach(AbstractBlock* block, blocks) {
+    if (block->isGroupBlock()) {
+      GroupBlock* group = AB_TO_GRP(block);
+      group->removeAllBlocks();
+    }
+    removeBlock(block);
+  }
+}
 
 void GroupBlock::removeBlock(AbstractBlock* block) {
-    blocks.removeAll(block);
+  /* CAUTION: no check is done if the block has connected interface
+     or not. Thus, they must be deleted elsewhere.
+  */
+  blocks.removeAll(block);
+  delete block;
 }
 
 void GroupBlock::parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock *> *blocksToConfigure) {
diff --git a/GroupBlock.h b/GroupBlock.h
index 3316637..5a03236 100644
--- a/GroupBlock.h
+++ b/GroupBlock.h
@@ -21,7 +21,7 @@ public:
   virtual ~GroupBlock();
 
   // getters
-
+  inline QList<AbstractBlock*> getBlocks() { return blocks; }
   // setters
   void setParent(AbstractBlock *_parent);
 
@@ -32,6 +32,7 @@ public:
   // others
   inline void addBlock(AbstractBlock* block) { blocks.append(block); }
   void removeBlock(AbstractBlock* block);
+  void removeAllBlocks();
   void parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock*>* blocksToConfigure);  
   void addGenericParameter(QString name, QString type, QString value);
   void removeGenericParameter(QString name);
@@ -40,7 +41,7 @@ public:
 
 private:  
   bool topGroup;  
-  QList<AbstractBlock*> blocks; // contains instances of FunctionalBlock or GroupBlock
+  QList<AbstractBlock*> blocks; // contains instances of FunctionalBlock or GroupBlock that are children of this group
 
 };
 
diff --git a/GroupItem.cpp b/GroupItem.cpp
index bb26e53..fa341b2 100644
--- a/GroupItem.cpp
+++ b/GroupItem.cpp
@@ -9,6 +9,7 @@
 #include "AbstractInterface.h"
 #include "ConnectedInterface.h"
 #include "GroupScene.h"
+#include "ParametersWindow.h"
 
 
 GroupItem::GroupItem(BoxItem *_parentItem,
@@ -17,6 +18,9 @@ GroupItem::GroupItem(BoxItem *_parentItem,
                      Parameters *_params) throw(Exception) :AbstractBoxItem( _refBlock, _dispatcher, _params) {
 
   parentItem = _parentItem;
+  if (parentItem != NULL) {
+    parentItem->setChildGroupItem(this);
+  }
 
   /*
   minimumBoxWidth = nameWidth+2*nameMargin;
@@ -337,7 +341,7 @@ void GroupItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
 
   int mode = getScene()->getEditionMode();
 
-  dispatcher->setCurrentGroupWidget(getScene()->getGroupWindow());
+  dispatcher->setCurrentGroupWidget(getScene()->getGroupWidget());
 
   /* NOTE : commneted because group interface are normally
      created and the connected directly to a block within
@@ -500,12 +504,19 @@ void GroupItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
 
 void GroupItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
   QMenu menu;
+  QAction* titleAction = NULL;
   QAction* showProperties = NULL;
   QAction* removeAction = NULL;
   QAction* renameAction = NULL;
+  QAction* showParameters = NULL;
 
   InterfaceItem* ifaceItem = getInterfaceFromCursor(event->pos().x(), event->pos().y());
-  if( ifaceItem != NULL){
+
+  // menu for interface
+  if( ifaceItem != NULL) {
+    titleAction = menu.addAction("Interface operations");
+    titleAction->setEnabled(false);
+    menu.addSeparator();
     showProperties = menu.addAction("Show properties");
     renameAction = menu.addAction("Rename");
     menu.addSeparator();
@@ -520,6 +531,13 @@ void GroupItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
     }
   }
   else {
+    titleAction = menu.addAction("Block operations");
+    titleAction->setEnabled(false);
+    menu.addSeparator();
+
+    if (refBlock->nbParameters() > 0) {
+      showParameters = menu.addAction("Show parameters");
+    }
     renameAction = menu.addAction("Rename");
   }
   QAction* selectedAction = menu.exec(event->screenPos());
@@ -528,16 +546,19 @@ void GroupItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
 
   if(selectedAction == renameAction){
     if(ifaceItem != NULL)
-      dispatcher->rename(ifaceItem);
+      dispatcher->renameInterface(ifaceItem);
     else
-      dispatcher->rename(this);
+      dispatcher->renameBlockOrGroup(this);
   }
   else if(selectedAction == showProperties){
     dispatcher->showProperties(ifaceItem);
-  }
+  }  
   else if (selectedAction == removeAction) {
     dispatcher->removeGroupInterface(ifaceItem);
   }
+  else if(selectedAction == showParameters) {
+    new ParametersWindow(refBlock, params, NULL);
+  }
 }
 
 InterfaceItem* GroupItem::isHoverInterface(QPointF point) {
diff --git a/GroupScene.h b/GroupScene.h
index 3078305..e7b42ec 100644
--- a/GroupScene.h
+++ b/GroupScene.h
@@ -51,7 +51,8 @@ public:
   inline QList<BoxItem*> getBlockItems() { return blockItems; }
   inline QList<ConnectionItem*> getConnectionItems() { return connectionItems; }
   inline QList<GroupScene*> getChildrenScene() { return childrenScene; }
-  inline GroupWidget* getGroupWindow() { return window; }
+  inline GroupScene* getParentScene() { return parentScene; }
+  inline GroupWidget* getGroupWidget() { return window; }
   inline int getId() { return id; }
   inline EditMode getEditionMode() { return editMode; }
   InterfaceItem* getSelectedInterface(int id);
@@ -77,6 +78,8 @@ public:
   void removeConnectionItem(ConnectionItem* item);
   void removeGroupItem();
   inline void addChildScene(GroupScene* child) { childrenScene.append(child); }
+  inline void removeChildScene(GroupScene* child) { childrenScene.removeAll(child); }
+  inline int getNbChildScene() { return childrenScene.size(); }
   void unselecteInterfaces();
 
   QList<AbstractBoxItem*> getGroupAndBlocks();
@@ -94,7 +97,7 @@ public:
 private:
   Dispatcher *dispatcher;
   Parameters *params;
-  GroupScene* parentScene; // the parnet scene, =NULL for top scene
+  GroupScene* parentScene; // the parent scene, =NULL for top scene
   GroupWidget* window; // the GroupWindow that contains that scene
   int id;
   GroupItem *groupItem; // mandatory to be an instance of GroupItem.
diff --git a/GroupWidget.cpp b/GroupWidget.cpp
index 043561e..2ef7cd1 100644
--- a/GroupWidget.cpp
+++ b/GroupWidget.cpp
@@ -95,6 +95,7 @@ void GroupWidget::focusInEvent(QFocusEvent *e) {
 void GroupWidget::closeEvent(QCloseEvent *e) {
   clearFocus();
   focusNextChild();
+
 }
 
 
@@ -222,16 +223,8 @@ void GroupWidget::updateBlockButton() {
 
 void GroupWidget::slotNewEmptyGroup() {
 
-  // creating the GroupBlock in graph model
-  GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
-  cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
-  GroupBlock* groupBlock = params->getGraph()->createChildBlock(parent);
-  cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
-  // creating the BlockItem in the scene
-  BoxItem* newItem = scene->createBlockItem(groupBlock);
+  dispatcher->addNewEmptyGroup(scene);
 
-  GroupWidget* child = dispatcher->createChildScene(this,newItem);
-  child->show();
 }
 
 void GroupWidget::slotNewGroup()
diff --git a/MainWindow.cpp b/MainWindow.cpp
index 1f8c1c0..e9f8414 100644
--- a/MainWindow.cpp
+++ b/MainWindow.cpp
@@ -291,6 +291,7 @@ void MainWindow::slotNewProject(){
   GroupWidget* topGroup = dispatcher->createTopScene();
   addTopGroup(topGroup);
   library->updateComboScene();
+  params->isCurrentProject = true;
 }
 
 void MainWindow::slotCloseProject(){
diff --git a/Parameters.cpp b/Parameters.cpp
index c991e5f..fce0435 100644
--- a/Parameters.cpp
+++ b/Parameters.cpp
@@ -69,37 +69,23 @@ void Parameters::destroyGraph() {
   delete graph;
 }
 
-GroupBlock* Parameters::addGroupBlock() {
-  GroupBlock* parent = AB_TO_GRP(currentScene->getGroupItem()->getRefBlock());
-  GroupBlock* newOne = graph->createChildBlock(parent);
-  return newOne;
-}
-
-FunctionalBlock* Parameters::addFunctionalBlock(int idCategory, int idBlock) {
+ReferenceBlock* Parameters::getReferenceBlock(int idCategory, int idBlock) {
 
   BlockCategory* blockCat = categoryTree->searchCategory(idCategory);
 
   if (blockCat == NULL) return NULL;
-  GroupBlock* group = AB_TO_GRP(currentScene->getGroupItem()->getRefBlock());
   ReferenceBlock* ref = blockCat->getBlock(idBlock);
-  if (ref == NULL) return NULL;
-
-  FunctionalBlock* newOne = graph->addFunctionalBlock(group, ref);
-  unsaveModif = true;
-
-  return newOne;
+  return ref;
 }
 
+
 FunctionalBlock* Parameters::duplicateFunctionalBlock(FunctionalBlock *block) {
 
   ReferenceBlock* ref = block->getReference();
   GroupBlock* group = AB_TO_GRP(block->getParent());
 
-  // adding to the group
-  FunctionalBlock* newBlock = new FunctionalBlock(group,ref);
-  newBlock->populate();
-  group->addBlock(newBlock);
-
+  // adding to the graph
+  FunctionalBlock* newBlock = graph->addFunctionalBlock(group,ref);
   return newBlock;
 }
 
@@ -1032,11 +1018,11 @@ void Parameters::updateToolbar() {
   int nb = currentScene->getBlockItems().length();
   for(int i = 0; i<nb; i++){
     if(currentScene->getBlockItems().at(i)->isSelected()){
-      currentScene->getGroupWindow()->enableGroupButton(true);
+      currentScene->getGroupWidget()->enableGroupButton(true);
       return;
     }
   }
-  currentScene->getGroupWindow()->enableGroupButton(false);
+  currentScene->getGroupWidget()->enableGroupButton(false);
 }
 
 
@@ -1098,9 +1084,6 @@ void Parameters::save(QString confFile) {
     // cross the scene level by level using a FIFO
     QList<GroupScene*> fifoScene;
     fifoScene.append(topScene);
-    foreach(ConnectionItem* item, topScene->getConnectionItems()) {
-      allConnections.append(item);
-    }
 
     GroupScene *scene;
     while (!fifoScene.isEmpty()) {
@@ -1109,11 +1092,12 @@ void Parameters::save(QString confFile) {
       foreach(GroupScene* s, scene->getChildrenScene()) {
         fifoScene.append(s);
       }
-      foreach(ConnectionItem* item, topScene->getConnectionItems()) {
+
+      foreach(ConnectionItem* item, scene->getConnectionItems()) {
         allConnections.append(item);
       }
     }
-
+    writer.writeEndElement();    //</scenes>
 
     writer.writeStartElement("connections");
     foreach(ConnectionItem* item, allConnections) {
diff --git a/Parameters.h b/Parameters.h
index 69887a9..7f14814 100644
--- a/Parameters.h
+++ b/Parameters.h
@@ -35,6 +35,13 @@ class Exception;
 using namespace std;
 using namespace Qt;
 
+/*!
+ * \brief The Parameters class
+ *
+ * Parameters class represents the Model part of blast in MVC paradigm.
+ * It contains all data necessary to create a design: the graph of blocks,
+ * the scenes, ...
+ */
 class Parameters {
 
 public :
@@ -113,9 +120,8 @@ public :
 
   Graph* createGraph();
   void destroyGraph();
-  inline Graph* getGraph() { return graph; }
-  GroupBlock* addGroupBlock(); // adding an empty GroupBlock to the current group
-  FunctionalBlock* addFunctionalBlock(int idCategory, int idBlock); // adding a functional block to current group
+  inline Graph* getGraph() { return graph; }  
+  ReferenceBlock* getReferenceBlock(int idCategory, int idBlock); // get the reference block from its category and index
   FunctionalBlock* duplicateFunctionalBlock(FunctionalBlock* block); // adding a copy of a functional block to current group
 
 
diff --git a/ParametersWindow.cpp b/ParametersWindow.cpp
index 07f96fa..182460d 100644
--- a/ParametersWindow.cpp
+++ b/ParametersWindow.cpp
@@ -20,6 +20,7 @@ ParametersWindow::ParametersWindow(AbstractBlock *_block, Parameters *_params, B
 
     comboBox = new QComboBox;
 
+    cout << "block has " <<block->getParameters().size() << " params" << endl;
     foreach(BlockParameter *param, block->getParameters()){
       comboBox->addItem(param->getName());
     }
diff --git a/blast.creator.user b/blast.creator.user
index 868e2d3..9930e19 100755
--- a/blast.creator.user
+++ b/blast.creator.user
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 3.2.1, 2017-04-26T18:51:42. -->
+<!-- Written by QtCreator 3.2.1, 2017-04-27T20:11:44. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>
-  <value type="QByteArray">{3701e197-5b6c-48ea-9e98-a6cf6de18672}</value>
+  <value type="QByteArray">{c8006d66-d34f-42be-ad10-d0207752286d}</value>
  </data>
  <data>
   <variable>ProjectExplorer.Project.ActiveTarget</variable>
@@ -60,7 +60,7 @@
   <valuemap type="QVariantMap">
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
-   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{ed04208c-8774-456b-99b9-4a02094ca7a4}</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{2c9bf876-3476-44eb-8065-1f0844704dda}</value>
    <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
    <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
    <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
diff --git a/projectfile.xsd b/projectfile.xsd
index 36fe54e..8a35bc9 100644
--- a/projectfile.xsd
+++ b/projectfile.xsd
@@ -184,9 +184,9 @@
     </xs:group>
 
     <xs:group name="block_itemsElmtGroup">
-	<xs:sequence>
-	    <xs:element ref="bi_functional" minOccurs="0" maxOccurs="unbounded"/>
-	    <xs:element ref="bi_group" minOccurs="0"/>
+      <xs:sequence>
+	<xs:element ref="bi_group" minOccurs="0" maxOccurs="unbounded"/>
+	<xs:element ref="bi_functional" minOccurs="0" maxOccurs="unbounded"/>
 	</xs:sequence>
     </xs:group>