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

Private GIT Repository
8d1164964036eb4af1ede213cb1e7325ed9c9b0a
[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 first 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     // creating the clkrstgen item
697     BoxItem* clkResetItem = scene->createBoxItem(newOne, BoxItem::TopLeft, AbstractBoxItem::Position | AbstractBoxItem::Dimension, BoxItem::NoSpan);
698     params->blockToItem.insert(newOne,clkResetItem);
699     // creating top group ext_clk iface item
700     ConnectedInterface* fromIfaceClk = AI_TO_CON(topBlock->getIfaceFromName("ext_clk"));
701     InterfaceItem* fromIfaceItemClk = new InterfaceItem(0.5 , Parameters::West, fromIfaceClk, group, params, true);
702     group->addInterfaceItem(fromIfaceItemClk,true);
703     // creating top group ext_reset iface item
704     ConnectedInterface* fromIfaceReset = AI_TO_CON(topBlock->getIfaceFromName("ext_reset"));
705     InterfaceItem* fromIfaceItemReset = new InterfaceItem(0.5 , Parameters::West, fromIfaceReset, group, params, false);
706     group->addInterfaceItem(fromIfaceItemReset,true);
707     // connecting ext_clk iface items
708     InterfaceItem* toIfaceItemClk = clkResetItem->searchInterfaceItemByName("ext_clk");
709     if (toIfaceItemClk == NULL) {
710       cerr << "Abnormal case while connecting top group ext_clk to clkrstgen" << endl;
711     }
712     createConnection(context,fromIfaceItemClk, toIfaceItemClk, false);
713     // connecting ext_reset iface items
714     InterfaceItem* toIfaceItemReset = clkResetItem->searchInterfaceItemByName("ext_reset");
715     if (toIfaceItemReset == NULL) {
716       cerr << "Abnormal case while connecting top group ext_reset to clkrstgen" << endl;
717     }
718     createConnection(context,fromIfaceItemReset, toIfaceItemReset, false);
719   }
720
721
722   groupList.append(topGroupWidget);
723   return topGroupWidget;
724 }
725
726 GroupWidget* Dispatcher::addNewEmptyGroup(Context context, GroupScene* scene, bool show) {
727   static QString fctName = "Dispatcher::addNewEmptyGroup();";
728 #ifdef DEBUG_FCTNAME
729   cout << "call to " << qPrintable(fctName) << endl;
730 #endif
731
732   // getting the parent block in the graph
733   GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
734   cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
735   GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent);
736   cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
737   // creating the BlockItem in the scene
738   BoxItem* newItem = scene->createBoxItem(groupBlock);
739
740   params->unsaveModif = true;
741
742   GroupWidget* child = createChildScene(context, scene->getGroupWidget(),newItem);
743   if (show) child->show();
744   return child;
745
746 }
747
748 GroupWidget *Dispatcher::createChildScene(Context context, GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
749   static QString fctName = "Dispatcher::createChildScene()";
750 #ifdef DEBUG_FCTNAME
751   cout << "call to " << qPrintable(fctName) << endl;
752 #endif
753
754   GroupWidget* group = NULL;
755   /* NB: this method may be called during design process or when loading
756      a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
757      cannot be initialized yet. This is why there are 2 cases below
758    */
759
760   if (upperItemOfGroupItem != NULL) {
761     // getting back the goup block already created
762     GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
763     // creating the view part of the group
764     GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
765
766     // creating the group widget
767     group = new GroupWidget(parentWidget, this, params);
768     // getting the newly created scene
769     GroupScene *scene = group->getScene();
770     scene->setId(sceneCounter++);
771     // affecting group item to the scene
772     scene->setGroupItem(groupItem);
773     groupList.append(group);
774
775     mainWindow->getLibrary()->updateComboScene();
776   }
777   else {
778     GroupItem *groupItem = new GroupItem(this,params);
779     // creating the group widget
780     group = new GroupWidget(parentWidget, this, params);
781     // getting the newly created scene
782     GroupScene *scene = group->getScene();
783     // affecting group item to the scene
784     scene->setGroupItem(groupItem);
785     groupList.append(group);
786   }
787   return group;
788 }
789
790 void Dispatcher::destroyScene(Context context, GroupScene *scene) {
791   foreach(GroupScene* s, scene->getChildrenScene()) {
792     destroyScene(context, s);
793   }
794
795   if (scene->getNbChildScene() == 0) {
796     // remove scene from the parent list, if possible
797     if (scene->getParentScene() != NULL) {
798       scene->getParentScene()->removeChildScene(scene);
799     }
800     // destroy the GroupWidget
801     groupList.removeAll(scene->getGroupWidget());
802     scene->getGroupWidget()->deleteLater();
803   }
804   else {
805     cerr << "Abnormal case when destroying a scene" << endl;
806   }
807 }
808
809 void Dispatcher::showRaiseWindow(Context context, BoxItem *item) {
810   static QString fctName = "Dispatcher::showRaiseWindow()";
811 #ifdef DEBUG_FCTNAME
812   cout << "call to " << qPrintable(fctName) << endl;
813 #endif
814
815   cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
816   GroupItem* child = item->getChildGroupItem();
817   if (child == NULL) {
818     cerr << "abnormal case: child group item is null " << endl;
819     return;
820   }
821
822   GroupWidget* win = child->getScene()->getGroupWidget();
823
824   win->showNormal();
825   win->raise();
826   win->activateWindow();
827
828   currentGroupWidget = win;
829   params->setCurrentScene(currentGroupWidget->getScene());
830 }
831
832 void Dispatcher::showRstClkIface(Context context, AbstractBoxItem *item) {
833   static QString fctName = "Dispatcher::showRstClkIface()";
834 #ifdef DEBUG_FCTNAME
835   cout << "call to " << qPrintable(fctName) << endl;
836 #endif
837
838   item->setRstClkVisible(!item->isRstClkVisible());
839   
840 }
841
842 void Dispatcher::showWishboneIface(Context context, AbstractBoxItem *item) {
843   static QString fctName = "Dispatcher::showWishboneIface()";
844 #ifdef DEBUG_FCTNAME
845   cout << "call to " << qPrintable(fctName) << endl;
846 #endif
847
848   item->setWishboneVisible(!item->isWishboneVisible());  
849 }
850
851 void Dispatcher::addNewFullGroup(Context context) {
852   static QString fctName = "Dispatcher::addNewFullGroup()";
853 #ifdef DEBUG_FCTNAME
854   cout << "call to " << qPrintable(fctName) << endl;
855 #endif
856
857
858 #ifdef DEBUG_INCLFUN
859
860   QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
861   QList<AbstractBlock*> listAbstractBlocks;   //abstract blocks in the group
862   QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
863
864   /* What must be done:
865      1 - creating a new GroupBlock
866      2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
867      3 - creating a BlockItem that references the new GroupBlock
868      4 - creating a new GroupWidget
869      5 - creating a new GroupItem added to the scene of the GroupWidget
870
871    */
872
873   /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
874      associated to the GroupItem of the current scene
875    */
876   GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
877   GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
878   /* step 2: moving selected blocks */
879   foreach(BlockItem* blockItem, listBlocks) {
880     parentBlock->removeBlock(blockItem->getRefBlock());
881     newGroupBlock->addBlock(blockItem->getRefBlock());
882   }
883
884   GroupItem *parent = currentGroup->getScene()->getGroupItem();
885   GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
886   BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
887   GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
888
889   //create the new window
890   GroupWidget* win = new GroupWidget(this,params);
891   win->getScene()->setGroupItem(groupItem);
892   win->getScene()->addItem(groupItem);
893   ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
894   params->addWindow(win);
895   win->show();
896
897   //add the new group
898   params->getCurrentScene()->addBlockItem(blockItem);
899   params->getCurrentScene()->addItem(blockItem);
900   ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
901
902   //replace selected blocks in the group
903   foreach(AbstractBoxItem *block, listBlocks){
904     ((GroupItem*)block->getParentItem())->removeBlockItem(block);
905     ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
906     params->getCurrentScene()->removeItem(block);
907     params->getCurrentScene()->removeBlockItem(block);
908
909     groupBlock->addBlock(block->getRefBlock());
910     listAbstractBlocks.append(block->getRefBlock());
911
912     block->setUpperItem(groupItem);
913     groupItem->addBlockItem(block);
914     win->getScene()->addItem(block);
915     win->getScene()->addBlockItem(block);
916   }
917
918   //replace connection between selected blocks in the group
919   foreach(ConnectionItem *conn, connections){
920     if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
921       if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
922         parent->removeConnection(conn);
923         params->getCurrentScene()->removeItem(conn);
924
925         groupItem->addConnection(conn);
926         win->getScene()->addItem(conn);
927       }
928     }
929   }
930
931   //create new interfaces and connections for the new group
932   foreach(AbstractBoxItem *block, listBlocks){
933     foreach(InterfaceItem *inter, block->getInterfaces()){
934       cout << "inter : " << inter->getName().toStdString() << endl;
935       if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
936         cout << "connected from non null" << endl;
937         if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
938
939           AbstractInterface *iface = inter->refInter->clone(0);
940           iface->setName(iface->getName()+"_group");
941           groupBlock->addInterface(iface);
942
943           InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
944           blockItem->addInterface(ifaceItem);
945           blockItem->resetInterfacesPosition();
946
947           InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
948           groupItem->addInterface(ifaceGroupItem);
949           groupItem->resetInterfacesPosition();
950           foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
951             if(conn->getToInterfaceItem() == inter){
952               conn->setToInterfaceItem(ifaceItem);
953               ifaceItem->refInter->setConnectedFrom(NULL);
954               conn->getFromInterfaceItem()->refInter->clearConnectedTo();
955               connect(ifaceItem,conn->getFromInterfaceItem());
956             }
957           }
958           params->setCurrentWindow(win);
959
960           inter->refInter->setConnectedFrom(NULL);
961           ifaceGroupItem->refInter->clearConnectedTo();
962           connect(inter,ifaceGroupItem);
963           params->setCurrentWindow(mainWindow);
964         }
965       }
966
967       if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
968         cout << "connected to non null" << endl;
969         foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
970           if(!listAbstractBlocks.contains(iface->getOwner())){
971
972             AbstractInterface *iface = inter->refInter->clone(0);
973             iface->setName(iface->getName()+"_group");
974             groupBlock->addInterface(iface);
975
976             InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
977             blockItem->addInterface(ifaceItem);
978             blockItem->resetInterfacesPosition();
979
980             foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
981               if(conn->getFromInterfaceItem() == inter){
982                 conn->setFromInterfaceItem(ifaceItem);
983                 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
984                 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
985               }
986             }
987
988             InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
989             groupItem->addInterface(ifaceGroupItem);
990             groupItem->resetInterfacesPosition();
991             inter->refInter->clearConnectedTo();
992             ifaceGroupItem->refInter->setConnectedFrom(NULL);
993             connect(ifaceGroupItem,inter);
994           }
995         }
996       }
997     }
998   }
999
1000   //update window
1001
1002   parent->updateShape();
1003   currentGroup->getScene()->updateConnectionItemsShape();
1004   currentGroup = win;
1005   groupItem->updateShape();
1006   win->getScene()->updateConnectionItemsShape();
1007   groupItem->update(groupItem->boundingRect());
1008
1009 #endif
1010 }
1011
1012 void Dispatcher::removeBoxItem(Context context, BoxItem *item) {
1013   static QString fctName = "Dispatcher::removeBoxItem()";
1014 #ifdef DEBUG_FCTNAME
1015   cout << "call to " << qPrintable(fctName) << endl;
1016 #endif
1017
1018   if (context != Design) return;
1019
1020   /* a BoxItem (group of func) can be removed only if none of its
1021      interfaces is connected to a group interface that is itself
1022      connected to another one.
1023   */
1024   bool canRemove = true;
1025
1026   foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
1027     foreach(ConnectionItem* conn, ifaceItem->connections) {
1028       InterfaceItem* other = NULL;
1029       if (conn->getFromInterfaceItem() == ifaceItem) {
1030         other = conn->getToInterfaceItem();
1031       }
1032       else {
1033         other = conn->getFromInterfaceItem();
1034       }
1035
1036       if (other->getOwner()->isGroupItem()) {
1037         ConnectedInterface* ref = other->refInter;
1038         if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
1039           canRemove = false;
1040         }
1041       }
1042     }
1043   }
1044   if (!canRemove) {
1045     QMessageBox::warning(NULL,"Forbidden operation",
1046                          "The block has at least one connection to a group interface that is totally connected.",
1047                          QMessageBox::Ok);
1048     return;
1049   }
1050
1051   QString msg = "";
1052   if (item->getRefBlock()->isFunctionalBlock()) {
1053     msg = "Removing block ";
1054   }
1055   else {
1056      msg = "Removing group ";
1057   }
1058   msg += item->getRefBlock()->getName();
1059   msg += " and all its connections.\n\nAre you sure ?";
1060
1061   int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
1062   if (ret == QMessageBox::Cancel) {
1063     return;
1064   }
1065   removeAllBlockConnections(context, item);
1066
1067   if (item->getRefBlock()->isFunctionalBlock()) {
1068     FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());    
1069     item->getScene()->removeBoxItem(item);
1070     params->getGraph()->removeFunctionalBlock(block);
1071     params->blockToItem.remove(block);
1072
1073   }
1074   else if (item->getRefBlock()->isGroupBlock()) {
1075
1076     GroupBlock* group = AB_TO_GRP(item->getRefBlock());
1077
1078     // remove all child scenes recursively
1079     GroupItem* subgroup = item->getChildGroupItem();
1080     destroyScene(context, subgroup->getScene());
1081     // remove the BoxItem
1082     item->getScene()->removeBoxItem(item);
1083     // remove the group from the graph
1084     params->getGraph()->removeGroupBlock(group);
1085   }
1086 }
1087
1088 void Dispatcher::removeAllBlockConnections(Context context, AbstractBoxItem *item) {
1089   static QString fctName = "Dispatcher::removeAllBlockConnection()";
1090 #ifdef DEBUG_FCTNAME
1091   cout << "call to " << qPrintable(fctName) << endl;
1092 #endif
1093
1094   foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
1095     foreach(ConnectionItem* conn, ifaceItem->connections) {
1096       removeConnection(context, conn);
1097     }
1098   }
1099 }
1100
1101 void Dispatcher::removeSourceItem(Context context, SourceItem *item) {
1102   static QString fctName = "Dispatcher::removeSourceItem()";
1103 #ifdef DEBUG_FCTNAME
1104   cout << "call to " << qPrintable(fctName) << endl;
1105 #endif
1106   
1107   QString msg = "Removing source ";
1108   
1109   msg += item->getRefBlock()->getName();
1110   msg += " and all its connections.\n\nAre you sure ?";
1111
1112   int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
1113   if (ret == QMessageBox::Cancel) {
1114     return;
1115   }
1116   removeAllBlockConnections(context, item);
1117   
1118   FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());  
1119   item->getScene()->removeSourceItem(item);
1120   params->getGraph()->removeSourceBlock(block);  
1121 }
1122
1123
1124 void Dispatcher::removeConnection(Context context, ConnectionItem *connItem) {
1125   static QString fctName = "Dispatcher::removeConnection()";
1126 #ifdef DEBUG_FCTNAME
1127   cout << "call to " << qPrintable(fctName) << endl;
1128 #endif
1129   InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
1130   InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
1131
1132 #ifdef DEBUG
1133   cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
1134 #endif
1135
1136   InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not
1137   GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem
1138
1139   ConnectedInterface *fromInter = fromIfaceItem->refInter;
1140   ConnectedInterface *toInter = toIfaceItem->refInter;  
1141   
1142   // test if one of the interface bounded to item is owned by a GroupItem
1143   if (fromIfaceItem->getOwner()->isGroupItem()) {
1144     groupItem = ABI_TO_GI(fromIfaceItem->getOwner());
1145     groupIfaceItem = fromIfaceItem;    
1146   }
1147   else if (toIfaceItem->getOwner()->isGroupItem()) {
1148     groupItem = ABI_TO_GI(toIfaceItem->getOwner());
1149     groupIfaceItem = toIfaceItem;    
1150   }
1151   else {
1152     groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
1153   }
1154
1155   // removing the connection from graph
1156 #ifdef DEBUG
1157   cout << "removing connections from graph ..." ;
1158 #endif  
1159   fromInter->disconnectTo(toInter);
1160   
1161 #ifdef DEBUG
1162   cout << "done." << endl ;
1163 #endif
1164
1165   // removing the connection from scene
1166 #ifdef DEBUG
1167   cout << "removing connections from scene ..." ;
1168 #endif  
1169   groupItem->getScene()->removeConnectionItem(connItem);
1170
1171 #ifdef DEBUG
1172   cout << "done." << endl ;
1173 #endif
1174   
1175   // if one of the interface bounded to connItem is owned by the GroupItem of the scene
1176   if (groupIfaceItem != NULL) {
1177     
1178     // determine if the interface must be removed since it has no more connections.
1179     bool groupInterRemove = false;
1180     if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true;
1181     
1182     if (groupInterRemove) {
1183       // get the GroupInterface from interface item
1184       ConnectedInterface* groupInter = groupIfaceItem->refInter;            
1185       // remove interface from GroupItem, and delete it.
1186       groupItem->removeInterfaceItem(groupIfaceItem);      
1187       // get the parent BoxItem of GroupItem if it exists.
1188       BoxItem* parent2Item = groupItem->getParentItem();
1189       if (parent2Item != NULL) {
1190         InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter);
1191         // remove interface intem in parent BoxItem
1192         parent2Item->removeInterfaceItem(group2IfaceItem);
1193       }
1194       // remove GroupInterface in the graph.
1195       groupInter->getOwner()->removeInterface(groupInter);
1196     }
1197   }
1198 }
1199
1200 void Dispatcher::showBlocksLibrary(){
1201   cout << "showing block library" << endl;
1202   mainWindow->getLibrary()->show();
1203   mainWindow->getLibrary()->raise();
1204 }
1205
1206 void Dispatcher::showProperties(Context context, InterfaceItem *inter) {
1207   new InterfacePropertiesWindow(inter);
1208 }
1209
1210 /* connectInterToGroup() :
1211    The only way for a block (functional of group) within a GroupItem to be connected
1212    to the latter is to right-click on one of its interfaces and to choose "connect to group".
1213    That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
1214    interfaces.
1215 */
1216 void Dispatcher::connectInterToGroup(Context context, InterfaceItem *item){
1217
1218   // getting the GroupBlock and GroupItem that are parent of the block that owns item
1219   ConnectedInterface *refInter = item->refInter;
1220   cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
1221   GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
1222   cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
1223   GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
1224
1225   // creating/adding the group interface in the graph model
1226   GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());  
1227   parentItem->getRefBlock()->addInterface(groupInter);
1228   // creating/adding the group control interface in the graph model if the purpose is data
1229   if (refInter->getPurpose() == AbstractInterface::Data) {
1230     GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
1231     groupCtlInter->setAssociatedIface(groupInter);
1232     parentItem->getRefBlock()->addInterface(groupCtlInter);
1233   }
1234   // creating/adding the group interface in the current scene model, and connection item
1235   InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1236   parentItem->addInterfaceItem(groupIfaceItem,true);
1237
1238   // creating the connection, in graph and with an item
1239   createConnection(context, item, groupIfaceItem);
1240
1241   // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1242   BoxItem* parent2Item = parentItem->getParentItem();
1243   if(parent2Item != NULL){
1244     InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1245     parent2Item->addInterfaceItem(blockIfaceItem,true);
1246   }
1247
1248
1249   parentItem->getScene()->updateConnectionItemsShape();
1250   unselectAllItems(context);
1251   params->unsaveModif = true;
1252 }
1253
1254 void Dispatcher::removeFunctionalInterface(Context context, InterfaceItem *item) {
1255   static QString fctName = "Dispatcher::removeBlockInterface()";
1256 #ifdef DEBUG_FCTNAME
1257   cout << "call to " << qPrintable(fctName) << endl;
1258 #endif
1259
1260   /* first, remove all connections from item
1261      NB:  if there is a connection to a group interface, then this
1262      method should not be called if the group interface is also
1263      connected to another interface. Normally, this is not possible
1264      because such a check is done when creating the contextual menu
1265      that allows to remove an interface.
1266    */
1267   foreach(ConnectionItem* conn, item->connections) {
1268     removeConnection(context, conn);
1269   }
1270
1271   ConnectedInterface* ref = item->refInter;
1272   item->getOwner()->removeInterfaceItem(item);
1273   FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1274   fun->removeInterface(ref);
1275 }
1276
1277 void Dispatcher::removeGroupInterface(Context context, InterfaceItem *item) {
1278   static QString fctName = "Dispatcher::removeGroupInterface()";
1279 #ifdef DEBUG_FCTNAME
1280   cout << "call to " << qPrintable(fctName) << endl;
1281 #endif
1282
1283   /* NB: just remove all connections from/to this item, since when there are no more
1284      ones to a GroupItem, it is automatically deleted.
1285    */
1286   foreach(ConnectionItem* conn, item->connections) {
1287     removeConnection(context, conn);
1288   }
1289 }
1290
1291 QMap<int, QString> Dispatcher::getAllGroupNames() {
1292
1293   QMap<int, QString> list;
1294   foreach(GroupWidget *group, groupList) {
1295     list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1296   }
1297   return list;
1298 }
1299
1300 GroupScene* Dispatcher::getSceneById(int id) {
1301   foreach(GroupWidget *group, groupList){
1302     if(group->getScene()->getId() == id)
1303       return group->getScene();
1304   }
1305   cout << "search scene by id :" << id << " :: not found..." << endl;
1306   return NULL;
1307 }
1308
1309 GroupItem *Dispatcher::getGroupItemById(int id) {
1310   foreach(GroupWidget *group, groupList) {
1311     GroupScene* scene = group->getScene();
1312     if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1313   }
1314   cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1315   return NULL;
1316 }
1317
1318 BoxItem *Dispatcher::getBoxItemById(int id) {
1319   foreach(GroupWidget *group, groupList) {
1320
1321     GroupScene* scene = group->getScene();
1322     foreach(BoxItem *item, scene->getBoxItems()){
1323       if(item->getId() == id){
1324           return item;
1325       }
1326     }
1327   }
1328   cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1329   return NULL;
1330 }
1331
1332 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1333
1334   foreach(GroupWidget *group, groupList) {
1335
1336     GroupScene* scene = group->getScene();
1337
1338     foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1339       if(item->getId() == id){
1340         return item;
1341       }
1342     }
1343     foreach(BoxItem *block, scene->getBoxItems()){
1344       foreach(InterfaceItem *item, block->getInterfaces()){
1345         if(item->getId() == id){
1346           return item;
1347         }
1348       }
1349     }
1350   }
1351   cout << "search interface by id :" << id << " :: not found..." << endl;
1352   return NULL;
1353 }
1354
1355 void Dispatcher::findGraphModifications(Context context, FunctionalBlock *block) {
1356   static QString fctName = "Dispatcher::findGraphModifications()";
1357 #ifdef DEBUG_FCTNAME
1358   cout << "call to " << qPrintable(fctName) << endl;
1359 #endif
1360
1361   block->computeAdmittanceDelays();
1362   // get the block item that is associated to block
1363   BoxItem* toBlockItem = params->blockToItem.value(block);
1364
1365   /* VERSION 1: just add delays if needed */
1366   QMap<AbstractInterface*,QList<int>* > delays = block->getAdmittanceDelays();
1367   QMapIterator<AbstractInterface*,QList<int>* > iterD(delays);
1368   while (iterD.hasNext()) {
1369     iterD.next();
1370     QList<int>* delay = iterD.value();
1371     if (delay->at(0) > 0) {
1372       // create delay and associate it to the connected input
1373
1374       ConnectedInterface* toIface = AI_TO_CON(iterD.key());
1375       AbstractInputModifier* mod = new DelayInputModifier(toIface, delay->at(0));
1376       cout << "modify input of " << qPrintable(toIface->getName()) << endl;
1377       toIface->setInputModifier(mod);
1378       // repaint
1379       toBlockItem->update();
1380     }
1381   }
1382 }
1383