1 #include "Dispatcher.h"
2 #include "Parameters.h"
3 #include "MainWindow.h"
6 #include "ReferenceBlock.h"
7 #include "GroupBlock.h"
8 #include "FunctionalBlock.h"
10 #include "ConnectedInterface.h"
11 #include "ReferenceInterface.h"
12 #include "GroupInterface.h"
13 #include "FunctionalInterface.h"
15 #include "GroupWidget.h"
16 #include "GroupScene.h"
17 #include "GroupItem.h"
19 #include "SourceItem.h"
20 #include "InterfaceItem.h"
21 #include "ConnectionItem.h"
23 #include "BlockLibraryWidget.h"
24 #include "BlockLibraryTree.h"
26 #include "InterfacePropertiesWindow.h"
28 int Dispatcher::sceneCounter = 0;
30 Dispatcher::Dispatcher(Parameters* _params, MainWindow* _window) {
33 params->setDispatcher(this);
38 GroupWidget *Dispatcher::loadProject(const QString& filename) {
42 root = params->openProjectFile(filename);
44 catch(Exception err) {
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();
55 params->setTopScene(scene);
56 params->setCurrentScene(scene);
59 topGroup = params->loadProject(root);
62 cerr << qPrintable(e.getDefaultMessage()) << endl;
63 cerr << "Aborting ..." << endl;
64 // TO DO : deleteting topGroup and all
68 groupList.append(topGroup);
72 void Dispatcher::closeCurrentProject() {
74 foreach(GroupWidget* win, groupList) {
78 params->destroyGraph();
84 bool Dispatcher::createConnectionItem(InterfaceItem *iface1, InterfaceItem *iface2) {
86 ConnectedInterface* ref1 = iface1->refInter;
87 ConnectedInterface* ref2 = iface2->refInter;
88 ConnectedInterface* asso1 = iface1->refInter->getAssociatedIface();
89 ConnectedInterface* asso2 = iface2->refInter->getAssociatedIface();
90 // connect both interface
95 // test the ref1->ref2 connection
96 if ((ref1->canConnectTo(ref2)) && (ref2->canConnectFrom(ref1))) {
97 ref1->connectTo(ref2);
98 ref2->connectFrom(ref1);
99 if ((asso1 != NULL) && (asso2 != NULL)) {
100 asso1->connectTo(asso2);
101 asso2->connectFrom(asso1);
105 // if the frist one did not work, test ref2->ref1
106 if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) {
107 ref2->connectTo(ref1);
108 ref1->connectFrom(ref2);
109 if ((asso1 != NULL) && (asso2 != NULL)) {
110 asso1->connectFrom(asso2);
111 asso2->connectTo(asso1);
115 if ((ok1 == true) || (ok2 == true)) {
117 iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2);
120 params->unsaveModif = true;
127 void Dispatcher::unselectAllItems(int direction){
129 GroupScene *scene = params->getCurrentScene();
131 foreach(BoxItem* block, scene->getBoxItems()) {
132 block->setSelected(false);
133 block->setCurrentInterface(NULL);
135 scene->unselecteInterfaces();
139 void Dispatcher::setCurrentGroupWidget(GroupWidget *win){
141 win->changeConnectionMode(-1);
143 params->setCurrentScene(win->getScene());
146 void Dispatcher::changeConnectionMode(int mode){
149 foreach(GroupWidget* win, groupList){
151 QToolButton* buttonNewConnection = win->getButtonNewConnection();
153 QPalette pal = buttonNewConnection->palette();
156 if(params->sceneMode != Parameters::EditOnConnection){
157 params->sceneMode = Parameters::EditOnConnection;
158 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
160 params->sceneMode = Parameters::EditNoOperation;
161 pal.setColor(QPalette::Button, QColor("#edeceb"));
164 else if(mode == Parameters::EditOnConnection){
165 params->sceneMode = Parameters::EditOnConnection;
166 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
169 params->sceneMode = Parameters::EditNoOperation;
170 pal.setColor(QPalette::Button, QColor("#edeceb"));
172 unselectAllInterfaces();
174 buttonNewConnection->setAutoFillBackground(true);
175 buttonNewConnection->setPalette(pal);
176 buttonNewConnection->update();
181 void Dispatcher::renameFunctionalBlock(BoxItem *item){
182 static QString fctName = "Dispatcher::renameFunctionalBlock()";
184 cout << "call to " << qPrintable(fctName) << endl;
187 GroupWidget* win = item->getScene()->getGroupWidget();
192 text = QInputDialog::getText(win, "Rename a functional block",
193 "New name:", QLineEdit::Normal,
194 item->getRefBlock()->getName(), &ok);
197 if (text == item->getRefBlock()->getName()) return;
199 if( (text.isEmpty()) || (text.length() > 30)) {
200 QMessageBox::warning(win,"Error in given name",
201 "the block name must be shorter than 30 characters, cannot be empty",
206 FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
208 QMessageBox::warning(win,"Error in given name",
209 "the name provided is similar to that of another functional block within the group",
216 item->getRefBlock()->setName(text);
220 void Dispatcher::renameGroupBlock(GroupItem *item){
221 static QString fctName = "Dispatcher::renameGroupBlock()";
223 cout << "call to " << qPrintable(fctName) << endl;
226 GroupWidget* win = item->getScene()->getGroupWidget();
231 text = QInputDialog::getText(win, "Rename a group",
232 "New name:", QLineEdit::Normal,
233 item->getRefBlock()->getName(), &ok);
236 if (text == item->getRefBlock()->getName()) return;
238 if( (text.isEmpty()) || (text.length() > 30)) {
239 QMessageBox::warning(win,"Error in given name",
240 "the block name must be shorter than 30 characters, cannot be empty",
245 GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
247 QMessageBox::warning(win,"Error in given name",
248 "the name provided is similar to that of another group",
255 item->getRefBlock()->setName(text);
256 if(item->getScene()->getGroupWidget()->isTopGroup()) {
257 mainWindow->setWindowTitle("blast - "+text);
260 item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
263 mainWindow->getLibrary()->updateComboScene();
266 void Dispatcher::renameSourceBlock(SourceItem *item){
267 static QString fctName = "Dispatcher::renameSourceBlock()";
269 cout << "call to " << qPrintable(fctName) << endl;
272 GroupWidget* win = item->getScene()->getGroupWidget();
277 text = QInputDialog::getText(win, "Rename a source",
278 "New name:", QLineEdit::Normal,
279 item->getRefBlock()->getName(), &ok);
282 if (text == item->getRefBlock()->getName()) return;
284 if( (text.isEmpty()) || (text.length() > 30)) {
285 QMessageBox::warning(win,"Error in given name",
286 "the block name must be shorter than 30 characters, cannot be empty",
291 FunctionalBlock* block = params->getGraph()->getSourceBlockByName(text);
293 QMessageBox::warning(win,"Error in given name",
294 "the name provided is similar to that of another source block within the top group",
301 item->getRefBlock()->setName(text);
306 void Dispatcher::renameInterface(InterfaceItem *item) {
307 static QString fctName = "Dispatcher::renameInterface()";
309 cout << "call to " << qPrintable(fctName) << endl;
312 GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
317 text = QInputDialog::getText(win, "Rename an interface",
318 "New name:", QLineEdit::Normal,
319 item->refInter->getName(), &ok);
323 if (text == item->refInter->getName()) return;
325 if( (text.isEmpty()) || (text.length() > 30)) {
326 QMessageBox::warning(win,"Error in given name",
327 "the interface name must be shorter than 30 characters, cannot be empty",
332 AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
334 QMessageBox::warning(win,"Error in given name",
335 "the name provided is similar to that of another interface",
341 item->refInter->setName(text);
342 AbstractInterface* assoIface = item->refInter->getAssociatedIface();
343 if (assoIface != NULL) {
344 assoIface->setName(text+"_enb");
346 item->updateName(text);
347 item->getOwner()->nameChanged();
350 void Dispatcher::duplicateBoxItem(BoxItem *item){
351 static QString fctName = "Dispatcher::duplicateBoxItem()";
353 cout << "call to " << qPrintable(fctName) << endl;
356 GroupScene *scene = item->getScene();
357 AbstractBlock* block = item->getRefBlock();
358 AbstractBlock *newBlock;
360 // only duplicate functional blocks
361 if(block->isFunctionalBlock()) {
363 // adding to the model
364 FunctionalBlock* funBlock = (FunctionalBlock*)block;
365 newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
366 // adding to the view
367 scene->createBoxItem(newBlock);
369 params->unsaveModif = true;
373 void Dispatcher::duplicateSourceItem(SourceItem *item) {
374 static QString fctName = "Dispatcher::duplicateSourceItem()";
376 cout << "call to " << qPrintable(fctName) << endl;
379 GroupScene *scene = item->getScene();
380 AbstractBlock* block = item->getRefBlock();
381 AbstractBlock *newBlock;
383 // only duplicate functional blocks
384 if(block->isFunctionalBlock()) {
386 // adding to the model
387 FunctionalBlock* funBlock = (FunctionalBlock*)block;
388 newBlock = params->getGraph()->duplicateSourceBlock(funBlock);
389 // adding to the view
390 scene->createSourceItem(newBlock);
392 params->unsaveModif = true;
396 void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
397 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
399 cout << "call to " << qPrintable(fctName) << endl;
402 AbstractInterface *refI = item->refInter;
403 if (! refI->isFunctionalInterface()) return;
405 AbstractBlock *refB = refI->getOwner();
406 if(! refB->isFunctionalBlock()) return;
408 FunctionalInterface* iface = (FunctionalInterface*)refI;
409 AbstractInterface *cloneIface = iface->clone();
410 if (cloneIface == NULL) {
411 QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
415 refB->addInterface(cloneIface);
417 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
418 item->getOwner()->addInterface(cloneIfaceItem,true);
420 // creating control interface if needed
421 if (refI->getAssociatedIface() != NULL) {
422 QString ctlName = cloneIface->getName()+"_enb";
423 ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,"boolean","1",cloneIface->getDirection(), AbstractInterface::Control, 1);
424 refB->addInterface(ctlIface);
425 if (! ctlIface->setAssociatedIface(cloneIface)) {
426 cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
432 void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
433 static QString fctName = "Dispatcher::addBlock()";
435 cout << "call to " << qPrintable(fctName) << endl;
437 bool newSource = false;
438 GroupScene *scene = getSceneById(idScene);
439 ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
440 // if block has no inputs, propose to add it as a source to top scene
441 if ((scene->isTopScene()) && (ref->getDataInputs().isEmpty())) {
442 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 ?");
443 if (ret == QMessageBox::Yes) {
448 FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref);
449 scene->createSourceItem(newOne);
452 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
453 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
454 scene->createBoxItem(newOne);
456 params->unsaveModif = true;
460 GroupWidget *Dispatcher::createTopScene(){
461 static QString fctName = "Dispatcher::createTopScene()";
463 cout << "call to " << qPrintable(fctName) << endl;
466 // creating the model part of the group
467 Graph* graph = params->createGraph();
468 GroupBlock *refBlock = graph->getTopGroup();
470 // creating a fake and not connected interface
471 //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
473 // creating the group widget
474 topGroup = new GroupWidget(NULL,this,params);
475 currentGroup = topGroup;
476 // getting the newly created scene
477 GroupScene *scene = topGroup->getScene();
478 scene->setId(sceneCounter++);
479 params->setTopScene(scene);
480 params->setCurrentScene(scene);
481 // creating the view part of the group
482 GroupItem *group = new GroupItem(NULL,refBlock,this,params);
484 // adding the fake interface to the top group item
485 //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
486 //group->addInterface(item,true);
488 scene->setGroupItem(group);
490 groupList.append(topGroup);
494 GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
495 static QString fctName = "Dispatcher::addNewEmptyGroup();";
497 cout << "call to " << qPrintable(fctName) << endl;
500 // getting the parent block in the graph
501 GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
502 cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
503 GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent);
504 cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
505 // creating the BlockItem in the scene
506 BoxItem* newItem = scene->createBoxItem(groupBlock);
508 params->unsaveModif = true;
510 GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
511 if (show) child->show();
516 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
517 static QString fctName = "Dispatcher::createChildScene()";
519 cout << "call to " << qPrintable(fctName) << endl;
522 GroupWidget* group = NULL;
523 /* NB: this method may be called during design process or when loading
524 a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
525 cannot be initialized yet. This is why there are 2 cases below
528 if (upperItemOfGroupItem != NULL) {
529 // getting back the goup block already created
530 GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
531 // creating the view part of the group
532 GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
533 // creating the group widget
534 group = new GroupWidget(parentWidget, this, params);
535 // getting the newly created scene
536 GroupScene *scene = group->getScene();
537 scene->setId(sceneCounter++);
538 // affecting group item to the scene
539 scene->setGroupItem(groupItem);
540 groupList.append(group);
542 mainWindow->getLibrary()->updateComboScene();
545 GroupItem *groupItem = new GroupItem(this,params);
546 // creating the group widget
547 group = new GroupWidget(parentWidget, this, params);
548 // getting the newly created scene
549 GroupScene *scene = group->getScene();
550 // affecting group item to the scene
551 scene->setGroupItem(groupItem);
552 groupList.append(group);
557 void Dispatcher::destroyScene(GroupScene *scene) {
558 foreach(GroupScene* s, scene->getChildrenScene()) {
562 if (scene->getNbChildScene() == 0) {
563 // remove scene from the parent list, if possible
564 if (scene->getParentScene() != NULL) {
565 scene->getParentScene()->removeChildScene(scene);
567 // destroy the GroupWidget
568 groupList.removeAll(scene->getGroupWidget());
569 scene->getGroupWidget()->deleteLater();
572 cerr << "Abnormal case when destroying a scene" << endl;
576 void Dispatcher::showRaiseWindow(BoxItem *item) {
577 static QString fctName = "Dispatcher::showRaiseWindow()";
579 cout << "call to " << qPrintable(fctName) << endl;
582 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
583 GroupItem* child = item->getChildGroupItem();
585 cerr << "abnormal case: child group item is null " << endl;
589 GroupWidget* win = child->getScene()->getGroupWidget();
593 win->activateWindow();
596 params->setCurrentScene(currentGroup->getScene());
599 void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
600 static QString fctName = "Dispatcher::showRstClkIface()";
602 cout << "call to " << qPrintable(fctName) << endl;
605 item->setRstClkVisible(!item->isRstClkVisible());
609 void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
610 static QString fctName = "Dispatcher::showWishboneIface()";
612 cout << "call to " << qPrintable(fctName) << endl;
615 item->setWishboneVisible(!item->isWishboneVisible());
618 void Dispatcher::addNewFullGroup() {
619 static QString fctName = "Dispatcher::addNewFullGroup()";
621 cout << "call to " << qPrintable(fctName) << endl;
627 QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
628 QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
629 QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
631 /* What must be done:
632 1 - creating a new GroupBlock
633 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
634 3 - creating a BlockItem that references the new GroupBlock
635 4 - creating a new GroupWidget
636 5 - creating a new GroupItem added to the scene of the GroupWidget
640 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
641 associated to the GroupItem of the current scene
643 GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
644 GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
645 /* step 2: moving selected blocks */
646 foreach(BlockItem* blockItem, listBlocks) {
647 parentBlock->removeBlock(blockItem->getRefBlock());
648 newGroupBlock->addBlock(blockItem->getRefBlock());
651 GroupItem *parent = currentGroup->getScene()->getGroupItem();
652 GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
653 BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
654 GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
656 //create the new window
657 GroupWidget* win = new GroupWidget(this,params);
658 win->getScene()->setGroupItem(groupItem);
659 win->getScene()->addItem(groupItem);
660 ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
661 params->addWindow(win);
665 params->getCurrentScene()->addBlockItem(blockItem);
666 params->getCurrentScene()->addItem(blockItem);
667 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
669 //replace selected blocks in the group
670 foreach(AbstractBoxItem *block, listBlocks){
671 ((GroupItem*)block->getParentItem())->removeBlockItem(block);
672 ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
673 params->getCurrentScene()->removeItem(block);
674 params->getCurrentScene()->removeBlockItem(block);
676 groupBlock->addBlock(block->getRefBlock());
677 listAbstractBlocks.append(block->getRefBlock());
679 block->setUpperItem(groupItem);
680 groupItem->addBlockItem(block);
681 win->getScene()->addItem(block);
682 win->getScene()->addBlockItem(block);
685 //replace connection between selected blocks in the group
686 foreach(ConnectionItem *conn, connections){
687 if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
688 if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
689 parent->removeConnection(conn);
690 params->getCurrentScene()->removeItem(conn);
692 groupItem->addConnection(conn);
693 win->getScene()->addItem(conn);
698 //create new interfaces and connections for the new group
699 foreach(AbstractBoxItem *block, listBlocks){
700 foreach(InterfaceItem *inter, block->getInterfaces()){
701 cout << "inter : " << inter->getName().toStdString() << endl;
702 if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
703 cout << "connected from non null" << endl;
704 if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
706 AbstractInterface *iface = inter->refInter->clone(0);
707 iface->setName(iface->getName()+"_group");
708 groupBlock->addInterface(iface);
710 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
711 blockItem->addInterface(ifaceItem);
712 blockItem->resetInterfacesPosition();
714 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
715 groupItem->addInterface(ifaceGroupItem);
716 groupItem->resetInterfacesPosition();
717 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
718 if(conn->getToInterfaceItem() == inter){
719 conn->setToInterfaceItem(ifaceItem);
720 ifaceItem->refInter->setConnectedFrom(NULL);
721 conn->getFromInterfaceItem()->refInter->clearConnectedTo();
722 connect(ifaceItem,conn->getFromInterfaceItem());
725 params->setCurrentWindow(win);
727 inter->refInter->setConnectedFrom(NULL);
728 ifaceGroupItem->refInter->clearConnectedTo();
729 connect(inter,ifaceGroupItem);
730 params->setCurrentWindow(mainWindow);
734 if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
735 cout << "connected to non null" << endl;
736 foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
737 if(!listAbstractBlocks.contains(iface->getOwner())){
739 AbstractInterface *iface = inter->refInter->clone(0);
740 iface->setName(iface->getName()+"_group");
741 groupBlock->addInterface(iface);
743 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
744 blockItem->addInterface(ifaceItem);
745 blockItem->resetInterfacesPosition();
747 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
748 if(conn->getFromInterfaceItem() == inter){
749 conn->setFromInterfaceItem(ifaceItem);
750 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
751 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
755 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
756 groupItem->addInterface(ifaceGroupItem);
757 groupItem->resetInterfacesPosition();
758 inter->refInter->clearConnectedTo();
759 ifaceGroupItem->refInter->setConnectedFrom(NULL);
760 connect(ifaceGroupItem,inter);
769 parent->updateShape();
770 currentGroup->getScene()->updateConnectionItemsShape();
772 groupItem->updateShape();
773 win->getScene()->updateConnectionItemsShape();
774 groupItem->update(groupItem->boundingRect());
779 void Dispatcher::removeBoxItem(BoxItem *item) {
780 static QString fctName = "Dispatcher::removeBoxItem()";
782 cout << "call to " << qPrintable(fctName) << endl;
785 /* a BoxItem (group of func) can be removed only if none of its
786 interfaces is connected to a group interface that is itself
787 connected to another one.
789 bool canRemove = true;
791 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
792 foreach(ConnectionItem* conn, ifaceItem->connections) {
793 InterfaceItem* other = NULL;
794 if (conn->getFromInterfaceItem() == ifaceItem) {
795 other = conn->getToInterfaceItem();
798 other = conn->getFromInterfaceItem();
801 if (other->getOwner()->isGroupItem()) {
802 ConnectedInterface* ref = other->refInter;
803 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
810 QMessageBox::warning(NULL,"Forbidden operation",
811 "The block has at least one connection to a group interface that is totally connected.",
817 if (item->getRefBlock()->isFunctionalBlock()) {
818 msg = "Removing block ";
821 msg = "Removing group ";
823 msg += item->getRefBlock()->getName();
824 msg += " and all its connections.\n\nAre you sure ?";
826 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
827 if (ret == QMessageBox::Cancel) {
830 removeAllBlockConnections(item);
832 if (item->getRefBlock()->isFunctionalBlock()) {
833 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
834 GroupBlock* group = AB_TO_GRP(block->getParent());
835 item->getScene()->removeBoxItem(item);
836 params->getGraph()->removeFunctionalBlock(block);
838 else if (item->getRefBlock()->isGroupBlock()) {
840 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
842 // remove all child scenes recursively
843 GroupItem* subgroup = item->getChildGroupItem();
844 destroyScene(subgroup->getScene());
845 // remove the BoxItem
846 item->getScene()->removeBoxItem(item);
847 // remove the group from the graph
848 params->getGraph()->removeGroupBlock(group);
852 void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
853 static QString fctName = "Dispatcher::removeAllBlockConnection()";
855 cout << "call to " << qPrintable(fctName) << endl;
858 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
859 foreach(ConnectionItem* conn, ifaceItem->connections) {
860 removeConnection(conn);
865 void Dispatcher::removeSourceItem(SourceItem *item) {
866 static QString fctName = "Dispatcher::removeSourceItem()";
868 cout << "call to " << qPrintable(fctName) << endl;
871 QString msg = "Removing source ";
873 msg += item->getRefBlock()->getName();
874 msg += " and all its connections.\n\nAre you sure ?";
876 int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
877 if (ret == QMessageBox::Cancel) {
880 removeAllBlockConnections(item);
882 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
883 item->getScene()->removeSourceItem(item);
884 params->getGraph()->removeSourceBlock(block);
888 void Dispatcher::removeConnection(ConnectionItem *conn) {
889 static QString fctName = "Dispatcher::removeConnection()";
891 cout << "call to " << qPrintable(fctName) << endl;
893 InterfaceItem* fromIfaceItem = conn->getFromInterfaceItem();
894 InterfaceItem* toIfaceItem = conn->getToInterfaceItem();
897 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
900 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem
901 GroupItem* groupItem = NULL;
903 ConnectedInterface *fromInter = fromIfaceItem->refInter;
904 ConnectedInterface *toInter = toIfaceItem->refInter;
905 // process the special case source->group apart
906 if (fromIfaceItem->getOwner()->isSourceItem()) {
908 fromInter->removeConnectedTo(toInter);
909 toInter->clearConnectedFrom();
911 fromIfaceItem->removeConnectionItem(conn);
912 toIfaceItem->removeConnectionItem(conn);
913 groupItem->getScene()->removeConnectionItem(conn);
918 if (fromIfaceItem->getOwner()->isGroupItem()) {
919 groupIfaceItem = fromIfaceItem;
920 groupItem = toIfaceItem->getOwner()->getScene()->getGroupItem();
922 else if (toIfaceItem->getOwner()->isGroupItem()) {
923 groupIfaceItem = toIfaceItem;
924 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
927 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
930 // removing the connection from graph
932 cout << "removing connections from graph ..." ;
934 if (fromInter->getDirection() == AbstractInterface::InOut) {
935 fromInter->clearConnectedTo();
936 fromInter->clearConnectedFrom();
937 toInter->clearConnectedTo();
938 toInter->clearConnectedFrom();
941 fromInter->removeConnectedTo(toInter);
942 toInter->clearConnectedFrom();
945 cout << "done." << endl ;
948 // removing the connection from scene
950 cout << "removing connections from scene ..." ;
952 fromIfaceItem->removeConnectionItem(conn);
953 toIfaceItem->removeConnectionItem(conn);
954 groupItem->getScene()->removeConnectionItem(conn);
957 cout << "done." << endl ;
960 if (groupIfaceItem != NULL) {
961 ConnectedInterface* groupInter = groupIfaceItem->refInter;
962 groupItem->removeInterface(groupIfaceItem);
964 BoxItem* parent2Item = groupItem->getParentItem();
965 if (parent2Item != NULL) {
966 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
967 parent2Item->removeInterface(group2IfaceItem);
969 groupInter->getOwner()->removeInterface(groupInter);
973 void Dispatcher::showBlocksLibrary(){
974 cout << "showing block library" << endl;
975 mainWindow->getLibrary()->show();
976 mainWindow->getLibrary()->raise();
979 void Dispatcher::showProperties(InterfaceItem *inter)
981 new InterfacePropertiesWindow(inter);
984 /* connectInterToGroup() :
985 The only way for a block (functional of group) within a GroupItem to be connected
986 to the latter is to right-click on one of its interfaces and to choose "connect to group".
987 That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
990 void Dispatcher::connectInterToGroup(InterfaceItem *item){
992 // getting the GroupBlock and GroupItem that are parent of the block that owns item
993 ConnectedInterface *refInter = item->refInter;
994 cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
995 GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
996 cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
997 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
999 // creating/adding the group interface in the graph model
1000 GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
1001 parentItem->getRefBlock()->addInterface(groupInter);
1002 // creating/adding the group control interface in the graph model
1003 GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
1004 groupCtlInter->setAssociatedIface(groupInter);
1005 parentItem->getRefBlock()->addInterface(groupCtlInter);
1007 // connect both interface
1009 if (refInter->getDirection() == AbstractInterface::Output) {
1010 ok = refInter->connectTo(groupInter);
1011 ok = ok & groupInter->connectFrom(refInter);
1013 else if (refInter->getDirection() == AbstractInterface::Input) {
1014 ok = groupInter->connectTo(refInter);
1015 ok = ok & refInter->connectFrom(groupInter);
1017 else if (refInter->getDirection() == AbstractInterface::InOut) {
1018 ok = refInter->connectTo(groupInter);
1019 ok = ok & groupInter->connectFrom(refInter);
1020 ok = ok & groupInter->connectTo(refInter);
1021 ok = ok & refInter->connectFrom(groupInter);
1024 cerr << "abnormal case while connecting a block iface to its parent group" << endl;
1026 // creating/adding the group interface in the current scene model, and connection item
1027 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1028 parentItem->addInterface(groupIfaceItem,true);
1030 parentItem->getScene()->createConnectionItem(item, groupIfaceItem);
1032 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1033 BoxItem* parent2Item = parentItem->getParentItem();
1034 if(parent2Item != NULL){
1035 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1036 parent2Item->addInterface(blockIfaceItem,true);
1040 parentItem->getScene()->updateConnectionItemsShape();
1042 params->unsaveModif = true;
1047 void Dispatcher::disconnectInterFromGroup(InterfaceItem *item) {
1048 static QString fctName = "Dispatcher::disconnectInterFromGroup()";
1049 #ifdef DEBUG_FCTNAME
1050 cout << "call to " << qPrintable(fctName) << endl;
1053 // getting the GroupBlock and GroupItem that are parent of the block that owns item
1054 ConnectedInterface *refInter = item->refInter;
1055 ConnectedInterface *groupInter = NULL;
1056 GroupBlock* parentGroup = AB_TO_GRP(refInter->getOwner()->getParent());
1057 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
1059 // removing the connection from graph
1061 cout << "removing connections from graph ..." ;
1064 if (refInter->getDirection() == AbstractInterface::Output) {
1065 groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
1066 refInter->removeConnectedTo(groupInter);
1067 groupInter->clearConnectedFrom();
1069 else if (refInter->getDirection() == AbstractInterface::Input) {
1070 groupInter = refInter->getConnectedFrom();
1071 refInter->clearConnectedFrom();
1072 groupInter->removeConnectedTo(refInter);
1074 else if (refInter->getDirection() == AbstractInterface::InOut) {
1075 groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
1076 refInter->clearConnectedTo();
1077 refInter->clearConnectedFrom();
1078 groupInter->clearConnectedTo();
1079 groupInter->clearConnectedFrom();
1082 cout << "done." << endl ;
1085 if (groupInter == NULL) {
1086 cerr << "abnormal case 1 while removing an interface item of a block, linked to a parent group" << endl;
1090 cout << "getting group interface item, and connection item ..." ;
1094 InterfaceItem* groupIfaceItem = parentItem->searchInterfaceByRef(groupInter);
1095 if (groupIfaceItem == NULL) {
1096 cerr << "abnormal case 2 while removing an interface item of a block, linked to a parent group" << endl;
1098 ConnectionItem* conn = parentItem->getScene()->searchConnectionItem(item,groupIfaceItem);
1100 cerr << "abnormal case 3 while removing an interface item of a block, linked to a parent group" << endl;
1103 cout << "done." << endl ;
1106 // removing the interface group item from the group item, and the connection item
1108 cout << "removing group interface item, and connection item ..." ;
1111 bool groupInterRemove = false;
1112 if ((groupInter->isConnectedTo() == false) && (groupInter->isConnectedFrom() == false)) groupInterRemove = true;
1114 item->removeConnectionItem(conn);
1115 groupIfaceItem->removeConnectionItem(conn);
1116 if (groupInterRemove) {
1117 parentItem->removeInterface(groupIfaceItem); // CAUTION : this deletes the interface item.
1119 parentItem->getScene()->removeConnectionItem(conn);
1121 cout << "done." << endl ;
1124 if (groupInterRemove) {
1125 // removing the interface box item in the parent scene
1127 cout << "removing the inteeface item of box item in parent scene if needed ..." ;
1130 BoxItem* parent2Item = parentItem->getParentItem();
1131 if (parent2Item != NULL) {
1132 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
1133 parent2Item->removeInterface(group2IfaceItem);
1136 cout << "done." << endl ;
1139 // removing the interface group from the group
1141 cout << "removing group interface ..." ;
1143 parentGroup->removeInterface(groupInter);
1145 cout << "done." << endl ;
1150 void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
1151 static QString fctName = "Dispatcher::removeBlockInterface()";
1152 #ifdef DEBUG_FCTNAME
1153 cout << "call to " << qPrintable(fctName) << endl;
1156 /* first, remove all connections from item
1157 NB: if there is a connection to a group interface, then this
1158 method should not be called if the group interface is also
1159 connected to another interface. Normally, this is not possible
1160 because such a check is done when creating the contextual menu
1161 that allows to remove an interface.
1163 foreach(ConnectionItem* conn, item->connections) {
1164 removeConnection(conn);
1167 ConnectedInterface* ref = item->refInter;
1168 item->getOwner()->removeInterface(item);
1169 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1170 fun->removeInterface(ref);
1173 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
1174 static QString fctName = "Dispatcher::removeGroupInterface()";
1175 #ifdef DEBUG_FCTNAME
1176 cout << "call to " << qPrintable(fctName) << endl;
1179 /* NB: there is a single connection between item and another one that is owned
1180 by a BoxItem. Thus, we just have to find it and to call disconnectInterFromGroup();
1182 ConnectionItem* conn = item->connections.at(0);
1183 if (conn->getFromInterfaceItem() == item) {
1184 disconnectInterFromGroup(conn->getToInterfaceItem());
1187 disconnectInterFromGroup(conn->getFromInterfaceItem());
1191 QMap<int, QString> Dispatcher::getAllGroupNames() {
1193 QMap<int, QString> list;
1194 foreach(GroupWidget *group, groupList) {
1195 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1200 GroupScene* Dispatcher::getSceneById(int id) {
1201 foreach(GroupWidget *group, groupList){
1202 if(group->getScene()->getId() == id)
1203 return group->getScene();
1205 cout << "search scene by id :" << id << " :: not found..." << endl;
1209 GroupItem *Dispatcher::getGroupItemById(int id) {
1210 foreach(GroupWidget *group, groupList) {
1211 GroupScene* scene = group->getScene();
1212 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1214 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1218 BoxItem *Dispatcher::getBoxItemById(int id) {
1219 foreach(GroupWidget *group, groupList) {
1221 GroupScene* scene = group->getScene();
1222 foreach(BoxItem *item, scene->getBoxItems()){
1223 if(item->getId() == id){
1228 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1232 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1234 foreach(GroupWidget *group, groupList) {
1236 GroupScene* scene = group->getScene();
1238 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1239 if(item->getId() == id){
1243 foreach(BoxItem *block, scene->getBoxItems()){
1244 foreach(InterfaceItem *item, block->getInterfaces()){
1245 if(item->getId() == id){
1251 cout << "search interface by id :" << id << " :: not found..." << endl;