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

Private GIT Repository
begun integration of control ifaces
[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 "InterfaceItem.h"\r
13 #include "ConnectionItem.h"\r
14 \r
15 #include "Graph.h"\r
16 #include "ReferenceBlock.h"\r
17 #include "GroupBlock.h"\r
18 #include "FunctionalBlock.h"\r
19 #include "ReferenceInterface.h"\r
20 #include "GroupInterface.h"\r
21 #include "FunctionalInterface.h"\r
22 \r
23 #include "Exception.h"\r
24 #include "BlocksToConfigureWidget.h"\r
25 \r
26 Parameters::Parameters() {\r
27   categoryTree = NULL;\r
28   arrowWidth = 5;\r
29   arrowHeight = 10;\r
30   arrowLineLength = 10;\r
31 \r
32   defaultBlockWidth = 100;\r
33   defaultBlockHeight = 100;\r
34   defaultBlockFont = QFont("Arial");\r
35   defaultBlockFontSize = 12;\r
36 \r
37   setArrowPathes();\r
38 \r
39   sceneMode = MODE_EDITION; // default mode\r
40   editState = Parameters::EditNoOperation;\r
41 \r
42   unsaveModif = false;\r
43   isRstClkShown = false;\r
44 \r
45   projectPath = QDir::currentPath();\r
46 }\r
47 \r
48 Parameters::~Parameters() {\r
49   clear();\r
50 }\r
51 \r
52 void Parameters::clear() {\r
53   delete categoryTree;\r
54   QListIterator<ReferenceBlock *> iter(availableBlocks);\r
55   while(iter.hasNext()) {\r
56     ReferenceBlock* item = iter.next();\r
57     delete item;\r
58   }\r
59   availableBlocks.clear();\r
60   refPathes.clear();\r
61 }\r
62 \r
63 Graph* Parameters::createGraph() {\r
64   graph = new Graph();\r
65   return graph;\r
66 }\r
67 \r
68 void Parameters::destroyGraph() {\r
69   delete graph;\r
70 }\r
71 \r
72 ReferenceBlock* Parameters::getReferenceBlock(int idCategory, int idBlock) {\r
73 \r
74   BlockCategory* blockCat = categoryTree->searchCategory(idCategory);\r
75 \r
76   if (blockCat == NULL) return NULL;\r
77   ReferenceBlock* ref = blockCat->getBlock(idBlock);\r
78   return ref;\r
79 }\r
80 \r
81 \r
82 FunctionalBlock* Parameters::duplicateFunctionalBlock(FunctionalBlock *block) {\r
83 \r
84   ReferenceBlock* ref = block->getReference();\r
85   GroupBlock* group = AB_TO_GRP(block->getParent());\r
86 \r
87   // adding to the graph\r
88   FunctionalBlock* newBlock = graph->addFunctionalBlock(group,ref);\r
89   return newBlock;\r
90 }\r
91 \r
92 void Parameters::validateXmlFile(const QString& xmlFileName, const QString& xsdFileName, XmlFileType fileType) throw(Exception) {\r
93   // opening configFile\r
94   QFile xmlFile(xmlFileName);\r
95   if (!xmlFile.open(QIODevice::ReadOnly)) {\r
96     if (fileType == Configuration) {\r
97       throw(Exception(CONFIGFILE_NOACCESS));\r
98     }\r
99     else if (fileType == Reference) {\r
100       throw(Exception(BLOCKFILE_NOACCESS));\r
101     }\r
102     else if (fileType == Implementation) {\r
103       throw(Exception(IMPLFILE_NOACCESS));\r
104     }\r
105     else if (fileType == Project) {\r
106       throw(Exception(PROJECTFILE_NOACCESS));\r
107     }\r
108   }\r
109 \r
110   QFile xsdFile(xsdFileName);\r
111   if (!xsdFile.open(QIODevice::ReadOnly)) {\r
112     xsdFile.close();\r
113     if (fileType == Configuration) {\r
114       throw(Exception(CONFIGFILE_NOACCESS));\r
115     }\r
116     else if (fileType == Reference) {\r
117       throw(Exception(BLOCKFILE_NOACCESS));\r
118     }\r
119     else if (fileType == Implementation) {\r
120       throw(Exception(IMPLFILE_NOACCESS));\r
121     }\r
122     else if (fileType == Project) {\r
123       throw(Exception(PROJECTFILE_NOACCESS));\r
124     }\r
125   }\r
126 \r
127   if(validate(xmlFile,xsdFile) == false) {\r
128     xmlFile.close();\r
129     xsdFile.close();\r
130     if (fileType == Configuration) {\r
131       throw(Exception(CONFIGFILE_CORRUPTED));\r
132     }\r
133     else if (fileType == Reference) {\r
134       throw(Exception(BLOCKFILE_CORRUPTED));\r
135     }\r
136     else if (fileType == Implementation) {\r
137       throw(Exception(IMPLFILE_CORRUPTED));\r
138     }\r
139     else if (fileType == Project) {\r
140       throw(Exception(PROJECTFILE_CORRUPTED));\r
141     }\r
142   }\r
143   xmlFile.close();\r
144   xsdFile.close();\r
145 }\r
146 \r
147 bool Parameters::validate(QFile& fileXml, QFile& fileSchema) {\r
148 \r
149   // 2 files are supposed to be already opened\r
150   QXmlSchema schema;\r
151 \r
152   if(! schema.load(&fileSchema)){\r
153     cout << "invalid schema" << endl;\r
154     return false;\r
155   }\r
156 \r
157   QXmlSchemaValidator validator(schema);\r
158 \r
159   if(! validator.validate(&fileXml)){\r
160     cout << "invalid xml" << endl;\r
161     return false;\r
162   }\r
163   return true;\r
164 }\r
165 \r
166 QDomElement Parameters::openProjectFile(const QString& projectFileName) throw(Exception) {\r
167 \r
168   try {\r
169     validateXmlFile(projectFileName,"projectfile.xsd",Project);\r
170   }\r
171   catch(Exception err) {\r
172     throw(err);\r
173   }\r
174 \r
175   QFile projectFile(projectFileName);\r
176   QDomDocument doc("projectFile");\r
177 \r
178   if(!projectFile.open(QIODevice::ReadOnly)) {\r
179     throw(Exception(PROJECTFILE_NOACCESS));\r
180   }\r
181   if(!doc.setContent(&projectFile)) {\r
182     projectFile.close();\r
183     throw(Exception(PROJECTFILE_CORRUPTED));\r
184   }\r
185   projectFile.close();\r
186 \r
187   QDomElement root = doc.documentElement();\r
188 \r
189   return root;\r
190 }\r
191 \r
192 GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) {\r
193 \r
194   bool ok = false;\r
195   GroupWidget* groupWidget = NULL;\r
196   GroupItem *groupItem = NULL;\r
197   GroupBlock *groupBlock = NULL;\r
198 \r
199   GroupWidget* topGroup = NULL;\r
200   /**********************************************************\r
201    1 : getting scene and creating associated group widgets\r
202   ***********************************************************/\r
203   QDomNodeList scenesNodes = root.elementsByTagName("scene");\r
204 \r
205   int maxIdScene = -1;\r
206   for(int i=0; i<scenesNodes.length(); i++) {\r
207     QDomElement currentSceneNode = scenesNodes.at(i).toElement();\r
208     int idScene = currentSceneNode.attribute("id","none").toInt(&ok);\r
209     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
210     if (idScene > maxIdScene) maxIdScene = idScene;\r
211     int idUpperScene = currentSceneNode.attribute("upper_scene","none").toInt(&ok);\r
212     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
213 \r
214     if (idUpperScene == -1) {\r
215       topGroup = dispatcher->createTopScene();\r
216       topScene->setId(idScene);\r
217       groupItem = topScene->getGroupItem();      \r
218       cout << "top group added to scene n°" << idScene << endl;\r
219     }\r
220     else {\r
221       cout << "trying to create scene n°" << idScene << " with upper scene n°" <<idUpperScene << endl;\r
222       GroupScene* upperScene = searchSceneById(idUpperScene, topScene);\r
223       groupWidget = dispatcher->addNewEmptyGroup(upperScene,false);\r
224       groupWidget->getScene()->setId(idScene);\r
225       groupItem = groupWidget->getScene()->getGroupItem();      \r
226     }\r
227     groupBlock = AB_TO_GRP(groupItem->getRefBlock());\r
228     /**********************************************************\r
229      1.1 : getting the group item of each scene\r
230     ***********************************************************/\r
231     QDomElement groupItemNode = currentSceneNode.firstChildElement("group_item");\r
232     try {\r
233       groupItem->load(groupItemNode);\r
234     }\r
235     catch(Exception err) {\r
236       throw(err);\r
237     }\r
238 \r
239     if (idUpperScene != -1) {\r
240       groupWidget->setWindowTitle(groupBlock->getName());\r
241       groupWidget->show();\r
242     }    \r
243   }\r
244   dispatcher->setSceneCounter(maxIdScene+1);\r
245   cout << "groupItems loaded and windows created succefully!" << endl;\r
246 \r
247   /**********************************************************\r
248    2 : getting the functional blocks of each scene\r
249   ***********************************************************/\r
250 \r
251   for(int i=0; i<scenesNodes.length(); i++){\r
252     QDomElement currentSceneNode = scenesNodes.at(i).toElement();\r
253     int idScene = currentSceneNode.attribute("id","none").toInt(&ok);\r
254     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
255     cout << "SCENE : " << idScene << endl;\r
256     GroupScene *currentScene = searchSceneById(idScene,topScene);\r
257 \r
258     if(currentScene == NULL) throw(Exception(PROJECTFILE_CORRUPTED));\r
259 \r
260     QDomNodeList functionalBlockNodes = currentSceneNode.elementsByTagName("bi_functional");\r
261 \r
262     for(int j=0; j<functionalBlockNodes.length(); j++) {\r
263       QDomElement currentFBNode = functionalBlockNodes.at(j).toElement();      \r
264       BoxItem* funcItem = new BoxItem(dispatcher,this, currentScene->getGroupItem());\r
265       try {\r
266         funcItem->loadFunctional(currentFBNode);\r
267       }\r
268       catch(Exception err) {\r
269         throw(err);\r
270       }\r
271       // add the block to the GroupScene\r
272       currentScene->addBlockItem(funcItem);\r
273     }\r
274   }\r
275   cout << "functional blocks loaded and created succefully!" << endl;\r
276 \r
277   /**********************************************************\r
278    3 : set the BoxItem that represents a GroupItem in a child scene\r
279   ***********************************************************/\r
280 \r
281   for(int i=0; i<scenesNodes.length(); i++){\r
282     QDomElement currentSceneNode = scenesNodes.at(i).toElement();\r
283     int idScene = currentSceneNode.attribute("id","none").toInt(&ok);\r
284     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
285     GroupScene *currentScene = searchSceneById(idScene, topScene);\r
286     if(currentScene == NULL) throw(Exception(PROJECTFILE_CORRUPTED));\r
287 \r
288     QDomNodeList biGroupNodes = currentSceneNode.elementsByTagName("bi_group");\r
289 \r
290     for(int j=0; j<biGroupNodes.length(); j++){\r
291       QDomElement currentBiGroup = biGroupNodes.at(j).toElement();\r
292 \r
293       int id = currentBiGroup.attribute("id","none").toInt(&ok);\r
294       if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
295 \r
296       int idGroup = currentBiGroup.attribute("inside_group","none").toInt(&ok);\r
297       if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
298 \r
299       QStringList positionStr = currentBiGroup.attribute("position","none").split(",");\r
300       if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));\r
301       int posX = positionStr.at(0).toInt(&ok);\r
302       if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
303       int posY = positionStr.at(1).toInt(&ok);\r
304       if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
305 \r
306       QStringList dimensionStr = currentBiGroup.attribute("dimension","none").split(",");\r
307       if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));\r
308       int dimX = dimensionStr.at(0).toInt(&ok);\r
309       if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
310       int dimY = dimensionStr.at(1).toInt(&ok);\r
311       if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
312 \r
313       // get the GroupItem already created and set at phase 1\r
314       GroupItem *insideGroup = searchGroupItemById(idGroup, topScene);\r
315       BoxItem* upperItem = NULL;\r
316       if(insideGroup == NULL) cout << "group null" << endl;\r
317       // now search within the scene which BoxItem has a childItem that is = to insideGroup\r
318       QList<BoxItem *> lst = currentScene->getBlockItems();\r
319       foreach(BoxItem* item, lst) {\r
320         if (item->getChildGroupItem() == insideGroup) {\r
321           upperItem = item;\r
322           break;\r
323         }\r
324       }\r
325       if (upperItem == NULL) {\r
326         throw(Exception(PROJECTFILE_CORRUPTED));\r
327       }\r
328 \r
329       upperItem->setId(id);\r
330       upperItem->setPos(posX,posY);\r
331       upperItem->setDimension(dimX,dimY);\r
332 \r
333       // set interfaces of this BoxItem\r
334       QDomNodeList interfaceNodes = currentBiGroup.elementsByTagName("big_iface");\r
335 \r
336       for(int k=0; k<interfaceNodes.length(); k++){\r
337         QDomElement currentInterfaceNode = interfaceNodes.at(k).toElement();\r
338 \r
339         int id = currentInterfaceNode.attribute("id","none").toInt(&ok);\r
340         if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
341 \r
342         QString refName = currentInterfaceNode.attribute("ref_name","none");\r
343         if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
344 \r
345         QString orientationStr = currentInterfaceNode.attribute("orientation","none");\r
346         int orientation = InterfaceItem::getIntOrientation(orientationStr);\r
347         if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));\r
348 \r
349         double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);\r
350         if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
351 \r
352         ConnectedInterface *refInter = insideGroup->searchInterfaceByName(refName)->refInter;\r
353         InterfaceItem *ifaceItem = new InterfaceItem(position, orientation, refInter, upperItem, this);\r
354         ifaceItem->setId(id);\r
355         upperItem->addInterface(ifaceItem);\r
356       }\r
357     }\r
358   }\r
359   cout << "blockItems \"group\" loaded and created succefully!" << endl;\r
360 \r
361   QDomNodeList connectionNodes = root.elementsByTagName("connection");\r
362 \r
363   for(int i=0; i<connectionNodes.length(); i++){\r
364     QDomElement currentConnectionNode = connectionNodes.at(i).toElement();\r
365 \r
366     int from = currentConnectionNode.attribute("from","none").toInt(&ok);\r
367     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
368 \r
369     int to = currentConnectionNode.attribute("to","none").toInt(&ok);\r
370     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
371 \r
372 \r
373     InterfaceItem *iface1 = searchInterfaceItemById(from,topScene);\r
374     InterfaceItem *iface2 = searchInterfaceItemById(to,topScene);\r
375 \r
376     if(iface1 != NULL && iface2 != NULL){\r
377       dispatcher->connect(iface1,iface2);\r
378     } else {\r
379       cout << "interfaces not found, connect canceled!" << endl;\r
380     }\r
381   }\r
382   cout << "connections loaded and created succefully!" << endl;\r
383 \r
384   return topGroup;\r
385 }\r
386 \r
387 void Parameters::loadBlastConfiguration(QString confFile) throw(Exception) {\r
388 \r
389   try {\r
390     validateXmlFile("blastconfig.xml", "blastconfig.xsd",Configuration);\r
391   }\r
392   catch(Exception err) {\r
393     throw(err);\r
394   }\r
395 \r
396   bool ok;\r
397   // opening configFile\r
398   QFile configFile(confFile);\r
399   // reading in into QDomDocument\r
400   QDomDocument document("configFile");\r
401 \r
402   if (!configFile.open(QIODevice::ReadOnly)) {\r
403     throw(Exception(CONFIGFILE_NOACCESS));\r
404   }\r
405   if (!document.setContent(&configFile)) {\r
406     configFile.close();\r
407     throw(Exception(CONFIGFILE_NOACCESS));\r
408   }\r
409   configFile.close();\r
410 \r
411   //Get the root element\r
412   QDomElement config = document.documentElement();\r
413 \r
414   QDomElement eltCat = config.firstChildElement("categories");\r
415   try {\r
416     categoryTree = new BlockLibraryTree();\r
417     categoryTree->load(eltCat);\r
418   }\r
419   catch(Exception err) {\r
420     throw(err);\r
421   }\r
422 \r
423   QDomElement eltReferences = eltCat.nextSiblingElement("references");\r
424   refLib = eltReferences.attribute("lib_file","none");\r
425   cout << "references lib : " << qPrintable(refLib)  << endl;\r
426   int nbPathes;\r
427   QString nbPathesStr;\r
428   nbPathesStr = eltReferences.attribute("nb","none");\r
429   nbPathes = nbPathesStr.toInt(&ok);\r
430   QDomNodeList listBlockDir = eltReferences.elementsByTagName("reference_lib");\r
431   if ((!ok) || (nbPathes != listBlockDir.size())) throw(Exception(CONFIGFILE_CORRUPTED));\r
432 \r
433   for(int i=0;i<listBlockDir.size();i++) {\r
434     QDomNode nodeBlockDir = listBlockDir.at(i);\r
435     QDomElement eltBlockDir = nodeBlockDir.toElement();\r
436     if (eltBlockDir.isNull()) throw(Exception(CONFIGFILE_CORRUPTED));\r
437     QString path = eltBlockDir.attribute("path","none");\r
438     if (path == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
439     refPathes.append(path);\r
440     cout << "references path : " << qPrintable(path) << endl;\r
441   }\r
442 \r
443   QDomElement eltImpl = eltReferences.nextSiblingElement("implementations");\r
444   implLib = eltImpl.attribute("lib_file","none");\r
445   cout << "implementation lib : " << qPrintable(implLib)  << endl;\r
446   nbPathesStr = eltImpl.attribute("nb","none");\r
447   nbPathes = nbPathesStr.toInt(&ok);\r
448   QDomNodeList listImplDir = eltImpl.elementsByTagName("impl_lib");\r
449   if ((!ok) || (nbPathes != listImplDir.size())) throw(Exception(CONFIGFILE_CORRUPTED));\r
450 \r
451   for(int i=0;i<listImplDir.size();i++) {\r
452     QDomNode nodeImplDir = listImplDir.at(i);\r
453     QDomElement eltImplDir = nodeImplDir.toElement();\r
454     if (eltImplDir.isNull()) throw(Exception(CONFIGFILE_CORRUPTED));\r
455     QString path = eltImplDir.attribute("path","none");\r
456     if (path == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
457     implPathes.append(path);\r
458     cout << "impl path : " << qPrintable(path) << endl << endl;\r
459   }\r
460   // getting elt = the element <defaults>\r
461   // for each child element, initialize the associated attributes of Parameters\r
462 \r
463   QDomElement eltDefaults = eltImpl.nextSiblingElement("defaults");\r
464 \r
465   QDomElement eltBlocks = eltDefaults.firstChildElement("blocks");\r
466   QString attributeStr = eltBlocks.attribute("width", "none");\r
467   defaultBlockWidth = attributeStr.toInt(&ok);\r
468   if (!ok || defaultBlockWidth < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
469   attributeStr = eltBlocks.attribute("height", "none");\r
470   defaultBlockHeight = attributeStr.toInt(&ok);\r
471   if (!ok || defaultBlockHeight < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
472   attributeStr = eltBlocks.attribute("font_size", "none");\r
473   defaultBlockFontSize = attributeStr.toFloat(&ok);\r
474   if (!ok || defaultBlockFontSize < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
475   attributeStr = eltBlocks.attribute("font", "none");\r
476   if (attributeStr == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
477   defaultBlockFontName = attributeStr;\r
478   defaultBlockFont = QFont(defaultBlockFontName, defaultBlockFontSize);\r
479 \r
480   QDomElement eltInterfaces = eltBlocks.nextSiblingElement("interfaces");\r
481   attributeStr = eltInterfaces.attribute("width", "none");\r
482   arrowWidth = attributeStr.toInt(&ok);\r
483   if (!ok || arrowWidth < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
484   attributeStr = eltInterfaces.attribute("height", "none");\r
485   arrowHeight = attributeStr.toInt(&ok);\r
486   if (!ok || arrowHeight < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
487   attributeStr = eltInterfaces.attribute("linelength", "none");\r
488   arrowLineLength = attributeStr.toInt(&ok);\r
489   if (!ok || arrowLineLength < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
490   attributeStr = eltInterfaces.attribute("font_size", "none");\r
491   defaultIfaceFontSize = attributeStr.toFloat(&ok);\r
492   if (!ok || defaultIfaceFontSize < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
493   attributeStr = eltInterfaces.attribute("font", "none");\r
494   if (attributeStr == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
495   defaultIfaceFontName = attributeStr;\r
496   defaultIfaceFont = QFont(defaultIfaceFontName, defaultIfaceFontSize);\r
497 \r
498   QDomElement eltConnections = eltInterfaces.nextSiblingElement("connections");\r
499   attributeStr = eltConnections.attribute("gaplength", "none");\r
500   connGapLength = attributeStr.toInt(&ok);\r
501   if (!ok || connGapLength < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
502 }\r
503 \r
504 void Parameters::loadReferencesFromXml() throw(Exception) {\r
505   cout << "load references from xml" << endl;\r
506   for(int i=0;i<refPathes.size();i++) {\r
507     cout << "analyzing " << qPrintable(refPathes.at(i)) << endl;\r
508     QDir dir(refPathes.at(i));\r
509     QStringList filter;\r
510     filter << "*.xml";\r
511     dir.setNameFilters(filter);\r
512     QStringList list = dir.entryList();\r
513     for(int j=0;j<list.size();j++) {\r
514       QString fileName = dir.absolutePath();\r
515       fileName.append("/"+list.at(j));\r
516 \r
517       QFile blockXML(fileName);\r
518       if (!blockXML.open(QIODevice::ReadOnly)) {\r
519         throw(Exception(BLOCKFILE_NOACCESS));\r
520       }\r
521       QTextStream in(&blockXML);\r
522       QString line = in.readLine();\r
523       line = in.readLine();\r
524 \r
525       if (!line.contains("<block>")) {\r
526         blockXML.close();\r
527         continue;\r
528       }\r
529 \r
530       blockXML.close();\r
531       try {\r
532         validateXmlFile(fileName,"reference.xsd",Reference);\r
533       }\r
534       catch(Exception err) {\r
535         throw(err);\r
536       }\r
537 \r
538       // reading in into QDomDocument\r
539       QDomDocument document ("FileXML");\r
540       if (!blockXML.open(QIODevice::ReadOnly)) {\r
541         throw(Exception(BLOCKFILE_NOACCESS));\r
542       }\r
543       if (!document.setContent(&blockXML)) {\r
544         blockXML.close();\r
545         throw(Exception(BLOCKFILE_NOACCESS));\r
546       }\r
547       blockXML.close();\r
548 \r
549       QDomElement blockRoot = document.documentElement();\r
550       QString name = blockRoot.tagName();\r
551       if (name == "block") {\r
552 \r
553         cout << "xml:" << fileName.toStdString() << endl;\r
554         ReferenceBlock* b = new ReferenceBlock(fileName);\r
555         try {\r
556           b->load(blockRoot);\r
557           b->setHashMd5();\r
558         }\r
559         catch(int err) {\r
560           throw(err);\r
561         }\r
562         cout << "xml:" << b->getXmlFile().toStdString() << endl;\r
563 \r
564         availableBlocks.append(b);\r
565         foreach (int id,b->getCategories()) {\r
566           cout << "ajout du bloc dans cat n° : " << id << endl;\r
567           BlockCategory* cat = categoryTree->searchCategory(id);\r
568           cat->blocks.append(b);\r
569         }\r
570       }\r
571     }\r
572   }\r
573 }\r
574 \r
575 void Parameters::loadReferencesFromLib() throw(Exception) {\r
576 \r
577   cout << "loading references from lib" << endl;\r
578 \r
579   // removing blocks from category tree if they exist\r
580   categoryTree->clearBlocks();\r
581   // deleting existings blocks\r
582   ReferenceBlock* b = NULL;\r
583   for(int i=0;i<availableBlocks.size();i++) {\r
584     b = availableBlocks.at(i);\r
585     delete b;\r
586   }\r
587   availableBlocks.clear();\r
588 \r
589   QFile libFile(refLib);\r
590   if (!libFile.open(QIODevice::ReadOnly)) {\r
591     throw(Exception(BLOCKFILE_NOACCESS));\r
592   }\r
593   QDataStream in(&libFile);\r
594   quint32 size;\r
595 \r
596   in >> size;\r
597 \r
598   int nbBlocks;\r
599   in >> nbBlocks;\r
600   for(int i=0;i<nbBlocks;i++) {\r
601     b = new ReferenceBlock("");\r
602     in >> *b;\r
603     availableBlocks.append(b);\r
604     foreach (int id,b->getCategories()) {\r
605       BlockCategory* cat = categoryTree->searchCategory(id);\r
606       cat->blocks.append(b);\r
607     }\r
608   }\r
609   libFile.close();\r
610 }\r
611 \r
612 void Parameters::saveReferencesToLib() throw(Exception) {\r
613 \r
614   cout << "saving blocks in " << qPrintable(refLib) << endl;\r
615   QFile libFile(refLib);\r
616   if (!libFile.open(QIODevice::WriteOnly)) {\r
617     throw(Exception(BLOCKFILE_NOACCESS));\r
618   }\r
619   QDataStream out(&libFile);\r
620 \r
621   out.setVersion(QDataStream::Qt_5_0);\r
622 \r
623   QByteArray blockData;\r
624   QDataStream toWrite(&blockData, QIODevice::WriteOnly);\r
625 \r
626   toWrite << availableBlocks.size();\r
627   for(int i=0;i<availableBlocks.size();i++) {\r
628     ReferenceBlock* b = availableBlocks.at(i);\r
629     toWrite << *b;\r
630   }\r
631 \r
632   out << blockData;\r
633 \r
634   libFile.close();\r
635 \r
636 }\r
637 \r
638 void Parameters::loadImplementationsFromXml() throw(Exception) {\r
639 \r
640   for(int i=0;i<implPathes.size();i++) {\r
641     cout << "analyzing " << qPrintable(implPathes.at(i)) << endl;\r
642     QDir dir(implPathes.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       cout << "checking " << qPrintable(fileName) << " is an implementation file ...";\r
652       QFile implXML(fileName);\r
653       if (!implXML.open(QIODevice::ReadOnly)) {\r
654         throw(Exception(IMPLFILE_NOACCESS));\r
655       }\r
656       QTextStream in(&implXML);\r
657       QString line = in.readLine();\r
658       line = in.readLine();\r
659 \r
660       if (!line.contains("<block_impl")) {\r
661         implXML.close();\r
662         continue;\r
663       }\r
664 \r
665       implXML.close();\r
666       cout << "OK" << endl;\r
667       cout << "reading " << qPrintable(fileName) << " content ...";\r
668 \r
669       try {\r
670         validateXmlFile(fileName,"implementation.xsd",Implementation);\r
671       }\r
672       catch(Exception e) {\r
673         throw(e);\r
674       }\r
675 \r
676       // reading in into QDomDocument\r
677       QDomDocument document ("FileXML");\r
678       if (!implXML.open(QIODevice::ReadOnly)) {\r
679         throw(Exception(IMPLFILE_NOACCESS));\r
680       }\r
681       cout << "OK" << endl;\r
682       cout << "convert " << qPrintable(fileName) << " content into document...";\r
683       if (!document.setContent(&implXML)) {\r
684         implXML.close();\r
685         throw(Exception(IMPLFILE_NOACCESS));\r
686       }\r
687       implXML.close();\r
688 \r
689       QDomElement implRoot = document.documentElement();\r
690       QString refXml = implRoot.attribute("ref_name","none");\r
691       QString refMd5 = implRoot.attribute("ref_md5","none");\r
692       BlockImplementation* impl = new BlockImplementation(fileName,refXml,refMd5);\r
693       availableImplementations.append(impl);\r
694 \r
695       ReferenceBlock* ref = NULL;\r
696       if (! refMd5.isEmpty()) {\r
697         ref = searchBlockByMd5(refMd5);\r
698       }\r
699       if (ref == NULL) {\r
700         ref = searchBlockByXml(refXml);\r
701       }\r
702       if (ref == NULL) {\r
703         cout << "Cannot find a reference block for impl :" << qPrintable(fileName) << endl;\r
704       }\r
705       ref->addImplementation(impl);\r
706       impl->setReference(ref);\r
707       cout << "OK" << endl;\r
708     }\r
709   }\r
710 }\r
711 \r
712 void Parameters::loadImplementationsFromLib() throw(Exception) {\r
713 \r
714   cout << "loading implementations from lib" << endl;\r
715 \r
716   BlockImplementation* impl = NULL;\r
717   ReferenceBlock* ref = NULL;\r
718   for(int i=0;i<availableImplementations.size();i++) {\r
719     impl = availableImplementations.at(i);\r
720     delete impl;\r
721   }\r
722   availableImplementations.clear();\r
723 \r
724   QFile libFile(implLib);\r
725   if (!libFile.open(QIODevice::ReadOnly)) {\r
726     throw(Exception(IMPLFILE_NOACCESS));\r
727   }\r
728   QDataStream in(&libFile);\r
729   quint32 size;\r
730 \r
731   in >> size;\r
732 \r
733   int nbImpls;\r
734   in >> nbImpls;\r
735   for(int i=0;i<nbImpls;i++) {\r
736     impl = new BlockImplementation("");\r
737     in >> *impl;\r
738     availableImplementations.append(impl);\r
739     QString refMd5 = impl->getReferenceMd5();\r
740     QString refXml = impl->getReferenceXml();\r
741     ref = NULL;\r
742     if (! refMd5.isEmpty()) {\r
743       ref = searchBlockByMd5(refMd5);\r
744     }\r
745     if (ref == NULL) {\r
746       ref = searchBlockByXml(refXml);\r
747     }\r
748     if (ref == NULL) {\r
749       cout << "Cannot find a reference block for impl :" << qPrintable(impl->getXmlFile()) << endl;\r
750     }\r
751     ref->addImplementation(impl);\r
752     impl->setReference(ref);\r
753   }\r
754   libFile.close();\r
755 }\r
756 \r
757 void Parameters::saveImplementationsToLib() throw(Exception) {\r
758 \r
759   cout << "saving implementations in " << qPrintable(implLib) << endl;\r
760   QFile libFile(implLib);\r
761   if (!libFile.open(QIODevice::WriteOnly)) {\r
762     throw(Exception(IMPLFILE_NOACCESS));\r
763   }\r
764   QDataStream out(&libFile);\r
765 \r
766   out.setVersion(QDataStream::Qt_5_0);\r
767 \r
768   QByteArray blockData;\r
769   QDataStream toWrite(&blockData, QIODevice::WriteOnly);\r
770 \r
771   toWrite << availableImplementations.size();\r
772   for(int i=0;i<availableImplementations.size();i++) {\r
773     BlockImplementation* impl = availableImplementations.at(i);\r
774     toWrite << *impl;\r
775   }\r
776 \r
777   out << blockData;\r
778 \r
779   libFile.close();\r
780 \r
781 }\r
782 void Parameters::addAvailableBlock(ReferenceBlock *block) {\r
783   availableBlocks.append(block);\r
784   foreach (int id,block->getCategories()) {\r
785     cout << "ajout du bloc dans cat n° : " << id << endl;\r
786     BlockCategory* cat = categoryTree->searchCategory(id);\r
787     cat->blocks.append(block);\r
788   }\r
789 }\r
790 \r
791 void Parameters::parametersValidation() {\r
792   QList<AbstractBlock*> blocksToConfigure = getBlocksToConfigure();\r
793 \r
794   if(!blocksToConfigure.isEmpty()){\r
795     BlocksToConfigureWidget *widget = new BlocksToConfigureWidget(blocksToConfigure, this, NULL);\r
796     widget->show();\r
797   }\r
798 }\r
799 \r
800 void Parameters::connectionsValidation() {\r
801 \r
802 #ifdef DEBUG_INCLFUN\r
803 \r
804   QStack<AbstractInterface*> *interfaceToValidate = new QStack<AbstractInterface*>;\r
805   QList<AbstractInterface*> *validatedInterface = new QList<AbstractInterface*>;\r
806 \r
807   foreach(AbstractInterface *inter, topWindow->getScene()->getGroupItem()->getRefBlock()->getInterfaces()){\r
808     foreach(AbstractInterface *connectedInter, inter->getConnectedTo()){\r
809 \r
810       inter->setWidth(connectedInter->getWidth());\r
811       interfaceToValidate->push(connectedInter);\r
812     }\r
813   }\r
814 \r
815 \r
816   try{\r
817     while(!interfaceToValidate->isEmpty()){\r
818       interfaceToValidate->pop()->connectionsValidation(interfaceToValidate, validatedInterface);\r
819     }\r
820   }\r
821   catch(Exception e){\r
822     cerr << e.getMessage().toStdString() << endl;\r
823   }\r
824 #endif\r
825 }\r
826 \r
827 QList<AbstractBlock *> Parameters::getBlocksToConfigure() {\r
828 \r
829 #ifdef DEBUG_INCLFUN\r
830 \r
831   QList<AbstractBlock*> *checkedBlocks = new QList<AbstractBlock*>;\r
832   QList<AbstractBlock*> *blocksToConfigure = new QList<AbstractBlock*>;\r
833 \r
834   foreach(AbstractInterface *inter, topWindow->getScene()->getGroupItem()->getRefBlock()->getInterfaces()){\r
835     foreach(AbstractInterface *connectedInter, inter->getConnectedTo()){\r
836       if(!checkedBlocks->contains(connectedInter->getOwner())){\r
837         connectedInter->getOwner()->parametersValidation(checkedBlocks, blocksToConfigure);\r
838       }\r
839     }\r
840   }\r
841   return *blocksToConfigure;\r
842 #endif\r
843 }\r
844 \r
845 \r
846 void Parameters::updateToolbar() {\r
847   int nb = currentScene->getBlockItems().length();\r
848   for(int i = 0; i<nb; i++){\r
849     if(currentScene->getBlockItems().at(i)->isSelected()){\r
850       currentScene->getGroupWidget()->enableGroupButton(true);\r
851       return;\r
852     }\r
853   }\r
854   currentScene->getGroupWidget()->enableGroupButton(false);\r
855 }\r
856 \r
857 \r
858 void Parameters::updateIds() {\r
859 \r
860   /* a in-width cross of the graph must be done so that ids of GroupItem\r
861      are in the correct ordre when saving/loading a project\r
862    */\r
863   int countItem = 1;\r
864   int countIface = 1;\r
865   QList<GroupScene *> fifo;\r
866   fifo.append(topScene);\r
867   while (!fifo.isEmpty()) {\r
868     GroupScene* scene = fifo.takeFirst();\r
869     countItem = scene->setItemsId(countItem);\r
870     countIface = scene->setInterfacesId(countIface);\r
871     foreach(GroupScene* s, scene->getChildrenScene()) {\r
872       fifo.append(s);\r
873     }\r
874   }\r
875 }\r
876 \r
877 \r
878 ReferenceBlock *Parameters::searchBlockByXml(QString xmlName) {\r
879   foreach(ReferenceBlock *block, availableBlocks){\r
880     if(block->getXmlFile().contains(xmlName))\r
881       return block;\r
882   }\r
883   return NULL;\r
884 }\r
885 \r
886 ReferenceBlock *Parameters::searchBlockByMd5(QString sumMd5) {\r
887   foreach(ReferenceBlock *block, availableBlocks){\r
888     if(block->getHashMd5() == sumMd5)\r
889       return block;\r
890   }\r
891   return NULL;\r
892 }\r
893 \r
894 void Parameters::save(QString confFile) {\r
895 \r
896 //#ifdef DEBUG_INCLFUN\r
897 \r
898   updateIds();\r
899   QList<ConnectionItem*> allConnections;\r
900   QFile file(confFile);\r
901   if(file.open(QIODevice::WriteOnly)){\r
902 \r
903     QXmlStreamWriter writer(&file);\r
904 \r
905     writer.setAutoFormatting(true);\r
906     writer.writeStartDocument();\r
907 \r
908     writer.writeStartElement("blast_project");\r
909     writer.writeStartElement("scenes");\r
910 \r
911     writer.writeAttribute("count",QString::number(dispatcher->getNumberOfScenes()));\r
912 \r
913     // cross the scene level by level using a FIFO\r
914     QList<GroupScene*> fifoScene;\r
915     fifoScene.append(topScene);\r
916 \r
917     GroupScene *scene;\r
918     while (!fifoScene.isEmpty()) {\r
919       scene = fifoScene.takeFirst();\r
920       scene->save(writer);\r
921       foreach(GroupScene* s, scene->getChildrenScene()) {\r
922         fifoScene.append(s);\r
923       }\r
924 \r
925       foreach(ConnectionItem* item, scene->getConnectionItems()) {\r
926         allConnections.append(item);\r
927       }\r
928     }\r
929     writer.writeEndElement();    //</scenes>\r
930 \r
931     writer.writeStartElement("connections");\r
932     foreach(ConnectionItem* item, allConnections) {\r
933 \r
934       writer.writeStartElement("connection");\r
935 \r
936       writer.writeAttribute("from",QString::number(item->getFromInterfaceItem()->getId()));\r
937       writer.writeAttribute("to", QString::number(item->getToInterfaceItem()->getId()));\r
938 \r
939       writer.writeEndElement();\r
940     }\r
941 \r
942     writer.writeEndElement();    //</connections>\r
943     writer.writeEndElement();      //</blast_project\r
944 \r
945     writer.writeEndDocument();\r
946 \r
947     file.close();\r
948     unsaveModif = false;\r
949   }\r
950 //#endif\r
951 }\r
952 \r
953 void Parameters::setArrowPathes() {\r
954   QPainterPath _inArrow;\r
955   _inArrow.lineTo(arrowLineLength,0);\r
956   _inArrow.lineTo(arrowLineLength+arrowWidth,-arrowHeight/2);\r
957   _inArrow.lineTo(arrowLineLength+arrowWidth,arrowHeight/2);\r
958   _inArrow.lineTo(arrowLineLength,0);\r
959   _inArrow.closeSubpath();\r
960   inArrow = _inArrow;\r
961 \r
962   QPainterPath _outArrow;\r
963   _outArrow.lineTo(arrowLineLength,0);\r
964   _outArrow.lineTo(arrowLineLength,-arrowHeight/2);\r
965   _outArrow.lineTo(arrowLineLength+arrowWidth,0);\r
966   _outArrow.lineTo(arrowLineLength,arrowHeight/2);\r
967   _outArrow.lineTo(arrowLineLength,0);\r
968   _outArrow.closeSubpath();\r
969   outArrow = _outArrow;\r
970 \r
971 }\r
972 \r
973 GroupScene* Parameters::searchSceneById(int id, GroupScene *scene) {\r
974 \r
975   if (scene->getId() == id) return scene;\r
976   GroupScene* sc = NULL;\r
977 \r
978   foreach(GroupScene *s, scene->getChildrenScene()) {\r
979     sc = searchSceneById(id,s);\r
980     if (sc != NULL) return sc;\r
981   }\r
982   return NULL;\r
983 }\r
984 \r
985 GroupItem* Parameters::searchGroupItemById(int id, GroupScene *scene) {\r
986 \r
987   if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();\r
988 \r
989   GroupItem* item = NULL;\r
990   foreach(GroupScene *s, scene->getChildrenScene()) {\r
991     item = searchGroupItemById(id,s);\r
992     if (item != NULL) return item;\r
993   }\r
994   return NULL;\r
995 }\r
996 \r
997 BoxItem* Parameters::searchBlockItemById(int id, GroupScene *scene) {\r
998 \r
999   foreach(BoxItem *item, scene->getBlockItems()){\r
1000     if(item->getId() == id){\r
1001       return item;\r
1002     }\r
1003   }\r
1004 \r
1005   BoxItem* item = NULL;\r
1006   foreach(GroupScene *s, scene->getChildrenScene()) {\r
1007     item = searchBlockItemById(id,s);\r
1008     if (item != NULL) return item;\r
1009   }\r
1010   return NULL;\r
1011 }\r
1012 \r
1013 InterfaceItem* Parameters::searchInterfaceItemById(int id, GroupScene* scene) {\r
1014 \r
1015   foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){\r
1016     if(item->getId() == id){\r
1017       return item;\r
1018     }\r
1019   }\r
1020   foreach(BoxItem *block, scene->getBlockItems()){\r
1021     foreach(InterfaceItem *item, block->getInterfaces()){\r
1022       if(item->getId() == id){\r
1023         return item;\r
1024       }\r
1025     }\r
1026   }\r
1027   InterfaceItem* item = NULL;\r
1028   foreach(GroupScene *s, scene->getChildrenScene()) {\r
1029     item = searchInterfaceItemById(id,s);\r
1030     if (item != NULL) return item;\r
1031   }\r
1032   return NULL;\r
1033 }\r