2 #include "GroupScene.h"
3 #include "ConnectionItem.h"
4 #include "InterfaceItem.h"
6 #include "Parameters.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"
18 BoxItem::BoxItem(AbstractBlock *_refBlock,
19 Dispatcher *_dispatcher,
20 Parameters *_params, GroupItem *parent, int _lock, SpanType _span, Position _position) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params, _lock, parent) {
23 _refBlock : mandatory a FunctionalBlock or a GroupBlock
25 if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
30 childGroupItem = NULL;
31 //boxWidth = params->defaultBlockWidth;
32 //boxHeight = params->defaultBlockHeight;
33 currentBorder = NoBorder;
37 QGraphicsItem::GraphicsItemFlags flags = QGraphicsItem::ItemIsSelectable;
38 if (!isPositionLock()) {
39 flags |= QGraphicsItem::ItemIsMovable;
40 cout << "item " << qPrintable(refBlock->getName()) << "is movable" << endl;
42 if (!isDimensionLock()) {
43 flags |= QGraphicsItem::ItemSendsGeometryChanges;
44 cout << "item " << qPrintable(refBlock->getName()) << "is resizable" << endl;
48 bool freeBorder[4]; // 0 = east, 1 = north, 2 = west, 3 = south
49 Parameters::Direction dirs[4];
50 for(int i=0;i<4;i++) {
53 dirs[0] = Parameters::East;
54 dirs[1] = Parameters::North;
55 dirs[2] = Parameters::West;
56 dirs[3] = Parameters::South;
59 if (position == Top) {
60 freeBorder[1] = false;
62 if (position == Bottom) {
63 freeBorder[3] = false;
65 if (position == Left) {
66 freeBorder[2] = false;
68 if (position == Right) {
69 freeBorder[0] = false;
72 freeBorder[2] = false;
73 freeBorder[0] = false;
76 freeBorder[1] = false;
77 freeBorder[3] = false;
79 Parameters::Direction dIn = Parameters::West;
80 Parameters::Direction dOut = Parameters::East;
81 Parameters::Direction dBi = Parameters::South;
82 if (freeBorder[2] == false) {
84 while (freeBorder[i] == false) {
89 if (freeBorder[0] == false) {
91 while (freeBorder[i] == false) {
96 if (freeBorder[3] == false) {
98 while (freeBorder[i] == false) {
104 createInterfaceItems(dIn,dOut,dBi);
105 updateGeometry(Creation);
108 int groupWidth = getScene()->getGroupItem()->getWidth();
109 int groupHeight = getScene()->getGroupItem()->getHeight();
110 double xx = 0.0,yy = 0.0;
111 if ((position == BoxItem::Left) || (position == BoxItem::TopLeft) || (position == BoxItem::BottomLeft)) {
113 if ((span == VSpan) || (position == BoxItem::TopLeft)) {
116 else if (position == BoxItem::BottomLeft) {
117 yy = groupHeight-totalHeight;
120 yy = (groupHeight-totalHeight)/2.0;
123 else if ((position == BoxItem::Right) || (position == BoxItem::TopRight) || (position == BoxItem::BottomRight)) {
124 xx = groupWidth-totalWidth;
126 if ((span == VSpan) || (position == BoxItem::TopRight)) {
129 else if (position == BoxItem::BottomRight) {
130 yy = groupHeight-totalHeight;
133 yy = (groupHeight-totalHeight)/2.0;
136 else if ((position == BoxItem::Top) || (position == BoxItem::TopLeft) || (position == BoxItem::TopRight)) {
138 if ((span == HSpan) || (position == BoxItem::TopLeft)) {
141 else if (position == BoxItem::TopRight) {
142 xx = groupWidth-totalWidth;
145 xx = (groupWidth-totalWidth)/2.0;
148 else if ((position == BoxItem::Bottom) || (position == BoxItem::BottomLeft) || (position == BoxItem::BottomRight)) {
149 yy = groupHeight-totalHeight;
150 if ((span == HSpan) || (position == BoxItem::BottomLeft)) {
153 else if (position == BoxItem::BottomRight) {
154 xx = groupWidth-totalWidth;
157 xx = (groupWidth-totalWidth)/2.0;
161 int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
162 xx = (groupWidth-totalWidth)/2.0;
163 if (xx < marginConn) xx = marginConn;
164 yy = (groupHeight-totalHeight)/2.0;
165 if (yy < marginConn) yy = marginConn;
167 cout << "setting raw pos to " << xx << "," << yy << endl;
168 QPointF initPos(xx,yy);
169 initPos = initPos-originPoint;
171 cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
172 cout << "pos in group: " << x() << "," << y() << endl;
175 BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent, int _lock, SpanType _span, Position _position) throw(Exception) : AbstractBoxItem(_dispatcher, _params, _lock, parent) {
178 position = _position;
181 childGroupItem = NULL;
182 currentBorder = NoBorder;
186 QGraphicsItem::GraphicsItemFlags flags = QGraphicsItem::ItemIsSelectable;
187 if (!isPositionLock()) {
188 flags |= QGraphicsItem::ItemIsMovable;
190 if (!isDimensionLock()) {
191 flags |= QGraphicsItem::ItemSendsGeometryChanges;
195 boxWidth = params->defaultBlockWidth;
196 boxHeight = params->defaultBlockHeight;
198 //updateGeometry(InterfaceMove);
199 //resetInterfacesPosition();
200 //QPointF initPos = QPointF(0.0,0.0) - originPoint;
202 //cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
203 //cout << "pos in group: " << x() << "," << y() << endl;
206 BoxItem::~BoxItem() {
209 void BoxItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
210 QPen pen(Qt::black, 3);
212 pen.setColor(Qt::red);
214 painter->setPen(pen);
215 painter->setBrush(Qt::yellow);
217 painter->drawRect(0,0,boxWidth, boxHeight);
218 painter->drawText(0,0,boxWidth, boxHeight,Qt::AlignCenter | Qt::TextWordWrap,QString(refBlock->getName()));
219 foreach(InterfaceItem *inter, interfaces) {
220 inter->paint(painter);
224 void BoxItem::moveTo(QPointF dest) {
226 currentPosition = dest;
229 bool BoxItem::isBoxItem() {
233 void BoxItem::updateMinimumSize() {
239 int nbSouth = nbInterfacesByOrientation(Parameters::South);
240 int nbNorth = nbInterfacesByOrientation(Parameters::North);
241 int nbMaxSN = nbNorth;
242 if (nbSouth > nbNorth) nbMaxSN = nbSouth;
243 int nbEast = nbInterfacesByOrientation(Parameters::East);
244 int nbWest = nbInterfacesByOrientation(Parameters::West);
245 int nbMaxEW = nbEast;
246 if (nbWest > nbEast) {
253 foreach(InterfaceItem* iface, interfaces) {
255 if (iface->visible) {
256 ifaceWidth = iface->getNameWidth();
257 ifaceHeight = iface->getNameHeight();
258 if (iface->getOrientation() == Parameters::South) {
259 if (ifaceWidth > maxSouth) maxSouth = ifaceWidth;
261 else if (iface->getOrientation() == Parameters::North) {
262 if (ifaceWidth > maxNorth) maxNorth = ifaceWidth;
264 else if (iface->getOrientation() == Parameters::East) {
265 if (ifaceWidth > maxEast) maxEast = ifaceWidth;
267 else if (iface->getOrientation() == Parameters::West) {
268 if (ifaceWidth > maxWest) maxWest = ifaceWidth;
273 /* NB: the width layout is the following
274 ifaceMargin | maxWest | nameMargin | name | nameMargin | maxEast | ifaceMargin
276 minimumBoxWidth = maxWest+maxEast+nameWidth+2*(ifaceMargin+nameMargin);
277 // if the minimum is not sufficent taking into account N/S interfaces
278 if (minimumBoxWidth < (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1))) {
279 minimumBoxWidth = (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1));
281 minimumBoxHeight = maxNorth+maxSouth+3*ifaceMargin;
282 if (minimumBoxHeight < (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1))) {
283 minimumBoxHeight = (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1));
288 /* updateGeometry() :
291 bool BoxItem::updateGeometry(ChangeType type) {
293 currentPosition = pos();
294 //cout << "current pos of block: " << currentPosition.x() << "," << currentPosition.y() << endl;
295 QPointF oldOrigin = originPoint;
296 QSize oldSize(totalWidth,totalHeight);
297 bool boxSizeChanged = false;
299 // whatever the change, the minimum size may have changed
302 int groupWidth = getScene()->getGroupItem()->getWidth();
303 int groupHeight = getScene()->getGroupItem()->getHeight();
305 cout << "minimum box size is " << minimumBoxWidth << "x" << minimumBoxHeight << endl;
306 cout << "group size is " << groupWidth << "x" << groupHeight << endl;
308 if (type == Creation) {
310 boxSizeChanged = true;
311 boxWidth = minimumBoxWidth;
312 boxHeight = minimumBoxHeight;
313 /* reset and update interfaces positions
314 * in case of spanning, the interface are positionned
315 * only on free borders.
317 resetInterfaceItemsPosition();
318 /* must test if the GroupItem must be resized */
319 if ((span == HSpan) && (boxWidth < groupWidth)) {
320 boxWidth = groupWidth; // no interfaces in east/west (done in constructor)
322 else if ((span == VSpan) && (boxHeight < groupHeight)) {
323 boxHeight = groupHeight;
326 else if (type == Resize) {
327 // resize implies to move interfaces and to update connections
328 boxSizeChanged = true;
329 updateInterfaceAndConnectionItems();
331 else if (type == InterfaceMove) {
332 // if an interface moves, it may change the box size
333 if (boxWidth < minimumBoxWidth) {
334 boxWidth = minimumBoxWidth;
335 boxSizeChanged = true;
336 updateInterfaceAndConnectionItems();
338 if (boxHeight < minimumBoxHeight) {
339 boxHeight = minimumBoxHeight;
340 boxSizeChanged = true;
341 updateInterfaceAndConnectionItems();
349 totalWidth = boxWidth;
350 totalHeight = boxHeight;
352 if(isInterfaces(Parameters::East)){
353 totalWidth += params->arrowWidth+params->arrowLineLength;
355 if(isInterfaces(Parameters::West)){
356 totalWidth += params->arrowWidth+params->arrowLineLength;
357 x -= params->arrowWidth+params->arrowLineLength;
359 if(isInterfaces(Parameters::South)){
360 totalHeight += params->arrowWidth+params->arrowLineLength;
362 if(isInterfaces(Parameters::North)){
363 totalHeight += params->arrowWidth+params->arrowLineLength;
364 y -= params->arrowWidth+params->arrowLineLength;
366 QSizeF newSize(totalWidth,totalHeight);
369 cout << "change orig pos of " << qPrintable(refBlock->getName()) << "to " << x << "," << y << endl;
370 cout << "box size is " << boxWidth << "x" << boxHeight << endl;
371 cout << "total size is " << totalWidth << "x" << totalHeight << endl;
373 if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
374 prepareGeometryChange();
380 void BoxItem::nameChanged() {
382 QFontMetrics fmId(params->defaultBlockFont);
383 nameWidth = fmId.width(refBlock->getName());
384 nameHeight = fmId.height();
386 if (updateGeometry(InterfaceMove)) {
387 //cout << "must recompute group item geometry" << endl;
388 (getScene()->getGroupItem())->updateShape();
390 // force the update in case of size has not changed
394 void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
396 if(params->editState == Parameters::EditBlockMove) {
398 if (isPositionLock()) return;
399 QPointF absPos = currentPosition + originPoint;
400 int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
401 int gapX = event->scenePos().x() - cursorPosition.x();
402 int gapY = event->scenePos().y() - cursorPosition.y();
403 // update cursor position
404 cursorPosition = event->scenePos();
406 //cout << "block abs. pos: " << absPos.x() << "," << absPos.y() << " | ";
407 //cout << "block current. pos: " << currentPosition.x() << "," << currentPosition.y() << " | ";
409 if ((position == Left) || (position == Right)) {
412 else if ((gapX < 0) && (absPos.x() == marginConn)) {
415 else if (absPos.x()+gapX < marginConn) {
416 gapX = marginConn-absPos.x();
418 if ((position == Top) || (position == Bottom)) {
421 else if ((gapY < 0) && (absPos.y() == marginConn)) {
424 else if (absPos.y()+gapY < marginConn) {
425 gapY = marginConn-absPos.y();
427 //cout << "gap: " << gapX << "," << gapY << endl;
428 if ((gapX != 0) || (gapY != 0)) {
429 QPointF gap(gapX,gapY);
430 currentPosition = currentPosition+gap;
431 setPos(currentPosition);
432 // update all connections from/to this block
433 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
434 if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
438 // udpate the groupitem
439 (getScene()->getGroupItem())->updateShape();
442 else if(params->editState == Parameters::EditBlockResize) {
444 if (isDimensionLock()) return;
445 int gapX = event->scenePos().x() - cursorPosition.x();
446 int gapY = event->scenePos().y() - cursorPosition.y();
447 //cout << "gap: " << gapX << "," << gapY << endl;
448 switch(currentBorder){
450 if(boxWidth+gapX > minimumBoxWidth){
456 if(boxHeight+gapY > minimumBoxHeight){
461 case CornerSouthEast: {
462 if(boxWidth+gapX > minimumBoxWidth){
465 if(boxHeight+gapY > minimumBoxHeight){
471 cout << "abnormal case while resizing block" << endl;
474 cout << "abnormal case while resizing block" << endl;
477 cout << "abnormal case while resizing block" << endl;
480 cout << "abnormal case while resizing block" << endl;
483 // recompute the geometry of the block and possibly the group item
484 if (updateGeometry(Resize)) {
485 (getScene()->getGroupItem())->updateShape();
488 cursorPosition = event->scenePos();
490 else if(params->editState == Parameters::EditInterfaceMove) {
491 prepareGeometryChange();
492 moveInterfaceItemTo(event->pos());
493 // recompute the geometry of the block
494 if (updateGeometry(InterfaceMove)) {
495 //cout << "must recompute group item geometry" << endl;
496 (getScene()->getGroupItem())->updateShape();
498 // update connection from/to the selected interface
499 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
500 if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
507 void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
509 QPointF pos = event->pos();
513 //QGraphicsItem::mousePressEvent(event);
515 if(event->button() == Qt::RightButton) return;
517 int mode = getScene()->getEditionMode();
519 dispatcher->setCurrentGroupWidget(Dispatcher::Design, getScene()->getGroupWidget());
521 if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) {
522 InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
525 if (params->editState == Parameters::EditNoOperation) {
526 getScene()->setSelectedInterface(1,inter);
527 params->setEditState(Parameters::EditStartConnection);
529 else if (params->editState == Parameters::EditStartConnection) {
530 if (inter == getScene()->getSelectedInterface(1)) {
531 params->setEditState(Parameters::EditAbortConnection);
534 getScene()->setSelectedInterface(2,inter);
535 params->setEditState(Parameters::EditCloseConnection);
540 else if (mode == GroupScene::ItemEdition) {
541 //setZValue(zValue()+100);
542 if (params->cursorState == Parameters::CursorOnInterface) {
543 InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
545 if (inter == currentInterface) {
546 params->setEditState(Parameters::EditInterfaceDeselect);
549 setFlag(ItemIsMovable, false);
550 currentInterface = inter;
551 params->setEditState(Parameters::EditInterfaceMove);
555 else if (params->cursorState == Parameters::CursorInBlock) {
556 selected = !selected;
557 params->setEditState(Parameters::EditBlockMove);
558 cursorPosition = event->scenePos();
559 //cout << "cursor current pos. in scene " << cursorPosition.x() << "," << cursorPosition.y() << endl;
562 else if (params->cursorState == Parameters::CursorOnBorder) {
563 if (isDimensionLock()) {
564 if ((position == Bottom)||(position == Right)) {
569 setFlag(ItemIsMovable, false);
570 cursorPosition = event->scenePos();
571 params->setEditState(Parameters::EditBlockResize);
577 void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
579 //setZValue(zValue()-100);
581 int mode = getScene()->getEditionMode();
583 if (mode == GroupScene::AddConnection) {
585 if (params->editState == Parameters::EditStartConnection) {
586 InterfaceItem* iface = getScene()->getSelectedInterface(1);
587 iface->selected = true;
588 update(iface->boundingRect());
590 else if (params->editState == Parameters::EditAbortConnection) {
591 InterfaceItem* iface = getScene()->getSelectedInterface(1);
592 iface->selected = false;
593 update(iface->boundingRect());
594 getScene()->setSelectedInterface(1,NULL);
595 params->setEditState(Parameters::EditNoOperation);
597 else if (params->editState == Parameters::EditCloseConnection) {
598 InterfaceItem* iface1 = getScene()->getSelectedInterface(1);
599 InterfaceItem* iface2 = getScene()->getSelectedInterface(2);
600 bool ok = dispatcher->createConnection(Dispatcher::Design, iface1,iface2);
602 iface1->selected = false;
603 update(iface1->boundingRect());
604 iface2->selected = false;
605 update(iface2->boundingRect());
606 getScene()->setSelectedInterface(1,NULL);
607 getScene()->setSelectedInterface(2,NULL);
608 params->setEditState(Parameters::EditNoOperation);
611 //QMessageBox::warning(NULL,"Error","Cannot connect selected interfaces", QMessageBox::Ok);
612 getScene()->setSelectedInterface(2,NULL);
613 params->setEditState(Parameters::EditStartConnection);
617 else if (mode == GroupScene::ItemEdition) {
618 currentInterface = NULL;
619 params->editState = Parameters::EditNoOperation;
620 setFlag(ItemIsMovable);
623 QGraphicsItem::mouseReleaseEvent(event);
626 void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
628 QPointF evPos = event->pos();
631 currentBorder = NoBorder;
632 int mode = getScene()->getEditionMode();
634 if (mode == GroupScene::AddConnection) {
635 InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
637 params->cursorState = Parameters::CursorOnInterface;
638 setCursor(Qt::PointingHandCursor);
641 params->cursorState = Parameters::CursorNowhere;
642 setCursor(Qt::ArrowCursor);
645 else if (mode == GroupScene::ItemEdition) {
649 InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
651 params->cursorState = Parameters::CursorOnInterface;
652 setCursor(Qt::PointingHandCursor);
654 else if ((x>boxWidth-marginE)&&(x<boxWidth)) {
656 params->cursorState = Parameters::CursorOnBorder;
658 if ((y>boxHeight-2*marginS)&&(y<boxHeight)) {
659 currentBorder = CornerSouthEast;
660 setCursor(Qt::SizeFDiagCursor);
663 currentBorder = BorderEast;
664 setCursor(Qt::SizeHorCursor);
667 else if ((y>boxHeight-marginS)&&(y<boxHeight)) {
669 params->cursorState = Parameters::CursorOnBorder;
671 if ((x>boxWidth-2*marginE)&&(x<boxWidth)) {
672 currentBorder = CornerSouthEast;
673 setCursor(Qt::SizeFDiagCursor);
676 currentBorder = BorderSouth;
677 setCursor(Qt::SizeVerCursor);
681 if ((x>0) && (x<boxWidth-marginE) && (y>0) && (y<boxHeight-marginS)) {
682 params->cursorState = Parameters::CursorInBlock;
683 setCursor(Qt::OpenHandCursor);
686 params->cursorState = Parameters::CursorNowhere;
687 setCursor(Qt::ArrowCursor);
691 if (params->cursorState == Parameters::CursorOnBorder) {
692 if (isDimensionLock()) {
693 if ((position == Bottom)||(position == Right)) {
694 event->setPos(evPos+pos());
695 getScene()->getGroupItem()->hoverMoveEvent(event);
702 void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
705 QAction* titleAction = NULL;
706 QAction* removeAction = NULL;
707 QAction* duplicateAction = NULL;
708 QAction* renameAction = NULL;
709 QAction* connectToGroup = NULL;
710 QAction* showProperties = NULL;
711 QAction* cloneInterface = NULL;
712 QAction* openWindow = NULL;
713 QAction* showRstClkIface = NULL;
714 QAction* showWishboneIface = NULL;
715 QAction* showParameters = NULL;
716 QAction* showPatterns = NULL;
717 QAction* showModifier = NULL;
718 QAction* removeModifier = NULL;
719 QAction* generateVHDL = NULL;
721 InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y());
722 // menu for interface
723 if( ifaceItem != NULL){
725 titleAction = menu.addAction("Interface operations");
726 titleAction->setEnabled(false);
730 showProperties = menu.addAction("Show properties");
731 renameAction = menu.addAction("Rename");
733 ConnectedInterface* iface = ifaceItem->refInter;
734 ConnectedInterface* ifaceGroup = NULL;
735 bool canRemove = true;
737 if ((iface->getDirection() == AbstractInterface::Input) && (iface->getConnectedFrom() == NULL)) {
738 connectToGroup = menu.addAction("Connect to group input");
740 else if ((iface->getDirection() == AbstractInterface::Output) && (iface->getConnectionToParentGroup() == NULL)) {
741 connectToGroup = menu.addAction("Connect to group output");
743 else if (iface->getConnectionFromParentGroup() != NULL) {
744 ifaceGroup = iface->getConnectionFromParentGroup();
745 if (ifaceGroup->isConnectedFrom()) {
749 else if (iface->getConnectionToParentGroup() != NULL) {
750 ifaceGroup = iface->getConnectionToParentGroup();
751 if (ifaceGroup->isConnectedTo()) {
756 if (iface->isFunctionalInterface()) {
757 FunctionalInterface* fi = AI_TO_FUN(ifaceItem->refInter);
758 ReferenceInterface* ri = (ReferenceInterface*)(fi->getReference());
759 if(ri->getMultiplicity() == -1 || ri->getMultiplicity() > 1){
760 cloneInterface = menu.addAction("Duplicate");
761 if ((canRemove) && (fi->getInterfaceMultiplicity() > 1)) {
762 removeAction = menu.addAction("Remove");
766 if (iface->getAssociatedIface() != NULL) {
767 if (iface->getDirection() == AbstractInterface::Output) {
768 showPatterns = menu.addAction("Show output pattern");
770 else if (iface->getDirection() == AbstractInterface::Input) {
771 showPatterns = menu.addAction("Show input pattern");
775 if (iface->getAssociatedIface() != NULL) {
776 ConnectedInterface* assoIface = AI_TO_CON(iface->getAssociatedIface());
777 if (assoIface->getInputModifier() != NULL) {
778 removeModifier = menu.addAction("Remove input modifier");
780 if (assoIface->getInputModifier() != NULL) {
781 showModifier = menu.addAction("Show input modifier parameters");
786 // menu for blocks (group or func)
788 titleAction = menu.addAction("Block operations");
789 titleAction->setEnabled(false);
792 if (refBlock->nbParameters() > 0) {
793 showParameters = menu.addAction("Show parameters");
795 renameAction = menu.addAction("Rename");
797 if(refBlock->isGroupBlock()){
798 openWindow = menu.addAction("Open/show group window");
801 duplicateAction = menu.addAction("Duplicate");
802 showRstClkIface = menu.addAction("Show reset/clock interfaces");
803 showRstClkIface->setCheckable(true);
804 showRstClkIface->setChecked(rstClkVisible);
805 showWishboneIface = menu.addAction("Show wishbone interfaces");
806 showWishboneIface->setCheckable(true);
807 showWishboneIface->setChecked(wishboneVisible);
809 removeAction = menu.addAction("Remove");
810 generateVHDL = menu.addAction("Generate VHDL");
813 QAction* selectedAction = NULL;
814 selectedAction = menu.exec(event->screenPos());
816 if(selectedAction == NULL) return ;
818 if (selectedAction == removeAction) {
819 if(ifaceItem != NULL) {
820 dispatcher->removeFunctionalInterface(Dispatcher::Design, ifaceItem);
823 dispatcher->removeBoxItem(Dispatcher::Design, this);
826 else if (selectedAction == duplicateAction) {
827 dispatcher->duplicateBoxItem(Dispatcher::Design, this);
829 else if(selectedAction == renameAction){
830 if(ifaceItem != NULL) {
831 dispatcher->renameInterface(Dispatcher::Design, ifaceItem);
834 if (refBlock->isFunctionalBlock()) {
835 dispatcher->renameFunctionalBlock(Dispatcher::Design, this);
837 else if (refBlock->isGroupBlock()) {
838 dispatcher->renameGroupBlock(Dispatcher::Design, childGroupItem);
842 else if(selectedAction == showProperties){
843 dispatcher->showProperties(Dispatcher::Design, ifaceItem);
845 else if (selectedAction == connectToGroup){
846 dispatcher->connectInterToGroup(Dispatcher::Design, ifaceItem);
848 else if (selectedAction == cloneInterface){
849 dispatcher->duplicateInterfaceItem(Dispatcher::Design, ifaceItem);
851 else if (selectedAction == openWindow){
852 dispatcher->showRaiseWindow(Dispatcher::Design, this);
854 else if(selectedAction == showRstClkIface) {
855 dispatcher->showRstClkIface(Dispatcher::Design, this);
857 else if(selectedAction == showWishboneIface) {
858 dispatcher->showWishboneIface(Dispatcher::Design, this);
860 else if(selectedAction == showParameters) {
861 new ParametersWindow(refBlock, params, NULL);
863 else if(selectedAction == showPatterns) {
864 dispatcher->showPatterns(Dispatcher::Design, ifaceItem);
866 else if(selectedAction == removeModifier) {
867 dispatcher->removeModifier(Dispatcher::Design, ifaceItem);
869 else if(selectedAction == showModifier) {
870 dispatcher->showModifier(Dispatcher::Design, ifaceItem);
872 else if(selectedAction == generateVHDL) {
873 dispatcher->generateBlockVHDL(Dispatcher::Design, this);
878 void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) {
882 int id = funcElement.attribute("id","none").toInt(&ok);
883 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
885 QString refXml = funcElement.attribute("ref_xml","none");
886 if(refXml == "none") throw(Exception(PROJECTFILE_CORRUPTED));
888 QString refMd5 = funcElement.attribute("ref_md5","none");
889 if(refMd5 == "none") throw(Exception(PROJECTFILE_CORRUPTED));
891 cout << "ref md5 : " << refMd5.toStdString() << "\nref xml : " << refXml.toStdString() << endl;
893 QString name = funcElement.attribute("name","none");
894 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
896 QStringList positionStr = funcElement.attribute("position","none").split(",");
897 if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
898 int posX = positionStr.at(0).toInt(&ok);
899 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
900 int posY = positionStr.at(1).toInt(&ok);
901 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
903 QStringList dimensionStr = funcElement.attribute("dimension","none").split(",");
904 if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
905 int dimX = dimensionStr.at(0).toInt(&ok);
906 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
907 int dimY = dimensionStr.at(1).toInt(&ok);
908 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
910 ReferenceBlock *referenceMd5 = NULL;
911 ReferenceBlock *referenceXml = NULL;
912 ReferenceBlock *reference = NULL;
913 if(refMd5 != "none") {
914 referenceMd5 = params->searchBlockByMd5(refMd5);
916 if(refXml != "none"){
917 referenceXml = params->searchBlockByXml(refXml);
919 if ((referenceMd5 == NULL) && (referenceXml == NULL)) {
920 throw(Exception(PROJECTFILE_CORRUPTED));
922 if (referenceMd5 != referenceXml) {
923 reference = referenceXml;
926 reference = referenceMd5;
929 GroupBlock* parentGroupBlock = AB_TO_GRP(((GroupItem *)parentItem())->getRefBlock());
930 FunctionalBlock* functionalBlock = params->getGraph()->createFunctionalBlock(parentGroupBlock, reference);
931 /* NB: addFunctionalBlock creates all interfaces from the reference, which is annoying when
932 reading bif_iface tags. Thus interface are all removed.
934 functionalBlock->setName(name);
935 setRefBlock(functionalBlock);
936 params->blockToItem.insert(functionalBlock,this);
939 setDimension(dimX,dimY);
943 QDomNodeList blockParamNodes = funcElement.elementsByTagName("bif_parameter");
944 // setting parameters value
945 for(int i=0; i<blockParamNodes.length(); i++){
946 QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement();
948 QString name = currentBlockParamNode.attribute("name","none");
949 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
951 QString value = currentBlockParamNode.attribute("value","none");
952 if(value == "none") throw(Exception(PROJECTFILE_CORRUPTED));
954 BlockParameter *blockParam = NULL;
955 blockParam = functionalBlock->getParameterFromName(name);
956 if (blockParam == NULL) throw(Exception(PROJECTFILE_CORRUPTED));
957 blockParam->setValue(value);
960 // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars
961 functionalBlock->removeAllInterfaces();
962 QDomNodeList interfaceNodes = funcElement.elementsByTagName("bif_iface");
963 // setting interfaces (user name, and for multiplicity>1 may be create some new ones)
964 for(int i=0; i<interfaceNodes.length(); i++) {
966 QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
968 QString name = currentInterfaceNode.attribute("name","none");
969 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
971 QString refName = currentInterfaceNode.attribute("ref_name","none");
972 if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));
974 ReferenceInterface* refInter = AI_TO_REF(reference->getIfaceFromName(refName));
975 cout << "creating iface from reference named " << qPrintable(refName) << endl;
976 FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter);
977 functionalInterface->setName(name);
978 functionalBlock->addInterface(functionalInterface);
980 // searching for control interface
981 QString ctlRefName = refName+"_enb";
982 ReferenceInterface* ctlRefIface = AI_TO_REF(reference->getIfaceFromName(ctlRefName));
984 if (ctlRefIface != NULL) {
985 cout << "found a control iface:" << qPrintable(ctlRefName) << endl;
986 FunctionalInterface *ctlIface = new FunctionalInterface(functionalBlock,ctlRefIface);
987 if (! ctlIface->setAssociatedIface(functionalInterface)) {
988 throw(Exception(PROJECTFILE_CORRUPTED));
990 ctlIface->setName(name+"_enb");
991 functionalBlock->addInterface(ctlIface);
995 // creating InterfaceItem
996 createInterfaceItems();
997 // setting them with saved values
998 for(int i=0; i<interfaceNodes.length(); i++){
1000 QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
1002 int id = currentInterfaceNode.attribute("id","none").toInt(&ok);
1003 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
1005 QString name = currentInterfaceNode.attribute("name","none");
1006 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
1008 QString orientationStr = currentInterfaceNode.attribute("orientation","none");
1009 int orientation = InterfaceItem::getIntOrientation(orientationStr);
1010 if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));
1012 double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);
1013 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
1015 InterfaceItem *interfaceItem = searchInterfaceItemByName(name);
1016 interfaceItem->setId(id);
1017 interfaceItem->setOrientation(orientation);
1018 interfaceItem->setPositionRatio(position);
1020 updateGeometry(Resize);
1023 void BoxItem::save(QXmlStreamWriter &writer) {
1024 if (refBlock->isFunctionalBlock()) {
1025 writer.writeStartElement("bi_functional");
1027 writer.writeAttribute("id",QString::number(id));
1028 writer.writeAttribute("ref_xml", ((FunctionalBlock*)refBlock)->getReferenceXmlFile());
1029 writer.writeAttribute("ref_md5", ((FunctionalBlock*)refBlock)->getReferenceHashMd5());
1030 writer.writeAttribute("name",refBlock->getName());
1031 QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
1032 writer.writeAttribute("position",attrPos);
1033 QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
1034 writer.writeAttribute("dimension",attrDim);
1036 writer.writeStartElement("bif_parameters");
1037 foreach(BlockParameter *param,refBlock->getParameters()){
1038 writer.writeStartElement("bif_parameter");
1040 writer.writeAttribute("name",param->getName());
1041 writer.writeAttribute("value",param->getValue().toString());
1043 writer.writeAttribute("context",param->getStrContext());
1044 writer.writeAttribute("type",param->getTypeString());
1046 writer.writeEndElement(); //</bif_parameter>
1048 writer.writeEndElement(); //</bif_parameters>
1050 writer.writeStartElement("bif_ifaces");
1051 writer.writeAttribute("count",QString::number(interfaces.length()));
1052 foreach(InterfaceItem* inter, interfaces){
1053 writer.writeStartElement("bif_iface");
1055 writer.writeAttribute("id",QString::number(inter->getId()));
1056 writer.writeAttribute("name",inter->getName());
1057 writer.writeAttribute("ref_name",inter->refInter->getName());
1058 writer.writeAttribute("orientation",inter->getStrOrientation());
1059 writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
1061 writer.writeEndElement(); //</bif_iface>
1063 writer.writeEndElement(); //</bif_ifaces>
1065 writer.writeEndElement(); //</bi_functional>
1068 writer.writeStartElement("bi_group");
1070 writer.writeAttribute("id",QString::number(id));
1071 writer.writeAttribute("inside_group",QString::number(childGroupItem->getId()));
1072 QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
1073 writer.writeAttribute("position",attrPos);
1074 QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
1075 writer.writeAttribute("dimension",attrDim);
1077 writer.writeStartElement("big_ifaces");
1078 writer.writeAttribute("count",QString::number(interfaces.length()));
1079 foreach(InterfaceItem* inter, interfaces){
1080 writer.writeStartElement("big_iface");
1082 writer.writeAttribute("id",QString::number(inter->getId()));
1083 writer.writeAttribute("ref_name",inter->refInter->getName());
1084 writer.writeAttribute("orientation",inter->getStrOrientation());
1085 writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
1087 writer.writeEndElement(); //</big_iface>
1090 writer.writeEndElement(); //</big_ifaces>
1091 writer.writeEndElement(); //</bi_group>
1095 QDataStream &operator <<(QDataStream &out, BoxItem &b) {
1096 out.setVersion(QDataStream::Qt_4_8);
1098 QByteArray blockData;
1099 QDataStream toWrite(&blockData, QIODevice::WriteOnly);
1101 QString refXml = ((FunctionalBlock*)b.refBlock)->getReferenceXmlFile();
1102 QByteArray xmlFile = QByteArray(refXml.toStdString().c_str());
1106 toWrite << (int)b.x();
1107 toWrite << (int)b.y();
1108 toWrite << b.boxWidth;
1109 toWrite << b.boxHeight;
1110 toWrite << b.getInterfaces().length();
1112 for(int i=0; i<b.getInterfaces().length(); i++){
1113 InterfaceItem *inter = b.getInterfaces().at(i);
1114 toWrite << inter->getId();
1115 //toWrite << inter->getName();
1116 toWrite << inter->getPositionRatio();
1117 toWrite << inter->getOrientation();
1125 QDataStream &operator >>(QDataStream &in, BoxItem &b) {
1127 in.setVersion(QDataStream::Qt_4_8);
1142 cout << "nbInter:" << nbInter << endl;
1143 for(int i=0; i<nbInter; i++){
1145 int id, orientation;
1146 double positionRatio;
1149 InterfaceItem *inter = b.getInterfaces().at(i);
1152 in >> positionRatio;
1156 inter->setPositionRatio(positionRatio);
1157 inter->setOrientation(orientation);
1158 inter->updatePosition();