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 "AbstractInputModifier.h"
27 #include "DelayInputModifier.h"
30 #include "InterfacePropertiesWindow.h"
32 int Dispatcher::sceneCounter = 0;
34 Dispatcher::Dispatcher(Parameters* _params, MainWindow* _window) {
37 params->setDispatcher(this);
42 GroupWidget *Dispatcher::loadProject(const QString& filename) {
46 root = params->openProjectFile(filename);
48 catch(Exception err) {
53 // creating the top widget/scene
54 topGroup = new GroupWidget(NULL,this,params);
55 currentGroup = topGroup;
56 // getting the newly created scene
57 GroupScene *scene = topGroup->getScene();
59 params->setTopScene(scene);
60 params->setCurrentScene(scene);
63 topGroup = params->loadProject(root);
66 cerr << qPrintable(e.getDefaultMessage()) << endl;
67 cerr << "Aborting ..." << endl;
68 // TO DO : deleteting topGroup and all
72 groupList.append(topGroup);
76 void Dispatcher::closeCurrentProject() {
78 foreach(GroupWidget* win, groupList) {
82 params->destroyGraph();
88 bool Dispatcher::createConnection(InterfaceItem *iface1, InterfaceItem *iface2) {
90 ConnectedInterface* ref1 = iface1->refInter;
91 ConnectedInterface* ref2 = iface2->refInter;
92 // connect both interface
97 // test the ref1->ref2 connection
98 if ((ref1->canConnectTo(ref2)) && (ref2->canConnectFrom(ref1))) {
99 ref1->connectTo(ref2);
102 // if the frist one did not work, test ref2->ref1
103 if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) {
104 ref2->connectTo(ref1);
107 if ((ok1 == true) || (ok2 == true)) {
109 iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2);
112 params->unsaveModif = true;
113 cout << "created a connection from " << qPrintable(ref1->getName()) << " to " << qPrintable(ref2->getName()) << endl;
120 void Dispatcher::unselectAllItems(int direction){
122 GroupScene *scene = params->getCurrentScene();
124 foreach(BoxItem* block, scene->getBoxItems()) {
125 block->setSelected(false);
126 block->setCurrentInterface(NULL);
128 scene->unselecteInterfaces();
132 void Dispatcher::setCurrentGroupWidget(GroupWidget *win){
134 win->changeConnectionMode(-1);
136 params->setCurrentScene(win->getScene());
139 void Dispatcher::changeConnectionMode(int mode){
142 foreach(GroupWidget* win, groupList){
144 QToolButton* buttonNewConnection = win->getButtonNewConnection();
146 QPalette pal = buttonNewConnection->palette();
149 if(params->sceneMode != Parameters::EditOnConnection){
150 params->sceneMode = Parameters::EditOnConnection;
151 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
153 params->sceneMode = Parameters::EditNoOperation;
154 pal.setColor(QPalette::Button, QColor("#edeceb"));
157 else if(mode == Parameters::EditOnConnection){
158 params->sceneMode = Parameters::EditOnConnection;
159 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
162 params->sceneMode = Parameters::EditNoOperation;
163 pal.setColor(QPalette::Button, QColor("#edeceb"));
165 unselectAllInterfaces();
167 buttonNewConnection->setAutoFillBackground(true);
168 buttonNewConnection->setPalette(pal);
169 buttonNewConnection->update();
174 void Dispatcher::generateBlockVHDL(BoxItem *item){
175 static QString fctName = "Dispatcher::generateBlockVHDL()";
177 cout << "call to " << qPrintable(fctName) << endl;
180 if (item->getRefBlock()->isFunctionalBlock()) {
181 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
182 ReferenceBlock* ref = block->getReference();
183 BlockImplementation* impl = ref->getImplementations().at(0);
185 impl->generateVHDL(block,"/home/sdomas/");
188 cout << qPrintable(e.getMessage()) << endl;
193 void Dispatcher::renameFunctionalBlock(BoxItem *item){
194 static QString fctName = "Dispatcher::renameFunctionalBlock()";
196 cout << "call to " << qPrintable(fctName) << endl;
199 GroupWidget* win = item->getScene()->getGroupWidget();
204 text = QInputDialog::getText(win, "Rename a functional block",
205 "New name:", QLineEdit::Normal,
206 item->getRefBlock()->getName(), &ok);
209 if (text == item->getRefBlock()->getName()) return;
211 if( (text.isEmpty()) || (text.length() > 30)) {
212 QMessageBox::warning(win,"Error in given name",
213 "the block name must be shorter than 30 characters, cannot be empty",
218 FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
220 QMessageBox::warning(win,"Error in given name",
221 "the name provided is similar to that of another functional block within the group",
228 item->getRefBlock()->setName(text);
232 void Dispatcher::renameGroupBlock(GroupItem *item){
233 static QString fctName = "Dispatcher::renameGroupBlock()";
235 cout << "call to " << qPrintable(fctName) << endl;
238 GroupWidget* win = item->getScene()->getGroupWidget();
243 text = QInputDialog::getText(win, "Rename a group",
244 "New name:", QLineEdit::Normal,
245 item->getRefBlock()->getName(), &ok);
248 if (text == item->getRefBlock()->getName()) return;
250 if( (text.isEmpty()) || (text.length() > 30)) {
251 QMessageBox::warning(win,"Error in given name",
252 "the block name must be shorter than 30 characters, cannot be empty",
257 GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
259 QMessageBox::warning(win,"Error in given name",
260 "the name provided is similar to that of another group",
267 item->getRefBlock()->setName(text);
268 if(item->getScene()->getGroupWidget()->isTopGroup()) {
269 mainWindow->setWindowTitle("blast - "+text);
272 item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
275 mainWindow->getLibrary()->updateComboScene();
278 void Dispatcher::renameSourceBlock(SourceItem *item){
279 static QString fctName = "Dispatcher::renameSourceBlock()";
281 cout << "call to " << qPrintable(fctName) << endl;
284 GroupWidget* win = item->getScene()->getGroupWidget();
289 text = QInputDialog::getText(win, "Rename a source",
290 "New name:", QLineEdit::Normal,
291 item->getRefBlock()->getName(), &ok);
294 if (text == item->getRefBlock()->getName()) return;
296 if( (text.isEmpty()) || (text.length() > 30)) {
297 QMessageBox::warning(win,"Error in given name",
298 "the block name must be shorter than 30 characters, cannot be empty",
303 FunctionalBlock* block = params->getGraph()->getSourceBlockByName(text);
305 QMessageBox::warning(win,"Error in given name",
306 "the name provided is similar to that of another source block within the top group",
313 item->getRefBlock()->setName(text);
318 void Dispatcher::renameInterface(InterfaceItem *item) {
319 static QString fctName = "Dispatcher::renameInterface()";
321 cout << "call to " << qPrintable(fctName) << endl;
324 GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
329 text = QInputDialog::getText(win, "Rename an interface",
330 "New name:", QLineEdit::Normal,
331 item->refInter->getName(), &ok);
335 if (text == item->refInter->getName()) return;
337 if( (text.isEmpty()) || (text.length() > 30)) {
338 QMessageBox::warning(win,"Error in given name",
339 "the interface name must be shorter than 30 characters, cannot be empty",
344 AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
346 QMessageBox::warning(win,"Error in given name",
347 "the name provided is similar to that of another interface",
353 item->refInter->setName(text);
354 AbstractInterface* assoIface = item->refInter->getAssociatedIface();
355 if (assoIface != NULL) {
356 assoIface->setName(text+"_enb");
358 item->updateName(text);
359 item->getOwner()->nameChanged();
362 void Dispatcher::showPatterns(InterfaceItem *item) {
363 static QString fctName = "Dispatcher::showPatterns()";
365 cout << "call to " << qPrintable(fctName) << endl;
368 if (item->refInter->getDirection() == AbstractInterface::Input) {
369 msg = "Input pattern of iface ";
370 msg += item->refInter->getName();
372 msg += item->refInter->getOwner()->getName();
374 ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
375 ConnectedInterface* fromIface = iface->getConnectedFrom();
376 if (fromIface->getOutputPattern() == NULL) return;
377 foreach(char c, *(fromIface->getOutputPattern())) {
378 msg += QString::number((int)c);
382 else if (item->refInter->getDirection() == AbstractInterface::Output) {
383 msg = "Output pattern of iface ";
384 msg += item->refInter->getName();
386 msg += item->refInter->getOwner()->getName();
388 ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
389 if (iface->getOutputPattern() == NULL) return;
390 foreach(char c, *(iface->getOutputPattern())) {
391 msg += QString::number((int)c);
395 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
398 void Dispatcher::showModifier(InterfaceItem *item) {
399 static QString fctName = "Dispatcher::showModifier()";
401 cout << "call to " << qPrintable(fctName) << endl;
404 AbstractInputModifier* mod = item->refInter->getInputModifier();
405 if (mod->isDelay()) {
406 DelayInputModifier* delay = (DelayInputModifier *)mod;
407 msg = "Pattern of iface ";
408 msg += item->refInter->getName();
410 msg += item->refInter->getOwner()->getName();
411 msg += " is modified by a simple delay of ";
412 msg += QString::number(delay->getDelayLength());
415 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
418 void Dispatcher::removeModifier(InterfaceItem *item) {
419 static QString fctName = "Dispatcher::showModifier()";
421 cout << "call to " << qPrintable(fctName) << endl;
424 item->refInter->clearInputModifier();
428 void Dispatcher::duplicateBoxItem(BoxItem *item){
429 static QString fctName = "Dispatcher::duplicateBoxItem()";
431 cout << "call to " << qPrintable(fctName) << endl;
434 GroupScene *scene = item->getScene();
435 AbstractBlock* block = item->getRefBlock();
436 AbstractBlock *newBlock;
438 // only duplicate functional blocks
439 if(block->isFunctionalBlock()) {
441 // adding to the model
442 FunctionalBlock* funBlock = (FunctionalBlock*)block;
443 newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
444 // adding to the view
445 scene->createBoxItem(newBlock);
447 params->unsaveModif = true;
451 void Dispatcher::duplicateSourceItem(SourceItem *item) {
452 static QString fctName = "Dispatcher::duplicateSourceItem()";
454 cout << "call to " << qPrintable(fctName) << endl;
457 GroupScene *scene = item->getScene();
458 AbstractBlock* block = item->getRefBlock();
459 AbstractBlock *newBlock;
461 // only duplicate functional blocks
462 if(block->isFunctionalBlock()) {
464 // adding to the model
465 FunctionalBlock* funBlock = (FunctionalBlock*)block;
466 newBlock = params->getGraph()->duplicateSourceBlock(funBlock);
467 // adding to the view
468 scene->createSourceItem(newBlock);
470 params->unsaveModif = true;
474 void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
475 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
477 cout << "call to " << qPrintable(fctName) << endl;
480 AbstractInterface *refI = item->refInter;
481 if (! refI->isFunctionalInterface()) return;
483 AbstractBlock *refB = refI->getOwner();
484 if(! refB->isFunctionalBlock()) return;
486 FunctionalInterface* iface = (FunctionalInterface*)refI;
487 AbstractInterface *cloneIface = iface->clone();
488 if (cloneIface == NULL) {
489 QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
493 refB->addInterface(cloneIface);
495 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
496 item->getOwner()->addInterfaceItem(cloneIfaceItem,true);
498 // creating control interface if needed
499 if (refI->getAssociatedIface() != NULL) {
500 QString ctlName = cloneIface->getName()+"_enb";
501 ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,cloneIface->getDirection(), AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
502 refB->addInterface(ctlIface);
503 if (! ctlIface->setAssociatedIface(cloneIface)) {
504 cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
510 BoxItem* Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
511 static QString fctName = "Dispatcher::addBlock()";
513 cout << "call to " << qPrintable(fctName) << endl;
515 bool newSource = false;
516 BoxItem* item = NULL;
517 GroupScene *scene = getSceneById(idScene);
518 ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
519 // if block has no inputs, propose to add it as a source to top scene
520 if ((scene->isTopScene()) && (ref->isGeneratorBlock())) {
521 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 ?");
522 if (ret == QMessageBox::Yes) {
527 FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref);
528 scene->createSourceItem(newOne);
531 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
532 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
533 item = scene->createBoxItem(newOne);
534 params->blockToItem.insert(newOne,item);
536 params->unsaveModif = true;
541 GroupWidget *Dispatcher::createTopScene(){
542 static QString fctName = "Dispatcher::createTopScene()";
544 cout << "call to " << qPrintable(fctName) << endl;
547 // creating the model part of the group
548 Graph* graph = params->createGraph();
549 GroupBlock *refBlock = graph->getTopGroup();
551 // creating a fake and not connected interface
552 //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
554 // creating the group widget
555 topGroup = new GroupWidget(NULL,this,params);
556 currentGroup = topGroup;
557 // getting the newly created scene
558 GroupScene *scene = topGroup->getScene();
559 scene->setId(sceneCounter++);
560 params->setTopScene(scene);
561 params->setCurrentScene(scene);
562 // creating the view part of the group
563 GroupItem *group = new GroupItem(NULL,refBlock,this,params);
566 // adding the fake interface to the top group item
567 //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
568 //group->addInterface(item,true);
570 scene->setGroupItem(group);
572 groupList.append(topGroup);
576 GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
577 static QString fctName = "Dispatcher::addNewEmptyGroup();";
579 cout << "call to " << qPrintable(fctName) << endl;
582 // getting the parent block in the graph
583 GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
584 cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
585 GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent);
586 cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
587 // creating the BlockItem in the scene
588 BoxItem* newItem = scene->createBoxItem(groupBlock);
590 params->unsaveModif = true;
592 GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
593 if (show) child->show();
598 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
599 static QString fctName = "Dispatcher::createChildScene()";
601 cout << "call to " << qPrintable(fctName) << endl;
604 GroupWidget* group = NULL;
605 /* NB: this method may be called during design process or when loading
606 a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
607 cannot be initialized yet. This is why there are 2 cases below
610 if (upperItemOfGroupItem != NULL) {
611 // getting back the goup block already created
612 GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
613 // creating the view part of the group
614 GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
616 // creating the group widget
617 group = new GroupWidget(parentWidget, this, params);
618 // getting the newly created scene
619 GroupScene *scene = group->getScene();
620 scene->setId(sceneCounter++);
621 // affecting group item to the scene
622 scene->setGroupItem(groupItem);
623 groupList.append(group);
625 mainWindow->getLibrary()->updateComboScene();
628 GroupItem *groupItem = new GroupItem(this,params);
629 // creating the group widget
630 group = new GroupWidget(parentWidget, this, params);
631 // getting the newly created scene
632 GroupScene *scene = group->getScene();
633 // affecting group item to the scene
634 scene->setGroupItem(groupItem);
635 groupList.append(group);
640 void Dispatcher::destroyScene(GroupScene *scene) {
641 foreach(GroupScene* s, scene->getChildrenScene()) {
645 if (scene->getNbChildScene() == 0) {
646 // remove scene from the parent list, if possible
647 if (scene->getParentScene() != NULL) {
648 scene->getParentScene()->removeChildScene(scene);
650 // destroy the GroupWidget
651 groupList.removeAll(scene->getGroupWidget());
652 scene->getGroupWidget()->deleteLater();
655 cerr << "Abnormal case when destroying a scene" << endl;
659 void Dispatcher::showRaiseWindow(BoxItem *item) {
660 static QString fctName = "Dispatcher::showRaiseWindow()";
662 cout << "call to " << qPrintable(fctName) << endl;
665 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
666 GroupItem* child = item->getChildGroupItem();
668 cerr << "abnormal case: child group item is null " << endl;
672 GroupWidget* win = child->getScene()->getGroupWidget();
676 win->activateWindow();
679 params->setCurrentScene(currentGroup->getScene());
682 void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
683 static QString fctName = "Dispatcher::showRstClkIface()";
685 cout << "call to " << qPrintable(fctName) << endl;
688 item->setRstClkVisible(!item->isRstClkVisible());
692 void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
693 static QString fctName = "Dispatcher::showWishboneIface()";
695 cout << "call to " << qPrintable(fctName) << endl;
698 item->setWishboneVisible(!item->isWishboneVisible());
701 void Dispatcher::addNewFullGroup() {
702 static QString fctName = "Dispatcher::addNewFullGroup()";
704 cout << "call to " << qPrintable(fctName) << endl;
710 QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
711 QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
712 QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
714 /* What must be done:
715 1 - creating a new GroupBlock
716 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
717 3 - creating a BlockItem that references the new GroupBlock
718 4 - creating a new GroupWidget
719 5 - creating a new GroupItem added to the scene of the GroupWidget
723 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
724 associated to the GroupItem of the current scene
726 GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
727 GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
728 /* step 2: moving selected blocks */
729 foreach(BlockItem* blockItem, listBlocks) {
730 parentBlock->removeBlock(blockItem->getRefBlock());
731 newGroupBlock->addBlock(blockItem->getRefBlock());
734 GroupItem *parent = currentGroup->getScene()->getGroupItem();
735 GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
736 BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
737 GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
739 //create the new window
740 GroupWidget* win = new GroupWidget(this,params);
741 win->getScene()->setGroupItem(groupItem);
742 win->getScene()->addItem(groupItem);
743 ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
744 params->addWindow(win);
748 params->getCurrentScene()->addBlockItem(blockItem);
749 params->getCurrentScene()->addItem(blockItem);
750 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
752 //replace selected blocks in the group
753 foreach(AbstractBoxItem *block, listBlocks){
754 ((GroupItem*)block->getParentItem())->removeBlockItem(block);
755 ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
756 params->getCurrentScene()->removeItem(block);
757 params->getCurrentScene()->removeBlockItem(block);
759 groupBlock->addBlock(block->getRefBlock());
760 listAbstractBlocks.append(block->getRefBlock());
762 block->setUpperItem(groupItem);
763 groupItem->addBlockItem(block);
764 win->getScene()->addItem(block);
765 win->getScene()->addBlockItem(block);
768 //replace connection between selected blocks in the group
769 foreach(ConnectionItem *conn, connections){
770 if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
771 if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
772 parent->removeConnection(conn);
773 params->getCurrentScene()->removeItem(conn);
775 groupItem->addConnection(conn);
776 win->getScene()->addItem(conn);
781 //create new interfaces and connections for the new group
782 foreach(AbstractBoxItem *block, listBlocks){
783 foreach(InterfaceItem *inter, block->getInterfaces()){
784 cout << "inter : " << inter->getName().toStdString() << endl;
785 if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
786 cout << "connected from non null" << endl;
787 if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
789 AbstractInterface *iface = inter->refInter->clone(0);
790 iface->setName(iface->getName()+"_group");
791 groupBlock->addInterface(iface);
793 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
794 blockItem->addInterface(ifaceItem);
795 blockItem->resetInterfacesPosition();
797 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
798 groupItem->addInterface(ifaceGroupItem);
799 groupItem->resetInterfacesPosition();
800 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
801 if(conn->getToInterfaceItem() == inter){
802 conn->setToInterfaceItem(ifaceItem);
803 ifaceItem->refInter->setConnectedFrom(NULL);
804 conn->getFromInterfaceItem()->refInter->clearConnectedTo();
805 connect(ifaceItem,conn->getFromInterfaceItem());
808 params->setCurrentWindow(win);
810 inter->refInter->setConnectedFrom(NULL);
811 ifaceGroupItem->refInter->clearConnectedTo();
812 connect(inter,ifaceGroupItem);
813 params->setCurrentWindow(mainWindow);
817 if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
818 cout << "connected to non null" << endl;
819 foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
820 if(!listAbstractBlocks.contains(iface->getOwner())){
822 AbstractInterface *iface = inter->refInter->clone(0);
823 iface->setName(iface->getName()+"_group");
824 groupBlock->addInterface(iface);
826 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
827 blockItem->addInterface(ifaceItem);
828 blockItem->resetInterfacesPosition();
830 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
831 if(conn->getFromInterfaceItem() == inter){
832 conn->setFromInterfaceItem(ifaceItem);
833 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
834 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
838 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
839 groupItem->addInterface(ifaceGroupItem);
840 groupItem->resetInterfacesPosition();
841 inter->refInter->clearConnectedTo();
842 ifaceGroupItem->refInter->setConnectedFrom(NULL);
843 connect(ifaceGroupItem,inter);
852 parent->updateShape();
853 currentGroup->getScene()->updateConnectionItemsShape();
855 groupItem->updateShape();
856 win->getScene()->updateConnectionItemsShape();
857 groupItem->update(groupItem->boundingRect());
862 void Dispatcher::removeBoxItem(BoxItem *item) {
863 static QString fctName = "Dispatcher::removeBoxItem()";
865 cout << "call to " << qPrintable(fctName) << endl;
868 /* a BoxItem (group of func) can be removed only if none of its
869 interfaces is connected to a group interface that is itself
870 connected to another one.
872 bool canRemove = true;
874 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
875 foreach(ConnectionItem* conn, ifaceItem->connections) {
876 InterfaceItem* other = NULL;
877 if (conn->getFromInterfaceItem() == ifaceItem) {
878 other = conn->getToInterfaceItem();
881 other = conn->getFromInterfaceItem();
884 if (other->getOwner()->isGroupItem()) {
885 ConnectedInterface* ref = other->refInter;
886 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
893 QMessageBox::warning(NULL,"Forbidden operation",
894 "The block has at least one connection to a group interface that is totally connected.",
900 if (item->getRefBlock()->isFunctionalBlock()) {
901 msg = "Removing block ";
904 msg = "Removing group ";
906 msg += item->getRefBlock()->getName();
907 msg += " and all its connections.\n\nAre you sure ?";
909 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
910 if (ret == QMessageBox::Cancel) {
913 removeAllBlockConnections(item);
915 if (item->getRefBlock()->isFunctionalBlock()) {
916 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
917 item->getScene()->removeBoxItem(item);
918 params->getGraph()->removeFunctionalBlock(block);
919 params->blockToItem.remove(block);
922 else if (item->getRefBlock()->isGroupBlock()) {
924 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
926 // remove all child scenes recursively
927 GroupItem* subgroup = item->getChildGroupItem();
928 destroyScene(subgroup->getScene());
929 // remove the BoxItem
930 item->getScene()->removeBoxItem(item);
931 // remove the group from the graph
932 params->getGraph()->removeGroupBlock(group);
936 void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
937 static QString fctName = "Dispatcher::removeAllBlockConnection()";
939 cout << "call to " << qPrintable(fctName) << endl;
942 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
943 foreach(ConnectionItem* conn, ifaceItem->connections) {
944 removeConnection(conn);
949 void Dispatcher::removeSourceItem(SourceItem *item) {
950 static QString fctName = "Dispatcher::removeSourceItem()";
952 cout << "call to " << qPrintable(fctName) << endl;
955 QString msg = "Removing source ";
957 msg += item->getRefBlock()->getName();
958 msg += " and all its connections.\n\nAre you sure ?";
960 int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
961 if (ret == QMessageBox::Cancel) {
964 removeAllBlockConnections(item);
966 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
967 item->getScene()->removeSourceItem(item);
968 params->getGraph()->removeSourceBlock(block);
972 void Dispatcher::removeConnection(ConnectionItem *connItem) {
973 static QString fctName = "Dispatcher::removeConnection()";
975 cout << "call to " << qPrintable(fctName) << endl;
977 InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
978 InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
981 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
984 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not
985 GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem
987 ConnectedInterface *fromInter = fromIfaceItem->refInter;
988 ConnectedInterface *toInter = toIfaceItem->refInter;
990 // test if one of the interface bounded to item is owned by a GroupItem
991 if (fromIfaceItem->getOwner()->isGroupItem()) {
992 groupItem = ABI_TO_GI(fromIfaceItem->getOwner());
993 groupIfaceItem = fromIfaceItem;
995 else if (toIfaceItem->getOwner()->isGroupItem()) {
996 groupItem = ABI_TO_GI(toIfaceItem->getOwner());
997 groupIfaceItem = toIfaceItem;
1000 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
1003 // removing the connection from graph
1005 cout << "removing connections from graph ..." ;
1007 fromInter->disconnectTo(toInter);
1010 cout << "done." << endl ;
1013 // removing the connection from scene
1015 cout << "removing connections from scene ..." ;
1017 groupItem->getScene()->removeConnectionItem(connItem);
1020 cout << "done." << endl ;
1023 // if one of the interface bounded to connItem is owned by the GroupItem of the scene
1024 if (groupIfaceItem != NULL) {
1026 // determine if the interface must be removed since it has no more connections.
1027 bool groupInterRemove = false;
1028 if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true;
1030 if (groupInterRemove) {
1031 // get the GroupInterface from interface item
1032 ConnectedInterface* groupInter = groupIfaceItem->refInter;
1033 // remove interface from GroupItem, and delete it.
1034 groupItem->removeInterfaceItem(groupIfaceItem);
1035 // get the parent BoxItem of GroupItem if it exists.
1036 BoxItem* parent2Item = groupItem->getParentItem();
1037 if (parent2Item != NULL) {
1038 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter);
1039 // remove interface intem in parent BoxItem
1040 parent2Item->removeInterfaceItem(group2IfaceItem);
1042 // remove GroupInterface in the graph.
1043 groupInter->getOwner()->removeInterface(groupInter);
1048 void Dispatcher::showBlocksLibrary(){
1049 cout << "showing block library" << endl;
1050 mainWindow->getLibrary()->show();
1051 mainWindow->getLibrary()->raise();
1054 void Dispatcher::showProperties(InterfaceItem *inter) {
1055 new InterfacePropertiesWindow(inter);
1058 /* connectInterToGroup() :
1059 The only way for a block (functional of group) within a GroupItem to be connected
1060 to the latter is to right-click on one of its interfaces and to choose "connect to group".
1061 That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
1064 void Dispatcher::connectInterToGroup(InterfaceItem *item){
1066 // getting the GroupBlock and GroupItem that are parent of the block that owns item
1067 ConnectedInterface *refInter = item->refInter;
1068 cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
1069 GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
1070 cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
1071 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
1073 // creating/adding the group interface in the graph model
1074 GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
1075 parentItem->getRefBlock()->addInterface(groupInter);
1076 // creating/adding the group control interface in the graph model
1077 GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
1078 groupCtlInter->setAssociatedIface(groupInter);
1079 parentItem->getRefBlock()->addInterface(groupCtlInter);
1080 // creating/adding the group interface in the current scene model, and connection item
1081 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1082 parentItem->addInterfaceItem(groupIfaceItem,true);
1084 // creating the connection, in graph and with an item
1085 createConnection(item, groupIfaceItem);
1087 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1088 BoxItem* parent2Item = parentItem->getParentItem();
1089 if(parent2Item != NULL){
1090 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1091 parent2Item->addInterfaceItem(blockIfaceItem,true);
1095 parentItem->getScene()->updateConnectionItemsShape();
1097 params->unsaveModif = true;
1100 void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
1101 static QString fctName = "Dispatcher::removeBlockInterface()";
1102 #ifdef DEBUG_FCTNAME
1103 cout << "call to " << qPrintable(fctName) << endl;
1106 /* first, remove all connections from item
1107 NB: if there is a connection to a group interface, then this
1108 method should not be called if the group interface is also
1109 connected to another interface. Normally, this is not possible
1110 because such a check is done when creating the contextual menu
1111 that allows to remove an interface.
1113 foreach(ConnectionItem* conn, item->connections) {
1114 removeConnection(conn);
1117 ConnectedInterface* ref = item->refInter;
1118 item->getOwner()->removeInterfaceItem(item);
1119 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1120 fun->removeInterface(ref);
1123 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
1124 static QString fctName = "Dispatcher::removeGroupInterface()";
1125 #ifdef DEBUG_FCTNAME
1126 cout << "call to " << qPrintable(fctName) << endl;
1129 /* NB: just remove all connections from/to this item, since when there are no more
1130 ones to a GroupItem, it is automatically deleted.
1132 foreach(ConnectionItem* conn, item->connections) {
1133 removeConnection(conn);
1137 QMap<int, QString> Dispatcher::getAllGroupNames() {
1139 QMap<int, QString> list;
1140 foreach(GroupWidget *group, groupList) {
1141 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1146 GroupScene* Dispatcher::getSceneById(int id) {
1147 foreach(GroupWidget *group, groupList){
1148 if(group->getScene()->getId() == id)
1149 return group->getScene();
1151 cout << "search scene by id :" << id << " :: not found..." << endl;
1155 GroupItem *Dispatcher::getGroupItemById(int id) {
1156 foreach(GroupWidget *group, groupList) {
1157 GroupScene* scene = group->getScene();
1158 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1160 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1164 BoxItem *Dispatcher::getBoxItemById(int id) {
1165 foreach(GroupWidget *group, groupList) {
1167 GroupScene* scene = group->getScene();
1168 foreach(BoxItem *item, scene->getBoxItems()){
1169 if(item->getId() == id){
1174 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1178 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1180 foreach(GroupWidget *group, groupList) {
1182 GroupScene* scene = group->getScene();
1184 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1185 if(item->getId() == id){
1189 foreach(BoxItem *block, scene->getBoxItems()){
1190 foreach(InterfaceItem *item, block->getInterfaces()){
1191 if(item->getId() == id){
1197 cout << "search interface by id :" << id << " :: not found..." << endl;
1201 void Dispatcher::findGraphModifications(FunctionalBlock *block) {
1202 static QString fctName = "Dispatcher::findGraphModifications()";
1203 #ifdef DEBUG_FCTNAME
1204 cout << "call to " << qPrintable(fctName) << endl;
1207 block->computeAdmittanceDelays();
1208 // get the block item that is associated to block
1209 BoxItem* toBlockItem = params->blockToItem.value(block);
1211 /* VERSION 1: just add delays if needed */
1212 QMap<AbstractInterface*,QList<int>* > delays = block->getAdmittanceDelays();
1213 QMapIterator<AbstractInterface*,QList<int>* > iterD(delays);
1214 while (iterD.hasNext()) {
1216 QList<int>* delay = iterD.value();
1217 if (delay->at(0) > 0) {
1218 // create delay and associate it to the connected input
1219 AbstractInputModifier* mod = new DelayInputModifier(delay->at(0));
1220 ConnectedInterface* toIface = AI_TO_CON(iterD.key()->getAssociatedIface());
1221 cout << "modify input of " << qPrintable(toIface->getName()) << endl;
1222 toIface->setInputModifier(mod);
1224 toBlockItem->update();