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

Private GIT Repository
patter compat continued
[blast.git] / Dispatcher.cpp
1 #include "Dispatcher.h"
2 #include "Parameters.h"
3 #include "MainWindow.h"
4
5 #include "Graph.h"
6 #include "ReferenceBlock.h"
7 #include "GroupBlock.h"
8 #include "FunctionalBlock.h"
9
10 #include "ConnectedInterface.h"
11 #include "ReferenceInterface.h"
12 #include "GroupInterface.h"
13 #include "FunctionalInterface.h"
14
15 #include "GroupWidget.h"
16 #include "GroupScene.h"
17 #include "GroupItem.h"
18 #include "BoxItem.h"
19 #include "SourceItem.h"
20 #include "InterfaceItem.h"
21 #include "ConnectionItem.h"
22
23 #include "BlockLibraryWidget.h"
24 #include "BlockLibraryTree.h"
25
26 #include "InterfacePropertiesWindow.h"
27
28 int Dispatcher::sceneCounter = 0;
29
30 Dispatcher::Dispatcher(Parameters* _params, MainWindow* _window) {
31   params = _params;
32   mainWindow =_window;
33   params->setDispatcher(this);
34   currentGroup = NULL;
35   topGroup = NULL;    
36 }
37
38 GroupWidget *Dispatcher::loadProject(const QString& filename) {
39
40   QDomElement root;
41   try {
42     root = params->openProjectFile(filename);
43   }
44   catch(Exception err) {
45     return NULL;
46   }
47
48   /*
49   // creating the top widget/scene
50   topGroup = new GroupWidget(NULL,this,params);
51   currentGroup = topGroup;
52   // getting the newly created scene
53   GroupScene *scene = topGroup->getScene();
54
55   params->setTopScene(scene);
56   params->setCurrentScene(scene);
57 */
58   try {   
59     topGroup = params->loadProject(root);
60   }
61   catch(Exception e){
62     cerr << qPrintable(e.getDefaultMessage()) << endl;
63     cerr << "Aborting ..." << endl;
64     // TO DO : deleteting topGroup and all
65     return NULL;
66   }
67
68   groupList.append(topGroup);
69   return topGroup;
70 }
71
72 void Dispatcher::closeCurrentProject() {
73
74   foreach(GroupWidget* win, groupList) {
75     win->deleteLater();
76   }
77   groupList.clear();
78   params->destroyGraph();
79   topGroup = NULL;
80   currentGroup = NULL;
81   sceneCounter = 0;
82 }
83
84 bool Dispatcher::createConnection(InterfaceItem *iface1, InterfaceItem *iface2) {
85     
86   ConnectedInterface* ref1 = iface1->refInter;
87   ConnectedInterface* ref2 = iface2->refInter;
88   ConnectedInterface* asso1 = (ConnectedInterface*)(iface1->refInter->getAssociatedIface());
89   ConnectedInterface* asso2 = (ConnectedInterface*)(iface2->refInter->getAssociatedIface());
90   // connect both interface
91
92   bool ok1 = false;
93   bool ok2 = false;
94
95   // test the ref1->ref2 connection
96   if ((ref1->canConnectTo(ref2)) && (ref2->canConnectFrom(ref1))) {
97     ref1->connectTo(ref2);    
98     ok1 = true;
99   }
100   // if the frist one did not work, test ref2->ref1
101   if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) {  
102     ref2->connectTo(ref1);    
103     ok2 = true;
104   }
105   if ((ok1 == true) || (ok2 == true)) {
106
107     iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2);
108
109     unselectAllItems();
110     params->unsaveModif = true;
111     cout << "created a connection from " << qPrintable(ref1->getName()) << " to " << qPrintable(ref2->getName()) << endl;
112     return true;
113   }
114   return false;
115 }
116
117
118 void Dispatcher::unselectAllItems(int direction){
119
120   GroupScene *scene = params->getCurrentScene();
121
122   foreach(BoxItem* block, scene->getBoxItems()) {
123     block->setSelected(false);
124     block->setCurrentInterface(NULL);
125   }
126   scene->unselecteInterfaces();
127   scene->update();
128 }
129
130 void Dispatcher::setCurrentGroupWidget(GroupWidget *win){
131   win->setFocus();
132   win->changeConnectionMode(-1);
133   currentGroup = win;
134   params->setCurrentScene(win->getScene());
135 }
136
137 void Dispatcher::changeConnectionMode(int mode){
138
139   /*
140   foreach(GroupWidget* win, groupList){
141
142     QToolButton* buttonNewConnection = win->getButtonNewConnection();
143
144     QPalette pal = buttonNewConnection->palette();
145
146     if(mode == -1){
147       if(params->sceneMode != Parameters::EditOnConnection){
148         params->sceneMode = Parameters::EditOnConnection;
149         pal.setColor(QPalette::Button, QColor(Qt::lightGray));
150       } else {
151         params->sceneMode = Parameters::EditNoOperation;
152         pal.setColor(QPalette::Button, QColor("#edeceb"));
153       }
154     }
155     else if(mode == Parameters::EditOnConnection){
156       params->sceneMode = Parameters::EditOnConnection;
157       pal.setColor(QPalette::Button, QColor(Qt::lightGray));
158     }
159     else {
160       params->sceneMode = Parameters::EditNoOperation;
161       pal.setColor(QPalette::Button, QColor("#edeceb"));
162     }
163     unselectAllInterfaces();
164
165     buttonNewConnection->setAutoFillBackground(true);
166     buttonNewConnection->setPalette(pal);
167     buttonNewConnection->update();
168   }
169   */
170 }
171
172 void Dispatcher::renameFunctionalBlock(BoxItem *item){
173   static QString fctName = "Dispatcher::renameFunctionalBlock()";
174 #ifdef DEBUG_FCTNAME
175   cout << "call to " << qPrintable(fctName) << endl;
176 #endif
177     
178   GroupWidget* win = item->getScene()->getGroupWidget();
179   
180   bool ok = false;
181   QString text = "";  
182   while (!ok) {  
183     text = QInputDialog::getText(win, "Rename a functional block",
184                                        "New name:", QLineEdit::Normal,
185                                        item->getRefBlock()->getName(), &ok);
186     if (!ok) return;
187     
188     if (text == item->getRefBlock()->getName()) return;
189     
190     if( (text.isEmpty()) || (text.length() > 30)) {
191       QMessageBox::warning(win,"Error in given name",
192                            "the block name must be shorter than 30 characters, cannot be empty",
193                            QMessageBox::Ok);
194       ok = false;
195     }
196     else {
197       FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
198       if (block != NULL) {
199         QMessageBox::warning(win,"Error in given name",
200                              "the name provided is similar to that of another functional block within the group",
201                              QMessageBox::Ok);
202         ok = false;
203       }
204     }    
205   }  
206
207   item->getRefBlock()->setName(text);
208   item->nameChanged();
209 }
210
211 void Dispatcher::renameGroupBlock(GroupItem *item){
212   static QString fctName = "Dispatcher::renameGroupBlock()";
213 #ifdef DEBUG_FCTNAME
214   cout << "call to " << qPrintable(fctName) << endl;
215 #endif
216   
217   GroupWidget* win = item->getScene()->getGroupWidget();
218   
219   bool ok = false;
220   QString text = "";
221   while (!ok) {  
222     text = QInputDialog::getText(win, "Rename a group",
223                                        "New name:", QLineEdit::Normal,
224                                        item->getRefBlock()->getName(), &ok);
225     if (!ok) return;
226     
227     if (text == item->getRefBlock()->getName()) return;
228     
229     if( (text.isEmpty()) || (text.length() > 30)) {
230       QMessageBox::warning(win,"Error in given name",
231                            "the block name must be shorter than 30 characters, cannot be empty",
232                            QMessageBox::Ok);
233       ok = false;
234     }
235     else {
236       GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
237       if (block != NULL) {
238         QMessageBox::warning(win,"Error in given name",
239                              "the name provided is similar to that of another group",
240                              QMessageBox::Ok);
241         ok = false;
242       }
243     }    
244   }
245   
246   item->getRefBlock()->setName(text);
247   if(item->getScene()->getGroupWidget()->isTopGroup()) {
248     mainWindow->setWindowTitle("blast - "+text);
249   }
250   else {
251     item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
252   }
253   item->nameChanged();
254   mainWindow->getLibrary()->updateComboScene();   
255 }
256
257 void Dispatcher::renameSourceBlock(SourceItem *item){
258   static QString fctName = "Dispatcher::renameSourceBlock()";
259 #ifdef DEBUG_FCTNAME
260   cout << "call to " << qPrintable(fctName) << endl;
261 #endif
262     
263   GroupWidget* win = item->getScene()->getGroupWidget();
264   
265   bool ok = false;
266   QString text = "";  
267   while (!ok) {  
268     text = QInputDialog::getText(win, "Rename a source",
269                                        "New name:", QLineEdit::Normal,
270                                        item->getRefBlock()->getName(), &ok);
271     if (!ok) return;
272     
273     if (text == item->getRefBlock()->getName()) return;
274     
275     if( (text.isEmpty()) || (text.length() > 30)) {
276       QMessageBox::warning(win,"Error in given name",
277                            "the block name must be shorter than 30 characters, cannot be empty",
278                            QMessageBox::Ok);
279       ok = false;
280     }
281     else {
282       FunctionalBlock* block = params->getGraph()->getSourceBlockByName(text);
283       if (block != NULL) {
284         QMessageBox::warning(win,"Error in given name",
285                              "the name provided is similar to that of another source block within the top group",
286                              QMessageBox::Ok);
287         ok = false;
288       }
289     }    
290   }  
291
292   item->getRefBlock()->setName(text);
293   item->nameChanged();
294 }
295
296
297 void Dispatcher::renameInterface(InterfaceItem *item) {
298   static QString fctName = "Dispatcher::renameInterface()";
299 #ifdef DEBUG_FCTNAME
300   cout << "call to " << qPrintable(fctName) << endl;
301 #endif
302
303   GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
304   
305   bool ok = false;
306   QString text = "";
307   while (!ok) {
308     text = QInputDialog::getText(win, "Rename an interface",
309                                        "New name:", QLineEdit::Normal,
310                                        item->refInter->getName(), &ok);
311    
312     if (!ok) return;
313     
314     if (text == item->refInter->getName()) return;
315     
316     if( (text.isEmpty()) || (text.length() > 30)) {
317       QMessageBox::warning(win,"Error in given name",
318                            "the interface name must be shorter than 30 characters, cannot be empty",
319                            QMessageBox::Ok);
320       ok = false;
321     }
322     else {
323       AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
324       if (iface != NULL) {
325         QMessageBox::warning(win,"Error in given name",
326                              "the name provided is similar to that of another interface",
327                              QMessageBox::Ok);
328         ok = false;
329       }
330     }
331   }
332   item->refInter->setName(text);
333   AbstractInterface* assoIface = item->refInter->getAssociatedIface();
334   if (assoIface != NULL) {
335     assoIface->setName(text+"_enb");
336   }
337   item->updateName(text);
338   item->getOwner()->nameChanged();  
339 }
340
341 void Dispatcher::showPatterns(InterfaceItem *item) {
342   static QString fctName = "Dispatcher::showPatterns()";
343 #ifdef DEBUG_FCTNAME
344   cout << "call to " << qPrintable(fctName) << endl;
345 #endif
346   ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
347   foreach(char c, *(iface->getOutputPattern())) {
348     cout << (int)c;
349   }
350   cout << endl;
351 }
352
353 void Dispatcher::duplicateBoxItem(BoxItem *item){
354   static QString fctName = "Dispatcher::duplicateBoxItem()";
355 #ifdef DEBUG_FCTNAME
356   cout << "call to " << qPrintable(fctName) << endl;
357 #endif
358
359   GroupScene *scene = item->getScene();
360   AbstractBlock* block = item->getRefBlock();  
361   AbstractBlock *newBlock;
362
363   // only duplicate functional blocks
364   if(block->isFunctionalBlock()) {
365
366     // adding to the model
367     FunctionalBlock* funBlock = (FunctionalBlock*)block;
368     newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
369     // adding to the view
370     scene->createBoxItem(newBlock);
371
372     params->unsaveModif = true;
373   }
374 }
375
376 void Dispatcher::duplicateSourceItem(SourceItem *item) {
377   static QString fctName = "Dispatcher::duplicateSourceItem()";
378 #ifdef DEBUG_FCTNAME
379   cout << "call to " << qPrintable(fctName) << endl;
380 #endif
381
382   GroupScene *scene = item->getScene();
383   AbstractBlock* block = item->getRefBlock();  
384   AbstractBlock *newBlock;
385
386   // only duplicate functional blocks
387   if(block->isFunctionalBlock()) {
388
389     // adding to the model
390     FunctionalBlock* funBlock = (FunctionalBlock*)block;
391     newBlock = params->getGraph()->duplicateSourceBlock(funBlock);
392     // adding to the view
393     scene->createSourceItem(newBlock);
394
395     params->unsaveModif = true;
396   }
397 }
398
399 void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
400   static QString fctName = "Dispatcher::duplicateInterfaceItem()";
401 #ifdef DEBUG_FCTNAME
402   cout << "call to " << qPrintable(fctName) << endl;
403 #endif
404
405   AbstractInterface *refI = item->refInter;
406   if (! refI->isFunctionalInterface()) return;
407
408   AbstractBlock *refB = refI->getOwner();
409   if(! refB->isFunctionalBlock()) return;
410
411   FunctionalInterface* iface = (FunctionalInterface*)refI;
412   AbstractInterface *cloneIface = iface->clone();
413   if (cloneIface == NULL) {
414     QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
415     return;
416   }
417
418   refB->addInterface(cloneIface);
419
420   InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
421   item->getOwner()->addInterfaceItem(cloneIfaceItem,true);
422   
423   // creating control interface if needed
424   if (refI->getAssociatedIface() != NULL) {
425     QString ctlName = cloneIface->getName()+"_enb";
426     ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,"boolean","1",cloneIface->getDirection(), AbstractInterface::Control, 1);
427     refB->addInterface(ctlIface);
428     if (! ctlIface->setAssociatedIface(cloneIface)) {
429       cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
430     }
431   }
432 }
433
434
435 void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
436   static QString fctName = "Dispatcher::addBlock()";
437 #ifdef DEBUG_FCTNAME
438   cout << "call to " << qPrintable(fctName) << endl;
439 #endif
440   bool newSource = false;
441   GroupScene *scene = getSceneById(idScene);
442   ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
443   // if block has no inputs, propose to add it as a source to top scene
444   if ((scene->isTopScene()) && (ref->isGeneratorBlock())) {
445     int ret = QMessageBox::question(NULL,"Adding a block to top scene","Selected block may be used as a source for the top scene. Do you want to add it as a source ?");
446     if (ret == QMessageBox::Yes) {
447       newSource = true;      
448     }   
449   }
450   if (newSource) {
451     FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref);
452     scene->createSourceItem(newOne);
453   }
454   else {
455     GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
456     FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
457     scene->createBoxItem(newOne);
458   }
459   params->unsaveModif = true;
460 }
461
462
463 GroupWidget *Dispatcher::createTopScene(){
464   static QString fctName = "Dispatcher::createTopScene()";
465 #ifdef DEBUG_FCTNAME
466   cout << "call to " << qPrintable(fctName) << endl;
467 #endif
468
469   // creating the model part of the group
470   Graph* graph = params->createGraph();
471   GroupBlock *refBlock = graph->getTopGroup();
472
473   // creating a fake and not connected interface
474   //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
475
476   // creating the group widget
477   topGroup = new GroupWidget(NULL,this,params);
478   currentGroup = topGroup;
479   // getting the newly created scene
480   GroupScene *scene = topGroup->getScene();
481   scene->setId(sceneCounter++);
482   params->setTopScene(scene);
483   params->setCurrentScene(scene);
484   // creating the view part of the group
485   GroupItem *group = new GroupItem(NULL,refBlock,this,params);
486
487   // adding the fake interface to the top group item
488   //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
489   //group->addInterface(item,true);
490
491   scene->setGroupItem(group);
492
493   groupList.append(topGroup);
494   return topGroup;
495 }
496
497 GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
498   static QString fctName = "Dispatcher::addNewEmptyGroup();";
499 #ifdef DEBUG_FCTNAME
500   cout << "call to " << qPrintable(fctName) << endl;
501 #endif
502
503   // getting the parent block in the graph
504   GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
505   cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
506   GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent);
507   cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
508   // creating the BlockItem in the scene
509   BoxItem* newItem = scene->createBoxItem(groupBlock);
510
511   params->unsaveModif = true;
512
513   GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
514   if (show) child->show();
515   return child;
516
517 }
518
519 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
520   static QString fctName = "Dispatcher::createChildScene()";
521 #ifdef DEBUG_FCTNAME
522   cout << "call to " << qPrintable(fctName) << endl;
523 #endif
524
525   GroupWidget* group = NULL;
526   /* NB: this method may be called during design process or when loading
527      a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
528      cannot be initialized yet. This is why there are 2 cases below
529    */
530
531   if (upperItemOfGroupItem != NULL) {
532     // getting back the goup block already created
533     GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
534     // creating the view part of the group
535     GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
536     // creating the group widget
537     group = new GroupWidget(parentWidget, this, params);
538     // getting the newly created scene
539     GroupScene *scene = group->getScene();
540     scene->setId(sceneCounter++);
541     // affecting group item to the scene
542     scene->setGroupItem(groupItem);
543     groupList.append(group);
544
545     mainWindow->getLibrary()->updateComboScene();
546   }
547   else {
548     GroupItem *groupItem = new GroupItem(this,params);
549     // creating the group widget
550     group = new GroupWidget(parentWidget, this, params);
551     // getting the newly created scene
552     GroupScene *scene = group->getScene();
553     // affecting group item to the scene
554     scene->setGroupItem(groupItem);
555     groupList.append(group);
556   }
557   return group;
558 }
559
560 void Dispatcher::destroyScene(GroupScene *scene) {
561   foreach(GroupScene* s, scene->getChildrenScene()) {
562     destroyScene(s);
563   }
564
565   if (scene->getNbChildScene() == 0) {
566     // remove scene from the parent list, if possible
567     if (scene->getParentScene() != NULL) {
568       scene->getParentScene()->removeChildScene(scene);
569     }
570     // destroy the GroupWidget
571     groupList.removeAll(scene->getGroupWidget());
572     scene->getGroupWidget()->deleteLater();
573   }
574   else {
575     cerr << "Abnormal case when destroying a scene" << endl;
576   }
577 }
578
579 void Dispatcher::showRaiseWindow(BoxItem *item) {
580   static QString fctName = "Dispatcher::showRaiseWindow()";
581 #ifdef DEBUG_FCTNAME
582   cout << "call to " << qPrintable(fctName) << endl;
583 #endif
584
585   cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
586   GroupItem* child = item->getChildGroupItem();
587   if (child == NULL) {
588     cerr << "abnormal case: child group item is null " << endl;
589     return;
590   }
591
592   GroupWidget* win = child->getScene()->getGroupWidget();
593
594   win->showNormal();
595   win->raise();
596   win->activateWindow();
597
598   currentGroup = win;
599   params->setCurrentScene(currentGroup->getScene());
600 }
601
602 void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
603   static QString fctName = "Dispatcher::showRstClkIface()";
604 #ifdef DEBUG_FCTNAME
605   cout << "call to " << qPrintable(fctName) << endl;
606 #endif
607
608   item->setRstClkVisible(!item->isRstClkVisible());
609   
610 }
611
612 void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
613   static QString fctName = "Dispatcher::showWishboneIface()";
614 #ifdef DEBUG_FCTNAME
615   cout << "call to " << qPrintable(fctName) << endl;
616 #endif
617
618   item->setWishboneVisible(!item->isWishboneVisible());  
619 }
620
621 void Dispatcher::addNewFullGroup() {
622   static QString fctName = "Dispatcher::addNewFullGroup()";
623 #ifdef DEBUG_FCTNAME
624   cout << "call to " << qPrintable(fctName) << endl;
625 #endif
626
627
628 #ifdef DEBUG_INCLFUN
629
630   QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
631   QList<AbstractBlock*> listAbstractBlocks;   //abstract blocks in the group
632   QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
633
634   /* What must be done:
635      1 - creating a new GroupBlock
636      2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
637      3 - creating a BlockItem that references the new GroupBlock
638      4 - creating a new GroupWidget
639      5 - creating a new GroupItem added to the scene of the GroupWidget
640
641    */
642
643   /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
644      associated to the GroupItem of the current scene
645    */
646   GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
647   GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
648   /* step 2: moving selected blocks */
649   foreach(BlockItem* blockItem, listBlocks) {
650     parentBlock->removeBlock(blockItem->getRefBlock());
651     newGroupBlock->addBlock(blockItem->getRefBlock());
652   }
653
654   GroupItem *parent = currentGroup->getScene()->getGroupItem();
655   GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
656   BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
657   GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
658
659   //create the new window
660   GroupWidget* win = new GroupWidget(this,params);
661   win->getScene()->setGroupItem(groupItem);
662   win->getScene()->addItem(groupItem);
663   ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
664   params->addWindow(win);
665   win->show();
666
667   //add the new group
668   params->getCurrentScene()->addBlockItem(blockItem);
669   params->getCurrentScene()->addItem(blockItem);
670   ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
671
672   //replace selected blocks in the group
673   foreach(AbstractBoxItem *block, listBlocks){
674     ((GroupItem*)block->getParentItem())->removeBlockItem(block);
675     ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
676     params->getCurrentScene()->removeItem(block);
677     params->getCurrentScene()->removeBlockItem(block);
678
679     groupBlock->addBlock(block->getRefBlock());
680     listAbstractBlocks.append(block->getRefBlock());
681
682     block->setUpperItem(groupItem);
683     groupItem->addBlockItem(block);
684     win->getScene()->addItem(block);
685     win->getScene()->addBlockItem(block);
686   }
687
688   //replace connection between selected blocks in the group
689   foreach(ConnectionItem *conn, connections){
690     if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
691       if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
692         parent->removeConnection(conn);
693         params->getCurrentScene()->removeItem(conn);
694
695         groupItem->addConnection(conn);
696         win->getScene()->addItem(conn);
697       }
698     }
699   }
700
701   //create new interfaces and connections for the new group
702   foreach(AbstractBoxItem *block, listBlocks){
703     foreach(InterfaceItem *inter, block->getInterfaces()){
704       cout << "inter : " << inter->getName().toStdString() << endl;
705       if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
706         cout << "connected from non null" << endl;
707         if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
708
709           AbstractInterface *iface = inter->refInter->clone(0);
710           iface->setName(iface->getName()+"_group");
711           groupBlock->addInterface(iface);
712
713           InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
714           blockItem->addInterface(ifaceItem);
715           blockItem->resetInterfacesPosition();
716
717           InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
718           groupItem->addInterface(ifaceGroupItem);
719           groupItem->resetInterfacesPosition();
720           foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
721             if(conn->getToInterfaceItem() == inter){
722               conn->setToInterfaceItem(ifaceItem);
723               ifaceItem->refInter->setConnectedFrom(NULL);
724               conn->getFromInterfaceItem()->refInter->clearConnectedTo();
725               connect(ifaceItem,conn->getFromInterfaceItem());
726             }
727           }
728           params->setCurrentWindow(win);
729
730           inter->refInter->setConnectedFrom(NULL);
731           ifaceGroupItem->refInter->clearConnectedTo();
732           connect(inter,ifaceGroupItem);
733           params->setCurrentWindow(mainWindow);
734         }
735       }
736
737       if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
738         cout << "connected to non null" << endl;
739         foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
740           if(!listAbstractBlocks.contains(iface->getOwner())){
741
742             AbstractInterface *iface = inter->refInter->clone(0);
743             iface->setName(iface->getName()+"_group");
744             groupBlock->addInterface(iface);
745
746             InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
747             blockItem->addInterface(ifaceItem);
748             blockItem->resetInterfacesPosition();
749
750             foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
751               if(conn->getFromInterfaceItem() == inter){
752                 conn->setFromInterfaceItem(ifaceItem);
753                 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
754                 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
755               }
756             }
757
758             InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
759             groupItem->addInterface(ifaceGroupItem);
760             groupItem->resetInterfacesPosition();
761             inter->refInter->clearConnectedTo();
762             ifaceGroupItem->refInter->setConnectedFrom(NULL);
763             connect(ifaceGroupItem,inter);
764           }
765         }
766       }
767     }
768   }
769
770   //update window
771
772   parent->updateShape();
773   currentGroup->getScene()->updateConnectionItemsShape();
774   currentGroup = win;
775   groupItem->updateShape();
776   win->getScene()->updateConnectionItemsShape();
777   groupItem->update(groupItem->boundingRect());
778
779 #endif
780 }
781
782 void Dispatcher::removeBoxItem(BoxItem *item) {
783   static QString fctName = "Dispatcher::removeBoxItem()";
784 #ifdef DEBUG_FCTNAME
785   cout << "call to " << qPrintable(fctName) << endl;
786 #endif
787
788   /* a BoxItem (group of func) can be removed only if none of its
789      interfaces is connected to a group interface that is itself
790      connected to another one.
791   */
792   bool canRemove = true;
793
794   foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
795     foreach(ConnectionItem* conn, ifaceItem->connections) {
796       InterfaceItem* other = NULL;
797       if (conn->getFromInterfaceItem() == ifaceItem) {
798         other = conn->getToInterfaceItem();
799       }
800       else {
801         other = conn->getFromInterfaceItem();
802       }
803
804       if (other->getOwner()->isGroupItem()) {
805         ConnectedInterface* ref = other->refInter;
806         if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
807           canRemove = false;
808         }
809       }
810     }
811   }
812   if (!canRemove) {
813     QMessageBox::warning(NULL,"Forbidden operation",
814                          "The block has at least one connection to a group interface that is totally connected.",
815                          QMessageBox::Ok);
816     return;
817   }
818
819   QString msg = "";
820   if (item->getRefBlock()->isFunctionalBlock()) {
821     msg = "Removing block ";
822   }
823   else {
824      msg = "Removing group ";
825   }
826   msg += item->getRefBlock()->getName();
827   msg += " and all its connections.\n\nAre you sure ?";
828
829   int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
830   if (ret == QMessageBox::Cancel) {
831     return;
832   }
833   removeAllBlockConnections(item);
834
835   if (item->getRefBlock()->isFunctionalBlock()) {
836     FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
837     GroupBlock* group = AB_TO_GRP(block->getParent());
838     item->getScene()->removeBoxItem(item);
839     params->getGraph()->removeFunctionalBlock(block);
840   }
841   else if (item->getRefBlock()->isGroupBlock()) {
842
843     GroupBlock* group = AB_TO_GRP(item->getRefBlock());
844
845     // remove all child scenes recursively
846     GroupItem* subgroup = item->getChildGroupItem();
847     destroyScene(subgroup->getScene());
848     // remove the BoxItem
849     item->getScene()->removeBoxItem(item);
850     // remove the group from the graph
851     params->getGraph()->removeGroupBlock(group);
852   }
853 }
854
855 void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
856   static QString fctName = "Dispatcher::removeAllBlockConnection()";
857 #ifdef DEBUG_FCTNAME
858   cout << "call to " << qPrintable(fctName) << endl;
859 #endif
860
861   foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
862     foreach(ConnectionItem* conn, ifaceItem->connections) {
863       removeConnection(conn);
864     }
865   }
866 }
867
868 void Dispatcher::removeSourceItem(SourceItem *item) {
869   static QString fctName = "Dispatcher::removeSourceItem()";
870 #ifdef DEBUG_FCTNAME
871   cout << "call to " << qPrintable(fctName) << endl;
872 #endif
873   
874   QString msg = "Removing source ";
875   
876   msg += item->getRefBlock()->getName();
877   msg += " and all its connections.\n\nAre you sure ?";
878
879   int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
880   if (ret == QMessageBox::Cancel) {
881     return;
882   }
883   removeAllBlockConnections(item);
884   
885   FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());  
886   item->getScene()->removeSourceItem(item);
887   params->getGraph()->removeSourceBlock(block);  
888 }
889
890
891 void Dispatcher::removeConnection(ConnectionItem *connItem) {
892   static QString fctName = "Dispatcher::removeConnection()";
893 #ifdef DEBUG_FCTNAME
894   cout << "call to " << qPrintable(fctName) << endl;
895 #endif
896   InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
897   InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
898
899 #ifdef DEBUG
900   cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
901 #endif
902
903   InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not
904   GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem
905
906   ConnectedInterface *fromInter = fromIfaceItem->refInter;
907   ConnectedInterface *toInter = toIfaceItem->refInter;  
908   
909   // test if one of the interface bounded to item is owned by a GroupItem
910   if (fromIfaceItem->getOwner()->isGroupItem()) {
911     groupItem = ABI_TO_GI(fromIfaceItem->getOwner());
912     groupIfaceItem = fromIfaceItem;    
913   }
914   else if (toIfaceItem->getOwner()->isGroupItem()) {
915     groupItem = ABI_TO_GI(toIfaceItem->getOwner());
916     groupIfaceItem = toIfaceItem;    
917   }
918   else {
919     groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
920   }
921
922   // removing the connection from graph
923 #ifdef DEBUG
924   cout << "removing connections from graph ..." ;
925 #endif  
926   fromInter->disconnectTo(toInter);
927   
928 #ifdef DEBUG
929   cout << "done." << endl ;
930 #endif
931
932   // removing the connection from scene
933 #ifdef DEBUG
934   cout << "removing connections from scene ..." ;
935 #endif  
936   groupItem->getScene()->removeConnectionItem(connItem);
937
938 #ifdef DEBUG
939   cout << "done." << endl ;
940 #endif
941   
942   // if one of the interface bounded to connItem is owned by the GroupItem of the scene
943   if (groupIfaceItem != NULL) {
944     
945     // determine if the interface must be removed since it has no more connections.
946     bool groupInterRemove = false;
947     if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true;
948     
949     if (groupInterRemove) {
950       // get the GroupInterface from interface item
951       ConnectedInterface* groupInter = groupIfaceItem->refInter;            
952       // remove interface from GroupItem, and delete it.
953       groupItem->removeInterfaceItem(groupIfaceItem);      
954       // get the parent BoxItem of GroupItem if it exists.
955       BoxItem* parent2Item = groupItem->getParentItem();
956       if (parent2Item != NULL) {
957         InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter);
958         // remove interface intem in parent BoxItem
959         parent2Item->removeInterfaceItem(group2IfaceItem);
960       }
961       // remove GroupInterface in the graph.
962       groupInter->getOwner()->removeInterface(groupInter);
963     }
964   }
965 }
966
967 void Dispatcher::showBlocksLibrary(){
968   cout << "showing block library" << endl;
969   mainWindow->getLibrary()->show();
970   mainWindow->getLibrary()->raise();
971 }
972
973 void Dispatcher::showProperties(InterfaceItem *inter) {
974   new InterfacePropertiesWindow(inter);
975 }
976
977 /* connectInterToGroup() :
978    The only way for a block (functional of group) within a GroupItem to be connected
979    to the latter is to right-click on one of its interfaces and to choose "connect to group".
980    That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
981    interfaces.
982 */
983 void Dispatcher::connectInterToGroup(InterfaceItem *item){
984
985   // getting the GroupBlock and GroupItem that are parent of the block that owns item
986   ConnectedInterface *refInter = item->refInter;
987   cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
988   GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
989   cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
990   GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
991
992   // creating/adding the group interface in the graph model
993   GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());  
994   parentItem->getRefBlock()->addInterface(groupInter);
995   // creating/adding the group control interface in the graph model
996   GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
997   groupCtlInter->setAssociatedIface(groupInter);
998   parentItem->getRefBlock()->addInterface(groupCtlInter);  
999   // creating/adding the group interface in the current scene model, and connection item
1000   InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1001   parentItem->addInterfaceItem(groupIfaceItem,true);
1002
1003   // creating the connection, in graph and with an item
1004   createConnection(item, groupIfaceItem);
1005
1006   // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1007   BoxItem* parent2Item = parentItem->getParentItem();
1008   if(parent2Item != NULL){
1009     InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1010     parent2Item->addInterfaceItem(blockIfaceItem,true);
1011   }
1012
1013
1014   parentItem->getScene()->updateConnectionItemsShape();
1015   unselectAllItems();
1016   params->unsaveModif = true;
1017 }
1018
1019 void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
1020   static QString fctName = "Dispatcher::removeBlockInterface()";
1021 #ifdef DEBUG_FCTNAME
1022   cout << "call to " << qPrintable(fctName) << endl;
1023 #endif
1024
1025   /* first, remove all connections from item
1026      NB:  if there is a connection to a group interface, then this
1027      method should not be called if the group interface is also
1028      connected to another interface. Normally, this is not possible
1029      because such a check is done when creating the contextual menu
1030      that allows to remove an interface.
1031    */
1032   foreach(ConnectionItem* conn, item->connections) {
1033     removeConnection(conn);
1034   }
1035
1036   ConnectedInterface* ref = item->refInter;
1037   item->getOwner()->removeInterfaceItem(item);
1038   FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1039   fun->removeInterface(ref);
1040 }
1041
1042 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
1043   static QString fctName = "Dispatcher::removeGroupInterface()";
1044 #ifdef DEBUG_FCTNAME
1045   cout << "call to " << qPrintable(fctName) << endl;
1046 #endif
1047
1048   /* NB: just remove all connections from/to this item, since when there are no more
1049      ones to a GroupItem, it is automatically deleted.
1050    */
1051   foreach(ConnectionItem* conn, item->connections) {
1052     removeConnection(conn);
1053   }
1054 }
1055
1056 QMap<int, QString> Dispatcher::getAllGroupNames() {
1057
1058   QMap<int, QString> list;
1059   foreach(GroupWidget *group, groupList) {
1060     list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1061   }
1062   return list;
1063 }
1064
1065 GroupScene* Dispatcher::getSceneById(int id) {
1066   foreach(GroupWidget *group, groupList){
1067     if(group->getScene()->getId() == id)
1068       return group->getScene();
1069   }
1070   cout << "search scene by id :" << id << " :: not found..." << endl;
1071   return NULL;
1072 }
1073
1074 GroupItem *Dispatcher::getGroupItemById(int id) {
1075   foreach(GroupWidget *group, groupList) {
1076     GroupScene* scene = group->getScene();
1077     if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1078   }
1079   cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1080   return NULL;
1081 }
1082
1083 BoxItem *Dispatcher::getBoxItemById(int id) {
1084   foreach(GroupWidget *group, groupList) {
1085
1086     GroupScene* scene = group->getScene();
1087     foreach(BoxItem *item, scene->getBoxItems()){
1088       if(item->getId() == id){
1089           return item;
1090       }
1091     }
1092   }
1093   cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1094   return NULL;
1095 }
1096
1097 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1098
1099   foreach(GroupWidget *group, groupList) {
1100
1101     GroupScene* scene = group->getScene();
1102
1103     foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1104       if(item->getId() == id){
1105         return item;
1106       }
1107     }
1108     foreach(BoxItem *block, scene->getBoxItems()){
1109       foreach(InterfaceItem *item, block->getInterfaces()){
1110         if(item->getId() == id){
1111           return item;
1112         }
1113       }
1114     }
1115   }
1116   cout << "search interface by id :" << id << " :: not found..." << endl;
1117   return NULL;
1118 }
1119