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

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