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);
100 // if the frist one did not work, test ref2->ref1
101 if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) {
102 ref2->connectTo(ref1);
105 if ((ok1 == true) || (ok2 == true)) {
107 iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2);
110 params->unsaveModif = true;
111 cout << "created a connection from " << qPrintable(ref1->getName()) << " to " << qPrintable(ref2->getName()) << endl;
118 void Dispatcher::unselectAllItems(int direction){
120 GroupScene *scene = params->getCurrentScene();
122 foreach(BoxItem* block, scene->getBoxItems()) {
123 block->setSelected(false);
124 block->setCurrentInterface(NULL);
126 scene->unselecteInterfaces();
130 void Dispatcher::setCurrentGroupWidget(GroupWidget *win){
132 win->changeConnectionMode(-1);
134 params->setCurrentScene(win->getScene());
137 void Dispatcher::changeConnectionMode(int mode){
140 foreach(GroupWidget* win, groupList){
142 QToolButton* buttonNewConnection = win->getButtonNewConnection();
144 QPalette pal = buttonNewConnection->palette();
147 if(params->sceneMode != Parameters::EditOnConnection){
148 params->sceneMode = Parameters::EditOnConnection;
149 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
151 params->sceneMode = Parameters::EditNoOperation;
152 pal.setColor(QPalette::Button, QColor("#edeceb"));
155 else if(mode == Parameters::EditOnConnection){
156 params->sceneMode = Parameters::EditOnConnection;
157 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
160 params->sceneMode = Parameters::EditNoOperation;
161 pal.setColor(QPalette::Button, QColor("#edeceb"));
163 unselectAllInterfaces();
165 buttonNewConnection->setAutoFillBackground(true);
166 buttonNewConnection->setPalette(pal);
167 buttonNewConnection->update();
172 void Dispatcher::renameFunctionalBlock(BoxItem *item){
173 static QString fctName = "Dispatcher::renameFunctionalBlock()";
175 cout << "call to " << qPrintable(fctName) << endl;
178 GroupWidget* win = item->getScene()->getGroupWidget();
183 text = QInputDialog::getText(win, "Rename a functional block",
184 "New name:", QLineEdit::Normal,
185 item->getRefBlock()->getName(), &ok);
188 if (text == item->getRefBlock()->getName()) return;
190 if( (text.isEmpty()) || (text.length() > 30)) {
191 QMessageBox::warning(win,"Error in given name",
192 "the block name must be shorter than 30 characters, cannot be empty",
197 FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
199 QMessageBox::warning(win,"Error in given name",
200 "the name provided is similar to that of another functional block within the group",
207 item->getRefBlock()->setName(text);
211 void Dispatcher::renameGroupBlock(GroupItem *item){
212 static QString fctName = "Dispatcher::renameGroupBlock()";
214 cout << "call to " << qPrintable(fctName) << endl;
217 GroupWidget* win = item->getScene()->getGroupWidget();
222 text = QInputDialog::getText(win, "Rename a group",
223 "New name:", QLineEdit::Normal,
224 item->getRefBlock()->getName(), &ok);
227 if (text == item->getRefBlock()->getName()) return;
229 if( (text.isEmpty()) || (text.length() > 30)) {
230 QMessageBox::warning(win,"Error in given name",
231 "the block name must be shorter than 30 characters, cannot be empty",
236 GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
238 QMessageBox::warning(win,"Error in given name",
239 "the name provided is similar to that of another group",
246 item->getRefBlock()->setName(text);
247 if(item->getScene()->getGroupWidget()->isTopGroup()) {
248 mainWindow->setWindowTitle("blast - "+text);
251 item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
254 mainWindow->getLibrary()->updateComboScene();
257 void Dispatcher::renameSourceBlock(SourceItem *item){
258 static QString fctName = "Dispatcher::renameSourceBlock()";
260 cout << "call to " << qPrintable(fctName) << endl;
263 GroupWidget* win = item->getScene()->getGroupWidget();
268 text = QInputDialog::getText(win, "Rename a source",
269 "New name:", QLineEdit::Normal,
270 item->getRefBlock()->getName(), &ok);
273 if (text == item->getRefBlock()->getName()) return;
275 if( (text.isEmpty()) || (text.length() > 30)) {
276 QMessageBox::warning(win,"Error in given name",
277 "the block name must be shorter than 30 characters, cannot be empty",
282 FunctionalBlock* block = params->getGraph()->getSourceBlockByName(text);
284 QMessageBox::warning(win,"Error in given name",
285 "the name provided is similar to that of another source block within the top group",
292 item->getRefBlock()->setName(text);
297 void Dispatcher::renameInterface(InterfaceItem *item) {
298 static QString fctName = "Dispatcher::renameInterface()";
300 cout << "call to " << qPrintable(fctName) << endl;
303 GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
308 text = QInputDialog::getText(win, "Rename an interface",
309 "New name:", QLineEdit::Normal,
310 item->refInter->getName(), &ok);
314 if (text == item->refInter->getName()) return;
316 if( (text.isEmpty()) || (text.length() > 30)) {
317 QMessageBox::warning(win,"Error in given name",
318 "the interface name must be shorter than 30 characters, cannot be empty",
323 AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
325 QMessageBox::warning(win,"Error in given name",
326 "the name provided is similar to that of another interface",
332 item->refInter->setName(text);
333 AbstractInterface* assoIface = item->refInter->getAssociatedIface();
334 if (assoIface != NULL) {
335 assoIface->setName(text+"_enb");
337 item->updateName(text);
338 item->getOwner()->nameChanged();
341 void Dispatcher::showPatterns(InterfaceItem *item) {
342 static QString fctName = "Dispatcher::showPatterns()";
344 cout << "call to " << qPrintable(fctName) << endl;
346 ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
347 foreach(char c, iface->getOutputPattern()) {
353 void Dispatcher::duplicateBoxItem(BoxItem *item){
354 static QString fctName = "Dispatcher::duplicateBoxItem()";
356 cout << "call to " << qPrintable(fctName) << endl;
359 GroupScene *scene = item->getScene();
360 AbstractBlock* block = item->getRefBlock();
361 AbstractBlock *newBlock;
363 // only duplicate functional blocks
364 if(block->isFunctionalBlock()) {
366 // adding to the model
367 FunctionalBlock* funBlock = (FunctionalBlock*)block;
368 newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
369 // adding to the view
370 scene->createBoxItem(newBlock);
372 params->unsaveModif = true;
376 void Dispatcher::duplicateSourceItem(SourceItem *item) {
377 static QString fctName = "Dispatcher::duplicateSourceItem()";
379 cout << "call to " << qPrintable(fctName) << endl;
382 GroupScene *scene = item->getScene();
383 AbstractBlock* block = item->getRefBlock();
384 AbstractBlock *newBlock;
386 // only duplicate functional blocks
387 if(block->isFunctionalBlock()) {
389 // adding to the model
390 FunctionalBlock* funBlock = (FunctionalBlock*)block;
391 newBlock = params->getGraph()->duplicateSourceBlock(funBlock);
392 // adding to the view
393 scene->createSourceItem(newBlock);
395 params->unsaveModif = true;
399 void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
400 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
402 cout << "call to " << qPrintable(fctName) << endl;
405 AbstractInterface *refI = item->refInter;
406 if (! refI->isFunctionalInterface()) return;
408 AbstractBlock *refB = refI->getOwner();
409 if(! refB->isFunctionalBlock()) return;
411 FunctionalInterface* iface = (FunctionalInterface*)refI;
412 AbstractInterface *cloneIface = iface->clone();
413 if (cloneIface == NULL) {
414 QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
418 refB->addInterface(cloneIface);
420 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
421 item->getOwner()->addInterfaceItem(cloneIfaceItem,true);
423 // creating control interface if needed
424 if (refI->getAssociatedIface() != NULL) {
425 QString ctlName = cloneIface->getName()+"_enb";
426 ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,"boolean","1",cloneIface->getDirection(), AbstractInterface::Control, 1);
427 refB->addInterface(ctlIface);
428 if (! ctlIface->setAssociatedIface(cloneIface)) {
429 cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
435 void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
436 static QString fctName = "Dispatcher::addBlock()";
438 cout << "call to " << qPrintable(fctName) << endl;
440 bool newSource = false;
441 GroupScene *scene = getSceneById(idScene);
442 ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
443 // if block has no inputs, propose to add it as a source to top scene
444 if ((scene->isTopScene()) && (ref->isGeneratorBlock())) {
445 int ret = QMessageBox::question(NULL,"Adding a block to top scene","Selected block may be used as a source for the top scene. Do you want to add it as a source ?");
446 if (ret == QMessageBox::Yes) {
451 FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref);
452 scene->createSourceItem(newOne);
455 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
456 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
457 scene->createBoxItem(newOne);
459 params->unsaveModif = true;
463 GroupWidget *Dispatcher::createTopScene(){
464 static QString fctName = "Dispatcher::createTopScene()";
466 cout << "call to " << qPrintable(fctName) << endl;
469 // creating the model part of the group
470 Graph* graph = params->createGraph();
471 GroupBlock *refBlock = graph->getTopGroup();
473 // creating a fake and not connected interface
474 //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
476 // creating the group widget
477 topGroup = new GroupWidget(NULL,this,params);
478 currentGroup = topGroup;
479 // getting the newly created scene
480 GroupScene *scene = topGroup->getScene();
481 scene->setId(sceneCounter++);
482 params->setTopScene(scene);
483 params->setCurrentScene(scene);
484 // creating the view part of the group
485 GroupItem *group = new GroupItem(NULL,refBlock,this,params);
487 // adding the fake interface to the top group item
488 //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
489 //group->addInterface(item,true);
491 scene->setGroupItem(group);
493 groupList.append(topGroup);
497 GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
498 static QString fctName = "Dispatcher::addNewEmptyGroup();";
500 cout << "call to " << qPrintable(fctName) << endl;
503 // getting the parent block in the graph
504 GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
505 cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
506 GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent);
507 cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
508 // creating the BlockItem in the scene
509 BoxItem* newItem = scene->createBoxItem(groupBlock);
511 params->unsaveModif = true;
513 GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
514 if (show) child->show();
519 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
520 static QString fctName = "Dispatcher::createChildScene()";
522 cout << "call to " << qPrintable(fctName) << endl;
525 GroupWidget* group = NULL;
526 /* NB: this method may be called during design process or when loading
527 a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
528 cannot be initialized yet. This is why there are 2 cases below
531 if (upperItemOfGroupItem != NULL) {
532 // getting back the goup block already created
533 GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
534 // creating the view part of the group
535 GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
536 // creating the group widget
537 group = new GroupWidget(parentWidget, this, params);
538 // getting the newly created scene
539 GroupScene *scene = group->getScene();
540 scene->setId(sceneCounter++);
541 // affecting group item to the scene
542 scene->setGroupItem(groupItem);
543 groupList.append(group);
545 mainWindow->getLibrary()->updateComboScene();
548 GroupItem *groupItem = new GroupItem(this,params);
549 // creating the group widget
550 group = new GroupWidget(parentWidget, this, params);
551 // getting the newly created scene
552 GroupScene *scene = group->getScene();
553 // affecting group item to the scene
554 scene->setGroupItem(groupItem);
555 groupList.append(group);
560 void Dispatcher::destroyScene(GroupScene *scene) {
561 foreach(GroupScene* s, scene->getChildrenScene()) {
565 if (scene->getNbChildScene() == 0) {
566 // remove scene from the parent list, if possible
567 if (scene->getParentScene() != NULL) {
568 scene->getParentScene()->removeChildScene(scene);
570 // destroy the GroupWidget
571 groupList.removeAll(scene->getGroupWidget());
572 scene->getGroupWidget()->deleteLater();
575 cerr << "Abnormal case when destroying a scene" << endl;
579 void Dispatcher::showRaiseWindow(BoxItem *item) {
580 static QString fctName = "Dispatcher::showRaiseWindow()";
582 cout << "call to " << qPrintable(fctName) << endl;
585 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
586 GroupItem* child = item->getChildGroupItem();
588 cerr << "abnormal case: child group item is null " << endl;
592 GroupWidget* win = child->getScene()->getGroupWidget();
596 win->activateWindow();
599 params->setCurrentScene(currentGroup->getScene());
602 void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
603 static QString fctName = "Dispatcher::showRstClkIface()";
605 cout << "call to " << qPrintable(fctName) << endl;
608 item->setRstClkVisible(!item->isRstClkVisible());
612 void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
613 static QString fctName = "Dispatcher::showWishboneIface()";
615 cout << "call to " << qPrintable(fctName) << endl;
618 item->setWishboneVisible(!item->isWishboneVisible());
621 void Dispatcher::addNewFullGroup() {
622 static QString fctName = "Dispatcher::addNewFullGroup()";
624 cout << "call to " << qPrintable(fctName) << endl;
630 QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
631 QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
632 QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
634 /* What must be done:
635 1 - creating a new GroupBlock
636 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
637 3 - creating a BlockItem that references the new GroupBlock
638 4 - creating a new GroupWidget
639 5 - creating a new GroupItem added to the scene of the GroupWidget
643 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
644 associated to the GroupItem of the current scene
646 GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
647 GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
648 /* step 2: moving selected blocks */
649 foreach(BlockItem* blockItem, listBlocks) {
650 parentBlock->removeBlock(blockItem->getRefBlock());
651 newGroupBlock->addBlock(blockItem->getRefBlock());
654 GroupItem *parent = currentGroup->getScene()->getGroupItem();
655 GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
656 BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
657 GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
659 //create the new window
660 GroupWidget* win = new GroupWidget(this,params);
661 win->getScene()->setGroupItem(groupItem);
662 win->getScene()->addItem(groupItem);
663 ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
664 params->addWindow(win);
668 params->getCurrentScene()->addBlockItem(blockItem);
669 params->getCurrentScene()->addItem(blockItem);
670 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
672 //replace selected blocks in the group
673 foreach(AbstractBoxItem *block, listBlocks){
674 ((GroupItem*)block->getParentItem())->removeBlockItem(block);
675 ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
676 params->getCurrentScene()->removeItem(block);
677 params->getCurrentScene()->removeBlockItem(block);
679 groupBlock->addBlock(block->getRefBlock());
680 listAbstractBlocks.append(block->getRefBlock());
682 block->setUpperItem(groupItem);
683 groupItem->addBlockItem(block);
684 win->getScene()->addItem(block);
685 win->getScene()->addBlockItem(block);
688 //replace connection between selected blocks in the group
689 foreach(ConnectionItem *conn, connections){
690 if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
691 if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
692 parent->removeConnection(conn);
693 params->getCurrentScene()->removeItem(conn);
695 groupItem->addConnection(conn);
696 win->getScene()->addItem(conn);
701 //create new interfaces and connections for the new group
702 foreach(AbstractBoxItem *block, listBlocks){
703 foreach(InterfaceItem *inter, block->getInterfaces()){
704 cout << "inter : " << inter->getName().toStdString() << endl;
705 if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
706 cout << "connected from non null" << endl;
707 if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
709 AbstractInterface *iface = inter->refInter->clone(0);
710 iface->setName(iface->getName()+"_group");
711 groupBlock->addInterface(iface);
713 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
714 blockItem->addInterface(ifaceItem);
715 blockItem->resetInterfacesPosition();
717 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
718 groupItem->addInterface(ifaceGroupItem);
719 groupItem->resetInterfacesPosition();
720 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
721 if(conn->getToInterfaceItem() == inter){
722 conn->setToInterfaceItem(ifaceItem);
723 ifaceItem->refInter->setConnectedFrom(NULL);
724 conn->getFromInterfaceItem()->refInter->clearConnectedTo();
725 connect(ifaceItem,conn->getFromInterfaceItem());
728 params->setCurrentWindow(win);
730 inter->refInter->setConnectedFrom(NULL);
731 ifaceGroupItem->refInter->clearConnectedTo();
732 connect(inter,ifaceGroupItem);
733 params->setCurrentWindow(mainWindow);
737 if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
738 cout << "connected to non null" << endl;
739 foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
740 if(!listAbstractBlocks.contains(iface->getOwner())){
742 AbstractInterface *iface = inter->refInter->clone(0);
743 iface->setName(iface->getName()+"_group");
744 groupBlock->addInterface(iface);
746 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
747 blockItem->addInterface(ifaceItem);
748 blockItem->resetInterfacesPosition();
750 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
751 if(conn->getFromInterfaceItem() == inter){
752 conn->setFromInterfaceItem(ifaceItem);
753 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
754 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
758 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
759 groupItem->addInterface(ifaceGroupItem);
760 groupItem->resetInterfacesPosition();
761 inter->refInter->clearConnectedTo();
762 ifaceGroupItem->refInter->setConnectedFrom(NULL);
763 connect(ifaceGroupItem,inter);
772 parent->updateShape();
773 currentGroup->getScene()->updateConnectionItemsShape();
775 groupItem->updateShape();
776 win->getScene()->updateConnectionItemsShape();
777 groupItem->update(groupItem->boundingRect());
782 void Dispatcher::removeBoxItem(BoxItem *item) {
783 static QString fctName = "Dispatcher::removeBoxItem()";
785 cout << "call to " << qPrintable(fctName) << endl;
788 /* a BoxItem (group of func) can be removed only if none of its
789 interfaces is connected to a group interface that is itself
790 connected to another one.
792 bool canRemove = true;
794 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
795 foreach(ConnectionItem* conn, ifaceItem->connections) {
796 InterfaceItem* other = NULL;
797 if (conn->getFromInterfaceItem() == ifaceItem) {
798 other = conn->getToInterfaceItem();
801 other = conn->getFromInterfaceItem();
804 if (other->getOwner()->isGroupItem()) {
805 ConnectedInterface* ref = other->refInter;
806 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
813 QMessageBox::warning(NULL,"Forbidden operation",
814 "The block has at least one connection to a group interface that is totally connected.",
820 if (item->getRefBlock()->isFunctionalBlock()) {
821 msg = "Removing block ";
824 msg = "Removing group ";
826 msg += item->getRefBlock()->getName();
827 msg += " and all its connections.\n\nAre you sure ?";
829 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
830 if (ret == QMessageBox::Cancel) {
833 removeAllBlockConnections(item);
835 if (item->getRefBlock()->isFunctionalBlock()) {
836 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
837 GroupBlock* group = AB_TO_GRP(block->getParent());
838 item->getScene()->removeBoxItem(item);
839 params->getGraph()->removeFunctionalBlock(block);
841 else if (item->getRefBlock()->isGroupBlock()) {
843 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
845 // remove all child scenes recursively
846 GroupItem* subgroup = item->getChildGroupItem();
847 destroyScene(subgroup->getScene());
848 // remove the BoxItem
849 item->getScene()->removeBoxItem(item);
850 // remove the group from the graph
851 params->getGraph()->removeGroupBlock(group);
855 void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
856 static QString fctName = "Dispatcher::removeAllBlockConnection()";
858 cout << "call to " << qPrintable(fctName) << endl;
861 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
862 foreach(ConnectionItem* conn, ifaceItem->connections) {
863 removeConnection(conn);
868 void Dispatcher::removeSourceItem(SourceItem *item) {
869 static QString fctName = "Dispatcher::removeSourceItem()";
871 cout << "call to " << qPrintable(fctName) << endl;
874 QString msg = "Removing source ";
876 msg += item->getRefBlock()->getName();
877 msg += " and all its connections.\n\nAre you sure ?";
879 int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
880 if (ret == QMessageBox::Cancel) {
883 removeAllBlockConnections(item);
885 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
886 item->getScene()->removeSourceItem(item);
887 params->getGraph()->removeSourceBlock(block);
891 void Dispatcher::removeConnection(ConnectionItem *connItem) {
892 static QString fctName = "Dispatcher::removeConnection()";
894 cout << "call to " << qPrintable(fctName) << endl;
896 InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
897 InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
900 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
903 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not
904 GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem
906 ConnectedInterface *fromInter = fromIfaceItem->refInter;
907 ConnectedInterface *toInter = toIfaceItem->refInter;
909 // test if one of the interface bounded to item is owned by a GroupItem
910 if (fromIfaceItem->getOwner()->isGroupItem()) {
911 groupItem = ABI_TO_GI(fromIfaceItem->getOwner());
912 groupIfaceItem = fromIfaceItem;
914 else if (toIfaceItem->getOwner()->isGroupItem()) {
915 groupItem = ABI_TO_GI(toIfaceItem->getOwner());
916 groupIfaceItem = toIfaceItem;
919 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
922 // removing the connection from graph
924 cout << "removing connections from graph ..." ;
926 fromInter->disconnectTo(toInter);
929 cout << "done." << endl ;
932 // removing the connection from scene
934 cout << "removing connections from scene ..." ;
936 groupItem->getScene()->removeConnectionItem(connItem);
939 cout << "done." << endl ;
942 // if one of the interface bounded to connItem is owned by the GroupItem of the scene
943 if (groupIfaceItem != NULL) {
945 // determine if the interface must be removed since it has no more connections.
946 bool groupInterRemove = false;
947 if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true;
949 if (groupInterRemove) {
950 // get the GroupInterface from interface item
951 ConnectedInterface* groupInter = groupIfaceItem->refInter;
952 // remove interface from GroupItem, and delete it.
953 groupItem->removeInterfaceItem(groupIfaceItem);
954 // get the parent BoxItem of GroupItem if it exists.
955 BoxItem* parent2Item = groupItem->getParentItem();
956 if (parent2Item != NULL) {
957 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter);
958 // remove interface intem in parent BoxItem
959 parent2Item->removeInterfaceItem(group2IfaceItem);
961 // remove GroupInterface in the graph.
962 groupInter->getOwner()->removeInterface(groupInter);
967 void Dispatcher::showBlocksLibrary(){
968 cout << "showing block library" << endl;
969 mainWindow->getLibrary()->show();
970 mainWindow->getLibrary()->raise();
973 void Dispatcher::showProperties(InterfaceItem *inter) {
974 new InterfacePropertiesWindow(inter);
977 /* connectInterToGroup() :
978 The only way for a block (functional of group) within a GroupItem to be connected
979 to the latter is to right-click on one of its interfaces and to choose "connect to group".
980 That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
983 void Dispatcher::connectInterToGroup(InterfaceItem *item){
985 // getting the GroupBlock and GroupItem that are parent of the block that owns item
986 ConnectedInterface *refInter = item->refInter;
987 cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
988 GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
989 cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
990 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
992 // creating/adding the group interface in the graph model
993 GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
994 parentItem->getRefBlock()->addInterface(groupInter);
995 // creating/adding the group control interface in the graph model
996 GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
997 groupCtlInter->setAssociatedIface(groupInter);
998 parentItem->getRefBlock()->addInterface(groupCtlInter);
999 // creating/adding the group interface in the current scene model, and connection item
1000 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1001 parentItem->addInterfaceItem(groupIfaceItem,true);
1003 // creating the connection, in graph and with an item
1004 createConnection(item, groupIfaceItem);
1006 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1007 BoxItem* parent2Item = parentItem->getParentItem();
1008 if(parent2Item != NULL){
1009 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1010 parent2Item->addInterfaceItem(blockIfaceItem,true);
1014 parentItem->getScene()->updateConnectionItemsShape();
1016 params->unsaveModif = true;
1019 void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
1020 static QString fctName = "Dispatcher::removeBlockInterface()";
1021 #ifdef DEBUG_FCTNAME
1022 cout << "call to " << qPrintable(fctName) << endl;
1025 /* first, remove all connections from item
1026 NB: if there is a connection to a group interface, then this
1027 method should not be called if the group interface is also
1028 connected to another interface. Normally, this is not possible
1029 because such a check is done when creating the contextual menu
1030 that allows to remove an interface.
1032 foreach(ConnectionItem* conn, item->connections) {
1033 removeConnection(conn);
1036 ConnectedInterface* ref = item->refInter;
1037 item->getOwner()->removeInterfaceItem(item);
1038 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1039 fun->removeInterface(ref);
1042 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
1043 static QString fctName = "Dispatcher::removeGroupInterface()";
1044 #ifdef DEBUG_FCTNAME
1045 cout << "call to " << qPrintable(fctName) << endl;
1048 /* NB: just remove all connections from/to this item, since when there are no more
1049 ones to a GroupItem, it is automatically deleted.
1051 foreach(ConnectionItem* conn, item->connections) {
1052 removeConnection(conn);
1056 QMap<int, QString> Dispatcher::getAllGroupNames() {
1058 QMap<int, QString> list;
1059 foreach(GroupWidget *group, groupList) {
1060 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1065 GroupScene* Dispatcher::getSceneById(int id) {
1066 foreach(GroupWidget *group, groupList){
1067 if(group->getScene()->getId() == id)
1068 return group->getScene();
1070 cout << "search scene by id :" << id << " :: not found..." << endl;
1074 GroupItem *Dispatcher::getGroupItemById(int id) {
1075 foreach(GroupWidget *group, groupList) {
1076 GroupScene* scene = group->getScene();
1077 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1079 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1083 BoxItem *Dispatcher::getBoxItemById(int id) {
1084 foreach(GroupWidget *group, groupList) {
1086 GroupScene* scene = group->getScene();
1087 foreach(BoxItem *item, scene->getBoxItems()){
1088 if(item->getId() == id){
1093 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1097 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1099 foreach(GroupWidget *group, groupList) {
1101 GroupScene* scene = group->getScene();
1103 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1104 if(item->getId() == id){
1108 foreach(BoxItem *block, scene->getBoxItems()){
1109 foreach(InterfaceItem *item, block->getInterfaces()){
1110 if(item->getId() == id){
1116 cout << "search interface by id :" << id << " :: not found..." << endl;