]> AND Private Git Repository - blast.git/blob - Parameters.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
moved clocks list to graph
[blast.git] / Parameters.cpp
1 #include "Parameters.h"\r
2 \r
3 #include "Dispatcher.h"\r
4 #include "BlockLibraryTree.h"\r
5 \r
6 #include "BlockCategory.h"\r
7 \r
8 #include "GroupWidget.h"\r
9 #include "GroupScene.h"\r
10 #include "GroupItem.h"\r
11 #include "BoxItem.h"\r
12 #include "StimuliItem.h"\r
13 #include "InterfaceItem.h"\r
14 #include "ConnectionItem.h"\r
15 \r
16 #include "Graph.h"\r
17 #include "ReferenceBlock.h"\r
18 #include "GroupBlock.h"\r
19 #include "FunctionalBlock.h"\r
20 #include "ReferenceInterface.h"\r
21 #include "GroupInterface.h"\r
22 #include "FunctionalInterface.h"\r
23 \r
24 #include "Exception.h"\r
25 #include "BlocksToConfigureWidget.h"\r
26 \r
27 #include "BlockParameterGeneric.h"\r
28 \r
29 #include "DelayInputModifier.h"\r
30 \r
31 Parameters::Parameters() {\r
32   categoryTree = NULL;\r
33   arrowWidth = 5;\r
34   arrowHeight = 10;\r
35   arrowLineLength = 10;\r
36 \r
37   defaultBlockWidth = 100;\r
38   defaultBlockHeight = 100;\r
39   defaultBlockFont = QFont("Arial");\r
40   defaultBlockFontSize = 12;\r
41 \r
42   setArrowPathes();\r
43 \r
44   sceneMode = MODE_EDITION; // default mode\r
45   editState = Parameters::EditNoOperation;\r
46 \r
47   unsaveModif = false;\r
48   isRstClkShown = false;\r
49   \r
50   validityExtension = "_enb";\r
51 \r
52   projectPath = "";\r
53   projectName = "";\r
54   projectFile = "";\r
55 \r
56   graph = new Graph();\r
57 }\r
58 \r
59 Parameters::~Parameters() {\r
60   clear();\r
61 }\r
62 \r
63 void Parameters::clear() {\r
64   delete categoryTree;\r
65   QListIterator<ReferenceBlock *> iter(availableBlocks);\r
66   while(iter.hasNext()) {\r
67     ReferenceBlock* item = iter.next();\r
68     delete item;\r
69   }\r
70   availableBlocks.clear();\r
71   refPathes.clear();\r
72 }\r
73 \r
74 Graph* Parameters::initGraph(bool createTopGroupIfaces) {\r
75   graph->createTopGroup(createTopGroupIfaces);\r
76   return graph;\r
77 }\r
78 \r
79 void Parameters::destroyGraph() {\r
80   delete graph;\r
81 }\r
82 \r
83 ReferenceBlock* Parameters::getReferenceBlock(int idCategory, int idBlock) {\r
84 \r
85   BlockCategory* blockCat = categoryTree->searchCategory(idCategory);\r
86 \r
87   if (blockCat == NULL) return NULL;\r
88   ReferenceBlock* ref = blockCat->getBlockById(idBlock);\r
89   return ref;\r
90 }\r
91 \r
92 ReferenceBlock* Parameters::getHiddenReferenceBlock(QString blockName) {\r
93 \r
94   BlockCategory* blockCat = categoryTree->searchCategory(100);\r
95   if (blockCat == NULL) return NULL;\r
96   ReferenceBlock* ref = blockCat->getBlockByName(blockName);\r
97   return ref;\r
98 }\r
99 \r
100 double Parameters::getFeedingClockFrequency(AbstractInterface *iface) {\r
101 \r
102   int idClock = 0;\r
103 \r
104   if (iface->isReferenceInterface()) return 0.0;\r
105 \r
106   if (iface->getClockIfaceType() == AbstractInterface::ParameterName) {\r
107     BlockParameter* param = iface->getOwner()->getParameterFromName(iface->getClockIfaceString());\r
108     if (!param->isUserParameter()) return 0.0;\r
109     bool ok;\r
110     double freq = param->getDoubleValue(&ok);\r
111     if (!ok) {\r
112       cerr << "Abnormal case: cannot retrieve clock id from parameter  " << qPrintable(param->getName()) << endl;\r
113     }\r
114     return freq;\r
115   }\r
116   else if ( (iface->getClockIfaceType() == AbstractInterface::ClockName) || ((iface->getDirection() == AbstractInterface::Input) && (iface->getPurpose() == AbstractInterface::Clock))) {\r
117 \r
118     // if iface is not clock, retrieve the clock related to it\r
119     if (iface->getClockIfaceType() == AbstractInterface::ClockName) {\r
120       iface = iface->getClockIface();\r
121     }\r
122     // if iface is a group interface, then iface name is ext_clk_X, thus extract the X\r
123     if (iface->isGroupInterface()) {\r
124       QString name = iface->getName();\r
125       name.remove(0,8);\r
126       bool ok;\r
127       idClock = name.toInt(&ok);\r
128       if (!ok) {\r
129         cerr << "Abnormal case: cannot retrieve clock id from iface name " << qPrintable(iface->getName()) << endl;\r
130         return 0.0;\r
131       }\r
132     }\r
133     // if iface is a functional interface, it is connected to clkrstgen_X (in top group) or to ext_clk_X (in subgroup)\r
134     else if (iface->isFunctionalInterface()) {\r
135       FunctionalInterface* funIface = AI_TO_FUN(iface);\r
136       ConnectedInterface* connFrom = funIface->getConnectedFrom();\r
137       if (connFrom == NULL) {\r
138         cerr << "Abnormal case: input clock " << qPrintable(iface->getName()) << " is not connected" << endl;\r
139         return 0.0;\r
140       }\r
141       if (iface->getOwner()->isTopGroupBlock()) {\r
142         QString name = connFrom->getOwner()->getName();\r
143         name.remove(0,10);\r
144         bool ok;\r
145         idClock = name.toInt(&ok);\r
146         if (!ok) {\r
147           cerr << "Abnormal case: cannot retrieve clock id for " << qPrintable(iface->getName()) << endl;\r
148           return 0.0;\r
149         }\r
150       }\r
151       else {\r
152         QString name = connFrom->getName();\r
153         name.remove(0,8);\r
154         bool ok;\r
155         idClock = name.toInt(&ok);\r
156         if (!ok) {\r
157           cerr << "Abnormal case: cannot retrieve clock id for " << qPrintable(iface->getName()) << endl;\r
158           return 0.0;\r
159         }\r
160       }\r
161     }\r
162   }\r
163   return graph->getClock(idClock);\r
164 }\r
165 \r
166 void Parameters::createDelayBlock() {\r
167   delayRef = new ReferenceBlock("no.xml");\r
168   delayRef->addCategory(100);\r
169   delayRef->setName("delay");\r
170 \r
171   BlockCategory* cat = categoryTree->searchCategory(100);\r
172   cat->blocks.append(delayRef);\r
173 \r
174   AbstractInterface* interIn = new ReferenceInterface(delayRef,"data_in",AbstractInterface::Input, AbstractInterface::Data, "expression","$in_width");\r
175   delayRef->addInterface(interIn);\r
176   AbstractInterface* interInCtl = new ReferenceInterface(delayRef,"data_in_enb",AbstractInterface::Input, AbstractInterface::Control, "boolean","1");\r
177   delayRef->addInterface(interInCtl);\r
178   interInCtl->setAssociatedIface(interIn);\r
179   AbstractInterface* interOut = new ReferenceInterface(delayRef,"data_out",AbstractInterface::Output, AbstractInterface::Data, "expression","$in_width");\r
180   delayRef->addInterface(interOut);\r
181   AbstractInterface* interOutCtl = new ReferenceInterface(delayRef,"data_out_enb",AbstractInterface::Output, AbstractInterface::Control, "boolean","1");\r
182   delayRef->addInterface(interOutCtl);\r
183   interOutCtl->setAssociatedIface(interOut);\r
184   BlockParameter* param1 = new BlockParameterGeneric(delayRef,"in_width","natural","8");\r
185   BlockParameter* param2 = new BlockParameterGeneric(delayRef,"dly_length","natural","1");\r
186   delayRef->addParameter(param1);\r
187   delayRef->addParameter(param2);\r
188   delayImpl = new BlockImplementation("no.xml");\r
189   delayImpl->setDelta("1");\r
190   QHash<QString,QString> consPattern;\r
191   consPattern.insert("data_in_enb","1");\r
192   delayImpl->setConsumptionPattern(consPattern);\r
193   QHash<QString,QString> prodPattern;\r
194   prodPattern.insert("data_out_enb","O{$dly_length}1");\r
195   delayImpl->setProductionPattern(prodPattern);\r
196   delayImpl->setProductionCounter("1");\r
197   delayRef->addImplementation(delayImpl);\r
198   delayImpl->setReference(delayRef);\r
199   if (! delayImpl->checkPatterns()) {\r
200     cout << "Delay block creation: failure" << endl;\r
201   }\r
202   else {\r
203     cout << "Delay block creation: success" << endl;\r
204   }\r
205 \r
206 }\r
207 \r
208 \r
209 \r
210 void Parameters::validateXmlFile(const QString& xmlFileName, const QString& xsdFileName, XmlFileType fileType) throw(Exception) {\r
211   // opening configFile\r
212   QFile xmlFile(xmlFileName);\r
213   if (!xmlFile.open(QIODevice::ReadOnly)) {\r
214     if (fileType == Configuration) {\r
215       throw(Exception(CONFIGFILE_NOACCESS));\r
216     }\r
217     else if (fileType == Reference) {\r
218       throw(Exception(BLOCKFILE_NOACCESS));\r
219     }\r
220     else if (fileType == Implementation) {\r
221       throw(Exception(IMPLFILE_NOACCESS));\r
222     }\r
223     else if (fileType == Project) {\r
224       throw(Exception(PROJECTFILE_NOACCESS));\r
225     }\r
226   }\r
227 \r
228   QFile xsdFile(xsdFileName);\r
229   if (!xsdFile.open(QIODevice::ReadOnly)) {\r
230     xsdFile.close();\r
231     if (fileType == Configuration) {\r
232       throw(Exception(CONFIGFILE_NOACCESS));\r
233     }\r
234     else if (fileType == Reference) {\r
235       throw(Exception(BLOCKFILE_NOACCESS));\r
236     }\r
237     else if (fileType == Implementation) {\r
238       throw(Exception(IMPLFILE_NOACCESS));\r
239     }\r
240     else if (fileType == Project) {\r
241       throw(Exception(PROJECTFILE_NOACCESS));\r
242     }\r
243   }\r
244 \r
245   if(validate(xmlFile,xsdFile) == false) {\r
246     xmlFile.close();\r
247     xsdFile.close();\r
248     if (fileType == Configuration) {\r
249       throw(Exception(CONFIGFILE_CORRUPTED));\r
250     }\r
251     else if (fileType == Reference) {\r
252       throw(Exception(BLOCKFILE_CORRUPTED));\r
253     }\r
254     else if (fileType == Implementation) {\r
255       throw(Exception(IMPLFILE_CORRUPTED));\r
256     }\r
257     else if (fileType == Project) {\r
258       throw(Exception(PROJECTFILE_CORRUPTED));\r
259     }\r
260   }\r
261   xmlFile.close();\r
262   xsdFile.close();\r
263 }\r
264 \r
265 bool Parameters::validate(QFile& fileXml, QFile& fileSchema) {\r
266 \r
267   // 2 files are supposed to be already opened\r
268   QXmlSchema schema;\r
269 \r
270   if(! schema.load(&fileSchema)){\r
271     cout << "invalid schema" << endl;\r
272     return false;\r
273   }\r
274 \r
275   QXmlSchemaValidator validator(schema);\r
276 \r
277   if(! validator.validate(&fileXml)){\r
278     cout << "invalid xml" << endl;\r
279     return false;\r
280   }\r
281   return true;\r
282 }\r
283 \r
284 QDomElement Parameters::openProjectFile(const QString& projectFileName) throw(Exception) {\r
285 \r
286   try {\r
287     validateXmlFile(projectFileName,"projectfile.xsd",Project);\r
288   }\r
289   catch(Exception err) {\r
290     throw(err);\r
291   }\r
292 \r
293   QFile projectFile(projectFileName);\r
294   QDomDocument doc("projectFile");\r
295 \r
296   if(!projectFile.open(QIODevice::ReadOnly)) {\r
297     throw(Exception(PROJECTFILE_NOACCESS));\r
298   }\r
299   if(!doc.setContent(&projectFile)) {\r
300     projectFile.close();\r
301     throw(Exception(PROJECTFILE_CORRUPTED));\r
302   }\r
303   projectFile.close();\r
304 \r
305   QDomElement root = doc.documentElement();\r
306 \r
307   return root;\r
308 }\r
309 \r
310 GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) {\r
311 \r
312   bool ok = false;\r
313   GroupWidget* groupWidget = NULL;\r
314   GroupItem *groupItem = NULL;\r
315   GroupBlock *groupBlock = NULL;\r
316 \r
317   GroupWidget* topGroup = NULL;\r
318 \r
319   QString path = root.attribute("project_path","none");\r
320   if (path != "none") {\r
321     QDir dir(path);\r
322     if (dir.exists()) {\r
323       projectPath = path;\r
324 \r
325     }\r
326     cout << "project path set to " << qPrintable(projectPath) << endl;\r
327   }\r
328   /**********************************************************\r
329    1 : getting scene and creating associated group widgets\r
330   ***********************************************************/\r
331   QDomNodeList scenesNodes = root.elementsByTagName("scene");\r
332 \r
333   int maxIdScene = -1;\r
334   for(int i=0; i<scenesNodes.length(); i++) {\r
335     QDomElement currentSceneNode = scenesNodes.at(i).toElement();\r
336     int idScene = currentSceneNode.attribute("id","none").toInt(&ok);\r
337     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
338     if (idScene > maxIdScene) maxIdScene = idScene;\r
339     int idUpperScene = currentSceneNode.attribute("upper_scene","none").toInt(&ok);\r
340     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
341 \r
342     if (idUpperScene == -1) {\r
343       topGroup = dispatcher->createTopScene(Dispatcher::Load);\r
344       topScene->setId(idScene);\r
345       groupItem = topScene->getGroupItem();      \r
346       cout << "top group added to scene n°" << idScene << endl;\r
347     }\r
348     else {\r
349       cout << "trying to create scene n°" << idScene << " with upper scene n°" <<idUpperScene << endl;\r
350       GroupScene* upperScene = searchSceneById(idUpperScene, topScene);\r
351       /* IMPORTANT: calling addNewEmptyGroup() leads to create a new GroupWidget\r
352        *            AND a BoxItem in upperScene that represents the GroupItem in the\r
353        *            newly created child scene. Thus, it has not to be created when\r
354        *            reading bi_group tags in the following but just searched\r
355        */\r
356       groupWidget = dispatcher->addNewEmptyGroup(Dispatcher::Load, upperScene,false);\r
357       groupWidget->getScene()->setId(idScene);\r
358       groupItem = groupWidget->getScene()->getGroupItem();      \r
359     }\r
360     groupBlock = AB_TO_GRP(groupItem->getRefBlock());\r
361     /**********************************************************\r
362      1.1 : getting the group item of each scene\r
363     ***********************************************************/\r
364     QDomElement groupItemNode = currentSceneNode.firstChildElement("group_item");\r
365     try {\r
366       groupItem->load(groupItemNode);\r
367     }\r
368     catch(Exception err) {\r
369       throw(err);\r
370     }\r
371 \r
372     if (idUpperScene != -1) {\r
373       groupWidget->setWindowTitle(groupBlock->getName());\r
374       groupWidget->show();\r
375       cout << qPrintable(groupItem->getRefBlock()->getName()) << " has upper box item in " << qPrintable(groupItem->getParentItem()->getScene()->getGroupItem()->getRefBlock()->getName()) << endl;\r
376     }    \r
377   }\r
378   dispatcher->setSceneCounter(Dispatcher::Load, maxIdScene+1);\r
379   cout << "groupItems loaded and windows created succefully!" << endl;\r
380 \r
381   /**********************************************************\r
382    2 : getting the functional blocks of each scene\r
383   ***********************************************************/\r
384 \r
385   for(int i=0; i<scenesNodes.length(); i++){\r
386     QDomElement currentSceneNode = scenesNodes.at(i).toElement();\r
387     int idScene = currentSceneNode.attribute("id","none").toInt(&ok);\r
388     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
389     cout << "SCENE : " << idScene << endl;\r
390     GroupScene *currentScene = searchSceneById(idScene,topScene);\r
391 \r
392     if(currentScene == NULL) throw(Exception(PROJECTFILE_CORRUPTED));\r
393     /**********************************************************\r
394      2.1 : getting sources if it is top scene\r
395     ***********************************************************/\r
396     if (currentScene->isTopScene()) {\r
397       QDomNodeList sourceNodes = currentSceneNode.elementsByTagName("source_item");\r
398       cout << "top scene has " << sourceNodes.length() << " sources" << endl;\r
399       for(int j=0; j<sourceNodes.length(); j++) {\r
400         QDomElement currentSBNode = sourceNodes.at(j).toElement();      \r
401         StimuliItem* sourceItem = new StimuliItem(dispatcher,this);\r
402         try {\r
403           sourceItem->load(currentSBNode);\r
404         }\r
405         catch(Exception err) {\r
406           throw(err);\r
407         }\r
408         cout << "source item has been read, add it to the scene" << endl;\r
409         // add the block to the GroupScene\r
410         currentScene->addStimuliItem(sourceItem);\r
411       } \r
412     }\r
413     /**********************************************************\r
414      2.2 : getting functional blocks\r
415     ***********************************************************/\r
416     QDomNodeList functionalBlockNodes = currentSceneNode.elementsByTagName("bi_functional");\r
417 \r
418     for(int j=0; j<functionalBlockNodes.length(); j++) {\r
419       QDomElement currentFBNode = functionalBlockNodes.at(j).toElement();      \r
420       BoxItem* funcItem = new BoxItem(dispatcher,this, currentScene->getGroupItem());\r
421       try {\r
422         funcItem->loadFunctional(currentFBNode);\r
423       }\r
424       catch(Exception err) {\r
425         throw(err);\r
426       }\r
427       // add the block to the GroupScene\r
428       currentScene->addBoxItem(funcItem);\r
429     }\r
430   }\r
431   cout << "functional blocks loaded and created succefully!" << endl;\r
432 \r
433   /**********************************************************\r
434    3 : set the BoxItem that represents a GroupItem in a child scene\r
435   ***********************************************************/\r
436 \r
437   for(int i=0; i<scenesNodes.length(); i++){\r
438     QDomElement currentSceneNode = scenesNodes.at(i).toElement();\r
439     int idScene = currentSceneNode.attribute("id","none").toInt(&ok);\r
440     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
441     GroupScene *currentScene = searchSceneById(idScene, topScene);\r
442     if(currentScene == NULL) throw(Exception(PROJECTFILE_CORRUPTED));\r
443 \r
444     QDomNodeList biGroupNodes = currentSceneNode.elementsByTagName("bi_group");\r
445 \r
446     for(int j=0; j<biGroupNodes.length(); j++){\r
447       QDomElement currentBiGroup = biGroupNodes.at(j).toElement();\r
448 \r
449       int id = currentBiGroup.attribute("id","none").toInt(&ok);\r
450       if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
451 \r
452       int idGroup = currentBiGroup.attribute("inside_group","none").toInt(&ok);\r
453       if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
454 \r
455       QStringList positionStr = currentBiGroup.attribute("position","none").split(",");\r
456       if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));\r
457       int posX = positionStr.at(0).toInt(&ok);\r
458       if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
459       int posY = positionStr.at(1).toInt(&ok);\r
460       if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
461 \r
462       QStringList dimensionStr = currentBiGroup.attribute("dimension","none").split(",");\r
463       if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));\r
464       int dimX = dimensionStr.at(0).toInt(&ok);\r
465       if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
466       int dimY = dimensionStr.at(1).toInt(&ok);\r
467       if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
468 \r
469       // get the GroupItem already created and set at phase 1\r
470       GroupItem *insideGroup = searchGroupItemById(idGroup, topScene);\r
471       BoxItem* upperItem = NULL;\r
472       if(insideGroup == NULL) cout << "group null" << endl;      \r
473       // now search within the scene which BoxItem has a childItem that is = to insideGroup\r
474       QList<BoxItem *> lst = currentScene->getBoxItems();\r
475       foreach(BoxItem* item, lst) {\r
476         if (item->getChildGroupItem() == insideGroup) {\r
477           upperItem = item;\r
478           break;\r
479         }\r
480       }\r
481       if (upperItem == NULL) {\r
482         throw(Exception(PROJECTFILE_CORRUPTED));\r
483       }\r
484 \r
485       upperItem->setId(id);\r
486       upperItem->setPos(posX,posY);\r
487       upperItem->setDimension(dimX,dimY);\r
488 \r
489       // set interfaces of this BoxItem\r
490       QDomNodeList interfaceNodes = currentBiGroup.elementsByTagName("big_iface");\r
491 \r
492       for(int k=0; k<interfaceNodes.length(); k++){\r
493         QDomElement currentInterfaceNode = interfaceNodes.at(k).toElement();\r
494 \r
495         int id = currentInterfaceNode.attribute("id","none").toInt(&ok);\r
496         if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
497 \r
498         QString refName = currentInterfaceNode.attribute("ref_name","none");\r
499         if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
500 \r
501         QString orientationStr = currentInterfaceNode.attribute("orientation","none");\r
502         int orientation = InterfaceItem::getIntOrientation(orientationStr);\r
503         if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));\r
504 \r
505         double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);\r
506         if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
507 \r
508         ConnectedInterface *refInter = insideGroup->searchInterfaceItemByName(refName)->refInter;\r
509         InterfaceItem *ifaceItem = new InterfaceItem(position, orientation, refInter, upperItem, this);\r
510         ifaceItem->setId(id);\r
511         upperItem->addInterfaceItem(ifaceItem);\r
512       }\r
513     }\r
514   }\r
515   cout << "blockItems \"group\" loaded and created succefully!" << endl;\r
516 \r
517   QDomNodeList connectionNodes = root.elementsByTagName("connection");\r
518 \r
519   for(int i=0; i<connectionNodes.length(); i++){\r
520     QDomElement currentConnectionNode = connectionNodes.at(i).toElement();\r
521 \r
522     int from = currentConnectionNode.attribute("from","none").toInt(&ok);\r
523     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
524 \r
525     int to = currentConnectionNode.attribute("to","none").toInt(&ok);\r
526     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
527 \r
528 \r
529     InterfaceItem *iface1 = searchInterfaceItemById(from,topScene);\r
530     InterfaceItem *iface2 = searchInterfaceItemById(to,topScene);\r
531 \r
532     if(iface1 != NULL && iface2 != NULL){\r
533       dispatcher->createConnection(Dispatcher::Load, iface1,iface2);\r
534     } else {\r
535       cout << "interfaces not found, connect canceled!" << endl;\r
536     }\r
537   }\r
538   cout << "connections loaded and created succefully!" << endl;\r
539 \r
540   QDomNodeList modifierNodes = root.elementsByTagName("modifier");\r
541 \r
542   for(int i=0; i<modifierNodes.length(); i++){\r
543     QDomElement currentModifierNode = modifierNodes.at(i).toElement();\r
544 \r
545     int id = currentModifierNode.attribute("id","none").toInt(&ok);\r
546     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
547 \r
548     QString typeStr = currentModifierNode.attribute("type","none");\r
549     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
550     QString paramsStr = currentModifierNode.attribute("params","none");\r
551     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
552 \r
553     /* NB: just adding delays for now. To be cont'd */\r
554     InterfaceItem *iface = searchInterfaceItemById(id,topScene);\r
555 \r
556     if ((iface == NULL ) || (iface->refInter == NULL) || (iface->refInter->getAssociatedIface() == NULL)) {\r
557       cout << "modified interface not found, modifiers setup canceled!" << endl;\r
558     }\r
559     else {\r
560       ConnectedInterface* connIface = AI_TO_CON(iface->refInter->getAssociatedIface());\r
561 \r
562       AbstractInputModifier* mod = NULL;\r
563       if (typeStr == "delay") {\r
564         int delay = paramsStr.toInt(&ok);\r
565         if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
566         mod = new DelayInputModifier(connIface, delay);\r
567         connIface->setInputModifier(mod);\r
568       }\r
569     }\r
570   }\r
571 \r
572   cout << "modifiers loaded and created succefully!" << endl;\r
573 \r
574   return topGroup;\r
575 }\r
576 \r
577 void Parameters::loadBlastConfiguration(QString confFile) throw(Exception) {\r
578 \r
579   try {\r
580     validateXmlFile("blastconfig.xml", "blastconfig.xsd",Configuration);\r
581   }\r
582   catch(Exception err) {\r
583     throw(err);\r
584   }\r
585 \r
586   bool ok;\r
587   // opening configFile\r
588   QFile configFile(confFile);\r
589   // reading in into QDomDocument\r
590   QDomDocument document("configFile");\r
591 \r
592   if (!configFile.open(QIODevice::ReadOnly)) {\r
593     throw(Exception(CONFIGFILE_NOACCESS));\r
594   }\r
595   if (!document.setContent(&configFile)) {\r
596     configFile.close();\r
597     throw(Exception(CONFIGFILE_NOACCESS));\r
598   }\r
599   configFile.close();\r
600 \r
601   //Get the root element\r
602   QDomElement config = document.documentElement();\r
603 \r
604   QDomElement eltCat = config.firstChildElement("categories");\r
605   try {\r
606     categoryTree = new BlockLibraryTree();\r
607     categoryTree->load(eltCat);\r
608   }\r
609   catch(Exception err) {\r
610     throw(err);\r
611   }\r
612 \r
613   QDomElement eltReferences = eltCat.nextSiblingElement("references");\r
614   refLib = eltReferences.attribute("lib_file","none");\r
615   cout << "references lib : " << qPrintable(refLib)  << endl;\r
616   int nbPathes;\r
617   QString nbPathesStr;\r
618   nbPathesStr = eltReferences.attribute("nb","none");\r
619   nbPathes = nbPathesStr.toInt(&ok);\r
620   QDomNodeList listBlockDir = eltReferences.elementsByTagName("reference_lib");\r
621   if ((!ok) || (nbPathes != listBlockDir.size())) throw(Exception(CONFIGFILE_CORRUPTED));\r
622 \r
623   for(int i=0;i<listBlockDir.size();i++) {\r
624     QDomNode nodeBlockDir = listBlockDir.at(i);\r
625     QDomElement eltBlockDir = nodeBlockDir.toElement();\r
626     if (eltBlockDir.isNull()) throw(Exception(CONFIGFILE_CORRUPTED));\r
627     QString path = eltBlockDir.attribute("path","none");\r
628     if (path == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
629     refPathes.append(path);\r
630     cout << "references path : " << qPrintable(path) << endl;\r
631   }\r
632 \r
633   QDomElement eltImpl = eltReferences.nextSiblingElement("implementations");\r
634   implLib = eltImpl.attribute("lib_file","none");\r
635   cout << "implementation lib : " << qPrintable(implLib)  << endl;\r
636   nbPathesStr = eltImpl.attribute("nb","none");\r
637   nbPathes = nbPathesStr.toInt(&ok);\r
638   QDomNodeList listImplDir = eltImpl.elementsByTagName("impl_lib");\r
639   if ((!ok) || (nbPathes != listImplDir.size())) throw(Exception(CONFIGFILE_CORRUPTED));\r
640 \r
641   for(int i=0;i<listImplDir.size();i++) {\r
642     QDomNode nodeImplDir = listImplDir.at(i);\r
643     QDomElement eltImplDir = nodeImplDir.toElement();\r
644     if (eltImplDir.isNull()) throw(Exception(CONFIGFILE_CORRUPTED));\r
645     QString path = eltImplDir.attribute("path","none");\r
646     if (path == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
647     implPathes.append(path);\r
648     cout << "impl path : " << qPrintable(path) << endl << endl;\r
649   }\r
650 \r
651   QDomElement eltSource = eltImpl.nextSiblingElement("sources");\r
652   nbPathesStr = eltSource.attribute("nb","none");\r
653   nbPathes = nbPathesStr.toInt(&ok);\r
654   QDomNodeList listSourceDir = eltSource.elementsByTagName("source_lib");\r
655   if ((!ok) || (nbPathes != listSourceDir.size())) throw(Exception(CONFIGFILE_CORRUPTED));\r
656 \r
657   for(int i=0;i<listSourceDir.size();i++) {\r
658     QDomNode nodeSourceDir = listSourceDir.at(i);\r
659     QDomElement eltSourceDir = nodeSourceDir.toElement();\r
660     if (eltSourceDir.isNull()) throw(Exception(CONFIGFILE_CORRUPTED));\r
661     QString path = eltSourceDir.attribute("path","none");\r
662     if (path == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
663     sourcePathes.append(path);\r
664     cout << "core path : " << qPrintable(path) << endl << endl;\r
665   }\r
666 \r
667   // getting elt = the element <defaults>\r
668   // for each child element, initialize the associated attributes of Parameters\r
669 \r
670   QDomElement eltDefaults = eltSource.nextSiblingElement("defaults");\r
671 \r
672   QDomElement eltBlocks = eltDefaults.firstChildElement("blocks");\r
673   QString attributeStr = eltBlocks.attribute("width", "none");\r
674   defaultBlockWidth = attributeStr.toInt(&ok);\r
675   if (!ok || defaultBlockWidth < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
676   attributeStr = eltBlocks.attribute("height", "none");\r
677   defaultBlockHeight = attributeStr.toInt(&ok);\r
678   if (!ok || defaultBlockHeight < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
679   attributeStr = eltBlocks.attribute("font_size", "none");\r
680   defaultBlockFontSize = attributeStr.toFloat(&ok);\r
681   if (!ok || defaultBlockFontSize < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
682   attributeStr = eltBlocks.attribute("font", "none");\r
683   if (attributeStr == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
684   defaultBlockFontName = attributeStr;\r
685   defaultBlockFont = QFont(defaultBlockFontName, defaultBlockFontSize);\r
686 \r
687   QDomElement eltInterfaces = eltBlocks.nextSiblingElement("interfaces");\r
688   attributeStr = eltInterfaces.attribute("width", "none");\r
689   arrowWidth = attributeStr.toInt(&ok);\r
690   if (!ok || arrowWidth < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
691   attributeStr = eltInterfaces.attribute("height", "none");\r
692   arrowHeight = attributeStr.toInt(&ok);\r
693   if (!ok || arrowHeight < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
694   attributeStr = eltInterfaces.attribute("linelength", "none");\r
695   arrowLineLength = attributeStr.toInt(&ok);\r
696   if (!ok || arrowLineLength < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
697   attributeStr = eltInterfaces.attribute("font_size", "none");\r
698   defaultIfaceFontSize = attributeStr.toFloat(&ok);\r
699   if (!ok || defaultIfaceFontSize < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
700   attributeStr = eltInterfaces.attribute("font", "none");\r
701   if (attributeStr == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
702   defaultIfaceFontName = attributeStr;\r
703   defaultIfaceFont = QFont(defaultIfaceFontName, defaultIfaceFontSize);\r
704 \r
705   QDomElement eltConnections = eltInterfaces.nextSiblingElement("connections");\r
706   attributeStr = eltConnections.attribute("gaplength", "none");\r
707   connGapLength = attributeStr.toInt(&ok);\r
708   if (!ok || connGapLength < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
709 }\r
710 \r
711 void Parameters::loadReferencesFromXml() throw(Exception) {\r
712   cout << "load references from xml" << endl;\r
713   for(int i=0;i<refPathes.size();i++) {\r
714     cout << "analyzing " << qPrintable(refPathes.at(i)) << endl;\r
715     QDir dir(refPathes.at(i));\r
716     QStringList filter;\r
717     filter << "*.xml";\r
718     dir.setNameFilters(filter);\r
719     QStringList list = dir.entryList();\r
720     for(int j=0;j<list.size();j++) {\r
721       QString fileName = dir.absolutePath();\r
722       fileName.append("/"+list.at(j));\r
723 \r
724       QFile blockXML(fileName);\r
725       if (!blockXML.open(QIODevice::ReadOnly)) {\r
726         throw(Exception(BLOCKFILE_NOACCESS));\r
727       }\r
728       QTextStream in(&blockXML);\r
729       QString line = in.readLine();\r
730       line = in.readLine();\r
731 \r
732       if (!line.contains("<block")) {\r
733         blockXML.close();\r
734         continue;\r
735       }\r
736 \r
737       blockXML.close();\r
738       try {\r
739         validateXmlFile(fileName,"reference.xsd",Reference);\r
740       }\r
741       catch(Exception err) {\r
742         throw(err);\r
743       }\r
744 \r
745       // reading in into QDomDocument\r
746       QDomDocument document ("FileXML");\r
747       if (!blockXML.open(QIODevice::ReadOnly)) {\r
748         throw(Exception(BLOCKFILE_NOACCESS));\r
749       }\r
750       if (!document.setContent(&blockXML)) {\r
751         blockXML.close();\r
752         throw(Exception(BLOCKFILE_NOACCESS));\r
753       }\r
754       blockXML.close();\r
755 \r
756       QDomElement blockRoot = document.documentElement();\r
757       QString name = blockRoot.tagName();\r
758       if (name == "block") {\r
759 \r
760         cout << "xml:" << fileName.toStdString() << endl;\r
761         ReferenceBlock* b = new ReferenceBlock(fileName);\r
762         try {\r
763           b->load(blockRoot);\r
764           b->setHashMd5();\r
765         }\r
766         catch(int err) {\r
767           throw(err);\r
768         }\r
769         cout << "xml:" << b->getXmlFile().toStdString() << endl;\r
770 \r
771         availableBlocks.append(b);\r
772         foreach (int id,b->getCategories()) {\r
773           cout << "ajout du bloc dans cat n° : " << id << endl;\r
774           BlockCategory* cat = categoryTree->searchCategory(id);\r
775           cat->blocks.append(b);\r
776         }\r
777       }\r
778     }\r
779   }\r
780 }\r
781 \r
782 void Parameters::loadReferencesFromLib() throw(Exception) {\r
783 \r
784   cout << "loading references from lib" << endl;\r
785 \r
786   // removing blocks from category tree if they exist\r
787   categoryTree->clearBlocks();\r
788   // deleting existings blocks\r
789   ReferenceBlock* b = NULL;\r
790   for(int i=0;i<availableBlocks.size();i++) {\r
791     b = availableBlocks.at(i);\r
792     delete b;\r
793   }\r
794   availableBlocks.clear();\r
795 \r
796   QFile libFile(refLib);\r
797   if (!libFile.open(QIODevice::ReadOnly)) {\r
798     throw(Exception(BLOCKFILE_NOACCESS));\r
799   }\r
800   QDataStream in(&libFile);\r
801   quint32 size;\r
802 \r
803   in >> size;\r
804 \r
805   int nbBlocks;\r
806   in >> nbBlocks;\r
807   for(int i=0;i<nbBlocks;i++) {\r
808     b = new ReferenceBlock("");\r
809     in >> *b;\r
810     availableBlocks.append(b);\r
811     foreach (int id,b->getCategories()) {\r
812       BlockCategory* cat = categoryTree->searchCategory(id);\r
813       cat->blocks.append(b);\r
814     }\r
815   }\r
816   libFile.close();\r
817 }\r
818 \r
819 void Parameters::saveReferencesToLib() throw(Exception) {\r
820 \r
821   cout << "saving blocks in " << qPrintable(refLib) << endl;\r
822   QFile libFile(refLib);\r
823   if (!libFile.open(QIODevice::WriteOnly)) {\r
824     throw(Exception(BLOCKFILE_NOACCESS));\r
825   }\r
826   QDataStream out(&libFile);\r
827 \r
828   out.setVersion(QDataStream::Qt_5_0);\r
829 \r
830   QByteArray blockData;\r
831   QDataStream toWrite(&blockData, QIODevice::WriteOnly);\r
832 \r
833   toWrite << availableBlocks.size();\r
834   for(int i=0;i<availableBlocks.size();i++) {\r
835     ReferenceBlock* b = availableBlocks.at(i);\r
836     toWrite << *b;\r
837   }\r
838 \r
839   out << blockData;\r
840 \r
841   libFile.close();\r
842 \r
843 }\r
844 \r
845 void Parameters::loadImplementationsFromXml() throw(Exception) {\r
846 \r
847   for(int i=0;i<implPathes.size();i++) {\r
848     cout << "analyzing " << qPrintable(implPathes.at(i)) << endl;\r
849     QDir dir(implPathes.at(i));\r
850     QStringList filter;\r
851     filter << "*.xml";\r
852     dir.setNameFilters(filter);\r
853     QStringList list = dir.entryList();\r
854     for(int j=0;j<list.size();j++) {\r
855       QString fileName = dir.absolutePath();\r
856       fileName.append("/"+list.at(j));\r
857 \r
858       cout << "checking " << qPrintable(fileName) << " is an implementation file ...";\r
859       QFile implXML(fileName);\r
860       if (!implXML.open(QIODevice::ReadOnly)) {\r
861         throw(Exception(IMPLFILE_NOACCESS));\r
862       }\r
863       QTextStream in(&implXML);\r
864       QString line = in.readLine();\r
865       line = in.readLine();\r
866 \r
867       if (!line.contains("<block_impl")) {\r
868         implXML.close();\r
869         continue;\r
870       }\r
871 \r
872       implXML.close();\r
873       cout << "OK" << endl;\r
874       cout << "reading " << qPrintable(fileName) << " content ...";\r
875 \r
876       try {\r
877         validateXmlFile(fileName,"implementation.xsd",Implementation);\r
878       }\r
879       catch(Exception e) {\r
880         throw(e);\r
881       }\r
882 \r
883       // reading in into QDomDocument\r
884       QDomDocument document ("FileXML");\r
885       if (!implXML.open(QIODevice::ReadOnly)) {\r
886         throw(Exception(IMPLFILE_NOACCESS));\r
887       }\r
888       cout << "OK" << endl;\r
889       cout << "convert " << qPrintable(fileName) << " content into document...";\r
890       if (!document.setContent(&implXML)) {\r
891         implXML.close();\r
892         throw(Exception(IMPLFILE_NOACCESS));\r
893       }\r
894       implXML.close();\r
895 \r
896       QDomElement implRoot = document.documentElement();\r
897       QString refXml = implRoot.attribute("ref_name","none");\r
898       QString refMd5 = implRoot.attribute("ref_md5","none");\r
899       BlockImplementation* impl = new BlockImplementation(fileName,refXml,refMd5);\r
900 \r
901       QDomNodeList archNode = implRoot.elementsByTagName("architecture");\r
902 \r
903       if (archNode.isEmpty()) {\r
904         cout << "impl has no architecture" << endl;\r
905         return;\r
906       }\r
907       QDomElement archElt = archNode.at(0).toElement();\r
908       QString compList = archElt.attribute("comp_list","none");\r
909       if (compList != "none") {\r
910         QStringList compos = compList.split(",");\r
911         foreach(QString s, compos) {\r
912           impl->addResource(s);\r
913         }\r
914       }\r
915 \r
916       try {\r
917         impl->loadPatterns(implRoot);\r
918       }\r
919       catch(int err) {\r
920         throw(err);\r
921       }\r
922       availableImplementations.append(impl);\r
923 \r
924       ReferenceBlock* ref = NULL;\r
925       if (! refMd5.isEmpty()) {\r
926         ref = searchBlockByMd5(refMd5);\r
927       }\r
928       if (ref == NULL) {\r
929         ref = searchBlockByXml(refXml);\r
930       }\r
931       if (ref == NULL) {\r
932         cout << "Cannot find a reference block for impl :" << qPrintable(fileName) << endl;\r
933       }      \r
934       else {          \r
935         ref->addImplementation(impl);\r
936         impl->setReference(ref);\r
937         if (! impl->checkPatterns()) throw(Exception(IMPLFILE_CORRUPTED));\r
938       }      \r
939       cout << "OK" << endl;\r
940     }\r
941   }\r
942 }\r
943 \r
944 void Parameters::loadImplementationsFromLib() throw(Exception) {\r
945 \r
946   cout << "loading implementations from lib" << endl;\r
947 \r
948   BlockImplementation* impl = NULL;\r
949   ReferenceBlock* ref = NULL;\r
950   for(int i=0;i<availableImplementations.size();i++) {\r
951     impl = availableImplementations.at(i);\r
952     delete impl;\r
953   }\r
954   availableImplementations.clear();\r
955 \r
956   QFile libFile(implLib);\r
957   if (!libFile.open(QIODevice::ReadOnly)) {\r
958     throw(Exception(IMPLFILE_NOACCESS));\r
959   }\r
960   QDataStream in(&libFile);\r
961   quint32 size;\r
962 \r
963   in >> size;\r
964 \r
965   int nbImpls;\r
966   in >> nbImpls;\r
967   for(int i=0;i<nbImpls;i++) {\r
968     impl = new BlockImplementation("");\r
969     in >> *impl;\r
970     availableImplementations.append(impl);\r
971     QString refMd5 = impl->getReferenceMd5();\r
972     QString refXml = impl->getReferenceXml();\r
973     ref = NULL;\r
974     if (! refMd5.isEmpty()) {\r
975       ref = searchBlockByMd5(refMd5);\r
976     }\r
977     if (ref == NULL) {\r
978       ref = searchBlockByXml(refXml);\r
979     }\r
980     if (ref == NULL) {\r
981       cout << "Cannot find a reference block for impl :" << qPrintable(impl->getXmlFile()) << endl;\r
982     }\r
983     else {          \r
984       ref->addImplementation(impl);\r
985       impl->setReference(ref);\r
986       if (! impl->checkPatterns()) throw(Exception(IMPLFILE_CORRUPTED));\r
987     }\r
988   }\r
989   libFile.close();\r
990 }\r
991 \r
992 void Parameters::saveImplementationsToLib() throw(Exception) {\r
993 \r
994   cout << "saving implementations in " << qPrintable(implLib) << endl;\r
995   QFile libFile(implLib);\r
996   if (!libFile.open(QIODevice::WriteOnly)) {\r
997     throw(Exception(IMPLFILE_NOACCESS));\r
998   }\r
999   QDataStream out(&libFile);\r
1000 \r
1001   out.setVersion(QDataStream::Qt_5_0);\r
1002 \r
1003   QByteArray blockData;\r
1004   QDataStream toWrite(&blockData, QIODevice::WriteOnly);\r
1005 \r
1006   toWrite << availableImplementations.size();\r
1007   for(int i=0;i<availableImplementations.size();i++) {\r
1008     BlockImplementation* impl = availableImplementations.at(i);\r
1009     toWrite << *impl;\r
1010   }\r
1011 \r
1012   out << blockData;\r
1013 \r
1014   libFile.close();\r
1015 \r
1016 }\r
1017 \r
1018 \r
1019 void Parameters::loadSources() throw(Exception) {\r
1020 \r
1021   for(int i=0;i<sourcePathes.size();i++) {\r
1022     cout << "analyzing " << qPrintable(sourcePathes.at(i)) << endl;\r
1023     QDir dir(sourcePathes.at(i));\r
1024     QStringList filter;\r
1025     filter << "*.vhd" << "*.ngc";\r
1026     dir.setNameFilters(filter);\r
1027     QStringList list = dir.entryList();\r
1028     for(int j=0;j<list.size();j++) {\r
1029       QString fileName = dir.absolutePath();\r
1030       fileName.append("/"+list.at(j));\r
1031 \r
1032       if (list.at(j).endsWith(".ngc")) {\r
1033         QString netName = list.at(j);\r
1034         netName.truncate(list.at(j).size() -4);\r
1035         cout << "found netlist " << qPrintable(netName) << endl;\r
1036         availableResources.append(new ExternalResource(netName,fileName,ExternalResource::Netlist));\r
1037       }\r
1038       else {\r
1039         cout << "parsing " << qPrintable(fileName) << " ... ";\r
1040         QFile srcXML(fileName);\r
1041         if (!srcXML.open(QIODevice::ReadOnly)) {\r
1042           throw(Exception(IMPLFILE_NOACCESS));\r
1043         }\r
1044         QTextStream in(&srcXML);\r
1045 \r
1046         QString line = in.readLine();\r
1047         while (!line.isNull()) {\r
1048           if (line.contains("package", Qt::CaseInsensitive)) {\r
1049             QRegularExpression rxPack("^package (.+) is$",QRegularExpression::CaseInsensitiveOption);\r
1050             QRegularExpressionMatch matchPack = rxPack.match(line);\r
1051             if (matchPack.hasMatch()) {\r
1052               QString packName = matchPack.captured(1);\r
1053               cout << "found package " << qPrintable(packName) << endl;\r
1054               availableResources.append(new ExternalResource(packName,fileName,ExternalResource::Package));\r
1055             }\r
1056           }\r
1057           else if (line.contains("entity", Qt::CaseInsensitive)) {\r
1058             QRegularExpression rxEnt("^entity (.+) is$",QRegularExpression::CaseInsensitiveOption);\r
1059             QRegularExpressionMatch matchEnt = rxEnt.match(line);\r
1060             if (matchEnt.hasMatch()) {\r
1061               QString entityName = matchEnt.captured(1);\r
1062               cout << "found entity " << qPrintable(entityName) << endl;\r
1063               availableResources.append(new ExternalResource(entityName,fileName,ExternalResource::Code));\r
1064             }\r
1065           }\r
1066           line = in.readLine();\r
1067         }\r
1068         srcXML.close();\r
1069         cout << "OK" << endl;\r
1070       }\r
1071     }\r
1072   }\r
1073 }\r
1074 \r
1075 QList<ExternalResource *> Parameters::searchResourceByName(const QString& name) {\r
1076   QList<ExternalResource*> listRes;\r
1077   foreach(ExternalResource* s, availableResources) {\r
1078     if (s->getName() == name) {\r
1079       listRes.append(s);\r
1080     }\r
1081   }\r
1082   return listRes;\r
1083 }\r
1084 \r
1085 void Parameters::addAvailableBlock(ReferenceBlock *block) {\r
1086   availableBlocks.append(block);\r
1087   foreach (int id,block->getCategories()) {\r
1088     cout << "ajout du bloc dans cat n° : " << id << endl;\r
1089     BlockCategory* cat = categoryTree->searchCategory(id);\r
1090     cat->blocks.append(block);\r
1091   }\r
1092 }\r
1093 \r
1094 void Parameters::parametersValidation() {\r
1095   QList<AbstractBlock*> blocksToConfigure = getBlocksToConfigure();\r
1096 \r
1097   if(!blocksToConfigure.isEmpty()){\r
1098     BlocksToConfigureWidget *widget = new BlocksToConfigureWidget(blocksToConfigure, this, NULL);\r
1099     widget->show();\r
1100   }\r
1101 }\r
1102 \r
1103 void Parameters::connectionsValidation() {\r
1104 \r
1105 #ifdef DEBUG_INCLFUN\r
1106 \r
1107   QStack<AbstractInterface*> *interfaceToValidate = new QStack<AbstractInterface*>;\r
1108   QList<AbstractInterface*> *validatedInterface = new QList<AbstractInterface*>;\r
1109 \r
1110   foreach(AbstractInterface *inter, topWindow->getScene()->getGroupItem()->getRefBlock()->getInterfaces()){\r
1111     foreach(AbstractInterface *connectedInter, inter->getConnectedTo()){\r
1112 \r
1113       inter->setWidth(connectedInter->getWidth());\r
1114       interfaceToValidate->push(connectedInter);\r
1115     }\r
1116   }\r
1117 \r
1118 \r
1119   try{\r
1120     while(!interfaceToValidate->isEmpty()){\r
1121       interfaceToValidate->pop()->connectionsValidation(interfaceToValidate, validatedInterface);\r
1122     }\r
1123   }\r
1124   catch(Exception e){\r
1125     cerr << e.getMessage().toStdString() << endl;\r
1126   }\r
1127 #endif\r
1128 }\r
1129 \r
1130 QList<AbstractBlock *> Parameters::getBlocksToConfigure() {\r
1131 \r
1132 #ifdef DEBUG_INCLFUN\r
1133 \r
1134   QList<AbstractBlock*> *checkedBlocks = new QList<AbstractBlock*>;\r
1135   QList<AbstractBlock*> *blocksToConfigure = new QList<AbstractBlock*>;\r
1136 \r
1137   foreach(AbstractInterface *inter, topWindow->getScene()->getGroupItem()->getRefBlock()->getInterfaces()){\r
1138     foreach(AbstractInterface *connectedInter, inter->getConnectedTo()){\r
1139       if(!checkedBlocks->contains(connectedInter->getOwner())){\r
1140         connectedInter->getOwner()->parametersValidation(checkedBlocks, blocksToConfigure);\r
1141       }\r
1142     }\r
1143   }\r
1144   return *blocksToConfigure;\r
1145 #endif\r
1146 }\r
1147 \r
1148 \r
1149 void Parameters::updateToolbar() {\r
1150   int nb = currentScene->getBoxItems().length();\r
1151   for(int i = 0; i<nb; i++){\r
1152     if(currentScene->getBoxItems().at(i)->isSelected()){\r
1153       currentScene->getGroupWidget()->enableGroupButton(true);\r
1154       return;\r
1155     }\r
1156   }\r
1157   currentScene->getGroupWidget()->enableGroupButton(false);\r
1158 }\r
1159 \r
1160 \r
1161 void Parameters::updateIds() {\r
1162 \r
1163   /* a in-width cross of the graph must be done so that ids of GroupItem\r
1164      are in the correct ordre when saving/loading a project\r
1165    */\r
1166   int countItem = 1;\r
1167   int countIface = 1;\r
1168   QList<GroupScene *> fifo;\r
1169   fifo.append(topScene);\r
1170   while (!fifo.isEmpty()) {\r
1171     GroupScene* scene = fifo.takeFirst();\r
1172     countItem = scene->setItemsId(countItem);\r
1173     countIface = scene->setInterfacesId(countIface);\r
1174     foreach(GroupScene* s, scene->getChildrenScene()) {\r
1175       fifo.append(s);\r
1176     }\r
1177   }\r
1178 }\r
1179 \r
1180 \r
1181 ReferenceBlock *Parameters::searchBlockByXml(QString xmlName) {\r
1182   foreach(ReferenceBlock *block, availableBlocks){\r
1183     if(block->getXmlFile().contains(xmlName))\r
1184       return block;\r
1185   }\r
1186   return NULL;\r
1187 }\r
1188 \r
1189 ReferenceBlock *Parameters::searchBlockByMd5(QString sumMd5) {\r
1190   foreach(ReferenceBlock *block, availableBlocks){\r
1191     if(block->getHashMd5() == sumMd5)\r
1192       return block;\r
1193   }\r
1194   return NULL;\r
1195 }\r
1196 \r
1197 void Parameters::save(QString confFile) {\r
1198 \r
1199 //#ifdef DEBUG_INCLFUN\r
1200 \r
1201   updateIds();\r
1202   QList<ConnectionItem*> allConnections;\r
1203   QFile file(confFile);\r
1204   if(file.open(QIODevice::WriteOnly)){\r
1205 \r
1206     QXmlStreamWriter writer(&file);\r
1207 \r
1208     writer.setAutoFormatting(true);\r
1209     writer.writeStartDocument();\r
1210 \r
1211     writer.writeStartElement("blast_project");\r
1212     writer.writeStartElement("scenes");\r
1213 \r
1214     writer.writeAttribute("count",QString::number(dispatcher->getNumberOfScenes()));\r
1215 \r
1216     // cross the scene level by level using a FIFO\r
1217     QList<GroupScene*> fifoScene;\r
1218     fifoScene.append(topScene);\r
1219 \r
1220     GroupScene *scene;\r
1221     while (!fifoScene.isEmpty()) {\r
1222       scene = fifoScene.takeFirst();\r
1223       scene->save(writer);\r
1224       foreach(GroupScene* s, scene->getChildrenScene()) {\r
1225         fifoScene.append(s);\r
1226       }\r
1227 \r
1228       foreach(ConnectionItem* item, scene->getConnectionItems()) {\r
1229         allConnections.append(item);\r
1230       }\r
1231     }\r
1232     writer.writeEndElement();    //</scenes>\r
1233 \r
1234     writer.writeStartElement("connections");\r
1235     foreach(ConnectionItem* item, allConnections) {\r
1236 \r
1237       writer.writeStartElement("connection");\r
1238 \r
1239       writer.writeAttribute("from",QString::number(item->getFromInterfaceItem()->getId()));\r
1240       writer.writeAttribute("to", QString::number(item->getToInterfaceItem()->getId()));\r
1241 \r
1242       writer.writeEndElement();\r
1243     }\r
1244 \r
1245     writer.writeEndElement();    //</connections>\r
1246 \r
1247     QList<InterfaceItem *> lstIfaceItem;\r
1248     // search for modifiers\r
1249     foreach(ConnectionItem* item, allConnections) {\r
1250       InterfaceItem* fromIfaceItem = item->getFromInterfaceItem();\r
1251       AbstractInputModifier* mod = fromIfaceItem->refInter->getInputModifier();\r
1252       if (mod != NULL) {\r
1253         if (!lstIfaceItem.contains(fromIfaceItem)) lstIfaceItem.append(fromIfaceItem);\r
1254       }\r
1255       InterfaceItem* toIfaceItem = item->getToInterfaceItem();\r
1256       mod = toIfaceItem->refInter->getInputModifier();\r
1257       if (mod != NULL) {\r
1258         if (!lstIfaceItem.contains(toIfaceItem)) lstIfaceItem.append(toIfaceItem);\r
1259       }\r
1260     }\r
1261     // write input modifiers\r
1262     writer.writeStartElement("modifiers");\r
1263     foreach(InterfaceItem* item, lstIfaceItem) {\r
1264       AbstractInputModifier* mod = item->refInter->getInputModifier();\r
1265       if (mod != NULL) {\r
1266         writer.writeStartElement("modifier");\r
1267         writer.writeAttribute("id", QString::number(item->getId()));\r
1268         writer.writeAttribute("type",mod->getTypeStr());\r
1269         writer.writeAttribute("params", mod->getParametersStr());\r
1270         writer.writeEndElement();\r
1271       }\r
1272     }\r
1273 \r
1274     writer.writeEndElement();    //</modifiers>\r
1275     writer.writeEndElement();      //</blast_project\r
1276 \r
1277     writer.writeEndDocument();\r
1278 \r
1279     file.close();\r
1280     unsaveModif = false;\r
1281   }\r
1282 //#endif\r
1283 }\r
1284 \r
1285 void Parameters::setArrowPathes() {\r
1286   QPainterPath _inArrow;\r
1287   _inArrow.lineTo(arrowLineLength,0);\r
1288   _inArrow.lineTo(arrowLineLength+arrowWidth,-arrowHeight/2);\r
1289   _inArrow.lineTo(arrowLineLength+arrowWidth,arrowHeight/2);\r
1290   _inArrow.lineTo(arrowLineLength,0);\r
1291   //_inArrow.closeSubpath();\r
1292   dataArrowIn = _inArrow;\r
1293 \r
1294   QPainterPath _inArrowC;\r
1295   _inArrowC.lineTo(arrowLineLength,0);\r
1296   _inArrowC.addEllipse(arrowLineLength,-arrowHeight/2,arrowHeight-1,arrowHeight-1);\r
1297   clkrstArrow = _inArrowC;\r
1298 \r
1299   QPainterPath _outArrow;\r
1300   _outArrow.lineTo(arrowLineLength,0);\r
1301   _outArrow.lineTo(arrowLineLength,-arrowHeight/2);\r
1302   _outArrow.lineTo(arrowLineLength+arrowWidth,0);\r
1303   _outArrow.lineTo(arrowLineLength,arrowHeight/2);\r
1304   _outArrow.lineTo(arrowLineLength,0);\r
1305   //_outArrow.closeSubpath();\r
1306   dataArrowOut = _outArrow;\r
1307 \r
1308 }\r
1309 \r
1310 GroupScene* Parameters::searchSceneById(int id, GroupScene *scene) {\r
1311 \r
1312   if (scene->getId() == id) return scene;\r
1313   GroupScene* sc = NULL;\r
1314 \r
1315   foreach(GroupScene *s, scene->getChildrenScene()) {\r
1316     sc = searchSceneById(id,s);\r
1317     if (sc != NULL) return sc;\r
1318   }\r
1319   return NULL;\r
1320 }\r
1321 \r
1322 GroupItem* Parameters::searchGroupItemById(int id, GroupScene *scene) {\r
1323 \r
1324   if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();\r
1325 \r
1326   GroupItem* item = NULL;\r
1327   foreach(GroupScene *s, scene->getChildrenScene()) {\r
1328     item = searchGroupItemById(id,s);\r
1329     if (item != NULL) return item;\r
1330   }\r
1331   return NULL;\r
1332 }\r
1333 \r
1334 BoxItem* Parameters::searchBlockItemById(int id, GroupScene *scene) {\r
1335 \r
1336   foreach(BoxItem *item, scene->getBoxItems()){\r
1337     if(item->getId() == id){\r
1338       return item;\r
1339     }\r
1340   }\r
1341 \r
1342   BoxItem* item = NULL;\r
1343   foreach(GroupScene *s, scene->getChildrenScene()) {\r
1344     item = searchBlockItemById(id,s);\r
1345     if (item != NULL) return item;\r
1346   }\r
1347   return NULL;\r
1348 }\r
1349 \r
1350 BoxItem* Parameters::searchFunctionalBlock(AbstractBlock* block) {\r
1351 \r
1352   return searchFunctionalBlockRecur(block,topScene);\r
1353 }\r
1354 \r
1355 BoxItem* Parameters::searchFunctionalBlockRecur(AbstractBlock* block, GroupScene* scene) {\r
1356 \r
1357   foreach(BoxItem *item, scene->getBoxItems()){\r
1358     if(item->getRefBlock() == block) {\r
1359       return item;\r
1360     }\r
1361   }\r
1362 \r
1363   BoxItem* item = NULL;\r
1364   foreach(GroupScene *s, scene->getChildrenScene()) {\r
1365     item = searchFunctionalBlockRecur(block,s);\r
1366     if (item != NULL) return item;\r
1367   }\r
1368   return NULL;\r
1369 }\r
1370 \r
1371 InterfaceItem* Parameters::searchInterfaceItemById(int id, GroupScene* scene) {\r
1372 \r
1373   foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){\r
1374     if(item->getId() == id){\r
1375       return item;\r
1376     }\r
1377   }\r
1378   if (scene->isTopScene()) {\r
1379     foreach(StimuliItem *block, scene->getSourceItems()){\r
1380       foreach(InterfaceItem *item, block->getInterfaces()){\r
1381         if(item->getId() == id){\r
1382           return item;\r
1383         }\r
1384       }\r
1385     } \r
1386   }\r
1387   foreach(BoxItem *block, scene->getBoxItems()){\r
1388     foreach(InterfaceItem *item, block->getInterfaces()){\r
1389       if(item->getId() == id){\r
1390         return item;\r
1391       }\r
1392     }\r
1393   }\r
1394   InterfaceItem* item = NULL;\r
1395   foreach(GroupScene *s, scene->getChildrenScene()) {\r
1396     item = searchInterfaceItemById(id,s);\r
1397     if (item != NULL) return item;\r
1398   }\r
1399   return NULL;\r
1400 }\r
1401 \r
1402 QString Parameters::normalizeName(const QString &name) {\r
1403   QString s = name;\r
1404   s.replace(QRegularExpression("[^a-zA-Z0-9_]"),"_");\r
1405   s.replace(QRegularExpression("[_]+"),"_");\r
1406   return s;\r
1407 }\r