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

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