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

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