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

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