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

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