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

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