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

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