From d43174d0eb3d293b3bb5fbe76662241134e74d0d Mon Sep 17 00:00:00 2001 From: stephane Domas Date: Wed, 3 May 2017 08:26:43 +0200 Subject: [PATCH] loading project corrected --- AbstractBlock.cpp | 31 +++-- AbstractBlock.h | 1 + AbstractBoxItem.cpp | 43 ++++++- AbstractBoxItem.h | 4 +- BoxItem.cpp | 157 +++++++++++++++++++++++- BoxItem.h | 4 + Dispatcher.cpp | 64 ++++++---- Dispatcher.h | 4 +- GroupItem.cpp | 94 ++++++++++++++ GroupItem.h | 6 + GroupScene.cpp | 28 +++-- GroupScene.h | 4 +- InterfaceItem.cpp | 13 +- InterfaceItem.h | 8 +- MainWindow.cpp | 76 +++++++----- MainWindow.h | 2 +- Parameters.cpp | 289 +++++++++----------------------------------- Parameters.h | 3 +- blast.creator.user | 2 +- projectfile.xsd | 9 ++ 20 files changed, 506 insertions(+), 336 deletions(-) diff --git a/AbstractBlock.cpp b/AbstractBlock.cpp index 6e9cc86..d316800 100644 --- a/AbstractBlock.cpp +++ b/AbstractBlock.cpp @@ -16,18 +16,8 @@ AbstractBlock::AbstractBlock(const QString& _name) { AbstractBlock::~AbstractBlock() { - foreach(AbstractInterface* iface, inputs) { - delete iface; - } - foreach(AbstractInterface* iface, outputs) { - delete iface; - } - foreach(AbstractInterface* iface, bidirs) { - delete iface; - } - inputs.clear(); - outputs.clear(); - bidirs.clear(); + removeAllInterfaces(); + foreach(BlockParameter* p, params) { delete p; } @@ -90,6 +80,23 @@ void AbstractBlock::removeInterface(AbstractInterface *inter) { delete inter; } +void AbstractBlock::removeAllInterfaces() { + + foreach(AbstractInterface* iface, inputs) { + delete iface; + } + foreach(AbstractInterface* iface, outputs) { + delete iface; + } + foreach(AbstractInterface* iface, bidirs) { + delete iface; + } + inputs.clear(); + outputs.clear(); + bidirs.clear(); + +} + void AbstractBlock::defineBlockParam(BlockParameter *param) { cout << "definition of param : " << param->getName().toStdString() << endl; diff --git a/AbstractBlock.h b/AbstractBlock.h index 19209b7..acdc1c8 100644 --- a/AbstractBlock.h +++ b/AbstractBlock.h @@ -51,6 +51,7 @@ public: void addParameter(BlockParameter *param); void addInterface(AbstractInterface *inter); void removeInterface(AbstractInterface *inter); + void removeAllInterfaces(); void defineBlockParam(BlockParameter *param); QList getInterfaces(); diff --git a/AbstractBoxItem.cpp b/AbstractBoxItem.cpp index ec791fb..c4cdae9 100644 --- a/AbstractBoxItem.cpp +++ b/AbstractBoxItem.cpp @@ -15,9 +15,8 @@ AbstractBoxItem:: AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, QGraphicsItem *parent) : QGraphicsItem(parent) { dispatcher = _dispatcher; params = _params; - refBlock = _refBlock; - QFont fontId("Arial",10); - QFontMetrics fmId(fontId); + refBlock = _refBlock; + QFontMetrics fmId(params->defaultBlockFont); nameWidth = fmId.width(refBlock->getName()); nameHeight = fmId.height(); nameMargin = 10; @@ -42,6 +41,34 @@ AbstractBoxItem:: AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispat // NOTE : initInterfaces() is only called in subclasses } +AbstractBoxItem::AbstractBoxItem(Dispatcher *_dispatcher, Parameters *_params, QGraphicsItem* parent) : QGraphicsItem(parent) { + dispatcher = _dispatcher; + params = _params; + refBlock = NULL; + nameWidth = 0; + nameHeight = 0; + nameMargin = 10; + ifaceMargin = 10; + + // the six following values will be override in subclass constructors + minimumBoxWidth = 0; + minimumBoxHeight = 0; + boxWidth = 0; + boxHeight = 0; + totalWidth = 0; + totalHeight = 0; + + originPoint = QPointF(0.0,0.0); + + selected = false; + currentInterface = NULL; + rstClkVisible = false; + + setAcceptHoverEvents(true); + + // NOTE : initInterfaces() is only called in subclasses +} + AbstractBoxItem::~AbstractBoxItem() { foreach(InterfaceItem* inter, interfaces) { delete inter; @@ -57,8 +84,14 @@ bool AbstractBoxItem::isGroupItem() { return false; } -void AbstractBoxItem::initInterfaces() -{ +void AbstractBoxItem::setRefBlock(AbstractBlock* _refBlock) { + refBlock = _refBlock; + QFontMetrics fmId(params->defaultBlockFont); + nameWidth = fmId.width(refBlock->getName()); + nameHeight = fmId.height(); +} + +void AbstractBoxItem::initInterfaces() { /* TO DO : creating all needed InterfaceItem, with by default, input at west and output at east */ int orientation = Parameters::West; diff --git a/AbstractBoxItem.h b/AbstractBoxItem.h index 375e9dc..98cec58 100644 --- a/AbstractBoxItem.h +++ b/AbstractBoxItem.h @@ -22,6 +22,7 @@ public: enum ChangeType { Resize = 0, InterfaceMove }; AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, QGraphicsItem* parent = Q_NULLPTR); + AbstractBoxItem(Dispatcher *_dispatcher, Parameters *_params, QGraphicsItem* parent = Q_NULLPTR); virtual ~AbstractBoxItem(); @@ -40,7 +41,8 @@ public: inline QPointF getOriginPoint() { return originPoint; } // setters - inline void setId(int id){ this->id = id; } + void setRefBlock(AbstractBlock* _refBlock); + inline void setId(int _id){ id = _id; } inline void setSelected(bool _selected) { selected = _selected; } inline void setRstClkVisible(bool b){ rstClkVisible = b;} void setDimension(int x, int y); diff --git a/BoxItem.cpp b/BoxItem.cpp index 237c7ee..a654718 100644 --- a/BoxItem.cpp +++ b/BoxItem.cpp @@ -12,6 +12,7 @@ #include "ReferenceBlock.h" #include "ParametersWindow.h" #include "BlockParameter.h" +#include "Graph.h" BoxItem::BoxItem(AbstractBlock *_refBlock, @@ -41,6 +42,26 @@ BoxItem::BoxItem(AbstractBlock *_refBlock, //cout << "pos in group: " << x() << "," << y() << endl; } +BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent) throw(Exception) : AbstractBoxItem(_dispatcher, _params, parent) { + + refBlock = NULL; + childGroupItem = NULL; + currentBorder = NoBorder; + selected = false; + + setZValue(100); + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges); + + boxWidth = params->defaultBlockWidth; + boxHeight = params->defaultBlockHeight; + //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; +} BoxItem::~BoxItem() { } @@ -133,7 +154,7 @@ bool BoxItem::updateGeometry(ChangeType type) { bool boxSizeChanged = false; - // whatever the change, the minimum size may ahve changed + // whatever the change, the minimum size may have changed updateMinimumSize(); if (type == Resize) { @@ -589,6 +610,132 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { new ParametersWindow(refBlock, params, NULL); } } +void BoxItem::loadFunctional(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()->addFunctionalBlock(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; igetParameterFromName(name); + if (blockParam == NULL) throw(Exception(PROJECTFILE_CORRUPTED)); + blockParam->setValue(value); + } + + // recreate all interface 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; igetIfaceFromName(refName)); + FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter); + functionalInterface->setName(name); + functionalBlock->addInterface(functionalInterface); + } + // creating InterfaceItem + initInterfaces(); + // setting them with saved values + for(int i=0; isetId(id); + interfaceItem->setOrientation(orientation); + interfaceItem->setPositionRatio(position); + } + updateGeometry(Resize); +} void BoxItem::save(QXmlStreamWriter &writer) { if (refBlock->isFunctionalBlock()) { @@ -682,7 +829,7 @@ QDataStream &operator <<(QDataStream &out, BoxItem &b) { for(int i=0; igetId(); - toWrite << inter->getName(); + //toWrite << inter->getName(); toWrite << inter->getPositionRatio(); toWrite << inter->getOrientation(); } @@ -692,8 +839,7 @@ QDataStream &operator <<(QDataStream &out, BoxItem &b) { return out; } -QDataStream &operator >>(QDataStream &in, BoxItem &b) -{ +QDataStream &operator >>(QDataStream &in, BoxItem &b) { in.setVersion(QDataStream::Qt_4_8); @@ -723,8 +869,7 @@ QDataStream &operator >>(QDataStream &in, BoxItem &b) in >> positionRatio; in >> orientation; - inter->setId(id); - inter->setName(name); + inter->setId(id); inter->setPositionRatio(positionRatio); inter->setOrientation(orientation); inter->updatePosition(); diff --git a/BoxItem.h b/BoxItem.h index 74eb36a..35a12a8 100644 --- a/BoxItem.h +++ b/BoxItem.h @@ -5,6 +5,8 @@ #include #include +#include +#include #include "AbstractBoxItem.h" @@ -29,6 +31,7 @@ class BoxItem : public AbstractBoxItem { public: BoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, GroupItem* parent) throw(Exception); + BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem* parent) throw(Exception); ~BoxItem(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); @@ -44,6 +47,7 @@ public: // others void moveTo(QPointF dest); + void loadFunctional(QDomElement funcElement) throw(Exception); void save(QXmlStreamWriter& writer); protected: diff --git a/Dispatcher.cpp b/Dispatcher.cpp index b191651..bbeb841 100644 --- a/Dispatcher.cpp +++ b/Dispatcher.cpp @@ -44,6 +44,7 @@ GroupWidget *Dispatcher::loadProject(const QString& filename) { return NULL; } + /* // creating the top widget/scene topGroup = new GroupWidget(NULL,this,params); currentGroup = topGroup; @@ -52,9 +53,9 @@ GroupWidget *Dispatcher::loadProject(const QString& filename) { params->setTopScene(scene); params->setCurrentScene(scene); - +*/ try { - params->loadProject(root); + topGroup = params->loadProject(root); } catch(Exception e){ cerr << qPrintable(e.getDefaultMessage()) << endl; @@ -72,7 +73,11 @@ void Dispatcher::closeCurrentProject() { foreach(GroupWidget* win, groupList) { win->deleteLater(); } + groupList.clear(); params->destroyGraph(); + topGroup = NULL; + currentGroup = NULL; + sceneCounter = 0; } bool Dispatcher::connect(InterfaceItem *iface1, InterfaceItem *iface2) { @@ -234,8 +239,6 @@ void Dispatcher::renameInterface(InterfaceItem *item) { if (item->refInter->getOwner()->isGroupBlock()) { item->refInter->setName(text); } - item->setName(text); - } else { QMessageBox::warning(NULL,"Error in given name", @@ -343,7 +346,7 @@ GroupWidget *Dispatcher::createTopScene(){ return topGroup; } -void Dispatcher::addNewEmptyGroup(GroupScene* scene) { +GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) { static QString fctName = "Dispatcher::addNewEmptyGroup();"; #ifdef DEBUG_FCTNAME cout << "call to " << qPrintable(fctName) << endl; @@ -360,7 +363,8 @@ void Dispatcher::addNewEmptyGroup(GroupScene* scene) { params->unsaveModif = true; GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem); - child->show(); + if (show) child->show(); + return child; } @@ -370,24 +374,38 @@ GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *up cout << "call to " << qPrintable(fctName) << endl; #endif - // getting back the goup block already created - GroupBlock* groupBlock = NULL; - if (upperItemOfGroupItem != NULL) { - groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock()); - } - // creating the view part of the group - GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params); - // creating the group widget - GroupWidget* group = new GroupWidget(parentWidget, this, params); - // getting the newly created scene - GroupScene *scene = group->getScene(); - scene->setId(sceneCounter++); - // affecting group item to the scene - scene->setGroupItem(groupItem); - groupList.append(group); - - mainWindow->getLibrary()->updateComboScene(); + GroupWidget* group = NULL; + /* NB: this method may be called during design process or when loading + a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things + cannot be initialized yet. This is why there are 2 cases below + */ + if (upperItemOfGroupItem != NULL) { + // getting back the goup block already created + GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock()); + // creating the view part of the group + GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params); + // creating the group widget + group = new GroupWidget(parentWidget, this, params); + // getting the newly created scene + GroupScene *scene = group->getScene(); + scene->setId(sceneCounter++); + // affecting group item to the scene + scene->setGroupItem(groupItem); + groupList.append(group); + + mainWindow->getLibrary()->updateComboScene(); + } + else { + GroupItem *groupItem = new GroupItem(this,params); + // creating the group widget + group = new GroupWidget(parentWidget, this, params); + // getting the newly created scene + GroupScene *scene = group->getScene(); + // affecting group item to the scene + scene->setGroupItem(groupItem); + groupList.append(group); + } return group; } diff --git a/Dispatcher.h b/Dispatcher.h index fd61087..e79ad60 100644 --- a/Dispatcher.h +++ b/Dispatcher.h @@ -44,11 +44,13 @@ public: void destroyScene(GroupScene* scene); void showRaiseWindow(BoxItem *item); void showRstClkInter(AbstractBoxItem *item); - void addNewEmptyGroup(GroupScene *scene); + GroupWidget *addNewEmptyGroup(GroupScene *scene, bool show = true); void addNewFullGroup(); inline GroupWidget* getCurrentGroup() { return currentGroup; } + inline void setSceneCounter(int value) { sceneCounter = value;} + bool isCurrentProject; public slots: diff --git a/GroupItem.cpp b/GroupItem.cpp index fa341b2..69b5e04 100644 --- a/GroupItem.cpp +++ b/GroupItem.cpp @@ -10,6 +10,8 @@ #include "ConnectedInterface.h" #include "GroupScene.h" #include "ParametersWindow.h" +#include "GroupBlock.h" +#include "GroupInterface.h" GroupItem::GroupItem(BoxItem *_parentItem, @@ -48,6 +50,21 @@ GroupItem::GroupItem(BoxItem *_parentItem, cout << "pos in scene: " << x() << "," << y() << endl; } +GroupItem::GroupItem(Dispatcher *_dispatcher,Parameters *_params) throw(Exception) :AbstractBoxItem(_dispatcher, _params) { + + parentItem = NULL; + rectTitle = QRectF(0,-(nameHeight+2*nameMargin),nameWidth+2*nameMargin,nameHeight+2*nameMargin); + selected = false; + setZValue(-100); + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges); + + updateGeometry(InterfaceMove); + QPointF initPos = QPointF(0.0,0.0) - originPoint; + setPos(initPos); + cout << "total size of group: " << totalWidth << "," << totalHeight << endl; + cout << "pos in scene: " << x() << "," << y() << endl; +} + GroupItem::~GroupItem() { // since the reference block is nowhere referenced except in this class, it must be deleted here delete refBlock; @@ -61,6 +78,13 @@ BoxItem* GroupItem::getParentItem() { return parentItem; } +void GroupItem::setParentItem(BoxItem *_parentItem) { + parentItem = _parentItem; + if (parentItem != NULL) { + parentItem->setChildGroupItem(this); + } +} + void GroupItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { if(boxWidth > 0 && boxHeight > 0){ if(selected) @@ -569,6 +593,76 @@ InterfaceItem* GroupItem::isHoverInterface(QPointF point) { return NULL; } +void GroupItem::load(QDomElement groupElement) throw(Exception) { + + GroupBlock* groupBlock = AB_TO_GRP(refBlock); + + bool ok = false; + + int id = groupElement.attribute("id","none").toInt(&ok); + if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); + + QString nameStr = groupElement.attribute("name","none"); + if(nameStr == "none") throw(Exception(PROJECTFILE_CORRUPTED)); + + QStringList positionStr = groupElement.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 = groupElement.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)); + + setId(id); + setPos(posX,posY); + setDimension(dimX,dimY); + groupBlock->setName(nameStr); + + cout << "group info : \n-id : " << id << "\n-pos : " << posX << ", " << posY << "\n-dim : " << dimX << ", " << dimY << "\n-name : " << nameStr.toStdString() << endl; + + QDomNodeList interfaces = groupElement.elementsByTagName("group_iface"); + for(int j=0; jsetId(id); + + groupBlock->addInterface(groupInterface); + addInterface(interfaceItem, false); + cout << "interface add to " << groupBlock->getName().toStdString() << endl; + } + +} + void GroupItem::save(QXmlStreamWriter &writer) { writer.writeStartElement("group_item"); diff --git a/GroupItem.h b/GroupItem.h index 3882a60..137ff03 100644 --- a/GroupItem.h +++ b/GroupItem.h @@ -5,6 +5,9 @@ #include #include +#include +#include + #include "AbstractBoxItem.h" class AbstractBoxItem; @@ -31,12 +34,14 @@ public: */ GroupItem(BoxItem* _parentItem, AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params) throw(Exception); + GroupItem(Dispatcher *_dispatcher, Parameters *_params) throw(Exception); //! uses only when loading a project file ~GroupItem(); // getters BoxItem* getParentItem(); // setters + void setParentItem(BoxItem* _parentItem); // testers bool isGroupItem(); @@ -44,6 +49,7 @@ public: // others void updateShape(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + void load(QDomElement groupElement) throw(Exception); void save(QXmlStreamWriter& writer); protected: diff --git a/GroupScene.cpp b/GroupScene.cpp index daf6bf1..e8c9e84 100644 --- a/GroupScene.cpp +++ b/GroupScene.cpp @@ -86,15 +86,8 @@ QList GroupScene::getGroupAndBlocks() { BoxItem *GroupScene::createBlockItem(AbstractBlock *block) { - BoxItem* blockItem = new BoxItem(block,dispatcher,params,groupItem); - blockItem->setZValue(1); - addBlockItem(blockItem); - return blockItem; -} - -void GroupScene::addBlockItem(BoxItem* item) { - // add item from the viewport - //addItem(item); + BoxItem* item = new BoxItem(block,dispatcher,params,groupItem); + item->setZValue(1); // add item from the QList blockItems.append(item); // repainting the group @@ -102,7 +95,16 @@ void GroupScene::addBlockItem(BoxItem* item) { // center the new block QPointF newPos((groupItem->getWidth()-item->getTotalWidth())/2.0, (groupItem->getHeight()-item->getTotalHeight())/2.0); newPos = newPos-item->getOriginPoint(); - item->moveTo(newPos); + item->moveTo(newPos); + + return item; +} + +void GroupScene::addBlockItem(BoxItem* item) { + // add item from the QList + blockItems.append(item); + // repainting the group + groupItem->updateShape(); } void GroupScene::removeBlockItem(BoxItem* item) { @@ -187,6 +189,12 @@ void GroupScene::updateConnectionItemsShape() { void GroupScene::save(QXmlStreamWriter &writer) { writer.writeStartElement("scene"); writer.writeAttribute("id",QString::number(id)); + if (parentScene == NULL) { + writer.writeAttribute("upper_scene",QString::number(-1)); + } + else { + writer.writeAttribute("upper_scene",QString::number(parentScene->getId())); + } groupItem->save(writer); writer.writeStartElement("block_items"); diff --git a/GroupScene.h b/GroupScene.h index e7b42ec..a14ef0b 100644 --- a/GroupScene.h +++ b/GroupScene.h @@ -69,8 +69,8 @@ public: // others - BoxItem* createBlockItem(AbstractBlock* block); - void addBlockItem(BoxItem* item); + BoxItem* createBlockItem(AbstractBlock* block); //! create a new BoxItem and place it at the center of the scene + void addBlockItem(BoxItem* item); //! add an already configured BoxItem in the scene. void removeBlockItem(BoxItem* item); void createConnectionItem(InterfaceItem* iface1, InterfaceItem* iface2); ConnectionItem* searchConnectionItem(InterfaceItem* iface1, InterfaceItem* iface2); diff --git a/InterfaceItem.cpp b/InterfaceItem.cpp index 552e159..0e87a19 100644 --- a/InterfaceItem.cpp +++ b/InterfaceItem.cpp @@ -19,10 +19,9 @@ InterfaceItem::InterfaceItem(double _position, // CAUTION : the owner must add explicitely this item to its interface, calling addInterface() owner = _owner; params = _params; - selected = false; - name = refInter->getName(); + selected = false; QFontMetrics fmName(params->defaultIfaceFont); - nameWidth = fmName.width(name); + nameWidth = fmName.width(refInter->getName()); nameHeight = fmName.height(); // by default, only data interface are visible if (refInter->getPurpose() == AbstractInterface::Data) { @@ -42,6 +41,10 @@ InterfaceItem::InterfaceItem(){ this->id = counter++; } +QString InterfaceItem::getName() { + return refInter->getName(); +} + /* boundingRect() : give the bounding rect in the blockitem coord. system */ QRectF InterfaceItem::boundingRect() const { @@ -364,11 +367,11 @@ void InterfaceItem::unconnectTo(InterfaceItem *iface) iface->refInter->connectFrom(NULL); } if(iface->refInter->getConnectedTo().contains(refInter)){ - cout << "abnormal case while removing iface conn from " << qPrintable(name) << " to " << qPrintable(iface->name) << endl; + cout << "abnormal case while removing iface conn from " << qPrintable(refInter->getName()) << " to " << qPrintable(iface->refInter->getName()) << endl; iface->refInter->removeConnectedTo(refInter); } if(refInter->getConnectedFrom() == iface->refInter) { - cout << "abnormal case while removing iface conn from " << qPrintable(name) << " to " << qPrintable(iface->name) << endl; + cout << "abnormal case while removing iface conn from " << qPrintable(refInter->getName()) << " to " << qPrintable(iface->refInter->getName()) << endl; refInter->connectFrom(NULL); } if(refInter->getConnectedTo().contains(iface->refInter)){ diff --git a/InterfaceItem.h b/InterfaceItem.h index ce65b9e..ef3b58d 100644 --- a/InterfaceItem.h +++ b/InterfaceItem.h @@ -30,7 +30,7 @@ public: // getters inline int getId() { return id; } - inline QString getName() { return name; } + QString getName(); inline double getPositionRatio() { return positionRatio; } inline double getPosition() { return position; } inline int getOrientation() { return orientation; } @@ -43,8 +43,7 @@ public: // setters void setOriginPoint(); - inline void setId(int id){ this->id = id; } - inline void setName(QString name){ this->name = name; } + inline void setId(int id){ this->id = id; } inline void setPositionRatio(double ratio) { positionRatio = ratio; } inline void setOrientation(int _orientation){ orientation = _orientation; } @@ -68,8 +67,7 @@ public: private: - int id; - QString name; + int id; double positionRatio; int position; // position in pixels on the "orientation side" of the owner int orientation; // north, south, east, west diff --git a/MainWindow.cpp b/MainWindow.cpp index e9f8414..6afabcd 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -271,11 +271,12 @@ void MainWindow::slotLoadProject(){ if (topGroup != NULL) { addTopGroup(topGroup); library->updateComboScene(); + params->isCurrentProject = true; + enableProjectActions(true, PROJECT_CLOSE | PROJECT_SAVE | PROJECT_SAVEAS | PROJECT_LIB, OP_RAZ); } else { QMessageBox msgBox; - msgBox.setText("Cannot open the project."); - msgBox.setInformativeText("Do you want to save your changes?"); + msgBox.setText("Cannot open the project."); msgBox.setStandardButtons(QMessageBox::Cancel); msgBox.setDefaultButton(QMessageBox::Cancel); @@ -294,21 +295,46 @@ void MainWindow::slotNewProject(){ params->isCurrentProject = true; } -void MainWindow::slotCloseProject(){ +bool MainWindow::slotCloseProject(){ - // removing the GroupWidget from stack - QWidget *widget = stackedWidget->widget(1); - stackedWidget->removeWidget(widget); - stackedWidget->setCurrentIndex(0); + bool doClose = false; - dispatcher->closeCurrentProject(); + if(params->isCurrentProject) { + if (params->unsaveModif) { + QMessageBox msgBox; + msgBox.setText("The project has been modified."); + msgBox.setInformativeText("Do you want to save your changes?"); + msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Save); + int ret = msgBox.exec(); - params->isCurrentProject = false; - params->unsaveModif = false; - absoluteFilename = QString(); + switch(ret) { + case QMessageBox::Save : + slotSaveProject(); + doClose = true; + break; + case QMessageBox::Discard : + doClose = true; + break; + } + } + if (doClose) { + // removing the GroupWidget from stack + QWidget *widget = stackedWidget->widget(1); + stackedWidget->removeWidget(widget); + stackedWidget->setCurrentIndex(0); - initialize(); + dispatcher->closeCurrentProject(); + + params->isCurrentProject = false; + params->unsaveModif = false; + absoluteFilename = QString(); + + initialize(); + } + } + return doClose; } @@ -358,29 +384,13 @@ void MainWindow::removeTopGroup() { stackedWidget->setCurrentIndex(0); } -void MainWindow::closeEvent(QCloseEvent *event){ - if(params->isCurrentProject){ - QMessageBox msgBox; - msgBox.setText("The project has been modified."); - msgBox.setInformativeText("Do you want to save your changes?"); - msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); - msgBox.setDefaultButton(QMessageBox::Save); - - int ret = msgBox.exec(); - - switch(ret) { - case QMessageBox::Save : - slotSaveProject(); - slotCloseProject(); - break; - case QMessageBox::Discard : - slotCloseProject(); - break; - } +void MainWindow::closeEvent(QCloseEvent *event) { + + if (params->isCurrentProject) { + slotCloseProject(); event->ignore(); - } else { - exit(0); } + } void MainWindow::mousePressEvent(QMouseEvent *e) { diff --git a/MainWindow.h b/MainWindow.h index 28feaff..2dee56c 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -115,7 +115,7 @@ private slots: void slotLoadProject(); void slotSaveProject(); void slotSaveAsProject(); - void slotCloseProject(); + bool slotCloseProject(); void slotOpenBlockLibrary(); void slotNewBlockWidget(); diff --git a/Parameters.cpp b/Parameters.cpp index fce0435..4fd583d 100644 --- a/Parameters.cpp +++ b/Parameters.cpp @@ -189,115 +189,64 @@ QDomElement Parameters::openProjectFile(const QString& projectFileName) throw(Ex return root; } -void Parameters::loadProject(QDomElement root) { - -#ifdef DEBUG_INCLFUN +GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { bool ok = false; GroupWidget* groupWidget = NULL; GroupItem *groupItem = NULL; GroupBlock *groupBlock = NULL; + GroupWidget* topGroup = NULL; /********************************************************** 1 : getting scene and creating associated group widgets ***********************************************************/ QDomNodeList scenesNodes = root.elementsByTagName("scene"); + int maxIdScene = -1; for(int i=0; i maxIdScene) maxIdScene = idScene; int idUpperScene = currentSceneNode.attribute("upper_scene","none").toInt(&ok); if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); if (idUpperScene == -1) { - dispatcher->createTopScene(); + topGroup = dispatcher->createTopScene(); topScene->setId(idScene); - groupItem = topScene->getGroupItem(); - groupBlock = AB_TO_GRP(groupItem->getRefBlock()); + groupItem = topScene->getGroupItem(); cout << "top group added to scene n°" << idScene << endl; } else { - GroupScene* scene = searchSceneById(idUpperScene, topScene); - GroupWidget* parent = scene->getGroupWindow(); - groupWidget = dispatcher->createChildScene(parent); - groupItem = groupWidget->getScene()->getGroupItem(); - groupBlock = AB_TO_GRP(groupItem->getRefBlock()); + cout << "trying to create scene n°" << idScene << " with upper scene n°" <addNewEmptyGroup(upperScene,false); + groupWidget->getScene()->setId(idScene); + groupItem = groupWidget->getScene()->getGroupItem(); } + groupBlock = AB_TO_GRP(groupItem->getRefBlock()); /********************************************************** - 1.1 : getting the group item + 1.1 : getting the group item of each scene ***********************************************************/ QDomElement groupItemNode = currentSceneNode.firstChildElement("group_item"); - - int id = groupItemNode.attribute("id","none").toInt(&ok); - if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); - - QString name = groupItemNode.attribute("name","none"); - if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED)); - - QStringList positionStr = groupItemNode.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 = groupItemNode.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)); - - groupItem->setId(id); - groupItem->setPos(posX,posY); - groupItem->setDimension(dimX,dimY); - groupBlock->setName(name); + try { + groupItem->load(groupItemNode); + } + catch(Exception err) { + throw(err); + } if (idUpperScene != -1) { groupWidget->setWindowTitle(groupBlock->getName()); groupWidget->show(); - } - cout << "group info : \n-id : " << id << "\n-pos : " << posX << ", " << posY << "\n-dim : " << dimX << ", " << dimY << "\n-name : " << name.toStdString() << endl; - - QDomNodeList interfaces = groupItemNode.elementsByTagName("group_iface"); - for(int j=0; jsetId(id); - - groupBlock->addInterface(groupInterface); - groupItem->addInterface(interfaceItem); - cout << "interface add to " << groupBlock->getName().toStdString() << endl; - } + } } - + dispatcher->setSceneCounter(maxIdScene+1); cout << "groupItems loaded and windows created succefully!" << endl; + /********************************************************** + 2 : getting the functional blocks of each scene + ***********************************************************/ for(int i=0; igetGroupItem()->getRefBlock(),reference); - functionalBlock->setName(name); - - ((GroupBlock*)currentScene->getGroupItem()->getRefBlock())->addBlock(functionalBlock); - - - BlockItem *blockItem = new BlockItem(currentScene->getGroupItem(),functionalBlock,dispatcher,this); - blockItem->setPos(posX,posY); - blockItem->setDimension(dimX,dimY); - blockItem->setId(id); - ((GroupItem*)currentScene->getGroupItem())->addBlockItem(blockItem); - currentScene->addItem(blockItem); - currentScene->addBlockItem(blockItem); - - QDomNodeList blockParamNodes = currentFBNode.elementsByTagName("bif_parameter"); - - for(int i=0; isetName(name); - blockParam->setValue(value); - blockParam->setType(type); - if(context == "constant") blockParam->setContext(BlockParameter::Constant); - if(context == "user") blockParam->setContext(BlockParameter::User); - if(context == "generic") blockParam->setContext(BlockParameter::Generic); - if(context == "wb") blockParam->setContext(BlockParameter::Wishbone); - if(context == "port") blockParam->setContext(BlockParameter::Port); - - functionalBlock->addParameter(blockParam); + for(int j=0; jgetGroupItem()); + try { + funcItem->loadFunctional(currentFBNode); } - - - QDomNodeList interfaceNodes = currentFBNode.elementsByTagName("bif_iface"); - - for(int i=0; igetIfaceFromName(refName); - FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter); - functionalBlock->addInterface(functionalInterface); - functionalInterface->setName(refName); - - InterfaceItem *interfaceItem = new InterfaceItem(position,orientation,functionalInterface,blockItem,this); - interfaceItem->setId(id); - interfaceItem->setName(name); - - blockItem->addInterface(interfaceItem); - + catch(Exception err) { + throw(err); } + // add the block to the GroupScene + currentScene->addBlockItem(funcItem); } } - cout << "functionalBlocks loaded and created succefully!" << endl; + cout << "functional blocks loaded and created succefully!" << endl; + /********************************************************** + 3 : set the BoxItem that represents a GroupItem in a child scene + ***********************************************************/ for(int i=0; igetRefBlock(), dispatcher, this); - blockItem->setChildGroupItem(insideGroup); - blockItem->setId(id); - blockItem->setPos(posX,posY); - blockItem->setDimension(dimX,dimY); + // now search within the scene which BoxItem has a childItem that is = to insideGroup + QList lst = currentScene->getBlockItems(); + foreach(BoxItem* item, lst) { + if (item->getChildGroupItem() == insideGroup) { + upperItem = item; + break; + } + } + if (upperItem == NULL) { + throw(Exception(PROJECTFILE_CORRUPTED)); + } - ((GroupItem*)currentScene->getGroupItem())->addBlockItem(blockItem); - currentScene->addItem(blockItem); - currentScene->addBlockItem(blockItem); + upperItem->setId(id); + upperItem->setPos(posX,posY); + upperItem->setDimension(dimX,dimY); + // set interfaces of this BoxItem QDomNodeList interfaceNodes = currentBiGroup.elementsByTagName("big_iface"); for(int k=0; ksearchInterfaceByName(refName)->refInter; - InterfaceItem *ifaceItem = new InterfaceItem(position, orientation, refInter, blockItem, this); + ConnectedInterface *refInter = insideGroup->searchInterfaceByName(refName)->refInter; + InterfaceItem *ifaceItem = new InterfaceItem(position, orientation, refInter, upperItem, this); ifaceItem->setId(id); - blockItem->addInterface(ifaceItem); + upperItem->addInterface(ifaceItem); } } } cout << "blockItems \"group\" loaded and created succefully!" << endl; - - for(int i=0; isetUpperItem(upperItem); - } - } - QDomNodeList connectionNodes = root.elementsByTagName("connection"); for(int i=0; i - + EnvironmentId diff --git a/projectfile.xsd b/projectfile.xsd index 8a35bc9..e5693dc 100644 --- a/projectfile.xsd +++ b/projectfile.xsd @@ -90,6 +90,14 @@ + + + + + + + + @@ -213,6 +221,7 @@ + -- 2.39.5