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)) {
123 cout << "trying to create a connection from " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
124 cout << " to " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
127 iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2, visible);
130 iface2->getOwner()->getScene()->createConnectionItem(iface2,iface1, visible);
133 cout << " ... done." << endl;
135 unselectAllItems(context);
136 params->unsaveModif = true;
143 void Dispatcher::unselectAllItems(Context context, int direction){
145 GroupScene *scene = params->getCurrentScene();
147 foreach(BoxItem* block, scene->getBoxItems()) {
148 block->setSelected(false);
149 block->setCurrentInterface(NULL);
151 scene->unselecteInterfaces();
155 void Dispatcher::setCurrentGroupWidget(Context context, GroupWidget *win){
157 win->changeConnectionMode(-1);
158 currentGroupWidget = win;
159 params->setCurrentScene(win->getScene());
162 void Dispatcher::changeConnectionMode(Context context, int mode){
165 foreach(GroupWidget* win, groupList){
167 QToolButton* buttonNewConnection = win->getButtonNewConnection();
169 QPalette pal = buttonNewConnection->palette();
172 if(params->sceneMode != Parameters::EditOnConnection){
173 params->sceneMode = Parameters::EditOnConnection;
174 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
176 params->sceneMode = Parameters::EditNoOperation;
177 pal.setColor(QPalette::Button, QColor("#edeceb"));
180 else if(mode == Parameters::EditOnConnection){
181 params->sceneMode = Parameters::EditOnConnection;
182 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
185 params->sceneMode = Parameters::EditNoOperation;
186 pal.setColor(QPalette::Button, QColor("#edeceb"));
188 unselectAllInterfaces();
190 buttonNewConnection->setAutoFillBackground(true);
191 buttonNewConnection->setPalette(pal);
192 buttonNewConnection->update();
197 void Dispatcher::generateVHDL(Context context) throw(Exception) {
198 static QString fctName = "Dispatcher::generateVHDL()";
200 cout << "call to " << qPrintable(fctName) << endl;
203 QDir baseDir(params->projectPath);
204 QDir srcDir(params->projectPath+"/src");
206 if (!baseDir.exists()) {
207 cerr << "Project path " << qPrintable(params->projectPath) << " no longer exists. First, recreate it and put the project file within. Then retry to generate." << endl;
211 if (srcDir.exists()) {
212 srcDir.removeRecursively();
214 baseDir.mkdir("src");
216 if (! baseDir.exists("testbench")) {
217 baseDir.mkdir("testbench");
219 if (! baseDir.exists("Makefile")) {
220 QFile make("/home/sdomas/Projet/Blast/code/blast/Makefile-isim");
221 QString dest = params->projectPath;
226 // copying external resources
227 QString dest = params->projectPath;
230 params->getGraph()->generateVHDL(dest);
232 QList<QString> extResources = params->getGraph()->getExternalResources();
233 foreach(QString name, extResources) {
234 cout << qPrintable(name) << endl;
235 QList<ExternalResource*> lstRes = params->searchResourceByName(name);
236 foreach(ExternalResource* res, lstRes) {
237 QFile resFile(res->getFile());
238 QFileInfo info(res->getFile());
239 QString destFile = dest+info.fileName();
240 cout << "copying " << qPrintable(res->getFile()) << " into " << qPrintable(destFile) << endl;
241 resFile.copy(destFile);
249 // creating parameters file
250 QString paramName = params->projectPath+"/params-isim.txt";
251 QFile paramFile(paramName);
252 if (!paramFile.open(QIODevice::WriteOnly)) {
253 throw(Exception(PROJECTPATH_NOACCESS));
255 QTextStream out(¶mFile);
256 out << "PROJECT_NAME := " << params->projectName << endl << endl;
257 out << "SRC_DIR := src" << endl;
258 out << "TB_DIR := testbench" << endl << endl;
259 out << "VHDL_SRC := ";
262 srcDir.setNameFilters(filter);
263 QStringList listVHDL = srcDir.entryList();
264 for(int j=0;j<listVHDL.size();j++) {
268 out << "$(SRC_DIR)/" << qPrintable(listVHDL.at(j));
269 if (j != listVHDL.size()-1) {
275 out << "VL_SRC := ${XILINX}/verilog/src/glbl.v" << endl << endl;
276 out << "TB_SRC := $(TB_DIR)/read_csv.vhd \\" << endl;
277 out << "\t$(TB_DIR)/$(PROJECT_NAME)_tb.vhd" << endl << endl;
278 out << "SIMU_EXE := $(PROJECT_NAME)_tb" << endl << endl;
282 QString msg = "VHDL generation completed successfully. Go to ";
283 msg += params->projectPath+" and type the following commands to launch a simulation:\n";
284 msg += "\tmake clean\n";
286 msg += "\tmake view\n";
287 QMessageBox::information(mainWindow,"VHDL generation", msg, QMessageBox::Ok);
291 void Dispatcher::generateBlockVHDL(Context context, BoxItem *item){
292 static QString fctName = "Dispatcher::generateBlockVHDL()";
294 cout << "call to " << qPrintable(fctName) << endl;
297 if (item->getRefBlock()->isFunctionalBlock()) {
298 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
300 block->generateVHDL(params->projectPath);
303 cout << qPrintable(e.getMessage()) << endl;
308 void Dispatcher::renameFunctionalBlock(Context context, BoxItem *item){
309 static QString fctName = "Dispatcher::renameFunctionalBlock()";
311 cout << "call to " << qPrintable(fctName) << endl;
314 GroupWidget* win = item->getScene()->getGroupWidget();
319 text = QInputDialog::getText(win, "Rename a functional block",
320 "New name:", QLineEdit::Normal,
321 item->getRefBlock()->getName(), &ok);
324 if (text == item->getRefBlock()->getName()) return;
326 if( (text.isEmpty()) || (text.length() > 30)) {
327 QMessageBox::warning(win,"Error in given name",
328 "the block name must be shorter than 30 characters, cannot be empty",
333 FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
335 QMessageBox::warning(win,"Error in given name",
336 "the name provided is similar to that of another functional block within the group",
343 item->getRefBlock()->setName(text);
347 void Dispatcher::renameGroupBlock(Context context, GroupItem *item){
348 static QString fctName = "Dispatcher::renameGroupBlock()";
350 cout << "call to " << qPrintable(fctName) << endl;
353 GroupWidget* win = item->getScene()->getGroupWidget();
358 text = QInputDialog::getText(win, "Rename a group",
359 "New name:", QLineEdit::Normal,
360 item->getRefBlock()->getName(), &ok);
363 if (text == item->getRefBlock()->getName()) return;
365 if( (text.isEmpty()) || (text.length() > 30)) {
366 QMessageBox::warning(win,"Error in given name",
367 "the block name must be shorter than 30 characters, cannot be empty",
372 GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
374 QMessageBox::warning(win,"Error in given name",
375 "the name provided is similar to that of another group",
382 item->getRefBlock()->setName(text);
383 if(item->getScene()->getGroupWidget()->isTopGroup()) {
384 mainWindow->setWindowTitle("blast - "+text);
387 item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
390 mainWindow->getLibrary()->updateComboScene();
393 void Dispatcher::renameStimuliItem(Context context, StimuliItem *item){
394 static QString fctName = "Dispatcher::renameStimuliItem()";
396 cout << "call to " << qPrintable(fctName) << endl;
399 GroupWidget* win = item->getScene()->getGroupWidget();
404 text = QInputDialog::getText(win, "Rename a stimuli",
405 "New name:", QLineEdit::Normal,
406 item->getRefBlock()->getName(), &ok);
409 if (text == item->getRefBlock()->getName()) return;
411 if( (text.isEmpty()) || (text.length() > 30)) {
412 QMessageBox::warning(win,"Error in given name",
413 "the block name must be shorter than 30 characters, cannot be empty",
418 FunctionalBlock* block = params->getGraph()->getStimuliBlockByName(text);
420 QMessageBox::warning(win,"Error in given name",
421 "the name provided is similar to that of another stimuli block within the top group",
428 item->getRefBlock()->setName(text);
433 void Dispatcher::renameInterface(Context context, InterfaceItem *item) {
434 static QString fctName = "Dispatcher::renameInterface()";
436 cout << "call to " << qPrintable(fctName) << endl;
439 GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
444 text = QInputDialog::getText(win, "Rename an interface",
445 "New name:", QLineEdit::Normal,
446 item->refInter->getName(), &ok);
450 if (text == item->refInter->getName()) return;
452 if( (text.isEmpty()) || (text.length() > 30)) {
453 QMessageBox::warning(win,"Error in given name",
454 "the interface name must be shorter than 30 characters, cannot be empty",
459 AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
461 QMessageBox::warning(win,"Error in given name",
462 "the name provided is similar to that of another interface",
468 item->refInter->setName(text);
469 AbstractInterface* assoIface = item->refInter->getAssociatedIface();
470 if (assoIface != NULL) {
471 assoIface->setName(text+"_enb");
473 item->updateName(text);
474 item->getOwner()->nameChanged();
477 void Dispatcher::showPatterns(Context context, InterfaceItem *item) {
478 static QString fctName = "Dispatcher::showPatterns()";
480 cout << "call to " << qPrintable(fctName) << endl;
483 if (item->refInter->getDirection() == AbstractInterface::Input) {
484 msg = "Input pattern of iface ";
485 msg += item->refInter->getName();
487 msg += item->refInter->getOwner()->getName();
489 // get the precursor output pattern
490 ConnectedInterface* connIface = AI_TO_CON(item->refInter->getAssociatedIface());
491 QList<char>* out = connIface->getConnectedFrom()->getOutputPattern();
493 AbstractInputModifier* modifier = connIface->getInputModifier();
494 // check if the input is modified
495 if (modifier != NULL) {
497 out = modifier->getModifiedInput(out);
500 foreach(char c, *out) {
501 msg += QString::number((int)c);
505 else if (item->refInter->getDirection() == AbstractInterface::Output) {
506 msg = "Output pattern of iface ";
507 msg += item->refInter->getName();
509 msg += item->refInter->getOwner()->getName();
511 ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
512 if (iface->getOutputPattern() == NULL) return;
513 foreach(char c, *(iface->getOutputPattern())) {
514 msg += QString::number((int)c);
518 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
521 void Dispatcher::showModifier(Context context, InterfaceItem *item) {
522 static QString fctName = "Dispatcher::showModifier()";
524 cout << "call to " << qPrintable(fctName) << endl;
527 ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
528 AbstractInputModifier* mod = assoIface->getInputModifier();
529 if (mod->isDelay()) {
530 DelayInputModifier* delay = (DelayInputModifier *)mod;
531 msg = "Pattern of iface ";
532 msg += item->refInter->getName();
534 msg += item->refInter->getOwner()->getName();
535 msg += " is modified by a simple delay of ";
536 msg += QString::number(delay->getDelayLength());
539 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
542 void Dispatcher::removeModifier(Context context, InterfaceItem *item) {
543 static QString fctName = "Dispatcher::showModifier()";
545 cout << "call to " << qPrintable(fctName) << endl;
548 ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
549 assoIface->clearInputModifier();
553 void Dispatcher::duplicateBoxItem(Context context, BoxItem *item){
554 static QString fctName = "Dispatcher::duplicateBoxItem()";
556 cout << "call to " << qPrintable(fctName) << endl;
559 GroupScene *scene = item->getScene();
560 AbstractBlock* block = item->getRefBlock();
561 AbstractBlock *newBlock;
563 // only duplicate functional blocks
564 if(block->isFunctionalBlock()) {
566 // adding to the model
567 FunctionalBlock* funBlock = (FunctionalBlock*)block;
568 newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
569 // adding to the view
570 scene->createBoxItem(newBlock);
572 params->unsaveModif = true;
576 void Dispatcher::duplicateStimuliItem(Context context, StimuliItem *item) {
577 static QString fctName = "Dispatcher::duplicateStimuliItem()";
579 cout << "call to " << qPrintable(fctName) << endl;
582 GroupScene *scene = item->getScene();
583 AbstractBlock* block = item->getRefBlock();
584 AbstractBlock *newBlock;
586 // only duplicate functional blocks
587 if(block->isFunctionalBlock()) {
589 // adding to the model
590 FunctionalBlock* funBlock = (FunctionalBlock*)block;
591 newBlock = params->getGraph()->duplicateStimuliBlock(funBlock);
592 // adding to the view
593 scene->createStimuliItem(newBlock);
595 params->unsaveModif = true;
599 void Dispatcher::duplicateInterfaceItem(Context context, InterfaceItem *item) {
600 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
602 cout << "call to " << qPrintable(fctName) << endl;
605 AbstractInterface *refI = item->refInter;
606 if (! refI->isFunctionalInterface()) return;
608 AbstractBlock *refB = refI->getOwner();
609 if(! refB->isFunctionalBlock()) return;
611 FunctionalInterface* iface = (FunctionalInterface*)refI;
612 AbstractInterface *cloneIface = iface->clone();
613 if (cloneIface == NULL) {
614 QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
618 refB->addInterface(cloneIface);
620 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
621 item->getOwner()->addInterfaceItem(cloneIfaceItem,true);
623 // creating control interface if needed
624 if (refI->getAssociatedIface() != NULL) {
625 QString ctlName = cloneIface->getName()+"_enb";
626 ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,cloneIface->getDirection(), AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
627 refB->addInterface(ctlIface);
628 if (! ctlIface->setAssociatedIface(cloneIface)) {
629 cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
635 void Dispatcher::addBlock(Context context, int idCategory, int idBlock, int idScene, QHash<QString, int> clkRstToGen) {
636 static QString fctName = "Dispatcher::addBlock()";
638 cout << "call to " << qPrintable(fctName) << endl;
640 bool newStimuli = false;
642 /* For now, this method is only used while designing and not loading */
643 if (context == Design) {
644 GroupScene *scene = getSceneById(idScene);
645 ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
646 // if block has no inputs, propose to add it as a source to top scene
647 if ((scene->isTopScene()) && (ref->isSourceBlock())) {
648 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 ?");
649 if (ret == QMessageBox::Yes) {
654 FunctionalBlock* newOne = params->getGraph()->createStimuliBlock(ref, true);
655 StimuliItem* item = scene->createStimuliItem(newOne);
656 QHashIterator<QString,int> iter(clkRstToGen);
657 while (iter.hasNext()) {
659 AbstractInterface* iface = newOne->getIfaceFromName(iter.key());
660 if (iface->getPurpose() == AbstractInterface::Clock) {
661 connectStimuliItemClock(context,item,iface->getName(),iter.value());
663 else if (iface->getPurpose() == AbstractInterface::Reset) {
664 connectStimuliItemReset(context,item,iface->getName(),iter.value());
670 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
671 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref, true);
673 // creating the box item
674 BoxItem* item = scene->createBoxItem(newOne);
676 QHashIterator<QString,int> iter(clkRstToGen);
677 while (iter.hasNext()) {
679 AbstractInterface* iface = newOne->getIfaceFromName(iter.key());
680 if (iface->getPurpose() == AbstractInterface::Clock) {
681 connectBoxItemClock(context,item,iface->getName(),iter.value());
683 else if (iface->getPurpose() == AbstractInterface::Reset) {
684 connectBoxItemReset(context,item,iface->getName(),iter.value());
688 params->blockToItem.insert(newOne,item);
690 params->unsaveModif = true;
694 void Dispatcher::addClkRstGenBlock(Context context, double frequency) {
695 static QString fctName = "Dispatcher::addClkRstGenBlock()";
697 cout << "call to " << qPrintable(fctName) << endl;
701 if (context == Design) {
703 params->getGraph()->addClock(frequency);
706 GroupBlock *group = params->getGraph()->getTopGroup();
707 GroupScene *scene = topGroupWidget->getScene();
709 // creating the clkrstgen block
710 ReferenceBlock* ref = params->getHiddenReferenceBlock("clkrstgen");
711 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref, true);
713 QString name = "clkrstgen_";
714 name += QString::number(params->getGraph()->getClocks().size()-1);
715 newOne->setName(name);
717 // creating the box item
718 BoxItem* item = scene->createBoxItem(newOne, BoxItem::Left, AbstractBoxItem::Dimension);
719 item->setVisible(false);
721 ConnectedInterface* fromIfaceClk = NULL;
722 ConnectedInterface* fromIfaceReset = NULL;
723 QString clkName = "ext_clk_"+QString::number(params->getGraph()->getClocks().size()-1);
724 QString rstName = "ext_reset_"+QString::number(params->getGraph()->getClocks().size()-1);
725 fromIfaceClk = new GroupInterface(group,clkName, AbstractInterface::Input, AbstractInterface::Clock);
726 fromIfaceReset = new GroupInterface(group,rstName, AbstractInterface::Input, AbstractInterface::Reset);
727 group->addInterface(fromIfaceClk);
728 group->addInterface(fromIfaceReset);
729 // creating top group ext_clk iface item
730 GroupItem* groupItem = scene->getGroupItem();
731 InterfaceItem* fromIfaceItemClk = new InterfaceItem(0.5 , Parameters::West, fromIfaceClk, groupItem, params, true);
732 groupItem->addInterfaceItem(fromIfaceItemClk,true);
733 // creating top group ext_reset iface item
734 InterfaceItem* fromIfaceItemReset = new InterfaceItem(0.5 , Parameters::West, fromIfaceReset, groupItem, params, false);
735 groupItem->addInterfaceItem(fromIfaceItemReset,true);
736 // connecting ext_clk iface items
737 InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName("ext_clk");
738 if (toIfaceItemClk == NULL) {
739 cerr << "Abnormal case while connecting top group ext_clk to clkrstgen" << endl;
741 createConnection(context,fromIfaceItemClk, toIfaceItemClk, false);
742 // connecting ext_reset iface items
743 InterfaceItem* toIfaceItemReset = item->searchInterfaceItemByName("ext_reset");
744 if (toIfaceItemReset == NULL) {
745 cerr << "Abnormal case while connecting top group ext_reset to clkrstgen" << endl;
747 createConnection(context,fromIfaceItemReset, toIfaceItemReset, false);
749 params->blockToItem.insert(newOne,item);
750 params->unsaveModif = true;
756 GroupWidget *Dispatcher::createTopScene(Context context, double mainClock){
757 static QString fctName = "Dispatcher::createTopScene()";
759 cout << "call to " << qPrintable(fctName) << endl;
762 bool createIfaces = true;
763 if (context == Load) {
764 createIfaces = false;
766 // creating the graph and thus, the topgroup
767 Graph* graph = params->initGraph(createIfaces);
768 graph->addClock(mainClock);
770 GroupBlock *topBlock = graph->getTopGroup();
771 // creating the top group widget
772 topGroupWidget = new GroupWidget(NULL,this,params);
773 currentGroupWidget = topGroupWidget;
774 // getting the newly created scene
775 GroupScene *scene = topGroupWidget->getScene();
776 scene->setId(sceneCounter++);
777 params->setTopScene(scene);
778 params->setCurrentScene(scene);
779 // creating the view part of the group
780 GroupItem *group = new GroupItem(NULL,topBlock,this,params);
781 // associate the top scene to the top group iten
782 scene->setGroupItem(group);
784 // adding the fake interface to the top group item
785 //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
786 //group->addInterface(item,true);
789 if (context == Design) {
791 double freq = params->getGraph()->getClock(0);
792 params->getGraph()->resetClocks();
793 addClkRstGenBlock(context,freq);
796 groupList.append(topGroupWidget);
797 return topGroupWidget;
800 GroupWidget* Dispatcher::addNewEmptyGroup(Context context, GroupScene* scene, bool show) {
801 static QString fctName = "Dispatcher::addNewEmptyGroup();";
803 cout << "call to " << qPrintable(fctName) << endl;
805 bool createIfaces = true;
806 if (context == Load) {
807 createIfaces = false;
810 // getting the parent block in the graph
811 GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
812 cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
813 GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent, createIfaces);
814 cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
815 // creating the BlockItem in the scene
816 BoxItem* newItem = scene->createBoxItem(groupBlock);
818 params->unsaveModif = true;
820 GroupWidget* child = createChildScene(context, scene->getGroupWidget(),newItem);
821 if (show) child->show();
826 GroupWidget *Dispatcher::createChildScene(Context context, GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
827 static QString fctName = "Dispatcher::createChildScene()";
829 cout << "call to " << qPrintable(fctName) << endl;
832 GroupWidget* group = NULL;
833 /* NB: this method may be called during design process or when loading
834 a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
835 cannot be initialized yet. This is why there are 2 cases below
838 if (upperItemOfGroupItem != NULL) {
839 // getting back the goup block already created
840 GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
841 // creating the view part of the group
842 GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
844 // creating the group widget
845 group = new GroupWidget(parentWidget, this, params);
846 // getting the newly created scene
847 GroupScene *scene = group->getScene();
848 scene->setId(sceneCounter++);
849 // affecting group item to the scene
850 scene->setGroupItem(groupItem);
851 groupList.append(group);
853 mainWindow->getLibrary()->updateComboScene();
856 GroupItem *groupItem = new GroupItem(this,params);
857 // creating the group widget
858 group = new GroupWidget(parentWidget, this, params);
859 // getting the newly created scene
860 GroupScene *scene = group->getScene();
861 // affecting group item to the scene
862 scene->setGroupItem(groupItem);
863 groupList.append(group);
868 void Dispatcher::destroyScene(Context context, GroupScene *scene) {
869 foreach(GroupScene* s, scene->getChildrenScene()) {
870 destroyScene(context, s);
873 if (scene->getNbChildScene() == 0) {
874 // remove scene from the parent list, if possible
875 if (scene->getParentScene() != NULL) {
876 scene->getParentScene()->removeChildScene(scene);
878 // destroy the GroupWidget
879 groupList.removeAll(scene->getGroupWidget());
880 scene->getGroupWidget()->deleteLater();
883 cerr << "Abnormal case when destroying a scene" << endl;
887 void Dispatcher::showRaiseWindow(Context context, BoxItem *item) {
888 static QString fctName = "Dispatcher::showRaiseWindow()";
890 cout << "call to " << qPrintable(fctName) << endl;
893 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
894 GroupItem* child = item->getChildGroupItem();
896 cerr << "abnormal case: child group item is null " << endl;
900 GroupWidget* win = child->getScene()->getGroupWidget();
904 win->activateWindow();
906 currentGroupWidget = win;
907 params->setCurrentScene(currentGroupWidget->getScene());
910 void Dispatcher::showRstClkIface(Context context, AbstractBoxItem *item) {
911 static QString fctName = "Dispatcher::showRstClkIface()";
913 cout << "call to " << qPrintable(fctName) << endl;
916 item->setRstClkVisible(!item->isRstClkVisible());
920 void Dispatcher::showWishboneIface(Context context, AbstractBoxItem *item) {
921 static QString fctName = "Dispatcher::showWishboneIface()";
923 cout << "call to " << qPrintable(fctName) << endl;
926 item->setWishboneVisible(!item->isWishboneVisible());
929 void Dispatcher::addNewFullGroup(Context context) {
930 static QString fctName = "Dispatcher::addNewFullGroup()";
932 cout << "call to " << qPrintable(fctName) << endl;
938 QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
939 QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
940 QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
942 /* What must be done:
943 1 - creating a new GroupBlock
944 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
945 3 - creating a BlockItem that references the new GroupBlock
946 4 - creating a new GroupWidget
947 5 - creating a new GroupItem added to the scene of the GroupWidget
951 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
952 associated to the GroupItem of the current scene
954 GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
955 GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
956 /* step 2: moving selected blocks */
957 foreach(BlockItem* blockItem, listBlocks) {
958 parentBlock->removeBlock(blockItem->getRefBlock());
959 newGroupBlock->addBlock(blockItem->getRefBlock());
962 GroupItem *parent = currentGroup->getScene()->getGroupItem();
963 GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
964 BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
965 GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
967 //create the new window
968 GroupWidget* win = new GroupWidget(this,params);
969 win->getScene()->setGroupItem(groupItem);
970 win->getScene()->addItem(groupItem);
971 ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
972 params->addWindow(win);
976 params->getCurrentScene()->addBlockItem(blockItem);
977 params->getCurrentScene()->addItem(blockItem);
978 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
980 //replace selected blocks in the group
981 foreach(AbstractBoxItem *block, listBlocks){
982 ((GroupItem*)block->getParentItem())->removeBlockItem(block);
983 ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
984 params->getCurrentScene()->removeItem(block);
985 params->getCurrentScene()->removeBlockItem(block);
987 groupBlock->addBlock(block->getRefBlock());
988 listAbstractBlocks.append(block->getRefBlock());
990 block->setUpperItem(groupItem);
991 groupItem->addBlockItem(block);
992 win->getScene()->addItem(block);
993 win->getScene()->addBlockItem(block);
996 //replace connection between selected blocks in the group
997 foreach(ConnectionItem *conn, connections){
998 if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
999 if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
1000 parent->removeConnection(conn);
1001 params->getCurrentScene()->removeItem(conn);
1003 groupItem->addConnection(conn);
1004 win->getScene()->addItem(conn);
1009 //create new interfaces and connections for the new group
1010 foreach(AbstractBoxItem *block, listBlocks){
1011 foreach(InterfaceItem *inter, block->getInterfaces()){
1012 cout << "inter : " << inter->getName().toStdString() << endl;
1013 if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
1014 cout << "connected from non null" << endl;
1015 if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
1017 AbstractInterface *iface = inter->refInter->clone(0);
1018 iface->setName(iface->getName()+"_group");
1019 groupBlock->addInterface(iface);
1021 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
1022 blockItem->addInterface(ifaceItem);
1023 blockItem->resetInterfacesPosition();
1025 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
1026 groupItem->addInterface(ifaceGroupItem);
1027 groupItem->resetInterfacesPosition();
1028 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
1029 if(conn->getToInterfaceItem() == inter){
1030 conn->setToInterfaceItem(ifaceItem);
1031 ifaceItem->refInter->setConnectedFrom(NULL);
1032 conn->getFromInterfaceItem()->refInter->clearConnectedTo();
1033 connect(ifaceItem,conn->getFromInterfaceItem());
1036 params->setCurrentWindow(win);
1038 inter->refInter->setConnectedFrom(NULL);
1039 ifaceGroupItem->refInter->clearConnectedTo();
1040 connect(inter,ifaceGroupItem);
1041 params->setCurrentWindow(mainWindow);
1045 if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
1046 cout << "connected to non null" << endl;
1047 foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
1048 if(!listAbstractBlocks.contains(iface->getOwner())){
1050 AbstractInterface *iface = inter->refInter->clone(0);
1051 iface->setName(iface->getName()+"_group");
1052 groupBlock->addInterface(iface);
1054 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
1055 blockItem->addInterface(ifaceItem);
1056 blockItem->resetInterfacesPosition();
1058 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
1059 if(conn->getFromInterfaceItem() == inter){
1060 conn->setFromInterfaceItem(ifaceItem);
1061 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
1062 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
1066 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
1067 groupItem->addInterface(ifaceGroupItem);
1068 groupItem->resetInterfacesPosition();
1069 inter->refInter->clearConnectedTo();
1070 ifaceGroupItem->refInter->setConnectedFrom(NULL);
1071 connect(ifaceGroupItem,inter);
1080 parent->updateShape();
1081 currentGroup->getScene()->updateConnectionItemsShape();
1083 groupItem->updateShape();
1084 win->getScene()->updateConnectionItemsShape();
1085 groupItem->update(groupItem->boundingRect());
1090 void Dispatcher::removeBoxItem(Context context, BoxItem *item) {
1091 static QString fctName = "Dispatcher::removeBoxItem()";
1092 #ifdef DEBUG_FCTNAME
1093 cout << "call to " << qPrintable(fctName) << endl;
1096 if (context != Design) return;
1098 /* a BoxItem (group of func) can be removed only if none of its
1099 interfaces is connected to a group interface that is itself
1100 connected to another one.
1102 bool canRemove = true;
1104 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
1105 foreach(ConnectionItem* conn, ifaceItem->connections) {
1106 InterfaceItem* other = NULL;
1107 if (conn->getFromInterfaceItem() == ifaceItem) {
1108 other = conn->getToInterfaceItem();
1111 other = conn->getFromInterfaceItem();
1114 if (other->getOwner()->isGroupItem()) {
1115 ConnectedInterface* ref = other->refInter;
1116 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
1123 QMessageBox::warning(NULL,"Forbidden operation",
1124 "The block has at least one connection to a group interface that is totally connected.",
1130 if (item->getRefBlock()->isFunctionalBlock()) {
1131 msg = "Removing block ";
1134 msg = "Removing group ";
1136 msg += item->getRefBlock()->getName();
1137 msg += " and all its connections.\n\nAre you sure ?";
1139 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
1140 if (ret == QMessageBox::Cancel) {
1143 removeAllBlockConnections(context, item);
1145 if (item->getRefBlock()->isFunctionalBlock()) {
1146 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
1147 item->getScene()->removeBoxItem(item);
1148 params->getGraph()->removeFunctionalBlock(block);
1149 params->blockToItem.remove(block);
1152 else if (item->getRefBlock()->isGroupBlock()) {
1154 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
1156 // remove all child scenes recursively
1157 GroupItem* subgroup = item->getChildGroupItem();
1158 destroyScene(context, subgroup->getScene());
1159 // remove the BoxItem
1160 item->getScene()->removeBoxItem(item);
1161 // remove the group from the graph
1162 params->getGraph()->removeGroupBlock(group);
1166 void Dispatcher::removeAllBlockConnections(Context context, AbstractBoxItem *item) {
1167 static QString fctName = "Dispatcher::removeAllBlockConnection()";
1168 #ifdef DEBUG_FCTNAME
1169 cout << "call to " << qPrintable(fctName) << endl;
1172 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
1173 foreach(ConnectionItem* conn, ifaceItem->connections) {
1174 removeConnection(context, conn);
1179 void Dispatcher::removeStimuliItem(Context context, StimuliItem *item) {
1180 static QString fctName = "Dispatcher::removeStimuliItem()";
1181 #ifdef DEBUG_FCTNAME
1182 cout << "call to " << qPrintable(fctName) << endl;
1185 QString msg = "Removing stimmuli ";
1187 msg += item->getRefBlock()->getName();
1188 msg += " and all its connections.\n\nAre you sure ?";
1190 int ret = QMessageBox::question(NULL,"Removing stimuli block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
1191 if (ret == QMessageBox::Cancel) {
1194 removeAllBlockConnections(context, item);
1196 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
1197 item->getScene()->removeStimuliItem(item);
1198 params->getGraph()->removeStimuliBlock(block);
1202 void Dispatcher::removeConnection(Context context, ConnectionItem *connItem) {
1203 static QString fctName = "Dispatcher::removeConnection()";
1204 #ifdef DEBUG_FCTNAME
1205 cout << "call to " << qPrintable(fctName) << endl;
1207 InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
1208 InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
1211 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
1214 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not
1215 GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem
1217 ConnectedInterface *fromInter = fromIfaceItem->refInter;
1218 ConnectedInterface *toInter = toIfaceItem->refInter;
1220 // test if one of the interface bounded to item is owned by a GroupItem
1221 if (fromIfaceItem->getOwner()->isGroupItem()) {
1222 groupItem = ABI_TO_GI(fromIfaceItem->getOwner());
1223 groupIfaceItem = fromIfaceItem;
1225 else if (toIfaceItem->getOwner()->isGroupItem()) {
1226 groupItem = ABI_TO_GI(toIfaceItem->getOwner());
1227 groupIfaceItem = toIfaceItem;
1230 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
1233 // removing the connection from graph
1235 cout << "removing connections from graph ..." ;
1237 fromInter->disconnectTo(toInter);
1240 cout << "done." << endl ;
1243 // removing the connection from scene
1245 cout << "removing connections from scene ..." ;
1247 groupItem->getScene()->removeConnectionItem(connItem);
1250 cout << "done." << endl ;
1253 // if one of the interface bounded to connItem is owned by the GroupItem of the scene
1254 if (groupIfaceItem != NULL) {
1256 // determine if the interface must be removed since it has no more connections.
1257 bool groupInterRemove = false;
1258 if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true;
1260 if (groupInterRemove) {
1261 // get the GroupInterface from interface item
1262 ConnectedInterface* groupInter = groupIfaceItem->refInter;
1263 // remove interface from GroupItem, and delete it.
1264 groupItem->removeInterfaceItem(groupIfaceItem);
1265 // get the parent BoxItem of GroupItem if it exists.
1266 BoxItem* parent2Item = groupItem->getParentItem();
1267 if (parent2Item != NULL) {
1268 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter);
1269 // remove interface intem in parent BoxItem
1270 parent2Item->removeInterfaceItem(group2IfaceItem);
1272 // remove GroupInterface in the graph.
1273 groupInter->getOwner()->removeInterface(groupInter);
1278 void Dispatcher::connectBoxItemClock(Context context, BoxItem *item, QString clkName, int idGen) throw(Exception) {
1280 InterfaceItem* fromIfaceItemClk = NULL;
1281 InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName(clkName);
1282 GroupItem* parentGroup = item->getScene()->getGroupItem();
1283 BoxItem* clkrstItem = NULL;
1285 if (parentGroup->getRefBlock()->isTopGroupBlock()) {
1286 QString genName = "clkrstgen_" + QString::number(idGen);
1287 clkrstItem = item->getScene()->searchBoxItemByName(genName);
1288 if (clkrstItem == NULL) {
1289 throw(Exception(IFACE_TOP_NOCLKRSTGEN));
1292 fromIfaceItemClk = clkrstItem->searchInterfaceItemByName("clk");
1294 cout << "connecting clock of " << qPrintable(item->getRefBlock()->getName()) << " to clk of " << qPrintable(genName) << endl;
1297 // searching for ext_clk_idGen
1298 QString name = "ext_clk_"+QString::number(idGen);
1299 fromIfaceItemClk = parentGroup->searchInterfaceItemByName(name);
1300 cout << "connecting clock of " << qPrintable(item->getRefBlock()->getName()) << " to " << qPrintable(name) << " of parent group " << qPrintable(parentGroup->getRefBlock()->getName()) << endl;
1303 if (fromIfaceItemClk == NULL) {
1304 throw(Exception(IFACE_GROUP_NOCLKRST));
1307 createConnection(context, fromIfaceItemClk, toIfaceItemClk, false);
1308 cout << "connection done." << endl;
1312 void Dispatcher::connectBoxItemReset(Context context, BoxItem *item, QString rstName, int idGen) throw(Exception) {
1313 InterfaceItem* fromIfaceItemRst = NULL;
1314 InterfaceItem* toIfaceItemRst = item->searchInterfaceItemByName(rstName);
1315 GroupItem* parentGroup = item->getScene()->getGroupItem();
1316 BoxItem* clkrstItem = NULL;
1318 if (parentGroup->getRefBlock()->isTopGroupBlock()) {
1319 QString genName = "clkrstgen_" + QString::number(idGen);
1320 clkrstItem = item->getScene()->searchBoxItemByName(genName);
1321 if (clkrstItem == NULL) {
1322 throw(Exception(IFACE_TOP_NOCLKRSTGEN));
1325 fromIfaceItemRst = clkrstItem->searchInterfaceItemByName("reset");
1327 cout << "connecting reset of " << qPrintable(item->getRefBlock()->getName()) << " to reset of " << qPrintable(genName) << endl;
1330 // searching for ext_rst_idGen
1331 QString name = "ext_rst_"+QString::number(idGen);
1332 fromIfaceItemRst = parentGroup->searchInterfaceItemByName(name);
1333 cout << "connecting reset of " << qPrintable(item->getRefBlock()->getName()) << " to " << qPrintable(name) << " of parent group " << qPrintable(parentGroup->getRefBlock()->getName()) << endl;
1336 if (fromIfaceItemRst == NULL) {
1337 throw(Exception(IFACE_GROUP_NOCLKRST));
1340 createConnection(context, fromIfaceItemRst, toIfaceItemRst, false);
1341 cout << "connection done." << endl;
1345 void Dispatcher::connectStimuliItemClock(Context context, StimuliItem *item, QString clkName, int idGen) throw(Exception) {
1346 InterfaceItem* fromIfaceItemClk = NULL;
1347 InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName(clkName);
1348 BoxItem* clkrstItem = NULL;
1350 QString genName = "clkrstgen_" + QString::number(idGen);
1351 clkrstItem = item->getScene()->searchBoxItemByName(genName);
1352 if (clkrstItem == NULL) {
1353 throw(Exception(IFACE_TOP_NOCLKRSTGEN));
1356 fromIfaceItemClk = clkrstItem->searchInterfaceItemByName("clk");
1358 cout << "connecting clock of " << qPrintable(item->getRefBlock()->getName()) << " to clock of " << qPrintable(genName) << endl;
1360 if (fromIfaceItemClk == NULL) {
1361 throw(Exception(IFACE_GROUP_NOCLKRST));
1364 createConnection(context, fromIfaceItemClk, toIfaceItemClk, false);
1365 cout << "connection done." << endl;
1369 void Dispatcher::connectStimuliItemReset(Context context, StimuliItem *item, QString rstName, int idGen) throw(Exception) {
1370 InterfaceItem* fromIfaceItemRst = NULL;
1371 InterfaceItem* toIfaceItemRst = item->searchInterfaceItemByName(rstName);
1372 BoxItem* clkrstItem = NULL;
1374 QString genName = "clkrstgen_" + QString::number(idGen);
1375 clkrstItem = item->getScene()->searchBoxItemByName(genName);
1376 if (clkrstItem == NULL) {
1377 throw(Exception(IFACE_TOP_NOCLKRSTGEN));
1380 fromIfaceItemRst = clkrstItem->searchInterfaceItemByName("reset");
1382 cout << "connecting reset of " << qPrintable(item->getRefBlock()->getName()) << " to reset of " << qPrintable(genName) << endl;
1384 if (fromIfaceItemRst == NULL) {
1385 throw(Exception(IFACE_GROUP_NOCLKRST));
1388 createConnection(context, fromIfaceItemRst, toIfaceItemRst, false);
1389 cout << "connection done." << endl;
1394 void Dispatcher::showBlocksLibrary(){
1395 cout << "showing block library" << endl;
1396 mainWindow->getLibrary()->show();
1397 mainWindow->getLibrary()->raise();
1400 void Dispatcher::showProperties(Context context, InterfaceItem *inter) {
1401 QDialog* dial = new InterfacePropertiesDialog(inter);
1405 /* connectInterToGroup() :
1406 The only way for a block (functional of group) within a GroupItem to be connected
1407 to the latter is to right-click on one of its interfaces and to choose "connect to group".
1408 That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
1411 void Dispatcher::connectInterToGroup(Context context, InterfaceItem *item){
1413 // getting the GroupBlock and GroupItem that are parent of the block that owns item
1414 ConnectedInterface *refInter = item->refInter;
1415 cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
1416 GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
1417 cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
1418 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
1420 // creating/adding the group interface in the graph model
1421 GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
1422 parentItem->getRefBlock()->addInterface(groupInter);
1423 // creating/adding the group control interface in the graph model if the purpose is data
1424 if (refInter->getPurpose() == AbstractInterface::Data) {
1425 GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
1426 groupCtlInter->setAssociatedIface(groupInter);
1427 parentItem->getRefBlock()->addInterface(groupCtlInter);
1429 // creating/adding the group interface in the current scene model, and connection item
1430 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1431 parentItem->addInterfaceItem(groupIfaceItem,true);
1433 // creating the connection, in graph and with an item
1434 createConnection(context, item, groupIfaceItem);
1436 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1437 BoxItem* parent2Item = parentItem->getParentItem();
1438 if(parent2Item != NULL){
1439 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1440 parent2Item->addInterfaceItem(blockIfaceItem,true);
1444 parentItem->getScene()->updateConnectionItemsShape();
1445 unselectAllItems(context);
1446 params->unsaveModif = true;
1449 void Dispatcher::removeFunctionalInterface(Context context, InterfaceItem *item) {
1450 static QString fctName = "Dispatcher::removeBlockInterface()";
1451 #ifdef DEBUG_FCTNAME
1452 cout << "call to " << qPrintable(fctName) << endl;
1455 /* first, remove all connections from item
1456 NB: if there is a connection to a group interface, then this
1457 method should not be called if the group interface is also
1458 connected to another interface. Normally, this is not possible
1459 because such a check is done when creating the contextual menu
1460 that allows to remove an interface.
1462 foreach(ConnectionItem* conn, item->connections) {
1463 removeConnection(context, conn);
1466 ConnectedInterface* ref = item->refInter;
1467 item->getOwner()->removeInterfaceItem(item);
1468 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1469 fun->removeInterface(ref);
1472 void Dispatcher::removeGroupInterface(Context context, InterfaceItem *item) {
1473 static QString fctName = "Dispatcher::removeGroupInterface()";
1474 #ifdef DEBUG_FCTNAME
1475 cout << "call to " << qPrintable(fctName) << endl;
1478 /* NB: just remove all connections from/to this item, since when there are no more
1479 ones to a GroupItem, it is automatically deleted.
1481 foreach(ConnectionItem* conn, item->connections) {
1482 removeConnection(context, conn);
1486 QMap<int, QString> Dispatcher::getAllGroupNames() {
1488 QMap<int, QString> list;
1489 foreach(GroupWidget *group, groupList) {
1490 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1495 GroupScene* Dispatcher::getSceneById(int id) {
1496 foreach(GroupWidget *group, groupList){
1497 if(group->getScene()->getId() == id)
1498 return group->getScene();
1500 cout << "search scene by id :" << id << " :: not found..." << endl;
1504 GroupItem *Dispatcher::getGroupItemById(int id) {
1505 foreach(GroupWidget *group, groupList) {
1506 GroupScene* scene = group->getScene();
1507 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1509 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1513 BoxItem *Dispatcher::getBoxItemById(int id) {
1514 foreach(GroupWidget *group, groupList) {
1516 GroupScene* scene = group->getScene();
1517 foreach(BoxItem *item, scene->getBoxItems()){
1518 if(item->getId() == id){
1523 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1527 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1529 foreach(GroupWidget *group, groupList) {
1531 GroupScene* scene = group->getScene();
1533 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1534 if(item->getId() == id){
1538 foreach(BoxItem *block, scene->getBoxItems()){
1539 foreach(InterfaceItem *item, block->getInterfaces()){
1540 if(item->getId() == id){
1546 cout << "search interface by id :" << id << " :: not found..." << endl;
1550 void Dispatcher::findGraphModifications(Context context, FunctionalBlock *block) {
1551 static QString fctName = "Dispatcher::findGraphModifications()";
1552 #ifdef DEBUG_FCTNAME
1553 cout << "call to " << qPrintable(fctName) << endl;
1556 block->computeAdmittanceDelays();
1557 // get the block item that is associated to block
1558 BoxItem* toBlockItem = params->blockToItem.value(block);
1560 /* VERSION 1: just add delays if needed */
1561 QMap<AbstractInterface*,QList<int>* > delays = block->getAdmittanceDelays();
1562 QMapIterator<AbstractInterface*,QList<int>* > iterD(delays);
1563 while (iterD.hasNext()) {
1565 QList<int>* delay = iterD.value();
1566 if (delay->at(0) > 0) {
1567 // create delay and associate it to the connected input
1569 ConnectedInterface* toIface = AI_TO_CON(iterD.key());
1570 AbstractInputModifier* mod = new DelayInputModifier(toIface, delay->at(0));
1571 cout << "modify input of " << qPrintable(toIface->getName()) << endl;
1572 toIface->setInputModifier(mod);
1574 toBlockItem->update();