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

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