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 // test the ref1->ref2 connection
94 if ((ref1->canConnectTo(ref2)) && (ref2->canConnectFrom(ref1))) {
95 ref1->connectTo(ref2);
96 ref2->connectFrom(ref1);
99 // if the frist one did not work, test ref2->ref1
100 if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) {
101 ref2->connectTo(ref1);
102 ref1->connectFrom(ref2);
105 if ((ok1 == true) || (ok2 == true)) {
107 iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2);
110 params->unsaveModif = true;
117 void Dispatcher::unselectAllItems(int direction){
119 GroupScene *scene = params->getCurrentScene();
121 foreach(BoxItem* block, scene->getBoxItems()) {
122 block->setSelected(false);
123 block->setCurrentInterface(NULL);
125 scene->unselecteInterfaces();
129 void Dispatcher::setCurrentGroupWidget(GroupWidget *win){
131 win->changeConnectionMode(-1);
133 params->setCurrentScene(win->getScene());
136 void Dispatcher::changeConnectionMode(int mode){
139 foreach(GroupWidget* win, groupList){
141 QToolButton* buttonNewConnection = win->getButtonNewConnection();
143 QPalette pal = buttonNewConnection->palette();
146 if(params->sceneMode != Parameters::EditOnConnection){
147 params->sceneMode = Parameters::EditOnConnection;
148 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
150 params->sceneMode = Parameters::EditNoOperation;
151 pal.setColor(QPalette::Button, QColor("#edeceb"));
154 else if(mode == Parameters::EditOnConnection){
155 params->sceneMode = Parameters::EditOnConnection;
156 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
159 params->sceneMode = Parameters::EditNoOperation;
160 pal.setColor(QPalette::Button, QColor("#edeceb"));
162 unselectAllInterfaces();
164 buttonNewConnection->setAutoFillBackground(true);
165 buttonNewConnection->setPalette(pal);
166 buttonNewConnection->update();
171 void Dispatcher::renameFunctionalBlock(BoxItem *item){
172 static QString fctName = "Dispatcher::renameFunctionalBlock()";
174 cout << "call to " << qPrintable(fctName) << endl;
177 GroupWidget* win = item->getScene()->getGroupWidget();
182 text = QInputDialog::getText(win, "Rename a functional block",
183 "New name:", QLineEdit::Normal,
184 item->getRefBlock()->getName(), &ok);
187 if (text == item->getRefBlock()->getName()) return;
189 if( (text.isEmpty()) || (text.length() > 30)) {
190 QMessageBox::warning(win,"Error in given name",
191 "the block name must be shorter than 30 characters, cannot be empty",
196 FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
198 QMessageBox::warning(win,"Error in given name",
199 "the name provided is similar to that of another functional block within the group",
206 item->getRefBlock()->setName(text);
210 void Dispatcher::renameGroupBlock(GroupItem *item){
211 static QString fctName = "Dispatcher::renameGroupBlock()";
213 cout << "call to " << qPrintable(fctName) << endl;
216 GroupWidget* win = item->getScene()->getGroupWidget();
221 text = QInputDialog::getText(win, "Rename a group",
222 "New name:", QLineEdit::Normal,
223 item->getRefBlock()->getName(), &ok);
226 if (text == item->getRefBlock()->getName()) return;
228 if( (text.isEmpty()) || (text.length() > 30)) {
229 QMessageBox::warning(win,"Error in given name",
230 "the block name must be shorter than 30 characters, cannot be empty",
235 GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
237 QMessageBox::warning(win,"Error in given name",
238 "the name provided is similar to that of another group",
245 item->getRefBlock()->setName(text);
246 if(item->getScene()->getGroupWidget()->isTopGroup()) {
247 mainWindow->setWindowTitle("blast - "+text);
250 item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
253 mainWindow->getLibrary()->updateComboScene();
256 void Dispatcher::renameSourceBlock(SourceItem *item){
257 static QString fctName = "Dispatcher::renameSourceBlock()";
259 cout << "call to " << qPrintable(fctName) << endl;
262 GroupWidget* win = item->getScene()->getGroupWidget();
267 text = QInputDialog::getText(win, "Rename a source",
268 "New name:", QLineEdit::Normal,
269 item->getRefBlock()->getName(), &ok);
272 if (text == item->getRefBlock()->getName()) return;
274 if( (text.isEmpty()) || (text.length() > 30)) {
275 QMessageBox::warning(win,"Error in given name",
276 "the block name must be shorter than 30 characters, cannot be empty",
281 FunctionalBlock* block = params->getGraph()->getSourceBlockByName(text);
283 QMessageBox::warning(win,"Error in given name",
284 "the name provided is similar to that of another source block within the top group",
291 item->getRefBlock()->setName(text);
296 void Dispatcher::renameInterface(InterfaceItem *item) {
297 static QString fctName = "Dispatcher::renameInterface()";
299 cout << "call to " << qPrintable(fctName) << endl;
302 GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
307 text = QInputDialog::getText(win, "Rename an interface",
308 "New name:", QLineEdit::Normal,
309 item->refInter->getName(), &ok);
313 if (text == item->refInter->getName()) return;
315 if( (text.isEmpty()) || (text.length() > 30)) {
316 QMessageBox::warning(win,"Error in given name",
317 "the interface name must be shorter than 30 characters, cannot be empty",
322 AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
324 QMessageBox::warning(win,"Error in given name",
325 "the name provided is similar to that of another interface",
331 item->refInter->setName(text);
332 AbstractInterface* assoIface = item->refInter->getAssociatedIface();
333 if (assoIface != NULL) {
334 assoIface->setName(text+"_ctl");
336 item->updateName(text);
337 item->getOwner()->nameChanged();
340 void Dispatcher::duplicateBoxItem(BoxItem *item){
341 static QString fctName = "Dispatcher::duplicateBoxItem()";
343 cout << "call to " << qPrintable(fctName) << endl;
346 GroupScene *scene = item->getScene();
347 AbstractBlock* block = item->getRefBlock();
348 AbstractBlock *newBlock;
350 // only duplicate functional blocks
351 if(block->isFunctionalBlock()) {
353 // adding to the model
354 FunctionalBlock* funBlock = (FunctionalBlock*)block;
355 newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
356 // adding to the view
357 scene->createBoxItem(newBlock);
359 params->unsaveModif = true;
363 void Dispatcher::duplicateSourceItem(SourceItem *item) {
364 static QString fctName = "Dispatcher::duplicateSourceItem()";
366 cout << "call to " << qPrintable(fctName) << endl;
369 GroupScene *scene = item->getScene();
370 AbstractBlock* block = item->getRefBlock();
371 AbstractBlock *newBlock;
373 // only duplicate functional blocks
374 if(block->isFunctionalBlock()) {
376 // adding to the model
377 FunctionalBlock* funBlock = (FunctionalBlock*)block;
378 newBlock = params->getGraph()->duplicateSourceBlock(funBlock);
379 // adding to the view
380 scene->createSourceItem(newBlock);
382 params->unsaveModif = true;
386 void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
387 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
389 cout << "call to " << qPrintable(fctName) << endl;
392 AbstractInterface *refI = item->refInter;
393 if (! refI->isFunctionalInterface()) return;
395 AbstractBlock *refB = refI->getOwner();
396 if(! refB->isFunctionalBlock()) return;
398 FunctionalInterface* iface = (FunctionalInterface*)refI;
399 AbstractInterface *cloneIface = iface->clone();
400 if (cloneIface == NULL) {
401 QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
405 refB->addInterface(cloneIface);
407 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
408 item->getOwner()->addInterface(cloneIfaceItem,true);
410 // creating control interface if needed
411 if (refI->getAssociatedIface() != NULL) {
412 QString ctlName = cloneIface->getName()+"_ctl";
413 ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,"boolean","1",cloneIface->getDirection(), AbstractInterface::Control, 1);
414 refB->addInterface(ctlIface);
415 if (! ctlIface->setAssociatedIface(cloneIface)) {
416 cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
422 void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
423 static QString fctName = "Dispatcher::addBlock()";
425 cout << "call to " << qPrintable(fctName) << endl;
427 bool newSource = false;
428 GroupScene *scene = getSceneById(idScene);
429 ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
430 // if block has no inputs, propose to add it as a source to top scene
431 if ((scene->isTopScene()) && (ref->getDataInputs().isEmpty())) {
432 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 ?");
433 if (ret == QMessageBox::Yes) {
438 FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref);
439 scene->createSourceItem(newOne);
442 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
443 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
444 scene->createBoxItem(newOne);
446 params->unsaveModif = true;
450 GroupWidget *Dispatcher::createTopScene(){
451 static QString fctName = "Dispatcher::createTopScene()";
453 cout << "call to " << qPrintable(fctName) << endl;
456 // creating the model part of the group
457 Graph* graph = params->createGraph();
458 GroupBlock *refBlock = graph->getTopGroup();
460 // creating a fake and not connected interface
461 //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
463 // creating the group widget
464 topGroup = new GroupWidget(NULL,this,params);
465 currentGroup = topGroup;
466 // getting the newly created scene
467 GroupScene *scene = topGroup->getScene();
468 scene->setId(sceneCounter++);
469 params->setTopScene(scene);
470 params->setCurrentScene(scene);
471 // creating the view part of the group
472 GroupItem *group = new GroupItem(NULL,refBlock,this,params);
474 // adding the fake interface to the top group item
475 //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
476 //group->addInterface(item,true);
478 scene->setGroupItem(group);
480 groupList.append(topGroup);
484 GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
485 static QString fctName = "Dispatcher::addNewEmptyGroup();";
487 cout << "call to " << qPrintable(fctName) << endl;
490 // getting the parent block in the graph
491 GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
492 cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
493 GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent);
494 cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
495 // creating the BlockItem in the scene
496 BoxItem* newItem = scene->createBoxItem(groupBlock);
498 params->unsaveModif = true;
500 GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
501 if (show) child->show();
506 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
507 static QString fctName = "Dispatcher::createChildScene()";
509 cout << "call to " << qPrintable(fctName) << endl;
512 GroupWidget* group = NULL;
513 /* NB: this method may be called during design process or when loading
514 a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
515 cannot be initialized yet. This is why there are 2 cases below
518 if (upperItemOfGroupItem != NULL) {
519 // getting back the goup block already created
520 GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
521 // creating the view part of the group
522 GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
523 // creating the group widget
524 group = new GroupWidget(parentWidget, this, params);
525 // getting the newly created scene
526 GroupScene *scene = group->getScene();
527 scene->setId(sceneCounter++);
528 // affecting group item to the scene
529 scene->setGroupItem(groupItem);
530 groupList.append(group);
532 mainWindow->getLibrary()->updateComboScene();
535 GroupItem *groupItem = new GroupItem(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 // affecting group item to the scene
541 scene->setGroupItem(groupItem);
542 groupList.append(group);
547 void Dispatcher::destroyScene(GroupScene *scene) {
548 foreach(GroupScene* s, scene->getChildrenScene()) {
552 if (scene->getNbChildScene() == 0) {
553 // remove scene from the parent list, if possible
554 if (scene->getParentScene() != NULL) {
555 scene->getParentScene()->removeChildScene(scene);
557 // destroy the GroupWidget
558 groupList.removeAll(scene->getGroupWidget());
559 scene->getGroupWidget()->deleteLater();
562 cerr << "Abnormal case when destroying a scene" << endl;
566 void Dispatcher::showRaiseWindow(BoxItem *item) {
567 static QString fctName = "Dispatcher::showRaiseWindow()";
569 cout << "call to " << qPrintable(fctName) << endl;
572 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
573 GroupItem* child = item->getChildGroupItem();
575 cerr << "abnormal case: child group item is null " << endl;
579 GroupWidget* win = child->getScene()->getGroupWidget();
583 win->activateWindow();
586 params->setCurrentScene(currentGroup->getScene());
589 void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
590 static QString fctName = "Dispatcher::showRstClkIface()";
592 cout << "call to " << qPrintable(fctName) << endl;
595 item->setRstClkVisible(!item->isRstClkVisible());
599 void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
600 static QString fctName = "Dispatcher::showWishboneIface()";
602 cout << "call to " << qPrintable(fctName) << endl;
605 item->setWishboneVisible(!item->isWishboneVisible());
608 void Dispatcher::addNewFullGroup() {
609 static QString fctName = "Dispatcher::addNewFullGroup()";
611 cout << "call to " << qPrintable(fctName) << endl;
617 QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
618 QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
619 QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
621 /* What must be done:
622 1 - creating a new GroupBlock
623 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
624 3 - creating a BlockItem that references the new GroupBlock
625 4 - creating a new GroupWidget
626 5 - creating a new GroupItem added to the scene of the GroupWidget
630 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
631 associated to the GroupItem of the current scene
633 GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
634 GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
635 /* step 2: moving selected blocks */
636 foreach(BlockItem* blockItem, listBlocks) {
637 parentBlock->removeBlock(blockItem->getRefBlock());
638 newGroupBlock->addBlock(blockItem->getRefBlock());
641 GroupItem *parent = currentGroup->getScene()->getGroupItem();
642 GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
643 BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
644 GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
646 //create the new window
647 GroupWidget* win = new GroupWidget(this,params);
648 win->getScene()->setGroupItem(groupItem);
649 win->getScene()->addItem(groupItem);
650 ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
651 params->addWindow(win);
655 params->getCurrentScene()->addBlockItem(blockItem);
656 params->getCurrentScene()->addItem(blockItem);
657 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
659 //replace selected blocks in the group
660 foreach(AbstractBoxItem *block, listBlocks){
661 ((GroupItem*)block->getParentItem())->removeBlockItem(block);
662 ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
663 params->getCurrentScene()->removeItem(block);
664 params->getCurrentScene()->removeBlockItem(block);
666 groupBlock->addBlock(block->getRefBlock());
667 listAbstractBlocks.append(block->getRefBlock());
669 block->setUpperItem(groupItem);
670 groupItem->addBlockItem(block);
671 win->getScene()->addItem(block);
672 win->getScene()->addBlockItem(block);
675 //replace connection between selected blocks in the group
676 foreach(ConnectionItem *conn, connections){
677 if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
678 if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
679 parent->removeConnection(conn);
680 params->getCurrentScene()->removeItem(conn);
682 groupItem->addConnection(conn);
683 win->getScene()->addItem(conn);
688 //create new interfaces and connections for the new group
689 foreach(AbstractBoxItem *block, listBlocks){
690 foreach(InterfaceItem *inter, block->getInterfaces()){
691 cout << "inter : " << inter->getName().toStdString() << endl;
692 if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
693 cout << "connected from non null" << endl;
694 if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
696 AbstractInterface *iface = inter->refInter->clone(0);
697 iface->setName(iface->getName()+"_group");
698 groupBlock->addInterface(iface);
700 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
701 blockItem->addInterface(ifaceItem);
702 blockItem->resetInterfacesPosition();
704 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
705 groupItem->addInterface(ifaceGroupItem);
706 groupItem->resetInterfacesPosition();
707 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
708 if(conn->getToInterfaceItem() == inter){
709 conn->setToInterfaceItem(ifaceItem);
710 ifaceItem->refInter->setConnectedFrom(NULL);
711 conn->getFromInterfaceItem()->refInter->clearConnectedTo();
712 connect(ifaceItem,conn->getFromInterfaceItem());
715 params->setCurrentWindow(win);
717 inter->refInter->setConnectedFrom(NULL);
718 ifaceGroupItem->refInter->clearConnectedTo();
719 connect(inter,ifaceGroupItem);
720 params->setCurrentWindow(mainWindow);
724 if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
725 cout << "connected to non null" << endl;
726 foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
727 if(!listAbstractBlocks.contains(iface->getOwner())){
729 AbstractInterface *iface = inter->refInter->clone(0);
730 iface->setName(iface->getName()+"_group");
731 groupBlock->addInterface(iface);
733 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
734 blockItem->addInterface(ifaceItem);
735 blockItem->resetInterfacesPosition();
737 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
738 if(conn->getFromInterfaceItem() == inter){
739 conn->setFromInterfaceItem(ifaceItem);
740 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
741 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
745 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
746 groupItem->addInterface(ifaceGroupItem);
747 groupItem->resetInterfacesPosition();
748 inter->refInter->clearConnectedTo();
749 ifaceGroupItem->refInter->setConnectedFrom(NULL);
750 connect(ifaceGroupItem,inter);
759 parent->updateShape();
760 currentGroup->getScene()->updateConnectionItemsShape();
762 groupItem->updateShape();
763 win->getScene()->updateConnectionItemsShape();
764 groupItem->update(groupItem->boundingRect());
769 void Dispatcher::removeBoxItem(BoxItem *item) {
770 static QString fctName = "Dispatcher::removeBoxItem()";
772 cout << "call to " << qPrintable(fctName) << endl;
775 /* a BoxItem (group of func) can be removed only if none of its
776 interfaces is connected to a group interface that is itself
777 connected to another one.
779 bool canRemove = true;
781 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
782 foreach(ConnectionItem* conn, ifaceItem->connections) {
783 InterfaceItem* other = NULL;
784 if (conn->getFromInterfaceItem() == ifaceItem) {
785 other = conn->getToInterfaceItem();
788 other = conn->getFromInterfaceItem();
791 if (other->getOwner()->isGroupItem()) {
792 ConnectedInterface* ref = other->refInter;
793 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
800 QMessageBox::warning(NULL,"Forbidden operation",
801 "The block has at least one connection to a group interface that is totally connected.",
807 if (item->getRefBlock()->isFunctionalBlock()) {
808 msg = "Removing block ";
811 msg = "Removing group ";
813 msg += item->getRefBlock()->getName();
814 msg += " and all its connections.\n\nAre you sure ?";
816 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
817 if (ret == QMessageBox::Cancel) {
820 removeAllBlockConnections(item);
822 if (item->getRefBlock()->isFunctionalBlock()) {
823 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
824 GroupBlock* group = AB_TO_GRP(block->getParent());
825 item->getScene()->removeBoxItem(item);
826 params->getGraph()->removeFunctionalBlock(block);
828 else if (item->getRefBlock()->isGroupBlock()) {
830 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
832 // remove all child scenes recursively
833 GroupItem* subgroup = item->getChildGroupItem();
834 destroyScene(subgroup->getScene());
835 // remove the BoxItem
836 item->getScene()->removeBoxItem(item);
837 // remove the group from the graph
838 params->getGraph()->removeGroupBlock(group);
842 void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
843 static QString fctName = "Dispatcher::removeAllBlockConnection()";
845 cout << "call to " << qPrintable(fctName) << endl;
848 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
849 foreach(ConnectionItem* conn, ifaceItem->connections) {
850 removeConnection(conn);
855 void Dispatcher::removeSourceItem(SourceItem *item) {
856 static QString fctName = "Dispatcher::removeSourceItem()";
858 cout << "call to " << qPrintable(fctName) << endl;
861 QString msg = "Removing source ";
863 msg += item->getRefBlock()->getName();
864 msg += " and all its connections.\n\nAre you sure ?";
866 int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
867 if (ret == QMessageBox::Cancel) {
870 removeAllBlockConnections(item);
872 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
873 item->getScene()->removeSourceItem(item);
874 params->getGraph()->removeSourceBlock(block);
878 void Dispatcher::removeConnection(ConnectionItem *conn) {
879 static QString fctName = "Dispatcher::removeConnection()";
881 cout << "call to " << qPrintable(fctName) << endl;
883 InterfaceItem* fromIfaceItem = conn->getFromInterfaceItem();
884 InterfaceItem* toIfaceItem = conn->getToInterfaceItem();
887 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
890 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem
891 GroupItem* groupItem = NULL;
893 ConnectedInterface *fromInter = fromIfaceItem->refInter;
894 ConnectedInterface *toInter = toIfaceItem->refInter;
895 // process the speical case source->group apart
896 if (fromIfaceItem->getOwner()->isSourceItem()) {
898 fromInter->removeConnectedTo(toInter);
899 toInter->clearConnectedFrom();
901 fromIfaceItem->removeConnectionItem(conn);
902 toIfaceItem->removeConnectionItem(conn);
903 groupItem->getScene()->removeConnectionItem(conn);
908 if (fromIfaceItem->getOwner()->isGroupItem()) {
909 groupIfaceItem = fromIfaceItem;
910 groupItem = toIfaceItem->getOwner()->getScene()->getGroupItem();
912 else if (toIfaceItem->getOwner()->isGroupItem()) {
913 groupIfaceItem = toIfaceItem;
914 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
917 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
920 // removing the connection from graph
922 cout << "removing connections from graph ..." ;
924 if (fromInter->getDirection() == AbstractInterface::InOut) {
925 fromInter->clearConnectedTo();
926 fromInter->clearConnectedFrom();
927 toInter->clearConnectedTo();
928 toInter->clearConnectedFrom();
931 fromInter->removeConnectedTo(toInter);
932 toInter->clearConnectedFrom();
935 cout << "done." << endl ;
938 // removing the connection from scene
940 cout << "removing connections from scene ..." ;
942 fromIfaceItem->removeConnectionItem(conn);
943 toIfaceItem->removeConnectionItem(conn);
944 groupItem->getScene()->removeConnectionItem(conn);
947 cout << "done." << endl ;
950 if (groupIfaceItem != NULL) {
951 ConnectedInterface* groupInter = groupIfaceItem->refInter;
952 groupItem->removeInterface(groupIfaceItem);
954 BoxItem* parent2Item = groupItem->getParentItem();
955 if (parent2Item != NULL) {
956 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
957 parent2Item->removeInterface(group2IfaceItem);
959 groupInter->getOwner()->removeInterface(groupInter);
963 void Dispatcher::showBlocksLibrary(){
964 cout << "showing block library" << endl;
965 mainWindow->getLibrary()->show();
966 mainWindow->getLibrary()->raise();
969 void Dispatcher::showProperties(InterfaceItem *inter)
971 new InterfacePropertiesWindow(inter);
974 /* connectInterToGroup() :
975 The only way for a block (functional of group) within a GroupItem to be connected
976 to the latter is to right-click on one of its interfaces and to choose "connect to group".
977 That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
980 void Dispatcher::connectInterToGroup(InterfaceItem *item){
982 // getting the GroupBlock and GroupItem that are parent of the block that owns item
983 ConnectedInterface *refInter = item->refInter;
984 cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
985 GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
986 cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
987 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
989 // creating/adding the group interface in the graph model
990 GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
991 groupInter->setType(refInter->getType());
992 groupInter->setWidth(refInter->getWidth());
993 groupInter->setPurpose(refInter->getPurpose());
994 parentItem->getRefBlock()->addInterface(groupInter);
996 // connect both interface
998 if (refInter->getDirection() == AbstractInterface::Output) {
999 ok = refInter->connectTo(groupInter);
1000 ok = ok & groupInter->connectFrom(refInter);
1002 else if (refInter->getDirection() == AbstractInterface::Input) {
1003 ok = groupInter->connectTo(refInter);
1004 ok = ok & refInter->connectFrom(groupInter);
1006 else if (refInter->getDirection() == AbstractInterface::InOut) {
1007 ok = refInter->connectTo(groupInter);
1008 ok = ok & groupInter->connectFrom(refInter);
1009 ok = ok & groupInter->connectTo(refInter);
1010 ok = ok & refInter->connectFrom(groupInter);
1013 cerr << "abnormal case while connecting a block iface to its parent group" << endl;
1015 // creating/adding the group interface in the current scene model, and connection item
1016 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1017 parentItem->addInterface(groupIfaceItem,true);
1019 parentItem->getScene()->createConnectionItem(item, groupIfaceItem);
1021 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1022 BoxItem* parent2Item = parentItem->getParentItem();
1023 if(parent2Item != NULL){
1024 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1025 parent2Item->addInterface(blockIfaceItem,true);
1029 parentItem->getScene()->updateConnectionItemsShape();
1031 params->unsaveModif = true;
1036 void Dispatcher::disconnectInterFromGroup(InterfaceItem *item) {
1037 static QString fctName = "Dispatcher::disconnectInterFromGroup()";
1038 #ifdef DEBUG_FCTNAME
1039 cout << "call to " << qPrintable(fctName) << endl;
1042 // getting the GroupBlock and GroupItem that are parent of the block that owns item
1043 ConnectedInterface *refInter = item->refInter;
1044 ConnectedInterface *groupInter = NULL;
1045 GroupBlock* parentGroup = AB_TO_GRP(refInter->getOwner()->getParent());
1046 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
1048 // removing the connection from graph
1050 cout << "removing connections from graph ..." ;
1053 if (refInter->getDirection() == AbstractInterface::Output) {
1054 groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
1055 refInter->removeConnectedTo(groupInter);
1056 groupInter->clearConnectedFrom();
1058 else if (refInter->getDirection() == AbstractInterface::Input) {
1059 groupInter = refInter->getConnectedFrom();
1060 refInter->clearConnectedFrom();
1061 groupInter->clearConnectedTo();
1063 else if (refInter->getDirection() == AbstractInterface::InOut) {
1064 groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
1065 refInter->clearConnectedTo();
1066 refInter->clearConnectedFrom();
1067 groupInter->clearConnectedTo();
1068 groupInter->clearConnectedFrom();
1071 cout << "done." << endl ;
1074 if (groupInter == NULL) {
1075 cerr << "abnormal case 1 while removing an interface item of a block, linked to a parent group" << endl;
1079 cout << "getting group interface item, and connection item ..." ;
1083 InterfaceItem* groupIfaceItem = parentItem->searchInterfaceByRef(groupInter);
1084 if (groupIfaceItem == NULL) {
1085 cerr << "abnormal case 2 while removing an interface item of a block, linked to a parent group" << endl;
1087 ConnectionItem* conn = parentItem->getScene()->searchConnectionItem(item,groupIfaceItem);
1089 cerr << "abnormal case 3 while removing an interface item of a block, linked to a parent group" << endl;
1092 cout << "done." << endl ;
1095 // removing the interface group item from the group item, and the connection item
1097 cout << "removing group interface item, and connection item ..." ;
1100 item->removeConnectionItem(conn);
1101 groupIfaceItem->removeConnectionItem(conn);
1102 parentItem->removeInterface(groupIfaceItem); // CAUTION : this deletes the interface item.
1103 parentItem->getScene()->removeConnectionItem(conn);
1105 cout << "done." << endl ;
1108 // removing the interface box item in the parent scene
1110 cout << "removing the inteeface item of box item in parent scene if needed ..." ;
1113 BoxItem* parent2Item = parentItem->getParentItem();
1114 if (parent2Item != NULL) {
1115 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
1116 parent2Item->removeInterface(group2IfaceItem);
1119 cout << "done." << endl ;
1122 // removing the interface group from the group
1124 cout << "removing group interface ..." ;
1126 parentGroup->removeInterface(groupInter);
1128 cout << "done." << endl ;
1132 void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
1133 static QString fctName = "Dispatcher::removeBlockInterface()";
1134 #ifdef DEBUG_FCTNAME
1135 cout << "call to " << qPrintable(fctName) << endl;
1138 /* first, remove all connections from item
1139 NB: if there is a connection to a group interface, then this
1140 method should not be called if the group interface is also
1141 connected to another interface. Normally, this is not possible
1142 because such a check is done when creating the contextual menu
1143 that allows to remove an interface.
1145 foreach(ConnectionItem* conn, item->connections) {
1146 removeConnection(conn);
1149 ConnectedInterface* ref = item->refInter;
1150 item->getOwner()->removeInterface(item);
1151 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1152 fun->removeInterface(ref);
1155 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
1156 static QString fctName = "Dispatcher::removeGroupInterface()";
1157 #ifdef DEBUG_FCTNAME
1158 cout << "call to " << qPrintable(fctName) << endl;
1161 /* NB: there is a single connection between item and another one that is owned
1162 by a BoxItem. Thus, we just have to find it and to call disconnectInterFromGroup();
1164 ConnectionItem* conn = item->connections.at(0);
1165 if (conn->getFromInterfaceItem() == item) {
1166 disconnectInterFromGroup(conn->getToInterfaceItem());
1169 disconnectInterFromGroup(conn->getFromInterfaceItem());
1173 QMap<int, QString> Dispatcher::getAllGroupNames() {
1175 QMap<int, QString> list;
1176 foreach(GroupWidget *group, groupList) {
1177 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1182 GroupScene* Dispatcher::getSceneById(int id) {
1183 foreach(GroupWidget *group, groupList){
1184 if(group->getScene()->getId() == id)
1185 return group->getScene();
1187 cout << "search scene by id :" << id << " :: not found..." << endl;
1191 GroupItem *Dispatcher::getGroupItemById(int id) {
1192 foreach(GroupWidget *group, groupList) {
1193 GroupScene* scene = group->getScene();
1194 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1196 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1200 BoxItem *Dispatcher::getBoxItemById(int id) {
1201 foreach(GroupWidget *group, groupList) {
1203 GroupScene* scene = group->getScene();
1204 foreach(BoxItem *item, scene->getBoxItems()){
1205 if(item->getId() == id){
1210 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1214 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1216 foreach(GroupWidget *group, groupList) {
1218 GroupScene* scene = group->getScene();
1220 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1221 if(item->getId() == id){
1225 foreach(BoxItem *block, scene->getBoxItems()){
1226 foreach(InterfaceItem *item, block->getInterfaces()){
1227 if(item->getId() == id){
1233 cout << "search interface by id :" << id << " :: not found..." << endl;