1 #include "SourceItem.h"
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 SourceItem::SourceItem(AbstractBlock *_refBlock,
19 Dispatcher *_dispatcher,
20 Parameters *_params) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params) {
23 _refBlock : mandatory a FunctionalBlock or a GroupBlock
25 if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
27 currentBorder = NoBorder;
31 setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
33 createInterfaceItems();
34 updateGeometry(InterfaceMove);
35 resetInterfaceItemsPosition();
36 QPointF initPos = QPointF(0.0,0.0) - originPoint;
38 //cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
39 //cout << "pos in group: " << x() << "," << y() << endl;
42 SourceItem::SourceItem(Dispatcher *_dispatcher, Parameters *_params) throw(Exception) : AbstractBoxItem(_dispatcher, _params) {
45 currentBorder = NoBorder;
49 setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
51 boxWidth = params->defaultBlockWidth;
52 boxHeight = params->defaultBlockHeight;
55 SourceItem::~SourceItem() {
58 void SourceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
59 QPen pen(Qt::black, 3);
61 pen.setColor(Qt::red);
64 painter->setBrush(Qt::darkCyan);
66 painter->drawRect(0,0,boxWidth, boxHeight);
67 painter->drawText(0,0,boxWidth, boxHeight,Qt::AlignCenter | Qt::TextWordWrap,QString(refBlock->getName()));
68 foreach(InterfaceItem *inter, interfaces) {
70 inter->paint(painter);
74 void SourceItem::moveTo(QPointF dest) {
76 currentPosition = dest;
79 bool SourceItem::isSourceItem() {
83 void SourceItem::nameChanged() {
86 QFontMetrics fmId(params->defaultBlockFont);
87 nameWidth = fmId.width(refBlock->getName());
88 nameHeight = fmId.height();
89 updateGeometry(InterfaceMove);
90 // force the update in case of the size has not changed
94 void SourceItem::updateMinimumSize() {
100 int nbSouth = nbInterfacesByOrientation(Parameters::South);
101 int nbNorth = nbInterfacesByOrientation(Parameters::North);
102 int nbMaxSN = nbNorth;
103 if (nbSouth > nbNorth) nbMaxSN = nbSouth;
104 int nbEast = nbInterfacesByOrientation(Parameters::East);
105 int nbWest = nbInterfacesByOrientation(Parameters::West);
106 int nbMaxEW = nbEast;
107 if (nbWest > nbEast) {
114 foreach(InterfaceItem* iface, interfaces) {
115 ifaceWidth = iface->getNameWidth();
116 ifaceHeight = iface->getNameHeight();
117 if (iface->visible) {
118 if (iface->getOrientation() == Parameters::South) {
119 if (ifaceWidth > maxSouth) maxSouth = ifaceWidth;
121 else if (iface->getOrientation() == Parameters::North) {
122 if (ifaceWidth > maxNorth) maxNorth = ifaceWidth;
124 else if (iface->getOrientation() == Parameters::East) {
125 if (ifaceWidth > maxEast) maxEast = ifaceWidth;
127 else if (iface->getOrientation() == Parameters::West) {
128 if (ifaceWidth > maxWest) maxWest = ifaceWidth;
133 /* NB: the width layout is the following
134 ifaceMargin | maxWest | nameMargin | name | nameMargin | maxEast | ifaceMargin
136 minimumBoxWidth = maxWest+maxEast+nameWidth+2*(ifaceMargin+nameMargin);
137 // if the minimum is not sufficent taking into account N/S interfaces
138 if (minimumBoxWidth < (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1))) {
139 minimumBoxWidth = (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1));
141 minimumBoxHeight = maxNorth+maxSouth+3*ifaceMargin;
142 if (minimumBoxHeight < (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1))) {
143 minimumBoxHeight = (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1));
145 cout << "source minimum size = " << minimumBoxWidth << "x" << minimumBoxHeight << endl;
149 /* updateGeometry() :
152 bool SourceItem::updateGeometry(ChangeType type) {
154 currentPosition = pos();
155 //cout << "current pos of block: " << currentPosition.x() << "," << currentPosition.y() << endl;
156 QPointF oldOrigin = originPoint;
157 QSize oldSize(totalWidth,totalHeight);
159 bool boxSizeChanged = false;
161 // whatever the change, the minimum size may have changed
164 if (type == Resize) {
165 // resize implies to move interfaces and to update connections
166 boxSizeChanged = true;
168 else if (type == InterfaceMove) {
169 // if an interface moves, it may change the box size
170 if (boxWidth < minimumBoxWidth) {
171 boxWidth = minimumBoxWidth;
172 boxSizeChanged = true;
174 if (boxHeight < minimumBoxHeight) {
175 boxHeight = minimumBoxHeight;
176 boxSizeChanged = true;
179 if (boxSizeChanged) {
180 updateInterfaceAndConnectionItems();
186 totalWidth = boxWidth;
187 totalHeight = boxHeight;
189 if(isInterfaces(Parameters::East)){
190 totalWidth += params->arrowWidth+params->arrowLineLength;
192 if(isInterfaces(Parameters::West)){
193 totalWidth += params->arrowWidth+params->arrowLineLength;
194 x -= params->arrowWidth+params->arrowLineLength;
196 if(isInterfaces(Parameters::South)){
197 totalHeight += params->arrowWidth+params->arrowLineLength;
199 if(isInterfaces(Parameters::North)){
200 totalHeight += params->arrowWidth+params->arrowLineLength;
201 y -= params->arrowWidth+params->arrowLineLength;
203 QSizeF newSize(totalWidth,totalHeight);
207 cout << "source size = " << totalWidth << "x" << totalHeight << endl;
208 if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
209 prepareGeometryChange();
215 void SourceItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
217 if(params->editState == Parameters::EditBlockMove) {
218 QPointF absPos = currentPosition + originPoint;
220 int gapX = event->scenePos().x() - cursorPosition.x();
221 int gapY = event->scenePos().y() - cursorPosition.y();
225 QRectF rectSource = boundingRectInScene();
226 rectSource.moveTo(rectSource.x()+gapX,rectSource.y()+gapY);
227 GroupItem* group = getScene()->getGroupItem();
228 QRectF rectGroup = group->boundingRectInScene();
229 if (rectSource.intersects(rectGroup)) canMove = false;
232 foreach(SourceItem* source, getScene()->getSourceItems()) {
233 QRectF rectOther = source->boundingRectInScene();
234 if ((source != this) && (rectSource.intersects(rectOther))) canMove = false;
239 QPointF gap(gapX,gapY);
240 currentPosition = currentPosition+gap;
241 setPos(currentPosition);
242 // update all connections from/to this block
243 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
244 if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
249 cursorPosition = event->scenePos();
251 else if(params->editState == Parameters::EditBlockResize) {
253 int gapX = event->scenePos().x() - cursorPosition.x();
254 int gapY = event->scenePos().y() - cursorPosition.y();
255 //cout << "gap: " << gapX << "," << gapY << endl;
256 switch(currentBorder){
258 if(boxWidth+gapX > minimumBoxWidth){
264 if(boxHeight+gapY > minimumBoxHeight){
269 case CornerSouthEast: {
270 if(boxWidth+gapX > minimumBoxWidth){
273 if(boxHeight+gapY > minimumBoxHeight){
279 cout << "abnormal case while resizing block" << endl;
282 // recompute the geometry of the block and possibly the group item
283 if (updateGeometry(Resize)) {
284 (getScene()->getGroupItem())->updateShape();
287 cursorPosition = event->scenePos();
289 else if(params->editState == Parameters::EditInterfaceMove) {
290 prepareGeometryChange();
291 moveInterfaceItemTo(event->pos());
292 // recompute the geometry of the block
293 if (updateGeometry(InterfaceMove)) {
294 //cout << "must recompute group item geometry" << endl;
295 (getScene()->getGroupItem())->updateShape();
297 // update connection from/to the selected interface
298 foreach(ConnectionItem *item, getScene()->getConnectionItems()){
299 if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
306 void SourceItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
308 QPointF pos = event->pos();
312 //QGraphicsItem::mousePressEvent(event);
314 if(event->button() == Qt::RightButton) return;
316 int mode = getScene()->getEditionMode();
318 dispatcher->setCurrentGroupWidget(Dispatcher::Design, getScene()->getGroupWidget());
320 if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) {
321 InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
324 if (params->editState == Parameters::EditNoOperation) {
325 getScene()->setSelectedInterface(1,inter);
326 params->setEditState(Parameters::EditStartConnection);
328 else if (params->editState == Parameters::EditStartConnection) {
329 if (inter == getScene()->getSelectedInterface(1)) {
330 params->setEditState(Parameters::EditAbortConnection);
333 getScene()->setSelectedInterface(2,inter);
334 params->setEditState(Parameters::EditCloseConnection);
339 else if (mode == GroupScene::ItemEdition) {
340 //setZValue(zValue()+100);
341 if (params->cursorState == Parameters::CursorOnInterface) {
342 InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
344 if (inter == currentInterface) {
345 params->setEditState(Parameters::EditInterfaceDeselect);
348 setFlag(ItemIsMovable, false);
349 currentInterface = inter;
350 params->setEditState(Parameters::EditInterfaceMove);
354 else if (params->cursorState == Parameters::CursorInBlock) {
355 selected = !selected;
356 params->setEditState(Parameters::EditBlockMove);
357 cursorPosition = event->scenePos();
358 //cout << "cursor current pos. in scene " << cursorPosition.x() << "," << cursorPosition.y() << endl;
361 else if (params->cursorState == Parameters::CursorOnBorder) {
362 setFlag(ItemIsMovable, false);
363 cursorPosition = event->scenePos();
364 params->setEditState(Parameters::EditBlockResize);
369 void SourceItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
371 //setZValue(zValue()-100);
373 int mode = getScene()->getEditionMode();
375 if (mode == GroupScene::AddConnection) {
377 if (params->editState == Parameters::EditStartConnection) {
378 InterfaceItem* iface = getScene()->getSelectedInterface(1);
379 iface->selected = true;
380 update(iface->boundingRect());
382 else if (params->editState == Parameters::EditAbortConnection) {
383 InterfaceItem* iface = getScene()->getSelectedInterface(1);
384 iface->selected = false;
385 update(iface->boundingRect());
386 getScene()->setSelectedInterface(1,NULL);
387 params->setEditState(Parameters::EditNoOperation);
389 else if (params->editState == Parameters::EditCloseConnection) {
390 InterfaceItem* iface1 = getScene()->getSelectedInterface(1);
391 InterfaceItem* iface2 = getScene()->getSelectedInterface(2);
392 bool ok = dispatcher->createConnection(Dispatcher::Design, iface1,iface2);
394 iface1->selected = false;
395 update(iface1->boundingRect());
396 iface2->selected = false;
397 update(iface2->boundingRect());
398 getScene()->setSelectedInterface(1,NULL);
399 getScene()->setSelectedInterface(2,NULL);
400 params->setEditState(Parameters::EditNoOperation);
403 //QMessageBox::warning(NULL,"Error","Cannot connect selected interfaces", QMessageBox::Ok);
404 getScene()->setSelectedInterface(2,NULL);
405 params->setEditState(Parameters::EditStartConnection);
409 else if (mode == GroupScene::ItemEdition) {
410 currentInterface = NULL;
411 params->editState = Parameters::EditNoOperation;
412 setFlag(ItemIsMovable);
415 QGraphicsItem::mouseReleaseEvent(event);
418 void SourceItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
420 QPointF pos = event->pos();
423 currentBorder = NoBorder;
424 int mode = getScene()->getEditionMode();
426 if (mode == GroupScene::AddConnection) {
427 InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
429 params->cursorState = Parameters::CursorOnInterface;
430 setCursor(Qt::PointingHandCursor);
433 params->cursorState = Parameters::CursorNowhere;
434 setCursor(Qt::ArrowCursor);
437 else if (mode == GroupScene::ItemEdition) {
441 InterfaceItem* iface = getInterfaceItemFromCursor(x,y);
443 params->cursorState = Parameters::CursorOnInterface;
444 setCursor(Qt::PointingHandCursor);
446 else if ((x>boxWidth-marginE)&&(x<boxWidth)) {
448 params->cursorState = Parameters::CursorOnBorder;
450 if ((y>boxHeight-2*marginS)&&(y<boxHeight)) {
451 currentBorder = CornerSouthEast;
452 setCursor(Qt::SizeFDiagCursor);
455 currentBorder = BorderEast;
456 setCursor(Qt::SizeHorCursor);
459 else if ((y>boxHeight-marginS)&&(y<boxHeight)) {
461 params->cursorState = Parameters::CursorOnBorder;
463 if ((x>boxWidth-2*marginE)&&(x<boxWidth)) {
464 currentBorder = CornerSouthEast;
465 setCursor(Qt::SizeFDiagCursor);
468 currentBorder = BorderSouth;
469 setCursor(Qt::SizeVerCursor);
473 if ((x>0) && (x<boxWidth-marginE) && (y>0) && (y<boxHeight-marginS)) {
474 params->cursorState = Parameters::CursorInBlock;
475 setCursor(Qt::OpenHandCursor);
478 params->cursorState = Parameters::CursorNowhere;
479 setCursor(Qt::ArrowCursor);
483 //QGraphicsItem::hoverMoveEvent(event);
488 void SourceItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
493 QAction* titleAction = NULL;
494 QAction* removeAction = NULL;
495 QAction* duplicateAction = NULL;
496 QAction* renameAction = NULL;
497 QAction* showProperties = NULL;
498 QAction* showParameters = NULL;
499 QAction* showPatterns = NULL;
501 InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y());
502 // menu for interface
503 if( ifaceItem != NULL){
505 ConnectedInterface* iface = ifaceItem->refInter;
507 titleAction = menu.addAction("Interface operations");
508 titleAction->setEnabled(false);
512 showProperties = menu.addAction("Show properties");
513 renameAction = menu.addAction("Rename");
515 if (iface->getAssociatedIface() != NULL) {
516 if (iface->getDirection() == AbstractInterface::Output) {
517 showPatterns = menu.addAction("Show output pattern");
523 titleAction = menu.addAction("Block operations");
524 titleAction->setEnabled(false);
527 if (refBlock->nbParameters() > 0) {
528 showParameters = menu.addAction("Show parameters");
530 renameAction = menu.addAction("Rename");
532 duplicateAction = menu.addAction("Duplicate");
533 removeAction = menu.addAction("Remove");
536 QAction* selectedAction = NULL;
537 selectedAction = menu.exec(event->screenPos());
539 if(selectedAction == NULL) return ;
541 if (selectedAction == removeAction) {
542 dispatcher->removeSourceItem(Dispatcher::Design, this);
544 else if (selectedAction == duplicateAction) {
545 dispatcher->duplicateSourceItem(Dispatcher::Design, this);
547 else if(selectedAction == renameAction){
548 if(ifaceItem != NULL) {
549 dispatcher->renameInterface(Dispatcher::Design, ifaceItem);
552 dispatcher->renameSourceBlock(Dispatcher::Design, this);
555 else if(selectedAction == showProperties){
556 dispatcher->showProperties(Dispatcher::Design, ifaceItem);
558 else if(selectedAction == showParameters){
559 new ParametersWindow(refBlock, params, NULL);
561 else if(selectedAction == showPatterns) {
562 dispatcher->showPatterns(Dispatcher::Design, ifaceItem);
566 void SourceItem::load(QDomElement funcElement) throw(Exception) {
570 int id = funcElement.attribute("id","none").toInt(&ok);
571 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
573 QString refXml = funcElement.attribute("ref_xml","none");
574 if(refXml == "none") throw(Exception(PROJECTFILE_CORRUPTED));
576 QString refMd5 = funcElement.attribute("ref_md5","none");
577 if(refMd5 == "none") throw(Exception(PROJECTFILE_CORRUPTED));
579 cout << "ref md5 : " << refMd5.toStdString() << "\nref xml : " << refXml.toStdString() << endl;
581 QString name = funcElement.attribute("name","none");
582 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
584 QStringList positionStr = funcElement.attribute("position","none").split(",");
585 if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
586 int posX = positionStr.at(0).toInt(&ok);
587 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
588 int posY = positionStr.at(1).toInt(&ok);
589 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
591 QStringList dimensionStr = funcElement.attribute("dimension","none").split(",");
592 if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
593 int dimX = dimensionStr.at(0).toInt(&ok);
594 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
595 int dimY = dimensionStr.at(1).toInt(&ok);
596 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
598 ReferenceBlock *referenceMd5 = NULL;
599 ReferenceBlock *referenceXml = NULL;
600 ReferenceBlock *reference = NULL;
601 if(refMd5 != "none") {
602 referenceMd5 = params->searchBlockByMd5(refMd5);
604 if(refXml != "none"){
605 referenceXml = params->searchBlockByXml(refXml);
607 if ((referenceMd5 == NULL) && (referenceXml == NULL)) {
608 throw(Exception(PROJECTFILE_CORRUPTED));
610 if (referenceMd5 != referenceXml) {
611 reference = referenceXml;
614 reference = referenceMd5;
617 FunctionalBlock* functionalBlock = params->getGraph()->createSourceBlock(reference);
618 /* NB: createSourceBlock creates all interfaces from the reference, which is annoying when
619 reading bif_iface tags. Thus interface are all removed.
621 functionalBlock->setName(name);
622 setRefBlock(functionalBlock);
625 setDimension(dimX,dimY);
629 QDomNodeList blockParamNodes = funcElement.elementsByTagName("source_parameter");
630 // setting parameters value
631 for(int i=0; i<blockParamNodes.length(); i++){
632 QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement();
634 QString name = currentBlockParamNode.attribute("name","none");
635 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
637 QString value = currentBlockParamNode.attribute("value","none");
638 if(value == "none") throw(Exception(PROJECTFILE_CORRUPTED));
640 BlockParameter *blockParam = NULL;
641 blockParam = functionalBlock->getParameterFromName(name);
642 if (blockParam == NULL) throw(Exception(PROJECTFILE_CORRUPTED));
643 blockParam->setValue(value);
646 // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars
647 functionalBlock->removeAllInterfaces();
648 QDomNodeList interfaceNodes = funcElement.elementsByTagName("source_iface");
649 // setting interfaces (user name, and for multiplicity>1 may be create some new ones)
650 for(int i=0; i<interfaceNodes.length(); i++) {
652 QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
654 QString name = currentInterfaceNode.attribute("name","none");
655 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
657 QString refName = currentInterfaceNode.attribute("ref_name","none");
658 if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));
660 ReferenceInterface* refInter = AI_TO_REF(reference->getIfaceFromName(refName));
661 cout << "creating iface from reference named " << qPrintable(refName) << endl;
662 FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter);
663 functionalInterface->setName(name);
664 functionalBlock->addInterface(functionalInterface);
666 // searching for control interface
667 QString ctlRefName = refName+"_enb";
668 ReferenceInterface* ctlRefIface = AI_TO_REF(reference->getIfaceFromName(ctlRefName));
670 if (ctlRefIface != NULL) {
671 cout << "found a control iface:" << qPrintable(ctlRefName) << endl;
672 FunctionalInterface *ctlIface = new FunctionalInterface(functionalBlock,ctlRefIface);
673 if (! ctlIface->setAssociatedIface(functionalInterface)) {
674 throw(Exception(PROJECTFILE_CORRUPTED));
676 ctlIface->setName(name+"_enb");
677 functionalBlock->addInterface(ctlIface);
681 // creating InterfaceItem
682 createInterfaceItems();
683 // setting them with saved values
684 for(int i=0; i<interfaceNodes.length(); i++){
686 QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
688 int id = currentInterfaceNode.attribute("id","none").toInt(&ok);
689 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
691 QString name = currentInterfaceNode.attribute("name","none");
692 if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
694 QString orientationStr = currentInterfaceNode.attribute("orientation","none");
695 int orientation = InterfaceItem::getIntOrientation(orientationStr);
696 if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));
698 double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);
699 if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
701 InterfaceItem *interfaceItem = searchInterfaceItemByName(name);
702 interfaceItem->setId(id);
703 interfaceItem->setOrientation(orientation);
704 interfaceItem->setPositionRatio(position);
706 updateGeometry(Resize);
709 void SourceItem::save(QXmlStreamWriter &writer) {
711 writer.writeStartElement("source_item");
713 writer.writeAttribute("id",QString::number(id));
714 writer.writeAttribute("ref_xml", ((FunctionalBlock*)refBlock)->getReferenceXmlFile());
715 writer.writeAttribute("ref_md5", ((FunctionalBlock*)refBlock)->getReferenceHashMd5());
716 writer.writeAttribute("name",refBlock->getName());
717 QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
718 writer.writeAttribute("position",attrPos);
719 QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
720 writer.writeAttribute("dimension",attrDim);
722 writer.writeStartElement("source_parameters");
723 foreach(BlockParameter *param,refBlock->getParameters()){
724 writer.writeStartElement("source_parameter");
726 writer.writeAttribute("name",param->getName());
727 writer.writeAttribute("value",param->getValue().toString());
729 writer.writeAttribute("context",param->getStrContext());
730 writer.writeAttribute("type",param->getTypeString());
732 writer.writeEndElement(); //</source_parameter>
734 writer.writeEndElement(); //</source_parameters>
736 writer.writeStartElement("source_ifaces");
737 writer.writeAttribute("count",QString::number(interfaces.length()));
738 foreach(InterfaceItem* inter, interfaces){
739 writer.writeStartElement("source_iface");
741 writer.writeAttribute("id",QString::number(inter->getId()));
742 writer.writeAttribute("name",inter->getName());
743 writer.writeAttribute("ref_name",inter->refInter->getName());
744 writer.writeAttribute("orientation",inter->getStrOrientation());
745 writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
747 writer.writeEndElement(); //</source_iface>
749 writer.writeEndElement(); //</source_ifaces>
751 writer.writeEndElement(); //</source_item>