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

Private GIT Repository
removing save from repo
[blast.git] / Dispatcher.cpp
1 #include "Dispatcher.h"
2 #include "Parameters.h"
3 #include "MainWindow.h"
4
5 #include "Graph.h"
6 #include "ReferenceBlock.h"
7 #include "GroupBlock.h"
8 #include "FunctionalBlock.h"
9
10 #include "ConnectedInterface.h"
11 #include "ReferenceInterface.h"
12 #include "GroupInterface.h"
13 #include "FunctionalInterface.h"
14
15 #include "GroupWidget.h"
16 #include "GroupScene.h"
17 #include "GroupItem.h"
18 #include "BoxItem.h"
19 #include "InterfaceItem.h"
20 #include "ConnectionItem.h"
21
22 #include "BlockLibraryWidget.h"
23 #include "BlockLibraryTree.h"
24
25 #include "InterfacePropertiesWindow.h"
26
27 int Dispatcher::sceneCounter = 0;
28
29 Dispatcher::Dispatcher(Parameters* _params, MainWindow* _window) {
30   params = _params;
31   mainWindow =_window;
32   params->setDispatcher(this);
33   currentGroup = NULL;
34   topGroup = NULL;    
35 }
36
37 GroupWidget *Dispatcher::loadProject(const QString& filename) {
38
39   QDomElement root;
40   try {
41     root = params->openProjectFile(filename);
42   }
43   catch(Exception err) {
44     return NULL;
45   }
46
47   // creating the top widget/scene
48   topGroup = new GroupWidget(NULL,this,params);
49   currentGroup = topGroup;
50   // getting the newly created scene
51   GroupScene *scene = topGroup->getScene();
52
53   params->setTopScene(scene);
54   params->setCurrentScene(scene);
55
56   try {   
57     params->loadProject(root);
58   }
59   catch(Exception e){
60     cerr << qPrintable(e.getDefaultMessage()) << endl;
61     cerr << "Aborting ..." << endl;
62     // TO DO : deleteting topGroup and all
63     return NULL;
64   }
65
66   groupList.append(topGroup);
67   return topGroup;
68 }
69
70 void Dispatcher::closeCurrentProject() {
71
72   foreach(GroupWidget* win, groupList) {
73     win->deleteLater();
74   }
75   params->destroyGraph();
76 }
77
78 bool Dispatcher::connect(InterfaceItem *iface1, InterfaceItem *iface2) {
79
80   ConnectedInterface* ref1 = iface1->refInter;
81   ConnectedInterface* ref2 = iface2->refInter;
82   // connect both interface
83
84   bool ok1 = false;
85   bool ok2 = false;
86
87   if (ref1->canConnectTo(ref2)) {
88     ok1 = ref1->connectTo(ref2);
89     ok1 = ok1 & ref2->connectFrom(ref1);
90   }
91   if (ref2->canConnectTo(ref1)) {
92     ok2 = ref2->connectTo(ref1);
93     ok2 = ok2 & ref1->connectFrom(ref2);
94   }
95   if ((ok1 == true) || (ok2 == true)) {
96
97     iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2);
98
99     unselectAllItems();
100     params->unsaveModif = true;
101     return true;
102   }
103   return false;
104 }
105
106 void Dispatcher::checkSelection(){
107   InterfaceItem *iface1 = NULL;
108   InterfaceItem *iface2 = NULL;
109
110   GroupScene *scene = params->getCurrentScene();
111   QList<AbstractBoxItem*> list = scene->getGroupAndBlocks();
112   foreach(AbstractBoxItem *block, list){
113     InterfaceItem *tmp = block->getCurrentInterface();
114     if (tmp != NULL) {
115       if (iface1 == NULL) {
116         iface1 = tmp;
117       }
118       else {
119         iface2 = tmp;
120       }
121     }
122   }
123   if(iface1 != NULL && iface2 != NULL){
124     connect(iface1,iface2);
125   }
126 }
127
128 void Dispatcher::unselectAllItems(int direction){
129
130   GroupScene *scene = params->getCurrentScene();
131
132   foreach(BoxItem* block, scene->getBlockItems()) {
133     block->setSelected(false);
134     block->setCurrentInterface(NULL);
135   }
136   scene->unselecteInterfaces();
137   scene->update();
138 }
139
140 void Dispatcher::setCurrentGroupWidget(GroupWidget *win){
141   win->setFocus();
142   win->changeConnectionMode(-1);
143   currentGroup = win;
144   params->setCurrentScene(win->getScene());
145 }
146
147 void Dispatcher::changeConnectionMode(int mode){
148
149   /*
150   foreach(GroupWidget* win, groupList){
151
152     QToolButton* buttonNewConnection = win->getButtonNewConnection();
153
154     QPalette pal = buttonNewConnection->palette();
155
156     if(mode == -1){
157       if(params->sceneMode != Parameters::EditOnConnection){
158         params->sceneMode = Parameters::EditOnConnection;
159         pal.setColor(QPalette::Button, QColor(Qt::lightGray));
160       } else {
161         params->sceneMode = Parameters::EditNoOperation;
162         pal.setColor(QPalette::Button, QColor("#edeceb"));
163       }
164     }
165     else if(mode == Parameters::EditOnConnection){
166       params->sceneMode = Parameters::EditOnConnection;
167       pal.setColor(QPalette::Button, QColor(Qt::lightGray));
168     }
169     else {
170       params->sceneMode = Parameters::EditNoOperation;
171       pal.setColor(QPalette::Button, QColor("#edeceb"));
172     }
173     unselectAllInterfaces();
174
175     buttonNewConnection->setAutoFillBackground(true);
176     buttonNewConnection->setPalette(pal);
177     buttonNewConnection->update();
178   }
179   */
180 }
181
182 void Dispatcher::renameBlockOrGroup(AbstractBoxItem *item){
183   static QString fctName = "Dispatcher::renameBlockOrGroup()";
184 #ifdef DEBUG_FCTNAME
185   cout << "call to " << qPrintable(fctName) << endl;
186 #endif
187
188   bool ok;
189   QString text = QInputDialog::getText(NULL, "Rename an block/group",
190                                        "New name:", QLineEdit::Normal,
191                                        item->getRefBlock()->getName(), &ok);
192
193   if(ok){
194     if(!text.isEmpty() && text.length() < 30){
195       item->getRefBlock()->setName(text);
196       if(item->isGroupItem()){
197         if (currentGroup->isTopGroup()) {
198           mainWindow->setWindowTitle("blast - "+text);
199         }
200         else {
201           currentGroup->setWindowTitle("blast - "+text);
202         }
203       }
204
205       mainWindow->getLibrary()->updateComboScene();
206     }
207     else {
208       QMessageBox::warning(NULL,"Error in given name",
209                            "the element name must be shorter than 30 characters and can't be empty!",
210                            QMessageBox::Ok);
211       renameBlockOrGroup(item);
212     }
213   }
214 }
215
216 void Dispatcher::renameInterface(InterfaceItem *item) {
217   static QString fctName = "Dispatcher::renameInterface()";
218 #ifdef DEBUG_FCTNAME
219   cout << "call to " << qPrintable(fctName) << endl;
220 #endif
221
222   bool ok;
223   QString text = QInputDialog::getText(NULL, "Rename an interface",
224                                        "New name:", QLineEdit::Normal,
225                                        item->refInter->getName(), &ok);
226
227   /* CAUTION: when renaming an interface item, there are two cases :
228      - it refers to a functional block interface (fbi): the fbi keeps its name
229      and the new name is given to item
230      - it refers to a group block interface (gbi) : both gbi and item store the new name
231
232    */
233   if(ok && !text.isEmpty() && text.length() < 30) {
234     if (item->refInter->getOwner()->isGroupBlock()) {
235       item->refInter->setName(text);
236     }
237     item->setName(text);
238
239   }
240   else {
241     QMessageBox::warning(NULL,"Error in given name",
242                          "the interface name must be shorter than 30 characters and can't be empty!",
243                          QMessageBox::Ok);
244     renameInterface(item);
245   }
246 }
247
248 void Dispatcher::duplicateBlock(BoxItem *item){
249   static QString fctName = "Dispatcher::duplicateBlock()";
250 #ifdef DEBUG_FCTNAME
251   cout << "call to " << qPrintable(fctName) << endl;
252 #endif
253
254   GroupScene *scene = item->getScene();
255   AbstractBlock* block = item->getRefBlock();  
256   AbstractBlock *newBlock;
257
258   // only duplicate functional blocks
259   if(block->isFunctionalBlock()) {
260
261     // adding to the model
262     FunctionalBlock* funBlock = (FunctionalBlock*)block;
263     newBlock = params->duplicateFunctionalBlock(funBlock);
264     // adding to the view
265     scene->createBlockItem(newBlock);
266
267     params->unsaveModif = true;
268   }
269 }
270
271 void Dispatcher::duplicateInterface(InterfaceItem *item) {
272   static QString fctName = "Dispatcher::duplicateInterface()";
273 #ifdef DEBUG_FCTNAME
274   cout << "call to " << qPrintable(fctName) << endl;
275 #endif
276
277   AbstractInterface *refI = item->refInter;
278   if (! refI->isFunctionalInterface()) return;
279
280   AbstractBlock *refB = refI->getOwner();
281   if(! refB->isFunctionalBlock()) return;
282
283   FunctionalInterface* iface = (FunctionalInterface*)refI;
284   AbstractInterface *otherRef = iface->clone();
285   if (otherRef == NULL) {
286     QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
287     return;
288   }
289
290   refB->addInterface(otherRef);
291
292   InterfaceItem *otherIface = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)otherRef,item->getOwner(),params);
293   item->getOwner()->addInterface(otherIface,true);
294 }
295
296
297 void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
298   static QString fctName = "Dispatcher::addBlock()";
299 #ifdef DEBUG_FCTNAME
300   cout << "call to " << qPrintable(fctName) << endl;
301 #endif
302
303   GroupScene *scene = searchSceneById(idScene);
304   ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
305   GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
306   FunctionalBlock* newOne = params->getGraph()->addFunctionalBlock(group, ref);
307   scene->createBlockItem(newOne);
308   params->unsaveModif = true;
309 }
310
311
312 GroupWidget *Dispatcher::createTopScene(){
313   static QString fctName = "Dispatcher::createTopScene()";
314 #ifdef DEBUG_FCTNAME
315   cout << "call to " << qPrintable(fctName) << endl;
316 #endif
317
318   // creating the model part of the group
319   Graph* graph = params->createGraph();
320   GroupBlock *refBlock = graph->getTopGroup();
321
322   // creating a fake and not connected interface
323   //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
324
325   // creating the group widget
326   topGroup = new GroupWidget(NULL,this,params);
327   currentGroup = topGroup;
328   // getting the newly created scene
329   GroupScene *scene = topGroup->getScene();
330   scene->setId(sceneCounter++);
331   params->setTopScene(scene);
332   params->setCurrentScene(scene);
333   // creating the view part of the group
334   GroupItem *group = new GroupItem(NULL,refBlock,this,params);
335
336   // adding the fake interface to the top group item
337   //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
338   //group->addInterface(item,true);
339
340   scene->setGroupItem(group);
341
342   groupList.append(topGroup);
343   return topGroup;
344 }
345
346 void Dispatcher::addNewEmptyGroup(GroupScene* scene) {
347   static QString fctName = "Dispatcher::addNewEmptyGroup();";
348 #ifdef DEBUG_FCTNAME
349   cout << "call to " << qPrintable(fctName) << endl;
350 #endif
351
352   // getting the parent block in the graph
353   GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
354   cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
355   GroupBlock* groupBlock = params->getGraph()->createChildBlock(parent);
356   cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
357   // creating the BlockItem in the scene
358   BoxItem* newItem = scene->createBlockItem(groupBlock);
359
360   params->unsaveModif = true;
361
362   GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
363   child->show();
364
365 }
366
367 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
368   static QString fctName = "Dispatcher::createChildScene()";
369 #ifdef DEBUG_FCTNAME
370   cout << "call to " << qPrintable(fctName) << endl;
371 #endif
372
373   // getting back the goup block already created
374   GroupBlock* groupBlock = NULL;
375   if (upperItemOfGroupItem != NULL) {
376     groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
377   }  
378   // creating the view part of the group
379   GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
380   // creating the group widget
381   GroupWidget* group = new GroupWidget(parentWidget, this, params);
382   // getting the newly created scene
383   GroupScene *scene = group->getScene();
384   scene->setId(sceneCounter++);
385   // affecting group item to the scene
386   scene->setGroupItem(groupItem);
387   groupList.append(group);
388
389   mainWindow->getLibrary()->updateComboScene();
390
391   return group;
392 }
393
394 void Dispatcher::destroyScene(GroupScene *scene) {
395   foreach(GroupScene* s, scene->getChildrenScene()) {
396     destroyScene(s);
397   }
398
399   if (scene->getNbChildScene() == 0) {
400     // remove scene from the parent list
401     scene->getParentScene()->removeChildScene(scene);
402     // destroy the GroupWidget
403     groupList.removeAll(scene->getGroupWidget());
404     scene->getGroupWidget()->deleteLater();
405   }
406   else {
407     cerr << "Abnormal case when destroying a scene" << endl;
408   }
409 }
410
411 void Dispatcher::showRaiseWindow(BoxItem *item) {
412   static QString fctName = "Dispatcher::showRaiseWindow()";
413 #ifdef DEBUG_FCTNAME
414   cout << "call to " << qPrintable(fctName) << endl;
415 #endif
416
417   cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
418   GroupItem* child = item->getChildGroupItem();
419   if (child == NULL) {
420     cerr << "abnormal case: child group item is null " << endl;
421     return;
422   }
423
424   GroupWidget* win = child->getScene()->getGroupWidget();
425
426   win->showNormal();
427   win->raise();
428   win->activateWindow();
429
430   currentGroup = win;
431   params->setCurrentScene(currentGroup->getScene());
432 }
433
434 void Dispatcher::showRstClkInter(AbstractBoxItem *item) {
435   static QString fctName = "Dispatcher::showRstClkInter()";
436 #ifdef DEBUG_FCTNAME
437   cout << "call to " << qPrintable(fctName) << endl;
438 #endif
439
440   item->setRstClkVisible(!item->isRstClkVisible());
441   item->resetInterfacesPosition();
442
443   item->getScene()->updateConnectionItemsShape();
444 }
445
446 void Dispatcher::addNewFullGroup() {
447   static QString fctName = "Dispatcher::addNewFullGroup()";
448 #ifdef DEBUG_FCTNAME
449   cout << "call to " << qPrintable(fctName) << endl;
450 #endif
451
452
453 #ifdef DEBUG_INCLFUN
454
455   QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
456   QList<AbstractBlock*> listAbstractBlocks;   //abstract blocks in the group
457   QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
458
459   /* What must be done:
460      1 - creating a new GroupBlock
461      2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
462      3 - creating a BlockItem that references the new GroupBlock
463      4 - creating a new GroupWidget
464      5 - creating a new GroupItem added to the scene of the GroupWidget
465
466    */
467
468   /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
469      associated to the GroupItem of the current scene
470    */
471   GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
472   GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
473   /* step 2: moving selected blocks */
474   foreach(BlockItem* blockItem, listBlocks) {
475     parentBlock->removeBlock(blockItem->getRefBlock());
476     newGroupBlock->addBlock(blockItem->getRefBlock());
477   }
478
479   GroupItem *parent = currentGroup->getScene()->getGroupItem();
480   GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
481   BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
482   GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
483
484   //create the new window
485   GroupWidget* win = new GroupWidget(this,params);
486   win->getScene()->setGroupItem(groupItem);
487   win->getScene()->addItem(groupItem);
488   ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
489   params->addWindow(win);
490   win->show();
491
492   //add the new group
493   params->getCurrentScene()->addBlockItem(blockItem);
494   params->getCurrentScene()->addItem(blockItem);
495   ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
496
497   //replace selected blocks in the group
498   foreach(AbstractBoxItem *block, listBlocks){
499     ((GroupItem*)block->getParentItem())->removeBlockItem(block);
500     ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
501     params->getCurrentScene()->removeItem(block);
502     params->getCurrentScene()->removeBlockItem(block);
503
504     groupBlock->addBlock(block->getRefBlock());
505     listAbstractBlocks.append(block->getRefBlock());
506
507     block->setUpperItem(groupItem);
508     groupItem->addBlockItem(block);
509     win->getScene()->addItem(block);
510     win->getScene()->addBlockItem(block);
511   }
512
513   //replace connection between selected blocks in the group
514   foreach(ConnectionItem *conn, connections){
515     if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
516       if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
517         parent->removeConnection(conn);
518         params->getCurrentScene()->removeItem(conn);
519
520         groupItem->addConnection(conn);
521         win->getScene()->addItem(conn);
522       }
523     }
524   }
525
526   //create new interfaces and connections for the new group
527   foreach(AbstractBoxItem *block, listBlocks){
528     foreach(InterfaceItem *inter, block->getInterfaces()){
529       cout << "inter : " << inter->getName().toStdString() << endl;
530       if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
531         cout << "connected from non null" << endl;
532         if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
533
534           AbstractInterface *iface = inter->refInter->clone(0);
535           iface->setName(iface->getName()+"_group");
536           groupBlock->addInterface(iface);
537
538           InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
539           blockItem->addInterface(ifaceItem);
540           blockItem->resetInterfacesPosition();
541
542           InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
543           groupItem->addInterface(ifaceGroupItem);
544           groupItem->resetInterfacesPosition();
545           foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
546             if(conn->getToInterfaceItem() == inter){
547               conn->setToInterfaceItem(ifaceItem);
548               ifaceItem->refInter->setConnectedFrom(NULL);
549               conn->getFromInterfaceItem()->refInter->clearConnectedTo();
550               connect(ifaceItem,conn->getFromInterfaceItem());
551             }
552           }
553           params->setCurrentWindow(win);
554
555           inter->refInter->setConnectedFrom(NULL);
556           ifaceGroupItem->refInter->clearConnectedTo();
557           connect(inter,ifaceGroupItem);
558           params->setCurrentWindow(mainWindow);
559         }
560       }
561
562       if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
563         cout << "connected to non null" << endl;
564         foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
565           if(!listAbstractBlocks.contains(iface->getOwner())){
566
567             AbstractInterface *iface = inter->refInter->clone(0);
568             iface->setName(iface->getName()+"_group");
569             groupBlock->addInterface(iface);
570
571             InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
572             blockItem->addInterface(ifaceItem);
573             blockItem->resetInterfacesPosition();
574
575             foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
576               if(conn->getFromInterfaceItem() == inter){
577                 conn->setFromInterfaceItem(ifaceItem);
578                 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
579                 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
580               }
581             }
582
583             InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
584             groupItem->addInterface(ifaceGroupItem);
585             groupItem->resetInterfacesPosition();
586             inter->refInter->clearConnectedTo();
587             ifaceGroupItem->refInter->setConnectedFrom(NULL);
588             connect(ifaceGroupItem,inter);
589           }
590         }
591       }
592     }
593   }
594
595   //update window
596
597   parent->updateShape();
598   currentGroup->getScene()->updateConnectionItemsShape();
599   currentGroup = win;
600   groupItem->updateShape();
601   win->getScene()->updateConnectionItemsShape();
602   groupItem->update(groupItem->boundingRect());
603
604 #endif
605 }
606
607 void Dispatcher::removeBlock(BoxItem *item) {
608   static QString fctName = "Dispatcher::removeBlock()";
609 #ifdef DEBUG_FCTNAME
610   cout << "call to " << qPrintable(fctName) << endl;
611 #endif
612
613   /* a BoxItem (group of func) can be removed only if none of its
614      interfaces is connected to a group interface that is itself
615      connected to another one.
616   */
617   bool canRemove = true;
618
619   foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
620     foreach(ConnectionItem* conn, ifaceItem->connections) {
621       InterfaceItem* other = NULL;
622       if (conn->getFromInterfaceItem() == ifaceItem) {
623         other = conn->getToInterfaceItem();
624       }
625       else {
626         other = conn->getFromInterfaceItem();
627       }
628
629       if (other->getOwner()->isGroupItem()) {
630         ConnectedInterface* ref = other->refInter;
631         if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
632           canRemove = false;
633         }
634       }
635     }
636   }
637   if (!canRemove) {
638     QMessageBox::warning(NULL,"Forbidden operation",
639                          "The block has at least one connection to a group interface that is totally connected.",
640                          QMessageBox::Ok);
641     return;
642   }
643
644   QString msg = "";
645   if (item->getRefBlock()->isFunctionalBlock()) {
646     msg = "Removing block ";
647   }
648   else {
649      msg = "Removing group ";
650   }
651   msg += item->getRefBlock()->getName();
652   msg += " and all its connections.\n\nAre you sure ?";
653
654   int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
655   if (ret == QMessageBox::Cancel) {
656     return;
657   }
658   removeAllBlockConnections(item);
659
660   if (item->getRefBlock()->isFunctionalBlock()) {
661     FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
662     GroupBlock* group = AB_TO_GRP(block->getParent());
663     item->getScene()->removeBlockItem(item);
664     params->getGraph()->removeFunctionalBlock(block,group);
665   }
666   else if (item->getRefBlock()->isGroupBlock()) {
667
668     GroupBlock* group = AB_TO_GRP(item->getRefBlock());
669
670     // remove all child scenes recursively
671     GroupItem* subgroup = item->getChildGroupItem();
672     destroyScene(subgroup->getScene());
673     // remove the BoxItem
674     item->getScene()->removeBlockItem(item);
675     // remove the group from the graph
676     params->getGraph()->removeGroupBlock(group);
677   }
678 }
679
680 void Dispatcher::removeAllBlockConnections(BoxItem *item) {
681   static QString fctName = "Dispatcher::removeAllBlockConnection()";
682 #ifdef DEBUG_FCTNAME
683   cout << "call to " << qPrintable(fctName) << endl;
684 #endif
685
686   foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
687     foreach(ConnectionItem* conn, ifaceItem->connections) {
688       removeConnection(conn);
689     }
690   }
691 }
692
693 void Dispatcher::removeConnection(ConnectionItem *conn) {
694   static QString fctName = "Dispatcher::removeConnection()";
695 #ifdef DEBUG_FCTNAME
696   cout << "call to " << qPrintable(fctName) << endl;
697 #endif
698   InterfaceItem* fromIfaceItem = conn->getFromInterfaceItem();
699   InterfaceItem* toIfaceItem = conn->getToInterfaceItem();
700
701 #ifdef DEBUG
702   cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
703 #endif
704
705   InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem
706   GroupItem* groupItem = NULL;
707
708   if (fromIfaceItem->getOwner()->isGroupItem()) {
709     groupIfaceItem = fromIfaceItem;
710     groupItem = toIfaceItem->getOwner()->getScene()->getGroupItem();
711   }
712   else if (toIfaceItem->getOwner()->isGroupItem()) {
713     groupIfaceItem = toIfaceItem;
714     groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
715   }
716   else {
717     groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
718   }
719
720   // removing the connection from graph
721 #ifdef DEBUG
722   cout << "removing connections from graph ..." ;
723 #endif
724   ConnectedInterface *fromInter = fromIfaceItem->refInter;
725   ConnectedInterface *toInter = toIfaceItem->refInter;
726   if (fromInter->getDirection() == AbstractInterface::InOut) {
727     fromInter->clearConnectedTo();
728     fromInter->clearConnectedFrom();
729     toInter->clearConnectedTo();
730     toInter->clearConnectedFrom();
731   }
732   else {
733     fromInter->removeConnectedTo(toInter);
734     toInter->clearConnectedFrom();
735   }
736 #ifdef DEBUG
737   cout << "done." << endl ;
738 #endif
739
740   // removing the connection from scene
741 #ifdef DEBUG
742   cout << "removing connections from scene ..." ;
743 #endif
744   fromIfaceItem->removeConnectionItem(conn);
745   toIfaceItem->removeConnectionItem(conn);
746   groupItem->getScene()->removeConnectionItem(conn);
747
748 #ifdef DEBUG
749   cout << "done." << endl ;
750 #endif
751
752   if (groupIfaceItem != NULL) {
753     ConnectedInterface* groupInter = groupIfaceItem->refInter;
754     groupItem->removeInterface(groupIfaceItem);
755
756     BoxItem* parent2Item = groupItem->getParentItem();
757     if (parent2Item != NULL) {
758       InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
759       parent2Item->removeInterface(group2IfaceItem);
760     }
761     groupInter->getOwner()->removeInterface(groupInter);
762   }
763 }
764
765 void Dispatcher::showBlocksLibrary(){
766   cout << "showing block library" << endl;
767   mainWindow->getLibrary()->show();
768   mainWindow->getLibrary()->raise();
769 }
770
771 void Dispatcher::showProperties(InterfaceItem *inter)
772 {
773   new InterfacePropertiesWindow(inter);
774 }
775
776 /* connectInterToGroup() :
777    The only way for a block (functional of group) within a GroupItem to be connected
778    to the latter is to right-click on one of its interfaces and to choose "connect to group".
779    That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
780    interfaces.
781 */
782 void Dispatcher::connectInterToGroup(InterfaceItem *item){
783
784   // getting the GroupBlock and GroupItem that are parent of the block that owns item
785   ConnectedInterface *refInter = item->refInter;
786   cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
787   GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
788   cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
789   GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
790
791   // creating/adding the group interface in the graph model
792   GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getLevel());
793   groupInter->setType(refInter->getType());
794   groupInter->setWidth(refInter->getWidth());
795   groupInter->setPurpose(refInter->getPurpose());
796   parentItem->getRefBlock()->addInterface(groupInter);
797
798   // connect both interface
799   bool ok = true;
800   if (refInter->getDirection() == AbstractInterface::Output) {
801     ok = refInter->connectTo(groupInter);
802     ok = ok & groupInter->connectFrom(refInter);    
803   }
804   else if (refInter->getDirection() == AbstractInterface::Input) {
805     ok = groupInter->connectTo(refInter);
806     ok = ok & refInter->connectFrom(groupInter);
807   }
808   else if (refInter->getDirection() == AbstractInterface::InOut) {
809     ok = refInter->connectTo(groupInter);
810     ok = ok & groupInter->connectFrom(refInter);
811     ok = ok & groupInter->connectTo(refInter);
812     ok = ok & refInter->connectFrom(groupInter);
813   }
814   if (!ok) {
815     cerr << "abnormal case while connecting a block iface to its parent group" << endl;
816   }
817   // creating/adding the group interface in the current scene model, and connection item
818   InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
819   parentItem->addInterface(groupIfaceItem,true);
820
821   parentItem->getScene()->createConnectionItem(item, groupIfaceItem);
822
823   // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
824   BoxItem* parent2Item = parentItem->getParentItem();
825   if(parent2Item != NULL){
826     InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
827     parent2Item->addInterface(blockIfaceItem,true);
828   }
829
830
831   parentItem->getScene()->updateConnectionItemsShape();
832   unselectAllItems();
833   params->unsaveModif = true;
834
835
836 }
837
838 void Dispatcher::disconnectInterFromGroup(InterfaceItem *item) {
839   static QString fctName = "Dispatcher::disconnectInterFromGroup()";
840 #ifdef DEBUG_FCTNAME
841   cout << "call to " << qPrintable(fctName) << endl;
842 #endif
843
844   // getting the GroupBlock and GroupItem that are parent of the block that owns item
845   ConnectedInterface *refInter = item->refInter;
846   ConnectedInterface *groupInter = NULL;
847   GroupBlock* parentGroup = AB_TO_GRP(refInter->getOwner()->getParent());
848   GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
849
850   // removing the connection from graph
851 #ifdef DEBUG
852   cout << "removing connections from graph ..." ;
853 #endif
854
855   if (refInter->getDirection() == AbstractInterface::Output) {
856     groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
857     refInter->removeConnectedTo(groupInter);
858     groupInter->clearConnectedFrom();
859   }
860   else if (refInter->getDirection() == AbstractInterface::Input) {
861     groupInter = refInter->getConnectedFrom();
862     refInter->clearConnectedFrom();
863     groupInter->clearConnectedTo();
864   }
865   else if (refInter->getDirection() == AbstractInterface::InOut) {
866     groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
867     refInter->clearConnectedTo();
868     refInter->clearConnectedFrom();
869     groupInter->clearConnectedTo();
870     groupInter->clearConnectedFrom();
871   }
872 #ifdef DEBUG
873   cout << "done." << endl ;
874 #endif
875
876   if (groupInter == NULL) {
877     cerr << "abnormal case 1 while removing an interface item of a block, linked to a parent group" << endl;
878   }
879
880 #ifdef DEBUG
881   cout << "getting group interface item, and connection item ..." ;
882 #endif
883
884
885   InterfaceItem* groupIfaceItem = parentItem->searchInterfaceByRef(groupInter);
886   if (groupIfaceItem == NULL) {
887     cerr << "abnormal case 2 while removing an interface item of a block, linked to a parent group" << endl;
888   }
889   ConnectionItem* conn = parentItem->getScene()->searchConnectionItem(item,groupIfaceItem);
890   if (conn == NULL) {
891     cerr << "abnormal case 3 while removing an interface item of a block, linked to a parent group" << endl;
892   }
893 #ifdef DEBUG
894   cout << "done." << endl ;
895 #endif
896
897   // removing the interface group item from the group item, and the connection item
898 #ifdef DEBUG
899   cout << "removing group interface item, and connection item ..." ;
900 #endif
901
902   item->removeConnectionItem(conn);
903   groupIfaceItem->removeConnectionItem(conn);
904   parentItem->removeInterface(groupIfaceItem); // CAUTION : this deletes the interface item.
905   parentItem->getScene()->removeConnectionItem(conn);
906 #ifdef DEBUG
907   cout << "done." << endl ;
908 #endif
909
910   // removing the interface box item in the parent scene
911 #ifdef DEBUG
912   cout << "removing the inteeface item of box item in parent scene if needed ..." ;
913 #endif
914
915   BoxItem* parent2Item = parentItem->getParentItem();
916   if (parent2Item != NULL) {
917     InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
918     parent2Item->removeInterface(group2IfaceItem);
919   }
920 #ifdef DEBUG
921   cout << "done." << endl ;
922 #endif
923
924   // removing the interface group from the group
925 #ifdef DEBUG
926   cout << "removing group interface ..." ;
927 #endif
928   parentGroup->removeInterface(groupInter);
929 #ifdef DEBUG
930   cout << "done." << endl ;
931 #endif
932
933 }
934 void Dispatcher::removeBlockInterface(InterfaceItem *item) {
935   static QString fctName = "Dispatcher::removeBlockInterface()";
936 #ifdef DEBUG_FCTNAME
937   cout << "call to " << qPrintable(fctName) << endl;
938 #endif
939
940   /* first, remove all connections from item
941      NB:  if there is a connection to a group interface, then this
942      method should not be called if the group interface is also
943      connected to another interface. Normally, this is not possible
944      because such a check is done when creating the contextual menu
945      that allows to remove an interface.
946    */
947   foreach(ConnectionItem* conn, item->connections) {
948     removeConnection(conn);
949   }
950
951   ConnectedInterface* ref = item->refInter;
952   item->getOwner()->removeInterface(item);
953   FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
954   fun->removeInterface(ref);
955 }
956
957 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
958   static QString fctName = "Dispatcher::removeGroupInterface()";
959 #ifdef DEBUG_FCTNAME
960   cout << "call to " << qPrintable(fctName) << endl;
961 #endif
962
963   /* NB: there is a single connection between item and another one that is owned
964      by a BoxItem. Thus, we just have to find it and to call disconnectInterFromGroup();
965    */
966   ConnectionItem* conn = item->connections.at(0);
967   if (conn->getFromInterfaceItem() == item) {
968     disconnectInterFromGroup(conn->getToInterfaceItem());
969   }
970   else {
971     disconnectInterFromGroup(conn->getFromInterfaceItem());
972   }
973 }
974
975 QMap<int, QString> Dispatcher::getAllGroupNames() {
976
977   QMap<int, QString> list;
978   foreach(GroupWidget *group, groupList) {
979     list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
980   }
981   return list;
982 }
983
984 GroupScene* Dispatcher::searchSceneById(int id) {
985   foreach(GroupWidget *group, groupList){
986     if(group->getScene()->getId() == id)
987       return group->getScene();
988   }
989   cout << "search scene by id :" << id << " :: not found..." << endl;
990   return NULL;
991 }
992
993 GroupItem *Dispatcher::searchGroupItemById(int id) {
994   foreach(GroupWidget *group, groupList) {
995     GroupScene* scene = group->getScene();
996     if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
997   }
998   cout << "search GroupItem by id :" << id << " :: not found..." << endl;
999   return NULL;
1000 }
1001
1002 BoxItem *Dispatcher::searchBlockItemById(int id) {
1003   foreach(GroupWidget *group, groupList) {
1004
1005     GroupScene* scene = group->getScene();
1006     foreach(BoxItem *item, scene->getBlockItems()){
1007       if(item->getId() == id){
1008           return item;
1009       }
1010     }
1011   }
1012   cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1013   return NULL;
1014 }
1015
1016 InterfaceItem* Dispatcher::searchInterfaceItemById(int id) {
1017
1018   foreach(GroupWidget *group, groupList) {
1019
1020     GroupScene* scene = group->getScene();
1021
1022     foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1023       if(item->getId() == id){
1024         return item;
1025       }
1026     }
1027     foreach(BoxItem *block, scene->getBlockItems()){
1028       foreach(InterfaceItem *item, block->getInterfaces()){
1029         if(item->getId() == id){
1030           return item;
1031         }
1032       }
1033     }
1034   }
1035   cout << "search interface by id :" << id << " :: not found..." << endl;
1036   return NULL;
1037 }
1038