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

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