3 #include "ConnectionItem.h"
4 #include "InterfaceItem.h"
5 #include "Dispatcher.h"
6 #include "Parameters.h"
8 #include "StimuliItem.h"
9 #include "AbstractBlock.h"
10 #include "AbstractInterface.h"
11 #include "ConnectedInterface.h"
12 #include "GroupScene.h"
13 #include "ParametersWindow.h"
14 #include "GroupBlock.h"
15 #include "GroupInterface.h"
18 GroupItem::GroupItem(BoxItem *_parentItem,
19 AbstractBlock *_refBlock,
20 Dispatcher *_dispatcher,
21 Parameters *_params) throw(Exception) :AbstractBoxItem( _refBlock, _dispatcher, _params) {
23 parentItem = _parentItem;
24 if (parentItem != NULL) {
25 parentItem->setChildGroupItem(this);
30 rectTitle = QRectF(0,-(nameHeight+2*nameMargin),nameWidth+2*nameMargin,nameHeight+2*nameMargin);
32 /* NB: boxPoint represent the position in scene of the top-left corner of the box, thus
33 * without taking into account the interfaces. It is also the reference position to draw the item.
34 * Nevertheless, in order to place sources in the scene, the real bouding box of the group is determined
35 * from originPoint and totalWidth/totalheight.
37 boxPoint = QPointF(0,0);
39 totalHeight = boxHeight + rectTitle.height();
40 totalWidth = boxWidth;
46 setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
49 updateGeometry(Creation);
51 cout << "total size of group: " << totalWidth << "," << totalHeight << endl;
52 cout << "pos in scene: " << x() << "," << y() << endl;
55 GroupItem::GroupItem(Dispatcher *_dispatcher,Parameters *_params) throw(Exception) :AbstractBoxItem(_dispatcher, _params) {
58 rectTitle = QRectF(0,-(nameHeight+2*nameMargin),nameWidth+2*nameMargin,nameHeight+2*nameMargin);
61 setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
63 updateGeometry(InterfaceMove);
64 QPointF initPos = QPointF(0.0,0.0) - originPoint;
66 cout << "total size of group: " << totalWidth << "," << totalHeight << endl;
67 cout << "pos in scene: " << x() << "," << y() << endl;
70 GroupItem::~GroupItem() {
71 // since the reference block is nowhere referenced except in this class, it must be deleted here
75 bool GroupItem::isGroupItem() {
79 BoxItem* GroupItem::getParentItem() {
83 void GroupItem::setParentItem(BoxItem *_parentItem) {
84 parentItem = _parentItem;
85 if (parentItem != NULL) {
86 parentItem->setChildGroupItem(this);
90 void GroupItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
91 if(boxWidth > 0 && boxHeight > 0){
93 painter->setPen(Qt::red);
95 painter->setPen(Qt::black);
97 painter->drawRect(0,0,boxWidth,boxHeight);
98 painter->drawRect(rectTitle);
99 painter->drawText(rectTitle,Qt::AlignCenter | Qt::TextWordWrap,refBlock->getName());
101 foreach(InterfaceItem *item, interfaces){
102 item->paint(painter);
107 Each time a new block is added in a GroupItem, it is placed
108 at an absolute position of (0,0) within the GroupItem. (NB: the absolute
109 position is computed by item.pos()+item.getOriginPoint()).
110 Thus, there are 3 cases :
111 - a single block is within the GroupItem
112 - several blocks already placed and a new one
113 - several blocks already placed and one is moving.
116 void GroupItem::updateMinimumSize() {
118 // compute place taken by blocks.
119 int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
120 if (rectTitle.width() > 2*marginConn) {
121 minimumBoxWidth = rectTitle.width();
124 minimumBoxWidth = 2*marginConn;
126 minimumBoxHeight = 2*marginConn;
128 if (getScene() == NULL) return;
129 QList<BoxItem *> blocks = getScene()->getBoxItems();
130 if(blocks.length() == 0) return; // no blocks within, keep the miniumum computed before.
132 QRectF boxFree; // the bounding box of free blocks.
133 foreach(BoxItem* item, blocks) {
134 QRectF boxItem = item->boundingRect();
135 if (item->getPosition() == BoxItem::Free) {
136 boxItem.translate(item->pos());
137 if (item->getSpan() == BoxItem::NoSpan) {
138 boxFree = boxFree.united(boxItem);
140 else if (item->getSpan() == BoxItem::HSpan) {
141 QRectF r(boxFree.left()+boxFree.width()/2.0,boxItem.top(),1,boxItem.height());
142 boxFree = boxFree.united(r);
144 else if (item->getSpan() == BoxItem::VSpan) {
145 QRectF r(boxItem.left(),boxFree.top()+boxFree.height()/2.0,boxItem.width(),1);
146 boxFree = boxFree.united(r);
150 // find the move to apply to freely located items
151 double gapXLeft = 0.0;
152 double gapYTop = 0.0;
153 if (boxFree.left() < marginConn) {
154 gapXLeft = boxFree.left() - marginConn;
156 if (boxFree.top() < marginConn) {
157 gapYTop = boxFree.top() - marginConn;
160 boxFree.translate(-gapXLeft,-gapYTop);
161 minimumBoxWidth = boxFree.right() + marginConn;
162 minimumBoxHeight = boxFree.bottom() + marginConn;
164 // find the highest/largest item stick on top/bottom/left/right
166 qreal topHighest = 0.0;
167 qreal bottomHighest = 0.0;
168 qreal leftLargest = 0.0;
169 qreal rightLargest = 0.0;
171 foreach(BoxItem* item, blocks) {
172 QRectF boxItem = item->boundingRect();
174 if (item->getPosition() == BoxItem::Top) {
176 if (item->getSpan() == BoxItem::VSpan) {
177 if (item->getMinimumBoxHeight() > topHighest) {
178 topHighest = item->getMinimumBoxHeight();
182 if (boxItem.height()+marginConn > topHighest) {
183 topHighest = boxItem.height()+marginConn;
186 if (item->getSpan() == BoxItem::HSpan) {
187 if (item->getMinimumBoxWidth() > leftLargest) {
188 leftLargest = item->getMinimumBoxWidth();
193 if (item->getPosition() == BoxItem::Bottom) {
195 if (item->getSpan() == BoxItem::VSpan) {
196 if (item->getMinimumBoxHeight() > bottomHighest) {
197 bottomHighest = item->getMinimumBoxHeight();
201 if (boxItem.height()+marginConn > bottomHighest) {
202 bottomHighest = boxItem.height()+marginConn;
205 if (item->getSpan() == BoxItem::HSpan) {
206 if (item->getMinimumBoxWidth() > leftLargest) {
207 leftLargest = item->getMinimumBoxWidth();
212 if (item->getPosition() == BoxItem::Left) {
214 if (item->getSpan() == BoxItem::HSpan) {
215 if (item->getMinimumBoxWidth() > leftLargest) {
216 leftLargest = item->getMinimumBoxWidth();
220 if (boxItem.width()+marginConn > leftLargest) {
221 leftLargest = boxItem.width()+marginConn;
224 if (item->getSpan() == BoxItem::VSpan) {
225 if (item->getMinimumBoxHeight() > topHighest) {
226 topHighest = item->getMinimumBoxHeight();
231 if (item->getPosition() == BoxItem::Right) {
233 if (item->getSpan() == BoxItem::HSpan) {
234 if (item->getMinimumBoxWidth() > rightLargest) {
235 rightLargest = item->getMinimumBoxWidth();
239 if (boxItem.width()+marginConn > rightLargest) {
240 rightLargest = boxItem.width()+marginConn;
243 if (item->getSpan() == BoxItem::VSpan) {
244 if (item->getMinimumBoxHeight() > topHighest) {
245 topHighest = item->getMinimumBoxHeight();
251 if (leftLargest > minimumBoxWidth) {
252 minimumBoxWidth = leftLargest;
254 if (rightLargest > minimumBoxWidth) {
255 minimumBoxWidth = rightLargest;
257 if (topHighest > minimumBoxHeight) {
258 minimumBoxHeight = topHighest;
260 if (bottomHighest > minimumBoxHeight) {
261 minimumBoxHeight = bottomHighest;
263 // must move all free boxitem within of -gapXLeft,-gapYTop
264 foreach(BoxItem* item, blocks) {
265 if (item->getPosition() == BoxItem::Free) {
266 if (item->getSpan() == BoxItem::HSpan) {
267 item->moveBy(0,-gapYTop);
269 if (item->getSpan() == BoxItem::VSpan) {
270 item->moveBy(-gapXLeft,0);
273 item->moveBy(-gapXLeft,-gapYTop);
278 //cout << "min group size: " << minimumBoxWidth << "," << minimumBoxHeight << endl;
281 void GroupItem::updateShape() {
282 updateGeometry(InterfaceMove);
285 void GroupItem::updateBorderSpanItems() {
286 QList<BoxItem *> blocks = getScene()->getBoxItems();
287 bool changed = false;
288 foreach(BoxItem* item, blocks) {
290 if (item->getPosition() == BoxItem::Bottom) {
292 QPointF pos = item->pos();
293 item->moveTo(QPointF(pos.x(),boxHeight-item->getTotalHeight()));
295 else if (item->getPosition() == BoxItem::Right) {
297 QPointF pos = item->pos();
298 item->moveTo(QPointF(boxWidth-item->getTotalWidth(),pos.y()));
300 if (item->getSpan() == BoxItem::HSpan) {
302 item->setWidth(boxWidth);
304 else if (item->getSpan() == BoxItem::VSpan) {
306 item->setHeight(boxHeight);
309 item->updateGeometry(Resize);
314 bool GroupItem::updateGeometry(ChangeType type) {
316 QPointF oldOrigin = originPoint;
317 QSize oldSize(totalWidth,totalHeight);
319 bool boxSizeChanged = false;
321 // whatever the change, the minimum size may have changed
324 if (type == Creation) {
325 boxSizeChanged = true;
326 boxWidth = minimumBoxWidth;
327 boxHeight = minimumBoxHeight;
328 /* reset and update interfaces positions
329 * in case of spanning, the interface are positionned
330 * only on free borders.
332 resetInterfaceItemsPosition();
334 else if (type == Resize) {
335 boxSizeChanged = true;
336 updateInterfaceAndConnectionItems();
337 updateBorderSpanItems();
339 else if (type == InterfaceMove) {
340 // if an internal block has moved, the actual box size may be inadequate
341 if (boxWidth < minimumBoxWidth) {
342 boxWidth = minimumBoxWidth;
343 boxSizeChanged = true;
344 updateInterfaceAndConnectionItems();
345 updateBorderSpanItems();
347 if (boxHeight < minimumBoxHeight) {
348 boxHeight = minimumBoxHeight;
349 boxSizeChanged = true;
350 updateInterfaceAndConnectionItems();
351 updateBorderSpanItems();
356 // compute the max. width of interfaces' name for 4 orientations.
363 foreach(InterfaceItem* iface, interfaces) {
364 ifaceWidth = iface->getNameWidth();
365 if (iface->getOrientation() == Parameters::South) {
366 if (ifaceWidth > maxSouth) maxSouth = ifaceWidth+ifaceMargin+params->arrowWidth+params->arrowLineLength;
368 else if (iface->getOrientation() == Parameters::North) {
369 if (ifaceWidth > maxNorth) maxNorth = ifaceWidth+ifaceMargin+params->arrowWidth+params->arrowLineLength;
371 else if (iface->getOrientation() == Parameters::East) {
372 if (ifaceWidth > maxEast) maxEast = ifaceWidth+ifaceMargin+params->arrowWidth+params->arrowLineLength;
374 else if (iface->getOrientation() == Parameters::West) {
375 if (ifaceWidth > maxWest) maxWest = ifaceWidth+ifaceMargin+params->arrowWidth+params->arrowLineLength;
380 totalWidth = boxWidth+maxEast;
381 totalHeight = boxHeight+maxSouth;
385 totalWidth += maxWest;
387 if (maxNorth > (nameHeight+2*nameMargin)) {
389 totalHeight += maxNorth;
392 y -= nameHeight+2*nameMargin;
393 totalHeight += nameHeight+2*nameMargin;
395 QSizeF newSize(totalWidth,totalHeight);
399 if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
400 //cout << "GroupItem: must change group item shape" << endl;
401 prepareGeometryChange();
407 void GroupItem::nameChanged() {
410 QFontMetrics fmId(params->defaultBlockFont);
411 nameWidth = fmId.width(refBlock->getName());
412 nameHeight = fmId.height();
413 // changing the BoxItem in the upperscene
414 if (parentItem != NULL) {
415 parentItem->nameChanged();
417 updateGeometry(InterfaceMove);
418 // force the update in case of the size has not changed
423 void GroupItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
425 if(params->editState == Parameters::EditGroupMove) {
426 int gapX = event->scenePos().x() - cursorPosition.x();
427 int gapY = event->scenePos().y() - cursorPosition.y();
430 if (refBlock->isTopGroupBlock()) {
431 QRectF rectGroup = boundingRectInScene();
432 rectGroup.moveTo(rectGroup.x()+gapX,rectGroup.y()+gapY);
433 foreach(StimuliItem* source, getScene()->getSourceItems()) {
434 QRectF rectSource = source->boundingRectInScene();
435 if (rectGroup.intersects(rectSource)) canMove = false;
440 QPointF gap(gapX,gapY);
441 currentPosition = currentPosition+gap;
442 setPos(currentPosition);
444 // updating all connections of the scene.
445 getScene()->updateConnectionItemsShape();
447 cursorPosition = event->scenePos();
449 else if(params->editState == Parameters::EditGroupResize) {
451 int gapX = event->scenePos().x() - cursorPosition.x();
452 int gapY = event->scenePos().y() - cursorPosition.y();
453 //cout << "gap: " << gapX << "," << gapY << endl;
454 switch(currentBorder){
456 if(boxWidth+gapX > minimumBoxWidth){
462 if(boxHeight+gapY > minimumBoxHeight){
467 case CornerSouthEast: {
468 if(boxWidth+gapX > minimumBoxWidth){
471 if(boxHeight+gapY > minimumBoxHeight){
477 cout << "abnormal case while resizing block" << endl;
480 updateGeometry(Resize);
482 // recompute the geometry of the block
484 // update all interfaces positions
485 foreach(InterfaceItem *item, interfaces){
486 item->updatePosition();
488 // update all connections from/to this block
489 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
490 if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
495 cursorPosition = event->scenePos();
497 else if(params->editState == Parameters::EditInterfaceMove) {
498 prepareGeometryChange();
499 moveInterfaceItemTo(event->pos());
500 // recompute the geometry of the block
501 updateGeometry(InterfaceMove);
502 // update connection from/to the selected interface
503 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
504 if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
512 void GroupItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
514 QPointF pos = event->pos();
518 QGraphicsItem::mousePressEvent(event);
520 if(event->button() == Qt::RightButton) return;
522 int mode = getScene()->getEditionMode();
524 dispatcher->setCurrentGroupWidget(Dispatcher::Design, getScene()->getGroupWidget());
526 if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) {
527 InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
530 if (params->editState == Parameters::EditNoOperation) {
531 getScene()->setSelectedInterface(1,inter);
532 params->setEditState(Parameters::EditStartConnection);
534 else if (params->editState == Parameters::EditStartConnection) {
535 if (inter == getScene()->getSelectedInterface(1)) {
536 params->setEditState(Parameters::EditAbortConnection);
539 getScene()->setSelectedInterface(2,inter);
540 params->setEditState(Parameters::EditCloseConnection);
545 else if (mode == GroupScene::ItemEdition) {
547 if (params->cursorState == Parameters::CursorOnInterface) {
548 InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
550 currentInterface = inter;
551 params->setEditState(Parameters::EditInterfaceMove);
554 else if (params->cursorState == Parameters::CursorInGroupTitle) {
555 params->setEditState(Parameters::EditGroupMove);
556 cursorPosition = event->scenePos();
558 else if (params->cursorState == Parameters::CursorOnBorder) {
559 setFlag(ItemIsMovable, false);
560 cursorPosition = event->scenePos();
561 params->setEditState(Parameters::EditGroupResize);
566 void GroupItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
568 int mode = getScene()->getEditionMode();
570 if (mode == GroupScene::AddConnection) {
572 if (params->editState == Parameters::EditStartConnection) {
573 params->setEditState(Parameters::EditStartConnection);
574 InterfaceItem* iface = getScene()->getSelectedInterface(1);
575 iface->selected = true;
576 update(iface->boundingRect());
578 else if (params->editState == Parameters::EditAbortConnection) {
579 InterfaceItem* iface = getScene()->getSelectedInterface(1);
580 iface->selected = false;
581 update(iface->boundingRect());
582 getScene()->setSelectedInterface(1,NULL);
583 params->setEditState(Parameters::EditNoOperation);
585 else if (params->editState == Parameters::EditCloseConnection) {
586 InterfaceItem* iface1 = getScene()->getSelectedInterface(1);
587 InterfaceItem* iface2 = getScene()->getSelectedInterface(2);
588 bool ok = dispatcher->createConnection(Dispatcher::Design, iface1,iface2);
590 iface1->selected = false;
591 update(iface1->boundingRect());
592 iface2->selected = false;
593 update(iface2->boundingRect());
594 getScene()->setSelectedInterface(1,NULL);
595 getScene()->setSelectedInterface(2,NULL);
596 params->setEditState(Parameters::EditNoOperation);
599 //QMessageBox::warning(NULL,"Error","Cannot connect selected interfaces", QMessageBox::Ok);
600 getScene()->setSelectedInterface(2,NULL);
601 params->setEditState(Parameters::EditStartConnection);
605 else if (mode == GroupScene::ItemEdition) {
606 currentInterface = NULL;
607 setFlag(ItemIsMovable, true);
608 params->editState = Parameters::EditNoOperation;
610 QGraphicsItem::mouseReleaseEvent(event);
613 void GroupItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
614 QPointF pos = event->pos();
617 currentBorder = NoBorder;
618 int mode = getScene()->getEditionMode();
620 if (mode == GroupScene::AddConnection) {
621 InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
623 params->cursorState = Parameters::CursorOnInterface;
624 setCursor(Qt::PointingHandCursor);
627 params->cursorState = Parameters::CursorNowhere;
628 setCursor(Qt::ArrowCursor);
631 else if (mode == GroupScene::ItemEdition) {
635 InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
637 params->cursorState = Parameters::CursorOnInterface;
638 setCursor(Qt::PointingHandCursor);
640 else if ((x>boxWidth-marginE)&&(x<boxWidth)) {
642 params->cursorState = Parameters::CursorOnBorder;
644 if ((y>boxHeight-2*marginS)&&(y<boxHeight)) {
645 currentBorder = CornerSouthEast;
646 setCursor(Qt::SizeFDiagCursor);
649 currentBorder = BorderEast;
650 setCursor(Qt::SizeHorCursor);
653 else if ((y>boxHeight-marginS)&&(y<boxHeight)) {
655 params->cursorState = Parameters::CursorOnBorder;
657 if ((x>boxWidth-2*marginE)&&(x<boxWidth)) {
658 currentBorder = CornerSouthEast;
659 setCursor(Qt::SizeFDiagCursor);
662 currentBorder = BorderSouth;
663 setCursor(Qt::SizeVerCursor);
667 if (rectTitle.contains(x,y)) {
668 params->cursorState = Parameters::CursorInGroupTitle;
669 setCursor(Qt::OpenHandCursor);
672 params->cursorState = Parameters::CursorNowhere;
673 setCursor(Qt::ArrowCursor);
679 void GroupItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
681 QAction* titleAction = NULL;
682 QAction* showProperties = NULL;
683 QAction* removeAction = NULL;
684 QAction* renameAction = NULL;
685 QAction* showParameters = NULL;
686 QAction* addExtClkAction = NULL;
688 InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y());
690 // menu for interface
691 if( ifaceItem != NULL) {
692 titleAction = menu.addAction("Interface operations");
693 titleAction->setEnabled(false);
695 showProperties = menu.addAction("Show properties");
696 renameAction = menu.addAction("Rename");
698 /* CAUTION : the interface can be removed only if its
699 connected to only one side, i.e. connectedFrom is null
700 or connectedTo is empty.
703 ConnectedInterface* ref = ifaceItem->refInter;
704 if ((!ref->isConnectedFrom()) || (!ref->isConnectedTo())) {
705 removeAction = menu.addAction("Remove");
709 titleAction = menu.addAction("Block operations");
710 titleAction->setEnabled(false);
713 if (refBlock->nbParameters() > 0) {
714 showParameters = menu.addAction("Show parameters");
716 renameAction = menu.addAction("Rename");
717 if (refBlock->isTopGroupBlock()) {
718 addExtClkAction = menu.addAction("Add new external clock/reset");
722 QAction* selectedAction = menu.exec(event->screenPos());
724 if(selectedAction == NULL) return;
726 if(selectedAction == renameAction){
727 if(ifaceItem != NULL)
728 dispatcher->renameInterface(Dispatcher::Design, ifaceItem);
730 dispatcher->renameGroupBlock(Dispatcher::Design, this);
732 else if(selectedAction == showProperties){
733 dispatcher->showProperties(Dispatcher::Design, ifaceItem);
735 else if (selectedAction == removeAction) {
736 dispatcher->removeGroupInterface(Dispatcher::Design, ifaceItem);
738 else if(selectedAction == showParameters) {
739 new ParametersWindow(refBlock, params, NULL);
741 else if (selectedAction == addExtClkAction) {
743 double freq = QInputDialog::getDouble(NULL,"Adding a clkrstgen","External clock frequency (in MHz)",100,0,100000,1,&ok);
745 dispatcher->addClkRstGenBlock(Dispatcher::Design, freq);
749 InterfaceItem* GroupItem::isHoverInterface(QPointF point) {
750 foreach(InterfaceItem *inter, interfaces){
751 if(inter->boundingRect().contains(point))
757 void GroupItem::load(QDomElement groupElement) throw(Exception) {
759 GroupBlock* groupBlock = AB_TO_GRP(refBlock);
763 int id = groupElement.attribute("id","none").toInt(&ok);
764 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
766 QString nameStr = groupElement.attribute("name","none");
767 if(nameStr == "none") throw(Exception(PROJECTFILE_CORRUPTED));
769 QStringList positionStr = groupElement.attribute("position","none").split(",");
770 if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
771 int posX = positionStr.at(0).toInt(&ok);
772 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
773 int posY = positionStr.at(1).toInt(&ok);
774 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
776 QStringList dimensionStr = groupElement.attribute("dimension","none").split(",");
777 if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
778 int dimX = dimensionStr.at(0).toInt(&ok);
779 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
780 int dimY = dimensionStr.at(1).toInt(&ok);
781 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
785 setDimension(dimX,dimY);
786 groupBlock->setName(nameStr);
788 cout << "group info : \n-id : " << id << "\n-pos : " << posX << ", " << posY << "\n-dim : " << dimX << ", " << dimY << "\n-name : " << nameStr.toStdString() << endl;
790 QDomNodeList interfaces = groupElement.elementsByTagName("group_iface");
791 for(int j=0; j<interfaces.length(); j++){
792 QDomElement currentInterfaceNode = interfaces.at(j).toElement();
794 int id = currentInterfaceNode.attribute("id","none").toInt(&ok);
795 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
797 QString name = currentInterfaceNode.attribute("name","none");
798 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
800 QString purposeStr = currentInterfaceNode.attribute("purpose","none");
801 int purpose = AbstractInterface::getIntPurpose(purposeStr);
802 if(purpose == -1) throw(Exception(PROJECTFILE_CORRUPTED));
804 QString directionStr = currentInterfaceNode.attribute("direction","none");
805 int direction = AbstractInterface::getIntDirection(directionStr);
806 if(direction == -1) throw(Exception(PROJECTFILE_CORRUPTED));
808 QString orientationStr = currentInterfaceNode.attribute("orientation","none");
809 int orientation = InterfaceItem::getIntOrientation(orientationStr);
810 if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));
812 double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);
813 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
815 GroupInterface *groupIface = new GroupInterface(groupBlock,name,direction,purpose);
816 groupBlock->addInterface(groupIface);
817 InterfaceItem *interfaceItem = new InterfaceItem(position,orientation,groupIface,this,params);
818 interfaceItem->setId(id);
819 addInterfaceItem(interfaceItem, false);
821 if (purpose == AbstractInterface::Data) {
822 GroupInterface *groupCtlIface = new GroupInterface(groupBlock,name+"_enb",direction,AbstractInterface::Control);
823 groupCtlIface->setAssociatedIface(groupIface);
824 groupBlock->addInterface(groupCtlIface);
826 cout << "interface add to " << groupBlock->getName().toStdString() << endl;
831 void GroupItem::save(QXmlStreamWriter &writer) {
833 writer.writeStartElement("group_item");
835 QString attrId = QString::number(id);
836 QString attrName(getRefBlock()->getName());
837 QString attrUpperItem = QString::number(-1);
838 if(parentItem != NULL){
839 attrUpperItem = QString::number(parentItem->getId());
841 QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
842 QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
845 writer.writeAttribute("id",attrId);
846 writer.writeAttribute("upper_item",attrUpperItem);
847 writer.writeAttribute("name",attrName);
848 writer.writeAttribute("position", attrPos);
849 writer.writeAttribute("dimension", attrDim);
851 writer.writeStartElement("group_ifaces");
853 writer.writeAttribute("count",QString::number(interfaces.length()));
855 foreach(InterfaceItem *item, interfaces){
856 writer.writeStartElement("group_iface");
858 writer.writeAttribute("id",QString::number(item->getId()));
859 writer.writeAttribute("name",item->getName());
860 writer.writeAttribute("purpose",QString(item->refInter->getPurposeString()));
861 writer.writeAttribute("direction",QString(item->refInter->getDirectionString()));
862 writer.writeAttribute("orientation",item->getStrOrientation());
863 writer.writeAttribute("position",QString::number(item->getPositionRatio()));
865 writer.writeEndElement();
868 writer.writeEndElement();//</interfaces>
870 writer.writeEndElement();//</group_item>