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

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