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

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