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 QFileInfo info(filename);
73 params->projectPath = info.absolutePath();
74 cout << "project path = " << qPrintable(params->projectPath) << endl;
75 groupList.append(topGroup);
79 void Dispatcher::closeCurrentProject() {
81 foreach(GroupWidget* win, groupList) {
85 params->destroyGraph();
91 bool Dispatcher::createConnection(InterfaceItem *iface1, InterfaceItem *iface2, bool visible) {
93 ConnectedInterface* ref1 = iface1->refInter;
94 ConnectedInterface* ref2 = iface2->refInter;
95 // connect both interface
100 // test the ref1->ref2 connection
101 if ((ref1->canConnectTo(ref2)) && (ref2->canConnectFrom(ref1))) {
102 ref1->connectTo(ref2);
105 // if the frist one did not work, test ref2->ref1
106 if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) {
107 ref2->connectTo(ref1);
110 if ((ok1 == true) || (ok2 == true)) {
112 iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2, visible);
115 params->unsaveModif = true;
116 cout << "created a connection from " << qPrintable(ref1->getName()) << " to " << qPrintable(ref2->getName()) << endl;
123 void Dispatcher::unselectAllItems(int direction){
125 GroupScene *scene = params->getCurrentScene();
127 foreach(BoxItem* block, scene->getBoxItems()) {
128 block->setSelected(false);
129 block->setCurrentInterface(NULL);
131 scene->unselecteInterfaces();
135 void Dispatcher::setCurrentGroupWidget(GroupWidget *win){
137 win->changeConnectionMode(-1);
139 params->setCurrentScene(win->getScene());
142 void Dispatcher::changeConnectionMode(int mode){
145 foreach(GroupWidget* win, groupList){
147 QToolButton* buttonNewConnection = win->getButtonNewConnection();
149 QPalette pal = buttonNewConnection->palette();
152 if(params->sceneMode != Parameters::EditOnConnection){
153 params->sceneMode = Parameters::EditOnConnection;
154 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
156 params->sceneMode = Parameters::EditNoOperation;
157 pal.setColor(QPalette::Button, QColor("#edeceb"));
160 else if(mode == Parameters::EditOnConnection){
161 params->sceneMode = Parameters::EditOnConnection;
162 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
165 params->sceneMode = Parameters::EditNoOperation;
166 pal.setColor(QPalette::Button, QColor("#edeceb"));
168 unselectAllInterfaces();
170 buttonNewConnection->setAutoFillBackground(true);
171 buttonNewConnection->setPalette(pal);
172 buttonNewConnection->update();
177 void Dispatcher::generateBlockVHDL(BoxItem *item){
178 static QString fctName = "Dispatcher::generateBlockVHDL()";
180 cout << "call to " << qPrintable(fctName) << endl;
183 if (item->getRefBlock()->isFunctionalBlock()) {
184 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
186 block->generateVHDL(params->projectPath);
189 cout << qPrintable(e.getMessage()) << endl;
194 void Dispatcher::renameFunctionalBlock(BoxItem *item){
195 static QString fctName = "Dispatcher::renameFunctionalBlock()";
197 cout << "call to " << qPrintable(fctName) << endl;
200 GroupWidget* win = item->getScene()->getGroupWidget();
205 text = QInputDialog::getText(win, "Rename a functional block",
206 "New name:", QLineEdit::Normal,
207 item->getRefBlock()->getName(), &ok);
210 if (text == item->getRefBlock()->getName()) return;
212 if( (text.isEmpty()) || (text.length() > 30)) {
213 QMessageBox::warning(win,"Error in given name",
214 "the block name must be shorter than 30 characters, cannot be empty",
219 FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
221 QMessageBox::warning(win,"Error in given name",
222 "the name provided is similar to that of another functional block within the group",
229 item->getRefBlock()->setName(text);
233 void Dispatcher::renameGroupBlock(GroupItem *item){
234 static QString fctName = "Dispatcher::renameGroupBlock()";
236 cout << "call to " << qPrintable(fctName) << endl;
239 GroupWidget* win = item->getScene()->getGroupWidget();
244 text = QInputDialog::getText(win, "Rename a group",
245 "New name:", QLineEdit::Normal,
246 item->getRefBlock()->getName(), &ok);
249 if (text == item->getRefBlock()->getName()) return;
251 if( (text.isEmpty()) || (text.length() > 30)) {
252 QMessageBox::warning(win,"Error in given name",
253 "the block name must be shorter than 30 characters, cannot be empty",
258 GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
260 QMessageBox::warning(win,"Error in given name",
261 "the name provided is similar to that of another group",
268 item->getRefBlock()->setName(text);
269 if(item->getScene()->getGroupWidget()->isTopGroup()) {
270 mainWindow->setWindowTitle("blast - "+text);
273 item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
276 mainWindow->getLibrary()->updateComboScene();
279 void Dispatcher::renameSourceBlock(SourceItem *item){
280 static QString fctName = "Dispatcher::renameSourceBlock()";
282 cout << "call to " << qPrintable(fctName) << endl;
285 GroupWidget* win = item->getScene()->getGroupWidget();
290 text = QInputDialog::getText(win, "Rename a source",
291 "New name:", QLineEdit::Normal,
292 item->getRefBlock()->getName(), &ok);
295 if (text == item->getRefBlock()->getName()) return;
297 if( (text.isEmpty()) || (text.length() > 30)) {
298 QMessageBox::warning(win,"Error in given name",
299 "the block name must be shorter than 30 characters, cannot be empty",
304 FunctionalBlock* block = params->getGraph()->getSourceBlockByName(text);
306 QMessageBox::warning(win,"Error in given name",
307 "the name provided is similar to that of another source block within the top group",
314 item->getRefBlock()->setName(text);
319 void Dispatcher::renameInterface(InterfaceItem *item) {
320 static QString fctName = "Dispatcher::renameInterface()";
322 cout << "call to " << qPrintable(fctName) << endl;
325 GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
330 text = QInputDialog::getText(win, "Rename an interface",
331 "New name:", QLineEdit::Normal,
332 item->refInter->getName(), &ok);
336 if (text == item->refInter->getName()) return;
338 if( (text.isEmpty()) || (text.length() > 30)) {
339 QMessageBox::warning(win,"Error in given name",
340 "the interface name must be shorter than 30 characters, cannot be empty",
345 AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
347 QMessageBox::warning(win,"Error in given name",
348 "the name provided is similar to that of another interface",
354 item->refInter->setName(text);
355 AbstractInterface* assoIface = item->refInter->getAssociatedIface();
356 if (assoIface != NULL) {
357 assoIface->setName(text+"_enb");
359 item->updateName(text);
360 item->getOwner()->nameChanged();
363 void Dispatcher::showPatterns(InterfaceItem *item) {
364 static QString fctName = "Dispatcher::showPatterns()";
366 cout << "call to " << qPrintable(fctName) << endl;
369 if (item->refInter->getDirection() == AbstractInterface::Input) {
370 msg = "Input pattern of iface ";
371 msg += item->refInter->getName();
373 msg += item->refInter->getOwner()->getName();
375 // get the precursor output pattern
376 ConnectedInterface* connIface = AI_TO_CON(item->refInter->getAssociatedIface());
377 QList<char>* out = connIface->getConnectedFrom()->getOutputPattern();
379 AbstractInputModifier* modifier = connIface->getInputModifier();
380 // check if the input is modified
381 if (modifier != NULL) {
383 out = modifier->getModifiedInput(out);
386 foreach(char c, *out) {
387 msg += QString::number((int)c);
391 else if (item->refInter->getDirection() == AbstractInterface::Output) {
392 msg = "Output pattern of iface ";
393 msg += item->refInter->getName();
395 msg += item->refInter->getOwner()->getName();
397 ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
398 if (iface->getOutputPattern() == NULL) return;
399 foreach(char c, *(iface->getOutputPattern())) {
400 msg += QString::number((int)c);
404 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
407 void Dispatcher::showModifier(InterfaceItem *item) {
408 static QString fctName = "Dispatcher::showModifier()";
410 cout << "call to " << qPrintable(fctName) << endl;
413 ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
414 AbstractInputModifier* mod = assoIface->getInputModifier();
415 if (mod->isDelay()) {
416 DelayInputModifier* delay = (DelayInputModifier *)mod;
417 msg = "Pattern of iface ";
418 msg += item->refInter->getName();
420 msg += item->refInter->getOwner()->getName();
421 msg += " is modified by a simple delay of ";
422 msg += QString::number(delay->getDelayLength());
425 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
428 void Dispatcher::removeModifier(InterfaceItem *item) {
429 static QString fctName = "Dispatcher::showModifier()";
431 cout << "call to " << qPrintable(fctName) << endl;
434 ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
435 assoIface->clearInputModifier();
439 void Dispatcher::duplicateBoxItem(BoxItem *item){
440 static QString fctName = "Dispatcher::duplicateBoxItem()";
442 cout << "call to " << qPrintable(fctName) << endl;
445 GroupScene *scene = item->getScene();
446 AbstractBlock* block = item->getRefBlock();
447 AbstractBlock *newBlock;
449 // only duplicate functional blocks
450 if(block->isFunctionalBlock()) {
452 // adding to the model
453 FunctionalBlock* funBlock = (FunctionalBlock*)block;
454 newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
455 // adding to the view
456 scene->createBoxItem(newBlock);
458 params->unsaveModif = true;
462 void Dispatcher::duplicateSourceItem(SourceItem *item) {
463 static QString fctName = "Dispatcher::duplicateSourceItem()";
465 cout << "call to " << qPrintable(fctName) << endl;
468 GroupScene *scene = item->getScene();
469 AbstractBlock* block = item->getRefBlock();
470 AbstractBlock *newBlock;
472 // only duplicate functional blocks
473 if(block->isFunctionalBlock()) {
475 // adding to the model
476 FunctionalBlock* funBlock = (FunctionalBlock*)block;
477 newBlock = params->getGraph()->duplicateSourceBlock(funBlock);
478 // adding to the view
479 scene->createSourceItem(newBlock);
481 params->unsaveModif = true;
485 void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
486 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
488 cout << "call to " << qPrintable(fctName) << endl;
491 AbstractInterface *refI = item->refInter;
492 if (! refI->isFunctionalInterface()) return;
494 AbstractBlock *refB = refI->getOwner();
495 if(! refB->isFunctionalBlock()) return;
497 FunctionalInterface* iface = (FunctionalInterface*)refI;
498 AbstractInterface *cloneIface = iface->clone();
499 if (cloneIface == NULL) {
500 QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
504 refB->addInterface(cloneIface);
506 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
507 item->getOwner()->addInterfaceItem(cloneIfaceItem,true);
509 // creating control interface if needed
510 if (refI->getAssociatedIface() != NULL) {
511 QString ctlName = cloneIface->getName()+"_enb";
512 ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,cloneIface->getDirection(), AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
513 refB->addInterface(ctlIface);
514 if (! ctlIface->setAssociatedIface(cloneIface)) {
515 cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
521 BoxItem* Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
522 static QString fctName = "Dispatcher::addBlock()";
524 cout << "call to " << qPrintable(fctName) << endl;
526 bool newSource = false;
527 BoxItem* item = NULL;
528 GroupScene *scene = getSceneById(idScene);
529 ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
530 // if block has no inputs, propose to add it as a source to top scene
531 if ((scene->isTopScene()) && (ref->isGeneratorBlock())) {
532 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 ?");
533 if (ret == QMessageBox::Yes) {
538 FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref);
539 scene->createSourceItem(newOne);
542 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
543 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
544 item = scene->createBoxItem(newOne);
545 params->blockToItem.insert(newOne,item);
547 params->unsaveModif = true;
552 GroupWidget *Dispatcher::createTopScene(){
553 static QString fctName = "Dispatcher::createTopScene()";
555 cout << "call to " << qPrintable(fctName) << endl;
558 // creating the model part of the group
559 Graph* graph = params->createGraph();
560 GroupBlock *topBlock = graph->getTopGroup();
561 // creating the clkrstgen block
562 ReferenceBlock* ref = params->getHiddenReferenceBlock("clkrstgen");
563 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(topBlock, ref);
564 ConnectedInterface* fromIface = AI_TO_CON(topBlock->getIfaceFromName("ext_clk"));
565 ConnectedInterface* toIface = AI_TO_CON(newOne->getIfaceFromName("ext_clk"));
566 fromIface->connectTo(toIface);
567 fromIface = AI_TO_CON(topBlock->getIfaceFromName("ext_reset"));
568 toIface = AI_TO_CON(newOne->getIfaceFromName("ext_reset"));
569 fromIface->connectTo(toIface);
571 // creating a fake and not connected interface
572 //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
574 // creating the group widget
575 topGroup = new GroupWidget(NULL,this,params);
576 currentGroup = topGroup;
577 // getting the newly created scene
578 GroupScene *scene = topGroup->getScene();
579 scene->setId(sceneCounter++);
580 params->setTopScene(scene);
581 params->setCurrentScene(scene);
582 // creating the view part of the group
583 GroupItem *group = new GroupItem(NULL,topBlock,this,params);
586 // adding the fake interface to the top group item
587 //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
588 //group->addInterface(item,true);
590 scene->setGroupItem(group);
592 groupList.append(topGroup);
596 GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
597 static QString fctName = "Dispatcher::addNewEmptyGroup();";
599 cout << "call to " << qPrintable(fctName) << endl;
602 // getting the parent block in the graph
603 GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
604 cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
605 GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent);
606 cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
607 // creating the BlockItem in the scene
608 BoxItem* newItem = scene->createBoxItem(groupBlock);
610 params->unsaveModif = true;
612 GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
613 if (show) child->show();
618 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
619 static QString fctName = "Dispatcher::createChildScene()";
621 cout << "call to " << qPrintable(fctName) << endl;
624 GroupWidget* group = NULL;
625 /* NB: this method may be called during design process or when loading
626 a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
627 cannot be initialized yet. This is why there are 2 cases below
630 if (upperItemOfGroupItem != NULL) {
631 // getting back the goup block already created
632 GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
633 // creating the view part of the group
634 GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
636 // creating the group widget
637 group = new GroupWidget(parentWidget, this, params);
638 // getting the newly created scene
639 GroupScene *scene = group->getScene();
640 scene->setId(sceneCounter++);
641 // affecting group item to the scene
642 scene->setGroupItem(groupItem);
643 groupList.append(group);
645 mainWindow->getLibrary()->updateComboScene();
648 GroupItem *groupItem = new GroupItem(this,params);
649 // creating the group widget
650 group = new GroupWidget(parentWidget, this, params);
651 // getting the newly created scene
652 GroupScene *scene = group->getScene();
653 // affecting group item to the scene
654 scene->setGroupItem(groupItem);
655 groupList.append(group);
660 void Dispatcher::destroyScene(GroupScene *scene) {
661 foreach(GroupScene* s, scene->getChildrenScene()) {
665 if (scene->getNbChildScene() == 0) {
666 // remove scene from the parent list, if possible
667 if (scene->getParentScene() != NULL) {
668 scene->getParentScene()->removeChildScene(scene);
670 // destroy the GroupWidget
671 groupList.removeAll(scene->getGroupWidget());
672 scene->getGroupWidget()->deleteLater();
675 cerr << "Abnormal case when destroying a scene" << endl;
679 void Dispatcher::showRaiseWindow(BoxItem *item) {
680 static QString fctName = "Dispatcher::showRaiseWindow()";
682 cout << "call to " << qPrintable(fctName) << endl;
685 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
686 GroupItem* child = item->getChildGroupItem();
688 cerr << "abnormal case: child group item is null " << endl;
692 GroupWidget* win = child->getScene()->getGroupWidget();
696 win->activateWindow();
699 params->setCurrentScene(currentGroup->getScene());
702 void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
703 static QString fctName = "Dispatcher::showRstClkIface()";
705 cout << "call to " << qPrintable(fctName) << endl;
708 item->setRstClkVisible(!item->isRstClkVisible());
712 void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
713 static QString fctName = "Dispatcher::showWishboneIface()";
715 cout << "call to " << qPrintable(fctName) << endl;
718 item->setWishboneVisible(!item->isWishboneVisible());
721 void Dispatcher::addNewFullGroup() {
722 static QString fctName = "Dispatcher::addNewFullGroup()";
724 cout << "call to " << qPrintable(fctName) << endl;
730 QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
731 QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
732 QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
734 /* What must be done:
735 1 - creating a new GroupBlock
736 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
737 3 - creating a BlockItem that references the new GroupBlock
738 4 - creating a new GroupWidget
739 5 - creating a new GroupItem added to the scene of the GroupWidget
743 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
744 associated to the GroupItem of the current scene
746 GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
747 GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
748 /* step 2: moving selected blocks */
749 foreach(BlockItem* blockItem, listBlocks) {
750 parentBlock->removeBlock(blockItem->getRefBlock());
751 newGroupBlock->addBlock(blockItem->getRefBlock());
754 GroupItem *parent = currentGroup->getScene()->getGroupItem();
755 GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
756 BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
757 GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
759 //create the new window
760 GroupWidget* win = new GroupWidget(this,params);
761 win->getScene()->setGroupItem(groupItem);
762 win->getScene()->addItem(groupItem);
763 ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
764 params->addWindow(win);
768 params->getCurrentScene()->addBlockItem(blockItem);
769 params->getCurrentScene()->addItem(blockItem);
770 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
772 //replace selected blocks in the group
773 foreach(AbstractBoxItem *block, listBlocks){
774 ((GroupItem*)block->getParentItem())->removeBlockItem(block);
775 ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
776 params->getCurrentScene()->removeItem(block);
777 params->getCurrentScene()->removeBlockItem(block);
779 groupBlock->addBlock(block->getRefBlock());
780 listAbstractBlocks.append(block->getRefBlock());
782 block->setUpperItem(groupItem);
783 groupItem->addBlockItem(block);
784 win->getScene()->addItem(block);
785 win->getScene()->addBlockItem(block);
788 //replace connection between selected blocks in the group
789 foreach(ConnectionItem *conn, connections){
790 if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
791 if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
792 parent->removeConnection(conn);
793 params->getCurrentScene()->removeItem(conn);
795 groupItem->addConnection(conn);
796 win->getScene()->addItem(conn);
801 //create new interfaces and connections for the new group
802 foreach(AbstractBoxItem *block, listBlocks){
803 foreach(InterfaceItem *inter, block->getInterfaces()){
804 cout << "inter : " << inter->getName().toStdString() << endl;
805 if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
806 cout << "connected from non null" << endl;
807 if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
809 AbstractInterface *iface = inter->refInter->clone(0);
810 iface->setName(iface->getName()+"_group");
811 groupBlock->addInterface(iface);
813 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
814 blockItem->addInterface(ifaceItem);
815 blockItem->resetInterfacesPosition();
817 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
818 groupItem->addInterface(ifaceGroupItem);
819 groupItem->resetInterfacesPosition();
820 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
821 if(conn->getToInterfaceItem() == inter){
822 conn->setToInterfaceItem(ifaceItem);
823 ifaceItem->refInter->setConnectedFrom(NULL);
824 conn->getFromInterfaceItem()->refInter->clearConnectedTo();
825 connect(ifaceItem,conn->getFromInterfaceItem());
828 params->setCurrentWindow(win);
830 inter->refInter->setConnectedFrom(NULL);
831 ifaceGroupItem->refInter->clearConnectedTo();
832 connect(inter,ifaceGroupItem);
833 params->setCurrentWindow(mainWindow);
837 if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
838 cout << "connected to non null" << endl;
839 foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
840 if(!listAbstractBlocks.contains(iface->getOwner())){
842 AbstractInterface *iface = inter->refInter->clone(0);
843 iface->setName(iface->getName()+"_group");
844 groupBlock->addInterface(iface);
846 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
847 blockItem->addInterface(ifaceItem);
848 blockItem->resetInterfacesPosition();
850 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
851 if(conn->getFromInterfaceItem() == inter){
852 conn->setFromInterfaceItem(ifaceItem);
853 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
854 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
858 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
859 groupItem->addInterface(ifaceGroupItem);
860 groupItem->resetInterfacesPosition();
861 inter->refInter->clearConnectedTo();
862 ifaceGroupItem->refInter->setConnectedFrom(NULL);
863 connect(ifaceGroupItem,inter);
872 parent->updateShape();
873 currentGroup->getScene()->updateConnectionItemsShape();
875 groupItem->updateShape();
876 win->getScene()->updateConnectionItemsShape();
877 groupItem->update(groupItem->boundingRect());
882 void Dispatcher::removeBoxItem(BoxItem *item) {
883 static QString fctName = "Dispatcher::removeBoxItem()";
885 cout << "call to " << qPrintable(fctName) << endl;
888 /* a BoxItem (group of func) can be removed only if none of its
889 interfaces is connected to a group interface that is itself
890 connected to another one.
892 bool canRemove = true;
894 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
895 foreach(ConnectionItem* conn, ifaceItem->connections) {
896 InterfaceItem* other = NULL;
897 if (conn->getFromInterfaceItem() == ifaceItem) {
898 other = conn->getToInterfaceItem();
901 other = conn->getFromInterfaceItem();
904 if (other->getOwner()->isGroupItem()) {
905 ConnectedInterface* ref = other->refInter;
906 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
913 QMessageBox::warning(NULL,"Forbidden operation",
914 "The block has at least one connection to a group interface that is totally connected.",
920 if (item->getRefBlock()->isFunctionalBlock()) {
921 msg = "Removing block ";
924 msg = "Removing group ";
926 msg += item->getRefBlock()->getName();
927 msg += " and all its connections.\n\nAre you sure ?";
929 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
930 if (ret == QMessageBox::Cancel) {
933 removeAllBlockConnections(item);
935 if (item->getRefBlock()->isFunctionalBlock()) {
936 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
937 item->getScene()->removeBoxItem(item);
938 params->getGraph()->removeFunctionalBlock(block);
939 params->blockToItem.remove(block);
942 else if (item->getRefBlock()->isGroupBlock()) {
944 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
946 // remove all child scenes recursively
947 GroupItem* subgroup = item->getChildGroupItem();
948 destroyScene(subgroup->getScene());
949 // remove the BoxItem
950 item->getScene()->removeBoxItem(item);
951 // remove the group from the graph
952 params->getGraph()->removeGroupBlock(group);
956 void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
957 static QString fctName = "Dispatcher::removeAllBlockConnection()";
959 cout << "call to " << qPrintable(fctName) << endl;
962 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
963 foreach(ConnectionItem* conn, ifaceItem->connections) {
964 removeConnection(conn);
969 void Dispatcher::removeSourceItem(SourceItem *item) {
970 static QString fctName = "Dispatcher::removeSourceItem()";
972 cout << "call to " << qPrintable(fctName) << endl;
975 QString msg = "Removing source ";
977 msg += item->getRefBlock()->getName();
978 msg += " and all its connections.\n\nAre you sure ?";
980 int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
981 if (ret == QMessageBox::Cancel) {
984 removeAllBlockConnections(item);
986 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
987 item->getScene()->removeSourceItem(item);
988 params->getGraph()->removeSourceBlock(block);
992 void Dispatcher::removeConnection(ConnectionItem *connItem) {
993 static QString fctName = "Dispatcher::removeConnection()";
995 cout << "call to " << qPrintable(fctName) << endl;
997 InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
998 InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
1001 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
1004 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not
1005 GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem
1007 ConnectedInterface *fromInter = fromIfaceItem->refInter;
1008 ConnectedInterface *toInter = toIfaceItem->refInter;
1010 // test if one of the interface bounded to item is owned by a GroupItem
1011 if (fromIfaceItem->getOwner()->isGroupItem()) {
1012 groupItem = ABI_TO_GI(fromIfaceItem->getOwner());
1013 groupIfaceItem = fromIfaceItem;
1015 else if (toIfaceItem->getOwner()->isGroupItem()) {
1016 groupItem = ABI_TO_GI(toIfaceItem->getOwner());
1017 groupIfaceItem = toIfaceItem;
1020 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
1023 // removing the connection from graph
1025 cout << "removing connections from graph ..." ;
1027 fromInter->disconnectTo(toInter);
1030 cout << "done." << endl ;
1033 // removing the connection from scene
1035 cout << "removing connections from scene ..." ;
1037 groupItem->getScene()->removeConnectionItem(connItem);
1040 cout << "done." << endl ;
1043 // if one of the interface bounded to connItem is owned by the GroupItem of the scene
1044 if (groupIfaceItem != NULL) {
1046 // determine if the interface must be removed since it has no more connections.
1047 bool groupInterRemove = false;
1048 if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true;
1050 if (groupInterRemove) {
1051 // get the GroupInterface from interface item
1052 ConnectedInterface* groupInter = groupIfaceItem->refInter;
1053 // remove interface from GroupItem, and delete it.
1054 groupItem->removeInterfaceItem(groupIfaceItem);
1055 // get the parent BoxItem of GroupItem if it exists.
1056 BoxItem* parent2Item = groupItem->getParentItem();
1057 if (parent2Item != NULL) {
1058 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter);
1059 // remove interface intem in parent BoxItem
1060 parent2Item->removeInterfaceItem(group2IfaceItem);
1062 // remove GroupInterface in the graph.
1063 groupInter->getOwner()->removeInterface(groupInter);
1068 void Dispatcher::showBlocksLibrary(){
1069 cout << "showing block library" << endl;
1070 mainWindow->getLibrary()->show();
1071 mainWindow->getLibrary()->raise();
1074 void Dispatcher::showProperties(InterfaceItem *inter) {
1075 new InterfacePropertiesWindow(inter);
1078 /* connectInterToGroup() :
1079 The only way for a block (functional of group) within a GroupItem to be connected
1080 to the latter is to right-click on one of its interfaces and to choose "connect to group".
1081 That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
1084 void Dispatcher::connectInterToGroup(InterfaceItem *item){
1086 // getting the GroupBlock and GroupItem that are parent of the block that owns item
1087 ConnectedInterface *refInter = item->refInter;
1088 cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
1089 GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
1090 cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
1091 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
1093 // creating/adding the group interface in the graph model
1094 GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
1095 parentItem->getRefBlock()->addInterface(groupInter);
1096 // creating/adding the group control interface in the graph model if the purpose is data
1097 if (refInter->getPurpose() == AbstractInterface::Data) {
1098 GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
1099 groupCtlInter->setAssociatedIface(groupInter);
1100 parentItem->getRefBlock()->addInterface(groupCtlInter);
1102 // creating/adding the group interface in the current scene model, and connection item
1103 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1104 parentItem->addInterfaceItem(groupIfaceItem,true);
1106 // creating the connection, in graph and with an item
1107 createConnection(item, groupIfaceItem);
1109 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1110 BoxItem* parent2Item = parentItem->getParentItem();
1111 if(parent2Item != NULL){
1112 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1113 parent2Item->addInterfaceItem(blockIfaceItem,true);
1117 parentItem->getScene()->updateConnectionItemsShape();
1119 params->unsaveModif = true;
1122 void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
1123 static QString fctName = "Dispatcher::removeBlockInterface()";
1124 #ifdef DEBUG_FCTNAME
1125 cout << "call to " << qPrintable(fctName) << endl;
1128 /* first, remove all connections from item
1129 NB: if there is a connection to a group interface, then this
1130 method should not be called if the group interface is also
1131 connected to another interface. Normally, this is not possible
1132 because such a check is done when creating the contextual menu
1133 that allows to remove an interface.
1135 foreach(ConnectionItem* conn, item->connections) {
1136 removeConnection(conn);
1139 ConnectedInterface* ref = item->refInter;
1140 item->getOwner()->removeInterfaceItem(item);
1141 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1142 fun->removeInterface(ref);
1145 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
1146 static QString fctName = "Dispatcher::removeGroupInterface()";
1147 #ifdef DEBUG_FCTNAME
1148 cout << "call to " << qPrintable(fctName) << endl;
1151 /* NB: just remove all connections from/to this item, since when there are no more
1152 ones to a GroupItem, it is automatically deleted.
1154 foreach(ConnectionItem* conn, item->connections) {
1155 removeConnection(conn);
1159 QMap<int, QString> Dispatcher::getAllGroupNames() {
1161 QMap<int, QString> list;
1162 foreach(GroupWidget *group, groupList) {
1163 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1168 GroupScene* Dispatcher::getSceneById(int id) {
1169 foreach(GroupWidget *group, groupList){
1170 if(group->getScene()->getId() == id)
1171 return group->getScene();
1173 cout << "search scene by id :" << id << " :: not found..." << endl;
1177 GroupItem *Dispatcher::getGroupItemById(int id) {
1178 foreach(GroupWidget *group, groupList) {
1179 GroupScene* scene = group->getScene();
1180 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1182 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1186 BoxItem *Dispatcher::getBoxItemById(int id) {
1187 foreach(GroupWidget *group, groupList) {
1189 GroupScene* scene = group->getScene();
1190 foreach(BoxItem *item, scene->getBoxItems()){
1191 if(item->getId() == id){
1196 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1200 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1202 foreach(GroupWidget *group, groupList) {
1204 GroupScene* scene = group->getScene();
1206 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1207 if(item->getId() == id){
1211 foreach(BoxItem *block, scene->getBoxItems()){
1212 foreach(InterfaceItem *item, block->getInterfaces()){
1213 if(item->getId() == id){
1219 cout << "search interface by id :" << id << " :: not found..." << endl;
1223 void Dispatcher::findGraphModifications(FunctionalBlock *block) {
1224 static QString fctName = "Dispatcher::findGraphModifications()";
1225 #ifdef DEBUG_FCTNAME
1226 cout << "call to " << qPrintable(fctName) << endl;
1229 block->computeAdmittanceDelays();
1230 // get the block item that is associated to block
1231 BoxItem* toBlockItem = params->blockToItem.value(block);
1233 /* VERSION 1: just add delays if needed */
1234 QMap<AbstractInterface*,QList<int>* > delays = block->getAdmittanceDelays();
1235 QMapIterator<AbstractInterface*,QList<int>* > iterD(delays);
1236 while (iterD.hasNext()) {
1238 QList<int>* delay = iterD.value();
1239 if (delay->at(0) > 0) {
1240 // create delay and associate it to the connected input
1242 ConnectedInterface* toIface = AI_TO_CON(iterD.key());
1243 AbstractInputModifier* mod = new DelayInputModifier(toIface, delay->at(0));
1244 cout << "modify input of " << qPrintable(toIface->getName()) << endl;
1245 toIface->setInputModifier(mod);
1247 toBlockItem->update();