1 #include "Dispatcher.h"
2 #include "Parameters.h"
3 #include "MainWindow.h"
5 #include "ExternalResource.h"
8 #include "ReferenceBlock.h"
9 #include "GroupBlock.h"
10 #include "FunctionalBlock.h"
12 #include "ConnectedInterface.h"
13 #include "ReferenceInterface.h"
14 #include "GroupInterface.h"
15 #include "FunctionalInterface.h"
17 #include "GroupWidget.h"
18 #include "GroupScene.h"
19 #include "GroupItem.h"
21 #include "StimuliItem.h"
22 #include "InterfaceItem.h"
23 #include "ConnectionItem.h"
25 #include "BlockLibraryWidget.h"
26 #include "BlockLibraryTree.h"
28 #include "AbstractInputModifier.h"
29 #include "DelayInputModifier.h"
32 #include "InterfacePropertiesDialog.h"
34 #include <QHashIterator>
36 int Dispatcher::sceneCounter = 0;
38 Dispatcher::Dispatcher(Parameters* _params, MainWindow* _window) {
41 params->setDispatcher(this);
42 currentGroupWidget = NULL;
43 topGroupWidget = NULL;
46 GroupWidget *Dispatcher::loadProject(const QString& filename) {
50 root = params->openProjectFile(filename);
52 catch(Exception err) {
57 // creating the top widget/scene
58 topGroup = new GroupWidget(NULL,this,params);
59 currentGroup = topGroup;
60 // getting the newly created scene
61 GroupScene *scene = topGroup->getScene();
63 params->setTopScene(scene);
64 params->setCurrentScene(scene);
67 topGroupWidget = params->loadProject(root);
70 cerr << qPrintable(e.getDefaultMessage()) << endl;
71 cerr << "Aborting ..." << endl;
72 // TO DO : deleteting topGroup and all
76 QFileInfo info(filename);
77 params->projectPath = info.absolutePath();
78 params->projectName = info.baseName();
79 cout << "project path = " << qPrintable(params->projectPath) << endl;
80 groupList.append(topGroupWidget);
81 return topGroupWidget;
84 void Dispatcher::closeCurrentProject() {
86 foreach(GroupWidget* win, groupList) {
90 params->destroyGraph();
91 topGroupWidget = NULL;
92 currentGroupWidget = NULL;
96 void Dispatcher::setSceneCounter(Context context, int value) {
98 if (context != Load) return;
102 bool Dispatcher::createConnection(Context context, InterfaceItem *iface1, InterfaceItem *iface2, bool visible) {
104 ConnectedInterface* ref1 = iface1->refInter;
105 ConnectedInterface* ref2 = iface2->refInter;
106 // connect both interface
111 // test the ref1->ref2 connection
112 if ((ref1->canConnectTo(ref2)) && (ref2->canConnectFrom(ref1))) {
113 ref1->connectTo(ref2);
116 // if the first one did not work, test ref2->ref1
117 if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) {
118 ref2->connectTo(ref1);
121 if ((ok1 == true) || (ok2 == true)) {
124 cout << "trying to create a connection from " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
125 cout << " to " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
126 iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2, visible);
129 cout << "trying to create a connection from " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
130 cout << " to " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
131 iface2->getOwner()->getScene()->createConnectionItem(iface2,iface1, visible);
134 cout << " ... done." << endl;
136 unselectAllItems(context);
137 params->unsaveModif = true;
144 void Dispatcher::unselectAllItems(Context context, int direction){
146 GroupScene *scene = params->getCurrentScene();
148 foreach(BoxItem* block, scene->getBoxItems()) {
149 block->setSelected(false);
150 block->setCurrentInterface(NULL);
152 scene->unselecteInterfaces();
156 void Dispatcher::setCurrentGroupWidget(Context context, GroupWidget *win){
158 win->changeConnectionMode(-1);
159 currentGroupWidget = win;
160 params->setCurrentScene(win->getScene());
163 void Dispatcher::changeConnectionMode(Context context, int mode){
166 foreach(GroupWidget* win, groupList){
168 QToolButton* buttonNewConnection = win->getButtonNewConnection();
170 QPalette pal = buttonNewConnection->palette();
173 if(params->sceneMode != Parameters::EditOnConnection){
174 params->sceneMode = Parameters::EditOnConnection;
175 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
177 params->sceneMode = Parameters::EditNoOperation;
178 pal.setColor(QPalette::Button, QColor("#edeceb"));
181 else if(mode == Parameters::EditOnConnection){
182 params->sceneMode = Parameters::EditOnConnection;
183 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
186 params->sceneMode = Parameters::EditNoOperation;
187 pal.setColor(QPalette::Button, QColor("#edeceb"));
189 unselectAllInterfaces();
191 buttonNewConnection->setAutoFillBackground(true);
192 buttonNewConnection->setPalette(pal);
193 buttonNewConnection->update();
198 void Dispatcher::generateVHDL(Context context) throw(Exception) {
199 static QString fctName = "Dispatcher::generateVHDL()";
201 cout << "call to " << qPrintable(fctName) << endl;
204 QDir baseDir(params->projectPath);
205 QDir srcDir(params->projectPath+"/src");
207 if (!baseDir.exists()) {
208 cerr << "Project path " << qPrintable(params->projectPath) << " no longer exists. First, recreate it and put the project file within. Then retry to generate." << endl;
212 if (srcDir.exists()) {
213 srcDir.removeRecursively();
215 baseDir.mkdir("src");
217 if (! baseDir.exists("testbench")) {
218 baseDir.mkdir("testbench");
220 if (! baseDir.exists("Makefile")) {
221 QFile make("/home/sdomas/Projet/Blast/code/blast/Makefile-isim");
222 QString dest = params->projectPath;
227 // generate VHDL + copying external resources
228 QString dest = params->projectPath;
231 params->getGraph()->generateVHDL(dest);
233 QList<QString> extResources = params->getGraph()->getExternalResources();
234 foreach(QString name, extResources) {
235 cout << qPrintable(name) << endl;
236 QList<ExternalResource*> lstRes = params->searchResourceByName(name);
237 foreach(ExternalResource* res, lstRes) {
238 QFile resFile(res->getFile());
239 QFileInfo info(res->getFile());
240 QString destFile = dest+info.fileName();
241 cout << "copying " << qPrintable(res->getFile()) << " into " << qPrintable(destFile) << endl;
242 resFile.copy(destFile);
249 // generate testbench
250 dest = params->projectPath;
251 dest += "/testbench/";
252 dest += params->projectName;
255 params->getGraph()->generateTestbench(params->projectName, dest);
261 // creating parameters file
262 QString paramName = params->projectPath+"/params-isim.txt";
263 QFile paramFile(paramName);
264 if (!paramFile.open(QIODevice::WriteOnly)) {
265 throw(Exception(PROJECTPATH_NOACCESS));
267 QTextStream out(¶mFile);
268 out << "PROJECT_NAME := " << params->projectName << endl << endl;
269 out << "SRC_DIR := src" << endl;
270 out << "TB_DIR := testbench" << endl << endl;
271 out << "VHDL_SRC := ";
274 srcDir.setNameFilters(filter);
275 QStringList listVHDL = srcDir.entryList();
276 for(int j=0;j<listVHDL.size();j++) {
280 out << "$(SRC_DIR)/" << qPrintable(listVHDL.at(j));
281 if (j != listVHDL.size()-1) {
287 out << "VL_SRC := ${XILINX}/verilog/src/glbl.v" << endl << endl;
288 out << "TB_SRC := $(TB_DIR)/$(PROJECT_NAME)_tb.vhd" << endl << endl;
289 out << "SIMU_EXE := $(PROJECT_NAME)_tb" << endl << endl;
293 QString msg = "VHDL generation completed successfully. Go to ";
294 msg += params->projectPath+" and type the following commands to launch a simulation:\n";
295 msg += "\tmake clean\n";
297 msg += "\tmake view\n";
298 QMessageBox::information(mainWindow,"VHDL generation", msg, QMessageBox::Ok);
302 void Dispatcher::generateBlockVHDL(Context context, BoxItem *item){
303 static QString fctName = "Dispatcher::generateBlockVHDL()";
305 cout << "call to " << qPrintable(fctName) << endl;
308 if (item->getRefBlock()->isFunctionalBlock()) {
309 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
311 block->generateVHDL(params->projectPath);
314 cout << qPrintable(e.getMessage()) << endl;
319 void Dispatcher::renameFunctionalBlock(Context context, BoxItem *item){
320 static QString fctName = "Dispatcher::renameFunctionalBlock()";
322 cout << "call to " << qPrintable(fctName) << endl;
325 GroupWidget* win = item->getScene()->getGroupWidget();
330 text = QInputDialog::getText(win, "Rename a functional block",
331 "New name:", QLineEdit::Normal,
332 item->getRefBlock()->getName(), &ok);
335 if (text == item->getRefBlock()->getName()) return;
337 if( (text.isEmpty()) || (text.length() > 30)) {
338 QMessageBox::warning(win,"Error in given name",
339 "the block name must be shorter than 30 characters, cannot be empty",
344 FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
346 QMessageBox::warning(win,"Error in given name",
347 "the name provided is similar to that of another functional block within the group",
354 item->getRefBlock()->setName(text);
358 void Dispatcher::renameGroupBlock(Context context, GroupItem *item){
359 static QString fctName = "Dispatcher::renameGroupBlock()";
361 cout << "call to " << qPrintable(fctName) << endl;
364 GroupWidget* win = item->getScene()->getGroupWidget();
369 text = QInputDialog::getText(win, "Rename a group",
370 "New name:", QLineEdit::Normal,
371 item->getRefBlock()->getName(), &ok);
374 if (text == item->getRefBlock()->getName()) return;
376 if( (text.isEmpty()) || (text.length() > 30)) {
377 QMessageBox::warning(win,"Error in given name",
378 "the block name must be shorter than 30 characters, cannot be empty",
383 GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
385 QMessageBox::warning(win,"Error in given name",
386 "the name provided is similar to that of another group",
393 item->getRefBlock()->setName(text);
394 if(item->getScene()->getGroupWidget()->isTopGroup()) {
395 mainWindow->setWindowTitle("blast - "+text);
398 item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
401 mainWindow->getLibrary()->updateComboScene();
404 void Dispatcher::renameStimuliItem(Context context, StimuliItem *item){
405 static QString fctName = "Dispatcher::renameStimuliItem()";
407 cout << "call to " << qPrintable(fctName) << endl;
410 GroupWidget* win = item->getScene()->getGroupWidget();
415 text = QInputDialog::getText(win, "Rename a stimuli",
416 "New name:", QLineEdit::Normal,
417 item->getRefBlock()->getName(), &ok);
420 if (text == item->getRefBlock()->getName()) return;
422 if( (text.isEmpty()) || (text.length() > 30)) {
423 QMessageBox::warning(win,"Error in given name",
424 "the block name must be shorter than 30 characters, cannot be empty",
429 FunctionalBlock* block = params->getGraph()->getStimuliBlockByName(text);
431 QMessageBox::warning(win,"Error in given name",
432 "the name provided is similar to that of another stimuli block within the top group",
439 item->getRefBlock()->setName(text);
444 void Dispatcher::renameInterface(Context context, InterfaceItem *item) {
445 static QString fctName = "Dispatcher::renameInterface()";
447 cout << "call to " << qPrintable(fctName) << endl;
450 GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
455 text = QInputDialog::getText(win, "Rename an interface",
456 "New name:", QLineEdit::Normal,
457 item->refInter->getName(), &ok);
461 if (text == item->refInter->getName()) return;
463 if( (text.isEmpty()) || (text.length() > 30)) {
464 QMessageBox::warning(win,"Error in given name",
465 "the interface name must be shorter than 30 characters, cannot be empty",
470 AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
472 QMessageBox::warning(win,"Error in given name",
473 "the name provided is similar to that of another interface",
479 item->refInter->setName(text);
480 AbstractInterface* assoIface = item->refInter->getAssociatedIface();
481 if (assoIface != NULL) {
482 assoIface->setName(text+"_enb");
484 item->updateName(text);
485 item->getOwner()->nameChanged();
488 void Dispatcher::showPatterns(Context context, InterfaceItem *item) {
489 static QString fctName = "Dispatcher::showPatterns()";
491 cout << "call to " << qPrintable(fctName) << endl;
494 if (item->refInter->getDirection() == AbstractInterface::Input) {
495 msg = "Input pattern of iface ";
496 msg += item->refInter->getName();
498 msg += item->refInter->getOwner()->getName();
500 // get the precursor output pattern
501 ConnectedInterface* connIface = AI_TO_CON(item->refInter->getAssociatedIface());
502 QList<char>* out = connIface->getConnectedFrom()->getOutputPattern();
504 AbstractInputModifier* modifier = connIface->getInputModifier();
505 // check if the input is modified
506 if (modifier != NULL) {
508 out = modifier->getModifiedInput(out);
511 foreach(char c, *out) {
512 msg += QString::number((int)c);
516 else if (item->refInter->getDirection() == AbstractInterface::Output) {
517 msg = "Output pattern of iface ";
518 msg += item->refInter->getName();
520 msg += item->refInter->getOwner()->getName();
522 ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
523 if (iface->getOutputPattern() == NULL) return;
524 foreach(char c, *(iface->getOutputPattern())) {
525 msg += QString::number((int)c);
529 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
532 void Dispatcher::showModifier(Context context, InterfaceItem *item) {
533 static QString fctName = "Dispatcher::showModifier()";
535 cout << "call to " << qPrintable(fctName) << endl;
538 ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
539 AbstractInputModifier* mod = assoIface->getInputModifier();
540 if (mod->isDelay()) {
541 DelayInputModifier* delay = (DelayInputModifier *)mod;
542 msg = "Pattern of iface ";
543 msg += item->refInter->getName();
545 msg += item->refInter->getOwner()->getName();
546 msg += " is modified by a simple delay of ";
547 msg += QString::number(delay->getDelayLength());
550 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
553 void Dispatcher::removeModifier(Context context, InterfaceItem *item) {
554 static QString fctName = "Dispatcher::showModifier()";
556 cout << "call to " << qPrintable(fctName) << endl;
559 ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
560 assoIface->clearInputModifier();
564 void Dispatcher::duplicateBoxItem(Context context, BoxItem *item){
565 static QString fctName = "Dispatcher::duplicateBoxItem()";
567 cout << "call to " << qPrintable(fctName) << endl;
570 GroupScene *scene = item->getScene();
571 AbstractBlock* block = item->getRefBlock();
572 AbstractBlock *newBlock;
574 // only duplicate functional blocks
575 if(block->isFunctionalBlock()) {
577 // adding to the model
578 FunctionalBlock* funBlock = (FunctionalBlock*)block;
579 newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
580 // adding to the view
581 scene->createBoxItem(newBlock);
583 params->unsaveModif = true;
587 void Dispatcher::duplicateStimuliItem(Context context, StimuliItem *item) {
588 static QString fctName = "Dispatcher::duplicateStimuliItem()";
590 cout << "call to " << qPrintable(fctName) << endl;
593 GroupScene *scene = item->getScene();
594 AbstractBlock* block = item->getRefBlock();
595 AbstractBlock *newBlock;
597 // only duplicate functional blocks
598 if(block->isFunctionalBlock()) {
600 // adding to the model
601 FunctionalBlock* funBlock = (FunctionalBlock*)block;
602 newBlock = params->getGraph()->duplicateStimuliBlock(funBlock);
603 // adding to the view
604 scene->createStimuliItem(newBlock);
606 params->unsaveModif = true;
610 void Dispatcher::duplicateInterfaceItem(Context context, InterfaceItem *item) {
611 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
613 cout << "call to " << qPrintable(fctName) << endl;
616 AbstractInterface *refI = item->refInter;
617 if (! refI->isFunctionalInterface()) return;
619 AbstractBlock *refB = refI->getOwner();
620 if(! refB->isFunctionalBlock()) return;
622 FunctionalInterface* iface = (FunctionalInterface*)refI;
623 AbstractInterface *cloneIface = iface->clone();
624 if (cloneIface == NULL) {
625 QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
629 refB->addInterface(cloneIface);
631 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
632 item->getOwner()->addInterfaceItem(cloneIfaceItem,true);
634 // creating control interface if needed
635 if (refI->getAssociatedIface() != NULL) {
636 QString ctlName = cloneIface->getName()+"_enb";
637 ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,cloneIface->getDirection(), AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
638 refB->addInterface(ctlIface);
639 if (! ctlIface->setAssociatedIface(cloneIface)) {
640 cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
646 void Dispatcher::addBlock(Context context, int idCategory, int idBlock, int idScene, QHash<QString, int> clkRstToGen) {
647 static QString fctName = "Dispatcher::addBlock()";
649 cout << "call to " << qPrintable(fctName) << endl;
651 bool newStimuli = false;
653 /* For now, this method is only used while designing and not loading */
654 if (context == Design) {
655 GroupScene *scene = getSceneById(idScene);
656 ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
657 // if block has no inputs, propose to add it as a source to top scene
658 if ((scene->isTopScene()) && (ref->isSourceBlock())) {
659 int ret = QMessageBox::question(NULL,"Adding a block to top scene","Selected block may be used as a stimuli for the top scene. Do you want to add it as a stimuli ?");
660 if (ret == QMessageBox::Yes) {
665 FunctionalBlock* newOne = params->getGraph()->createStimuliBlock(ref, true);
666 StimuliItem* item = scene->createStimuliItem(newOne);
667 QHashIterator<QString,int> iter(clkRstToGen);
668 while (iter.hasNext()) {
670 AbstractInterface* iface = newOne->getIfaceFromName(iter.key());
671 if (iface->getPurpose() == AbstractInterface::Clock) {
672 connectStimuliItemClock(context,item,iface->getName(),iter.value());
674 else if (iface->getPurpose() == AbstractInterface::Reset) {
675 connectStimuliItemReset(context,item,iface->getName(),iter.value());
681 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
682 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref, true);
684 // creating the box item
685 BoxItem* item = scene->createBoxItem(newOne);
687 QHashIterator<QString,int> iter(clkRstToGen);
688 while (iter.hasNext()) {
690 AbstractInterface* iface = newOne->getIfaceFromName(iter.key());
691 if (iface->getPurpose() == AbstractInterface::Clock) {
692 connectBoxItemClock(context,item,iface->getName(),iter.value());
694 else if (iface->getPurpose() == AbstractInterface::Reset) {
695 connectBoxItemReset(context,item,iface->getName(),iter.value());
699 params->blockToItem.insert(newOne,item);
701 params->unsaveModif = true;
705 void Dispatcher::addClkRstGenBlock(Context context, double frequency) {
706 static QString fctName = "Dispatcher::addClkRstGenBlock()";
708 cout << "call to " << qPrintable(fctName) << endl;
712 if (context == Design) {
714 params->getGraph()->addClock(frequency);
717 GroupBlock *group = params->getGraph()->getTopGroup();
718 GroupScene *scene = topGroupWidget->getScene();
720 // creating the clkrstgen block
721 ReferenceBlock* ref = params->getHiddenReferenceBlock("clkrstgen");
722 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref, true);
724 QString name = "clkrstgen_";
725 name += QString::number(params->getGraph()->getClocks().size()-1);
726 newOne->setName(name);
728 // creating the box item
729 BoxItem* item = scene->createBoxItem(newOne, BoxItem::Left, AbstractBoxItem::Dimension);
730 item->setVisible(false);
732 ConnectedInterface* fromIfaceClk = NULL;
733 ConnectedInterface* fromIfaceReset = NULL;
734 QString clkName = "ext_clk_"+QString::number(params->getGraph()->getClocks().size()-1);
735 QString rstName = "ext_reset_"+QString::number(params->getGraph()->getClocks().size()-1);
736 fromIfaceClk = new GroupInterface(group,clkName, AbstractInterface::Input, AbstractInterface::Clock);
737 fromIfaceReset = new GroupInterface(group,rstName, AbstractInterface::Input, AbstractInterface::Reset);
738 group->addInterface(fromIfaceClk);
739 group->addInterface(fromIfaceReset);
740 // creating top group ext_clk iface item
741 GroupItem* groupItem = scene->getGroupItem();
742 InterfaceItem* fromIfaceItemClk = new InterfaceItem(0.5 , Parameters::West, fromIfaceClk, groupItem, params, true);
743 groupItem->addInterfaceItem(fromIfaceItemClk,true);
744 // creating top group ext_reset iface item
745 InterfaceItem* fromIfaceItemReset = new InterfaceItem(0.5 , Parameters::West, fromIfaceReset, groupItem, params, false);
746 groupItem->addInterfaceItem(fromIfaceItemReset,true);
747 // connecting ext_clk iface items
748 InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName("ext_clk");
749 if (toIfaceItemClk == NULL) {
750 cerr << "Abnormal case while connecting top group ext_clk to clkrstgen" << endl;
752 createConnection(context,fromIfaceItemClk, toIfaceItemClk, false);
753 // connecting ext_reset iface items
754 InterfaceItem* toIfaceItemReset = item->searchInterfaceItemByName("ext_reset");
755 if (toIfaceItemReset == NULL) {
756 cerr << "Abnormal case while connecting top group ext_reset to clkrstgen" << endl;
758 createConnection(context,fromIfaceItemReset, toIfaceItemReset, false);
760 params->blockToItem.insert(newOne,item);
761 params->unsaveModif = true;
767 GroupWidget *Dispatcher::createTopScene(Context context, double mainClock){
768 static QString fctName = "Dispatcher::createTopScene()";
770 cout << "call to " << qPrintable(fctName) << endl;
774 // creating the graph and thus, the topgroup
775 if (context == Design) {
776 graph = params->initGraph(true);
777 graph->addClock(mainClock);
779 else if (context == Load) {
780 graph = params->initGraph(false);
784 GroupBlock *topBlock = graph->getTopGroup();
785 // creating the top group widget
786 topGroupWidget = new GroupWidget(NULL,this,params);
787 currentGroupWidget = topGroupWidget;
788 // getting the newly created scene
789 GroupScene *scene = topGroupWidget->getScene();
790 scene->setId(sceneCounter++);
791 params->setTopScene(scene);
792 params->setCurrentScene(scene);
793 // creating the view part of the group
794 GroupItem *group = new GroupItem(NULL,topBlock,this,params);
795 // associate the top scene to the top group iten
796 scene->setGroupItem(group);
798 // adding the fake interface to the top group item
799 //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
800 //group->addInterface(item,true);
803 if (context == Design) {
805 double freq = params->getGraph()->getClock(0);
806 params->getGraph()->resetClocks();
807 addClkRstGenBlock(context,freq);
810 groupList.append(topGroupWidget);
811 return topGroupWidget;
814 GroupWidget* Dispatcher::addNewEmptyGroup(Context context, GroupScene* scene, bool show) {
815 static QString fctName = "Dispatcher::addNewEmptyGroup();";
817 cout << "call to " << qPrintable(fctName) << endl;
819 bool createIfaces = true;
820 if (context == Load) {
821 createIfaces = false;
824 // getting the parent block in the graph
825 GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
826 cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
827 GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent, createIfaces);
828 cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
829 // creating the BlockItem in the scene
830 BoxItem* newItem = scene->createBoxItem(groupBlock);
832 params->unsaveModif = true;
834 GroupWidget* child = createChildScene(context, scene->getGroupWidget(),newItem);
835 if (show) child->show();
840 GroupWidget *Dispatcher::createChildScene(Context context, GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
841 static QString fctName = "Dispatcher::createChildScene()";
843 cout << "call to " << qPrintable(fctName) << endl;
846 GroupWidget* group = NULL;
847 /* NB: this method may be called during design process or when loading
848 a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
849 cannot be initialized yet. This is why there are 2 cases below
852 if (upperItemOfGroupItem != NULL) {
853 // getting back the goup block already created
854 GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
855 // creating the view part of the group
856 GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
858 // creating the group widget
859 group = new GroupWidget(parentWidget, this, params);
860 // getting the newly created scene
861 GroupScene *scene = group->getScene();
862 scene->setId(sceneCounter++);
863 // affecting group item to the scene
864 scene->setGroupItem(groupItem);
865 groupList.append(group);
867 mainWindow->getLibrary()->updateComboScene();
870 GroupItem *groupItem = new GroupItem(this,params);
871 // creating the group widget
872 group = new GroupWidget(parentWidget, this, params);
873 // getting the newly created scene
874 GroupScene *scene = group->getScene();
875 // affecting group item to the scene
876 scene->setGroupItem(groupItem);
877 groupList.append(group);
882 void Dispatcher::destroyScene(Context context, GroupScene *scene) {
883 foreach(GroupScene* s, scene->getChildrenScene()) {
884 destroyScene(context, s);
887 if (scene->getNbChildScene() == 0) {
888 // remove scene from the parent list, if possible
889 if (scene->getParentScene() != NULL) {
890 scene->getParentScene()->removeChildScene(scene);
892 // destroy the GroupWidget
893 groupList.removeAll(scene->getGroupWidget());
894 scene->getGroupWidget()->deleteLater();
897 cerr << "Abnormal case when destroying a scene" << endl;
901 void Dispatcher::showRaiseWindow(Context context, BoxItem *item) {
902 static QString fctName = "Dispatcher::showRaiseWindow()";
904 cout << "call to " << qPrintable(fctName) << endl;
907 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
908 GroupItem* child = item->getChildGroupItem();
910 cerr << "abnormal case: child group item is null " << endl;
914 GroupWidget* win = child->getScene()->getGroupWidget();
918 win->activateWindow();
920 currentGroupWidget = win;
921 params->setCurrentScene(currentGroupWidget->getScene());
924 void Dispatcher::showRstClkIface(Context context, AbstractBoxItem *item) {
925 static QString fctName = "Dispatcher::showRstClkIface()";
927 cout << "call to " << qPrintable(fctName) << endl;
930 item->setRstClkVisible(!item->isRstClkVisible());
934 void Dispatcher::showWishboneIface(Context context, AbstractBoxItem *item) {
935 static QString fctName = "Dispatcher::showWishboneIface()";
937 cout << "call to " << qPrintable(fctName) << endl;
940 item->setWishboneVisible(!item->isWishboneVisible());
943 void Dispatcher::addNewFullGroup(Context context) {
944 static QString fctName = "Dispatcher::addNewFullGroup()";
946 cout << "call to " << qPrintable(fctName) << endl;
952 QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
953 QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
954 QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
956 /* What must be done:
957 1 - creating a new GroupBlock
958 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
959 3 - creating a BlockItem that references the new GroupBlock
960 4 - creating a new GroupWidget
961 5 - creating a new GroupItem added to the scene of the GroupWidget
965 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
966 associated to the GroupItem of the current scene
968 GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
969 GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
970 /* step 2: moving selected blocks */
971 foreach(BlockItem* blockItem, listBlocks) {
972 parentBlock->removeBlock(blockItem->getRefBlock());
973 newGroupBlock->addBlock(blockItem->getRefBlock());
976 GroupItem *parent = currentGroup->getScene()->getGroupItem();
977 GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
978 BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
979 GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
981 //create the new window
982 GroupWidget* win = new GroupWidget(this,params);
983 win->getScene()->setGroupItem(groupItem);
984 win->getScene()->addItem(groupItem);
985 ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
986 params->addWindow(win);
990 params->getCurrentScene()->addBlockItem(blockItem);
991 params->getCurrentScene()->addItem(blockItem);
992 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
994 //replace selected blocks in the group
995 foreach(AbstractBoxItem *block, listBlocks){
996 ((GroupItem*)block->getParentItem())->removeBlockItem(block);
997 ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
998 params->getCurrentScene()->removeItem(block);
999 params->getCurrentScene()->removeBlockItem(block);
1001 groupBlock->addBlock(block->getRefBlock());
1002 listAbstractBlocks.append(block->getRefBlock());
1004 block->setUpperItem(groupItem);
1005 groupItem->addBlockItem(block);
1006 win->getScene()->addItem(block);
1007 win->getScene()->addBlockItem(block);
1010 //replace connection between selected blocks in the group
1011 foreach(ConnectionItem *conn, connections){
1012 if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
1013 if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
1014 parent->removeConnection(conn);
1015 params->getCurrentScene()->removeItem(conn);
1017 groupItem->addConnection(conn);
1018 win->getScene()->addItem(conn);
1023 //create new interfaces and connections for the new group
1024 foreach(AbstractBoxItem *block, listBlocks){
1025 foreach(InterfaceItem *inter, block->getInterfaces()){
1026 cout << "inter : " << inter->getName().toStdString() << endl;
1027 if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
1028 cout << "connected from non null" << endl;
1029 if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
1031 AbstractInterface *iface = inter->refInter->clone(0);
1032 iface->setName(iface->getName()+"_group");
1033 groupBlock->addInterface(iface);
1035 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
1036 blockItem->addInterface(ifaceItem);
1037 blockItem->resetInterfacesPosition();
1039 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
1040 groupItem->addInterface(ifaceGroupItem);
1041 groupItem->resetInterfacesPosition();
1042 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
1043 if(conn->getToInterfaceItem() == inter){
1044 conn->setToInterfaceItem(ifaceItem);
1045 ifaceItem->refInter->setConnectedFrom(NULL);
1046 conn->getFromInterfaceItem()->refInter->clearConnectedTo();
1047 connect(ifaceItem,conn->getFromInterfaceItem());
1050 params->setCurrentWindow(win);
1052 inter->refInter->setConnectedFrom(NULL);
1053 ifaceGroupItem->refInter->clearConnectedTo();
1054 connect(inter,ifaceGroupItem);
1055 params->setCurrentWindow(mainWindow);
1059 if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
1060 cout << "connected to non null" << endl;
1061 foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
1062 if(!listAbstractBlocks.contains(iface->getOwner())){
1064 AbstractInterface *iface = inter->refInter->clone(0);
1065 iface->setName(iface->getName()+"_group");
1066 groupBlock->addInterface(iface);
1068 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
1069 blockItem->addInterface(ifaceItem);
1070 blockItem->resetInterfacesPosition();
1072 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
1073 if(conn->getFromInterfaceItem() == inter){
1074 conn->setFromInterfaceItem(ifaceItem);
1075 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
1076 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
1080 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
1081 groupItem->addInterface(ifaceGroupItem);
1082 groupItem->resetInterfacesPosition();
1083 inter->refInter->clearConnectedTo();
1084 ifaceGroupItem->refInter->setConnectedFrom(NULL);
1085 connect(ifaceGroupItem,inter);
1094 parent->updateShape();
1095 currentGroup->getScene()->updateConnectionItemsShape();
1097 groupItem->updateShape();
1098 win->getScene()->updateConnectionItemsShape();
1099 groupItem->update(groupItem->boundingRect());
1104 void Dispatcher::removeBoxItem(Context context, BoxItem *item) {
1105 static QString fctName = "Dispatcher::removeBoxItem()";
1106 #ifdef DEBUG_FCTNAME
1107 cout << "call to " << qPrintable(fctName) << endl;
1110 if (context != Design) return;
1112 /* a BoxItem (group of func) can be removed only if none of its
1113 interfaces is connected to a group interface that is itself
1114 connected to another one.
1116 bool canRemove = true;
1118 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
1119 foreach(ConnectionItem* conn, ifaceItem->connections) {
1120 InterfaceItem* other = NULL;
1121 if (conn->getFromInterfaceItem() == ifaceItem) {
1122 other = conn->getToInterfaceItem();
1125 other = conn->getFromInterfaceItem();
1128 if (other->getOwner()->isGroupItem()) {
1129 ConnectedInterface* ref = other->refInter;
1130 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
1137 QMessageBox::warning(NULL,"Forbidden operation",
1138 "The block has at least one connection to a group interface that is totally connected.",
1144 if (item->getRefBlock()->isFunctionalBlock()) {
1145 msg = "Removing block ";
1148 msg = "Removing group ";
1150 msg += item->getRefBlock()->getName();
1151 msg += " and all its connections.\n\nAre you sure ?";
1153 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
1154 if (ret == QMessageBox::Cancel) {
1157 removeAllBlockConnections(context, item);
1159 if (item->getRefBlock()->isFunctionalBlock()) {
1160 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
1161 item->getScene()->removeBoxItem(item);
1162 params->getGraph()->removeFunctionalBlock(block);
1163 params->blockToItem.remove(block);
1166 else if (item->getRefBlock()->isGroupBlock()) {
1168 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
1170 // remove all child scenes recursively
1171 GroupItem* subgroup = item->getChildGroupItem();
1172 destroyScene(context, subgroup->getScene());
1173 // remove the BoxItem
1174 item->getScene()->removeBoxItem(item);
1175 // remove the group from the graph
1176 params->getGraph()->removeGroupBlock(group);
1180 void Dispatcher::removeAllBlockConnections(Context context, AbstractBoxItem *item) {
1181 static QString fctName = "Dispatcher::removeAllBlockConnection()";
1182 #ifdef DEBUG_FCTNAME
1183 cout << "call to " << qPrintable(fctName) << endl;
1186 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
1187 foreach(ConnectionItem* conn, ifaceItem->connections) {
1188 removeConnection(context, conn);
1193 void Dispatcher::removeStimuliItem(Context context, StimuliItem *item) {
1194 static QString fctName = "Dispatcher::removeStimuliItem()";
1195 #ifdef DEBUG_FCTNAME
1196 cout << "call to " << qPrintable(fctName) << endl;
1199 QString msg = "Removing stimmuli ";
1201 msg += item->getRefBlock()->getName();
1202 msg += " and all its connections.\n\nAre you sure ?";
1204 int ret = QMessageBox::question(NULL,"Removing stimuli block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
1205 if (ret == QMessageBox::Cancel) {
1208 removeAllBlockConnections(context, item);
1210 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
1211 item->getScene()->removeStimuliItem(item);
1212 params->getGraph()->removeStimuliBlock(block);
1216 void Dispatcher::removeConnection(Context context, ConnectionItem *connItem) {
1217 static QString fctName = "Dispatcher::removeConnection()";
1218 #ifdef DEBUG_FCTNAME
1219 cout << "call to " << qPrintable(fctName) << endl;
1221 InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
1222 InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
1225 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
1228 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not
1229 GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem
1231 ConnectedInterface *fromInter = fromIfaceItem->refInter;
1232 ConnectedInterface *toInter = toIfaceItem->refInter;
1234 // test if one of the interface bounded to item is owned by a GroupItem
1235 if (fromIfaceItem->getOwner()->isGroupItem()) {
1236 groupItem = ABI_TO_GI(fromIfaceItem->getOwner());
1237 groupIfaceItem = fromIfaceItem;
1239 else if (toIfaceItem->getOwner()->isGroupItem()) {
1240 groupItem = ABI_TO_GI(toIfaceItem->getOwner());
1241 groupIfaceItem = toIfaceItem;
1244 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
1247 // removing the connection from graph
1249 cout << "removing connections from graph ..." ;
1251 fromInter->disconnectTo(toInter);
1254 cout << "done." << endl ;
1257 // removing the connection from scene
1259 cout << "removing connections from scene ..." ;
1261 groupItem->getScene()->removeConnectionItem(connItem);
1264 cout << "done." << endl ;
1267 // if one of the interface bounded to connItem is owned by the GroupItem of the scene
1268 if (groupIfaceItem != NULL) {
1270 // determine if the interface must be removed since it has no more connections.
1271 bool groupInterRemove = false;
1272 if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true;
1274 if (groupInterRemove) {
1275 // get the GroupInterface from interface item
1276 ConnectedInterface* groupInter = groupIfaceItem->refInter;
1277 // remove interface from GroupItem, and delete it.
1278 groupItem->removeInterfaceItem(groupIfaceItem);
1279 // get the parent BoxItem of GroupItem if it exists.
1280 BoxItem* parent2Item = groupItem->getParentItem();
1281 if (parent2Item != NULL) {
1282 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter);
1283 // remove interface intem in parent BoxItem
1284 parent2Item->removeInterfaceItem(group2IfaceItem);
1286 // remove GroupInterface in the graph.
1287 groupInter->getOwner()->removeInterface(groupInter);
1292 void Dispatcher::connectBoxItemClock(Context context, BoxItem *item, QString clkName, int idGen) throw(Exception) {
1294 InterfaceItem* fromIfaceItemClk = NULL;
1295 InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName(clkName);
1296 GroupItem* parentGroup = item->getScene()->getGroupItem();
1297 BoxItem* clkrstItem = NULL;
1299 if (parentGroup->getRefBlock()->isTopGroupBlock()) {
1300 QString genName = "clkrstgen_" + QString::number(idGen);
1301 clkrstItem = item->getScene()->searchBoxItemByName(genName);
1302 if (clkrstItem == NULL) {
1303 throw(Exception(IFACE_TOP_NOCLKRSTGEN));
1306 fromIfaceItemClk = clkrstItem->searchInterfaceItemByName("clk");
1308 cout << "connecting clock of " << qPrintable(item->getRefBlock()->getName()) << " to clk of " << qPrintable(genName) << endl;
1311 // searching for ext_clk_idGen
1312 QString name = "ext_clk_"+QString::number(idGen);
1313 fromIfaceItemClk = parentGroup->searchInterfaceItemByName(name);
1314 cout << "connecting clock of " << qPrintable(item->getRefBlock()->getName()) << " to " << qPrintable(name) << " of parent group " << qPrintable(parentGroup->getRefBlock()->getName()) << endl;
1317 if (fromIfaceItemClk == NULL) {
1318 throw(Exception(IFACE_GROUP_NOCLKRST));
1321 createConnection(context, fromIfaceItemClk, toIfaceItemClk, false);
1322 cout << "connection done." << endl;
1326 void Dispatcher::connectBoxItemReset(Context context, BoxItem *item, QString rstName, int idGen) throw(Exception) {
1327 InterfaceItem* fromIfaceItemRst = NULL;
1328 InterfaceItem* toIfaceItemRst = item->searchInterfaceItemByName(rstName);
1329 GroupItem* parentGroup = item->getScene()->getGroupItem();
1330 BoxItem* clkrstItem = NULL;
1332 if (parentGroup->getRefBlock()->isTopGroupBlock()) {
1333 QString genName = "clkrstgen_" + QString::number(idGen);
1334 clkrstItem = item->getScene()->searchBoxItemByName(genName);
1335 if (clkrstItem == NULL) {
1336 throw(Exception(IFACE_TOP_NOCLKRSTGEN));
1339 fromIfaceItemRst = clkrstItem->searchInterfaceItemByName("reset");
1341 cout << "connecting reset of " << qPrintable(item->getRefBlock()->getName()) << " to reset of " << qPrintable(genName) << endl;
1344 // searching for ext_rst_idGen
1345 QString name = "ext_rst_"+QString::number(idGen);
1346 fromIfaceItemRst = parentGroup->searchInterfaceItemByName(name);
1347 cout << "connecting reset of " << qPrintable(item->getRefBlock()->getName()) << " to " << qPrintable(name) << " of parent group " << qPrintable(parentGroup->getRefBlock()->getName()) << endl;
1350 if (fromIfaceItemRst == NULL) {
1351 throw(Exception(IFACE_GROUP_NOCLKRST));
1354 createConnection(context, fromIfaceItemRst, toIfaceItemRst, false);
1355 cout << "connection done." << endl;
1359 void Dispatcher::connectStimuliItemClock(Context context, StimuliItem *item, QString clkName, int idGen) throw(Exception) {
1360 InterfaceItem* fromIfaceItemClk = NULL;
1361 InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName(clkName);
1362 BoxItem* clkrstItem = NULL;
1364 QString genName = "clkrstgen_" + QString::number(idGen);
1365 clkrstItem = item->getScene()->searchBoxItemByName(genName);
1366 if (clkrstItem == NULL) {
1367 throw(Exception(IFACE_TOP_NOCLKRSTGEN));
1370 fromIfaceItemClk = clkrstItem->searchInterfaceItemByName("clk");
1372 cout << "connecting clock of " << qPrintable(item->getRefBlock()->getName()) << " to clock of " << qPrintable(genName) << endl;
1374 if (fromIfaceItemClk == NULL) {
1375 throw(Exception(IFACE_GROUP_NOCLKRST));
1378 createConnection(context, fromIfaceItemClk, toIfaceItemClk, false);
1379 cout << "connection done." << endl;
1383 void Dispatcher::connectStimuliItemReset(Context context, StimuliItem *item, QString rstName, int idGen) throw(Exception) {
1384 InterfaceItem* fromIfaceItemRst = NULL;
1385 InterfaceItem* toIfaceItemRst = item->searchInterfaceItemByName(rstName);
1386 BoxItem* clkrstItem = NULL;
1388 QString genName = "clkrstgen_" + QString::number(idGen);
1389 clkrstItem = item->getScene()->searchBoxItemByName(genName);
1390 if (clkrstItem == NULL) {
1391 throw(Exception(IFACE_TOP_NOCLKRSTGEN));
1394 fromIfaceItemRst = clkrstItem->searchInterfaceItemByName("reset");
1396 cout << "connecting reset of " << qPrintable(item->getRefBlock()->getName()) << " to reset of " << qPrintable(genName) << endl;
1398 if (fromIfaceItemRst == NULL) {
1399 throw(Exception(IFACE_GROUP_NOCLKRST));
1402 createConnection(context, fromIfaceItemRst, toIfaceItemRst, false);
1403 cout << "connection done." << endl;
1408 void Dispatcher::showBlocksLibrary(){
1409 cout << "showing block library" << endl;
1410 mainWindow->getLibrary()->show();
1411 mainWindow->getLibrary()->raise();
1414 void Dispatcher::showProperties(Context context, InterfaceItem *inter) {
1415 QDialog* dial = new InterfacePropertiesDialog(inter);
1419 /* connectInterToGroup() :
1420 The only way for a block (functional of group) within a GroupItem to be connected
1421 to the latter is to right-click on one of its interfaces and to choose "connect to group".
1422 That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
1425 void Dispatcher::connectInterToGroup(Context context, InterfaceItem *item){
1427 // getting the GroupBlock and GroupItem that are parent of the block that owns item
1428 ConnectedInterface *refInter = item->refInter;
1429 cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
1430 GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
1431 cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
1432 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
1434 // creating/adding the group interface in the graph model
1435 GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
1436 parentItem->getRefBlock()->addInterface(groupInter);
1437 // creating/adding the group control interface in the graph model if the purpose is data
1438 if (refInter->getPurpose() == AbstractInterface::Data) {
1439 GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
1440 groupCtlInter->setAssociatedIface(groupInter);
1441 parentItem->getRefBlock()->addInterface(groupCtlInter);
1443 // creating/adding the group interface in the current scene model, and connection item
1444 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1445 parentItem->addInterfaceItem(groupIfaceItem,true);
1447 // creating the connection, in graph and with an item
1448 createConnection(context, item, groupIfaceItem);
1450 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1451 BoxItem* parent2Item = parentItem->getParentItem();
1452 if(parent2Item != NULL){
1453 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1454 parent2Item->addInterfaceItem(blockIfaceItem,true);
1458 parentItem->getScene()->updateConnectionItemsShape();
1459 unselectAllItems(context);
1460 params->unsaveModif = true;
1463 void Dispatcher::removeFunctionalInterface(Context context, InterfaceItem *item) {
1464 static QString fctName = "Dispatcher::removeBlockInterface()";
1465 #ifdef DEBUG_FCTNAME
1466 cout << "call to " << qPrintable(fctName) << endl;
1469 /* first, remove all connections from item
1470 NB: if there is a connection to a group interface, then this
1471 method should not be called if the group interface is also
1472 connected to another interface. Normally, this is not possible
1473 because such a check is done when creating the contextual menu
1474 that allows to remove an interface.
1476 foreach(ConnectionItem* conn, item->connections) {
1477 removeConnection(context, conn);
1480 ConnectedInterface* ref = item->refInter;
1481 item->getOwner()->removeInterfaceItem(item);
1482 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1483 fun->removeInterface(ref);
1486 void Dispatcher::removeGroupInterface(Context context, InterfaceItem *item) {
1487 static QString fctName = "Dispatcher::removeGroupInterface()";
1488 #ifdef DEBUG_FCTNAME
1489 cout << "call to " << qPrintable(fctName) << endl;
1492 /* NB: just remove all connections from/to this item, since when there are no more
1493 ones to a GroupItem, it is automatically deleted.
1495 foreach(ConnectionItem* conn, item->connections) {
1496 removeConnection(context, conn);
1500 QMap<int, QString> Dispatcher::getAllGroupNames() {
1502 QMap<int, QString> list;
1503 foreach(GroupWidget *group, groupList) {
1504 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1509 GroupScene* Dispatcher::getSceneById(int id) {
1510 foreach(GroupWidget *group, groupList){
1511 if(group->getScene()->getId() == id)
1512 return group->getScene();
1514 cout << "search scene by id :" << id << " :: not found..." << endl;
1518 GroupItem *Dispatcher::getGroupItemById(int id) {
1519 foreach(GroupWidget *group, groupList) {
1520 GroupScene* scene = group->getScene();
1521 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1523 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1527 BoxItem *Dispatcher::getBoxItemById(int id) {
1528 foreach(GroupWidget *group, groupList) {
1530 GroupScene* scene = group->getScene();
1531 foreach(BoxItem *item, scene->getBoxItems()){
1532 if(item->getId() == id){
1537 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1541 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1543 foreach(GroupWidget *group, groupList) {
1545 GroupScene* scene = group->getScene();
1547 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1548 if(item->getId() == id){
1552 foreach(BoxItem *block, scene->getBoxItems()){
1553 foreach(InterfaceItem *item, block->getInterfaces()){
1554 if(item->getId() == id){
1560 cout << "search interface by id :" << id << " :: not found..." << endl;
1564 void Dispatcher::findGraphModifications(Context context, FunctionalBlock *block) {
1565 static QString fctName = "Dispatcher::findGraphModifications()";
1566 #ifdef DEBUG_FCTNAME
1567 cout << "call to " << qPrintable(fctName) << endl;
1570 block->computeAdmittanceDelays();
1571 // get the block item that is associated to block
1572 BoxItem* toBlockItem = params->blockToItem.value(block);
1574 /* VERSION 1: just add delays if needed */
1575 QMap<AbstractInterface*,QList<int>* > delays = block->getAdmittanceDelays();
1576 QMapIterator<AbstractInterface*,QList<int>* > iterD(delays);
1577 while (iterD.hasNext()) {
1579 QList<int>* delay = iterD.value();
1580 if (delay->at(0) > 0) {
1581 // create delay and associate it to the connected input
1583 ConnectedInterface* toIface = AI_TO_CON(iterD.key());
1584 AbstractInputModifier* mod = new DelayInputModifier(toIface, delay->at(0));
1585 cout << "modify input of " << qPrintable(toIface->getName()) << endl;
1586 toIface->setInputModifier(mod);
1588 toBlockItem->update();