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

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