X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/5d4e709cb8d460b2efc083e6e7999f1c3a0eb602..6a0ffdb10d7344d99e04c5518fca2b8295df94be:/BoxItem.cpp diff --git a/BoxItem.cpp b/BoxItem.cpp index 568e946..deee2cc 100644 --- a/BoxItem.cpp +++ b/BoxItem.cpp @@ -17,12 +17,15 @@ BoxItem::BoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, - Parameters *_params, GroupItem *parent) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params, parent) { + Parameters *_params, GroupItem *parent, int _lock, SpanType _span, Position _position) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params, _lock, parent) { /* NOTE : _refBlock : mandatory a FunctionalBlock or a GroupBlock */ - if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE)); + if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE)); + + span = _span; + position = _position; childGroupItem = NULL; //boxWidth = params->defaultBlockWidth; @@ -31,18 +34,148 @@ BoxItem::BoxItem(AbstractBlock *_refBlock, selected = false; setZValue(100); - setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges); + QGraphicsItem::GraphicsItemFlags flags = QGraphicsItem::ItemIsSelectable; + if (!isPositionLock()) { + flags |= QGraphicsItem::ItemIsMovable; + cout << "item " << qPrintable(refBlock->getName()) << "is movable" << endl; + } + if (!isDimensionLock()) { + flags |= QGraphicsItem::ItemSendsGeometryChanges; + cout << "item " << qPrintable(refBlock->getName()) << "is resizable" << endl; + } + setFlags(flags); + + bool freeBorder[4]; // 0 = east, 1 = north, 2 = west, 3 = south + Parameters::Direction dirs[4]; + for(int i=0;i<4;i++) { + freeBorder[i] = true; + } + dirs[0] = Parameters::East; + dirs[1] = Parameters::North; + dirs[2] = Parameters::West; + dirs[3] = Parameters::South; + - initInterfaceItems(); - updateGeometry(InterfaceMove); - resetInterfaceItemsPosition(); - QPointF initPos = QPointF(0.0,0.0) - originPoint; + if (position == Top) { + freeBorder[1] = false; + } + if (position == Bottom) { + freeBorder[3] = false; + } + if (position == Left) { + freeBorder[2] = false; + } + if (position == Right) { + freeBorder[0] = false; + } + if (span == HSpan) { + freeBorder[2] = false; + freeBorder[0] = false; + } + if (span == VSpan) { + freeBorder[1] = false; + freeBorder[3] = false; + } + Parameters::Direction dIn = Parameters::West; + Parameters::Direction dOut = Parameters::East; + Parameters::Direction dBi = Parameters::South; + if (freeBorder[2] == false) { + int i=3; + while (freeBorder[i] == false) { + i = (i+1)%4; + } + dIn = dirs[i]; + } + if (freeBorder[0] == false) { + int i=1; + while (freeBorder[i] == false) { + i = (i+1)%4; + } + dOut = dirs[i]; + } + if (freeBorder[3] == false) { + int i=0; + while (freeBorder[i] == false) { + i = (i+1)%4; + } + dBi = dirs[i]; + } + + createInterfaceItems(dIn,dOut,dBi); + updateGeometry(Creation); + + // position the item + int groupWidth = getScene()->getGroupItem()->getWidth(); + int groupHeight = getScene()->getGroupItem()->getHeight(); + double xx = 0.0,yy = 0.0; + if ((position == BoxItem::Left) || (position == BoxItem::TopLeft) || (position == BoxItem::BottomLeft)) { + xx = 0; + if ((span == VSpan) || (position == BoxItem::TopLeft)) { + yy = 0; + } + else if (position == BoxItem::BottomLeft) { + yy = groupHeight-totalHeight; + } + else { + yy = (groupHeight-totalHeight)/2.0; + } + } + else if ((position == BoxItem::Right) || (position == BoxItem::TopRight) || (position == BoxItem::BottomRight)) { + xx = groupWidth-totalWidth; + if (xx < 0) xx = 0; + if ((span == VSpan) || (position == BoxItem::TopRight)) { + yy = 0; + } + else if (position == BoxItem::BottomRight) { + yy = groupHeight-totalHeight; + } + else { + yy = (groupHeight-totalHeight)/2.0; + } + } + else if ((position == BoxItem::Top) || (position == BoxItem::TopLeft) || (position == BoxItem::TopRight)) { + yy = 0; + if ((span == HSpan) || (position == BoxItem::TopLeft)) { + xx = 0; + } + else if (position == BoxItem::TopRight) { + xx = groupWidth-totalWidth; + } + else { + xx = (groupWidth-totalWidth)/2.0; + } + } + else if ((position == BoxItem::Bottom) || (position == BoxItem::BottomLeft) || (position == BoxItem::BottomRight)) { + yy = groupHeight-totalHeight; + if ((span == HSpan) || (position == BoxItem::BottomLeft)) { + xx = 0; + } + else if (position == BoxItem::BottomRight) { + xx = groupWidth-totalWidth; + } + else { + xx = (groupWidth-totalWidth)/2.0; + } + } + else { + int marginConn = 2*(params->arrowWidth+params->arrowLineLength); + xx = (groupWidth-totalWidth)/2.0; + if (xx < marginConn) xx = marginConn; + yy = (groupHeight-totalHeight)/2.0; + if (yy < marginConn) yy = marginConn; + } + cout << "setting raw pos to " << xx << "," << yy << endl; + QPointF initPos(xx,yy); + initPos = initPos-originPoint; setPos(initPos); - //cout << "total size of block: " << totalWidth << "," << totalHeight << endl; - //cout << "pos in group: " << x() << "," << y() << endl; + cout << "total size of block: " << totalWidth << "," << totalHeight << endl; + cout << "pos in group: " << x() << "," << y() << endl; } -BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent) throw(Exception) : AbstractBoxItem(_dispatcher, _params, parent) { +BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent, int _lock, SpanType _span, Position _position) throw(Exception) : AbstractBoxItem(_dispatcher, _params, _lock, parent) { + + span = _span; + position = _position; refBlock = NULL; childGroupItem = NULL; @@ -50,7 +183,14 @@ BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent selected = false; setZValue(100); - setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges); + QGraphicsItem::GraphicsItemFlags flags = QGraphicsItem::ItemIsSelectable; + if (!isPositionLock()) { + flags |= QGraphicsItem::ItemIsMovable; + } + if (!isDimensionLock()) { + flags |= QGraphicsItem::ItemSendsGeometryChanges; + } + setFlags(flags); boxWidth = params->defaultBlockWidth; boxHeight = params->defaultBlockHeight; @@ -111,19 +251,22 @@ void BoxItem::updateMinimumSize() { int ifaceHeight = 0; foreach(InterfaceItem* iface, interfaces) { - ifaceWidth = iface->getNameWidth(); - ifaceHeight = iface->getNameHeight(); - if (iface->getOrientation() == Parameters::South) { - if (ifaceWidth > maxSouth) maxSouth = ifaceWidth; - } - else if (iface->getOrientation() == Parameters::North) { - if (ifaceWidth > maxNorth) maxNorth = ifaceWidth; - } - else if (iface->getOrientation() == Parameters::East) { - if (ifaceWidth > maxEast) maxEast = ifaceWidth; - } - else if (iface->getOrientation() == Parameters::West) { - if (ifaceWidth > maxWest) maxWest = ifaceWidth; + + if (iface->visible) { + ifaceWidth = iface->getNameWidth(); + ifaceHeight = iface->getNameHeight(); + if (iface->getOrientation() == Parameters::South) { + if (ifaceWidth > maxSouth) maxSouth = ifaceWidth; + } + else if (iface->getOrientation() == Parameters::North) { + if (ifaceWidth > maxNorth) maxNorth = ifaceWidth; + } + else if (iface->getOrientation() == Parameters::East) { + if (ifaceWidth > maxEast) maxEast = ifaceWidth; + } + else if (iface->getOrientation() == Parameters::West) { + if (ifaceWidth > maxWest) maxWest = ifaceWidth; + } } } @@ -151,34 +294,58 @@ bool BoxItem::updateGeometry(ChangeType type) { //cout << "current pos of block: " << currentPosition.x() << "," << currentPosition.y() << endl; QPointF oldOrigin = originPoint; QSize oldSize(totalWidth,totalHeight); - bool boxSizeChanged = false; // whatever the change, the minimum size may have changed updateMinimumSize(); - if (type == Resize) { + int groupWidth = getScene()->getGroupItem()->getWidth(); + int groupHeight = getScene()->getGroupItem()->getHeight(); + + cout << "minimum box size is " << minimumBoxWidth << "x" << minimumBoxHeight << endl; + cout << "group size is " << groupWidth << "x" << groupHeight << endl; + + if (type == Creation) { + + boxSizeChanged = true; + boxWidth = minimumBoxWidth; + boxHeight = minimumBoxHeight; + /* reset and update interfaces positions + * in case of spanning, the interface are positionned + * only on free borders. + */ + resetInterfaceItemsPosition(); + /* must test if the GroupItem must be resized */ + if ((span == HSpan) && (boxWidth < groupWidth)) { + boxWidth = groupWidth; // no interfaces in east/west (done in constructor) + } + else if ((span == VSpan) && (boxHeight < groupHeight)) { + boxHeight = groupHeight; + } + } + else if (type == Resize) { // resize implies to move interfaces and to update connections boxSizeChanged = true; + updateInterfaceAndConnectionItems(); } else if (type == InterfaceMove) { // if an interface moves, it may change the box size if (boxWidth < minimumBoxWidth) { boxWidth = minimumBoxWidth; boxSizeChanged = true; + updateInterfaceAndConnectionItems(); } if (boxHeight < minimumBoxHeight) { boxHeight = minimumBoxHeight; boxSizeChanged = true; + updateInterfaceAndConnectionItems(); } } - if (boxSizeChanged) { - updateInterfaceAndConnectionItems(); - } - + // update total size double x = 0.0; double y = 0.0; + totalWidth = boxWidth; totalHeight = boxHeight; @@ -199,6 +366,9 @@ bool BoxItem::updateGeometry(ChangeType type) { QSizeF newSize(totalWidth,totalHeight); originPoint.setX(x); originPoint.setY(y); + cout << "change orig pos of " << qPrintable(refBlock->getName()) << "to " << x << "," << y << endl; + cout << "box size is " << boxWidth << "x" << boxHeight << endl; + cout << "total size is " << totalWidth << "x" << totalHeight << endl; if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) { prepareGeometryChange(); @@ -224,37 +394,48 @@ void BoxItem::nameChanged() { void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if(params->editState == Parameters::EditBlockMove) { + + if (isPositionLock()) return; QPointF absPos = currentPosition + originPoint; int marginConn = 2*(params->arrowWidth+params->arrowLineLength); int gapX = event->scenePos().x() - cursorPosition.x(); int gapY = event->scenePos().y() - cursorPosition.y(); + // update cursor position + cursorPosition = event->scenePos(); //cout << "block abs. pos: " << absPos.x() << "," << absPos.y() << " | "; //cout << "block current. pos: " << currentPosition.x() << "," << currentPosition.y() << " | "; - if (absPos.x()+gapX < marginConn) { + if ((gapX < 0) && (absPos.x() == marginConn)) { + gapX = 0; + } + else if (absPos.x()+gapX < marginConn) { gapX = marginConn-absPos.x(); } - if (absPos.y()+gapY < marginConn) { + if ((gapY < 0) && (absPos.y() == marginConn)) { + gapY = 0; + } + else if (absPos.y()+gapY < marginConn) { gapY = marginConn-absPos.y(); } //cout << "gap: " << gapX << "," << gapY << endl; - QPointF gap(gapX,gapY); - currentPosition = currentPosition+gap; - setPos(currentPosition); - // update all connections from/to this block - foreach(ConnectionItem *item, getScene()->getConnectionItems()){ - if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) { - item->setPath(); + if ((gapX != 0) || (gapY != 0)) { + QPointF gap(gapX,gapY); + currentPosition = currentPosition+gap; + setPos(currentPosition); + // update all connections from/to this block + foreach(ConnectionItem *item, getScene()->getConnectionItems()){ + if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) { + item->setPath(); + } } + // udpate the groupitem + (getScene()->getGroupItem())->updateShape(); } - cursorPosition = event->scenePos(); - - // udpate the groupitem - (getScene()->getGroupItem())->updateShape(); } else if(params->editState == Parameters::EditBlockResize) { + if (isDimensionLock()) return; int gapX = event->scenePos().x() - cursorPosition.x(); int gapY = event->scenePos().y() - cursorPosition.y(); //cout << "gap: " << gapX << "," << gapY << endl; @@ -280,6 +461,15 @@ void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { } break; } + case Title: + cout << "abnormal case while resizing block" << endl; + break; + case BorderWest: + cout << "abnormal case while resizing block" << endl; + break; + case BorderNorth: + cout << "abnormal case while resizing block" << endl; + break; case NoBorder: cout << "abnormal case while resizing block" << endl; break; @@ -320,7 +510,7 @@ void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { int mode = getScene()->getEditionMode(); - dispatcher->setCurrentGroupWidget(getScene()->getGroupWidget()); + dispatcher->setCurrentGroupWidget(Dispatcher::Design, getScene()->getGroupWidget()); if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) { InterfaceItem *inter = getInterfaceItemFromCursor(x,y); @@ -364,9 +554,16 @@ void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { update(); } else if (params->cursorState == Parameters::CursorOnBorder) { - setFlag(ItemIsMovable, false); - cursorPosition = event->scenePos(); - params->setEditState(Parameters::EditBlockResize); + if (isDimensionLock()) { + if ((position == Bottom)||(position == Right)) { + event->ignore(); + } + } + else { + setFlag(ItemIsMovable, false); + cursorPosition = event->scenePos(); + params->setEditState(Parameters::EditBlockResize); + } } } } @@ -394,7 +591,7 @@ void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { else if (params->editState == Parameters::EditCloseConnection) { InterfaceItem* iface1 = getScene()->getSelectedInterface(1); InterfaceItem* iface2 = getScene()->getSelectedInterface(2); - bool ok = dispatcher->createConnection(iface1,iface2); + bool ok = dispatcher->createConnection(Dispatcher::Design, iface1,iface2); if (ok) { iface1->selected = false; update(iface1->boundingRect()); @@ -422,9 +619,9 @@ void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) { - QPointF pos = event->pos(); - qreal x = pos.x(); - qreal y = pos.y(); + QPointF evPos = event->pos(); + qreal x = evPos.x(); + qreal y = evPos.y(); currentBorder = NoBorder; int mode = getScene()->getEditionMode(); @@ -485,8 +682,14 @@ void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) { } } } - //QGraphicsItem::hoverMoveEvent(event); - event->ignore(); + if (params->cursorState == Parameters::CursorOnBorder) { + if (isDimensionLock()) { + if ((position == Bottom)||(position == Right)) { + event->setPos(evPos+pos()); + getScene()->getGroupItem()->hoverMoveEvent(event); + } + } + } } @@ -504,6 +707,10 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { QAction* showRstClkIface = NULL; QAction* showWishboneIface = NULL; QAction* showParameters = NULL; + QAction* showPatterns = NULL; + QAction* showModifier = NULL; + QAction* removeModifier = NULL; + QAction* generateVHDL = NULL; InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y()); // menu for interface @@ -550,6 +757,25 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { } } } + if (iface->getAssociatedIface() != NULL) { + if (iface->getDirection() == AbstractInterface::Output) { + showPatterns = menu.addAction("Show output pattern"); + } + else if (iface->getDirection() == AbstractInterface::Input) { + showPatterns = menu.addAction("Show input pattern"); + } + } + + if (iface->getAssociatedIface() != NULL) { + ConnectedInterface* assoIface = AI_TO_CON(iface->getAssociatedIface()); + if (assoIface->getInputModifier() != NULL) { + removeModifier = menu.addAction("Remove input modifier"); + } + if (assoIface->getInputModifier() != NULL) { + showModifier = menu.addAction("Show input modifier parameters"); + } + } + } // menu for blocks (group or func) else { @@ -575,6 +801,7 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { showWishboneIface->setChecked(wishboneVisible); } removeAction = menu.addAction("Remove"); + generateVHDL = menu.addAction("Generate VHDL"); } QAction* selectedAction = NULL; @@ -584,53 +811,62 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { if (selectedAction == removeAction) { if(ifaceItem != NULL) { - dispatcher->removeFunctionalInterface(ifaceItem); + dispatcher->removeFunctionalInterface(Dispatcher::Design, ifaceItem); } else { - dispatcher->removeBoxItem(this); + dispatcher->removeBoxItem(Dispatcher::Design, this); } } else if (selectedAction == duplicateAction) { - dispatcher->duplicateBoxItem(this); + dispatcher->duplicateBoxItem(Dispatcher::Design, this); } else if(selectedAction == renameAction){ if(ifaceItem != NULL) { - dispatcher->renameInterface(ifaceItem); + dispatcher->renameInterface(Dispatcher::Design, ifaceItem); } else { if (refBlock->isFunctionalBlock()) { - dispatcher->renameFunctionalBlock(this); + dispatcher->renameFunctionalBlock(Dispatcher::Design, this); } else if (refBlock->isGroupBlock()) { - dispatcher->renameGroupBlock(childGroupItem); + dispatcher->renameGroupBlock(Dispatcher::Design, childGroupItem); } } } else if(selectedAction == showProperties){ - dispatcher->showProperties(ifaceItem); + dispatcher->showProperties(Dispatcher::Design, ifaceItem); } else if (selectedAction == connectToGroup){ - dispatcher->connectInterToGroup(ifaceItem); + dispatcher->connectInterToGroup(Dispatcher::Design, ifaceItem); } else if (selectedAction == cloneInterface){ - dispatcher->duplicateInterfaceItem(ifaceItem); + dispatcher->duplicateInterfaceItem(Dispatcher::Design, ifaceItem); } else if (selectedAction == openWindow){ - dispatcher->showRaiseWindow(this); + dispatcher->showRaiseWindow(Dispatcher::Design, this); } else if(selectedAction == showRstClkIface) { - dispatcher->showRstClkIface(this); + dispatcher->showRstClkIface(Dispatcher::Design, this); } else if(selectedAction == showWishboneIface) { - dispatcher->showWishboneIface(this); + dispatcher->showWishboneIface(Dispatcher::Design, this); } - else if(selectedAction == showParameters) { - if (refBlock->isFunctionalBlock()) { - FunctionalBlock* fun = AB_TO_FUN(refBlock); - fun->createDelta(); - } + else if(selectedAction == showParameters) { new ParametersWindow(refBlock, params, NULL); - } + } + else if(selectedAction == showPatterns) { + dispatcher->showPatterns(Dispatcher::Design, ifaceItem); + } + else if(selectedAction == removeModifier) { + dispatcher->removeModifier(Dispatcher::Design, ifaceItem); + } + else if(selectedAction == showModifier) { + dispatcher->showModifier(Dispatcher::Design, ifaceItem); + } + else if(selectedAction == generateVHDL) { + dispatcher->generateBlockVHDL(Dispatcher::Design, this); + } + } void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) { @@ -678,7 +914,7 @@ void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) { throw(Exception(PROJECTFILE_CORRUPTED)); } if (referenceMd5 != referenceXml) { - throw(Exception(PROJECTFILE_CORRUPTED)); + reference = referenceXml; } else { reference = referenceMd5; @@ -691,6 +927,7 @@ void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) { */ functionalBlock->setName(name); setRefBlock(functionalBlock); + params->blockToItem.insert(functionalBlock,this); setPos(posX,posY); setDimension(dimX,dimY); @@ -748,9 +985,20 @@ void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) { functionalBlock->addInterface(ctlIface); } } + // connect clk and rst to group clk/rst or to clkrstgen + if ((name != "clkrstgen") && (parentGroupBlock != NULL)) { + try { + functionalBlock->connectClkReset(); + } + catch(Exception e) { + AbstractBlock* source = (AbstractBlock *)(e.getSource()); + cerr << qPrintable(source->getName()) << ":" << qPrintable(e.getMessage()) << endl; + throw(e); + } + } // creating InterfaceItem - initInterfaceItems(); + createInterfaceItems(); // setting them with saved values for(int i=0; igetId())); - QString attrPos = QString::number(pos().x()).append(",").append(QString::number(pos().y())); + QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y()))); writer.writeAttribute("position",attrPos); QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight())); writer.writeAttribute("dimension",attrDim);