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());
183 block->generateVHDL(params->projectPath);
186 cout << qPrintable(e.getMessage()) << endl;
191 void Dispatcher::renameFunctionalBlock(BoxItem *item){
192 static QString fctName = "Dispatcher::renameFunctionalBlock()";
194 cout << "call to " << qPrintable(fctName) << endl;
197 GroupWidget* win = item->getScene()->getGroupWidget();
202 text = QInputDialog::getText(win, "Rename a functional block",
203 "New name:", QLineEdit::Normal,
204 item->getRefBlock()->getName(), &ok);
207 if (text == item->getRefBlock()->getName()) return;
209 if( (text.isEmpty()) || (text.length() > 30)) {
210 QMessageBox::warning(win,"Error in given name",
211 "the block name must be shorter than 30 characters, cannot be empty",
216 FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
218 QMessageBox::warning(win,"Error in given name",
219 "the name provided is similar to that of another functional block within the group",
226 item->getRefBlock()->setName(text);
230 void Dispatcher::renameGroupBlock(GroupItem *item){
231 static QString fctName = "Dispatcher::renameGroupBlock()";
233 cout << "call to " << qPrintable(fctName) << endl;
236 GroupWidget* win = item->getScene()->getGroupWidget();
241 text = QInputDialog::getText(win, "Rename a group",
242 "New name:", QLineEdit::Normal,
243 item->getRefBlock()->getName(), &ok);
246 if (text == item->getRefBlock()->getName()) return;
248 if( (text.isEmpty()) || (text.length() > 30)) {
249 QMessageBox::warning(win,"Error in given name",
250 "the block name must be shorter than 30 characters, cannot be empty",
255 GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
257 QMessageBox::warning(win,"Error in given name",
258 "the name provided is similar to that of another group",
265 item->getRefBlock()->setName(text);
266 if(item->getScene()->getGroupWidget()->isTopGroup()) {
267 mainWindow->setWindowTitle("blast - "+text);
270 item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
273 mainWindow->getLibrary()->updateComboScene();
276 void Dispatcher::renameSourceBlock(SourceItem *item){
277 static QString fctName = "Dispatcher::renameSourceBlock()";
279 cout << "call to " << qPrintable(fctName) << endl;
282 GroupWidget* win = item->getScene()->getGroupWidget();
287 text = QInputDialog::getText(win, "Rename a source",
288 "New name:", QLineEdit::Normal,
289 item->getRefBlock()->getName(), &ok);
292 if (text == item->getRefBlock()->getName()) return;
294 if( (text.isEmpty()) || (text.length() > 30)) {
295 QMessageBox::warning(win,"Error in given name",
296 "the block name must be shorter than 30 characters, cannot be empty",
301 FunctionalBlock* block = params->getGraph()->getSourceBlockByName(text);
303 QMessageBox::warning(win,"Error in given name",
304 "the name provided is similar to that of another source block within the top group",
311 item->getRefBlock()->setName(text);
316 void Dispatcher::renameInterface(InterfaceItem *item) {
317 static QString fctName = "Dispatcher::renameInterface()";
319 cout << "call to " << qPrintable(fctName) << endl;
322 GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
327 text = QInputDialog::getText(win, "Rename an interface",
328 "New name:", QLineEdit::Normal,
329 item->refInter->getName(), &ok);
333 if (text == item->refInter->getName()) return;
335 if( (text.isEmpty()) || (text.length() > 30)) {
336 QMessageBox::warning(win,"Error in given name",
337 "the interface name must be shorter than 30 characters, cannot be empty",
342 AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
344 QMessageBox::warning(win,"Error in given name",
345 "the name provided is similar to that of another interface",
351 item->refInter->setName(text);
352 AbstractInterface* assoIface = item->refInter->getAssociatedIface();
353 if (assoIface != NULL) {
354 assoIface->setName(text+"_enb");
356 item->updateName(text);
357 item->getOwner()->nameChanged();
360 void Dispatcher::showPatterns(InterfaceItem *item) {
361 static QString fctName = "Dispatcher::showPatterns()";
363 cout << "call to " << qPrintable(fctName) << endl;
366 if (item->refInter->getDirection() == AbstractInterface::Input) {
367 msg = "Input pattern of iface ";
368 msg += item->refInter->getName();
370 msg += item->refInter->getOwner()->getName();
372 // get the precursor output pattern
373 ConnectedInterface* connIface = AI_TO_CON(item->refInter->getAssociatedIface());
374 QList<char>* out = connIface->getConnectedFrom()->getOutputPattern();
376 AbstractInputModifier* modifier = connIface->getInputModifier();
377 // check if the input is modified
378 if (modifier != NULL) {
380 out = modifier->getModifiedInput(out);
383 foreach(char c, *out) {
384 msg += QString::number((int)c);
388 else if (item->refInter->getDirection() == AbstractInterface::Output) {
389 msg = "Output pattern of iface ";
390 msg += item->refInter->getName();
392 msg += item->refInter->getOwner()->getName();
394 ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
395 if (iface->getOutputPattern() == NULL) return;
396 foreach(char c, *(iface->getOutputPattern())) {
397 msg += QString::number((int)c);
401 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
404 void Dispatcher::showModifier(InterfaceItem *item) {
405 static QString fctName = "Dispatcher::showModifier()";
407 cout << "call to " << qPrintable(fctName) << endl;
410 ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
411 AbstractInputModifier* mod = assoIface->getInputModifier();
412 if (mod->isDelay()) {
413 DelayInputModifier* delay = (DelayInputModifier *)mod;
414 msg = "Pattern of iface ";
415 msg += item->refInter->getName();
417 msg += item->refInter->getOwner()->getName();
418 msg += " is modified by a simple delay of ";
419 msg += QString::number(delay->getDelayLength());
422 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
425 void Dispatcher::removeModifier(InterfaceItem *item) {
426 static QString fctName = "Dispatcher::showModifier()";
428 cout << "call to " << qPrintable(fctName) << endl;
431 ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
432 assoIface->clearInputModifier();
436 void Dispatcher::duplicateBoxItem(BoxItem *item){
437 static QString fctName = "Dispatcher::duplicateBoxItem()";
439 cout << "call to " << qPrintable(fctName) << endl;
442 GroupScene *scene = item->getScene();
443 AbstractBlock* block = item->getRefBlock();
444 AbstractBlock *newBlock;
446 // only duplicate functional blocks
447 if(block->isFunctionalBlock()) {
449 // adding to the model
450 FunctionalBlock* funBlock = (FunctionalBlock*)block;
451 newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
452 // adding to the view
453 scene->createBoxItem(newBlock);
455 params->unsaveModif = true;
459 void Dispatcher::duplicateSourceItem(SourceItem *item) {
460 static QString fctName = "Dispatcher::duplicateSourceItem()";
462 cout << "call to " << qPrintable(fctName) << endl;
465 GroupScene *scene = item->getScene();
466 AbstractBlock* block = item->getRefBlock();
467 AbstractBlock *newBlock;
469 // only duplicate functional blocks
470 if(block->isFunctionalBlock()) {
472 // adding to the model
473 FunctionalBlock* funBlock = (FunctionalBlock*)block;
474 newBlock = params->getGraph()->duplicateSourceBlock(funBlock);
475 // adding to the view
476 scene->createSourceItem(newBlock);
478 params->unsaveModif = true;
482 void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
483 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
485 cout << "call to " << qPrintable(fctName) << endl;
488 AbstractInterface *refI = item->refInter;
489 if (! refI->isFunctionalInterface()) return;
491 AbstractBlock *refB = refI->getOwner();
492 if(! refB->isFunctionalBlock()) return;
494 FunctionalInterface* iface = (FunctionalInterface*)refI;
495 AbstractInterface *cloneIface = iface->clone();
496 if (cloneIface == NULL) {
497 QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
501 refB->addInterface(cloneIface);
503 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
504 item->getOwner()->addInterfaceItem(cloneIfaceItem,true);
506 // creating control interface if needed
507 if (refI->getAssociatedIface() != NULL) {
508 QString ctlName = cloneIface->getName()+"_enb";
509 ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,cloneIface->getDirection(), AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
510 refB->addInterface(ctlIface);
511 if (! ctlIface->setAssociatedIface(cloneIface)) {
512 cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
518 BoxItem* Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
519 static QString fctName = "Dispatcher::addBlock()";
521 cout << "call to " << qPrintable(fctName) << endl;
523 bool newSource = false;
524 BoxItem* item = NULL;
525 GroupScene *scene = getSceneById(idScene);
526 ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
527 // if block has no inputs, propose to add it as a source to top scene
528 if ((scene->isTopScene()) && (ref->isGeneratorBlock())) {
529 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 ?");
530 if (ret == QMessageBox::Yes) {
535 FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref);
536 scene->createSourceItem(newOne);
539 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
540 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
541 item = scene->createBoxItem(newOne);
542 params->blockToItem.insert(newOne,item);
544 params->unsaveModif = true;
549 GroupWidget *Dispatcher::createTopScene(){
550 static QString fctName = "Dispatcher::createTopScene()";
552 cout << "call to " << qPrintable(fctName) << endl;
555 // creating the model part of the group
556 Graph* graph = params->createGraph();
557 GroupBlock *topBlock = graph->getTopGroup();
558 // creating the clkrstgen block
559 ReferenceBlock* ref = params->getHiddenReferenceBlock("clkrstgen");
560 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(topBlock, ref);
561 ConnectedInterface* fromIface = AI_TO_CON(topBlock->getIfaceFromName("ext_clk"));
562 ConnectedInterface* toIface = AI_TO_CON(newOne->getIfaceFromName("ext_clk"));
563 fromIface->connectTo(toIface);
564 fromIface = AI_TO_CON(topBlock->getIfaceFromName("ext_reset"));
565 toIface = AI_TO_CON(newOne->getIfaceFromName("ext_reset"));
566 fromIface->connectTo(toIface);
568 // creating a fake and not connected interface
569 //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
571 // creating the group widget
572 topGroup = new GroupWidget(NULL,this,params);
573 currentGroup = topGroup;
574 // getting the newly created scene
575 GroupScene *scene = topGroup->getScene();
576 scene->setId(sceneCounter++);
577 params->setTopScene(scene);
578 params->setCurrentScene(scene);
579 // creating the view part of the group
580 GroupItem *group = new GroupItem(NULL,topBlock,this,params);
583 // adding the fake interface to the top group item
584 //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
585 //group->addInterface(item,true);
587 scene->setGroupItem(group);
589 groupList.append(topGroup);
593 GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
594 static QString fctName = "Dispatcher::addNewEmptyGroup();";
596 cout << "call to " << qPrintable(fctName) << endl;
599 // getting the parent block in the graph
600 GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
601 cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
602 GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent);
603 cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
604 // creating the BlockItem in the scene
605 BoxItem* newItem = scene->createBoxItem(groupBlock);
607 params->unsaveModif = true;
609 GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
610 if (show) child->show();
615 GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
616 static QString fctName = "Dispatcher::createChildScene()";
618 cout << "call to " << qPrintable(fctName) << endl;
621 GroupWidget* group = NULL;
622 /* NB: this method may be called during design process or when loading
623 a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
624 cannot be initialized yet. This is why there are 2 cases below
627 if (upperItemOfGroupItem != NULL) {
628 // getting back the goup block already created
629 GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
630 // creating the view part of the group
631 GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
633 // creating the group widget
634 group = new GroupWidget(parentWidget, this, params);
635 // getting the newly created scene
636 GroupScene *scene = group->getScene();
637 scene->setId(sceneCounter++);
638 // affecting group item to the scene
639 scene->setGroupItem(groupItem);
640 groupList.append(group);
642 mainWindow->getLibrary()->updateComboScene();
645 GroupItem *groupItem = new GroupItem(this,params);
646 // creating the group widget
647 group = new GroupWidget(parentWidget, this, params);
648 // getting the newly created scene
649 GroupScene *scene = group->getScene();
650 // affecting group item to the scene
651 scene->setGroupItem(groupItem);
652 groupList.append(group);
657 void Dispatcher::destroyScene(GroupScene *scene) {
658 foreach(GroupScene* s, scene->getChildrenScene()) {
662 if (scene->getNbChildScene() == 0) {
663 // remove scene from the parent list, if possible
664 if (scene->getParentScene() != NULL) {
665 scene->getParentScene()->removeChildScene(scene);
667 // destroy the GroupWidget
668 groupList.removeAll(scene->getGroupWidget());
669 scene->getGroupWidget()->deleteLater();
672 cerr << "Abnormal case when destroying a scene" << endl;
676 void Dispatcher::showRaiseWindow(BoxItem *item) {
677 static QString fctName = "Dispatcher::showRaiseWindow()";
679 cout << "call to " << qPrintable(fctName) << endl;
682 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
683 GroupItem* child = item->getChildGroupItem();
685 cerr << "abnormal case: child group item is null " << endl;
689 GroupWidget* win = child->getScene()->getGroupWidget();
693 win->activateWindow();
696 params->setCurrentScene(currentGroup->getScene());
699 void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
700 static QString fctName = "Dispatcher::showRstClkIface()";
702 cout << "call to " << qPrintable(fctName) << endl;
705 item->setRstClkVisible(!item->isRstClkVisible());
709 void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
710 static QString fctName = "Dispatcher::showWishboneIface()";
712 cout << "call to " << qPrintable(fctName) << endl;
715 item->setWishboneVisible(!item->isWishboneVisible());
718 void Dispatcher::addNewFullGroup() {
719 static QString fctName = "Dispatcher::addNewFullGroup()";
721 cout << "call to " << qPrintable(fctName) << endl;
727 QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
728 QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
729 QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
731 /* What must be done:
732 1 - creating a new GroupBlock
733 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
734 3 - creating a BlockItem that references the new GroupBlock
735 4 - creating a new GroupWidget
736 5 - creating a new GroupItem added to the scene of the GroupWidget
740 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
741 associated to the GroupItem of the current scene
743 GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
744 GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
745 /* step 2: moving selected blocks */
746 foreach(BlockItem* blockItem, listBlocks) {
747 parentBlock->removeBlock(blockItem->getRefBlock());
748 newGroupBlock->addBlock(blockItem->getRefBlock());
751 GroupItem *parent = currentGroup->getScene()->getGroupItem();
752 GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
753 BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
754 GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
756 //create the new window
757 GroupWidget* win = new GroupWidget(this,params);
758 win->getScene()->setGroupItem(groupItem);
759 win->getScene()->addItem(groupItem);
760 ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
761 params->addWindow(win);
765 params->getCurrentScene()->addBlockItem(blockItem);
766 params->getCurrentScene()->addItem(blockItem);
767 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
769 //replace selected blocks in the group
770 foreach(AbstractBoxItem *block, listBlocks){
771 ((GroupItem*)block->getParentItem())->removeBlockItem(block);
772 ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
773 params->getCurrentScene()->removeItem(block);
774 params->getCurrentScene()->removeBlockItem(block);
776 groupBlock->addBlock(block->getRefBlock());
777 listAbstractBlocks.append(block->getRefBlock());
779 block->setUpperItem(groupItem);
780 groupItem->addBlockItem(block);
781 win->getScene()->addItem(block);
782 win->getScene()->addBlockItem(block);
785 //replace connection between selected blocks in the group
786 foreach(ConnectionItem *conn, connections){
787 if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
788 if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
789 parent->removeConnection(conn);
790 params->getCurrentScene()->removeItem(conn);
792 groupItem->addConnection(conn);
793 win->getScene()->addItem(conn);
798 //create new interfaces and connections for the new group
799 foreach(AbstractBoxItem *block, listBlocks){
800 foreach(InterfaceItem *inter, block->getInterfaces()){
801 cout << "inter : " << inter->getName().toStdString() << endl;
802 if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
803 cout << "connected from non null" << endl;
804 if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
806 AbstractInterface *iface = inter->refInter->clone(0);
807 iface->setName(iface->getName()+"_group");
808 groupBlock->addInterface(iface);
810 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
811 blockItem->addInterface(ifaceItem);
812 blockItem->resetInterfacesPosition();
814 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
815 groupItem->addInterface(ifaceGroupItem);
816 groupItem->resetInterfacesPosition();
817 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
818 if(conn->getToInterfaceItem() == inter){
819 conn->setToInterfaceItem(ifaceItem);
820 ifaceItem->refInter->setConnectedFrom(NULL);
821 conn->getFromInterfaceItem()->refInter->clearConnectedTo();
822 connect(ifaceItem,conn->getFromInterfaceItem());
825 params->setCurrentWindow(win);
827 inter->refInter->setConnectedFrom(NULL);
828 ifaceGroupItem->refInter->clearConnectedTo();
829 connect(inter,ifaceGroupItem);
830 params->setCurrentWindow(mainWindow);
834 if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
835 cout << "connected to non null" << endl;
836 foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
837 if(!listAbstractBlocks.contains(iface->getOwner())){
839 AbstractInterface *iface = inter->refInter->clone(0);
840 iface->setName(iface->getName()+"_group");
841 groupBlock->addInterface(iface);
843 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
844 blockItem->addInterface(ifaceItem);
845 blockItem->resetInterfacesPosition();
847 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
848 if(conn->getFromInterfaceItem() == inter){
849 conn->setFromInterfaceItem(ifaceItem);
850 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
851 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
855 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
856 groupItem->addInterface(ifaceGroupItem);
857 groupItem->resetInterfacesPosition();
858 inter->refInter->clearConnectedTo();
859 ifaceGroupItem->refInter->setConnectedFrom(NULL);
860 connect(ifaceGroupItem,inter);
869 parent->updateShape();
870 currentGroup->getScene()->updateConnectionItemsShape();
872 groupItem->updateShape();
873 win->getScene()->updateConnectionItemsShape();
874 groupItem->update(groupItem->boundingRect());
879 void Dispatcher::removeBoxItem(BoxItem *item) {
880 static QString fctName = "Dispatcher::removeBoxItem()";
882 cout << "call to " << qPrintable(fctName) << endl;
885 /* a BoxItem (group of func) can be removed only if none of its
886 interfaces is connected to a group interface that is itself
887 connected to another one.
889 bool canRemove = true;
891 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
892 foreach(ConnectionItem* conn, ifaceItem->connections) {
893 InterfaceItem* other = NULL;
894 if (conn->getFromInterfaceItem() == ifaceItem) {
895 other = conn->getToInterfaceItem();
898 other = conn->getFromInterfaceItem();
901 if (other->getOwner()->isGroupItem()) {
902 ConnectedInterface* ref = other->refInter;
903 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
910 QMessageBox::warning(NULL,"Forbidden operation",
911 "The block has at least one connection to a group interface that is totally connected.",
917 if (item->getRefBlock()->isFunctionalBlock()) {
918 msg = "Removing block ";
921 msg = "Removing group ";
923 msg += item->getRefBlock()->getName();
924 msg += " and all its connections.\n\nAre you sure ?";
926 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
927 if (ret == QMessageBox::Cancel) {
930 removeAllBlockConnections(item);
932 if (item->getRefBlock()->isFunctionalBlock()) {
933 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
934 item->getScene()->removeBoxItem(item);
935 params->getGraph()->removeFunctionalBlock(block);
936 params->blockToItem.remove(block);
939 else if (item->getRefBlock()->isGroupBlock()) {
941 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
943 // remove all child scenes recursively
944 GroupItem* subgroup = item->getChildGroupItem();
945 destroyScene(subgroup->getScene());
946 // remove the BoxItem
947 item->getScene()->removeBoxItem(item);
948 // remove the group from the graph
949 params->getGraph()->removeGroupBlock(group);
953 void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
954 static QString fctName = "Dispatcher::removeAllBlockConnection()";
956 cout << "call to " << qPrintable(fctName) << endl;
959 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
960 foreach(ConnectionItem* conn, ifaceItem->connections) {
961 removeConnection(conn);
966 void Dispatcher::removeSourceItem(SourceItem *item) {
967 static QString fctName = "Dispatcher::removeSourceItem()";
969 cout << "call to " << qPrintable(fctName) << endl;
972 QString msg = "Removing source ";
974 msg += item->getRefBlock()->getName();
975 msg += " and all its connections.\n\nAre you sure ?";
977 int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
978 if (ret == QMessageBox::Cancel) {
981 removeAllBlockConnections(item);
983 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
984 item->getScene()->removeSourceItem(item);
985 params->getGraph()->removeSourceBlock(block);
989 void Dispatcher::removeConnection(ConnectionItem *connItem) {
990 static QString fctName = "Dispatcher::removeConnection()";
992 cout << "call to " << qPrintable(fctName) << endl;
994 InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
995 InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
998 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
1001 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not
1002 GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem
1004 ConnectedInterface *fromInter = fromIfaceItem->refInter;
1005 ConnectedInterface *toInter = toIfaceItem->refInter;
1007 // test if one of the interface bounded to item is owned by a GroupItem
1008 if (fromIfaceItem->getOwner()->isGroupItem()) {
1009 groupItem = ABI_TO_GI(fromIfaceItem->getOwner());
1010 groupIfaceItem = fromIfaceItem;
1012 else if (toIfaceItem->getOwner()->isGroupItem()) {
1013 groupItem = ABI_TO_GI(toIfaceItem->getOwner());
1014 groupIfaceItem = toIfaceItem;
1017 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
1020 // removing the connection from graph
1022 cout << "removing connections from graph ..." ;
1024 fromInter->disconnectTo(toInter);
1027 cout << "done." << endl ;
1030 // removing the connection from scene
1032 cout << "removing connections from scene ..." ;
1034 groupItem->getScene()->removeConnectionItem(connItem);
1037 cout << "done." << endl ;
1040 // if one of the interface bounded to connItem is owned by the GroupItem of the scene
1041 if (groupIfaceItem != NULL) {
1043 // determine if the interface must be removed since it has no more connections.
1044 bool groupInterRemove = false;
1045 if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true;
1047 if (groupInterRemove) {
1048 // get the GroupInterface from interface item
1049 ConnectedInterface* groupInter = groupIfaceItem->refInter;
1050 // remove interface from GroupItem, and delete it.
1051 groupItem->removeInterfaceItem(groupIfaceItem);
1052 // get the parent BoxItem of GroupItem if it exists.
1053 BoxItem* parent2Item = groupItem->getParentItem();
1054 if (parent2Item != NULL) {
1055 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter);
1056 // remove interface intem in parent BoxItem
1057 parent2Item->removeInterfaceItem(group2IfaceItem);
1059 // remove GroupInterface in the graph.
1060 groupInter->getOwner()->removeInterface(groupInter);
1065 void Dispatcher::showBlocksLibrary(){
1066 cout << "showing block library" << endl;
1067 mainWindow->getLibrary()->show();
1068 mainWindow->getLibrary()->raise();
1071 void Dispatcher::showProperties(InterfaceItem *inter) {
1072 new InterfacePropertiesWindow(inter);
1075 /* connectInterToGroup() :
1076 The only way for a block (functional of group) within a GroupItem to be connected
1077 to the latter is to right-click on one of its interfaces and to choose "connect to group".
1078 That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
1081 void Dispatcher::connectInterToGroup(InterfaceItem *item){
1083 // getting the GroupBlock and GroupItem that are parent of the block that owns item
1084 ConnectedInterface *refInter = item->refInter;
1085 cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
1086 GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
1087 cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
1088 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
1090 // creating/adding the group interface in the graph model
1091 GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
1092 parentItem->getRefBlock()->addInterface(groupInter);
1093 // creating/adding the group control interface in the graph model if the purpose is data
1094 if (refInter->getPurpose() == AbstractInterface::Data) {
1095 GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
1096 groupCtlInter->setAssociatedIface(groupInter);
1097 parentItem->getRefBlock()->addInterface(groupCtlInter);
1099 // creating/adding the group interface in the current scene model, and connection item
1100 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1101 parentItem->addInterfaceItem(groupIfaceItem,true);
1103 // creating the connection, in graph and with an item
1104 createConnection(item, groupIfaceItem);
1106 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1107 BoxItem* parent2Item = parentItem->getParentItem();
1108 if(parent2Item != NULL){
1109 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1110 parent2Item->addInterfaceItem(blockIfaceItem,true);
1114 parentItem->getScene()->updateConnectionItemsShape();
1116 params->unsaveModif = true;
1119 void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
1120 static QString fctName = "Dispatcher::removeBlockInterface()";
1121 #ifdef DEBUG_FCTNAME
1122 cout << "call to " << qPrintable(fctName) << endl;
1125 /* first, remove all connections from item
1126 NB: if there is a connection to a group interface, then this
1127 method should not be called if the group interface is also
1128 connected to another interface. Normally, this is not possible
1129 because such a check is done when creating the contextual menu
1130 that allows to remove an interface.
1132 foreach(ConnectionItem* conn, item->connections) {
1133 removeConnection(conn);
1136 ConnectedInterface* ref = item->refInter;
1137 item->getOwner()->removeInterfaceItem(item);
1138 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1139 fun->removeInterface(ref);
1142 void Dispatcher::removeGroupInterface(InterfaceItem *item) {
1143 static QString fctName = "Dispatcher::removeGroupInterface()";
1144 #ifdef DEBUG_FCTNAME
1145 cout << "call to " << qPrintable(fctName) << endl;
1148 /* NB: just remove all connections from/to this item, since when there are no more
1149 ones to a GroupItem, it is automatically deleted.
1151 foreach(ConnectionItem* conn, item->connections) {
1152 removeConnection(conn);
1156 QMap<int, QString> Dispatcher::getAllGroupNames() {
1158 QMap<int, QString> list;
1159 foreach(GroupWidget *group, groupList) {
1160 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1165 GroupScene* Dispatcher::getSceneById(int id) {
1166 foreach(GroupWidget *group, groupList){
1167 if(group->getScene()->getId() == id)
1168 return group->getScene();
1170 cout << "search scene by id :" << id << " :: not found..." << endl;
1174 GroupItem *Dispatcher::getGroupItemById(int id) {
1175 foreach(GroupWidget *group, groupList) {
1176 GroupScene* scene = group->getScene();
1177 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1179 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1183 BoxItem *Dispatcher::getBoxItemById(int id) {
1184 foreach(GroupWidget *group, groupList) {
1186 GroupScene* scene = group->getScene();
1187 foreach(BoxItem *item, scene->getBoxItems()){
1188 if(item->getId() == id){
1193 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1197 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1199 foreach(GroupWidget *group, groupList) {
1201 GroupScene* scene = group->getScene();
1203 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1204 if(item->getId() == id){
1208 foreach(BoxItem *block, scene->getBoxItems()){
1209 foreach(InterfaceItem *item, block->getInterfaces()){
1210 if(item->getId() == id){
1216 cout << "search interface by id :" << id << " :: not found..." << endl;
1220 void Dispatcher::findGraphModifications(FunctionalBlock *block) {
1221 static QString fctName = "Dispatcher::findGraphModifications()";
1222 #ifdef DEBUG_FCTNAME
1223 cout << "call to " << qPrintable(fctName) << endl;
1226 block->computeAdmittanceDelays();
1227 // get the block item that is associated to block
1228 BoxItem* toBlockItem = params->blockToItem.value(block);
1230 /* VERSION 1: just add delays if needed */
1231 QMap<AbstractInterface*,QList<int>* > delays = block->getAdmittanceDelays();
1232 QMapIterator<AbstractInterface*,QList<int>* > iterD(delays);
1233 while (iterD.hasNext()) {
1235 QList<int>* delay = iterD.value();
1236 if (delay->at(0) > 0) {
1237 // create delay and associate it to the connected input
1239 ConnectedInterface* toIface = AI_TO_CON(iterD.key());
1240 AbstractInputModifier* mod = new DelayInputModifier(toIface, delay->at(0));
1241 cout << "modify input of " << qPrintable(toIface->getName()) << endl;
1242 toIface->setInputModifier(mod);
1244 toBlockItem->update();