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::createConnection(InterfaceItem *iface1, InterfaceItem *iface2) {
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
95 // test the ref1->ref2 connection
96 if ((ref1->canConnectTo(ref2)) && (ref2->canConnectFrom(ref1))) {
97 ref1->connectTo(ref2);
99 ref2->connectFrom(ref1);
100 if ((asso1 != NULL) && (asso2 != NULL)) {
101 asso1->connectTo(asso2);
102 asso2->connectFrom(asso1);
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);
111 ref1->connectFrom(ref2);
112 if ((asso1 != NULL) && (asso2 != NULL)) {
113 asso1->connectFrom(asso2);
114 asso2->connectTo(asso1);
119 if ((ok1 == true) || (ok2 == true)) {
121 iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2);
124 params->unsaveModif = true;
131 void Dispatcher::unselectAllItems(int direction){
133 GroupScene *scene = params->getCurrentScene();
135 foreach(BoxItem* block, scene->getBoxItems()) {
136 block->setSelected(false);
137 block->setCurrentInterface(NULL);
139 scene->unselecteInterfaces();
143 void Dispatcher::setCurrentGroupWidget(GroupWidget *win){
145 win->changeConnectionMode(-1);
147 params->setCurrentScene(win->getScene());
150 void Dispatcher::changeConnectionMode(int mode){
153 foreach(GroupWidget* win, groupList){
155 QToolButton* buttonNewConnection = win->getButtonNewConnection();
157 QPalette pal = buttonNewConnection->palette();
160 if(params->sceneMode != Parameters::EditOnConnection){
161 params->sceneMode = Parameters::EditOnConnection;
162 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
164 params->sceneMode = Parameters::EditNoOperation;
165 pal.setColor(QPalette::Button, QColor("#edeceb"));
168 else if(mode == Parameters::EditOnConnection){
169 params->sceneMode = Parameters::EditOnConnection;
170 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
173 params->sceneMode = Parameters::EditNoOperation;
174 pal.setColor(QPalette::Button, QColor("#edeceb"));
176 unselectAllInterfaces();
178 buttonNewConnection->setAutoFillBackground(true);
179 buttonNewConnection->setPalette(pal);
180 buttonNewConnection->update();
185 void Dispatcher::renameFunctionalBlock(BoxItem *item){
186 static QString fctName = "Dispatcher::renameFunctionalBlock()";
188 cout << "call to " << qPrintable(fctName) << endl;
191 GroupWidget* win = item->getScene()->getGroupWidget();
196 text = QInputDialog::getText(win, "Rename a functional block",
197 "New name:", QLineEdit::Normal,
198 item->getRefBlock()->getName(), &ok);
201 if (text == item->getRefBlock()->getName()) return;
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",
210 FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
212 QMessageBox::warning(win,"Error in given name",
213 "the name provided is similar to that of another functional block within the group",
220 item->getRefBlock()->setName(text);
224 void Dispatcher::renameGroupBlock(GroupItem *item){
225 static QString fctName = "Dispatcher::renameGroupBlock()";
227 cout << "call to " << qPrintable(fctName) << endl;
230 GroupWidget* win = item->getScene()->getGroupWidget();
235 text = QInputDialog::getText(win, "Rename a group",
236 "New name:", QLineEdit::Normal,
237 item->getRefBlock()->getName(), &ok);
240 if (text == item->getRefBlock()->getName()) return;
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",
249 GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
251 QMessageBox::warning(win,"Error in given name",
252 "the name provided is similar to that of another group",
259 item->getRefBlock()->setName(text);
260 if(item->getScene()->getGroupWidget()->isTopGroup()) {
261 mainWindow->setWindowTitle("blast - "+text);
264 item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
267 mainWindow->getLibrary()->updateComboScene();
270 void Dispatcher::renameSourceBlock(SourceItem *item){
271 static QString fctName = "Dispatcher::renameSourceBlock()";
273 cout << "call to " << qPrintable(fctName) << endl;
276 GroupWidget* win = item->getScene()->getGroupWidget();
281 text = QInputDialog::getText(win, "Rename a source",
282 "New name:", QLineEdit::Normal,
283 item->getRefBlock()->getName(), &ok);
286 if (text == item->getRefBlock()->getName()) return;
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",
295 FunctionalBlock* block = params->getGraph()->getSourceBlockByName(text);
297 QMessageBox::warning(win,"Error in given name",
298 "the name provided is similar to that of another source block within the top group",
305 item->getRefBlock()->setName(text);
310 void Dispatcher::renameInterface(InterfaceItem *item) {
311 static QString fctName = "Dispatcher::renameInterface()";
313 cout << "call to " << qPrintable(fctName) << endl;
316 GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
321 text = QInputDialog::getText(win, "Rename an interface",
322 "New name:", QLineEdit::Normal,
323 item->refInter->getName(), &ok);
327 if (text == item->refInter->getName()) return;
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",
336 AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
338 QMessageBox::warning(win,"Error in given name",
339 "the name provided is similar to that of another interface",
345 item->refInter->setName(text);
346 AbstractInterface* assoIface = item->refInter->getAssociatedIface();
347 if (assoIface != NULL) {
348 assoIface->setName(text+"_enb");
350 item->updateName(text);
351 item->getOwner()->nameChanged();
354 void Dispatcher::duplicateBoxItem(BoxItem *item){
355 static QString fctName = "Dispatcher::duplicateBoxItem()";
357 cout << "call to " << qPrintable(fctName) << endl;
360 GroupScene *scene = item->getScene();
361 AbstractBlock* block = item->getRefBlock();
362 AbstractBlock *newBlock;
364 // only duplicate functional blocks
365 if(block->isFunctionalBlock()) {
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);
373 params->unsaveModif = true;
377 void Dispatcher::duplicateSourceItem(SourceItem *item) {
378 static QString fctName = "Dispatcher::duplicateSourceItem()";
380 cout << "call to " << qPrintable(fctName) << endl;
383 GroupScene *scene = item->getScene();
384 AbstractBlock* block = item->getRefBlock();
385 AbstractBlock *newBlock;
387 // only duplicate functional blocks
388 if(block->isFunctionalBlock()) {
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);
396 params->unsaveModif = true;
400 void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
401 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
403 cout << "call to " << qPrintable(fctName) << endl;
406 AbstractInterface *refI = item->refInter;
407 if (! refI->isFunctionalInterface()) return;
409 AbstractBlock *refB = refI->getOwner();
410 if(! refB->isFunctionalBlock()) return;
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);
419 refB->addInterface(cloneIface);
421 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
422 item->getOwner()->addInterface(cloneIfaceItem,true);
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;
436 void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
437 static QString fctName = "Dispatcher::addBlock()";
439 cout << "call to " << qPrintable(fctName) << endl;
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->getDataInputs().isEmpty())) {
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) {
452 FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref);
453 scene->createSourceItem(newOne);
456 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
457 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
458 scene->createBoxItem(newOne);
460 params->unsaveModif = true;
464 GroupWidget *Dispatcher::createTopScene(){
465 static QString fctName = "Dispatcher::createTopScene()";
467 cout << "call to " << qPrintable(fctName) << endl;
470 // creating the model part of the group
471 Graph* graph = params->createGraph();
472 GroupBlock *refBlock = graph->getTopGroup();
474 // creating a fake and not connected interface
475 //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
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);
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);
492 scene->setGroupItem(group);
494 groupList.append(topGroup);
498 GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
499 static QString fctName = "Dispatcher::addNewEmptyGroup();";
501 cout << "call to " << qPrintable(fctName) << endl;
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);
512 params->unsaveModif = true;
514 GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
515 if (show) child->show();
520 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
521 static QString fctName = "Dispatcher::createChildScene()";
523 cout << "call to " << qPrintable(fctName) << endl;
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
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);
546 mainWindow->getLibrary()->updateComboScene();
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);
561 void Dispatcher::destroyScene(GroupScene *scene) {
562 foreach(GroupScene* s, scene->getChildrenScene()) {
566 if (scene->getNbChildScene() == 0) {
567 // remove scene from the parent list, if possible
568 if (scene->getParentScene() != NULL) {
569 scene->getParentScene()->removeChildScene(scene);
571 // destroy the GroupWidget
572 groupList.removeAll(scene->getGroupWidget());
573 scene->getGroupWidget()->deleteLater();
576 cerr << "Abnormal case when destroying a scene" << endl;
580 void Dispatcher::showRaiseWindow(BoxItem *item) {
581 static QString fctName = "Dispatcher::showRaiseWindow()";
583 cout << "call to " << qPrintable(fctName) << endl;
586 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
587 GroupItem* child = item->getChildGroupItem();
589 cerr << "abnormal case: child group item is null " << endl;
593 GroupWidget* win = child->getScene()->getGroupWidget();
597 win->activateWindow();
600 params->setCurrentScene(currentGroup->getScene());
603 void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
604 static QString fctName = "Dispatcher::showRstClkIface()";
606 cout << "call to " << qPrintable(fctName) << endl;
609 item->setRstClkVisible(!item->isRstClkVisible());
613 void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
614 static QString fctName = "Dispatcher::showWishboneIface()";
616 cout << "call to " << qPrintable(fctName) << endl;
619 item->setWishboneVisible(!item->isWishboneVisible());
622 void Dispatcher::addNewFullGroup() {
623 static QString fctName = "Dispatcher::addNewFullGroup()";
625 cout << "call to " << qPrintable(fctName) << endl;
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();
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
644 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
645 associated to the GroupItem of the current scene
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());
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);
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);
669 params->getCurrentScene()->addBlockItem(blockItem);
670 params->getCurrentScene()->addItem(blockItem);
671 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
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);
680 groupBlock->addBlock(block->getRefBlock());
681 listAbstractBlocks.append(block->getRefBlock());
683 block->setUpperItem(groupItem);
684 groupItem->addBlockItem(block);
685 win->getScene()->addItem(block);
686 win->getScene()->addBlockItem(block);
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);
696 groupItem->addConnection(conn);
697 win->getScene()->addItem(conn);
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())){
710 AbstractInterface *iface = inter->refInter->clone(0);
711 iface->setName(iface->getName()+"_group");
712 groupBlock->addInterface(iface);
714 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
715 blockItem->addInterface(ifaceItem);
716 blockItem->resetInterfacesPosition();
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());
729 params->setCurrentWindow(win);
731 inter->refInter->setConnectedFrom(NULL);
732 ifaceGroupItem->refInter->clearConnectedTo();
733 connect(inter,ifaceGroupItem);
734 params->setCurrentWindow(mainWindow);
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())){
743 AbstractInterface *iface = inter->refInter->clone(0);
744 iface->setName(iface->getName()+"_group");
745 groupBlock->addInterface(iface);
747 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
748 blockItem->addInterface(ifaceItem);
749 blockItem->resetInterfacesPosition();
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);
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);
773 parent->updateShape();
774 currentGroup->getScene()->updateConnectionItemsShape();
776 groupItem->updateShape();
777 win->getScene()->updateConnectionItemsShape();
778 groupItem->update(groupItem->boundingRect());
783 void Dispatcher::removeBoxItem(BoxItem *item) {
784 static QString fctName = "Dispatcher::removeBoxItem()";
786 cout << "call to " << qPrintable(fctName) << endl;
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.
793 bool canRemove = true;
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();
802 other = conn->getFromInterfaceItem();
805 if (other->getOwner()->isGroupItem()) {
806 ConnectedInterface* ref = other->refInter;
807 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
814 QMessageBox::warning(NULL,"Forbidden operation",
815 "The block has at least one connection to a group interface that is totally connected.",
821 if (item->getRefBlock()->isFunctionalBlock()) {
822 msg = "Removing block ";
825 msg = "Removing group ";
827 msg += item->getRefBlock()->getName();
828 msg += " and all its connections.\n\nAre you sure ?";
830 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
831 if (ret == QMessageBox::Cancel) {
834 removeAllBlockConnections(item);
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);
842 else if (item->getRefBlock()->isGroupBlock()) {
844 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
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);
856 void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
857 static QString fctName = "Dispatcher::removeAllBlockConnection()";
859 cout << "call to " << qPrintable(fctName) << endl;
862 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
863 foreach(ConnectionItem* conn, ifaceItem->connections) {
864 removeConnection(conn);
869 void Dispatcher::removeSourceItem(SourceItem *item) {
870 static QString fctName = "Dispatcher::removeSourceItem()";
872 cout << "call to " << qPrintable(fctName) << endl;
875 QString msg = "Removing source ";
877 msg += item->getRefBlock()->getName();
878 msg += " and all its connections.\n\nAre you sure ?";
880 int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
881 if (ret == QMessageBox::Cancel) {
884 removeAllBlockConnections(item);
886 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
887 item->getScene()->removeSourceItem(item);
888 params->getGraph()->removeSourceBlock(block);
892 void Dispatcher::removeConnection(ConnectionItem *conn) {
893 static QString fctName = "Dispatcher::removeConnection()";
895 cout << "call to " << qPrintable(fctName) << endl;
897 InterfaceItem* fromIfaceItem = conn->getFromInterfaceItem();
898 InterfaceItem* toIfaceItem = conn->getToInterfaceItem();
901 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
904 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem
905 GroupItem* groupItem = NULL;
907 ConnectedInterface *fromInter = fromIfaceItem->refInter;
908 ConnectedInterface *toInter = toIfaceItem->refInter;
909 // process the special case source->group apart
910 if (fromIfaceItem->getOwner()->isSourceItem()) {
912 fromInter->disconnectTo(toInter);
914 fromIfaceItem->removeConnectionItem(conn);
915 toIfaceItem->removeConnectionItem(conn);
916 groupItem->getScene()->removeConnectionItem(conn);
921 if (fromIfaceItem->getOwner()->isGroupItem()) {
922 groupIfaceItem = fromIfaceItem;
923 groupItem = toIfaceItem->getOwner()->getScene()->getGroupItem();
925 else if (toIfaceItem->getOwner()->isGroupItem()) {
926 groupIfaceItem = toIfaceItem;
927 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
930 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
933 // removing the connection from graph
935 cout << "removing connections from graph ..." ;
937 fromInter->disconnectTo(toInter);
940 cout << "done." << endl ;
943 // removing the connection from scene
945 cout << "removing connections from scene ..." ;
947 fromIfaceItem->removeConnectionItem(conn);
948 toIfaceItem->removeConnectionItem(conn);
949 groupItem->getScene()->removeConnectionItem(conn);
952 cout << "done." << endl ;
955 if (groupIfaceItem != NULL) {
957 bool groupInterRemove = false;
958 if ((groupIfaceItem->nter->isConnectedTo() == false) && (groupInter->isConnectedFrom() == false)) groupInterRemove = true;
960 ConnectedInterface* groupInter = groupIfaceItem->refInter;
961 groupItem->removeInterface(groupIfaceItem);
963 BoxItem* parent2Item = groupItem->getParentItem();
964 if (parent2Item != NULL) {
965 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
966 parent2Item->removeInterface(group2IfaceItem);
968 groupInter->getOwner()->removeInterface(groupInter);
972 void Dispatcher::showBlocksLibrary(){
973 cout << "showing block library" << endl;
974 mainWindow->getLibrary()->show();
975 mainWindow->getLibrary()->raise();
978 void Dispatcher::showProperties(InterfaceItem *inter)
980 new InterfacePropertiesWindow(inter);
983 /* connectInterToGroup() :
984 The only way for a block (functional of group) within a GroupItem to be connected
985 to the latter is to right-click on one of its interfaces and to choose "connect to group".
986 That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
989 void Dispatcher::connectInterToGroup(InterfaceItem *item){
991 // getting the GroupBlock and GroupItem that are parent of the block that owns item
992 ConnectedInterface *refInter = item->refInter;
993 cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
994 GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
995 cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
996 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
998 // creating/adding the group interface in the graph model
999 GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
1000 parentItem->getRefBlock()->addInterface(groupInter);
1001 // creating/adding the group control interface in the graph model
1002 GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
1003 groupCtlInter->setAssociatedIface(groupInter);
1004 parentItem->getRefBlock()->addInterface(groupCtlInter);
1005 // creating/adding the group interface in the current scene model, and connection item
1006 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1007 parentItem->addInterface(groupIfaceItem,true);
1009 // creating the connection, in graph and with an item
1010 createConnection(item, groupIfaceItem);
1012 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1013 BoxItem* parent2Item = parentItem->getParentItem();
1014 if(parent2Item != NULL){
1015 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1016 parent2Item->addInterface(blockIfaceItem,true);
1020 parentItem->getScene()->updateConnectionItemsShape();
1022 params->unsaveModif = true;
1027 void Dispatcher::disconnectInterFromGroup(InterfaceItem *item) {
1028 static QString fctName = "Dispatcher::disconnectInterFromGroup()";
1029 #ifdef DEBUG_FCTNAME
1030 cout << "call to " << qPrintable(fctName) << endl;
1033 // getting the GroupBlock and GroupItem that are parent of the block that owns item
1034 ConnectedInterface *refInter = item->refInter;
1035 ConnectedInterface *groupInter = NULL;
1036 GroupBlock* parentGroup = AB_TO_GRP(refInter->getOwner()->getParent());
1037 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
1039 // removing the connection from graph
1041 cout << "removing connections from graph ..." ;
1044 if (refInter->getDirection() == AbstractInterface::Output) {
1045 groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
1046 refInter->removeConnectedTo(groupInter);
1047 groupInter->clearConnectedFrom();
1049 else if (refInter->getDirection() == AbstractInterface::Input) {
1050 groupInter = refInter->getConnectedFrom();
1051 refInter->clearConnectedFrom();
1052 groupInter->removeConnectedTo(refInter);
1054 else if (refInter->getDirection() == AbstractInterface::InOut) {
1055 groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
1056 refInter->clearConnectedTo();
1057 refInter->clearConnectedFrom();
1058 groupInter->clearConnectedTo();
1059 groupInter->clearConnectedFrom();
1062 cout << "done." << endl ;
1065 if (groupInter == NULL) {
1066 cerr << "abnormal case 1 while removing an interface item of a block, linked to a parent group" << endl;
1070 cout << "getting group interface item, and connection item ..." ;
1074 InterfaceItem* groupIfaceItem = parentItem->searchInterfaceByRef(groupInter);
1075 if (groupIfaceItem == NULL) {
1076 cerr << "abnormal case 2 while removing an interface item of a block, linked to a parent group" << endl;
1078 ConnectionItem* conn = parentItem->getScene()->searchConnectionItem(item,groupIfaceItem);
1080 cerr << "abnormal case 3 while removing an interface item of a block, linked to a parent group" << endl;
1083 cout << "done." << endl ;
1086 // removing the interface group item from the group item, and the connection item
1088 cout << "removing group interface item, and connection item ..." ;
1091 bool groupInterRemove = false;
1092 if ((groupInter->isConnectedTo() == false) && (groupInter->isConnectedFrom() == false)) groupInterRemove = true;
1094 item->removeConnectionItem(conn);
1095 groupIfaceItem->removeConnectionItem(conn);
1096 if (groupInterRemove) {
1097 parentItem->removeInterface(groupIfaceItem); // CAUTION : this deletes the interface item.
1099 parentItem->getScene()->removeConnectionItem(conn);
1101 cout << "done." << endl ;
1104 if (groupInterRemove) {
1105 // removing the interface box item in the parent scene
1107 cout << "removing the inteeface item of box item in parent scene if needed ..." ;
1110 BoxItem* parent2Item = parentItem->getParentItem();
1111 if (parent2Item != NULL) {
1112 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
1113 parent2Item->removeInterface(group2IfaceItem);
1116 cout << "done." << endl ;
1119 // removing the interface group from the group
1121 cout << "removing group interface ..." ;
1123 parentGroup->removeInterface(groupInter);
1125 cout << "done." << endl ;
1130 void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
1131 static QString fctName = "Dispatcher::removeBlockInterface()";
1132 #ifdef DEBUG_FCTNAME
1133 cout << "call to " << qPrintable(fctName) << endl;
1136 /* first, remove all connections from item
1137 NB: if there is a connection to a group interface, then this
1138 method should not be called if the group interface is also
1139 connected to another interface. Normally, this is not possible
1140 because such a check is done when creating the contextual menu
1141 that allows to remove an interface.
1143 foreach(ConnectionItem* conn, item->connections) {
1144 removeConnection(conn);
1147 ConnectedInterface* ref = item->refInter;
1148 item->getOwner()->removeInterface(item);
1149 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1150 fun->removeInterface(ref);
1153 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
1154 static QString fctName = "Dispatcher::removeGroupInterface()";
1155 #ifdef DEBUG_FCTNAME
1156 cout << "call to " << qPrintable(fctName) << endl;
1159 /* NB: there is a single connection between item and another one that is owned
1160 by a BoxItem. Thus, we just have to find it and to call disconnectInterFromGroup();
1162 ConnectionItem* conn = item->connections.at(0);
1163 if (conn->getFromInterfaceItem() == item) {
1164 disconnectInterFromGroup(conn->getToInterfaceItem());
1167 disconnectInterFromGroup(conn->getFromInterfaceItem());
1171 QMap<int, QString> Dispatcher::getAllGroupNames() {
1173 QMap<int, QString> list;
1174 foreach(GroupWidget *group, groupList) {
1175 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1180 GroupScene* Dispatcher::getSceneById(int id) {
1181 foreach(GroupWidget *group, groupList){
1182 if(group->getScene()->getId() == id)
1183 return group->getScene();
1185 cout << "search scene by id :" << id << " :: not found..." << endl;
1189 GroupItem *Dispatcher::getGroupItemById(int id) {
1190 foreach(GroupWidget *group, groupList) {
1191 GroupScene* scene = group->getScene();
1192 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1194 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1198 BoxItem *Dispatcher::getBoxItemById(int id) {
1199 foreach(GroupWidget *group, groupList) {
1201 GroupScene* scene = group->getScene();
1202 foreach(BoxItem *item, scene->getBoxItems()){
1203 if(item->getId() == id){
1208 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1212 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1214 foreach(GroupWidget *group, groupList) {
1216 GroupScene* scene = group->getScene();
1218 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1219 if(item->getId() == id){
1223 foreach(BoxItem *block, scene->getBoxItems()){
1224 foreach(InterfaceItem *item, block->getInterfaces()){
1225 if(item->getId() == id){
1231 cout << "search interface by id :" << id << " :: not found..." << endl;