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

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