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

Private GIT Repository
82a41b08cea3b5528fd38ea3165b3ae3edfedf96
[blast.git] / SourceItem.cpp
1 #include "SourceItem.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 SourceItem::SourceItem(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   initInterfaces();
34   updateGeometry(InterfaceMove);
35   resetInterfacesPosition();
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 SourceItem::SourceItem(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 SourceItem::~SourceItem() {
56 }
57
58 void SourceItem::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 SourceItem::moveTo(QPointF dest) {
75   setPos(dest);
76   currentPosition = dest;
77 }
78
79 bool SourceItem::isSourceItem() {
80   return true;
81 }
82
83 void SourceItem::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 SourceItem::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 }
146
147
148 /* updateGeometry() :
149
150  */
151 bool SourceItem::updateGeometry(ChangeType type) {
152
153   currentPosition = pos();
154   //cout << "current pos of block: " << currentPosition.x() << "," << currentPosition.y() << endl;
155   QPointF oldOrigin = originPoint;
156   QSize oldSize(totalWidth,totalHeight);
157
158   bool boxSizeChanged = false;
159
160   // whatever the change, the minimum size may have changed
161   updateMinimumSize();
162
163   if (type == Resize) {
164     // resize implies to move interfaces and to update connections
165     boxSizeChanged = true;
166   }
167   else if (type == InterfaceMove) {
168     // if an interface moves, it may change the box size
169     if (boxWidth < minimumBoxWidth) {
170       boxWidth = minimumBoxWidth;
171       boxSizeChanged = true;
172     }
173     if (boxHeight < minimumBoxHeight) {
174       boxHeight = minimumBoxHeight;
175       boxSizeChanged = true;
176     }
177   }
178   if (boxSizeChanged) {
179     updateInterfacesAndConnections();
180   }
181
182
183   double x = 0.0;
184   double y = 0.0;
185   totalWidth = boxWidth;
186   totalHeight = boxHeight;
187
188   if(isInterfaces(Parameters::East)){
189     totalWidth += params->arrowWidth+params->arrowLineLength;
190   }
191   if(isInterfaces(Parameters::West)){
192     totalWidth += params->arrowWidth+params->arrowLineLength;
193     x -= params->arrowWidth+params->arrowLineLength;
194   }
195   if(isInterfaces(Parameters::South)){
196     totalHeight += params->arrowWidth+params->arrowLineLength;
197   }
198   if(isInterfaces(Parameters::North)){
199     totalHeight += params->arrowWidth+params->arrowLineLength;
200     y -= params->arrowWidth+params->arrowLineLength;
201   }
202   QSizeF newSize(totalWidth,totalHeight);
203   originPoint.setX(x);
204   originPoint.setY(y);
205
206   if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
207     prepareGeometryChange();
208     return true;
209   }
210   return false;
211 }
212
213 void SourceItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
214
215   if(params->editState == Parameters::EditBlockMove) {
216     QPointF absPos = currentPosition + originPoint;
217     
218     int gapX = event->scenePos().x() - cursorPosition.x();
219     int gapY = event->scenePos().y() - cursorPosition.y();
220
221     //cout << "block abs. pos: " << absPos.x() << "," << absPos.y() << " | ";
222     //cout << "block current. pos: " << currentPosition.x() << "," << currentPosition.y() << " | ";
223
224     /*
225     if (absPos.x()+gapX < marginConn) {
226       gapX = marginConn-absPos.x();
227     }
228     if (absPos.y()+gapY < marginConn) {
229       gapY = marginConn-absPos.y();
230     }
231     */
232     //cout << "gap: " << gapX << "," << gapY << endl;
233     QPointF gap(gapX,gapY);
234     currentPosition = currentPosition+gap;
235     setPos(currentPosition);
236     // update all connections from/to this block
237     foreach(ConnectionItem *item, getScene()->getConnectionItems()){
238       if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
239         item->setPath();
240       }
241     }
242     cursorPosition = event->scenePos();
243
244     // udpate the groupitem
245     (getScene()->getGroupItem())->updateShape();
246   }
247   else if(params->editState == Parameters::EditBlockResize) {
248
249     int gapX = event->scenePos().x() - cursorPosition.x();
250     int gapY = event->scenePos().y() - cursorPosition.y();
251     //cout << "gap: " << gapX << "," << gapY << endl;
252     switch(currentBorder){
253     case BorderEast: {    
254       if(boxWidth+gapX > minimumBoxWidth){
255         boxWidth += gapX;
256       }
257       break;
258     }
259     case BorderSouth: {      
260       if(boxHeight+gapY > minimumBoxHeight){
261         boxHeight += gapY;
262       }
263       break;
264     }
265     case CornerSouthEast: {
266       if(boxWidth+gapX > minimumBoxWidth){
267         boxWidth += gapX;
268       }
269       if(boxHeight+gapY > minimumBoxHeight){
270         boxHeight += gapY;
271       }
272       break;
273     }
274     case NoBorder:
275       cout << "abnormal case while resizing block" << endl;
276       break;
277     }
278     // recompute the geometry of the block and possibly the group item
279     if (updateGeometry(Resize)) {
280       (getScene()->getGroupItem())->updateShape();
281     }
282
283     cursorPosition = event->scenePos();   
284   }
285   else if(params->editState == Parameters::EditInterfaceMove) {
286     prepareGeometryChange();
287     moveInterfaceTo(event->pos());
288     // recompute the geometry of the block
289     if (updateGeometry(InterfaceMove)) {
290       //cout << "must recompute group item geometry" << endl;
291       (getScene()->getGroupItem())->updateShape();
292     }
293     // update connection from/to the selected interface
294     foreach(ConnectionItem *item, getScene()->getConnectionItems()){
295       if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
296         item->setPath();
297       }
298     }    
299   }
300 }
301
302 void SourceItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
303
304   QPointF pos = event->pos();
305   qreal x = pos.x();
306   qreal y = pos.y();
307
308   //QGraphicsItem::mousePressEvent(event);
309
310   if(event->button() == Qt::RightButton) return;
311
312   int mode = getScene()->getEditionMode();
313
314   dispatcher->setCurrentGroupWidget(getScene()->getGroupWidget());
315
316   if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) {
317     InterfaceItem *inter = getInterfaceFromCursor(x,y);
318     if (inter != NULL) {
319
320       if (params->editState == Parameters::EditNoOperation) {
321         getScene()->setSelectedInterface(1,inter);
322         params->setEditState(Parameters::EditStartConnection);
323       }
324       else if (params->editState == Parameters::EditStartConnection) {
325         if (inter == getScene()->getSelectedInterface(1)) {
326           params->setEditState(Parameters::EditAbortConnection);
327         }
328         else {
329           getScene()->setSelectedInterface(2,inter);
330           params->setEditState(Parameters::EditCloseConnection);
331         }
332       }
333     }
334   }
335   else if (mode == GroupScene::ItemEdition) {
336     setZValue(zValue()+100);
337     if (params->cursorState == Parameters::CursorOnInterface) {
338       InterfaceItem *inter = getInterfaceFromCursor(x,y);
339       if (inter != NULL) {
340         if (inter == currentInterface) {
341            params->setEditState(Parameters::EditInterfaceDeselect);
342         }
343         else {
344           setFlag(ItemIsMovable, false);
345           currentInterface = inter;
346           params->setEditState(Parameters::EditInterfaceMove);
347         }
348       }
349     }
350     else if (params->cursorState == Parameters::CursorInBlock) {
351       selected = !selected;
352       params->setEditState(Parameters::EditBlockMove);
353       cursorPosition = event->scenePos();
354       //cout << "cursor current pos. in scene " << cursorPosition.x() << "," << cursorPosition.y() << endl;
355       update();
356     }
357     else if (params->cursorState == Parameters::CursorOnBorder) {
358       setFlag(ItemIsMovable, false);
359       cursorPosition = event->scenePos();
360       params->setEditState(Parameters::EditBlockResize);
361     }
362   }
363 }
364
365 void SourceItem::mouseReleaseEvent(QGraphicsSceneMouseEvent  *event) {
366
367   setZValue(zValue()-100);
368
369   int mode = getScene()->getEditionMode();
370
371   if (mode == GroupScene::AddConnection) {
372
373     if (params->editState == Parameters::EditStartConnection) {
374       InterfaceItem* iface = getScene()->getSelectedInterface(1);
375       iface->selected = true;
376       update(iface->boundingRect());
377     }
378     else if (params->editState == Parameters::EditAbortConnection) {
379       InterfaceItem* iface = getScene()->getSelectedInterface(1);
380       iface->selected = false;
381       update(iface->boundingRect());
382       getScene()->setSelectedInterface(1,NULL);
383       params->setEditState(Parameters::EditNoOperation);
384     }
385     else if (params->editState == Parameters::EditCloseConnection) {
386       InterfaceItem* iface1 = getScene()->getSelectedInterface(1);
387       InterfaceItem* iface2 = getScene()->getSelectedInterface(2);
388       bool ok = dispatcher->createConnectionItem(iface1,iface2);
389       if (ok) {
390         iface1->selected = false;
391         // no update needed since the whole scene will be repainted
392         getScene()->setSelectedInterface(1,NULL);
393         getScene()->setSelectedInterface(2,NULL);
394         params->setEditState(Parameters::EditNoOperation);
395       }
396       else {
397         //QMessageBox::warning(NULL,"Error","Cannot connect selected interfaces", QMessageBox::Ok);
398         getScene()->setSelectedInterface(2,NULL);
399         params->setEditState(Parameters::EditStartConnection);
400       }
401     }
402   }
403   else if (mode == GroupScene::ItemEdition) {
404     currentInterface = NULL;
405     params->editState = Parameters::EditNoOperation;
406     setFlag(ItemIsMovable);
407   }
408
409   QGraphicsItem::mouseReleaseEvent(event);
410 }
411
412 void SourceItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
413
414   QPointF pos = event->pos();
415   qreal x = pos.x();
416   qreal y = pos.y();
417   currentBorder = NoBorder;
418   int mode = getScene()->getEditionMode();
419
420   if (mode == GroupScene::AddConnection) {
421     InterfaceItem* iface = getInterfaceFromCursor(x,y);
422     if (iface != NULL) {
423       params->cursorState = Parameters::CursorOnInterface;
424       setCursor(Qt::PointingHandCursor);
425     }
426     else {
427       params->cursorState = Parameters::CursorNowhere;
428       setCursor(Qt::ArrowCursor);
429     }
430   }
431   else if (mode == GroupScene::ItemEdition) {
432     int marginE = 5;
433     int marginS = 5;
434
435     InterfaceItem* iface = getInterfaceFromCursor(x,y);
436     if (iface != NULL) {
437       params->cursorState = Parameters::CursorOnInterface;
438       setCursor(Qt::PointingHandCursor);
439     }
440     else if ((x>boxWidth-marginE)&&(x<boxWidth)) {
441
442       params->cursorState = Parameters::CursorOnBorder;
443
444       if ((y>boxHeight-2*marginS)&&(y<boxHeight)) {
445         currentBorder = CornerSouthEast;
446         setCursor(Qt::SizeFDiagCursor);
447       }
448       else {
449         currentBorder = BorderEast;
450         setCursor(Qt::SizeHorCursor);
451       }
452     }
453     else if ((y>boxHeight-marginS)&&(y<boxHeight)) {
454
455       params->cursorState = Parameters::CursorOnBorder;
456
457       if ((x>boxWidth-2*marginE)&&(x<boxWidth)) {
458         currentBorder = CornerSouthEast;
459         setCursor(Qt::SizeFDiagCursor);
460       }
461       else {
462         currentBorder = BorderSouth;
463         setCursor(Qt::SizeVerCursor);
464       }
465     }
466     else {
467       if ((x>0) && (x<boxWidth-marginE) && (y>0) && (y<boxHeight-marginS)) {
468         params->cursorState = Parameters::CursorInBlock;
469         setCursor(Qt::OpenHandCursor);
470       }
471       else {
472         params->cursorState = Parameters::CursorNowhere;
473         setCursor(Qt::ArrowCursor);
474       }
475     }
476   }
477   QGraphicsItem::hoverMoveEvent(event);
478 }
479
480
481 void SourceItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
482
483   event->accept();
484
485   QMenu menu;
486   QAction* titleAction = NULL;
487   QAction* removeAction = NULL;
488   QAction* duplicateAction = NULL;
489   QAction* renameAction = NULL;
490   QAction* showProperties = NULL;
491   QAction* showParameters = NULL;
492
493
494   InterfaceItem* ifaceItem = getInterfaceFromCursor(event->pos().x(), event->pos().y());
495   // menu for interface
496   if( ifaceItem != NULL){
497
498     titleAction = menu.addAction("Interface operations");
499     titleAction->setEnabled(false);
500     menu.addSeparator();
501
502
503     showProperties = menu.addAction("Show properties");
504     renameAction = menu.addAction("Rename");
505
506   }
507   // menu for block
508   else {
509     titleAction = menu.addAction("Block operations");
510     titleAction->setEnabled(false);
511     menu.addSeparator();
512
513     if (refBlock->nbParameters() > 0) {
514       showParameters = menu.addAction("Show parameters");
515     }
516     renameAction = menu.addAction("Rename");
517
518     duplicateAction = menu.addAction("Duplicate");
519     removeAction = menu.addAction("Remove");
520   }
521
522   QAction* selectedAction = NULL;
523   selectedAction = menu.exec(event->screenPos());
524
525   if(selectedAction == NULL) return ;
526
527   if (selectedAction == removeAction) {    
528     dispatcher->removeSourceItem(this);    
529   }
530   else if (selectedAction == duplicateAction) {
531     dispatcher->duplicateSourceItem(this);
532   }
533   else if(selectedAction == renameAction){
534     if(ifaceItem != NULL) {
535       dispatcher->renameInterface(ifaceItem);
536     }
537     else {      
538       dispatcher->renameSourceBlock(this);      
539     }   
540   }
541   else if(selectedAction == showProperties){
542     dispatcher->showProperties(ifaceItem);
543   }  
544   else if(selectedAction == showParameters){
545     new ParametersWindow(refBlock, params, NULL);
546   }      
547 }
548
549 void SourceItem::load(QDomElement funcElement) throw(Exception) {
550
551   bool ok = false;
552
553   int id = funcElement.attribute("id","none").toInt(&ok);
554   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
555
556   QString refXml = funcElement.attribute("ref_xml","none");
557   if(refXml == "none") throw(Exception(PROJECTFILE_CORRUPTED));
558
559   QString refMd5 = funcElement.attribute("ref_md5","none");
560   if(refMd5 == "none") throw(Exception(PROJECTFILE_CORRUPTED));
561
562   cout << "ref md5 : " << refMd5.toStdString() << "\nref xml : " << refXml.toStdString() << endl;
563
564   QString name = funcElement.attribute("name","none");
565   if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
566
567   QStringList positionStr = funcElement.attribute("position","none").split(",");
568   if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
569   int posX = positionStr.at(0).toInt(&ok);
570   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
571   int posY = positionStr.at(1).toInt(&ok);
572   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
573
574   QStringList dimensionStr = funcElement.attribute("dimension","none").split(",");
575   if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
576   int dimX = dimensionStr.at(0).toInt(&ok);
577   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
578   int dimY = dimensionStr.at(1).toInt(&ok);
579   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
580   
581   ReferenceBlock *referenceMd5 = NULL;
582   ReferenceBlock *referenceXml = NULL;
583   ReferenceBlock *reference = NULL;
584   if(refMd5 != "none") {
585     referenceMd5 = params->searchBlockByMd5(refMd5);
586   }
587   if(refXml != "none"){
588     referenceXml = params->searchBlockByXml(refXml);
589   }
590   if ((referenceMd5 == NULL) && (referenceXml == NULL)) {
591     throw(Exception(PROJECTFILE_CORRUPTED));
592   }
593   if (referenceMd5 != referenceXml) {
594     throw(Exception(PROJECTFILE_CORRUPTED));
595   }
596   else {
597     reference = referenceMd5;
598   }
599   
600   GroupBlock* parentGroupBlock = AB_TO_GRP(((GroupItem *)parentItem())->getRefBlock());
601   FunctionalBlock* functionalBlock = params->getGraph()->createFunctionalBlock(parentGroupBlock, reference);
602   /* NB: addFunctionalBlock creates all interfaces from the reference, which is annoying when
603     reading bif_iface tags. Thus interface are all removed.
604   */
605   functionalBlock->setName(name);
606   setRefBlock(functionalBlock);
607
608   setPos(posX,posY);
609   setDimension(dimX,dimY);
610   setId(id);
611
612
613   QDomNodeList blockParamNodes = funcElement.elementsByTagName("bif_parameter");
614   // setting parameters value
615   for(int i=0; i<blockParamNodes.length(); i++){
616     QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement();
617
618     QString name = currentBlockParamNode.attribute("name","none");
619     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
620
621     QString value = currentBlockParamNode.attribute("value","none");
622     if(value == "none") throw(Exception(PROJECTFILE_CORRUPTED));
623
624     BlockParameter *blockParam = NULL;
625     blockParam = functionalBlock->getParameterFromName(name);
626     if (blockParam == NULL) throw(Exception(PROJECTFILE_CORRUPTED));
627     blockParam->setValue(value);
628   }  
629
630   // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars
631   functionalBlock->removeAllInterfaces();
632   QDomNodeList interfaceNodes = funcElement.elementsByTagName("bif_iface");
633   // setting interfaces (user name, and for multiplicity>1 may be create some new ones)
634   for(int i=0; i<interfaceNodes.length(); i++) {
635
636     QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
637
638     QString name = currentInterfaceNode.attribute("name","none");
639     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
640
641     QString refName = currentInterfaceNode.attribute("ref_name","none");
642     if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));
643
644     ReferenceInterface* refInter = AI_TO_REF(reference->getIfaceFromName(refName));
645     cout << "creating iface from reference named " << qPrintable(refName) << endl;
646     FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter);
647     functionalInterface->setName(name);
648     functionalBlock->addInterface(functionalInterface);
649     
650     // searching for control interface
651     QString ctlRefName = refName+"_ctl";
652     ReferenceInterface* ctlRefIface = AI_TO_REF(reference->getIfaceFromName(ctlRefName));
653     
654     if (ctlRefIface != NULL) {
655       cout << "found a control iface:" << qPrintable(ctlRefName) << endl;
656       FunctionalInterface *ctlIface = new FunctionalInterface(functionalBlock,ctlRefIface);      
657       if (! ctlIface->setAssociatedIface(functionalInterface)) {
658         throw(Exception(PROJECTFILE_CORRUPTED));
659       }      
660       ctlIface->setName(name+"_ctl");
661       functionalBlock->addInterface(ctlIface);
662     }    
663   }
664   
665   // creating InterfaceItem
666   initInterfaces();
667   // setting them with saved values
668   for(int i=0; i<interfaceNodes.length(); i++){
669
670     QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
671
672     int id = currentInterfaceNode.attribute("id","none").toInt(&ok);
673     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
674
675     QString name = currentInterfaceNode.attribute("name","none");
676     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
677
678     QString orientationStr = currentInterfaceNode.attribute("orientation","none");
679     int orientation = InterfaceItem::getIntOrientation(orientationStr);
680     if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));
681
682     double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);
683     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
684
685     InterfaceItem *interfaceItem = searchInterfaceByName(name);
686     interfaceItem->setId(id);
687     interfaceItem->setOrientation(orientation);
688     interfaceItem->setPositionRatio(position);
689   }
690   updateGeometry(Resize);
691 }
692
693 void SourceItem::save(QXmlStreamWriter &writer) {
694   
695   writer.writeStartElement("source_item");
696   
697   writer.writeAttribute("id",QString::number(id));
698   writer.writeAttribute("ref_xml", ((FunctionalBlock*)refBlock)->getReferenceXmlFile());
699   writer.writeAttribute("ref_md5", ((FunctionalBlock*)refBlock)->getReferenceHashMd5());
700   writer.writeAttribute("name",refBlock->getName());
701   QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
702   writer.writeAttribute("position",attrPos);
703   QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
704   writer.writeAttribute("dimension",attrDim);
705   
706   writer.writeStartElement("source_parameters");
707   foreach(BlockParameter *param,refBlock->getParameters()){
708     writer.writeStartElement("source_parameter");
709     
710     writer.writeAttribute("name",param->getName());
711     writer.writeAttribute("value",param->getValue().toString());
712     /*
713       writer.writeAttribute("context",param->getStrContext());
714       writer.writeAttribute("type",param->getTypeString());
715       */
716     writer.writeEndElement();   //</source_parameter>
717   }
718   writer.writeEndElement();   //</source_parameters>
719   
720   writer.writeStartElement("source_ifaces");
721   writer.writeAttribute("count",QString::number(interfaces.length()));
722   foreach(InterfaceItem* inter, interfaces){
723     writer.writeStartElement("source_iface");
724     
725     writer.writeAttribute("id",QString::number(inter->getId()));
726     writer.writeAttribute("name",inter->getName());
727     writer.writeAttribute("ref_name",inter->refInter->getName());
728     writer.writeAttribute("orientation",inter->getStrOrientation());
729     writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
730     
731     writer.writeEndElement();   //</source_iface>
732   }
733   writer.writeEndElement();   //</source_ifaces>
734   
735   writer.writeEndElement();   //</source_item>
736   
737 }