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 // connect both interface
93 if (ref1->canConnectTo(ref2)) {
94 ok1 = ref1->connectTo(ref2);
95 ok1 = ok1 & ref2->connectFrom(ref1);
97 if (ref2->canConnectTo(ref1)) {
98 ok2 = ref2->connectTo(ref1);
99 ok2 = ok2 & ref1->connectFrom(ref2);
101 if ((ok1 == true) || (ok2 == true)) {
103 iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2);
106 params->unsaveModif = true;
113 void Dispatcher::unselectAllItems(int direction){
115 GroupScene *scene = params->getCurrentScene();
117 foreach(BoxItem* block, scene->getBoxItems()) {
118 block->setSelected(false);
119 block->setCurrentInterface(NULL);
121 scene->unselecteInterfaces();
125 void Dispatcher::setCurrentGroupWidget(GroupWidget *win){
127 win->changeConnectionMode(-1);
129 params->setCurrentScene(win->getScene());
132 void Dispatcher::changeConnectionMode(int mode){
135 foreach(GroupWidget* win, groupList){
137 QToolButton* buttonNewConnection = win->getButtonNewConnection();
139 QPalette pal = buttonNewConnection->palette();
142 if(params->sceneMode != Parameters::EditOnConnection){
143 params->sceneMode = Parameters::EditOnConnection;
144 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
146 params->sceneMode = Parameters::EditNoOperation;
147 pal.setColor(QPalette::Button, QColor("#edeceb"));
150 else if(mode == Parameters::EditOnConnection){
151 params->sceneMode = Parameters::EditOnConnection;
152 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
155 params->sceneMode = Parameters::EditNoOperation;
156 pal.setColor(QPalette::Button, QColor("#edeceb"));
158 unselectAllInterfaces();
160 buttonNewConnection->setAutoFillBackground(true);
161 buttonNewConnection->setPalette(pal);
162 buttonNewConnection->update();
167 void Dispatcher::renameFunctionalBlock(BoxItem *item){
168 static QString fctName = "Dispatcher::renameFunctionalBlock()";
170 cout << "call to " << qPrintable(fctName) << endl;
173 GroupWidget* win = item->getScene()->getGroupWidget();
178 text = QInputDialog::getText(win, "Rename a functional block",
179 "New name:", QLineEdit::Normal,
180 item->getRefBlock()->getName(), &ok);
183 if (text == item->getRefBlock()->getName()) return;
185 if( (text.isEmpty()) || (text.length() > 30)) {
186 QMessageBox::warning(win,"Error in given name",
187 "the block name must be shorter than 30 characters, cannot be empty",
192 FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
194 QMessageBox::warning(win,"Error in given name",
195 "the name provided is similar to that of another functional block within the group",
202 item->getRefBlock()->setName(text);
206 void Dispatcher::renameGroupBlock(GroupItem *item){
207 static QString fctName = "Dispatcher::renameGroupBlock()";
209 cout << "call to " << qPrintable(fctName) << endl;
212 GroupWidget* win = item->getScene()->getGroupWidget();
217 text = QInputDialog::getText(win, "Rename a group",
218 "New name:", QLineEdit::Normal,
219 item->getRefBlock()->getName(), &ok);
222 if (text == item->getRefBlock()->getName()) return;
224 if( (text.isEmpty()) || (text.length() > 30)) {
225 QMessageBox::warning(win,"Error in given name",
226 "the block name must be shorter than 30 characters, cannot be empty",
231 GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
233 QMessageBox::warning(win,"Error in given name",
234 "the name provided is similar to that of another group",
241 item->getRefBlock()->setName(text);
242 if(item->getScene()->getGroupWidget()->isTopGroup()) {
243 mainWindow->setWindowTitle("blast - "+text);
246 item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
249 mainWindow->getLibrary()->updateComboScene();
252 void Dispatcher::renameSourceBlock(SourceItem *item){
253 static QString fctName = "Dispatcher::renameSourceBlock()";
255 cout << "call to " << qPrintable(fctName) << endl;
258 GroupWidget* win = item->getScene()->getGroupWidget();
263 text = QInputDialog::getText(win, "Rename a source",
264 "New name:", QLineEdit::Normal,
265 item->getRefBlock()->getName(), &ok);
268 if (text == item->getRefBlock()->getName()) return;
270 if( (text.isEmpty()) || (text.length() > 30)) {
271 QMessageBox::warning(win,"Error in given name",
272 "the block name must be shorter than 30 characters, cannot be empty",
277 FunctionalBlock* block = params->getGraph()->getSourceBlockByName(text);
279 QMessageBox::warning(win,"Error in given name",
280 "the name provided is similar to that of another source block within the top group",
287 item->getRefBlock()->setName(text);
292 void Dispatcher::renameInterface(InterfaceItem *item) {
293 static QString fctName = "Dispatcher::renameInterface()";
295 cout << "call to " << qPrintable(fctName) << endl;
298 GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
303 text = QInputDialog::getText(win, "Rename an interface",
304 "New name:", QLineEdit::Normal,
305 item->refInter->getName(), &ok);
309 if (text == item->refInter->getName()) return;
311 if( (text.isEmpty()) || (text.length() > 30)) {
312 QMessageBox::warning(win,"Error in given name",
313 "the interface name must be shorter than 30 characters, cannot be empty",
318 AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
320 QMessageBox::warning(win,"Error in given name",
321 "the name provided is similar to that of another interface",
327 item->refInter->setName(text);
328 AbstractInterface* assoIface = item->refInter->getAssociatedIface();
329 if (assoIface != NULL) {
330 assoIface->setName(text+"_ctl");
332 item->updateName(text);
333 item->getOwner()->nameChanged();
336 void Dispatcher::duplicateBoxItem(BoxItem *item){
337 static QString fctName = "Dispatcher::duplicateBoxItem()";
339 cout << "call to " << qPrintable(fctName) << endl;
342 GroupScene *scene = item->getScene();
343 AbstractBlock* block = item->getRefBlock();
344 AbstractBlock *newBlock;
346 // only duplicate functional blocks
347 if(block->isFunctionalBlock()) {
349 // adding to the model
350 FunctionalBlock* funBlock = (FunctionalBlock*)block;
351 newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
352 // adding to the view
353 scene->createBoxItem(newBlock);
355 params->unsaveModif = true;
359 void Dispatcher::duplicateSourceItem(SourceItem *item) {
360 static QString fctName = "Dispatcher::duplicateSourceItem()";
362 cout << "call to " << qPrintable(fctName) << endl;
365 GroupScene *scene = item->getScene();
366 AbstractBlock* block = item->getRefBlock();
367 AbstractBlock *newBlock;
369 // only duplicate functional blocks
370 if(block->isFunctionalBlock()) {
372 // adding to the model
373 FunctionalBlock* funBlock = (FunctionalBlock*)block;
374 newBlock = params->getGraph()->duplicateSourceBlock(funBlock);
375 // adding to the view
376 scene->createSourceItem(newBlock);
378 params->unsaveModif = true;
382 void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
383 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
385 cout << "call to " << qPrintable(fctName) << endl;
388 AbstractInterface *refI = item->refInter;
389 if (! refI->isFunctionalInterface()) return;
391 AbstractBlock *refB = refI->getOwner();
392 if(! refB->isFunctionalBlock()) return;
394 FunctionalInterface* iface = (FunctionalInterface*)refI;
395 AbstractInterface *cloneIface = iface->clone();
396 if (cloneIface == NULL) {
397 QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
401 refB->addInterface(cloneIface);
403 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
404 item->getOwner()->addInterface(cloneIfaceItem,true);
406 // creating control interface if needed
407 if (refI->getAssociatedIface() != NULL) {
408 QString ctlName = cloneIface->getName()+"_ctl";
409 ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,"boolean","1",cloneIface->getDirection(), AbstractInterface::Control, 1);
410 refB->addInterface(ctlIface);
411 if (! ctlIface->setAssociatedIface(cloneIface)) {
412 cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
418 void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
419 static QString fctName = "Dispatcher::addBlock()";
421 cout << "call to " << qPrintable(fctName) << endl;
423 bool newSource = false;
424 GroupScene *scene = getSceneById(idScene);
425 ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
426 // if block has no inputs, propose to add it as a source to top scene
427 if ((scene->isTopScene()) && (ref->getDataInputs().isEmpty())) {
428 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 ?");
429 if (ret == QMessageBox::Yes) {
434 FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref);
435 scene->createSourceItem(newOne);
438 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
439 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
440 scene->createBoxItem(newOne);
442 params->unsaveModif = true;
446 GroupWidget *Dispatcher::createTopScene(){
447 static QString fctName = "Dispatcher::createTopScene()";
449 cout << "call to " << qPrintable(fctName) << endl;
452 // creating the model part of the group
453 Graph* graph = params->createGraph();
454 GroupBlock *refBlock = graph->getTopGroup();
456 // creating a fake and not connected interface
457 //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
459 // creating the group widget
460 topGroup = new GroupWidget(NULL,this,params);
461 currentGroup = topGroup;
462 // getting the newly created scene
463 GroupScene *scene = topGroup->getScene();
464 scene->setId(sceneCounter++);
465 params->setTopScene(scene);
466 params->setCurrentScene(scene);
467 // creating the view part of the group
468 GroupItem *group = new GroupItem(NULL,refBlock,this,params);
470 // adding the fake interface to the top group item
471 //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
472 //group->addInterface(item,true);
474 scene->setGroupItem(group);
476 groupList.append(topGroup);
480 GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
481 static QString fctName = "Dispatcher::addNewEmptyGroup();";
483 cout << "call to " << qPrintable(fctName) << endl;
486 // getting the parent block in the graph
487 GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
488 cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
489 GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent);
490 cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
491 // creating the BlockItem in the scene
492 BoxItem* newItem = scene->createBoxItem(groupBlock);
494 params->unsaveModif = true;
496 GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
497 if (show) child->show();
502 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
503 static QString fctName = "Dispatcher::createChildScene()";
505 cout << "call to " << qPrintable(fctName) << endl;
508 GroupWidget* group = NULL;
509 /* NB: this method may be called during design process or when loading
510 a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
511 cannot be initialized yet. This is why there are 2 cases below
514 if (upperItemOfGroupItem != NULL) {
515 // getting back the goup block already created
516 GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
517 // creating the view part of the group
518 GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
519 // creating the group widget
520 group = new GroupWidget(parentWidget, this, params);
521 // getting the newly created scene
522 GroupScene *scene = group->getScene();
523 scene->setId(sceneCounter++);
524 // affecting group item to the scene
525 scene->setGroupItem(groupItem);
526 groupList.append(group);
528 mainWindow->getLibrary()->updateComboScene();
531 GroupItem *groupItem = new GroupItem(this,params);
532 // creating the group widget
533 group = new GroupWidget(parentWidget, this, params);
534 // getting the newly created scene
535 GroupScene *scene = group->getScene();
536 // affecting group item to the scene
537 scene->setGroupItem(groupItem);
538 groupList.append(group);
543 void Dispatcher::destroyScene(GroupScene *scene) {
544 foreach(GroupScene* s, scene->getChildrenScene()) {
548 if (scene->getNbChildScene() == 0) {
549 // remove scene from the parent list, if possible
550 if (scene->getParentScene() != NULL) {
551 scene->getParentScene()->removeChildScene(scene);
553 // destroy the GroupWidget
554 groupList.removeAll(scene->getGroupWidget());
555 scene->getGroupWidget()->deleteLater();
558 cerr << "Abnormal case when destroying a scene" << endl;
562 void Dispatcher::showRaiseWindow(BoxItem *item) {
563 static QString fctName = "Dispatcher::showRaiseWindow()";
565 cout << "call to " << qPrintable(fctName) << endl;
568 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
569 GroupItem* child = item->getChildGroupItem();
571 cerr << "abnormal case: child group item is null " << endl;
575 GroupWidget* win = child->getScene()->getGroupWidget();
579 win->activateWindow();
582 params->setCurrentScene(currentGroup->getScene());
585 void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
586 static QString fctName = "Dispatcher::showRstClkIface()";
588 cout << "call to " << qPrintable(fctName) << endl;
591 item->setRstClkVisible(!item->isRstClkVisible());
595 void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
596 static QString fctName = "Dispatcher::showWishboneIface()";
598 cout << "call to " << qPrintable(fctName) << endl;
601 item->setWishboneVisible(!item->isWishboneVisible());
604 void Dispatcher::addNewFullGroup() {
605 static QString fctName = "Dispatcher::addNewFullGroup()";
607 cout << "call to " << qPrintable(fctName) << endl;
613 QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
614 QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
615 QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
617 /* What must be done:
618 1 - creating a new GroupBlock
619 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
620 3 - creating a BlockItem that references the new GroupBlock
621 4 - creating a new GroupWidget
622 5 - creating a new GroupItem added to the scene of the GroupWidget
626 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
627 associated to the GroupItem of the current scene
629 GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
630 GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
631 /* step 2: moving selected blocks */
632 foreach(BlockItem* blockItem, listBlocks) {
633 parentBlock->removeBlock(blockItem->getRefBlock());
634 newGroupBlock->addBlock(blockItem->getRefBlock());
637 GroupItem *parent = currentGroup->getScene()->getGroupItem();
638 GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
639 BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
640 GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
642 //create the new window
643 GroupWidget* win = new GroupWidget(this,params);
644 win->getScene()->setGroupItem(groupItem);
645 win->getScene()->addItem(groupItem);
646 ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
647 params->addWindow(win);
651 params->getCurrentScene()->addBlockItem(blockItem);
652 params->getCurrentScene()->addItem(blockItem);
653 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
655 //replace selected blocks in the group
656 foreach(AbstractBoxItem *block, listBlocks){
657 ((GroupItem*)block->getParentItem())->removeBlockItem(block);
658 ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
659 params->getCurrentScene()->removeItem(block);
660 params->getCurrentScene()->removeBlockItem(block);
662 groupBlock->addBlock(block->getRefBlock());
663 listAbstractBlocks.append(block->getRefBlock());
665 block->setUpperItem(groupItem);
666 groupItem->addBlockItem(block);
667 win->getScene()->addItem(block);
668 win->getScene()->addBlockItem(block);
671 //replace connection between selected blocks in the group
672 foreach(ConnectionItem *conn, connections){
673 if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
674 if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
675 parent->removeConnection(conn);
676 params->getCurrentScene()->removeItem(conn);
678 groupItem->addConnection(conn);
679 win->getScene()->addItem(conn);
684 //create new interfaces and connections for the new group
685 foreach(AbstractBoxItem *block, listBlocks){
686 foreach(InterfaceItem *inter, block->getInterfaces()){
687 cout << "inter : " << inter->getName().toStdString() << endl;
688 if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
689 cout << "connected from non null" << endl;
690 if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
692 AbstractInterface *iface = inter->refInter->clone(0);
693 iface->setName(iface->getName()+"_group");
694 groupBlock->addInterface(iface);
696 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
697 blockItem->addInterface(ifaceItem);
698 blockItem->resetInterfacesPosition();
700 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
701 groupItem->addInterface(ifaceGroupItem);
702 groupItem->resetInterfacesPosition();
703 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
704 if(conn->getToInterfaceItem() == inter){
705 conn->setToInterfaceItem(ifaceItem);
706 ifaceItem->refInter->setConnectedFrom(NULL);
707 conn->getFromInterfaceItem()->refInter->clearConnectedTo();
708 connect(ifaceItem,conn->getFromInterfaceItem());
711 params->setCurrentWindow(win);
713 inter->refInter->setConnectedFrom(NULL);
714 ifaceGroupItem->refInter->clearConnectedTo();
715 connect(inter,ifaceGroupItem);
716 params->setCurrentWindow(mainWindow);
720 if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
721 cout << "connected to non null" << endl;
722 foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
723 if(!listAbstractBlocks.contains(iface->getOwner())){
725 AbstractInterface *iface = inter->refInter->clone(0);
726 iface->setName(iface->getName()+"_group");
727 groupBlock->addInterface(iface);
729 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
730 blockItem->addInterface(ifaceItem);
731 blockItem->resetInterfacesPosition();
733 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
734 if(conn->getFromInterfaceItem() == inter){
735 conn->setFromInterfaceItem(ifaceItem);
736 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
737 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
741 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
742 groupItem->addInterface(ifaceGroupItem);
743 groupItem->resetInterfacesPosition();
744 inter->refInter->clearConnectedTo();
745 ifaceGroupItem->refInter->setConnectedFrom(NULL);
746 connect(ifaceGroupItem,inter);
755 parent->updateShape();
756 currentGroup->getScene()->updateConnectionItemsShape();
758 groupItem->updateShape();
759 win->getScene()->updateConnectionItemsShape();
760 groupItem->update(groupItem->boundingRect());
765 void Dispatcher::removeBoxItem(BoxItem *item) {
766 static QString fctName = "Dispatcher::removeBoxItem()";
768 cout << "call to " << qPrintable(fctName) << endl;
771 /* a BoxItem (group of func) can be removed only if none of its
772 interfaces is connected to a group interface that is itself
773 connected to another one.
775 bool canRemove = true;
777 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
778 foreach(ConnectionItem* conn, ifaceItem->connections) {
779 InterfaceItem* other = NULL;
780 if (conn->getFromInterfaceItem() == ifaceItem) {
781 other = conn->getToInterfaceItem();
784 other = conn->getFromInterfaceItem();
787 if (other->getOwner()->isGroupItem()) {
788 ConnectedInterface* ref = other->refInter;
789 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
796 QMessageBox::warning(NULL,"Forbidden operation",
797 "The block has at least one connection to a group interface that is totally connected.",
803 if (item->getRefBlock()->isFunctionalBlock()) {
804 msg = "Removing block ";
807 msg = "Removing group ";
809 msg += item->getRefBlock()->getName();
810 msg += " and all its connections.\n\nAre you sure ?";
812 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
813 if (ret == QMessageBox::Cancel) {
816 removeAllBlockConnections(item);
818 if (item->getRefBlock()->isFunctionalBlock()) {
819 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
820 GroupBlock* group = AB_TO_GRP(block->getParent());
821 item->getScene()->removeBoxItem(item);
822 params->getGraph()->removeFunctionalBlock(block);
824 else if (item->getRefBlock()->isGroupBlock()) {
826 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
828 // remove all child scenes recursively
829 GroupItem* subgroup = item->getChildGroupItem();
830 destroyScene(subgroup->getScene());
831 // remove the BoxItem
832 item->getScene()->removeBoxItem(item);
833 // remove the group from the graph
834 params->getGraph()->removeGroupBlock(group);
838 void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
839 static QString fctName = "Dispatcher::removeAllBlockConnection()";
841 cout << "call to " << qPrintable(fctName) << endl;
844 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
845 foreach(ConnectionItem* conn, ifaceItem->connections) {
846 removeConnection(conn);
851 void Dispatcher::removeSourceItem(SourceItem *item) {
852 static QString fctName = "Dispatcher::removeSourceItem()";
854 cout << "call to " << qPrintable(fctName) << endl;
857 QString msg = "Removing source ";
859 msg += item->getRefBlock()->getName();
860 msg += " and all its connections.\n\nAre you sure ?";
862 int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
863 if (ret == QMessageBox::Cancel) {
866 removeAllBlockConnections(item);
868 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
869 item->getScene()->removeSourceItem(item);
870 params->getGraph()->removeSourceBlock(block);
874 void Dispatcher::removeConnection(ConnectionItem *conn) {
875 static QString fctName = "Dispatcher::removeConnection()";
877 cout << "call to " << qPrintable(fctName) << endl;
879 InterfaceItem* fromIfaceItem = conn->getFromInterfaceItem();
880 InterfaceItem* toIfaceItem = conn->getToInterfaceItem();
883 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
886 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem
887 GroupItem* groupItem = NULL;
889 ConnectedInterface *fromInter = fromIfaceItem->refInter;
890 ConnectedInterface *toInter = toIfaceItem->refInter;
891 // process the speical case source->group apart
892 if (fromIfaceItem->getOwner()->isSourceItem()) {
894 fromInter->removeConnectedTo(toInter);
895 toInter->clearConnectedFrom();
897 fromIfaceItem->removeConnectionItem(conn);
898 toIfaceItem->removeConnectionItem(conn);
899 groupItem->getScene()->removeConnectionItem(conn);
904 if (fromIfaceItem->getOwner()->isGroupItem()) {
905 groupIfaceItem = fromIfaceItem;
906 groupItem = toIfaceItem->getOwner()->getScene()->getGroupItem();
908 else if (toIfaceItem->getOwner()->isGroupItem()) {
909 groupIfaceItem = toIfaceItem;
910 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
913 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
916 // removing the connection from graph
918 cout << "removing connections from graph ..." ;
920 if (fromInter->getDirection() == AbstractInterface::InOut) {
921 fromInter->clearConnectedTo();
922 fromInter->clearConnectedFrom();
923 toInter->clearConnectedTo();
924 toInter->clearConnectedFrom();
927 fromInter->removeConnectedTo(toInter);
928 toInter->clearConnectedFrom();
931 cout << "done." << endl ;
934 // removing the connection from scene
936 cout << "removing connections from scene ..." ;
938 fromIfaceItem->removeConnectionItem(conn);
939 toIfaceItem->removeConnectionItem(conn);
940 groupItem->getScene()->removeConnectionItem(conn);
943 cout << "done." << endl ;
946 if (groupIfaceItem != NULL) {
947 ConnectedInterface* groupInter = groupIfaceItem->refInter;
948 groupItem->removeInterface(groupIfaceItem);
950 BoxItem* parent2Item = groupItem->getParentItem();
951 if (parent2Item != NULL) {
952 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
953 parent2Item->removeInterface(group2IfaceItem);
955 groupInter->getOwner()->removeInterface(groupInter);
959 void Dispatcher::showBlocksLibrary(){
960 cout << "showing block library" << endl;
961 mainWindow->getLibrary()->show();
962 mainWindow->getLibrary()->raise();
965 void Dispatcher::showProperties(InterfaceItem *inter)
967 new InterfacePropertiesWindow(inter);
970 /* connectInterToGroup() :
971 The only way for a block (functional of group) within a GroupItem to be connected
972 to the latter is to right-click on one of its interfaces and to choose "connect to group".
973 That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
976 void Dispatcher::connectInterToGroup(InterfaceItem *item){
978 // getting the GroupBlock and GroupItem that are parent of the block that owns item
979 ConnectedInterface *refInter = item->refInter;
980 cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
981 GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
982 cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
983 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
985 // creating/adding the group interface in the graph model
986 GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
987 groupInter->setType(refInter->getType());
988 groupInter->setWidth(refInter->getWidth());
989 groupInter->setPurpose(refInter->getPurpose());
990 parentItem->getRefBlock()->addInterface(groupInter);
992 // connect both interface
994 if (refInter->getDirection() == AbstractInterface::Output) {
995 ok = refInter->connectTo(groupInter);
996 ok = ok & groupInter->connectFrom(refInter);
998 else if (refInter->getDirection() == AbstractInterface::Input) {
999 ok = groupInter->connectTo(refInter);
1000 ok = ok & refInter->connectFrom(groupInter);
1002 else if (refInter->getDirection() == AbstractInterface::InOut) {
1003 ok = refInter->connectTo(groupInter);
1004 ok = ok & groupInter->connectFrom(refInter);
1005 ok = ok & groupInter->connectTo(refInter);
1006 ok = ok & refInter->connectFrom(groupInter);
1009 cerr << "abnormal case while connecting a block iface to its parent group" << endl;
1011 // creating/adding the group interface in the current scene model, and connection item
1012 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1013 parentItem->addInterface(groupIfaceItem,true);
1015 parentItem->getScene()->createConnectionItem(item, groupIfaceItem);
1017 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1018 BoxItem* parent2Item = parentItem->getParentItem();
1019 if(parent2Item != NULL){
1020 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1021 parent2Item->addInterface(blockIfaceItem,true);
1025 parentItem->getScene()->updateConnectionItemsShape();
1027 params->unsaveModif = true;
1032 void Dispatcher::disconnectInterFromGroup(InterfaceItem *item) {
1033 static QString fctName = "Dispatcher::disconnectInterFromGroup()";
1034 #ifdef DEBUG_FCTNAME
1035 cout << "call to " << qPrintable(fctName) << endl;
1038 // getting the GroupBlock and GroupItem that are parent of the block that owns item
1039 ConnectedInterface *refInter = item->refInter;
1040 ConnectedInterface *groupInter = NULL;
1041 GroupBlock* parentGroup = AB_TO_GRP(refInter->getOwner()->getParent());
1042 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
1044 // removing the connection from graph
1046 cout << "removing connections from graph ..." ;
1049 if (refInter->getDirection() == AbstractInterface::Output) {
1050 groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
1051 refInter->removeConnectedTo(groupInter);
1052 groupInter->clearConnectedFrom();
1054 else if (refInter->getDirection() == AbstractInterface::Input) {
1055 groupInter = refInter->getConnectedFrom();
1056 refInter->clearConnectedFrom();
1057 groupInter->clearConnectedTo();
1059 else if (refInter->getDirection() == AbstractInterface::InOut) {
1060 groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
1061 refInter->clearConnectedTo();
1062 refInter->clearConnectedFrom();
1063 groupInter->clearConnectedTo();
1064 groupInter->clearConnectedFrom();
1067 cout << "done." << endl ;
1070 if (groupInter == NULL) {
1071 cerr << "abnormal case 1 while removing an interface item of a block, linked to a parent group" << endl;
1075 cout << "getting group interface item, and connection item ..." ;
1079 InterfaceItem* groupIfaceItem = parentItem->searchInterfaceByRef(groupInter);
1080 if (groupIfaceItem == NULL) {
1081 cerr << "abnormal case 2 while removing an interface item of a block, linked to a parent group" << endl;
1083 ConnectionItem* conn = parentItem->getScene()->searchConnectionItem(item,groupIfaceItem);
1085 cerr << "abnormal case 3 while removing an interface item of a block, linked to a parent group" << endl;
1088 cout << "done." << endl ;
1091 // removing the interface group item from the group item, and the connection item
1093 cout << "removing group interface item, and connection item ..." ;
1096 item->removeConnectionItem(conn);
1097 groupIfaceItem->removeConnectionItem(conn);
1098 parentItem->removeInterface(groupIfaceItem); // CAUTION : this deletes the interface item.
1099 parentItem->getScene()->removeConnectionItem(conn);
1101 cout << "done." << endl ;
1104 // removing the interface box item in the parent scene
1106 cout << "removing the inteeface item of box item in parent scene if needed ..." ;
1109 BoxItem* parent2Item = parentItem->getParentItem();
1110 if (parent2Item != NULL) {
1111 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
1112 parent2Item->removeInterface(group2IfaceItem);
1115 cout << "done." << endl ;
1118 // removing the interface group from the group
1120 cout << "removing group interface ..." ;
1122 parentGroup->removeInterface(groupInter);
1124 cout << "done." << endl ;
1128 void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
1129 static QString fctName = "Dispatcher::removeBlockInterface()";
1130 #ifdef DEBUG_FCTNAME
1131 cout << "call to " << qPrintable(fctName) << endl;
1134 /* first, remove all connections from item
1135 NB: if there is a connection to a group interface, then this
1136 method should not be called if the group interface is also
1137 connected to another interface. Normally, this is not possible
1138 because such a check is done when creating the contextual menu
1139 that allows to remove an interface.
1141 foreach(ConnectionItem* conn, item->connections) {
1142 removeConnection(conn);
1145 ConnectedInterface* ref = item->refInter;
1146 item->getOwner()->removeInterface(item);
1147 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1148 fun->removeInterface(ref);
1151 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
1152 static QString fctName = "Dispatcher::removeGroupInterface()";
1153 #ifdef DEBUG_FCTNAME
1154 cout << "call to " << qPrintable(fctName) << endl;
1157 /* NB: there is a single connection between item and another one that is owned
1158 by a BoxItem. Thus, we just have to find it and to call disconnectInterFromGroup();
1160 ConnectionItem* conn = item->connections.at(0);
1161 if (conn->getFromInterfaceItem() == item) {
1162 disconnectInterFromGroup(conn->getToInterfaceItem());
1165 disconnectInterFromGroup(conn->getFromInterfaceItem());
1169 QMap<int, QString> Dispatcher::getAllGroupNames() {
1171 QMap<int, QString> list;
1172 foreach(GroupWidget *group, groupList) {
1173 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1178 GroupScene* Dispatcher::getSceneById(int id) {
1179 foreach(GroupWidget *group, groupList){
1180 if(group->getScene()->getId() == id)
1181 return group->getScene();
1183 cout << "search scene by id :" << id << " :: not found..." << endl;
1187 GroupItem *Dispatcher::getGroupItemById(int id) {
1188 foreach(GroupWidget *group, groupList) {
1189 GroupScene* scene = group->getScene();
1190 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1192 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1196 BoxItem *Dispatcher::getBoxItemById(int id) {
1197 foreach(GroupWidget *group, groupList) {
1199 GroupScene* scene = group->getScene();
1200 foreach(BoxItem *item, scene->getBoxItems()){
1201 if(item->getId() == id){
1206 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1210 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1212 foreach(GroupWidget *group, groupList) {
1214 GroupScene* scene = group->getScene();
1216 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1217 if(item->getId() == id){
1221 foreach(BoxItem *block, scene->getBoxItems()){
1222 foreach(InterfaceItem *item, block->getInterfaces()){
1223 if(item->getId() == id){
1229 cout << "search interface by id :" << id << " :: not found..." << endl;