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

Private GIT Repository
clkconvert OP compute done
[blast.git] / StimuliItem.cpp
1 #include "StimuliItem.h"
2 #include "GroupScene.h"
3 #include "ConnectionItem.h"
4 #include "InterfaceItem.h"
5 #include "GroupItem.h"
6 #include "Parameters.h"
7 #include "Exception.h"
8 #include "Dispatcher.h"
9 #include "FunctionalBlock.h"
10 #include "FunctionalInterface.h"
11 #include "ReferenceInterface.h"
12 #include "ReferenceBlock.h"
13 #include "ParametersWindow.h"
14 #include "BlockParameter.h"
15 #include "Graph.h"
16
17
18 StimuliItem::StimuliItem(AbstractBlock *_refBlock,
19                      Dispatcher *_dispatcher,
20                      Parameters *_params) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params) {
21
22   /*  NOTE :
23      _refBlock : mandatory a FunctionalBlock or a GroupBlock
24   */
25   if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
26
27   currentBorder = NoBorder;
28   selected = false;
29
30   setZValue(100);
31   setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
32
33   createInterfaceItems();
34   updateGeometry(InterfaceMove);
35   resetInterfaceItemsPosition();
36   QPointF initPos = QPointF(0.0,0.0) - originPoint;
37   setPos(initPos);
38   //cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
39   //cout << "pos in group: " << x() << "," << y() << endl;
40 }
41
42 StimuliItem::StimuliItem(Dispatcher *_dispatcher, Parameters *_params) throw(Exception) : AbstractBoxItem(_dispatcher, _params) {
43
44   refBlock = NULL;
45   currentBorder = NoBorder;
46   selected = false;
47
48   setZValue(100);
49   setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
50
51   boxWidth = params->defaultBlockWidth;
52   boxHeight = params->defaultBlockHeight;
53 }
54
55 StimuliItem::~StimuliItem() {
56 }
57
58 void StimuliItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
59   QPen pen(Qt::black, 3);
60   if(selected)
61     pen.setColor(Qt::red);
62
63   painter->setPen(pen);
64   painter->setBrush(Qt::darkCyan);
65
66   painter->drawRect(0,0,boxWidth, boxHeight);
67   painter->drawText(0,0,boxWidth, boxHeight,Qt::AlignCenter | Qt::TextWordWrap,QString(refBlock->getName()));
68   foreach(InterfaceItem *inter, interfaces) {
69     
70     inter->paint(painter);
71   }
72 }
73
74 void StimuliItem::moveTo(QPointF dest) {
75   setPos(dest);
76   currentPosition = dest;
77 }
78
79 bool StimuliItem::isStimuliItem() {
80   return true;
81 }
82
83 void StimuliItem::nameChanged() {
84
85   
86   QFontMetrics fmId(params->defaultBlockFont);
87   nameWidth = fmId.width(refBlock->getName());
88   nameHeight = fmId.height();  
89   updateGeometry(InterfaceMove);
90   // force the update in case of the size has not changed
91   update();  
92 }
93
94 void StimuliItem::updateMinimumSize() {
95
96   int maxSouth = 0;
97   int maxNorth = 0;
98   int maxEast = 0;
99   int maxWest = 0;
100   int nbSouth = nbInterfacesByOrientation(Parameters::South);
101   int nbNorth = nbInterfacesByOrientation(Parameters::North);
102   int nbMaxSN = nbNorth;
103   if (nbSouth > nbNorth) nbMaxSN = nbSouth;
104   int nbEast = nbInterfacesByOrientation(Parameters::East);
105   int nbWest = nbInterfacesByOrientation(Parameters::West);
106   int nbMaxEW = nbEast;
107   if (nbWest > nbEast) {
108     nbMaxEW = nbWest;
109   }
110
111   int ifaceWidth = 0;
112   int ifaceHeight = 0;
113
114   foreach(InterfaceItem* iface, interfaces) {
115     ifaceWidth = iface->getNameWidth();
116     ifaceHeight = iface->getNameHeight();
117     if (iface->visible) {
118       if (iface->getOrientation() == Parameters::South) {
119         if (ifaceWidth > maxSouth) maxSouth = ifaceWidth;
120       }
121       else if (iface->getOrientation() == Parameters::North) {
122         if (ifaceWidth > maxNorth) maxNorth = ifaceWidth;
123       }
124       else if (iface->getOrientation() == Parameters::East) {
125         if (ifaceWidth > maxEast) maxEast = ifaceWidth;
126       }
127       else if (iface->getOrientation() == Parameters::West) {
128         if (ifaceWidth > maxWest) maxWest = ifaceWidth;
129       }
130     }
131   }  
132
133   /* NB: the width layout is the following
134      ifaceMargin | maxWest | nameMargin | name | nameMargin | maxEast | ifaceMargin
135    */
136   minimumBoxWidth = maxWest+maxEast+nameWidth+2*(ifaceMargin+nameMargin);  
137   // if the minimum is not sufficent taking into account N/S interfaces
138   if (minimumBoxWidth < (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1))) {
139     minimumBoxWidth = (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1));
140   }  
141   minimumBoxHeight = maxNorth+maxSouth+3*ifaceMargin;
142   if (minimumBoxHeight < (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1))) {
143     minimumBoxHeight = (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1));
144   }
145   cout << "source minimum size = " << minimumBoxWidth << "x" << minimumBoxHeight << endl;
146 }
147
148
149 /* updateGeometry() :
150
151  */
152 bool StimuliItem::updateGeometry(ChangeType type) {
153
154   currentPosition = pos();
155   //cout << "current pos of block: " << currentPosition.x() << "," << currentPosition.y() << endl;
156   QPointF oldOrigin = originPoint;
157   QSize oldSize(totalWidth,totalHeight);
158
159   bool boxSizeChanged = false;
160
161   // whatever the change, the minimum size may have changed
162   updateMinimumSize();
163
164   if (type == Resize) {
165     // resize implies to move interfaces and to update connections
166     boxSizeChanged = true;
167   }
168   else if (type == InterfaceMove) {
169     // if an interface moves, it may change the box size
170     if (boxWidth < minimumBoxWidth) {
171       boxWidth = minimumBoxWidth;
172       boxSizeChanged = true;
173     }
174     if (boxHeight < minimumBoxHeight) {
175       boxHeight = minimumBoxHeight;
176       boxSizeChanged = true;
177     }
178   }
179   if (boxSizeChanged) {
180     updateInterfaceAndConnectionItems();
181   }
182
183
184   double x = 0.0;
185   double y = 0.0;
186   totalWidth = boxWidth;
187   totalHeight = boxHeight;
188
189   if(isInterfaces(Parameters::East)){
190     totalWidth += params->arrowWidth+params->arrowLineLength;
191   }
192   if(isInterfaces(Parameters::West)){
193     totalWidth += params->arrowWidth+params->arrowLineLength;
194     x -= params->arrowWidth+params->arrowLineLength;
195   }
196   if(isInterfaces(Parameters::South)){
197     totalHeight += params->arrowWidth+params->arrowLineLength;
198   }
199   if(isInterfaces(Parameters::North)){
200     totalHeight += params->arrowWidth+params->arrowLineLength;
201     y -= params->arrowWidth+params->arrowLineLength;
202   }
203   QSizeF newSize(totalWidth,totalHeight);
204   originPoint.setX(x);
205   originPoint.setY(y);
206
207   cout << "source size = " << totalWidth << "x" << totalHeight << endl;
208   if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
209     prepareGeometryChange();
210     return true;
211   }
212   return false;
213 }
214
215 void StimuliItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
216
217   if(params->editState == Parameters::EditBlockMove) {
218     QPointF absPos = currentPosition + originPoint;
219     
220     int gapX = event->scenePos().x() - cursorPosition.x();
221     int gapY = event->scenePos().y() - cursorPosition.y();
222     
223     bool canMove = true;
224     
225     QRectF rectSource = boundingRectInScene();
226     rectSource.moveTo(rectSource.x()+gapX,rectSource.y()+gapY);
227     GroupItem* group = getScene()->getGroupItem();
228     QRectF rectGroup = group->boundingRectInScene();    
229     if (rectSource.intersects(rectGroup)) canMove = false;
230     /*
231     if (canMove) {
232       foreach(SourceItem* source, getScene()->getSourceItems()) {
233         QRectF rectOther = source->boundingRectInScene();
234         if ((source != this) && (rectSource.intersects(rectOther))) canMove = false;
235       }
236     }
237     */
238     if (canMove) {
239       QPointF gap(gapX,gapY);
240       currentPosition = currentPosition+gap;
241       setPos(currentPosition);
242       // update all connections from/to this block
243       foreach(ConnectionItem *item, getScene()->getConnectionItems()){
244         if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
245           item->setPath();
246         }
247       }      
248     }
249     cursorPosition = event->scenePos();
250   }
251   else if(params->editState == Parameters::EditBlockResize) {
252
253     int gapX = event->scenePos().x() - cursorPosition.x();
254     int gapY = event->scenePos().y() - cursorPosition.y();
255     //cout << "gap: " << gapX << "," << gapY << endl;
256     switch(currentBorder){
257     case BorderEast: {    
258       if(boxWidth+gapX > minimumBoxWidth){
259         boxWidth += gapX;
260       }
261       break;
262     }
263     case BorderSouth: {      
264       if(boxHeight+gapY > minimumBoxHeight){
265         boxHeight += gapY;
266       }
267       break;
268     }
269     case CornerSouthEast: {
270       if(boxWidth+gapX > minimumBoxWidth){
271         boxWidth += gapX;
272       }
273       if(boxHeight+gapY > minimumBoxHeight){
274         boxHeight += gapY;
275       }
276       break;
277     }
278     case NoBorder:
279       cout << "abnormal case while resizing block" << endl;
280       break;
281     }
282     // recompute the geometry of the block and possibly the group item
283     if (updateGeometry(Resize)) {
284       (getScene()->getGroupItem())->updateShape();
285     }
286
287     cursorPosition = event->scenePos();   
288   }
289   else if(params->editState == Parameters::EditInterfaceMove) {
290     prepareGeometryChange();
291     moveInterfaceItemTo(event->pos());
292     // recompute the geometry of the block
293     if (updateGeometry(InterfaceMove)) {
294       //cout << "must recompute group item geometry" << endl;
295       (getScene()->getGroupItem())->updateShape();
296     }
297     // update connection from/to the selected interface
298     foreach(ConnectionItem *item, getScene()->getConnectionItems()){
299       if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
300         item->setPath();
301       }
302     }    
303   }
304 }
305
306 void StimuliItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
307
308   QPointF pos = event->pos();
309   qreal x = pos.x();
310   qreal y = pos.y();
311
312   //QGraphicsItem::mousePressEvent(event);
313
314   if(event->button() == Qt::RightButton) return;
315
316   int mode = getScene()->getEditionMode();
317
318   dispatcher->setCurrentGroupWidget(Dispatcher::Design, getScene()->getGroupWidget());
319
320   if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) {
321     InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
322     if (inter != NULL) {
323
324       if (params->editState == Parameters::EditNoOperation) {
325         getScene()->setSelectedInterface(1,inter);
326         params->setEditState(Parameters::EditStartConnection);
327       }
328       else if (params->editState == Parameters::EditStartConnection) {
329         if (inter == getScene()->getSelectedInterface(1)) {
330           params->setEditState(Parameters::EditAbortConnection);
331         }
332         else {
333           getScene()->setSelectedInterface(2,inter);
334           params->setEditState(Parameters::EditCloseConnection);
335         }
336       }
337     }
338   }
339   else if (mode == GroupScene::ItemEdition) {
340     //setZValue(zValue()+100);
341     if (params->cursorState == Parameters::CursorOnInterface) {
342       InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
343       if (inter != NULL) {
344         if (inter == currentInterface) {
345            params->setEditState(Parameters::EditInterfaceDeselect);
346         }
347         else {
348           setFlag(ItemIsMovable, false);
349           currentInterface = inter;
350           params->setEditState(Parameters::EditInterfaceMove);
351         }
352       }
353     }
354     else if (params->cursorState == Parameters::CursorInBlock) {
355       selected = !selected;
356       params->setEditState(Parameters::EditBlockMove);
357       cursorPosition = event->scenePos();
358       //cout << "cursor current pos. in scene " << cursorPosition.x() << "," << cursorPosition.y() << endl;
359       update();
360     }
361     else if (params->cursorState == Parameters::CursorOnBorder) {
362       setFlag(ItemIsMovable, false);
363       cursorPosition = event->scenePos();
364       params->setEditState(Parameters::EditBlockResize);
365     }
366   }
367 }
368
369 void StimuliItem::mouseReleaseEvent(QGraphicsSceneMouseEvent  *event) {
370
371   //setZValue(zValue()-100);
372
373   int mode = getScene()->getEditionMode();
374
375   if (mode == GroupScene::AddConnection) {
376
377     if (params->editState == Parameters::EditStartConnection) {
378       InterfaceItem* iface = getScene()->getSelectedInterface(1);
379       iface->selected = true;
380       update(iface->boundingRect());
381     }
382     else if (params->editState == Parameters::EditAbortConnection) {
383       InterfaceItem* iface = getScene()->getSelectedInterface(1);
384       iface->selected = false;
385       update(iface->boundingRect());
386       getScene()->setSelectedInterface(1,NULL);
387       params->setEditState(Parameters::EditNoOperation);
388     }
389     else if (params->editState == Parameters::EditCloseConnection) {
390       InterfaceItem* iface1 = getScene()->getSelectedInterface(1);
391       InterfaceItem* iface2 = getScene()->getSelectedInterface(2);
392       bool ok = dispatcher->createConnection(Dispatcher::Design, iface1,iface2);
393       if (ok) {
394         iface1->selected = false;
395         update(iface1->boundingRect());
396         iface2->selected = false;
397         update(iface2->boundingRect());        
398         getScene()->setSelectedInterface(1,NULL);
399         getScene()->setSelectedInterface(2,NULL);
400         params->setEditState(Parameters::EditNoOperation);
401       }
402       else {
403         //QMessageBox::warning(NULL,"Error","Cannot connect selected interfaces", QMessageBox::Ok);
404         getScene()->setSelectedInterface(2,NULL);
405         params->setEditState(Parameters::EditStartConnection);
406       }
407     }
408   }
409   else if (mode == GroupScene::ItemEdition) {
410     currentInterface = NULL;
411     params->editState = Parameters::EditNoOperation;
412     setFlag(ItemIsMovable);
413   }
414
415   QGraphicsItem::mouseReleaseEvent(event);
416 }
417
418 void StimuliItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
419
420   QPointF pos = event->pos();
421   qreal x = pos.x();
422   qreal y = pos.y();
423   currentBorder = NoBorder;
424   int mode = getScene()->getEditionMode();
425
426   if (mode == GroupScene::AddConnection) {
427     InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
428     if (iface != NULL) {
429       params->cursorState = Parameters::CursorOnInterface;
430       setCursor(Qt::PointingHandCursor);
431     }
432     else {
433       params->cursorState = Parameters::CursorNowhere;
434       setCursor(Qt::ArrowCursor);
435     }
436   }
437   else if (mode == GroupScene::ItemEdition) {
438     int marginE = 5;
439     int marginS = 5;
440
441     InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
442     if (iface != NULL) {
443       params->cursorState = Parameters::CursorOnInterface;
444       setCursor(Qt::PointingHandCursor);
445     }
446     else if ((x>boxWidth-marginE)&&(x<boxWidth)) {
447
448       params->cursorState = Parameters::CursorOnBorder;
449
450       if ((y>boxHeight-2*marginS)&&(y<boxHeight)) {
451         currentBorder = CornerSouthEast;
452         setCursor(Qt::SizeFDiagCursor);
453       }
454       else {
455         currentBorder = BorderEast;
456         setCursor(Qt::SizeHorCursor);
457       }
458     }
459     else if ((y>boxHeight-marginS)&&(y<boxHeight)) {
460
461       params->cursorState = Parameters::CursorOnBorder;
462
463       if ((x>boxWidth-2*marginE)&&(x<boxWidth)) {
464         currentBorder = CornerSouthEast;
465         setCursor(Qt::SizeFDiagCursor);
466       }
467       else {
468         currentBorder = BorderSouth;
469         setCursor(Qt::SizeVerCursor);
470       }
471     }
472     else {
473       if ((x>0) && (x<boxWidth-marginE) && (y>0) && (y<boxHeight-marginS)) {
474         params->cursorState = Parameters::CursorInBlock;
475         setCursor(Qt::OpenHandCursor);
476       }
477       else {
478         params->cursorState = Parameters::CursorNowhere;
479         setCursor(Qt::ArrowCursor);
480       }
481     }
482   }
483   //QGraphicsItem::hoverMoveEvent(event);
484   event->ignore();
485 }
486
487
488 void StimuliItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
489
490   event->accept();
491
492   QMenu menu;
493   QAction* titleAction = NULL;
494   QAction* removeAction = NULL;
495   QAction* duplicateAction = NULL;
496   QAction* renameAction = NULL;
497   QAction* showProperties = NULL;
498   QAction* showParameters = NULL;
499   QAction* showPatterns = NULL;
500
501   InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y());
502   // menu for interface
503   if( ifaceItem != NULL){
504
505     ConnectedInterface* iface = ifaceItem->refInter;
506
507     titleAction = menu.addAction("Interface operations");
508     titleAction->setEnabled(false);
509     menu.addSeparator();
510
511
512     showProperties = menu.addAction("Show properties");
513     renameAction = menu.addAction("Rename");
514
515     if (iface->getAssociatedIface() != NULL) {
516       if (iface->getDirection() == AbstractInterface::Output) {
517         showPatterns = menu.addAction("Show output pattern");
518       }
519     }
520   }
521   // menu for block
522   else {
523     titleAction = menu.addAction("Block operations");
524     titleAction->setEnabled(false);
525     menu.addSeparator();
526
527     if (refBlock->nbParameters() > 0) {
528       showParameters = menu.addAction("Show parameters");
529     }
530     renameAction = menu.addAction("Rename");
531
532     duplicateAction = menu.addAction("Duplicate");
533     removeAction = menu.addAction("Remove");
534   }
535
536   QAction* selectedAction = NULL;
537   selectedAction = menu.exec(event->screenPos());
538
539   if(selectedAction == NULL) return ;
540
541   if (selectedAction == removeAction) {    
542     dispatcher->removeStimuliItem(Dispatcher::Design, this);
543   }
544   else if (selectedAction == duplicateAction) {
545     dispatcher->duplicateStimuliItem(Dispatcher::Design, this);
546   }
547   else if(selectedAction == renameAction){
548     if(ifaceItem != NULL) {
549       dispatcher->renameInterface(Dispatcher::Design, ifaceItem);
550     }
551     else {      
552       dispatcher->renameStimuliItem(Dispatcher::Design, this);
553     }   
554   }
555   else if(selectedAction == showProperties){
556     dispatcher->showProperties(Dispatcher::Design, ifaceItem);
557   }  
558   else if(selectedAction == showParameters){
559     new ParametersWindow(refBlock, params, NULL);
560   }      
561   else if(selectedAction == showPatterns) {
562     dispatcher->showPatterns(Dispatcher::Design, ifaceItem);
563   }
564 }
565
566 void StimuliItem::load(QDomElement funcElement) throw(Exception) {
567
568   bool ok = false;
569
570   int id = funcElement.attribute("id","none").toInt(&ok);
571   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
572
573   QString refXml = funcElement.attribute("ref_xml","none");
574   if(refXml == "none") throw(Exception(PROJECTFILE_CORRUPTED));
575
576   QString refMd5 = funcElement.attribute("ref_md5","none");
577   if(refMd5 == "none") throw(Exception(PROJECTFILE_CORRUPTED));
578
579   cout << "ref md5 : " << refMd5.toStdString() << "\nref xml : " << refXml.toStdString() << endl;
580
581   QString name = funcElement.attribute("name","none");
582   if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
583
584   QStringList positionStr = funcElement.attribute("position","none").split(",");
585   if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
586   int posX = positionStr.at(0).toInt(&ok);
587   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
588   int posY = positionStr.at(1).toInt(&ok);
589   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
590
591   QStringList dimensionStr = funcElement.attribute("dimension","none").split(",");
592   if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
593   int dimX = dimensionStr.at(0).toInt(&ok);
594   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
595   int dimY = dimensionStr.at(1).toInt(&ok);
596   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
597   
598   ReferenceBlock *referenceMd5 = NULL;
599   ReferenceBlock *referenceXml = NULL;
600   ReferenceBlock *reference = NULL;
601   if(refMd5 != "none") {
602     referenceMd5 = params->searchBlockByMd5(refMd5);
603   }
604   if(refXml != "none"){
605     referenceXml = params->searchBlockByXml(refXml);
606   }
607   if ((referenceMd5 == NULL) && (referenceXml == NULL)) {
608     throw(Exception(PROJECTFILE_CORRUPTED));
609   }
610   if (referenceMd5 != referenceXml) {
611     reference = referenceXml;
612   }
613   else {
614     reference = referenceMd5;
615   }
616     
617   FunctionalBlock* functionalBlock = params->getGraph()->createStimuliBlock(reference, false);
618   /* NB: createSourceBlock creates all interfaces from the reference, which is annoying when
619     reading bif_iface tags. Thus interface are all removed.
620   */
621   functionalBlock->setName(name);
622   setRefBlock(functionalBlock);
623
624   setPos(posX,posY);
625   setDimension(dimX,dimY);
626   setId(id);
627
628
629   QDomNodeList blockParamNodes = funcElement.elementsByTagName("source_parameter");
630   // setting parameters value
631   for(int i=0; i<blockParamNodes.length(); i++){
632     QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement();
633
634     QString name = currentBlockParamNode.attribute("name","none");
635     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
636
637     QString value = currentBlockParamNode.attribute("value","none");
638     if(value == "none") throw(Exception(PROJECTFILE_CORRUPTED));
639
640     BlockParameter *blockParam = NULL;
641     blockParam = functionalBlock->getParameterFromName(name);
642     if (blockParam == NULL) throw(Exception(PROJECTFILE_CORRUPTED));
643     blockParam->setValue(value);    
644   }  
645
646   // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars
647   //functionalBlock->removeAllInterfaces();
648   QDomNodeList interfaceNodes = funcElement.elementsByTagName("source_iface");
649   // setting interfaces (user name, and for multiplicity>1 may be create some new ones)
650   for(int i=0; i<interfaceNodes.length(); i++) {
651
652     QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
653
654     QString name = currentInterfaceNode.attribute("name","none");
655     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
656
657     QString refName = currentInterfaceNode.attribute("ref_name","none");
658     if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));
659
660     ReferenceInterface* refInter = AI_TO_REF(reference->getIfaceFromName(refName));
661     cout << "creating iface from reference named " << qPrintable(refName) << endl;
662     FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter);
663     functionalInterface->setName(name);
664     functionalBlock->addInterface(functionalInterface);
665     
666     // searching for control interface
667     QString ctlRefName = refName+"_enb";
668     ReferenceInterface* ctlRefIface = AI_TO_REF(reference->getIfaceFromName(ctlRefName));
669     
670     if (ctlRefIface != NULL) {
671       cout << "found a control iface:" << qPrintable(ctlRefName) << endl;
672       FunctionalInterface *ctlIface = new FunctionalInterface(functionalBlock,ctlRefIface);      
673       if (! ctlIface->setAssociatedIface(functionalInterface)) {
674         throw(Exception(PROJECTFILE_CORRUPTED));
675       }      
676       ctlIface->setName(name+"_enb");
677       functionalBlock->addInterface(ctlIface);
678     }    
679   }
680   
681   // creating InterfaceItem
682   createInterfaceItems();
683   // setting them with saved values
684   for(int i=0; i<interfaceNodes.length(); i++){
685
686     QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
687
688     int id = currentInterfaceNode.attribute("id","none").toInt(&ok);
689     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
690
691     QString name = currentInterfaceNode.attribute("name","none");
692     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
693
694     QString orientationStr = currentInterfaceNode.attribute("orientation","none");
695     int orientation = InterfaceItem::getIntOrientation(orientationStr);
696     if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));
697
698     double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);
699     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
700
701     InterfaceItem *interfaceItem = searchInterfaceItemByName(name);
702     interfaceItem->setId(id);
703     interfaceItem->setOrientation(orientation);
704     interfaceItem->setPositionRatio(position);
705   }
706   updateGeometry(Resize);
707 }
708
709 void StimuliItem::save(QXmlStreamWriter &writer) {
710   
711   writer.writeStartElement("source_item");
712   
713   writer.writeAttribute("id",QString::number(id));
714   writer.writeAttribute("ref_xml", ((FunctionalBlock*)refBlock)->getReferenceXmlFile());
715   writer.writeAttribute("ref_md5", ((FunctionalBlock*)refBlock)->getReferenceHashMd5());
716   writer.writeAttribute("name",refBlock->getName());
717   QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
718   writer.writeAttribute("position",attrPos);
719   QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
720   writer.writeAttribute("dimension",attrDim);
721   
722   writer.writeStartElement("source_parameters");
723   foreach(BlockParameter *param,refBlock->getParameters()){
724     writer.writeStartElement("source_parameter");
725     
726     writer.writeAttribute("name",param->getName());
727     writer.writeAttribute("value",param->getValue().toString());
728     /*
729       writer.writeAttribute("context",param->getStrContext());
730       writer.writeAttribute("type",param->getTypeString());
731       */
732     writer.writeEndElement();   //</source_parameter>
733   }
734   writer.writeEndElement();   //</source_parameters>
735   
736   writer.writeStartElement("source_ifaces");
737   writer.writeAttribute("count",QString::number(interfaces.length()));
738   foreach(InterfaceItem* inter, interfaces){
739     writer.writeStartElement("source_iface");
740     
741     writer.writeAttribute("id",QString::number(inter->getId()));
742     writer.writeAttribute("name",inter->getName());
743     writer.writeAttribute("ref_name",inter->refInter->getName());
744     writer.writeAttribute("orientation",inter->getStrOrientation());
745     writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
746     
747     writer.writeEndElement();   //</source_iface>
748   }
749   writer.writeEndElement();   //</source_ifaces>
750   
751   writer.writeEndElement();   //</source_item>
752   
753 }