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) {
211 if (!visible) return;
213 QPen pen(Qt::black, 3);
215 pen.setColor(Qt::red);
217 painter->setPen(pen);
218 painter->setBrush(Qt::yellow);
220 painter->drawRect(0,0,boxWidth, boxHeight);
221 painter->drawText(0,0,boxWidth, boxHeight,Qt::AlignCenter | Qt::TextWordWrap,QString(refBlock->getName()));
222 foreach(InterfaceItem *inter, interfaces) {
223 inter->paint(painter);
227 void BoxItem::moveTo(QPointF dest) {
229 currentPosition = dest;
232 bool BoxItem::isBoxItem() {
236 void BoxItem::updateMinimumSize() {
242 int nbSouth = nbInterfacesByOrientation(Parameters::South);
243 int nbNorth = nbInterfacesByOrientation(Parameters::North);
244 int nbMaxSN = nbNorth;
245 if (nbSouth > nbNorth) nbMaxSN = nbSouth;
246 int nbEast = nbInterfacesByOrientation(Parameters::East);
247 int nbWest = nbInterfacesByOrientation(Parameters::West);
248 int nbMaxEW = nbEast;
249 if (nbWest > nbEast) {
256 foreach(InterfaceItem* iface, interfaces) {
258 if (iface->visible) {
259 ifaceWidth = iface->getNameWidth();
260 ifaceHeight = iface->getNameHeight();
261 if (iface->getOrientation() == Parameters::South) {
262 if (ifaceWidth > maxSouth) maxSouth = ifaceWidth;
264 else if (iface->getOrientation() == Parameters::North) {
265 if (ifaceWidth > maxNorth) maxNorth = ifaceWidth;
267 else if (iface->getOrientation() == Parameters::East) {
268 if (ifaceWidth > maxEast) maxEast = ifaceWidth;
270 else if (iface->getOrientation() == Parameters::West) {
271 if (ifaceWidth > maxWest) maxWest = ifaceWidth;
276 /* NB: the width layout is the following
277 ifaceMargin | maxWest | nameMargin | name | nameMargin | maxEast | ifaceMargin
279 minimumBoxWidth = maxWest+maxEast+nameWidth+2*(ifaceMargin+nameMargin);
280 // if the minimum is not sufficent taking into account N/S interfaces
281 if (minimumBoxWidth < (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1))) {
282 minimumBoxWidth = (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1));
284 minimumBoxHeight = maxNorth+maxSouth+3*ifaceMargin;
285 if (minimumBoxHeight < (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1))) {
286 minimumBoxHeight = (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1));
291 /* updateGeometry() :
294 bool BoxItem::updateGeometry(ChangeType type) {
296 currentPosition = pos();
297 //cout << "current pos of block: " << currentPosition.x() << "," << currentPosition.y() << endl;
298 QPointF oldOrigin = originPoint;
299 QSize oldSize(totalWidth,totalHeight);
300 bool boxSizeChanged = false;
302 // whatever the change, the minimum size may have changed
305 int groupWidth = getScene()->getGroupItem()->getWidth();
306 int groupHeight = getScene()->getGroupItem()->getHeight();
308 cout << "minimum box size is " << minimumBoxWidth << "x" << minimumBoxHeight << endl;
309 cout << "group size is " << groupWidth << "x" << groupHeight << endl;
311 if (type == Creation) {
313 boxSizeChanged = true;
314 boxWidth = minimumBoxWidth;
315 boxHeight = minimumBoxHeight;
316 /* reset and update interfaces positions
317 * in case of spanning, the interface are positionned
318 * only on free borders.
320 resetInterfaceItemsPosition();
321 /* must test if the GroupItem must be resized */
322 if ((span == HSpan) && (boxWidth < groupWidth)) {
323 boxWidth = groupWidth; // no interfaces in east/west (done in constructor)
325 else if ((span == VSpan) && (boxHeight < groupHeight)) {
326 boxHeight = groupHeight;
329 else if (type == Resize) {
330 // resize implies to move interfaces and to update connections
331 boxSizeChanged = true;
332 updateInterfaceAndConnectionItems();
334 else if (type == InterfaceMove) {
335 // if an interface moves, it may change the box size
336 if (boxWidth < minimumBoxWidth) {
337 boxWidth = minimumBoxWidth;
338 boxSizeChanged = true;
339 updateInterfaceAndConnectionItems();
341 if (boxHeight < minimumBoxHeight) {
342 boxHeight = minimumBoxHeight;
343 boxSizeChanged = true;
344 updateInterfaceAndConnectionItems();
352 totalWidth = boxWidth;
353 totalHeight = boxHeight;
355 if(isInterfaces(Parameters::East)){
356 totalWidth += params->arrowWidth+params->arrowLineLength;
358 if(isInterfaces(Parameters::West)){
359 totalWidth += params->arrowWidth+params->arrowLineLength;
360 x -= params->arrowWidth+params->arrowLineLength;
362 if(isInterfaces(Parameters::South)){
363 totalHeight += params->arrowWidth+params->arrowLineLength;
365 if(isInterfaces(Parameters::North)){
366 totalHeight += params->arrowWidth+params->arrowLineLength;
367 y -= params->arrowWidth+params->arrowLineLength;
369 QSizeF newSize(totalWidth,totalHeight);
372 cout << "change orig pos of " << qPrintable(refBlock->getName()) << "to " << x << "," << y << endl;
373 cout << "box size is " << boxWidth << "x" << boxHeight << endl;
374 cout << "total size is " << totalWidth << "x" << totalHeight << endl;
376 if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
377 prepareGeometryChange();
383 void BoxItem::nameChanged() {
385 QFontMetrics fmId(params->defaultBlockFont);
386 nameWidth = fmId.width(refBlock->getName());
387 nameHeight = fmId.height();
389 if (updateGeometry(InterfaceMove)) {
390 //cout << "must recompute group item geometry" << endl;
391 (getScene()->getGroupItem())->updateShape();
393 // force the update in case of size has not changed
397 void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
399 if(params->editState == Parameters::EditBlockMove) {
401 if (isPositionLock()) return;
402 QPointF absPos = currentPosition + originPoint;
403 int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
404 int gapX = event->scenePos().x() - cursorPosition.x();
405 int gapY = event->scenePos().y() - cursorPosition.y();
406 // update cursor position
407 cursorPosition = event->scenePos();
409 //cout << "block abs. pos: " << absPos.x() << "," << absPos.y() << " | ";
410 //cout << "block current. pos: " << currentPosition.x() << "," << currentPosition.y() << " | ";
412 if ((position == Left) || (position == Right)) {
415 else if ((gapX < 0) && (absPos.x() == marginConn)) {
418 else if (absPos.x()+gapX < marginConn) {
419 gapX = marginConn-absPos.x();
421 if ((position == Top) || (position == Bottom)) {
424 else if ((gapY < 0) && (absPos.y() == marginConn)) {
427 else if (absPos.y()+gapY < marginConn) {
428 gapY = marginConn-absPos.y();
430 //cout << "gap: " << gapX << "," << gapY << endl;
431 if ((gapX != 0) || (gapY != 0)) {
432 QPointF gap(gapX,gapY);
433 currentPosition = currentPosition+gap;
434 setPos(currentPosition);
435 // update all connections from/to this block
436 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
437 if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
441 // udpate the groupitem
442 (getScene()->getGroupItem())->updateShape();
445 else if(params->editState == Parameters::EditBlockResize) {
447 if (isDimensionLock()) return;
448 int gapX = event->scenePos().x() - cursorPosition.x();
449 int gapY = event->scenePos().y() - cursorPosition.y();
450 //cout << "gap: " << gapX << "," << gapY << endl;
451 switch(currentBorder){
453 if(boxWidth+gapX > minimumBoxWidth){
459 if(boxHeight+gapY > minimumBoxHeight){
464 case CornerSouthEast: {
465 if(boxWidth+gapX > minimumBoxWidth){
468 if(boxHeight+gapY > minimumBoxHeight){
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 cout << "abnormal case while resizing block" << endl;
486 // recompute the geometry of the block and possibly the group item
487 if (updateGeometry(Resize)) {
488 (getScene()->getGroupItem())->updateShape();
491 cursorPosition = event->scenePos();
493 else if(params->editState == Parameters::EditInterfaceMove) {
494 prepareGeometryChange();
495 moveInterfaceItemTo(event->pos());
496 // recompute the geometry of the block
497 if (updateGeometry(InterfaceMove)) {
498 //cout << "must recompute group item geometry" << endl;
499 (getScene()->getGroupItem())->updateShape();
501 // update connection from/to the selected interface
502 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
503 if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
510 void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
512 QPointF pos = event->pos();
516 //QGraphicsItem::mousePressEvent(event);
518 if(event->button() == Qt::RightButton) return;
520 int mode = getScene()->getEditionMode();
522 dispatcher->setCurrentGroupWidget(Dispatcher::Design, getScene()->getGroupWidget());
524 if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) {
525 InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
528 if (params->editState == Parameters::EditNoOperation) {
529 getScene()->setSelectedInterface(1,inter);
530 params->setEditState(Parameters::EditStartConnection);
532 else if (params->editState == Parameters::EditStartConnection) {
533 if (inter == getScene()->getSelectedInterface(1)) {
534 params->setEditState(Parameters::EditAbortConnection);
537 getScene()->setSelectedInterface(2,inter);
538 params->setEditState(Parameters::EditCloseConnection);
543 else if (mode == GroupScene::ItemEdition) {
544 //setZValue(zValue()+100);
545 if (params->cursorState == Parameters::CursorOnInterface) {
546 InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
548 if (inter == currentInterface) {
549 params->setEditState(Parameters::EditInterfaceDeselect);
552 setFlag(ItemIsMovable, false);
553 currentInterface = inter;
554 params->setEditState(Parameters::EditInterfaceMove);
558 else if (params->cursorState == Parameters::CursorInBlock) {
559 selected = !selected;
560 params->setEditState(Parameters::EditBlockMove);
561 cursorPosition = event->scenePos();
562 //cout << "cursor current pos. in scene " << cursorPosition.x() << "," << cursorPosition.y() << endl;
565 else if (params->cursorState == Parameters::CursorOnBorder) {
566 if (isDimensionLock()) {
567 if ((position == Bottom)||(position == Right)) {
572 setFlag(ItemIsMovable, false);
573 cursorPosition = event->scenePos();
574 params->setEditState(Parameters::EditBlockResize);
580 void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
582 //setZValue(zValue()-100);
584 int mode = getScene()->getEditionMode();
586 if (mode == GroupScene::AddConnection) {
588 if (params->editState == Parameters::EditStartConnection) {
589 InterfaceItem* iface = getScene()->getSelectedInterface(1);
590 iface->selected = true;
591 update(iface->boundingRect());
593 else if (params->editState == Parameters::EditAbortConnection) {
594 InterfaceItem* iface = getScene()->getSelectedInterface(1);
595 iface->selected = false;
596 update(iface->boundingRect());
597 getScene()->setSelectedInterface(1,NULL);
598 params->setEditState(Parameters::EditNoOperation);
600 else if (params->editState == Parameters::EditCloseConnection) {
601 InterfaceItem* iface1 = getScene()->getSelectedInterface(1);
602 InterfaceItem* iface2 = getScene()->getSelectedInterface(2);
603 bool ok = dispatcher->createConnection(Dispatcher::Design, iface1,iface2);
605 iface1->selected = false;
606 update(iface1->boundingRect());
607 iface2->selected = false;
608 update(iface2->boundingRect());
609 getScene()->setSelectedInterface(1,NULL);
610 getScene()->setSelectedInterface(2,NULL);
611 params->setEditState(Parameters::EditNoOperation);
614 //QMessageBox::warning(NULL,"Error","Cannot connect selected interfaces", QMessageBox::Ok);
615 getScene()->setSelectedInterface(2,NULL);
616 params->setEditState(Parameters::EditStartConnection);
620 else if (mode == GroupScene::ItemEdition) {
621 currentInterface = NULL;
622 params->editState = Parameters::EditNoOperation;
623 setFlag(ItemIsMovable);
626 QGraphicsItem::mouseReleaseEvent(event);
629 void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
631 QPointF evPos = event->pos();
634 currentBorder = NoBorder;
635 int mode = getScene()->getEditionMode();
637 if (mode == GroupScene::AddConnection) {
638 InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
640 params->cursorState = Parameters::CursorOnInterface;
641 setCursor(Qt::PointingHandCursor);
644 params->cursorState = Parameters::CursorNowhere;
645 setCursor(Qt::ArrowCursor);
648 else if (mode == GroupScene::ItemEdition) {
652 InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
654 params->cursorState = Parameters::CursorOnInterface;
655 setCursor(Qt::PointingHandCursor);
657 else if ((x>boxWidth-marginE)&&(x<boxWidth)) {
659 params->cursorState = Parameters::CursorOnBorder;
661 if ((y>boxHeight-2*marginS)&&(y<boxHeight)) {
662 currentBorder = CornerSouthEast;
663 setCursor(Qt::SizeFDiagCursor);
666 currentBorder = BorderEast;
667 setCursor(Qt::SizeHorCursor);
670 else if ((y>boxHeight-marginS)&&(y<boxHeight)) {
672 params->cursorState = Parameters::CursorOnBorder;
674 if ((x>boxWidth-2*marginE)&&(x<boxWidth)) {
675 currentBorder = CornerSouthEast;
676 setCursor(Qt::SizeFDiagCursor);
679 currentBorder = BorderSouth;
680 setCursor(Qt::SizeVerCursor);
684 if ((x>0) && (x<boxWidth-marginE) && (y>0) && (y<boxHeight-marginS)) {
685 params->cursorState = Parameters::CursorInBlock;
686 setCursor(Qt::OpenHandCursor);
689 params->cursorState = Parameters::CursorNowhere;
690 setCursor(Qt::ArrowCursor);
694 if (params->cursorState == Parameters::CursorOnBorder) {
695 if (isDimensionLock()) {
696 if ((position == Bottom)||(position == Right)) {
697 event->setPos(evPos+pos());
698 getScene()->getGroupItem()->hoverMoveEvent(event);
705 void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
708 QAction* titleAction = NULL;
709 QAction* removeAction = NULL;
710 QAction* duplicateAction = NULL;
711 QAction* renameAction = NULL;
712 QAction* connectToGroup = NULL;
713 QAction* showProperties = NULL;
714 QAction* cloneInterface = NULL;
715 QAction* openWindow = NULL;
716 QAction* showRstClkIface = NULL;
717 QAction* showWishboneIface = NULL;
718 QAction* showParameters = NULL;
719 QAction* showPatterns = NULL;
720 QAction* showModifier = NULL;
721 QAction* removeModifier = NULL;
722 QAction* generateVHDL = NULL;
724 InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y());
725 // menu for interface
726 if( ifaceItem != NULL){
728 titleAction = menu.addAction("Interface operations");
729 titleAction->setEnabled(false);
733 showProperties = menu.addAction("Show properties");
734 renameAction = menu.addAction("Rename");
736 ConnectedInterface* iface = ifaceItem->refInter;
737 ConnectedInterface* ifaceGroup = NULL;
738 bool canRemove = true;
740 if ((iface->getDirection() == AbstractInterface::Input) && (iface->getConnectedFrom() == NULL)) {
741 connectToGroup = menu.addAction("Connect to group input");
743 else if ((iface->getDirection() == AbstractInterface::Output) && (iface->getConnectionToParentGroup() == NULL)) {
744 connectToGroup = menu.addAction("Connect to group output");
746 else if (iface->getConnectionFromParentGroup() != NULL) {
747 ifaceGroup = iface->getConnectionFromParentGroup();
748 if (ifaceGroup->isConnectedFrom()) {
752 else if (iface->getConnectionToParentGroup() != NULL) {
753 ifaceGroup = iface->getConnectionToParentGroup();
754 if (ifaceGroup->isConnectedTo()) {
759 if (iface->isFunctionalInterface()) {
760 FunctionalInterface* fi = AI_TO_FUN(ifaceItem->refInter);
761 ReferenceInterface* ri = (ReferenceInterface*)(fi->getReference());
762 if(ri->getMultiplicity() == -1 || ri->getMultiplicity() > 1){
763 cloneInterface = menu.addAction("Duplicate");
764 if ((canRemove) && (fi->getInterfaceMultiplicity() > 1)) {
765 removeAction = menu.addAction("Remove");
769 if (iface->getAssociatedIface() != NULL) {
770 if (iface->getDirection() == AbstractInterface::Output) {
771 showPatterns = menu.addAction("Show output pattern");
773 else if (iface->getDirection() == AbstractInterface::Input) {
774 showPatterns = menu.addAction("Show input pattern");
778 if (iface->getAssociatedIface() != NULL) {
779 ConnectedInterface* assoIface = AI_TO_CON(iface->getAssociatedIface());
780 if (assoIface->getInputModifier() != NULL) {
781 removeModifier = menu.addAction("Remove input modifier");
783 if (assoIface->getInputModifier() != NULL) {
784 showModifier = menu.addAction("Show input modifier parameters");
789 // menu for blocks (group or func)
791 titleAction = menu.addAction("Block operations");
792 titleAction->setEnabled(false);
795 if (refBlock->nbParameters() > 0) {
796 showParameters = menu.addAction("Show parameters");
798 renameAction = menu.addAction("Rename");
800 if(refBlock->isGroupBlock()){
801 openWindow = menu.addAction("Open/show group window");
804 duplicateAction = menu.addAction("Duplicate");
805 showRstClkIface = menu.addAction("Show reset/clock interfaces");
806 showRstClkIface->setCheckable(true);
807 showRstClkIface->setChecked(rstClkVisible);
808 showWishboneIface = menu.addAction("Show wishbone interfaces");
809 showWishboneIface->setCheckable(true);
810 showWishboneIface->setChecked(wishboneVisible);
812 removeAction = menu.addAction("Remove");
813 generateVHDL = menu.addAction("Generate VHDL");
816 QAction* selectedAction = NULL;
817 selectedAction = menu.exec(event->screenPos());
819 if(selectedAction == NULL) return ;
821 if (selectedAction == removeAction) {
822 if(ifaceItem != NULL) {
823 dispatcher->removeFunctionalInterface(Dispatcher::Design, ifaceItem);
826 dispatcher->removeBoxItem(Dispatcher::Design, this);
829 else if (selectedAction == duplicateAction) {
830 dispatcher->duplicateBoxItem(Dispatcher::Design, this);
832 else if(selectedAction == renameAction){
833 if(ifaceItem != NULL) {
834 dispatcher->renameInterface(Dispatcher::Design, ifaceItem);
837 if (refBlock->isFunctionalBlock()) {
838 dispatcher->renameFunctionalBlock(Dispatcher::Design, this);
840 else if (refBlock->isGroupBlock()) {
841 dispatcher->renameGroupBlock(Dispatcher::Design, childGroupItem);
845 else if(selectedAction == showProperties){
846 dispatcher->showProperties(Dispatcher::Design, ifaceItem);
848 else if (selectedAction == connectToGroup){
849 dispatcher->connectInterToGroup(Dispatcher::Design, ifaceItem);
851 else if (selectedAction == cloneInterface){
852 dispatcher->duplicateInterfaceItem(Dispatcher::Design, ifaceItem);
854 else if (selectedAction == openWindow){
855 dispatcher->showRaiseWindow(Dispatcher::Design, this);
857 else if(selectedAction == showRstClkIface) {
858 dispatcher->showRstClkIface(Dispatcher::Design, this);
860 else if(selectedAction == showWishboneIface) {
861 dispatcher->showWishboneIface(Dispatcher::Design, this);
863 else if(selectedAction == showParameters) {
864 new ParametersWindow(refBlock, params, NULL);
866 else if(selectedAction == showPatterns) {
867 dispatcher->showPatterns(Dispatcher::Design, ifaceItem);
869 else if(selectedAction == removeModifier) {
870 dispatcher->removeModifier(Dispatcher::Design, ifaceItem);
872 else if(selectedAction == showModifier) {
873 dispatcher->showModifier(Dispatcher::Design, ifaceItem);
875 else if(selectedAction == generateVHDL) {
876 dispatcher->generateBlockVHDL(Dispatcher::Design, this);
881 void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) {
885 int id = funcElement.attribute("id","none").toInt(&ok);
886 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
888 QString refXml = funcElement.attribute("ref_xml","none");
889 if(refXml == "none") throw(Exception(PROJECTFILE_CORRUPTED));
891 QString refMd5 = funcElement.attribute("ref_md5","none");
892 if(refMd5 == "none") throw(Exception(PROJECTFILE_CORRUPTED));
894 cout << "ref md5 : " << refMd5.toStdString() << "\nref xml : " << refXml.toStdString() << endl;
896 QString name = funcElement.attribute("name","none");
897 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
899 QStringList positionStr = funcElement.attribute("position","none").split(",");
900 if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
901 int posX = positionStr.at(0).toInt(&ok);
902 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
903 int posY = positionStr.at(1).toInt(&ok);
904 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
906 QStringList dimensionStr = funcElement.attribute("dimension","none").split(",");
907 if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
908 int dimX = dimensionStr.at(0).toInt(&ok);
909 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
910 int dimY = dimensionStr.at(1).toInt(&ok);
911 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
913 QString visStr = funcElement.attribute("visible","none");
914 bool showItem = true;
915 if (visStr == "false") {
919 ReferenceBlock *referenceMd5 = NULL;
920 ReferenceBlock *referenceXml = NULL;
921 ReferenceBlock *reference = NULL;
922 if(refMd5 != "none") {
923 referenceMd5 = params->searchBlockByMd5(refMd5);
925 if(refXml != "none"){
926 referenceXml = params->searchBlockByXml(refXml);
928 if ((referenceMd5 == NULL) && (referenceXml == NULL)) {
929 throw(Exception(PROJECTFILE_CORRUPTED));
931 if (referenceMd5 != referenceXml) {
932 reference = referenceXml;
935 reference = referenceMd5;
938 GroupBlock* parentGroupBlock = AB_TO_GRP(((GroupItem *)parentItem())->getRefBlock());
939 FunctionalBlock* functionalBlock = params->getGraph()->createFunctionalBlock(parentGroupBlock, reference, false);
940 /* NB: addFunctionalBlock creates all interfaces from the reference, which is annoying when
941 reading bif_iface tags. Thus interface are all removed.
943 functionalBlock->setName(name);
944 setRefBlock(functionalBlock);
945 params->blockToItem.insert(functionalBlock,this);
948 setDimension(dimX,dimY);
952 QDomNodeList blockParamNodes = funcElement.elementsByTagName("bif_parameter");
953 // setting parameters value
954 for(int i=0; i<blockParamNodes.length(); i++){
955 QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement();
957 QString name = currentBlockParamNode.attribute("name","none");
958 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
960 QString value = currentBlockParamNode.attribute("value","none");
961 if(value == "none") throw(Exception(PROJECTFILE_CORRUPTED));
963 BlockParameter *blockParam = NULL;
964 blockParam = functionalBlock->getParameterFromName(name);
965 if (blockParam == NULL) throw(Exception(PROJECTFILE_CORRUPTED));
966 blockParam->setValue(value);
969 // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars
970 //functionalBlock->removeAllInterfaces();
971 QDomNodeList interfaceNodes = funcElement.elementsByTagName("bif_iface");
972 // setting interfaces (user name, and for multiplicity>1 may be create some new ones)
973 for(int i=0; i<interfaceNodes.length(); i++) {
975 QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
977 QString name = currentInterfaceNode.attribute("name","none");
978 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
980 QString refName = currentInterfaceNode.attribute("ref_name","none");
981 if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));
983 ReferenceInterface* refInter = AI_TO_REF(reference->getIfaceFromName(refName));
984 cout << "creating iface from reference named " << qPrintable(refName) << endl;
985 FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter);
986 functionalInterface->setName(name);
987 functionalBlock->addInterface(functionalInterface);
989 // searching for control interface
990 QString ctlRefName = refName+"_enb";
991 ReferenceInterface* ctlRefIface = AI_TO_REF(reference->getIfaceFromName(ctlRefName));
993 if (ctlRefIface != NULL) {
994 cout << "found a control iface:" << qPrintable(ctlRefName) << endl;
995 FunctionalInterface *ctlIface = new FunctionalInterface(functionalBlock,ctlRefIface);
996 if (! ctlIface->setAssociatedIface(functionalInterface)) {
997 throw(Exception(PROJECTFILE_CORRUPTED));
999 ctlIface->setName(name+"_enb");
1000 functionalBlock->addInterface(ctlIface);
1004 // creating InterfaceItem
1005 createInterfaceItems();
1006 // setting them with saved values
1007 for(int i=0; i<interfaceNodes.length(); i++){
1009 QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
1011 int id = currentInterfaceNode.attribute("id","none").toInt(&ok);
1012 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
1014 QString name = currentInterfaceNode.attribute("name","none");
1015 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
1017 QString orientationStr = currentInterfaceNode.attribute("orientation","none");
1018 int orientation = InterfaceItem::getIntOrientation(orientationStr);
1019 if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));
1021 double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);
1022 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
1024 InterfaceItem *interfaceItem = searchInterfaceItemByName(name);
1025 interfaceItem->setId(id);
1026 interfaceItem->setOrientation(orientation);
1027 interfaceItem->setPositionRatio(position);
1029 setVisible(showItem);
1030 updateGeometry(Resize);
1033 void BoxItem::save(QXmlStreamWriter &writer) {
1034 if (refBlock->isFunctionalBlock()) {
1035 writer.writeStartElement("bi_functional");
1037 writer.writeAttribute("id",QString::number(id));
1038 writer.writeAttribute("ref_xml", ((FunctionalBlock*)refBlock)->getReferenceXmlFile());
1039 writer.writeAttribute("ref_md5", ((FunctionalBlock*)refBlock)->getReferenceHashMd5());
1040 writer.writeAttribute("name",refBlock->getName());
1041 QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
1042 writer.writeAttribute("position",attrPos);
1043 QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
1044 writer.writeAttribute("dimension",attrDim);
1046 writer.writeAttribute("visible","false");
1049 writer.writeStartElement("bif_parameters");
1050 foreach(BlockParameter *param,refBlock->getParameters()){
1051 writer.writeStartElement("bif_parameter");
1053 writer.writeAttribute("name",param->getName());
1054 writer.writeAttribute("value",param->getValue().toString());
1056 writer.writeAttribute("context",param->getStrContext());
1057 writer.writeAttribute("type",param->getTypeString());
1059 writer.writeEndElement(); //</bif_parameter>
1061 writer.writeEndElement(); //</bif_parameters>
1063 writer.writeStartElement("bif_ifaces");
1064 writer.writeAttribute("count",QString::number(interfaces.length()));
1065 foreach(InterfaceItem* inter, interfaces){
1066 writer.writeStartElement("bif_iface");
1068 writer.writeAttribute("id",QString::number(inter->getId()));
1069 writer.writeAttribute("name",inter->getName());
1070 writer.writeAttribute("ref_name",inter->getReferenceName());
1071 writer.writeAttribute("orientation",inter->getStrOrientation());
1072 writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
1074 writer.writeEndElement(); //</bif_iface>
1076 writer.writeEndElement(); //</bif_ifaces>
1078 writer.writeEndElement(); //</bi_functional>
1081 writer.writeStartElement("bi_group");
1083 writer.writeAttribute("id",QString::number(id));
1084 writer.writeAttribute("inside_group",QString::number(childGroupItem->getId()));
1085 QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
1086 writer.writeAttribute("position",attrPos);
1087 QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
1088 writer.writeAttribute("dimension",attrDim);
1090 writer.writeStartElement("big_ifaces");
1091 writer.writeAttribute("count",QString::number(interfaces.length()));
1092 foreach(InterfaceItem* inter, interfaces){
1093 writer.writeStartElement("big_iface");
1095 writer.writeAttribute("id",QString::number(inter->getId()));
1096 writer.writeAttribute("ref_name",inter->refInter->getName());
1097 writer.writeAttribute("orientation",inter->getStrOrientation());
1098 writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
1100 writer.writeEndElement(); //</big_iface>
1103 writer.writeEndElement(); //</big_ifaces>
1104 writer.writeEndElement(); //</bi_group>
1108 QDataStream &operator <<(QDataStream &out, BoxItem &b) {
1109 out.setVersion(QDataStream::Qt_4_8);
1111 QByteArray blockData;
1112 QDataStream toWrite(&blockData, QIODevice::WriteOnly);
1114 QString refXml = ((FunctionalBlock*)b.refBlock)->getReferenceXmlFile();
1115 QByteArray xmlFile = QByteArray(refXml.toStdString().c_str());
1119 toWrite << (int)b.x();
1120 toWrite << (int)b.y();
1121 toWrite << b.boxWidth;
1122 toWrite << b.boxHeight;
1123 toWrite << b.getInterfaces().length();
1125 for(int i=0; i<b.getInterfaces().length(); i++){
1126 InterfaceItem *inter = b.getInterfaces().at(i);
1127 toWrite << inter->getId();
1128 //toWrite << inter->getName();
1129 toWrite << inter->getPositionRatio();
1130 toWrite << inter->getOrientation();
1138 QDataStream &operator >>(QDataStream &in, BoxItem &b) {
1140 in.setVersion(QDataStream::Qt_4_8);
1155 cout << "nbInter:" << nbInter << endl;
1156 for(int i=0; i<nbInter; i++){
1158 int id, orientation;
1159 double positionRatio;
1162 InterfaceItem *inter = b.getInterfaces().at(i);
1165 in >> positionRatio;
1169 inter->setPositionRatio(positionRatio);
1170 inter->setOrientation(orientation);
1171 inter->updatePosition();