+#include "SourceItem.h"
+#include "GroupScene.h"
+#include "ConnectionItem.h"
+#include "InterfaceItem.h"
+#include "GroupItem.h"
+#include "Parameters.h"
+#include "Exception.h"
+#include "Dispatcher.h"
+#include "FunctionalBlock.h"
+#include "FunctionalInterface.h"
+#include "ReferenceInterface.h"
+#include "ReferenceBlock.h"
+#include "ParametersWindow.h"
+#include "BlockParameter.h"
+#include "Graph.h"
+
+
+SourceItem::SourceItem(AbstractBlock *_refBlock,
+ Dispatcher *_dispatcher,
+ Parameters *_params) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params) {
+
+ /* NOTE :
+ _refBlock : mandatory a FunctionalBlock or a GroupBlock
+ */
+ if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
+
+ currentBorder = NoBorder;
+ selected = false;
+
+ setZValue(100);
+ setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
+
+ initInterfaces();
+ updateGeometry(InterfaceMove);
+ resetInterfacesPosition();
+ QPointF initPos = QPointF(0.0,0.0) - originPoint;
+ setPos(initPos);
+ //cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
+ //cout << "pos in group: " << x() << "," << y() << endl;
+}
+
+SourceItem::SourceItem(Dispatcher *_dispatcher, Parameters *_params) throw(Exception) : AbstractBoxItem(_dispatcher, _params) {
+
+ refBlock = NULL;
+ currentBorder = NoBorder;
+ selected = false;
+
+ setZValue(100);
+ setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
+
+ boxWidth = params->defaultBlockWidth;
+ boxHeight = params->defaultBlockHeight;
+}
+
+SourceItem::~SourceItem() {
+}
+
+void SourceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
+ QPen pen(Qt::black, 3);
+ if(selected)
+ pen.setColor(Qt::red);
+
+ painter->setPen(pen);
+ painter->setBrush(Qt::darkCyan);
+
+ painter->drawRect(0,0,boxWidth, boxHeight);
+ painter->drawText(0,0,boxWidth, boxHeight,Qt::AlignCenter | Qt::TextWordWrap,QString(refBlock->getName()));
+ foreach(InterfaceItem *inter, interfaces) {
+
+ inter->paint(painter);
+ }
+}
+
+void SourceItem::moveTo(QPointF dest) {
+ setPos(dest);
+ currentPosition = dest;
+}
+
+bool SourceItem::isSourceItem() {
+ return true;
+}
+
+void SourceItem::nameChanged() {
+
+
+ QFontMetrics fmId(params->defaultBlockFont);
+ nameWidth = fmId.width(refBlock->getName());
+ nameHeight = fmId.height();
+ updateGeometry(InterfaceMove);
+ // force the update in case of the size has not changed
+ update();
+}
+
+void SourceItem::updateMinimumSize() {
+
+ int maxSouth = 0;
+ int maxNorth = 0;
+ int maxEast = 0;
+ int maxWest = 0;
+ int nbSouth = nbInterfacesByOrientation(Parameters::South);
+ int nbNorth = nbInterfacesByOrientation(Parameters::North);
+ int nbMaxSN = nbNorth;
+ if (nbSouth > nbNorth) nbMaxSN = nbSouth;
+ int nbEast = nbInterfacesByOrientation(Parameters::East);
+ int nbWest = nbInterfacesByOrientation(Parameters::West);
+ int nbMaxEW = nbEast;
+ if (nbWest > nbEast) {
+ nbMaxEW = nbWest;
+ }
+
+ int ifaceWidth = 0;
+ int ifaceHeight = 0;
+
+ foreach(InterfaceItem* iface, interfaces) {
+ ifaceWidth = iface->getNameWidth();
+ ifaceHeight = iface->getNameHeight();
+ if (iface->visible) {
+ 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;
+ }
+ }
+ }
+
+ /* NB: the width layout is the following
+ ifaceMargin | maxWest | nameMargin | name | nameMargin | maxEast | ifaceMargin
+ */
+ minimumBoxWidth = maxWest+maxEast+nameWidth+2*(ifaceMargin+nameMargin);
+ // if the minimum is not sufficent taking into account N/S interfaces
+ if (minimumBoxWidth < (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1))) {
+ minimumBoxWidth = (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1));
+ }
+ minimumBoxHeight = maxNorth+maxSouth+3*ifaceMargin;
+ if (minimumBoxHeight < (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1))) {
+ minimumBoxHeight = (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1));
+ }
+}
+
+
+/* updateGeometry() :
+
+ */
+bool SourceItem::updateGeometry(ChangeType type) {
+
+ currentPosition = pos();
+ //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) {
+ // resize implies to move interfaces and to update connections
+ boxSizeChanged = true;
+ }
+ else if (type == InterfaceMove) {
+ // if an interface moves, it may change the box size
+ if (boxWidth < minimumBoxWidth) {
+ boxWidth = minimumBoxWidth;
+ boxSizeChanged = true;
+ }
+ if (boxHeight < minimumBoxHeight) {
+ boxHeight = minimumBoxHeight;
+ boxSizeChanged = true;
+ }
+ }
+ if (boxSizeChanged) {
+ updateInterfacesAndConnections();
+ }
+
+
+ double x = 0.0;
+ double y = 0.0;
+ totalWidth = boxWidth;
+ totalHeight = boxHeight;
+
+ if(isInterfaces(Parameters::East)){
+ totalWidth += params->arrowWidth+params->arrowLineLength;
+ }
+ if(isInterfaces(Parameters::West)){
+ totalWidth += params->arrowWidth+params->arrowLineLength;
+ x -= params->arrowWidth+params->arrowLineLength;
+ }
+ if(isInterfaces(Parameters::South)){
+ totalHeight += params->arrowWidth+params->arrowLineLength;
+ }
+ if(isInterfaces(Parameters::North)){
+ totalHeight += params->arrowWidth+params->arrowLineLength;
+ y -= params->arrowWidth+params->arrowLineLength;
+ }
+ QSizeF newSize(totalWidth,totalHeight);
+ originPoint.setX(x);
+ originPoint.setY(y);
+
+ if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
+ prepareGeometryChange();
+ return true;
+ }
+ return false;
+}
+
+void SourceItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
+
+ if(params->editState == Parameters::EditBlockMove) {
+ QPointF absPos = currentPosition + originPoint;
+
+ int gapX = event->scenePos().x() - cursorPosition.x();
+ int gapY = event->scenePos().y() - cursorPosition.y();
+
+ //cout << "block abs. pos: " << absPos.x() << "," << absPos.y() << " | ";
+ //cout << "block current. pos: " << currentPosition.x() << "," << currentPosition.y() << " | ";
+
+ /*
+ if (absPos.x()+gapX < marginConn) {
+ gapX = marginConn-absPos.x();
+ }
+ 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();
+ }
+ }
+ cursorPosition = event->scenePos();
+
+ // udpate the groupitem
+ (getScene()->getGroupItem())->updateShape();
+ }
+ else if(params->editState == Parameters::EditBlockResize) {
+
+ int gapX = event->scenePos().x() - cursorPosition.x();
+ int gapY = event->scenePos().y() - cursorPosition.y();
+ //cout << "gap: " << gapX << "," << gapY << endl;
+ switch(currentBorder){
+ case BorderEast: {
+ if(boxWidth+gapX > minimumBoxWidth){
+ boxWidth += gapX;
+ }
+ break;
+ }
+ case BorderSouth: {
+ if(boxHeight+gapY > minimumBoxHeight){
+ boxHeight += gapY;
+ }
+ break;
+ }
+ case CornerSouthEast: {
+ if(boxWidth+gapX > minimumBoxWidth){
+ boxWidth += gapX;
+ }
+ if(boxHeight+gapY > minimumBoxHeight){
+ boxHeight += gapY;
+ }
+ break;
+ }
+ case NoBorder:
+ cout << "abnormal case while resizing block" << endl;
+ break;
+ }
+ // recompute the geometry of the block and possibly the group item
+ if (updateGeometry(Resize)) {
+ (getScene()->getGroupItem())->updateShape();
+ }
+
+ cursorPosition = event->scenePos();
+ }
+ else if(params->editState == Parameters::EditInterfaceMove) {
+ prepareGeometryChange();
+ moveInterfaceTo(event->pos());
+ // recompute the geometry of the block
+ if (updateGeometry(InterfaceMove)) {
+ //cout << "must recompute group item geometry" << endl;
+ (getScene()->getGroupItem())->updateShape();
+ }
+ // update connection from/to the selected interface
+ foreach(ConnectionItem *item, getScene()->getConnectionItems()){
+ if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
+ item->setPath();
+ }
+ }
+ }
+}
+
+void SourceItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
+
+ QPointF pos = event->pos();
+ qreal x = pos.x();
+ qreal y = pos.y();
+
+ //QGraphicsItem::mousePressEvent(event);
+
+ if(event->button() == Qt::RightButton) return;
+
+ int mode = getScene()->getEditionMode();
+
+ dispatcher->setCurrentGroupWidget(getScene()->getGroupWidget());
+
+ if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) {
+ InterfaceItem *inter = getInterfaceFromCursor(x,y);
+ if (inter != NULL) {
+
+ if (params->editState == Parameters::EditNoOperation) {
+ getScene()->setSelectedInterface(1,inter);
+ params->setEditState(Parameters::EditStartConnection);
+ }
+ else if (params->editState == Parameters::EditStartConnection) {
+ if (inter == getScene()->getSelectedInterface(1)) {
+ params->setEditState(Parameters::EditAbortConnection);
+ }
+ else {
+ getScene()->setSelectedInterface(2,inter);
+ params->setEditState(Parameters::EditCloseConnection);
+ }
+ }
+ }
+ }
+ else if (mode == GroupScene::ItemEdition) {
+ setZValue(zValue()+100);
+ if (params->cursorState == Parameters::CursorOnInterface) {
+ InterfaceItem *inter = getInterfaceFromCursor(x,y);
+ if (inter != NULL) {
+ if (inter == currentInterface) {
+ params->setEditState(Parameters::EditInterfaceDeselect);
+ }
+ else {
+ setFlag(ItemIsMovable, false);
+ currentInterface = inter;
+ params->setEditState(Parameters::EditInterfaceMove);
+ }
+ }
+ }
+ else if (params->cursorState == Parameters::CursorInBlock) {
+ selected = !selected;
+ params->setEditState(Parameters::EditBlockMove);
+ cursorPosition = event->scenePos();
+ //cout << "cursor current pos. in scene " << cursorPosition.x() << "," << cursorPosition.y() << endl;
+ update();
+ }
+ else if (params->cursorState == Parameters::CursorOnBorder) {
+ setFlag(ItemIsMovable, false);
+ cursorPosition = event->scenePos();
+ params->setEditState(Parameters::EditBlockResize);
+ }
+ }
+}
+
+void SourceItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
+
+ setZValue(zValue()-100);
+
+ int mode = getScene()->getEditionMode();
+
+ if (mode == GroupScene::AddConnection) {
+
+ if (params->editState == Parameters::EditStartConnection) {
+ InterfaceItem* iface = getScene()->getSelectedInterface(1);
+ iface->selected = true;
+ update(iface->boundingRect());
+ }
+ else if (params->editState == Parameters::EditAbortConnection) {
+ InterfaceItem* iface = getScene()->getSelectedInterface(1);
+ iface->selected = false;
+ update(iface->boundingRect());
+ getScene()->setSelectedInterface(1,NULL);
+ params->setEditState(Parameters::EditNoOperation);
+ }
+ else if (params->editState == Parameters::EditCloseConnection) {
+ InterfaceItem* iface1 = getScene()->getSelectedInterface(1);
+ InterfaceItem* iface2 = getScene()->getSelectedInterface(2);
+ bool ok = dispatcher->createConnectionItem(iface1,iface2);
+ if (ok) {
+ iface1->selected = false;
+ // no update needed since the whole scene will be repainted
+ getScene()->setSelectedInterface(1,NULL);
+ getScene()->setSelectedInterface(2,NULL);
+ params->setEditState(Parameters::EditNoOperation);
+ }
+ else {
+ //QMessageBox::warning(NULL,"Error","Cannot connect selected interfaces", QMessageBox::Ok);
+ getScene()->setSelectedInterface(2,NULL);
+ params->setEditState(Parameters::EditStartConnection);
+ }
+ }
+ }
+ else if (mode == GroupScene::ItemEdition) {
+ currentInterface = NULL;
+ params->editState = Parameters::EditNoOperation;
+ setFlag(ItemIsMovable);
+ }
+
+ QGraphicsItem::mouseReleaseEvent(event);
+}
+
+void SourceItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
+
+ QPointF pos = event->pos();
+ qreal x = pos.x();
+ qreal y = pos.y();
+ currentBorder = NoBorder;
+ int mode = getScene()->getEditionMode();
+
+ if (mode == GroupScene::AddConnection) {
+ InterfaceItem* iface = getInterfaceFromCursor(x,y);
+ if (iface != NULL) {
+ params->cursorState = Parameters::CursorOnInterface;
+ setCursor(Qt::PointingHandCursor);
+ }
+ else {
+ params->cursorState = Parameters::CursorNowhere;
+ setCursor(Qt::ArrowCursor);
+ }
+ }
+ else if (mode == GroupScene::ItemEdition) {
+ int marginE = 5;
+ int marginS = 5;
+
+ InterfaceItem* iface = getInterfaceFromCursor(x,y);
+ if (iface != NULL) {
+ params->cursorState = Parameters::CursorOnInterface;
+ setCursor(Qt::PointingHandCursor);
+ }
+ else if ((x>boxWidth-marginE)&&(x<boxWidth)) {
+
+ params->cursorState = Parameters::CursorOnBorder;
+
+ if ((y>boxHeight-2*marginS)&&(y<boxHeight)) {
+ currentBorder = CornerSouthEast;
+ setCursor(Qt::SizeFDiagCursor);
+ }
+ else {
+ currentBorder = BorderEast;
+ setCursor(Qt::SizeHorCursor);
+ }
+ }
+ else if ((y>boxHeight-marginS)&&(y<boxHeight)) {
+
+ params->cursorState = Parameters::CursorOnBorder;
+
+ if ((x>boxWidth-2*marginE)&&(x<boxWidth)) {
+ currentBorder = CornerSouthEast;
+ setCursor(Qt::SizeFDiagCursor);
+ }
+ else {
+ currentBorder = BorderSouth;
+ setCursor(Qt::SizeVerCursor);
+ }
+ }
+ else {
+ if ((x>0) && (x<boxWidth-marginE) && (y>0) && (y<boxHeight-marginS)) {
+ params->cursorState = Parameters::CursorInBlock;
+ setCursor(Qt::OpenHandCursor);
+ }
+ else {
+ params->cursorState = Parameters::CursorNowhere;
+ setCursor(Qt::ArrowCursor);
+ }
+ }
+ }
+ QGraphicsItem::hoverMoveEvent(event);
+}
+
+
+void SourceItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
+
+ event->accept();
+
+ QMenu menu;
+ QAction* titleAction = NULL;
+ QAction* removeAction = NULL;
+ QAction* duplicateAction = NULL;
+ QAction* renameAction = NULL;
+ QAction* showProperties = NULL;
+ QAction* showParameters = NULL;
+
+
+ InterfaceItem* ifaceItem = getInterfaceFromCursor(event->pos().x(), event->pos().y());
+ // menu for interface
+ if( ifaceItem != NULL){
+
+ titleAction = menu.addAction("Interface operations");
+ titleAction->setEnabled(false);
+ menu.addSeparator();
+
+
+ showProperties = menu.addAction("Show properties");
+ renameAction = menu.addAction("Rename");
+
+ }
+ // menu for block
+ else {
+ titleAction = menu.addAction("Block operations");
+ titleAction->setEnabled(false);
+ menu.addSeparator();
+
+ if (refBlock->nbParameters() > 0) {
+ showParameters = menu.addAction("Show parameters");
+ }
+ renameAction = menu.addAction("Rename");
+
+ duplicateAction = menu.addAction("Duplicate");
+ removeAction = menu.addAction("Remove");
+ }
+
+ QAction* selectedAction = NULL;
+ selectedAction = menu.exec(event->screenPos());
+
+ if(selectedAction == NULL) return ;
+
+ if (selectedAction == removeAction) {
+ dispatcher->removeSourceItem(this);
+ }
+ else if (selectedAction == duplicateAction) {
+ dispatcher->duplicateSourceItem(this);
+ }
+ else if(selectedAction == renameAction){
+ if(ifaceItem != NULL) {
+ dispatcher->renameInterface(ifaceItem);
+ }
+ else {
+ dispatcher->renameSourceBlock(this);
+ }
+ }
+ else if(selectedAction == showProperties){
+ dispatcher->showProperties(ifaceItem);
+ }
+ else if(selectedAction == showParameters){
+ new ParametersWindow(refBlock, params, NULL);
+ }
+}
+
+void SourceItem::load(QDomElement funcElement) throw(Exception) {
+
+ bool ok = false;
+
+ int id = funcElement.attribute("id","none").toInt(&ok);
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+ QString refXml = funcElement.attribute("ref_xml","none");
+ if(refXml == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+ QString refMd5 = funcElement.attribute("ref_md5","none");
+ if(refMd5 == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+ cout << "ref md5 : " << refMd5.toStdString() << "\nref xml : " << refXml.toStdString() << endl;
+
+ QString name = funcElement.attribute("name","none");
+ if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+ QStringList positionStr = funcElement.attribute("position","none").split(",");
+ if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
+ int posX = positionStr.at(0).toInt(&ok);
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+ int posY = positionStr.at(1).toInt(&ok);
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+ QStringList dimensionStr = funcElement.attribute("dimension","none").split(",");
+ if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
+ int dimX = dimensionStr.at(0).toInt(&ok);
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+ int dimY = dimensionStr.at(1).toInt(&ok);
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+ ReferenceBlock *referenceMd5 = NULL;
+ ReferenceBlock *referenceXml = NULL;
+ ReferenceBlock *reference = NULL;
+ if(refMd5 != "none") {
+ referenceMd5 = params->searchBlockByMd5(refMd5);
+ }
+ if(refXml != "none"){
+ referenceXml = params->searchBlockByXml(refXml);
+ }
+ if ((referenceMd5 == NULL) && (referenceXml == NULL)) {
+ throw(Exception(PROJECTFILE_CORRUPTED));
+ }
+ if (referenceMd5 != referenceXml) {
+ throw(Exception(PROJECTFILE_CORRUPTED));
+ }
+ else {
+ reference = referenceMd5;
+ }
+
+ GroupBlock* parentGroupBlock = AB_TO_GRP(((GroupItem *)parentItem())->getRefBlock());
+ FunctionalBlock* functionalBlock = params->getGraph()->createFunctionalBlock(parentGroupBlock, reference);
+ /* NB: addFunctionalBlock creates all interfaces from the reference, which is annoying when
+ reading bif_iface tags. Thus interface are all removed.
+ */
+ functionalBlock->setName(name);
+ setRefBlock(functionalBlock);
+
+ setPos(posX,posY);
+ setDimension(dimX,dimY);
+ setId(id);
+
+
+ QDomNodeList blockParamNodes = funcElement.elementsByTagName("bif_parameter");
+ // setting parameters value
+ for(int i=0; i<blockParamNodes.length(); i++){
+ QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement();
+
+ QString name = currentBlockParamNode.attribute("name","none");
+ if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+ QString value = currentBlockParamNode.attribute("value","none");
+ if(value == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+ BlockParameter *blockParam = NULL;
+ blockParam = functionalBlock->getParameterFromName(name);
+ if (blockParam == NULL) throw(Exception(PROJECTFILE_CORRUPTED));
+ blockParam->setValue(value);
+ }
+
+ // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars
+ functionalBlock->removeAllInterfaces();
+ QDomNodeList interfaceNodes = funcElement.elementsByTagName("bif_iface");
+ // setting interfaces (user name, and for multiplicity>1 may be create some new ones)
+ for(int i=0; i<interfaceNodes.length(); i++) {
+
+ QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
+
+ QString name = currentInterfaceNode.attribute("name","none");
+ if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+ QString refName = currentInterfaceNode.attribute("ref_name","none");
+ if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+ ReferenceInterface* refInter = AI_TO_REF(reference->getIfaceFromName(refName));
+ cout << "creating iface from reference named " << qPrintable(refName) << endl;
+ FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter);
+ functionalInterface->setName(name);
+ functionalBlock->addInterface(functionalInterface);
+
+ // searching for control interface
+ QString ctlRefName = refName+"_ctl";
+ ReferenceInterface* ctlRefIface = AI_TO_REF(reference->getIfaceFromName(ctlRefName));
+
+ if (ctlRefIface != NULL) {
+ cout << "found a control iface:" << qPrintable(ctlRefName) << endl;
+ FunctionalInterface *ctlIface = new FunctionalInterface(functionalBlock,ctlRefIface);
+ if (! ctlIface->setAssociatedIface(functionalInterface)) {
+ throw(Exception(PROJECTFILE_CORRUPTED));
+ }
+ ctlIface->setName(name+"_ctl");
+ functionalBlock->addInterface(ctlIface);
+ }
+ }
+
+ // creating InterfaceItem
+ initInterfaces();
+ // setting them with saved values
+ for(int i=0; i<interfaceNodes.length(); i++){
+
+ QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
+
+ int id = currentInterfaceNode.attribute("id","none").toInt(&ok);
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+ QString name = currentInterfaceNode.attribute("name","none");
+ if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+ QString orientationStr = currentInterfaceNode.attribute("orientation","none");
+ int orientation = InterfaceItem::getIntOrientation(orientationStr);
+ if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));
+
+ double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+ InterfaceItem *interfaceItem = searchInterfaceByName(name);
+ interfaceItem->setId(id);
+ interfaceItem->setOrientation(orientation);
+ interfaceItem->setPositionRatio(position);
+ }
+ updateGeometry(Resize);
+}
+
+void SourceItem::save(QXmlStreamWriter &writer) {
+
+ writer.writeStartElement("source_item");
+
+ writer.writeAttribute("id",QString::number(id));
+ writer.writeAttribute("ref_xml", ((FunctionalBlock*)refBlock)->getReferenceXmlFile());
+ writer.writeAttribute("ref_md5", ((FunctionalBlock*)refBlock)->getReferenceHashMd5());
+ writer.writeAttribute("name",refBlock->getName());
+ 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);
+
+ writer.writeStartElement("source_parameters");
+ foreach(BlockParameter *param,refBlock->getParameters()){
+ writer.writeStartElement("source_parameter");
+
+ writer.writeAttribute("name",param->getName());
+ writer.writeAttribute("value",param->getValue().toString());
+ /*
+ writer.writeAttribute("context",param->getStrContext());
+ writer.writeAttribute("type",param->getTypeString());
+ */
+ writer.writeEndElement(); //</source_parameter>
+ }
+ writer.writeEndElement(); //</source_parameters>
+
+ writer.writeStartElement("source_ifaces");
+ writer.writeAttribute("count",QString::number(interfaces.length()));
+ foreach(InterfaceItem* inter, interfaces){
+ writer.writeStartElement("source_iface");
+
+ writer.writeAttribute("id",QString::number(inter->getId()));
+ writer.writeAttribute("name",inter->getName());
+ writer.writeAttribute("ref_name",inter->refInter->getName());
+ writer.writeAttribute("orientation",inter->getStrOrientation());
+ writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
+
+ writer.writeEndElement(); //</source_iface>
+ }
+ writer.writeEndElement(); //</source_ifaces>
+
+ writer.writeEndElement(); //</source_item>
+
+}