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, bool visible) {
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, visible);
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,params->projectPath);
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 // get the precursor output pattern
375 ConnectedInterface* connIface = AI_TO_CON(item->refInter->getAssociatedIface());
376 QList<char>* out = connIface->getConnectedFrom()->getOutputPattern();
378 AbstractInputModifier* modifier = connIface->getInputModifier();
379 // check if the input is modified
380 if (modifier != NULL) {
382 out = modifier->getModifiedInput(out);
385 foreach(char c, *out) {
386 msg += QString::number((int)c);
390 else if (item->refInter->getDirection() == AbstractInterface::Output) {
391 msg = "Output pattern of iface ";
392 msg += item->refInter->getName();
394 msg += item->refInter->getOwner()->getName();
396 ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
397 if (iface->getOutputPattern() == NULL) return;
398 foreach(char c, *(iface->getOutputPattern())) {
399 msg += QString::number((int)c);
403 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
406 void Dispatcher::showModifier(InterfaceItem *item) {
407 static QString fctName = "Dispatcher::showModifier()";
409 cout << "call to " << qPrintable(fctName) << endl;
412 ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
413 AbstractInputModifier* mod = assoIface->getInputModifier();
414 if (mod->isDelay()) {
415 DelayInputModifier* delay = (DelayInputModifier *)mod;
416 msg = "Pattern of iface ";
417 msg += item->refInter->getName();
419 msg += item->refInter->getOwner()->getName();
420 msg += " is modified by a simple delay of ";
421 msg += QString::number(delay->getDelayLength());
424 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
427 void Dispatcher::removeModifier(InterfaceItem *item) {
428 static QString fctName = "Dispatcher::showModifier()";
430 cout << "call to " << qPrintable(fctName) << endl;
433 ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
434 assoIface->clearInputModifier();
438 void Dispatcher::duplicateBoxItem(BoxItem *item){
439 static QString fctName = "Dispatcher::duplicateBoxItem()";
441 cout << "call to " << qPrintable(fctName) << endl;
444 GroupScene *scene = item->getScene();
445 AbstractBlock* block = item->getRefBlock();
446 AbstractBlock *newBlock;
448 // only duplicate functional blocks
449 if(block->isFunctionalBlock()) {
451 // adding to the model
452 FunctionalBlock* funBlock = (FunctionalBlock*)block;
453 newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
454 // adding to the view
455 scene->createBoxItem(newBlock);
457 params->unsaveModif = true;
461 void Dispatcher::duplicateSourceItem(SourceItem *item) {
462 static QString fctName = "Dispatcher::duplicateSourceItem()";
464 cout << "call to " << qPrintable(fctName) << endl;
467 GroupScene *scene = item->getScene();
468 AbstractBlock* block = item->getRefBlock();
469 AbstractBlock *newBlock;
471 // only duplicate functional blocks
472 if(block->isFunctionalBlock()) {
474 // adding to the model
475 FunctionalBlock* funBlock = (FunctionalBlock*)block;
476 newBlock = params->getGraph()->duplicateSourceBlock(funBlock);
477 // adding to the view
478 scene->createSourceItem(newBlock);
480 params->unsaveModif = true;
484 void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
485 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
487 cout << "call to " << qPrintable(fctName) << endl;
490 AbstractInterface *refI = item->refInter;
491 if (! refI->isFunctionalInterface()) return;
493 AbstractBlock *refB = refI->getOwner();
494 if(! refB->isFunctionalBlock()) return;
496 FunctionalInterface* iface = (FunctionalInterface*)refI;
497 AbstractInterface *cloneIface = iface->clone();
498 if (cloneIface == NULL) {
499 QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
503 refB->addInterface(cloneIface);
505 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
506 item->getOwner()->addInterfaceItem(cloneIfaceItem,true);
508 // creating control interface if needed
509 if (refI->getAssociatedIface() != NULL) {
510 QString ctlName = cloneIface->getName()+"_enb";
511 ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,cloneIface->getDirection(), AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
512 refB->addInterface(ctlIface);
513 if (! ctlIface->setAssociatedIface(cloneIface)) {
514 cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
520 BoxItem* Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
521 static QString fctName = "Dispatcher::addBlock()";
523 cout << "call to " << qPrintable(fctName) << endl;
525 bool newSource = false;
526 BoxItem* item = NULL;
527 GroupScene *scene = getSceneById(idScene);
528 ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
529 // if block has no inputs, propose to add it as a source to top scene
530 if ((scene->isTopScene()) && (ref->isGeneratorBlock())) {
531 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 ?");
532 if (ret == QMessageBox::Yes) {
537 FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref);
538 scene->createSourceItem(newOne);
541 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
542 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
543 item = scene->createBoxItem(newOne);
544 params->blockToItem.insert(newOne,item);
546 params->unsaveModif = true;
551 GroupWidget *Dispatcher::createTopScene(){
552 static QString fctName = "Dispatcher::createTopScene()";
554 cout << "call to " << qPrintable(fctName) << endl;
557 // creating the model part of the group
558 Graph* graph = params->createGraph();
559 GroupBlock *topBlock = graph->getTopGroup();
560 // creating the clkrstgen block
561 ReferenceBlock* ref = params->getHiddenReferenceBlock("clkrstgen");
562 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(topBlock, ref);
563 ConnectedInterface* fromIface = AI_TO_CON(topBlock->getIfaceFromName("ext_clk"));
564 ConnectedInterface* toIface = AI_TO_CON(newOne->getIfaceFromName("ext_clk"));
565 fromIface->connectTo(toIface);
566 fromIface = AI_TO_CON(topBlock->getIfaceFromName("ext_reset"));
567 toIface = AI_TO_CON(newOne->getIfaceFromName("ext_reset"));
568 fromIface->connectTo(toIface);
570 // creating a fake and not connected interface
571 //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
573 // creating the group widget
574 topGroup = new GroupWidget(NULL,this,params);
575 currentGroup = topGroup;
576 // getting the newly created scene
577 GroupScene *scene = topGroup->getScene();
578 scene->setId(sceneCounter++);
579 params->setTopScene(scene);
580 params->setCurrentScene(scene);
581 // creating the view part of the group
582 GroupItem *group = new GroupItem(NULL,topBlock,this,params);
585 // adding the fake interface to the top group item
586 //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
587 //group->addInterface(item,true);
589 scene->setGroupItem(group);
591 groupList.append(topGroup);
595 GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
596 static QString fctName = "Dispatcher::addNewEmptyGroup();";
598 cout << "call to " << qPrintable(fctName) << endl;
601 // getting the parent block in the graph
602 GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
603 cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
604 GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent);
605 cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
606 // creating the BlockItem in the scene
607 BoxItem* newItem = scene->createBoxItem(groupBlock);
609 params->unsaveModif = true;
611 GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
612 if (show) child->show();
617 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
618 static QString fctName = "Dispatcher::createChildScene()";
620 cout << "call to " << qPrintable(fctName) << endl;
623 GroupWidget* group = NULL;
624 /* NB: this method may be called during design process or when loading
625 a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
626 cannot be initialized yet. This is why there are 2 cases below
629 if (upperItemOfGroupItem != NULL) {
630 // getting back the goup block already created
631 GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
632 // creating the view part of the group
633 GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
635 // creating the group widget
636 group = new GroupWidget(parentWidget, this, params);
637 // getting the newly created scene
638 GroupScene *scene = group->getScene();
639 scene->setId(sceneCounter++);
640 // affecting group item to the scene
641 scene->setGroupItem(groupItem);
642 groupList.append(group);
644 mainWindow->getLibrary()->updateComboScene();
647 GroupItem *groupItem = new GroupItem(this,params);
648 // creating the group widget
649 group = new GroupWidget(parentWidget, this, params);
650 // getting the newly created scene
651 GroupScene *scene = group->getScene();
652 // affecting group item to the scene
653 scene->setGroupItem(groupItem);
654 groupList.append(group);
659 void Dispatcher::destroyScene(GroupScene *scene) {
660 foreach(GroupScene* s, scene->getChildrenScene()) {
664 if (scene->getNbChildScene() == 0) {
665 // remove scene from the parent list, if possible
666 if (scene->getParentScene() != NULL) {
667 scene->getParentScene()->removeChildScene(scene);
669 // destroy the GroupWidget
670 groupList.removeAll(scene->getGroupWidget());
671 scene->getGroupWidget()->deleteLater();
674 cerr << "Abnormal case when destroying a scene" << endl;
678 void Dispatcher::showRaiseWindow(BoxItem *item) {
679 static QString fctName = "Dispatcher::showRaiseWindow()";
681 cout << "call to " << qPrintable(fctName) << endl;
684 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
685 GroupItem* child = item->getChildGroupItem();
687 cerr << "abnormal case: child group item is null " << endl;
691 GroupWidget* win = child->getScene()->getGroupWidget();
695 win->activateWindow();
698 params->setCurrentScene(currentGroup->getScene());
701 void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
702 static QString fctName = "Dispatcher::showRstClkIface()";
704 cout << "call to " << qPrintable(fctName) << endl;
707 item->setRstClkVisible(!item->isRstClkVisible());
711 void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
712 static QString fctName = "Dispatcher::showWishboneIface()";
714 cout << "call to " << qPrintable(fctName) << endl;
717 item->setWishboneVisible(!item->isWishboneVisible());
720 void Dispatcher::addNewFullGroup() {
721 static QString fctName = "Dispatcher::addNewFullGroup()";
723 cout << "call to " << qPrintable(fctName) << endl;
729 QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
730 QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
731 QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
733 /* What must be done:
734 1 - creating a new GroupBlock
735 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
736 3 - creating a BlockItem that references the new GroupBlock
737 4 - creating a new GroupWidget
738 5 - creating a new GroupItem added to the scene of the GroupWidget
742 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
743 associated to the GroupItem of the current scene
745 GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
746 GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
747 /* step 2: moving selected blocks */
748 foreach(BlockItem* blockItem, listBlocks) {
749 parentBlock->removeBlock(blockItem->getRefBlock());
750 newGroupBlock->addBlock(blockItem->getRefBlock());
753 GroupItem *parent = currentGroup->getScene()->getGroupItem();
754 GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
755 BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
756 GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
758 //create the new window
759 GroupWidget* win = new GroupWidget(this,params);
760 win->getScene()->setGroupItem(groupItem);
761 win->getScene()->addItem(groupItem);
762 ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
763 params->addWindow(win);
767 params->getCurrentScene()->addBlockItem(blockItem);
768 params->getCurrentScene()->addItem(blockItem);
769 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
771 //replace selected blocks in the group
772 foreach(AbstractBoxItem *block, listBlocks){
773 ((GroupItem*)block->getParentItem())->removeBlockItem(block);
774 ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
775 params->getCurrentScene()->removeItem(block);
776 params->getCurrentScene()->removeBlockItem(block);
778 groupBlock->addBlock(block->getRefBlock());
779 listAbstractBlocks.append(block->getRefBlock());
781 block->setUpperItem(groupItem);
782 groupItem->addBlockItem(block);
783 win->getScene()->addItem(block);
784 win->getScene()->addBlockItem(block);
787 //replace connection between selected blocks in the group
788 foreach(ConnectionItem *conn, connections){
789 if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
790 if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
791 parent->removeConnection(conn);
792 params->getCurrentScene()->removeItem(conn);
794 groupItem->addConnection(conn);
795 win->getScene()->addItem(conn);
800 //create new interfaces and connections for the new group
801 foreach(AbstractBoxItem *block, listBlocks){
802 foreach(InterfaceItem *inter, block->getInterfaces()){
803 cout << "inter : " << inter->getName().toStdString() << endl;
804 if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
805 cout << "connected from non null" << endl;
806 if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
808 AbstractInterface *iface = inter->refInter->clone(0);
809 iface->setName(iface->getName()+"_group");
810 groupBlock->addInterface(iface);
812 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
813 blockItem->addInterface(ifaceItem);
814 blockItem->resetInterfacesPosition();
816 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
817 groupItem->addInterface(ifaceGroupItem);
818 groupItem->resetInterfacesPosition();
819 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
820 if(conn->getToInterfaceItem() == inter){
821 conn->setToInterfaceItem(ifaceItem);
822 ifaceItem->refInter->setConnectedFrom(NULL);
823 conn->getFromInterfaceItem()->refInter->clearConnectedTo();
824 connect(ifaceItem,conn->getFromInterfaceItem());
827 params->setCurrentWindow(win);
829 inter->refInter->setConnectedFrom(NULL);
830 ifaceGroupItem->refInter->clearConnectedTo();
831 connect(inter,ifaceGroupItem);
832 params->setCurrentWindow(mainWindow);
836 if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
837 cout << "connected to non null" << endl;
838 foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
839 if(!listAbstractBlocks.contains(iface->getOwner())){
841 AbstractInterface *iface = inter->refInter->clone(0);
842 iface->setName(iface->getName()+"_group");
843 groupBlock->addInterface(iface);
845 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
846 blockItem->addInterface(ifaceItem);
847 blockItem->resetInterfacesPosition();
849 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
850 if(conn->getFromInterfaceItem() == inter){
851 conn->setFromInterfaceItem(ifaceItem);
852 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
853 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
857 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
858 groupItem->addInterface(ifaceGroupItem);
859 groupItem->resetInterfacesPosition();
860 inter->refInter->clearConnectedTo();
861 ifaceGroupItem->refInter->setConnectedFrom(NULL);
862 connect(ifaceGroupItem,inter);
871 parent->updateShape();
872 currentGroup->getScene()->updateConnectionItemsShape();
874 groupItem->updateShape();
875 win->getScene()->updateConnectionItemsShape();
876 groupItem->update(groupItem->boundingRect());
881 void Dispatcher::removeBoxItem(BoxItem *item) {
882 static QString fctName = "Dispatcher::removeBoxItem()";
884 cout << "call to " << qPrintable(fctName) << endl;
887 /* a BoxItem (group of func) can be removed only if none of its
888 interfaces is connected to a group interface that is itself
889 connected to another one.
891 bool canRemove = true;
893 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
894 foreach(ConnectionItem* conn, ifaceItem->connections) {
895 InterfaceItem* other = NULL;
896 if (conn->getFromInterfaceItem() == ifaceItem) {
897 other = conn->getToInterfaceItem();
900 other = conn->getFromInterfaceItem();
903 if (other->getOwner()->isGroupItem()) {
904 ConnectedInterface* ref = other->refInter;
905 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
912 QMessageBox::warning(NULL,"Forbidden operation",
913 "The block has at least one connection to a group interface that is totally connected.",
919 if (item->getRefBlock()->isFunctionalBlock()) {
920 msg = "Removing block ";
923 msg = "Removing group ";
925 msg += item->getRefBlock()->getName();
926 msg += " and all its connections.\n\nAre you sure ?";
928 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
929 if (ret == QMessageBox::Cancel) {
932 removeAllBlockConnections(item);
934 if (item->getRefBlock()->isFunctionalBlock()) {
935 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
936 item->getScene()->removeBoxItem(item);
937 params->getGraph()->removeFunctionalBlock(block);
938 params->blockToItem.remove(block);
941 else if (item->getRefBlock()->isGroupBlock()) {
943 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
945 // remove all child scenes recursively
946 GroupItem* subgroup = item->getChildGroupItem();
947 destroyScene(subgroup->getScene());
948 // remove the BoxItem
949 item->getScene()->removeBoxItem(item);
950 // remove the group from the graph
951 params->getGraph()->removeGroupBlock(group);
955 void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
956 static QString fctName = "Dispatcher::removeAllBlockConnection()";
958 cout << "call to " << qPrintable(fctName) << endl;
961 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
962 foreach(ConnectionItem* conn, ifaceItem->connections) {
963 removeConnection(conn);
968 void Dispatcher::removeSourceItem(SourceItem *item) {
969 static QString fctName = "Dispatcher::removeSourceItem()";
971 cout << "call to " << qPrintable(fctName) << endl;
974 QString msg = "Removing source ";
976 msg += item->getRefBlock()->getName();
977 msg += " and all its connections.\n\nAre you sure ?";
979 int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
980 if (ret == QMessageBox::Cancel) {
983 removeAllBlockConnections(item);
985 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
986 item->getScene()->removeSourceItem(item);
987 params->getGraph()->removeSourceBlock(block);
991 void Dispatcher::removeConnection(ConnectionItem *connItem) {
992 static QString fctName = "Dispatcher::removeConnection()";
994 cout << "call to " << qPrintable(fctName) << endl;
996 InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
997 InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
1000 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
1003 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not
1004 GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem
1006 ConnectedInterface *fromInter = fromIfaceItem->refInter;
1007 ConnectedInterface *toInter = toIfaceItem->refInter;
1009 // test if one of the interface bounded to item is owned by a GroupItem
1010 if (fromIfaceItem->getOwner()->isGroupItem()) {
1011 groupItem = ABI_TO_GI(fromIfaceItem->getOwner());
1012 groupIfaceItem = fromIfaceItem;
1014 else if (toIfaceItem->getOwner()->isGroupItem()) {
1015 groupItem = ABI_TO_GI(toIfaceItem->getOwner());
1016 groupIfaceItem = toIfaceItem;
1019 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
1022 // removing the connection from graph
1024 cout << "removing connections from graph ..." ;
1026 fromInter->disconnectTo(toInter);
1029 cout << "done." << endl ;
1032 // removing the connection from scene
1034 cout << "removing connections from scene ..." ;
1036 groupItem->getScene()->removeConnectionItem(connItem);
1039 cout << "done." << endl ;
1042 // if one of the interface bounded to connItem is owned by the GroupItem of the scene
1043 if (groupIfaceItem != NULL) {
1045 // determine if the interface must be removed since it has no more connections.
1046 bool groupInterRemove = false;
1047 if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true;
1049 if (groupInterRemove) {
1050 // get the GroupInterface from interface item
1051 ConnectedInterface* groupInter = groupIfaceItem->refInter;
1052 // remove interface from GroupItem, and delete it.
1053 groupItem->removeInterfaceItem(groupIfaceItem);
1054 // get the parent BoxItem of GroupItem if it exists.
1055 BoxItem* parent2Item = groupItem->getParentItem();
1056 if (parent2Item != NULL) {
1057 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter);
1058 // remove interface intem in parent BoxItem
1059 parent2Item->removeInterfaceItem(group2IfaceItem);
1061 // remove GroupInterface in the graph.
1062 groupInter->getOwner()->removeInterface(groupInter);
1067 void Dispatcher::showBlocksLibrary(){
1068 cout << "showing block library" << endl;
1069 mainWindow->getLibrary()->show();
1070 mainWindow->getLibrary()->raise();
1073 void Dispatcher::showProperties(InterfaceItem *inter) {
1074 new InterfacePropertiesWindow(inter);
1077 /* connectInterToGroup() :
1078 The only way for a block (functional of group) within a GroupItem to be connected
1079 to the latter is to right-click on one of its interfaces and to choose "connect to group".
1080 That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
1083 void Dispatcher::connectInterToGroup(InterfaceItem *item){
1085 // getting the GroupBlock and GroupItem that are parent of the block that owns item
1086 ConnectedInterface *refInter = item->refInter;
1087 cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
1088 GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
1089 cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
1090 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
1092 // creating/adding the group interface in the graph model
1093 GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
1094 parentItem->getRefBlock()->addInterface(groupInter);
1095 // creating/adding the group control interface in the graph model if the purpose is data
1096 if (refInter->getPurpose() == AbstractInterface::Data) {
1097 GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
1098 groupCtlInter->setAssociatedIface(groupInter);
1099 parentItem->getRefBlock()->addInterface(groupCtlInter);
1101 // creating/adding the group interface in the current scene model, and connection item
1102 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1103 parentItem->addInterfaceItem(groupIfaceItem,true);
1105 // creating the connection, in graph and with an item
1106 createConnection(item, groupIfaceItem);
1108 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1109 BoxItem* parent2Item = parentItem->getParentItem();
1110 if(parent2Item != NULL){
1111 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1112 parent2Item->addInterfaceItem(blockIfaceItem,true);
1116 parentItem->getScene()->updateConnectionItemsShape();
1118 params->unsaveModif = true;
1121 void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
1122 static QString fctName = "Dispatcher::removeBlockInterface()";
1123 #ifdef DEBUG_FCTNAME
1124 cout << "call to " << qPrintable(fctName) << endl;
1127 /* first, remove all connections from item
1128 NB: if there is a connection to a group interface, then this
1129 method should not be called if the group interface is also
1130 connected to another interface. Normally, this is not possible
1131 because such a check is done when creating the contextual menu
1132 that allows to remove an interface.
1134 foreach(ConnectionItem* conn, item->connections) {
1135 removeConnection(conn);
1138 ConnectedInterface* ref = item->refInter;
1139 item->getOwner()->removeInterfaceItem(item);
1140 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1141 fun->removeInterface(ref);
1144 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
1145 static QString fctName = "Dispatcher::removeGroupInterface()";
1146 #ifdef DEBUG_FCTNAME
1147 cout << "call to " << qPrintable(fctName) << endl;
1150 /* NB: just remove all connections from/to this item, since when there are no more
1151 ones to a GroupItem, it is automatically deleted.
1153 foreach(ConnectionItem* conn, item->connections) {
1154 removeConnection(conn);
1158 QMap<int, QString> Dispatcher::getAllGroupNames() {
1160 QMap<int, QString> list;
1161 foreach(GroupWidget *group, groupList) {
1162 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1167 GroupScene* Dispatcher::getSceneById(int id) {
1168 foreach(GroupWidget *group, groupList){
1169 if(group->getScene()->getId() == id)
1170 return group->getScene();
1172 cout << "search scene by id :" << id << " :: not found..." << endl;
1176 GroupItem *Dispatcher::getGroupItemById(int id) {
1177 foreach(GroupWidget *group, groupList) {
1178 GroupScene* scene = group->getScene();
1179 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1181 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1185 BoxItem *Dispatcher::getBoxItemById(int id) {
1186 foreach(GroupWidget *group, groupList) {
1188 GroupScene* scene = group->getScene();
1189 foreach(BoxItem *item, scene->getBoxItems()){
1190 if(item->getId() == id){
1195 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1199 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1201 foreach(GroupWidget *group, groupList) {
1203 GroupScene* scene = group->getScene();
1205 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1206 if(item->getId() == id){
1210 foreach(BoxItem *block, scene->getBoxItems()){
1211 foreach(InterfaceItem *item, block->getInterfaces()){
1212 if(item->getId() == id){
1218 cout << "search interface by id :" << id << " :: not found..." << endl;
1222 void Dispatcher::findGraphModifications(FunctionalBlock *block) {
1223 static QString fctName = "Dispatcher::findGraphModifications()";
1224 #ifdef DEBUG_FCTNAME
1225 cout << "call to " << qPrintable(fctName) << endl;
1228 block->computeAdmittanceDelays();
1229 // get the block item that is associated to block
1230 BoxItem* toBlockItem = params->blockToItem.value(block);
1232 /* VERSION 1: just add delays if needed */
1233 QMap<AbstractInterface*,QList<int>* > delays = block->getAdmittanceDelays();
1234 QMapIterator<AbstractInterface*,QList<int>* > iterD(delays);
1235 while (iterD.hasNext()) {
1237 QList<int>* delay = iterD.value();
1238 if (delay->at(0) > 0) {
1239 // create delay and associate it to the connected input
1241 ConnectedInterface* toIface = AI_TO_CON(iterD.key());
1242 AbstractInputModifier* mod = new DelayInputModifier(toIface, delay->at(0));
1243 cout << "modify input of " << qPrintable(toIface->getName()) << endl;
1244 toIface->setInputModifier(mod);
1246 toBlockItem->update();