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

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