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

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