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

Private GIT Repository
finished VHDL gen. (but have to test further
[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 #include "Graph.h"
16
17
18 BoxItem::BoxItem(AbstractBlock *_refBlock,
19                      Dispatcher *_dispatcher,
20                      Parameters *_params, GroupItem *parent) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params, parent) {
21
22   /*  NOTE :
23      _refBlock : mandatory a FunctionalBlock or a GroupBlock
24   */
25   if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
26
27   childGroupItem = NULL;
28   //boxWidth = params->defaultBlockWidth;
29   //boxHeight = params->defaultBlockHeight;
30   currentBorder = NoBorder;
31   selected = false;
32
33   setZValue(100);
34   setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
35
36   initInterfaceItems();
37   updateGeometry(InterfaceMove);
38   resetInterfaceItemsPosition();
39   QPointF initPos = QPointF(0.0,0.0) - originPoint;
40   setPos(initPos);
41   //cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
42   //cout << "pos in group: " << x() << "," << y() << endl;
43 }
44
45 BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent) throw(Exception) : AbstractBoxItem(_dispatcher, _params, parent) {
46
47   refBlock = NULL;
48   childGroupItem = NULL;
49   currentBorder = NoBorder;
50   selected = false;
51
52   setZValue(100);
53   setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
54
55   boxWidth = params->defaultBlockWidth;
56   boxHeight = params->defaultBlockHeight;
57   //initInterfaces();
58   //updateGeometry(InterfaceMove);
59   //resetInterfacesPosition();
60   //QPointF initPos = QPointF(0.0,0.0) - originPoint;
61   //setPos(initPos);
62   //cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
63   //cout << "pos in group: " << x() << "," << y() << endl;
64 }
65
66 BoxItem::~BoxItem() {
67 }
68
69 void BoxItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
70   QPen pen(Qt::black, 3);
71   if(selected)
72     pen.setColor(Qt::red);
73
74   painter->setPen(pen);
75   painter->setBrush(Qt::yellow);
76
77   painter->drawRect(0,0,boxWidth, boxHeight);
78   painter->drawText(0,0,boxWidth, boxHeight,Qt::AlignCenter | Qt::TextWordWrap,QString(refBlock->getName()));
79   foreach(InterfaceItem *inter, interfaces) {
80     inter->paint(painter);
81   }
82 }
83
84 void BoxItem::moveTo(QPointF dest) {
85   setPos(dest);
86   currentPosition = dest;
87 }
88
89 bool BoxItem::isBoxItem() {
90   return true;
91 }
92
93 void BoxItem::updateMinimumSize() {
94
95   int maxSouth = 0;
96   int maxNorth = 0;
97   int maxEast = 0;
98   int maxWest = 0;
99   int nbSouth = nbInterfacesByOrientation(Parameters::South);
100   int nbNorth = nbInterfacesByOrientation(Parameters::North);
101   int nbMaxSN = nbNorth;
102   if (nbSouth > nbNorth) nbMaxSN = nbSouth;
103   int nbEast = nbInterfacesByOrientation(Parameters::East);
104   int nbWest = nbInterfacesByOrientation(Parameters::West);
105   int nbMaxEW = nbEast;
106   if (nbWest > nbEast) {
107     nbMaxEW = nbWest;
108   }
109
110   int ifaceWidth = 0;
111   int ifaceHeight = 0;
112
113   foreach(InterfaceItem* iface, interfaces) {
114     ifaceWidth = iface->getNameWidth();
115     ifaceHeight = iface->getNameHeight();
116     if (iface->getOrientation() == Parameters::South) {
117       if (ifaceWidth > maxSouth) maxSouth = ifaceWidth;
118     }
119     else if (iface->getOrientation() == Parameters::North) {
120       if (ifaceWidth > maxNorth) maxNorth = ifaceWidth;
121     }
122     else if (iface->getOrientation() == Parameters::East) {
123       if (ifaceWidth > maxEast) maxEast = ifaceWidth;
124     }
125     else if (iface->getOrientation() == Parameters::West) {
126       if (ifaceWidth > maxWest) maxWest = ifaceWidth;
127     }
128   }
129
130   /* NB: the width layout is the following
131      ifaceMargin | maxWest | nameMargin | name | nameMargin | maxEast | ifaceMargin
132    */
133   minimumBoxWidth = maxWest+maxEast+nameWidth+2*(ifaceMargin+nameMargin);
134   // if the minimum is not sufficent taking into account N/S interfaces
135   if (minimumBoxWidth < (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1))) {
136     minimumBoxWidth = (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1));
137   }
138   minimumBoxHeight = maxNorth+maxSouth+3*ifaceMargin;
139   if (minimumBoxHeight < (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1))) {
140     minimumBoxHeight = (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1));
141   }
142 }
143
144
145 /* updateGeometry() :
146
147  */
148 bool BoxItem::updateGeometry(ChangeType type) {
149
150   currentPosition = pos();
151   //cout << "current pos of block: " << currentPosition.x() << "," << currentPosition.y() << endl;
152   QPointF oldOrigin = originPoint;
153   QSize oldSize(totalWidth,totalHeight);
154
155   bool boxSizeChanged = false;
156
157   // whatever the change, the minimum size may have changed
158   updateMinimumSize();
159
160   if (type == Resize) {
161     // resize implies to move interfaces and to update connections
162     boxSizeChanged = true;
163   }
164   else if (type == InterfaceMove) {
165     // if an interface moves, it may change the box size
166     if (boxWidth < minimumBoxWidth) {
167       boxWidth = minimumBoxWidth;
168       boxSizeChanged = true;
169     }
170     if (boxHeight < minimumBoxHeight) {
171       boxHeight = minimumBoxHeight;
172       boxSizeChanged = true;
173     }
174   }
175   if (boxSizeChanged) {
176     updateInterfaceAndConnectionItems();
177   }
178
179
180   double x = 0.0;
181   double y = 0.0;
182   totalWidth = boxWidth;
183   totalHeight = boxHeight;
184
185   if(isInterfaces(Parameters::East)){
186     totalWidth += params->arrowWidth+params->arrowLineLength;
187   }
188   if(isInterfaces(Parameters::West)){
189     totalWidth += params->arrowWidth+params->arrowLineLength;
190     x -= params->arrowWidth+params->arrowLineLength;
191   }
192   if(isInterfaces(Parameters::South)){
193     totalHeight += params->arrowWidth+params->arrowLineLength;
194   }
195   if(isInterfaces(Parameters::North)){
196     totalHeight += params->arrowWidth+params->arrowLineLength;
197     y -= params->arrowWidth+params->arrowLineLength;
198   }
199   QSizeF newSize(totalWidth,totalHeight);
200   originPoint.setX(x);
201   originPoint.setY(y);
202
203   if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
204     prepareGeometryChange();
205     return true;
206   }
207   return false;
208 }
209
210 void BoxItem::nameChanged() {
211   
212   QFontMetrics fmId(params->defaultBlockFont);
213   nameWidth = fmId.width(refBlock->getName());
214   nameHeight = fmId.height();
215   
216   if (updateGeometry(InterfaceMove)) {
217     //cout << "must recompute group item geometry" << endl;
218     (getScene()->getGroupItem())->updateShape();
219   }
220   // force the update in case of size has not changed
221   update();
222 }
223
224 void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
225
226   if(params->editState == Parameters::EditBlockMove) {
227     QPointF absPos = currentPosition + originPoint;
228     int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
229     int gapX = event->scenePos().x() - cursorPosition.x();
230     int gapY = event->scenePos().y() - cursorPosition.y();
231
232     //cout << "block abs. pos: " << absPos.x() << "," << absPos.y() << " | ";
233     //cout << "block current. pos: " << currentPosition.x() << "," << currentPosition.y() << " | ";
234
235     if (absPos.x()+gapX < marginConn) {
236       gapX = marginConn-absPos.x();
237     }
238     if (absPos.y()+gapY < marginConn) {
239       gapY = marginConn-absPos.y();
240     }
241     //cout << "gap: " << gapX << "," << gapY << endl;
242     QPointF gap(gapX,gapY);
243     currentPosition = currentPosition+gap;
244     setPos(currentPosition);
245     // update all connections from/to this block
246     foreach(ConnectionItem *item, getScene()->getConnectionItems()){
247       if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
248         item->setPath();
249       }
250     }
251     cursorPosition = event->scenePos();
252
253     // udpate the groupitem
254     (getScene()->getGroupItem())->updateShape();
255   }
256   else if(params->editState == Parameters::EditBlockResize) {
257
258     int gapX = event->scenePos().x() - cursorPosition.x();
259     int gapY = event->scenePos().y() - cursorPosition.y();
260     //cout << "gap: " << gapX << "," << gapY << endl;
261     switch(currentBorder){
262     case BorderEast: {    
263       if(boxWidth+gapX > minimumBoxWidth){
264         boxWidth += gapX;
265       }
266       break;
267     }
268     case BorderSouth: {      
269       if(boxHeight+gapY > minimumBoxHeight){
270         boxHeight += gapY;
271       }
272       break;
273     }
274     case CornerSouthEast: {
275       if(boxWidth+gapX > minimumBoxWidth){
276         boxWidth += gapX;
277       }
278       if(boxHeight+gapY > minimumBoxHeight){
279         boxHeight += gapY;
280       }
281       break;
282     }
283     case Title:
284       cout << "abnormal case while resizing block" << endl;
285       break;
286     case BorderWest:
287       cout << "abnormal case while resizing block" << endl;
288       break;
289     case BorderNorth:
290       cout << "abnormal case while resizing block" << endl;
291       break;
292     case NoBorder:
293       cout << "abnormal case while resizing block" << endl;
294       break;
295     }
296     // recompute the geometry of the block and possibly the group item
297     if (updateGeometry(Resize)) {
298       (getScene()->getGroupItem())->updateShape();
299     }
300
301     cursorPosition = event->scenePos();   
302   }
303   else if(params->editState == Parameters::EditInterfaceMove) {
304     prepareGeometryChange();
305     moveInterfaceItemTo(event->pos());
306     // recompute the geometry of the block
307     if (updateGeometry(InterfaceMove)) {
308       //cout << "must recompute group item geometry" << endl;
309       (getScene()->getGroupItem())->updateShape();
310     }
311     // update connection from/to the selected interface
312     foreach(ConnectionItem *item, getScene()->getConnectionItems()){
313       if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
314         item->setPath();
315       }
316     }    
317   }
318 }
319
320 void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
321
322   QPointF pos = event->pos();
323   qreal x = pos.x();
324   qreal y = pos.y();
325
326   //QGraphicsItem::mousePressEvent(event);
327
328   if(event->button() == Qt::RightButton) return;
329
330   int mode = getScene()->getEditionMode();
331
332   dispatcher->setCurrentGroupWidget(getScene()->getGroupWidget());
333
334   if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) {
335     InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
336     if (inter != NULL) {
337
338       if (params->editState == Parameters::EditNoOperation) {
339         getScene()->setSelectedInterface(1,inter);
340         params->setEditState(Parameters::EditStartConnection);
341       }
342       else if (params->editState == Parameters::EditStartConnection) {
343         if (inter == getScene()->getSelectedInterface(1)) {
344           params->setEditState(Parameters::EditAbortConnection);
345         }
346         else {
347           getScene()->setSelectedInterface(2,inter);
348           params->setEditState(Parameters::EditCloseConnection);
349         }
350       }
351     }
352   }
353   else if (mode == GroupScene::ItemEdition) {
354     //setZValue(zValue()+100);
355     if (params->cursorState == Parameters::CursorOnInterface) {
356       InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
357       if (inter != NULL) {
358         if (inter == currentInterface) {
359            params->setEditState(Parameters::EditInterfaceDeselect);
360         }
361         else {
362           setFlag(ItemIsMovable, false);
363           currentInterface = inter;
364           params->setEditState(Parameters::EditInterfaceMove);
365         }
366       }
367     }
368     else if (params->cursorState == Parameters::CursorInBlock) {
369       selected = !selected;
370       params->setEditState(Parameters::EditBlockMove);
371       cursorPosition = event->scenePos();
372       //cout << "cursor current pos. in scene " << cursorPosition.x() << "," << cursorPosition.y() << endl;
373       update();
374     }
375     else if (params->cursorState == Parameters::CursorOnBorder) {
376       setFlag(ItemIsMovable, false);
377       cursorPosition = event->scenePos();
378       params->setEditState(Parameters::EditBlockResize);
379     }
380   }
381 }
382
383 void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent  *event) {
384
385   //setZValue(zValue()-100);
386
387   int mode = getScene()->getEditionMode();
388
389   if (mode == GroupScene::AddConnection) {
390
391     if (params->editState == Parameters::EditStartConnection) {
392       InterfaceItem* iface = getScene()->getSelectedInterface(1);
393       iface->selected = true;
394       update(iface->boundingRect());
395     }
396     else if (params->editState == Parameters::EditAbortConnection) {
397       InterfaceItem* iface = getScene()->getSelectedInterface(1);
398       iface->selected = false;
399       update(iface->boundingRect());
400       getScene()->setSelectedInterface(1,NULL);
401       params->setEditState(Parameters::EditNoOperation);
402     }
403     else if (params->editState == Parameters::EditCloseConnection) {
404       InterfaceItem* iface1 = getScene()->getSelectedInterface(1);
405       InterfaceItem* iface2 = getScene()->getSelectedInterface(2);
406       bool ok = dispatcher->createConnection(iface1,iface2);
407       if (ok) {
408         iface1->selected = false;
409         update(iface1->boundingRect());
410         iface2->selected = false;
411         update(iface2->boundingRect());        
412         getScene()->setSelectedInterface(1,NULL);
413         getScene()->setSelectedInterface(2,NULL);
414         params->setEditState(Parameters::EditNoOperation);
415       }
416       else {
417         //QMessageBox::warning(NULL,"Error","Cannot connect selected interfaces", QMessageBox::Ok);
418         getScene()->setSelectedInterface(2,NULL);
419         params->setEditState(Parameters::EditStartConnection);
420       }
421     }
422   }
423   else if (mode == GroupScene::ItemEdition) {
424     currentInterface = NULL;
425     params->editState = Parameters::EditNoOperation;
426     setFlag(ItemIsMovable);
427   }
428
429   QGraphicsItem::mouseReleaseEvent(event);
430 }
431
432 void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
433
434   QPointF pos = event->pos();
435   qreal x = pos.x();
436   qreal y = pos.y();
437   currentBorder = NoBorder;
438   int mode = getScene()->getEditionMode();
439
440   if (mode == GroupScene::AddConnection) {
441     InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
442     if (iface != NULL) {
443       params->cursorState = Parameters::CursorOnInterface;
444       setCursor(Qt::PointingHandCursor);
445     }
446     else {
447       params->cursorState = Parameters::CursorNowhere;
448       setCursor(Qt::ArrowCursor);
449     }
450   }
451   else if (mode == GroupScene::ItemEdition) {
452     int marginE = 5;
453     int marginS = 5;
454
455     InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
456     if (iface != NULL) {
457       params->cursorState = Parameters::CursorOnInterface;
458       setCursor(Qt::PointingHandCursor);
459     }
460     else if ((x>boxWidth-marginE)&&(x<boxWidth)) {
461
462       params->cursorState = Parameters::CursorOnBorder;
463
464       if ((y>boxHeight-2*marginS)&&(y<boxHeight)) {
465         currentBorder = CornerSouthEast;
466         setCursor(Qt::SizeFDiagCursor);
467       }
468       else {
469         currentBorder = BorderEast;
470         setCursor(Qt::SizeHorCursor);
471       }
472     }
473     else if ((y>boxHeight-marginS)&&(y<boxHeight)) {
474
475       params->cursorState = Parameters::CursorOnBorder;
476
477       if ((x>boxWidth-2*marginE)&&(x<boxWidth)) {
478         currentBorder = CornerSouthEast;
479         setCursor(Qt::SizeFDiagCursor);
480       }
481       else {
482         currentBorder = BorderSouth;
483         setCursor(Qt::SizeVerCursor);
484       }
485     }
486     else {
487       if ((x>0) && (x<boxWidth-marginE) && (y>0) && (y<boxHeight-marginS)) {
488         params->cursorState = Parameters::CursorInBlock;
489         setCursor(Qt::OpenHandCursor);
490       }
491       else {
492         params->cursorState = Parameters::CursorNowhere;
493         setCursor(Qt::ArrowCursor);
494       }
495     }
496   }
497   //QGraphicsItem::hoverMoveEvent(event);
498   event->ignore();
499 }
500
501
502 void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {  
503   
504   QMenu menu;
505   QAction* titleAction = NULL;
506   QAction* removeAction = NULL;
507   QAction* duplicateAction = NULL;
508   QAction* renameAction = NULL;
509   QAction* connectToGroup = NULL;  
510   QAction* showProperties = NULL;
511   QAction* cloneInterface = NULL;
512   QAction* openWindow = NULL;
513   QAction* showRstClkIface = NULL;
514   QAction* showWishboneIface = NULL;
515   QAction* showParameters = NULL;
516   QAction* showPatterns = NULL;
517   QAction* showModifier = NULL;
518   QAction* removeModifier = NULL;
519   QAction* generateVHDL = NULL;
520
521   InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y());
522   // menu for interface
523   if( ifaceItem != NULL){
524
525     titleAction = menu.addAction("Interface operations");
526     titleAction->setEnabled(false);
527     menu.addSeparator();
528
529
530     showProperties = menu.addAction("Show properties");
531     renameAction = menu.addAction("Rename");
532
533     ConnectedInterface* iface = ifaceItem->refInter;
534     ConnectedInterface* ifaceGroup = NULL;
535     bool canRemove = true;
536
537     if ((iface->getDirection() == AbstractInterface::Input) && (iface->getConnectedFrom() == NULL)) {
538         connectToGroup = menu.addAction("Connect to group input");
539     }
540     else if ((iface->getDirection() == AbstractInterface::Output) && (iface->getConnectionToParentGroup() == NULL)) {
541       connectToGroup = menu.addAction("Connect to group output");
542     }
543     else if (iface->getConnectionFromParentGroup() != NULL) {
544       ifaceGroup = iface->getConnectionFromParentGroup();     
545       if (ifaceGroup->isConnectedFrom()) {        
546         canRemove = false;
547       }
548     }
549     else if (iface->getConnectionToParentGroup() != NULL) {
550       ifaceGroup = iface->getConnectionToParentGroup();      
551       if (ifaceGroup->isConnectedTo()) {
552         canRemove = false;
553       }
554     }
555
556     if (iface->isFunctionalInterface()) {
557       FunctionalInterface* fi = AI_TO_FUN(ifaceItem->refInter);
558       ReferenceInterface* ri = (ReferenceInterface*)(fi->getReference());
559       if(ri->getMultiplicity() == -1 || ri->getMultiplicity() > 1){
560         cloneInterface = menu.addAction("Duplicate");
561         if ((canRemove) && (fi->getInterfaceMultiplicity() > 1)) {
562           removeAction = menu.addAction("Remove");
563         }
564       }      
565     }
566     if (iface->getAssociatedIface() != NULL) {
567       if (iface->getDirection() == AbstractInterface::Output) {
568         showPatterns = menu.addAction("Show output pattern");
569       }
570       else if (iface->getDirection() == AbstractInterface::Input) {
571         showPatterns = menu.addAction("Show input pattern");
572       }
573     }    
574
575     if (iface->getAssociatedIface() != NULL) {
576       ConnectedInterface* assoIface = AI_TO_CON(iface->getAssociatedIface());
577       if (assoIface->getInputModifier() != NULL) {
578         removeModifier = menu.addAction("Remove input modifier");
579       }
580       if (assoIface->getInputModifier() != NULL) {
581         showModifier = menu.addAction("Show input modifier parameters");
582       }
583     }
584
585   }
586   // menu for blocks (group or func)
587   else {
588     titleAction = menu.addAction("Block operations");
589     titleAction->setEnabled(false);
590     menu.addSeparator();
591
592     if (refBlock->nbParameters() > 0) {
593       showParameters = menu.addAction("Show parameters");
594     }
595     renameAction = menu.addAction("Rename");
596
597     if(refBlock->isGroupBlock()){
598       openWindow = menu.addAction("Open/show group window");
599     }
600     else {
601       duplicateAction = menu.addAction("Duplicate");
602       showRstClkIface = menu.addAction("Show reset/clock interfaces");
603       showRstClkIface->setCheckable(true);
604       showRstClkIface->setChecked(rstClkVisible);
605       showWishboneIface = menu.addAction("Show wishbone interfaces");
606       showWishboneIface->setCheckable(true);
607       showWishboneIface->setChecked(wishboneVisible);
608     }
609     removeAction = menu.addAction("Remove");
610     generateVHDL = menu.addAction("Generate VHDL");
611   }
612
613   QAction* selectedAction = NULL;
614   selectedAction = menu.exec(event->screenPos());
615
616   if(selectedAction == NULL) return ;
617
618   if (selectedAction == removeAction) {
619     if(ifaceItem != NULL) {
620      dispatcher->removeFunctionalInterface(ifaceItem);
621     }
622     else {
623       dispatcher->removeBoxItem(this);
624     }
625   }
626   else if (selectedAction == duplicateAction) {
627     dispatcher->duplicateBoxItem(this);
628   }
629   else if(selectedAction == renameAction){
630     if(ifaceItem != NULL) {
631       dispatcher->renameInterface(ifaceItem);
632     }
633     else {
634       if (refBlock->isFunctionalBlock()) {          
635         dispatcher->renameFunctionalBlock(this);
636       }
637       else if (refBlock->isGroupBlock()) {        
638         dispatcher->renameGroupBlock(childGroupItem);
639       }
640     }   
641   }
642   else if(selectedAction == showProperties){
643     dispatcher->showProperties(ifaceItem);
644   }
645   else if (selectedAction == connectToGroup){
646     dispatcher->connectInterToGroup(ifaceItem);
647   }
648   else if (selectedAction == cloneInterface){
649     dispatcher->duplicateInterfaceItem(ifaceItem);
650   }
651   else if (selectedAction == openWindow){
652     dispatcher->showRaiseWindow(this);
653   }
654   else if(selectedAction == showRstClkIface) {
655     dispatcher->showRstClkIface(this);
656   }
657   else if(selectedAction == showWishboneIface) {
658     dispatcher->showWishboneIface(this);
659   }
660   else if(selectedAction == showParameters) {    
661     new ParametersWindow(refBlock, params, NULL);
662   }
663   else if(selectedAction == showPatterns) {    
664     dispatcher->showPatterns(ifaceItem);
665   }
666   else if(selectedAction == removeModifier) {
667     dispatcher->removeModifier(ifaceItem);
668   }
669   else if(selectedAction == showModifier) {
670     dispatcher->showModifier(ifaceItem);
671   }
672   else if(selectedAction == generateVHDL) {
673     dispatcher->generateBlockVHDL(this);
674   }
675
676 }
677
678 void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) {
679
680   bool ok = false;
681
682   int id = funcElement.attribute("id","none").toInt(&ok);
683   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
684
685   QString refXml = funcElement.attribute("ref_xml","none");
686   if(refXml == "none") throw(Exception(PROJECTFILE_CORRUPTED));
687
688   QString refMd5 = funcElement.attribute("ref_md5","none");
689   if(refMd5 == "none") throw(Exception(PROJECTFILE_CORRUPTED));
690
691   cout << "ref md5 : " << refMd5.toStdString() << "\nref xml : " << refXml.toStdString() << endl;
692
693   QString name = funcElement.attribute("name","none");
694   if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
695
696   QStringList positionStr = funcElement.attribute("position","none").split(",");
697   if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
698   int posX = positionStr.at(0).toInt(&ok);
699   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
700   int posY = positionStr.at(1).toInt(&ok);
701   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
702
703   QStringList dimensionStr = funcElement.attribute("dimension","none").split(",");
704   if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
705   int dimX = dimensionStr.at(0).toInt(&ok);
706   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
707   int dimY = dimensionStr.at(1).toInt(&ok);
708   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
709   
710   ReferenceBlock *referenceMd5 = NULL;
711   ReferenceBlock *referenceXml = NULL;
712   ReferenceBlock *reference = NULL;
713   if(refMd5 != "none") {
714     referenceMd5 = params->searchBlockByMd5(refMd5);
715   }
716   if(refXml != "none"){
717     referenceXml = params->searchBlockByXml(refXml);
718   }
719   if ((referenceMd5 == NULL) && (referenceXml == NULL)) {
720     throw(Exception(PROJECTFILE_CORRUPTED));
721   }
722   if (referenceMd5 != referenceXml) {
723     reference = referenceXml;
724   }
725   else {
726     reference = referenceMd5;
727   }
728   
729   GroupBlock* parentGroupBlock = AB_TO_GRP(((GroupItem *)parentItem())->getRefBlock());
730   FunctionalBlock* functionalBlock = params->getGraph()->createFunctionalBlock(parentGroupBlock, reference);
731   /* NB: addFunctionalBlock creates all interfaces from the reference, which is annoying when
732     reading bif_iface tags. Thus interface are all removed.
733   */
734   functionalBlock->setName(name);
735   setRefBlock(functionalBlock);
736   params->blockToItem.insert(functionalBlock,this);
737
738   setPos(posX,posY);
739   setDimension(dimX,dimY);
740   setId(id);
741
742
743   QDomNodeList blockParamNodes = funcElement.elementsByTagName("bif_parameter");
744   // setting parameters value
745   for(int i=0; i<blockParamNodes.length(); i++){
746     QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement();
747
748     QString name = currentBlockParamNode.attribute("name","none");
749     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
750
751     QString value = currentBlockParamNode.attribute("value","none");
752     if(value == "none") throw(Exception(PROJECTFILE_CORRUPTED));
753
754     BlockParameter *blockParam = NULL;
755     blockParam = functionalBlock->getParameterFromName(name);
756     if (blockParam == NULL) throw(Exception(PROJECTFILE_CORRUPTED));
757     blockParam->setValue(value);
758   }  
759
760   // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars
761   functionalBlock->removeAllInterfaces();
762   QDomNodeList interfaceNodes = funcElement.elementsByTagName("bif_iface");
763   // setting interfaces (user name, and for multiplicity>1 may be create some new ones)
764   for(int i=0; i<interfaceNodes.length(); i++) {
765
766     QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
767
768     QString name = currentInterfaceNode.attribute("name","none");
769     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
770
771     QString refName = currentInterfaceNode.attribute("ref_name","none");
772     if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));
773
774     ReferenceInterface* refInter = AI_TO_REF(reference->getIfaceFromName(refName));
775     cout << "creating iface from reference named " << qPrintable(refName) << endl;
776     FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter);
777     functionalInterface->setName(name);
778     functionalBlock->addInterface(functionalInterface);
779     
780     // searching for control interface
781     QString ctlRefName = refName+"_enb";
782     ReferenceInterface* ctlRefIface = AI_TO_REF(reference->getIfaceFromName(ctlRefName));
783     
784     if (ctlRefIface != NULL) {
785       cout << "found a control iface:" << qPrintable(ctlRefName) << endl;
786       FunctionalInterface *ctlIface = new FunctionalInterface(functionalBlock,ctlRefIface);      
787       if (! ctlIface->setAssociatedIface(functionalInterface)) {
788         throw(Exception(PROJECTFILE_CORRUPTED));
789       }      
790       ctlIface->setName(name+"_enb");
791       functionalBlock->addInterface(ctlIface);
792     }    
793   }
794   // connect clk and rst to group clk/rst or to clkrstgen
795   if ((name != "clkrstgen") && (parentGroupBlock != NULL)) {
796     try {
797       functionalBlock->connectClkReset();
798     }
799     catch(Exception e) {
800       AbstractBlock* source = (AbstractBlock *)(e.getSource());
801       cerr << qPrintable(source->getName()) << ":" << qPrintable(e.getMessage()) << endl;
802       throw(e);
803     }
804   }
805   
806   // creating InterfaceItem
807   initInterfaceItems();
808   // setting them with saved values
809   for(int i=0; i<interfaceNodes.length(); i++){
810
811     QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
812
813     int id = currentInterfaceNode.attribute("id","none").toInt(&ok);
814     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
815
816     QString name = currentInterfaceNode.attribute("name","none");
817     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
818
819     QString orientationStr = currentInterfaceNode.attribute("orientation","none");
820     int orientation = InterfaceItem::getIntOrientation(orientationStr);
821     if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));
822
823     double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);
824     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
825
826     InterfaceItem *interfaceItem = searchInterfaceItemByName(name);
827     interfaceItem->setId(id);
828     interfaceItem->setOrientation(orientation);
829     interfaceItem->setPositionRatio(position);
830   }
831   updateGeometry(Resize);
832 }
833
834 void BoxItem::save(QXmlStreamWriter &writer) {
835   if (refBlock->isFunctionalBlock()) {
836     writer.writeStartElement("bi_functional");
837
838     writer.writeAttribute("id",QString::number(id));
839     writer.writeAttribute("ref_xml", ((FunctionalBlock*)refBlock)->getReferenceXmlFile());
840     writer.writeAttribute("ref_md5", ((FunctionalBlock*)refBlock)->getReferenceHashMd5());
841     writer.writeAttribute("name",refBlock->getName());
842     QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
843     writer.writeAttribute("position",attrPos);
844     QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
845     writer.writeAttribute("dimension",attrDim);
846
847     writer.writeStartElement("bif_parameters");
848     foreach(BlockParameter *param,refBlock->getParameters()){
849       writer.writeStartElement("bif_parameter");
850
851       writer.writeAttribute("name",param->getName());
852       writer.writeAttribute("value",param->getValue().toString());
853       /*
854       writer.writeAttribute("context",param->getStrContext());
855       writer.writeAttribute("type",param->getTypeString());
856       */
857       writer.writeEndElement();   //</bif_parameter>
858     }
859     writer.writeEndElement();   //</bif_parameters>
860
861     writer.writeStartElement("bif_ifaces");
862     writer.writeAttribute("count",QString::number(interfaces.length()));
863     foreach(InterfaceItem* inter, interfaces){
864       writer.writeStartElement("bif_iface");
865
866       writer.writeAttribute("id",QString::number(inter->getId()));
867       writer.writeAttribute("name",inter->getName());
868       writer.writeAttribute("ref_name",inter->refInter->getName());
869       writer.writeAttribute("orientation",inter->getStrOrientation());
870       writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
871
872       writer.writeEndElement();   //</bif_iface>
873     }
874     writer.writeEndElement();   //</bif_ifaces>
875
876     writer.writeEndElement();   //</bi_functional>
877   }
878   else {
879     writer.writeStartElement("bi_group");
880
881     writer.writeAttribute("id",QString::number(id));
882     writer.writeAttribute("inside_group",QString::number(childGroupItem->getId()));
883     QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
884     writer.writeAttribute("position",attrPos);
885     QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
886     writer.writeAttribute("dimension",attrDim);
887
888     writer.writeStartElement("big_ifaces");
889     writer.writeAttribute("count",QString::number(interfaces.length()));
890     foreach(InterfaceItem* inter, interfaces){
891       writer.writeStartElement("big_iface");
892
893       writer.writeAttribute("id",QString::number(inter->getId()));
894       writer.writeAttribute("ref_name",inter->refInter->getName());
895       writer.writeAttribute("orientation",inter->getStrOrientation());
896       writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
897
898       writer.writeEndElement(); //</big_iface>
899     }
900
901     writer.writeEndElement(); //</big_ifaces>
902     writer.writeEndElement(); //</bi_group>
903   }
904 }
905
906 QDataStream &operator <<(QDataStream &out, BoxItem &b) {
907   out.setVersion(QDataStream::Qt_4_8);
908
909   QByteArray blockData;
910   QDataStream toWrite(&blockData, QIODevice::WriteOnly);
911
912   QString refXml = ((FunctionalBlock*)b.refBlock)->getReferenceXmlFile();
913   QByteArray xmlFile = QByteArray(refXml.toStdString().c_str());
914   toWrite << xmlFile;
915
916   toWrite << b.id;
917   toWrite << (int)b.x();
918   toWrite << (int)b.y();
919   toWrite << b.boxWidth;
920   toWrite << b.boxHeight;
921   toWrite << b.getInterfaces().length();
922
923   for(int i=0; i<b.getInterfaces().length(); i++){
924     InterfaceItem *inter = b.getInterfaces().at(i);
925     toWrite << inter->getId();
926     //toWrite << inter->getName();
927     toWrite << inter->getPositionRatio();
928     toWrite << inter->getOrientation();
929   }
930
931   out << blockData;
932
933   return out;
934 }
935
936 QDataStream &operator >>(QDataStream &in, BoxItem &b) {
937
938   in.setVersion(QDataStream::Qt_4_8);
939
940   int x,y,nbInter;
941
942   in >> b.id;
943   in >> x;
944   in >> y;
945
946   b.setX(x);
947   b.setY(y);
948
949   in >> b.boxWidth;
950   in >> b.boxHeight;
951   in >> nbInter;
952
953   cout << "nbInter:" << nbInter << endl;
954   for(int i=0; i<nbInter; i++){
955
956     int id, orientation;
957     double positionRatio;
958     QString name;
959
960     InterfaceItem *inter = b.getInterfaces().at(i);
961     in >> id;
962     in >> name;
963     in >> positionRatio;
964     in >> orientation;
965
966     inter->setId(id);    
967     inter->setPositionRatio(positionRatio);
968     inter->setOrientation(orientation);
969     inter->updatePosition();
970
971   }
972
973   return in;
974 }