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

Private GIT Repository
c903f5d94be772d400ded37c64e1de0519b211b7
[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";\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       cout << "parsing " << qPrintable(fileName) << " ... ";\r
960       QFile srcXML(fileName);\r
961       if (!srcXML.open(QIODevice::ReadOnly)) {\r
962         throw(Exception(IMPLFILE_NOACCESS));\r
963       }\r
964       QTextStream in(&srcXML);\r
965 \r
966       QString line = in.readLine();\r
967       while (!line.isNull()) {\r
968         if (line.contains("package", Qt::CaseInsensitive)) {\r
969           QRegularExpression rxPack("^package (.+) is$",QRegularExpression::CaseInsensitiveOption);\r
970           QRegularExpressionMatch matchPack = rxPack.match(line);\r
971           if (matchPack.hasMatch()) {\r
972             QString packName = matchPack.captured(1);\r
973             cout << "found package " << qPrintable(packName) << endl;\r
974             availableSources.append(new ExternalSource(packName,fileName,ExternalSource::Package));\r
975           }\r
976         }\r
977         else if (line.contains("entity", Qt::CaseInsensitive)) {\r
978           QRegularExpression rxEnt("^entity (.+) is$",QRegularExpression::CaseInsensitiveOption);\r
979           QRegularExpressionMatch matchEnt = rxEnt.match(line);\r
980           if (matchEnt.hasMatch()) {\r
981             QString entityName = matchEnt.captured(1);\r
982             cout << "found entity " << qPrintable(entityName) << endl;\r
983             availableSources.append(new ExternalSource(entityName,fileName,ExternalSource::Code));\r
984           }\r
985         }\r
986         line = in.readLine();\r
987       }\r
988       srcXML.close();\r
989       cout << "OK" << endl;\r
990 \r
991     }\r
992   }\r
993 }\r
994 \r
995 ExternalSource* Parameters::searchSourceByName(const QString& name) {\r
996   foreach(ExternalSource* s, availableSources) {\r
997     if (s->getName() == name) return s;\r
998   }\r
999   return NULL;\r
1000 }\r
1001 \r
1002 void Parameters::addAvailableBlock(ReferenceBlock *block) {\r
1003   availableBlocks.append(block);\r
1004   foreach (int id,block->getCategories()) {\r
1005     cout << "ajout du bloc dans cat n° : " << id << endl;\r
1006     BlockCategory* cat = categoryTree->searchCategory(id);\r
1007     cat->blocks.append(block);\r
1008   }\r
1009 }\r
1010 \r
1011 void Parameters::parametersValidation() {\r
1012   QList<AbstractBlock*> blocksToConfigure = getBlocksToConfigure();\r
1013 \r
1014   if(!blocksToConfigure.isEmpty()){\r
1015     BlocksToConfigureWidget *widget = new BlocksToConfigureWidget(blocksToConfigure, this, NULL);\r
1016     widget->show();\r
1017   }\r
1018 }\r
1019 \r
1020 void Parameters::connectionsValidation() {\r
1021 \r
1022 #ifdef DEBUG_INCLFUN\r
1023 \r
1024   QStack<AbstractInterface*> *interfaceToValidate = new QStack<AbstractInterface*>;\r
1025   QList<AbstractInterface*> *validatedInterface = new QList<AbstractInterface*>;\r
1026 \r
1027   foreach(AbstractInterface *inter, topWindow->getScene()->getGroupItem()->getRefBlock()->getInterfaces()){\r
1028     foreach(AbstractInterface *connectedInter, inter->getConnectedTo()){\r
1029 \r
1030       inter->setWidth(connectedInter->getWidth());\r
1031       interfaceToValidate->push(connectedInter);\r
1032     }\r
1033   }\r
1034 \r
1035 \r
1036   try{\r
1037     while(!interfaceToValidate->isEmpty()){\r
1038       interfaceToValidate->pop()->connectionsValidation(interfaceToValidate, validatedInterface);\r
1039     }\r
1040   }\r
1041   catch(Exception e){\r
1042     cerr << e.getMessage().toStdString() << endl;\r
1043   }\r
1044 #endif\r
1045 }\r
1046 \r
1047 QList<AbstractBlock *> Parameters::getBlocksToConfigure() {\r
1048 \r
1049 #ifdef DEBUG_INCLFUN\r
1050 \r
1051   QList<AbstractBlock*> *checkedBlocks = new QList<AbstractBlock*>;\r
1052   QList<AbstractBlock*> *blocksToConfigure = new QList<AbstractBlock*>;\r
1053 \r
1054   foreach(AbstractInterface *inter, topWindow->getScene()->getGroupItem()->getRefBlock()->getInterfaces()){\r
1055     foreach(AbstractInterface *connectedInter, inter->getConnectedTo()){\r
1056       if(!checkedBlocks->contains(connectedInter->getOwner())){\r
1057         connectedInter->getOwner()->parametersValidation(checkedBlocks, blocksToConfigure);\r
1058       }\r
1059     }\r
1060   }\r
1061   return *blocksToConfigure;\r
1062 #endif\r
1063 }\r
1064 \r
1065 \r
1066 void Parameters::updateToolbar() {\r
1067   int nb = currentScene->getBoxItems().length();\r
1068   for(int i = 0; i<nb; i++){\r
1069     if(currentScene->getBoxItems().at(i)->isSelected()){\r
1070       currentScene->getGroupWidget()->enableGroupButton(true);\r
1071       return;\r
1072     }\r
1073   }\r
1074   currentScene->getGroupWidget()->enableGroupButton(false);\r
1075 }\r
1076 \r
1077 \r
1078 void Parameters::updateIds() {\r
1079 \r
1080   /* a in-width cross of the graph must be done so that ids of GroupItem\r
1081      are in the correct ordre when saving/loading a project\r
1082    */\r
1083   int countItem = 1;\r
1084   int countIface = 1;\r
1085   QList<GroupScene *> fifo;\r
1086   fifo.append(topScene);\r
1087   while (!fifo.isEmpty()) {\r
1088     GroupScene* scene = fifo.takeFirst();\r
1089     countItem = scene->setItemsId(countItem);\r
1090     countIface = scene->setInterfacesId(countIface);\r
1091     foreach(GroupScene* s, scene->getChildrenScene()) {\r
1092       fifo.append(s);\r
1093     }\r
1094   }\r
1095 }\r
1096 \r
1097 \r
1098 ReferenceBlock *Parameters::searchBlockByXml(QString xmlName) {\r
1099   foreach(ReferenceBlock *block, availableBlocks){\r
1100     if(block->getXmlFile().contains(xmlName))\r
1101       return block;\r
1102   }\r
1103   return NULL;\r
1104 }\r
1105 \r
1106 ReferenceBlock *Parameters::searchBlockByMd5(QString sumMd5) {\r
1107   foreach(ReferenceBlock *block, availableBlocks){\r
1108     if(block->getHashMd5() == sumMd5)\r
1109       return block;\r
1110   }\r
1111   return NULL;\r
1112 }\r
1113 \r
1114 void Parameters::save(QString confFile) {\r
1115 \r
1116 //#ifdef DEBUG_INCLFUN\r
1117 \r
1118   updateIds();\r
1119   QList<ConnectionItem*> allConnections;\r
1120   QFile file(confFile);\r
1121   if(file.open(QIODevice::WriteOnly)){\r
1122 \r
1123     QXmlStreamWriter writer(&file);\r
1124 \r
1125     writer.setAutoFormatting(true);\r
1126     writer.writeStartDocument();\r
1127 \r
1128     writer.writeStartElement("blast_project");\r
1129     writer.writeStartElement("scenes");\r
1130 \r
1131     writer.writeAttribute("count",QString::number(dispatcher->getNumberOfScenes()));\r
1132 \r
1133     // cross the scene level by level using a FIFO\r
1134     QList<GroupScene*> fifoScene;\r
1135     fifoScene.append(topScene);\r
1136 \r
1137     GroupScene *scene;\r
1138     while (!fifoScene.isEmpty()) {\r
1139       scene = fifoScene.takeFirst();\r
1140       scene->save(writer);\r
1141       foreach(GroupScene* s, scene->getChildrenScene()) {\r
1142         fifoScene.append(s);\r
1143       }\r
1144 \r
1145       foreach(ConnectionItem* item, scene->getConnectionItems()) {\r
1146         allConnections.append(item);\r
1147       }\r
1148     }\r
1149     writer.writeEndElement();    //</scenes>\r
1150 \r
1151     writer.writeStartElement("connections");\r
1152     foreach(ConnectionItem* item, allConnections) {\r
1153 \r
1154       writer.writeStartElement("connection");\r
1155 \r
1156       writer.writeAttribute("from",QString::number(item->getFromInterfaceItem()->getId()));\r
1157       writer.writeAttribute("to", QString::number(item->getToInterfaceItem()->getId()));\r
1158 \r
1159       writer.writeEndElement();\r
1160     }\r
1161 \r
1162     writer.writeEndElement();    //</connections>\r
1163 \r
1164     QList<InterfaceItem *> lstIfaceItem;\r
1165     // search for modifiers\r
1166     foreach(ConnectionItem* item, allConnections) {\r
1167       InterfaceItem* fromIfaceItem = item->getFromInterfaceItem();\r
1168       AbstractInputModifier* mod = fromIfaceItem->refInter->getInputModifier();\r
1169       if (mod != NULL) {\r
1170         if (!lstIfaceItem.contains(fromIfaceItem)) lstIfaceItem.append(fromIfaceItem);\r
1171       }\r
1172       InterfaceItem* toIfaceItem = item->getToInterfaceItem();\r
1173       mod = toIfaceItem->refInter->getInputModifier();\r
1174       if (mod != NULL) {\r
1175         if (!lstIfaceItem.contains(toIfaceItem)) lstIfaceItem.append(toIfaceItem);\r
1176       }\r
1177     }\r
1178     // write input modifiers\r
1179     writer.writeStartElement("modifiers");\r
1180     foreach(InterfaceItem* item, lstIfaceItem) {\r
1181       AbstractInputModifier* mod = item->refInter->getInputModifier();\r
1182       if (mod != NULL) {\r
1183         writer.writeStartElement("modifier");\r
1184         writer.writeAttribute("id", QString::number(item->getId()));\r
1185         writer.writeAttribute("type",mod->getTypeStr());\r
1186         writer.writeAttribute("params", mod->getParametersStr());\r
1187         writer.writeEndElement();\r
1188       }\r
1189     }\r
1190 \r
1191     writer.writeEndElement();    //</modifiers>\r
1192     writer.writeEndElement();      //</blast_project\r
1193 \r
1194     writer.writeEndDocument();\r
1195 \r
1196     file.close();\r
1197     unsaveModif = false;\r
1198   }\r
1199 //#endif\r
1200 }\r
1201 \r
1202 void Parameters::setArrowPathes() {\r
1203   QPainterPath _inArrow;\r
1204   _inArrow.lineTo(arrowLineLength,0);\r
1205   _inArrow.lineTo(arrowLineLength+arrowWidth,-arrowHeight/2);\r
1206   _inArrow.lineTo(arrowLineLength+arrowWidth,arrowHeight/2);\r
1207   _inArrow.lineTo(arrowLineLength,0);\r
1208   //_inArrow.closeSubpath();\r
1209   dataArrowIn = _inArrow;\r
1210 \r
1211   QPainterPath _inArrowC;\r
1212   _inArrowC.lineTo(arrowLineLength,0);\r
1213   _inArrowC.addEllipse(arrowLineLength,-arrowHeight/2,arrowHeight-1,arrowHeight-1);\r
1214   clkrstArrow = _inArrowC;\r
1215 \r
1216   QPainterPath _outArrow;\r
1217   _outArrow.lineTo(arrowLineLength,0);\r
1218   _outArrow.lineTo(arrowLineLength,-arrowHeight/2);\r
1219   _outArrow.lineTo(arrowLineLength+arrowWidth,0);\r
1220   _outArrow.lineTo(arrowLineLength,arrowHeight/2);\r
1221   _outArrow.lineTo(arrowLineLength,0);\r
1222   //_outArrow.closeSubpath();\r
1223   dataArrowOut = _outArrow;\r
1224 \r
1225 }\r
1226 \r
1227 GroupScene* Parameters::searchSceneById(int id, GroupScene *scene) {\r
1228 \r
1229   if (scene->getId() == id) return scene;\r
1230   GroupScene* sc = NULL;\r
1231 \r
1232   foreach(GroupScene *s, scene->getChildrenScene()) {\r
1233     sc = searchSceneById(id,s);\r
1234     if (sc != NULL) return sc;\r
1235   }\r
1236   return NULL;\r
1237 }\r
1238 \r
1239 GroupItem* Parameters::searchGroupItemById(int id, GroupScene *scene) {\r
1240 \r
1241   if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();\r
1242 \r
1243   GroupItem* item = NULL;\r
1244   foreach(GroupScene *s, scene->getChildrenScene()) {\r
1245     item = searchGroupItemById(id,s);\r
1246     if (item != NULL) return item;\r
1247   }\r
1248   return NULL;\r
1249 }\r
1250 \r
1251 BoxItem* Parameters::searchBlockItemById(int id, GroupScene *scene) {\r
1252 \r
1253   foreach(BoxItem *item, scene->getBoxItems()){\r
1254     if(item->getId() == id){\r
1255       return item;\r
1256     }\r
1257   }\r
1258 \r
1259   BoxItem* item = NULL;\r
1260   foreach(GroupScene *s, scene->getChildrenScene()) {\r
1261     item = searchBlockItemById(id,s);\r
1262     if (item != NULL) return item;\r
1263   }\r
1264   return NULL;\r
1265 }\r
1266 \r
1267 BoxItem* Parameters::searchFunctionalBlock(AbstractBlock* block) {\r
1268 \r
1269   return searchFunctionalBlockRecur(block,topScene);\r
1270 }\r
1271 \r
1272 BoxItem* Parameters::searchFunctionalBlockRecur(AbstractBlock* block, GroupScene* scene) {\r
1273 \r
1274   foreach(BoxItem *item, scene->getBoxItems()){\r
1275     if(item->getRefBlock() == block) {\r
1276       return item;\r
1277     }\r
1278   }\r
1279 \r
1280   BoxItem* item = NULL;\r
1281   foreach(GroupScene *s, scene->getChildrenScene()) {\r
1282     item = searchFunctionalBlockRecur(block,s);\r
1283     if (item != NULL) return item;\r
1284   }\r
1285   return NULL;\r
1286 }\r
1287 \r
1288 InterfaceItem* Parameters::searchInterfaceItemById(int id, GroupScene* scene) {\r
1289 \r
1290   foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){\r
1291     if(item->getId() == id){\r
1292       return item;\r
1293     }\r
1294   }\r
1295   if (scene->isTopScene()) {\r
1296     foreach(SourceItem *block, scene->getSourceItems()){\r
1297       foreach(InterfaceItem *item, block->getInterfaces()){\r
1298         if(item->getId() == id){\r
1299           return item;\r
1300         }\r
1301       }\r
1302     } \r
1303   }\r
1304   foreach(BoxItem *block, scene->getBoxItems()){\r
1305     foreach(InterfaceItem *item, block->getInterfaces()){\r
1306       if(item->getId() == id){\r
1307         return item;\r
1308       }\r
1309     }\r
1310   }\r
1311   InterfaceItem* item = NULL;\r
1312   foreach(GroupScene *s, scene->getChildrenScene()) {\r
1313     item = searchInterfaceItemById(id,s);\r
1314     if (item != NULL) return item;\r
1315   }\r
1316   return NULL;\r
1317 }\r
1318 \r
1319 QString Parameters::normalizeName(const QString &name) {\r
1320   QString s = name;\r
1321   s.replace(QRegularExpression("[^a-zA-Z0-9_]"),"_");\r
1322   s.replace(QRegularExpression("[_]+"),"_");\r
1323   return s;\r
1324 }\r