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

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