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

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