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 // connect both interface
93 // test the ref1->ref2 connection
94 if ((ref1->canConnectTo(ref2)) && (ref2->canConnectFrom(ref1))) {
95 ref1->connectTo(ref2);
98 // if the frist one did not work, test ref2->ref1
99 if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) {
100 ref2->connectTo(ref1);
103 if ((ok1 == true) || (ok2 == true)) {
105 iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2);
108 params->unsaveModif = true;
109 cout << "created a connection from " << qPrintable(ref1->getName()) << " to " << qPrintable(ref2->getName()) << endl;
116 void Dispatcher::unselectAllItems(int direction){
118 GroupScene *scene = params->getCurrentScene();
120 foreach(BoxItem* block, scene->getBoxItems()) {
121 block->setSelected(false);
122 block->setCurrentInterface(NULL);
124 scene->unselecteInterfaces();
128 void Dispatcher::setCurrentGroupWidget(GroupWidget *win){
130 win->changeConnectionMode(-1);
132 params->setCurrentScene(win->getScene());
135 void Dispatcher::changeConnectionMode(int mode){
138 foreach(GroupWidget* win, groupList){
140 QToolButton* buttonNewConnection = win->getButtonNewConnection();
142 QPalette pal = buttonNewConnection->palette();
145 if(params->sceneMode != Parameters::EditOnConnection){
146 params->sceneMode = Parameters::EditOnConnection;
147 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
149 params->sceneMode = Parameters::EditNoOperation;
150 pal.setColor(QPalette::Button, QColor("#edeceb"));
153 else if(mode == Parameters::EditOnConnection){
154 params->sceneMode = Parameters::EditOnConnection;
155 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
158 params->sceneMode = Parameters::EditNoOperation;
159 pal.setColor(QPalette::Button, QColor("#edeceb"));
161 unselectAllInterfaces();
163 buttonNewConnection->setAutoFillBackground(true);
164 buttonNewConnection->setPalette(pal);
165 buttonNewConnection->update();
170 void Dispatcher::renameFunctionalBlock(BoxItem *item){
171 static QString fctName = "Dispatcher::renameFunctionalBlock()";
173 cout << "call to " << qPrintable(fctName) << endl;
176 GroupWidget* win = item->getScene()->getGroupWidget();
181 text = QInputDialog::getText(win, "Rename a functional block",
182 "New name:", QLineEdit::Normal,
183 item->getRefBlock()->getName(), &ok);
186 if (text == item->getRefBlock()->getName()) return;
188 if( (text.isEmpty()) || (text.length() > 30)) {
189 QMessageBox::warning(win,"Error in given name",
190 "the block name must be shorter than 30 characters, cannot be empty",
195 FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
197 QMessageBox::warning(win,"Error in given name",
198 "the name provided is similar to that of another functional block within the group",
205 item->getRefBlock()->setName(text);
209 void Dispatcher::renameGroupBlock(GroupItem *item){
210 static QString fctName = "Dispatcher::renameGroupBlock()";
212 cout << "call to " << qPrintable(fctName) << endl;
215 GroupWidget* win = item->getScene()->getGroupWidget();
220 text = QInputDialog::getText(win, "Rename a group",
221 "New name:", QLineEdit::Normal,
222 item->getRefBlock()->getName(), &ok);
225 if (text == item->getRefBlock()->getName()) return;
227 if( (text.isEmpty()) || (text.length() > 30)) {
228 QMessageBox::warning(win,"Error in given name",
229 "the block name must be shorter than 30 characters, cannot be empty",
234 GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
236 QMessageBox::warning(win,"Error in given name",
237 "the name provided is similar to that of another group",
244 item->getRefBlock()->setName(text);
245 if(item->getScene()->getGroupWidget()->isTopGroup()) {
246 mainWindow->setWindowTitle("blast - "+text);
249 item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
252 mainWindow->getLibrary()->updateComboScene();
255 void Dispatcher::renameSourceBlock(SourceItem *item){
256 static QString fctName = "Dispatcher::renameSourceBlock()";
258 cout << "call to " << qPrintable(fctName) << endl;
261 GroupWidget* win = item->getScene()->getGroupWidget();
266 text = QInputDialog::getText(win, "Rename a source",
267 "New name:", QLineEdit::Normal,
268 item->getRefBlock()->getName(), &ok);
271 if (text == item->getRefBlock()->getName()) return;
273 if( (text.isEmpty()) || (text.length() > 30)) {
274 QMessageBox::warning(win,"Error in given name",
275 "the block name must be shorter than 30 characters, cannot be empty",
280 FunctionalBlock* block = params->getGraph()->getSourceBlockByName(text);
282 QMessageBox::warning(win,"Error in given name",
283 "the name provided is similar to that of another source block within the top group",
290 item->getRefBlock()->setName(text);
295 void Dispatcher::renameInterface(InterfaceItem *item) {
296 static QString fctName = "Dispatcher::renameInterface()";
298 cout << "call to " << qPrintable(fctName) << endl;
301 GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
306 text = QInputDialog::getText(win, "Rename an interface",
307 "New name:", QLineEdit::Normal,
308 item->refInter->getName(), &ok);
312 if (text == item->refInter->getName()) return;
314 if( (text.isEmpty()) || (text.length() > 30)) {
315 QMessageBox::warning(win,"Error in given name",
316 "the interface name must be shorter than 30 characters, cannot be empty",
321 AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
323 QMessageBox::warning(win,"Error in given name",
324 "the name provided is similar to that of another interface",
330 item->refInter->setName(text);
331 AbstractInterface* assoIface = item->refInter->getAssociatedIface();
332 if (assoIface != NULL) {
333 assoIface->setName(text+"_enb");
335 item->updateName(text);
336 item->getOwner()->nameChanged();
339 void Dispatcher::showPatterns(InterfaceItem *item) {
340 static QString fctName = "Dispatcher::showPatterns()";
342 cout << "call to " << qPrintable(fctName) << endl;
344 ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
345 foreach(char c, *(iface->getOutputPattern())) {
351 void Dispatcher::duplicateBoxItem(BoxItem *item){
352 static QString fctName = "Dispatcher::duplicateBoxItem()";
354 cout << "call to " << qPrintable(fctName) << endl;
357 GroupScene *scene = item->getScene();
358 AbstractBlock* block = item->getRefBlock();
359 AbstractBlock *newBlock;
361 // only duplicate functional blocks
362 if(block->isFunctionalBlock()) {
364 // adding to the model
365 FunctionalBlock* funBlock = (FunctionalBlock*)block;
366 newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
367 // adding to the view
368 scene->createBoxItem(newBlock);
370 params->unsaveModif = true;
374 void Dispatcher::duplicateSourceItem(SourceItem *item) {
375 static QString fctName = "Dispatcher::duplicateSourceItem()";
377 cout << "call to " << qPrintable(fctName) << endl;
380 GroupScene *scene = item->getScene();
381 AbstractBlock* block = item->getRefBlock();
382 AbstractBlock *newBlock;
384 // only duplicate functional blocks
385 if(block->isFunctionalBlock()) {
387 // adding to the model
388 FunctionalBlock* funBlock = (FunctionalBlock*)block;
389 newBlock = params->getGraph()->duplicateSourceBlock(funBlock);
390 // adding to the view
391 scene->createSourceItem(newBlock);
393 params->unsaveModif = true;
397 void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
398 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
400 cout << "call to " << qPrintable(fctName) << endl;
403 AbstractInterface *refI = item->refInter;
404 if (! refI->isFunctionalInterface()) return;
406 AbstractBlock *refB = refI->getOwner();
407 if(! refB->isFunctionalBlock()) return;
409 FunctionalInterface* iface = (FunctionalInterface*)refI;
410 AbstractInterface *cloneIface = iface->clone();
411 if (cloneIface == NULL) {
412 QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
416 refB->addInterface(cloneIface);
418 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
419 item->getOwner()->addInterfaceItem(cloneIfaceItem,true);
421 // creating control interface if needed
422 if (refI->getAssociatedIface() != NULL) {
423 QString ctlName = cloneIface->getName()+"_enb";
424 ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,cloneIface->getDirection(), AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
425 refB->addInterface(ctlIface);
426 if (! ctlIface->setAssociatedIface(cloneIface)) {
427 cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
433 void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
434 static QString fctName = "Dispatcher::addBlock()";
436 cout << "call to " << qPrintable(fctName) << endl;
438 bool newSource = false;
439 GroupScene *scene = getSceneById(idScene);
440 ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
441 // if block has no inputs, propose to add it as a source to top scene
442 if ((scene->isTopScene()) && (ref->isGeneratorBlock())) {
443 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 ?");
444 if (ret == QMessageBox::Yes) {
449 FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref);
450 scene->createSourceItem(newOne);
453 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
454 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
455 scene->createBoxItem(newOne);
457 params->unsaveModif = true;
461 GroupWidget *Dispatcher::createTopScene(){
462 static QString fctName = "Dispatcher::createTopScene()";
464 cout << "call to " << qPrintable(fctName) << endl;
467 // creating the model part of the group
468 Graph* graph = params->createGraph();
469 GroupBlock *refBlock = graph->getTopGroup();
471 // creating a fake and not connected interface
472 //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
474 // creating the group widget
475 topGroup = new GroupWidget(NULL,this,params);
476 currentGroup = topGroup;
477 // getting the newly created scene
478 GroupScene *scene = topGroup->getScene();
479 scene->setId(sceneCounter++);
480 params->setTopScene(scene);
481 params->setCurrentScene(scene);
482 // creating the view part of the group
483 GroupItem *group = new GroupItem(NULL,refBlock,this,params);
485 // adding the fake interface to the top group item
486 //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
487 //group->addInterface(item,true);
489 scene->setGroupItem(group);
491 groupList.append(topGroup);
495 GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
496 static QString fctName = "Dispatcher::addNewEmptyGroup();";
498 cout << "call to " << qPrintable(fctName) << endl;
501 // getting the parent block in the graph
502 GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
503 cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
504 GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent);
505 cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
506 // creating the BlockItem in the scene
507 BoxItem* newItem = scene->createBoxItem(groupBlock);
509 params->unsaveModif = true;
511 GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
512 if (show) child->show();
517 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
518 static QString fctName = "Dispatcher::createChildScene()";
520 cout << "call to " << qPrintable(fctName) << endl;
523 GroupWidget* group = NULL;
524 /* NB: this method may be called during design process or when loading
525 a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
526 cannot be initialized yet. This is why there are 2 cases below
529 if (upperItemOfGroupItem != NULL) {
530 // getting back the goup block already created
531 GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
532 // creating the view part of the group
533 GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
534 // creating the group widget
535 group = new GroupWidget(parentWidget, this, params);
536 // getting the newly created scene
537 GroupScene *scene = group->getScene();
538 scene->setId(sceneCounter++);
539 // affecting group item to the scene
540 scene->setGroupItem(groupItem);
541 groupList.append(group);
543 mainWindow->getLibrary()->updateComboScene();
546 GroupItem *groupItem = new GroupItem(this,params);
547 // creating the group widget
548 group = new GroupWidget(parentWidget, this, params);
549 // getting the newly created scene
550 GroupScene *scene = group->getScene();
551 // affecting group item to the scene
552 scene->setGroupItem(groupItem);
553 groupList.append(group);
558 void Dispatcher::destroyScene(GroupScene *scene) {
559 foreach(GroupScene* s, scene->getChildrenScene()) {
563 if (scene->getNbChildScene() == 0) {
564 // remove scene from the parent list, if possible
565 if (scene->getParentScene() != NULL) {
566 scene->getParentScene()->removeChildScene(scene);
568 // destroy the GroupWidget
569 groupList.removeAll(scene->getGroupWidget());
570 scene->getGroupWidget()->deleteLater();
573 cerr << "Abnormal case when destroying a scene" << endl;
577 void Dispatcher::showRaiseWindow(BoxItem *item) {
578 static QString fctName = "Dispatcher::showRaiseWindow()";
580 cout << "call to " << qPrintable(fctName) << endl;
583 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
584 GroupItem* child = item->getChildGroupItem();
586 cerr << "abnormal case: child group item is null " << endl;
590 GroupWidget* win = child->getScene()->getGroupWidget();
594 win->activateWindow();
597 params->setCurrentScene(currentGroup->getScene());
600 void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
601 static QString fctName = "Dispatcher::showRstClkIface()";
603 cout << "call to " << qPrintable(fctName) << endl;
606 item->setRstClkVisible(!item->isRstClkVisible());
610 void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
611 static QString fctName = "Dispatcher::showWishboneIface()";
613 cout << "call to " << qPrintable(fctName) << endl;
616 item->setWishboneVisible(!item->isWishboneVisible());
619 void Dispatcher::addNewFullGroup() {
620 static QString fctName = "Dispatcher::addNewFullGroup()";
622 cout << "call to " << qPrintable(fctName) << endl;
628 QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
629 QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
630 QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
632 /* What must be done:
633 1 - creating a new GroupBlock
634 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
635 3 - creating a BlockItem that references the new GroupBlock
636 4 - creating a new GroupWidget
637 5 - creating a new GroupItem added to the scene of the GroupWidget
641 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
642 associated to the GroupItem of the current scene
644 GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
645 GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
646 /* step 2: moving selected blocks */
647 foreach(BlockItem* blockItem, listBlocks) {
648 parentBlock->removeBlock(blockItem->getRefBlock());
649 newGroupBlock->addBlock(blockItem->getRefBlock());
652 GroupItem *parent = currentGroup->getScene()->getGroupItem();
653 GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
654 BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
655 GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
657 //create the new window
658 GroupWidget* win = new GroupWidget(this,params);
659 win->getScene()->setGroupItem(groupItem);
660 win->getScene()->addItem(groupItem);
661 ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
662 params->addWindow(win);
666 params->getCurrentScene()->addBlockItem(blockItem);
667 params->getCurrentScene()->addItem(blockItem);
668 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
670 //replace selected blocks in the group
671 foreach(AbstractBoxItem *block, listBlocks){
672 ((GroupItem*)block->getParentItem())->removeBlockItem(block);
673 ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
674 params->getCurrentScene()->removeItem(block);
675 params->getCurrentScene()->removeBlockItem(block);
677 groupBlock->addBlock(block->getRefBlock());
678 listAbstractBlocks.append(block->getRefBlock());
680 block->setUpperItem(groupItem);
681 groupItem->addBlockItem(block);
682 win->getScene()->addItem(block);
683 win->getScene()->addBlockItem(block);
686 //replace connection between selected blocks in the group
687 foreach(ConnectionItem *conn, connections){
688 if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
689 if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
690 parent->removeConnection(conn);
691 params->getCurrentScene()->removeItem(conn);
693 groupItem->addConnection(conn);
694 win->getScene()->addItem(conn);
699 //create new interfaces and connections for the new group
700 foreach(AbstractBoxItem *block, listBlocks){
701 foreach(InterfaceItem *inter, block->getInterfaces()){
702 cout << "inter : " << inter->getName().toStdString() << endl;
703 if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
704 cout << "connected from non null" << endl;
705 if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
707 AbstractInterface *iface = inter->refInter->clone(0);
708 iface->setName(iface->getName()+"_group");
709 groupBlock->addInterface(iface);
711 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
712 blockItem->addInterface(ifaceItem);
713 blockItem->resetInterfacesPosition();
715 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
716 groupItem->addInterface(ifaceGroupItem);
717 groupItem->resetInterfacesPosition();
718 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
719 if(conn->getToInterfaceItem() == inter){
720 conn->setToInterfaceItem(ifaceItem);
721 ifaceItem->refInter->setConnectedFrom(NULL);
722 conn->getFromInterfaceItem()->refInter->clearConnectedTo();
723 connect(ifaceItem,conn->getFromInterfaceItem());
726 params->setCurrentWindow(win);
728 inter->refInter->setConnectedFrom(NULL);
729 ifaceGroupItem->refInter->clearConnectedTo();
730 connect(inter,ifaceGroupItem);
731 params->setCurrentWindow(mainWindow);
735 if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
736 cout << "connected to non null" << endl;
737 foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
738 if(!listAbstractBlocks.contains(iface->getOwner())){
740 AbstractInterface *iface = inter->refInter->clone(0);
741 iface->setName(iface->getName()+"_group");
742 groupBlock->addInterface(iface);
744 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
745 blockItem->addInterface(ifaceItem);
746 blockItem->resetInterfacesPosition();
748 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
749 if(conn->getFromInterfaceItem() == inter){
750 conn->setFromInterfaceItem(ifaceItem);
751 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
752 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
756 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
757 groupItem->addInterface(ifaceGroupItem);
758 groupItem->resetInterfacesPosition();
759 inter->refInter->clearConnectedTo();
760 ifaceGroupItem->refInter->setConnectedFrom(NULL);
761 connect(ifaceGroupItem,inter);
770 parent->updateShape();
771 currentGroup->getScene()->updateConnectionItemsShape();
773 groupItem->updateShape();
774 win->getScene()->updateConnectionItemsShape();
775 groupItem->update(groupItem->boundingRect());
780 void Dispatcher::removeBoxItem(BoxItem *item) {
781 static QString fctName = "Dispatcher::removeBoxItem()";
783 cout << "call to " << qPrintable(fctName) << endl;
786 /* a BoxItem (group of func) can be removed only if none of its
787 interfaces is connected to a group interface that is itself
788 connected to another one.
790 bool canRemove = true;
792 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
793 foreach(ConnectionItem* conn, ifaceItem->connections) {
794 InterfaceItem* other = NULL;
795 if (conn->getFromInterfaceItem() == ifaceItem) {
796 other = conn->getToInterfaceItem();
799 other = conn->getFromInterfaceItem();
802 if (other->getOwner()->isGroupItem()) {
803 ConnectedInterface* ref = other->refInter;
804 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
811 QMessageBox::warning(NULL,"Forbidden operation",
812 "The block has at least one connection to a group interface that is totally connected.",
818 if (item->getRefBlock()->isFunctionalBlock()) {
819 msg = "Removing block ";
822 msg = "Removing group ";
824 msg += item->getRefBlock()->getName();
825 msg += " and all its connections.\n\nAre you sure ?";
827 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
828 if (ret == QMessageBox::Cancel) {
831 removeAllBlockConnections(item);
833 if (item->getRefBlock()->isFunctionalBlock()) {
834 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
835 item->getScene()->removeBoxItem(item);
836 params->getGraph()->removeFunctionalBlock(block);
838 else if (item->getRefBlock()->isGroupBlock()) {
840 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
842 // remove all child scenes recursively
843 GroupItem* subgroup = item->getChildGroupItem();
844 destroyScene(subgroup->getScene());
845 // remove the BoxItem
846 item->getScene()->removeBoxItem(item);
847 // remove the group from the graph
848 params->getGraph()->removeGroupBlock(group);
852 void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
853 static QString fctName = "Dispatcher::removeAllBlockConnection()";
855 cout << "call to " << qPrintable(fctName) << endl;
858 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
859 foreach(ConnectionItem* conn, ifaceItem->connections) {
860 removeConnection(conn);
865 void Dispatcher::removeSourceItem(SourceItem *item) {
866 static QString fctName = "Dispatcher::removeSourceItem()";
868 cout << "call to " << qPrintable(fctName) << endl;
871 QString msg = "Removing source ";
873 msg += item->getRefBlock()->getName();
874 msg += " and all its connections.\n\nAre you sure ?";
876 int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
877 if (ret == QMessageBox::Cancel) {
880 removeAllBlockConnections(item);
882 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
883 item->getScene()->removeSourceItem(item);
884 params->getGraph()->removeSourceBlock(block);
888 void Dispatcher::removeConnection(ConnectionItem *connItem) {
889 static QString fctName = "Dispatcher::removeConnection()";
891 cout << "call to " << qPrintable(fctName) << endl;
893 InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
894 InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
897 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
900 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not
901 GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem
903 ConnectedInterface *fromInter = fromIfaceItem->refInter;
904 ConnectedInterface *toInter = toIfaceItem->refInter;
906 // test if one of the interface bounded to item is owned by a GroupItem
907 if (fromIfaceItem->getOwner()->isGroupItem()) {
908 groupItem = ABI_TO_GI(fromIfaceItem->getOwner());
909 groupIfaceItem = fromIfaceItem;
911 else if (toIfaceItem->getOwner()->isGroupItem()) {
912 groupItem = ABI_TO_GI(toIfaceItem->getOwner());
913 groupIfaceItem = toIfaceItem;
916 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
919 // removing the connection from graph
921 cout << "removing connections from graph ..." ;
923 fromInter->disconnectTo(toInter);
926 cout << "done." << endl ;
929 // removing the connection from scene
931 cout << "removing connections from scene ..." ;
933 groupItem->getScene()->removeConnectionItem(connItem);
936 cout << "done." << endl ;
939 // if one of the interface bounded to connItem is owned by the GroupItem of the scene
940 if (groupIfaceItem != NULL) {
942 // determine if the interface must be removed since it has no more connections.
943 bool groupInterRemove = false;
944 if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true;
946 if (groupInterRemove) {
947 // get the GroupInterface from interface item
948 ConnectedInterface* groupInter = groupIfaceItem->refInter;
949 // remove interface from GroupItem, and delete it.
950 groupItem->removeInterfaceItem(groupIfaceItem);
951 // get the parent BoxItem of GroupItem if it exists.
952 BoxItem* parent2Item = groupItem->getParentItem();
953 if (parent2Item != NULL) {
954 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter);
955 // remove interface intem in parent BoxItem
956 parent2Item->removeInterfaceItem(group2IfaceItem);
958 // remove GroupInterface in the graph.
959 groupInter->getOwner()->removeInterface(groupInter);
964 void Dispatcher::showBlocksLibrary(){
965 cout << "showing block library" << endl;
966 mainWindow->getLibrary()->show();
967 mainWindow->getLibrary()->raise();
970 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 parentItem->getRefBlock()->addInterface(groupInter);
992 // creating/adding the group control interface in the graph model
993 GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
994 groupCtlInter->setAssociatedIface(groupInter);
995 parentItem->getRefBlock()->addInterface(groupCtlInter);
996 // creating/adding the group interface in the current scene model, and connection item
997 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
998 parentItem->addInterfaceItem(groupIfaceItem,true);
1000 // creating the connection, in graph and with an item
1001 createConnection(item, groupIfaceItem);
1003 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1004 BoxItem* parent2Item = parentItem->getParentItem();
1005 if(parent2Item != NULL){
1006 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1007 parent2Item->addInterfaceItem(blockIfaceItem,true);
1011 parentItem->getScene()->updateConnectionItemsShape();
1013 params->unsaveModif = true;
1016 void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
1017 static QString fctName = "Dispatcher::removeBlockInterface()";
1018 #ifdef DEBUG_FCTNAME
1019 cout << "call to " << qPrintable(fctName) << endl;
1022 /* first, remove all connections from item
1023 NB: if there is a connection to a group interface, then this
1024 method should not be called if the group interface is also
1025 connected to another interface. Normally, this is not possible
1026 because such a check is done when creating the contextual menu
1027 that allows to remove an interface.
1029 foreach(ConnectionItem* conn, item->connections) {
1030 removeConnection(conn);
1033 ConnectedInterface* ref = item->refInter;
1034 item->getOwner()->removeInterfaceItem(item);
1035 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1036 fun->removeInterface(ref);
1039 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
1040 static QString fctName = "Dispatcher::removeGroupInterface()";
1041 #ifdef DEBUG_FCTNAME
1042 cout << "call to " << qPrintable(fctName) << endl;
1045 /* NB: just remove all connections from/to this item, since when there are no more
1046 ones to a GroupItem, it is automatically deleted.
1048 foreach(ConnectionItem* conn, item->connections) {
1049 removeConnection(conn);
1053 QMap<int, QString> Dispatcher::getAllGroupNames() {
1055 QMap<int, QString> list;
1056 foreach(GroupWidget *group, groupList) {
1057 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1062 GroupScene* Dispatcher::getSceneById(int id) {
1063 foreach(GroupWidget *group, groupList){
1064 if(group->getScene()->getId() == id)
1065 return group->getScene();
1067 cout << "search scene by id :" << id << " :: not found..." << endl;
1071 GroupItem *Dispatcher::getGroupItemById(int id) {
1072 foreach(GroupWidget *group, groupList) {
1073 GroupScene* scene = group->getScene();
1074 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1076 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1080 BoxItem *Dispatcher::getBoxItemById(int id) {
1081 foreach(GroupWidget *group, groupList) {
1083 GroupScene* scene = group->getScene();
1084 foreach(BoxItem *item, scene->getBoxItems()){
1085 if(item->getId() == id){
1090 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1094 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1096 foreach(GroupWidget *group, groupList) {
1098 GroupScene* scene = group->getScene();
1100 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1101 if(item->getId() == id){
1105 foreach(BoxItem *block, scene->getBoxItems()){
1106 foreach(InterfaceItem *item, block->getInterfaces()){
1107 if(item->getId() == id){
1113 cout << "search interface by id :" << id << " :: not found..." << endl;