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

Private GIT Repository
patter compat continued
[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   initInterfaceItems();
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 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   cout << "source minimum size = " << minimumBoxWidth << "x" << minimumBoxHeight << endl;
146 }
147
148
149 /* updateGeometry() :
150
151  */
152 bool SourceItem::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 SourceItem::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 SourceItem::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(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 SourceItem::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(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 SourceItem::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 SourceItem::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
500
501   InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y());
502   // menu for interface
503   if( ifaceItem != NULL){
504
505     titleAction = menu.addAction("Interface operations");
506     titleAction->setEnabled(false);
507     menu.addSeparator();
508
509
510     showProperties = menu.addAction("Show properties");
511     renameAction = menu.addAction("Rename");
512
513   }
514   // menu for block
515   else {
516     titleAction = menu.addAction("Block operations");
517     titleAction->setEnabled(false);
518     menu.addSeparator();
519
520     if (refBlock->nbParameters() > 0) {
521       showParameters = menu.addAction("Show parameters");
522     }
523     renameAction = menu.addAction("Rename");
524
525     duplicateAction = menu.addAction("Duplicate");
526     removeAction = menu.addAction("Remove");
527   }
528
529   QAction* selectedAction = NULL;
530   selectedAction = menu.exec(event->screenPos());
531
532   if(selectedAction == NULL) return ;
533
534   if (selectedAction == removeAction) {    
535     dispatcher->removeSourceItem(this);    
536   }
537   else if (selectedAction == duplicateAction) {
538     dispatcher->duplicateSourceItem(this);
539   }
540   else if(selectedAction == renameAction){
541     if(ifaceItem != NULL) {
542       dispatcher->renameInterface(ifaceItem);
543     }
544     else {      
545       dispatcher->renameSourceBlock(this);      
546     }   
547   }
548   else if(selectedAction == showProperties){
549     dispatcher->showProperties(ifaceItem);
550   }  
551   else if(selectedAction == showParameters){
552     new ParametersWindow(refBlock, params, NULL);
553   }      
554 }
555
556 void SourceItem::load(QDomElement funcElement) throw(Exception) {
557
558   bool ok = false;
559
560   int id = funcElement.attribute("id","none").toInt(&ok);
561   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
562
563   QString refXml = funcElement.attribute("ref_xml","none");
564   if(refXml == "none") throw(Exception(PROJECTFILE_CORRUPTED));
565
566   QString refMd5 = funcElement.attribute("ref_md5","none");
567   if(refMd5 == "none") throw(Exception(PROJECTFILE_CORRUPTED));
568
569   cout << "ref md5 : " << refMd5.toStdString() << "\nref xml : " << refXml.toStdString() << endl;
570
571   QString name = funcElement.attribute("name","none");
572   if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
573
574   QStringList positionStr = funcElement.attribute("position","none").split(",");
575   if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
576   int posX = positionStr.at(0).toInt(&ok);
577   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
578   int posY = positionStr.at(1).toInt(&ok);
579   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
580
581   QStringList dimensionStr = funcElement.attribute("dimension","none").split(",");
582   if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
583   int dimX = dimensionStr.at(0).toInt(&ok);
584   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
585   int dimY = dimensionStr.at(1).toInt(&ok);
586   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
587   
588   ReferenceBlock *referenceMd5 = NULL;
589   ReferenceBlock *referenceXml = NULL;
590   ReferenceBlock *reference = NULL;
591   if(refMd5 != "none") {
592     referenceMd5 = params->searchBlockByMd5(refMd5);
593   }
594   if(refXml != "none"){
595     referenceXml = params->searchBlockByXml(refXml);
596   }
597   if ((referenceMd5 == NULL) && (referenceXml == NULL)) {
598     throw(Exception(PROJECTFILE_CORRUPTED));
599   }
600   if (referenceMd5 != referenceXml) {
601     throw(Exception(PROJECTFILE_CORRUPTED));
602   }
603   else {
604     reference = referenceMd5;
605   }
606     
607   FunctionalBlock* functionalBlock = params->getGraph()->createSourceBlock(reference);
608   /* NB: createSourceBlock creates all interfaces from the reference, which is annoying when
609     reading bif_iface tags. Thus interface are all removed.
610   */
611   functionalBlock->setName(name);
612   setRefBlock(functionalBlock);
613
614   setPos(posX,posY);
615   setDimension(dimX,dimY);
616   setId(id);
617
618
619   QDomNodeList blockParamNodes = funcElement.elementsByTagName("source_parameter");
620   // setting parameters value
621   for(int i=0; i<blockParamNodes.length(); i++){
622     QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement();
623
624     QString name = currentBlockParamNode.attribute("name","none");
625     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
626
627     QString value = currentBlockParamNode.attribute("value","none");
628     if(value == "none") throw(Exception(PROJECTFILE_CORRUPTED));
629
630     BlockParameter *blockParam = NULL;
631     blockParam = functionalBlock->getParameterFromName(name);
632     if (blockParam == NULL) throw(Exception(PROJECTFILE_CORRUPTED));
633     blockParam->setValue(value);
634   }  
635
636   // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars
637   functionalBlock->removeAllInterfaces();
638   QDomNodeList interfaceNodes = funcElement.elementsByTagName("source_iface");
639   // setting interfaces (user name, and for multiplicity>1 may be create some new ones)
640   for(int i=0; i<interfaceNodes.length(); i++) {
641
642     QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
643
644     QString name = currentInterfaceNode.attribute("name","none");
645     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
646
647     QString refName = currentInterfaceNode.attribute("ref_name","none");
648     if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));
649
650     ReferenceInterface* refInter = AI_TO_REF(reference->getIfaceFromName(refName));
651     cout << "creating iface from reference named " << qPrintable(refName) << endl;
652     FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter);
653     functionalInterface->setName(name);
654     functionalBlock->addInterface(functionalInterface);
655     
656     // searching for control interface
657     QString ctlRefName = refName+"_enb";
658     ReferenceInterface* ctlRefIface = AI_TO_REF(reference->getIfaceFromName(ctlRefName));
659     
660     if (ctlRefIface != NULL) {
661       cout << "found a control iface:" << qPrintable(ctlRefName) << endl;
662       FunctionalInterface *ctlIface = new FunctionalInterface(functionalBlock,ctlRefIface);      
663       if (! ctlIface->setAssociatedIface(functionalInterface)) {
664         throw(Exception(PROJECTFILE_CORRUPTED));
665       }      
666       ctlIface->setName(name+"_enb");
667       functionalBlock->addInterface(ctlIface);
668     }    
669   }
670   
671   // creating InterfaceItem
672   initInterfaceItems();
673   // setting them with saved values
674   for(int i=0; i<interfaceNodes.length(); i++){
675
676     QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
677
678     int id = currentInterfaceNode.attribute("id","none").toInt(&ok);
679     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
680
681     QString name = currentInterfaceNode.attribute("name","none");
682     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
683
684     QString orientationStr = currentInterfaceNode.attribute("orientation","none");
685     int orientation = InterfaceItem::getIntOrientation(orientationStr);
686     if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));
687
688     double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);
689     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
690
691     InterfaceItem *interfaceItem = searchInterfaceItemByName(name);
692     interfaceItem->setId(id);
693     interfaceItem->setOrientation(orientation);
694     interfaceItem->setPositionRatio(position);
695   }
696   updateGeometry(Resize);
697 }
698
699 void SourceItem::save(QXmlStreamWriter &writer) {
700   
701   writer.writeStartElement("source_item");
702   
703   writer.writeAttribute("id",QString::number(id));
704   writer.writeAttribute("ref_xml", ((FunctionalBlock*)refBlock)->getReferenceXmlFile());
705   writer.writeAttribute("ref_md5", ((FunctionalBlock*)refBlock)->getReferenceHashMd5());
706   writer.writeAttribute("name",refBlock->getName());
707   QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
708   writer.writeAttribute("position",attrPos);
709   QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
710   writer.writeAttribute("dimension",attrDim);
711   
712   writer.writeStartElement("source_parameters");
713   foreach(BlockParameter *param,refBlock->getParameters()){
714     writer.writeStartElement("source_parameter");
715     
716     writer.writeAttribute("name",param->getName());
717     writer.writeAttribute("value",param->getValue().toString());
718     /*
719       writer.writeAttribute("context",param->getStrContext());
720       writer.writeAttribute("type",param->getTypeString());
721       */
722     writer.writeEndElement();   //</source_parameter>
723   }
724   writer.writeEndElement();   //</source_parameters>
725   
726   writer.writeStartElement("source_ifaces");
727   writer.writeAttribute("count",QString::number(interfaces.length()));
728   foreach(InterfaceItem* inter, interfaces){
729     writer.writeStartElement("source_iface");
730     
731     writer.writeAttribute("id",QString::number(inter->getId()));
732     writer.writeAttribute("name",inter->getName());
733     writer.writeAttribute("ref_name",inter->refInter->getName());
734     writer.writeAttribute("orientation",inter->getStrOrientation());
735     writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
736     
737     writer.writeEndElement();   //</source_iface>
738   }
739   writer.writeEndElement();   //</source_ifaces>
740   
741   writer.writeEndElement();   //</source_item>
742   
743 }