--- /dev/null
+/archive/*
+/build/*
+/Makefile
+/configure
+*~
+*.aux
+*.log
+*.dvi
+*.bbl
+*.blg
\ No newline at end of file
--- /dev/null
+#include <AbstractBlock.h>\r
+#include <QInputDialog>\r
+#include <QMessageBox>\r
+#include "AbstractInterface.h"\r
+#include "BlockParameter.h"\r
+\r
+AbstractBlock::AbstractBlock() {\r
+ name = "";\r
+ parent = NULL;\r
+}\r
+\r
+AbstractBlock::AbstractBlock(const QString& _name) {\r
+ name = _name;\r
+ parent = NULL;\r
+}\r
+\r
+AbstractBlock::~AbstractBlock() {\r
+\r
+ foreach(AbstractInterface* iface, inputs) {\r
+ delete iface;\r
+ }\r
+ foreach(AbstractInterface* iface, outputs) {\r
+ delete iface;\r
+ }\r
+ foreach(AbstractInterface* iface, bidirs) {\r
+ delete iface;\r
+ }\r
+ inputs.clear();\r
+ outputs.clear();\r
+ bidirs.clear();\r
+ foreach(BlockParameter* p, params) {\r
+ delete p;\r
+ }\r
+ params.clear();\r
+}\r
+\r
+void AbstractBlock::setName(const QString& str) {\r
+ name = str;\r
+}\r
+\r
+void AbstractBlock::setParent(AbstractBlock* _parent) {\r
+ parent = _parent;\r
+}\r
+\r
+bool AbstractBlock::isReferenceBlock() {\r
+ return false;\r
+}\r
+\r
+bool AbstractBlock::isFunctionalBlock() {\r
+ return false;\r
+}\r
+\r
+bool AbstractBlock::isGroupBlock() {\r
+ return false;\r
+}\r
+\r
+void AbstractBlock::addParameter(BlockParameter *param) {\r
+ params.append(param);\r
+}\r
+\r
+\r
+BlockParameter* AbstractBlock::getParameterFromName(QString name) {\r
+ foreach(BlockParameter* p, params) {\r
+ if (p->getName() == name) return p;\r
+ }\r
+ return NULL;\r
+}\r
+\r
+void AbstractBlock::addInterface(AbstractInterface *inter) {\r
+ if(inter->getDirection() == AbstractInterface::Input){\r
+ inputs.append(inter);\r
+ } else if(inter->getDirection() == AbstractInterface::Output){\r
+ outputs.append(inter);\r
+ } else if(inter->getDirection() == AbstractInterface::InOut){\r
+ bidirs.append(inter);\r
+ }\r
+}\r
+\r
+void AbstractBlock::removeInterface(AbstractInterface *inter) {\r
+ /* CAUTION: no check is done about the connection state of this interface\r
+ Thus, if it is still connected to/from, there will be a crash\r
+ */\r
+ if(inter->getDirection() == AbstractInterface::Input){\r
+ inputs.removeAll(inter);\r
+ } else if(inter->getDirection() == AbstractInterface::Output){\r
+ outputs.removeAll(inter);\r
+ } else if(inter->getDirection() == AbstractInterface::InOut){\r
+ bidirs.removeAll(inter);\r
+ }\r
+ delete inter;\r
+}\r
+\r
+void AbstractBlock::defineBlockParam(BlockParameter *param)\r
+{\r
+ cout << "definition of param : " << param->getName().toStdString() << endl;\r
+ bool ok = false;\r
+ QString value = QInputDialog::getText(NULL, "Block parameter", "value for the "+ param->getName() +" parameter of " + param->getOwner()->getName() + "?", QLineEdit::Normal, param->getValue().toString(), &ok);\r
+\r
+ while (!ok && value.isEmpty())\r
+ {\r
+ QMessageBox::critical(NULL, "Error", "You have to insert a value for the parameter or accept the default value !");\r
+ value = QInputDialog::getText(NULL, "Block parameter", "value for the "+ param->getName() +" parameter of " + param->getOwner()->getName() + " ?", QLineEdit::Normal, param->getValue().toString(), &ok);\r
+ }\r
+ param->setValue(value); \r
+}\r
+\r
+QList<AbstractInterface *> AbstractBlock::getInterfaces() {\r
+ QList<AbstractInterface *> list;\r
+ list.append(inputs);\r
+ list.append(outputs);\r
+ list.append(bidirs);\r
+ return list;\r
+}\r
+\r
+AbstractInterface* AbstractBlock::getIfaceFromName(QString name) {\r
+\r
+ foreach(AbstractInterface* iface, inputs) {\r
+ if (iface->getName() == name) return iface;\r
+ }\r
+ foreach(AbstractInterface* iface, outputs) {\r
+ if (iface->getName() == name) return iface;\r
+ }\r
+ foreach(AbstractInterface* iface, bidirs) {\r
+ if (iface->getName() == name) return iface;\r
+ }\r
+ return NULL;\r
+}\r
+\r
+bool AbstractBlock::isWBConfigurable() {\r
+\r
+ foreach(BlockParameter* p, params) {\r
+ if (p->isWishboneParameter()) return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+QList<BlockParameter *> AbstractBlock::getUserParameters() {\r
+ QList<BlockParameter *> lst;\r
+ foreach(BlockParameter* p, params) {\r
+ if (p->isUserParameter()) lst.append(p);\r
+ }\r
+ return lst;\r
+}\r
+\r
+QList<BlockParameter *> AbstractBlock::getGenericParameters() {\r
+ QList<BlockParameter *> lst;\r
+ foreach(BlockParameter* p, params) {\r
+ if (p->isGenericParameter()) lst.append(p);\r
+ }\r
+ return lst;\r
+}\r
+\r
+QList<BlockParameter *> AbstractBlock::getPortParameters() {\r
+ QList<BlockParameter *> lst;\r
+ foreach(BlockParameter* p, params) {\r
+ if (p->isPortParameter()) lst.append(p);\r
+ }\r
+ return lst;\r
+}\r
+\r
+QList<BlockParameter *> AbstractBlock::getWishboneParameters() {\r
+ QList<BlockParameter *> lst;\r
+ foreach(BlockParameter* p, params) {\r
+ if (p->isWishboneParameter()) lst.append(p);\r
+ }\r
+ return lst;\r
+}\r
--- /dev/null
+#ifndef __ABSTRACTBLOCK_H__\r
+#define __ABSTRACTBLOCK_H__\r
+\r
+#include <iostream>\r
+\r
+#include <QtCore>\r
+\r
+class AbstractInterface;\r
+class BlockParameter;\r
+\r
+#define AB_TO_REF(ptr) ((ReferenceBlock*)ptr)\r
+#define AB_TO_FUN(ptr) ((FunctionalBlock*)ptr)\r
+#define AB_TO_GRP(ptr) ((GroupBlock*)ptr)\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+class AbstractBlock {\r
+\r
+public: \r
+\r
+ AbstractBlock();\r
+ AbstractBlock(const QString& _name);\r
+ virtual ~AbstractBlock();\r
+\r
+ // getters\r
+ inline QString getName() { return name; }\r
+ inline QList<BlockParameter *> getParameters() { return params; }\r
+ inline QList<AbstractInterface*> getInputs() { return inputs; }\r
+ inline QList<AbstractInterface*> getOutputs() { return outputs; }\r
+ inline QList<AbstractInterface*> getBidirs() { return bidirs; }\r
+ QList<BlockParameter *> getUserParameters();\r
+ QList<BlockParameter *> getGenericParameters();\r
+ QList<BlockParameter *> getPortParameters();\r
+ QList<BlockParameter *> getWishboneParameters();\r
+ inline AbstractBlock* getParent() { return parent; }\r
+ // setters\r
+ void setName(const QString& str);\r
+ virtual void setParent(AbstractBlock* _parent);\r
+\r
+ // testers\r
+ virtual bool isReferenceBlock();\r
+ virtual bool isFunctionalBlock();\r
+ virtual bool isGroupBlock();\r
+ bool isWBConfigurable();\r
+\r
+ // others\r
+ virtual void parametersValidation(QList<AbstractBlock*>* checkedBlocks, QList<AbstractBlock*>* blocksToConfigure) = 0; // ugly but usefull \r
+\r
+ void addParameter(BlockParameter *param);\r
+ void addInterface(AbstractInterface *inter);\r
+ void removeInterface(AbstractInterface *inter);\r
+ void defineBlockParam(BlockParameter *param);\r
+\r
+ QList<AbstractInterface *> getInterfaces();\r
+ AbstractInterface* getIfaceFromName(QString name);\r
+ BlockParameter* getParameterFromName(QString name);\r
+\r
+protected:\r
+\r
+\r
+ QString name;\r
+\r
+ // parameters\r
+ QList<BlockParameter *> params;\r
+\r
+ // interfaces\r
+ QList<AbstractInterface*> inputs;\r
+ QList<AbstractInterface*> outputs;\r
+ QList<AbstractInterface*> bidirs;\r
+\r
+ // others\r
+\r
+ // NB: only GroupBlock and FunctionalBlock have a real parent\r
+ AbstractBlock* parent;\r
+};\r
+\r
+#endif // __ABSTRACTBLOCK_H__\r
--- /dev/null
+#include "AbstractBoxItem.h"
+
+#include "Parameters.h"
+
+#include "Dispatcher.h"
+#include "InterfaceItem.h"
+#include "ConnectionItem.h"
+
+#include "AbstractBlock.h"
+#include "GroupScene.h"
+#include "AbstractInterface.h"
+#include "ConnectedInterface.h"
+
+
+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);
+ nameWidth = fmId.width(refBlock->getName());
+ nameHeight = fmId.height();
+ 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;
+ }
+ interfaces.clear();
+}
+
+bool AbstractBoxItem::isBoxItem() {
+ return false;
+}
+
+bool AbstractBoxItem::isGroupItem() {
+ return false;
+}
+
+void AbstractBoxItem::initInterfaces()
+{
+ /* TO DO : creating all needed InterfaceItem, with by default, input at west and output at east */
+ int orientation = Parameters::West;
+
+ foreach(AbstractInterface *inter, refBlock->getInterfaces()){
+ if(inter->getPurpose() != AbstractInterface::Wishbone){
+ InterfaceItem *item;
+ if(inter->getDirection() == AbstractInterface::Input){
+ orientation = Parameters::West;
+ } else if(inter->getDirection() == AbstractInterface::Output){
+ orientation = Parameters::East;
+ } else if(inter->getDirection() == AbstractInterface::InOut){
+ orientation = Parameters::North;
+ }
+ item = new InterfaceItem(0.0 , orientation, (ConnectedInterface *)inter, this, params);
+ interfaces.append(item);
+ }
+ }
+}
+
+InterfaceItem* AbstractBoxItem::searchInterfaceByName(QString name) {
+ foreach(InterfaceItem *inter, interfaces){
+ if(inter->getName() == name)
+ return inter;
+ }
+ return NULL;
+}
+
+InterfaceItem* AbstractBoxItem::searchInterfaceByRef(ConnectedInterface *ref) {
+ foreach(InterfaceItem *inter, interfaces){
+ if(inter->refInter == ref) {
+ return inter;
+ }
+ }
+ return NULL;
+}
+
+void AbstractBoxItem::addInterface(InterfaceItem *i, bool resetPosition) {
+ interfaces.append(i);
+ if (resetPosition) resetInterfacesPosition();
+ updateGeometry();
+ update();
+}
+
+void AbstractBoxItem::removeInterface(InterfaceItem *i) {
+ // NB : removing from model is done in dispatcher
+ interfaces.removeOne(i);
+ delete i;
+
+ //resetInterfacesPosition();
+ updateGeometry();
+ update();
+}
+
+
+void AbstractBoxItem::resetInterfacesPosition() {
+
+ int nbNorth=0, nbSouth=0, nbEast=0, nbWest=0;
+ double cntNorth=1.0,cntSouth=1.0,cntEast=1.0,cntWest=1.0;
+ double positionRatio = 1.0;
+
+
+ foreach(InterfaceItem* inter, interfaces) {
+ // only data interfaces and if needed time and reset
+ if(inter->refInter->getPurpose() == AbstractInterface::Data || inter->getOwner()->isRstClkVisible()){
+ if(inter->getOrientation() == Parameters::North){
+ nbNorth++;
+ } else if(inter->getOrientation() == Parameters::South){
+ nbSouth++;
+ } else if(inter->getOrientation() == Parameters::East){
+ nbEast++;
+ } else if(inter->getOrientation() == Parameters::West){
+ nbWest++;
+ }
+ }
+ }
+
+ foreach(InterfaceItem* inter, interfaces) {
+
+ if(inter->refInter->getPurpose() == AbstractInterface::Data || inter->getOwner()->isRstClkVisible()){
+
+ if(inter->getOrientation() == Parameters::North){
+ positionRatio = cntNorth/(double)(nbNorth+1);
+ cntNorth += 1.0;
+ } else if(inter->getOrientation() == Parameters::South){
+ positionRatio = cntSouth/(double)(nbSouth+1);
+ cntSouth += 1.0;
+ } else if(inter->getOrientation() == Parameters::East){
+ positionRatio = cntEast/(double)(nbEast+1);
+ cntEast += 1.0;
+ } else if(inter->getOrientation() == Parameters::West){
+ positionRatio = cntWest/(double)(nbWest+1);
+ cntWest += 1.0;
+ }
+ inter->setPositionRatio(positionRatio);
+ inter->updatePosition();
+ }
+ }
+}
+
+void AbstractBoxItem::deplaceInterface(QPointF pos) {
+ double positionRatio;
+ if(currentInterface->getOrientation() == Parameters::North || currentInterface->getOrientation() == Parameters::South){
+ if(pos.x() < 0){
+ positionRatio = 0;
+ if(pos.y() > 0 && pos.y() < boxHeight){
+ currentInterface->setOrientation(Parameters::West);
+ }
+ } else if(pos.x() > boxWidth){
+ positionRatio = 1;
+ if(pos.y() > 0 && pos.y() < boxHeight){
+ currentInterface->setOrientation(Parameters::East);
+ }
+ } else {
+ positionRatio = ((double) pos.x())/boxWidth;
+ }
+ } else {
+
+ if(pos.y() < 0){
+ positionRatio = 0;
+ if(pos.x() > 0 && pos.x() < boxWidth){
+ currentInterface->setOrientation(Parameters::North);
+ }
+ } else if(pos.y() > boxHeight){
+ positionRatio = 1;
+ if(pos.x() > 0 && pos.x() < boxWidth){
+ currentInterface->setOrientation(Parameters::South);
+ }
+ } else {
+ positionRatio = ((double) pos.y())/boxHeight;
+ }
+ }
+ currentInterface->setPositionRatio(positionRatio);
+ currentInterface->updatePosition();
+}
+
+QRectF AbstractBoxItem::boundingRect() const {
+ // returns a QRectF that contains the block (i.e the main rectangle, interfaces, title, ...)
+ QPointF p = originPoint - QPointF(nameHeight,nameHeight);
+ QSizeF s(totalWidth+2*nameHeight,totalHeight+2*nameHeight);
+ return QRectF(p,s);
+}
+
+
+/* isInterface() : return true if there are some interfaces
+ with the given orientation (N,S,E,O)
+*/
+bool AbstractBoxItem::isInterfaces(int orientation) const {
+ foreach(InterfaceItem* inter, interfaces) {
+ if (inter->getOrientation() == orientation) return true;
+ }
+ return false;
+}
+
+int AbstractBoxItem::nbInterfacesByOrientation(int orientation) {
+ int nb = 0;
+ foreach(InterfaceItem* inter, interfaces) {
+ if ((inter->visible) && (inter->getOrientation() == orientation)) nb++;
+ }
+ return nb;
+}
+
+void AbstractBoxItem::updateInterfacesAndConnections() {
+
+ // update all interfaces positions
+ foreach(InterfaceItem *item, interfaces){
+ item->updatePosition();
+ }
+ if (getScene() != NULL) {
+ // update all connections from/to this block
+ foreach(ConnectionItem *item, getScene()->getConnectionItems()){
+ if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
+ item->setPathes();
+ }
+ }
+ }
+}
+
+void AbstractBoxItem::setDimension(int x, int y) {
+ boxWidth = x;
+ boxHeight = y;
+}
+
+InterfaceItem* AbstractBoxItem::getInterfaceFromCursor(qreal x, qreal y) {
+
+ foreach(InterfaceItem* inter, interfaces) {
+ if(x > inter->boundingRect().x() && x < (inter->boundingRect().x() + inter->boundingRect().width())){
+ if(y > inter->boundingRect().y() && y < (inter->boundingRect().y() + inter->boundingRect().height())){
+ return inter;
+ }
+ }
+ }
+ /* TO DO : check each interfaces if it contains x,y. If yes, return that interface */
+ return NULL;
+}
--- /dev/null
+#ifndef __ABSTRACTBOXITEM_H__
+#define __ABSTRACTBOXITEM_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+#include <QGraphicsItem>
+
+class Dispatcher;
+class InterfaceItem;
+class Parameters;
+class AbstractBlock;
+class GroupScene;
+class ConnectedInterface;
+
+class AbstractBoxItem : public QGraphicsItem {
+
+public:
+
+ enum BorderType { NoBorder = 0, BorderEast, BorderNorth, BorderWest, BorderSouth, CornerSouthEast, Title};
+ enum ChangeType { Resize = 0, InterfaceMove };
+
+ AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, QGraphicsItem* parent = Q_NULLPTR);
+
+ virtual ~AbstractBoxItem();
+
+ // getters
+ inline AbstractBlock* getRefBlock() { return refBlock; }
+ inline int getWidth() { return boxWidth;}
+ inline int getHeight() { return boxHeight;}
+ inline int getTotalWidth() { return totalWidth;}
+ inline int getTotalHeight() { return totalHeight; }
+ inline QList<InterfaceItem* > getInterfaces() { return interfaces; }
+ inline InterfaceItem *getCurrentInterface() { return currentInterface; }
+ inline int getId(){ return id; }
+ inline GroupScene* getScene() { return (GroupScene*)(scene()); }
+ inline int getIfaceMargin() { return ifaceMargin; }
+ inline int getNameMargin() { return nameMargin; }
+ inline QPointF getOriginPoint() { return originPoint; }
+
+ // setters
+ inline void setId(int id){ this->id = id; }
+ inline void setSelected(bool _selected) { selected = _selected; }
+ inline void setRstClkVisible(bool b){ rstClkVisible = b;}
+ void setDimension(int x, int y);
+ inline void setCurrentInterface(InterfaceItem* iface) { currentInterface = iface; }
+
+ // testers
+ virtual bool isBoxItem();
+ virtual bool isGroupItem();
+ inline bool isSelected() { return selected; }
+ inline bool isRstClkVisible(){ return rstClkVisible;}
+ bool isInterfaces(int orientation) const;
+
+ // others
+
+ void addInterface(InterfaceItem* i, bool resetPosition = false);
+ void removeInterface(InterfaceItem* i);
+ void resetInterfacesPosition();
+ void deplaceInterface(QPointF pos);
+ void updateInterfacesAndConnections();
+
+ InterfaceItem *searchInterfaceByName(QString name);
+ InterfaceItem *searchInterfaceByRef(ConnectedInterface* ref);
+ InterfaceItem* getInterfaceFromCursor(qreal x, qreal y);
+
+protected:
+ Dispatcher *dispatcher;
+ Parameters *params;
+ QList<InterfaceItem*> interfaces;
+ /* NOTE : the reference block may be a FunctionalBlock or a GroupBlock, depending on the fact
+ that the real instace will be of FunctionalBlock or GroupBlock
+ */
+ AbstractBlock *refBlock;
+
+ InterfaceItem* currentInterface; // currently clicked interface in ItemEdition mode
+
+ BorderType currentBorder; // which border cursor is on
+ QPointF cursorPosition;
+
+ int id;
+ int boxWidth; // the width of the main box (without interface, title, ...)
+ int boxHeight; // the height of the main box (without interface, title, ...)
+ int minimumBoxWidth; // minimum width of the main box: may be recomputed if position/number of interface changes
+ int minimumBoxHeight; // minimum height of the main box: may be recomputed if position/number of interface changes
+ int totalWidth; // width and heigth taking into account interfaces,title, ...
+ int totalHeight;
+ int nameWidth; // the width of the box (group or block) name in Arial 10
+ int nameHeight; // the height of the name in Arial 10
+ int nameMargin; // the margin around each side of the name
+ int ifaceMargin; // the margin around each side of interfaces' name
+ QPointF originPoint; // the left-top point that is the origin of the bounding box
+
+ bool selected;
+ bool rstClkVisible;
+
+ QPointF currentPosition; // the start point for resize
+
+ virtual void updateMinimumSize() = 0; // modify the minimum size
+ virtual bool updateGeometry(ChangeType type) = 0; // modify the originPoint and the total dimension
+
+ QRectF boundingRect() const;
+ /* pure virtual method inherited from QGraphicsItem :
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) =0;
+ virtual QRectF boundingRect() const =0;
+ */
+ void initInterfaces();
+ int nbInterfacesByOrientation(int orientation);
+};
+
+#endif // __ABSTRACTBOXITEM_H__
--- /dev/null
+#include "AbstractInterface.h"
+#include "BlockParameterPort.h"
+#include "AbstractBlock.h"
+
+AbstractInterface::AbstractInterface(AbstractBlock* _owner) {
+
+ owner = _owner;
+ name = "";
+ width = "1";
+ direction = Input;
+ purpose = Data;
+ level = Basic;
+ type = Boolean;
+
+}
+
+AbstractInterface::AbstractInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose, int _level) {
+
+ owner = _owner;
+ name = _name;
+ width = _width;
+ direction = _direction;
+ purpose = _purpose;
+ level = _level;
+ if (direction == InOut) {
+ level = Top;
+ }
+ type = typeFromString(_type);
+}
+
+AbstractInterface::AbstractInterface(AbstractInterface* other) {
+ owner = NULL;
+ name = other->name;
+ type = other->type;
+ width = other->width;
+ direction = other->direction;
+ purpose = other->purpose;
+ level = other->level;
+}
+
+AbstractInterface::~AbstractInterface() {
+
+}
+
+bool AbstractInterface::isReferenceInterface() {
+ return false;
+}
+
+bool AbstractInterface::isFunctionalInterface() {
+ return false;
+}
+
+bool AbstractInterface::isGroupInterface() {
+ return false;
+}
+
+QString AbstractInterface::getPurposeString() {
+ QString str;
+ switch(purpose){
+ case AbstractInterface::Data:
+ str = QString("data");
+ break;
+ case AbstractInterface::Clock:
+ str = QString("clock");
+ break;
+ case AbstractInterface::Reset:
+ str = QString("reset");
+ break;
+ case AbstractInterface::Wishbone:
+ str = QString("wishbone");
+ break;
+ }
+ return str;
+}
+
+QString AbstractInterface::getDirectionString() {
+ QString str;
+ switch(direction){
+ case AbstractInterface::Input:
+ str = QString("input");
+ break;
+ case AbstractInterface::Output:
+ str = QString("output");
+ break;
+ case AbstractInterface::InOut:
+ str = QString("inout");
+ break;
+ }
+ return str;
+}
+
+QString AbstractInterface::getLevelString() {
+ QString str;
+ switch(level){
+ case AbstractInterface::Basic:
+ str = QString("basic");
+ break;
+ case AbstractInterface::Top:
+ str = QString("top");
+ break;
+ }
+ return str;
+}
+
+double AbstractInterface::getDoubleWidth() throw(QException) {
+
+ static QString fctName = "AbstractInterface::getDoubleWidth()";
+ #ifdef DEBUG_FCTNAME
+ cout << "call to " << qPrintable(fctName) << endl;
+ #endif
+
+ /*
+ cout << "start AbstractInterface::getDoubleWidth()" << endl;
+ bool ok;
+ double width = getWidth().toDouble(&ok);
+
+ if(!ok){
+ ArithmeticEvaluator *evaluator = new ArithmeticEvaluator;
+ cout << "evaluator created!" << endl;
+ evaluator->setExpression(getWidth());
+ cout << "expression defined!" << endl;
+ foreach(BlockParameter *param, getOwner()->getParameters()){
+ evaluator->setVariableValue(param->getName(), param->getIntValue());
+ cout << "param : " << param->getName().toStdString() << " evaluated!" << endl;
+ }
+ width = evaluator->evaluate();
+ cout << "expression evaluated succefully!" << endl;
+ }
+ cout << "real width : " << width << endl;
+ return width;
+ */
+
+ return 1.0;
+}
+
+void AbstractInterface::setPurpose(int _purpose) {
+ if ((_purpose>=Data) && (_purpose <= Wishbone)) {
+ purpose = _purpose;
+ }
+}
+
+void AbstractInterface::setDirection(int _direction) {
+ if ((_direction > Input) && (_direction <= InOut)) {
+ direction = _direction;
+ }
+ if (direction == InOut) {
+ level = Top;
+ }
+}
+
+void AbstractInterface::setLevel(int _level) {
+ if ((_level >= Basic) << (_level < Top)) {
+ level = _level;
+ }
+ if (direction == InOut) {
+ level = Top;
+ }
+}
+
+
+
+int AbstractInterface::getIntDirection(QString str)
+{
+ if(str == "input") return Input;
+ if(str == "output") return Output;
+ if(str == "inOut") return InOut;
+ return -1;
+}
+
+int AbstractInterface::getIntLevel(QString str)
+{
+ if(str == "basic") return Basic;
+ if(str == "top") return Top;
+ return -1;
+}
+
+QString AbstractInterface::getTypeString() {
+
+ if (type == Boolean) {
+ return "boolean";
+ }
+ else if (type == Natural) {
+ return "natural";
+ }
+ else if (type == Expression) {
+ return "expression";
+ }
+ return "invalid_type";
+}
+
+int AbstractInterface::typeFromString(const QString &_type) {
+
+ int ret;
+ if (_type == "expression") {
+ ret = Expression;
+ }
+ else if (_type == "boolean") {
+ ret = Boolean;
+ }
+ else if (_type == "natural") {
+ ret = Natural;
+ }
+ return ret;
+}
+
+QString AbstractInterface::toVHDL(int context, int flags) throw(Exception) {
+
+ if (isReferenceInterface()) throw(Exception(IFACE_INVALID_TYPE));
+
+ QString msb = width;
+ QString ret="";
+ bool ok;
+ if ((context == BlockParameter::Entity) || (context == BlockParameter::Component)) {
+
+ QString formatBool = "%1 : %2 std_logic";
+ QString formatVector = "%1 : %2 std_logic_vector(%3 downto %4)";
+ if ((flags & BlockParameter::NoComma) == 0) {
+ formatBool.append(";");
+ formatVector.append(";");
+ }
+ QString orientation="";
+ if (direction == Input) {
+ orientation = "in";
+ }
+ else if (direction == Output) {
+ orientation = "out";
+ }
+ else {
+ orientation = "inout";
+ }
+ if (type == Boolean) {
+ ret = formatVector.arg(name).arg(orientation);
+ }
+ else if (type == Natural) {
+ int w = width.toInt(&ok);
+ if (!ok) {
+ throw(Exception(INVALID_VALUE));
+ }
+ else {
+ w -= 1;
+ ret = formatVector.arg(name).arg(orientation).arg(w).arg("0");
+ }
+ }
+ else if (type == Expression) {
+ /* must check the following conditions :
+ - if it contains user/port parameters : must evaluate their numeric value
+ - if it contains generic parameters : just remove the $ -> the expression is not arithmetically evaluated.
+ */
+ QList<BlockParameter*> listGenerics = owner->getGenericParameters();
+ QList<BlockParameter*> listUsers = owner->getUserParameters();
+ QList<BlockParameter*> listPorts = owner->getPortParameters();
+ foreach(BlockParameter* p, listUsers) {
+ QString var = "$";
+ var.append(p->getName());
+ if (width.contains(var)) {
+ int w = p->getValue().toInt(&ok);
+ if (!ok) throw(Exception(INVALID_VALUE));
+ msb.replace(var,p->getValue().toString());
+ }
+ }
+ foreach(BlockParameter* p, listPorts) {
+ QString var = "$";
+ var.append(p->getName());
+ if (width.contains(var)) {
+ BlockParameterPort* pp = (BlockParameterPort*)p;
+ AbstractInterface* iface = owner->getIfaceFromName(pp->getIfaceName());
+
+ int w = p->getValue().toInt(&ok);
+ if (!ok) throw(Exception(INVALID_VALUE));
+ msb.replace(var,p->getValue().toString());
+ }
+ }
+
+ ret = formatVector.arg(name).arg(orientation).arg("toto").arg("0");
+ }
+ }
+ return ret;
+}
+
--- /dev/null
+#ifndef __ABSTRACTINTERFACE_H__
+#define __ABSTRACTINTERFACE_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+
+class AbstractBlock;
+
+#include "Exception.h"
+class Exception;
+
+#define AI_TO_REF(ptr) ((ReferenceInterface*)ptr)
+#define AI_TO_FUN(ptr) ((FunctionalInterface*)ptr)
+#define AI_TO_GRP(ptr) ((GroupInterface*)ptr)
+
+using namespace std;
+using namespace Qt;
+
+
+class AbstractInterface {
+
+public :
+
+ enum IfaceWidthType { Expression = 1, Boolean, Natural};
+ enum IfacePurpose { Data = 1, Clock = 2, Reset = 3, Wishbone = 4 };
+ enum IfaceDirection { Input = 1, Output = 2, InOut = 3 };
+ enum IfaceLevel { Basic = 1, Top = 2 };
+ enum IfaceVHDLContext { Entity = 1, Component = 2, Architecture = 3 }; // NB : 3 is when creating an instance of the block that owns this iface
+ enum IfaceVHDLFlags { NoComma = 1 };
+
+ static int getIntDirection(QString str);
+ static int getIntLevel(QString str);
+
+ AbstractInterface(AbstractBlock* _owner);
+ AbstractInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose, int _level);
+ AbstractInterface(AbstractInterface* other);
+ virtual ~AbstractInterface();
+
+ // getters
+ inline QString getName() { return name;}
+ inline int getType() { return type; }
+ QString getTypeString();
+ inline QString getWidth() { return width;}
+ inline int getPurpose() { return purpose;}
+ QString getPurposeString();
+ inline int getDirection() { return direction;}
+ QString getDirectionString();
+ inline int getLevel() { return level;}
+ QString getLevelString();
+ inline AbstractBlock *getOwner() { return owner;}
+
+ double getDoubleWidth() throw(QException);
+
+ //virtual QList<AbstractInterface*> getConnectedTo() = 0;
+
+ /* NB: only GroupInterface and FunctionalInterface have a connectedFrom, so
+ defining getConnectedFrom as pure virtual is normal, usefull even though it is ugly :-)
+ */
+ virtual AbstractInterface* getConnectedFrom() = 0;
+
+ // setters
+ inline void setOwner(AbstractBlock* _owner) { owner = _owner; }
+ inline void setName(const QString& _name) { name = _name; }
+ inline void setWidth(const QString& _width) { width = _width; }
+ inline void setType(int _type) { type = _type;}
+ inline void setType(const QString& _type) { type = typeFromString(_type);}
+ void setPurpose(int _purpose);
+ void setDirection(int _direction);
+ void setLevel(int _level);
+
+ // testers
+ virtual bool isReferenceInterface();
+ virtual bool isFunctionalInterface();
+ virtual bool isGroupInterface();
+ //virtual bool isConnectedTo() = 0;
+ //virtual bool isConnectedFrom() = 0;
+ //virtual bool canConnectTo(AbstractInterface* iface) = 0; // returns yes if this can be connected to iface, no if not
+ //virtual bool canConnectFrom(AbstractInterface* iface) = 0; // returns yes if this can be connected from iface, no if not
+
+ // others
+ virtual AbstractInterface *clone() = 0;
+
+ //virtual bool addConnectedTo(AbstractInterface *inter) = 0;
+ //virtual void removeConnectedTo(AbstractInterface *inter) = 0;
+ //virtual bool setConnectedFrom(AbstractInterface* inter) = 0;
+ //virtual void clearConnectedTo() = 0;
+ //virtual void clearConnections() = 0;
+ //virtual void connectionsValidation(QStack<AbstractInterface*> *interfacetoValidate, QList<AbstractInterface*> *validatedInterfaces) throw(Exception) = 0;
+ int typeFromString(const QString &_type);
+
+ QString toVHDL(int context, int flags) throw(Exception);
+
+protected:
+ QString name;
+ int type;
+ QString width;
+ int purpose;
+ int direction;
+ int level;
+
+ AbstractBlock* owner;
+};
+
+
+#endif // __ABSTRACTINTERFACE_H__
--- /dev/null
+/*-==============================================================-
+
+file : ArithmeticEvaluator.cpp
+
+creation date : 19/05/2015
+
+author : S. Domas (sdomas@univ-fcomte.fr)
+
+description :
+
+supp. infos : saved in UTF-8 [éè]
+
+-==============================================================-*/
+#include "ArithmeticEvaluator.h"
+#include <math.h>
+
+ArithmeticEvaluator::ArithmeticEvaluator() {
+ opMarkers = "+-*/";
+ varMarkers = "$";
+ expression = QStringList();
+ /* CAUTION : function are mandatory using ( ) to encapsulate the operand
+ since spaces are removed. Thus, an expression like sin 10 will lead to
+ sin10 after spaces removal, and thus becomes invalid.
+ */
+ fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round";
+}
+
+ArithmeticEvaluator::ArithmeticEvaluator(const QString& _expression) throw(int) {
+ opMarkers = "+-*/";
+ varMarkers = "$";
+ fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round";
+ try {
+ setExpression(_expression);
+ }
+ catch(int e) {
+ throw(e);
+ }
+}
+
+void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) {
+ try {
+ convert(_expression);
+ }
+ catch(int e) {
+ throw(e);
+ }
+}
+
+void ArithmeticEvaluator::print() {
+ foreach(QString elt, expression) {
+ cout << qPrintable(elt) << " ";
+ }
+ cout << endl;
+}
+
+double ArithmeticEvaluator::evalFunction(int indexFunc, double value) {
+ double res = 0.0;
+ if (indexFunc == 0) {
+ res = sin(value);
+ }
+ else if (indexFunc == 1) {
+ res = cos(value);
+ }
+ else if (indexFunc == 2) {
+ res = log10(value);
+ }
+ else if (indexFunc == 3) {
+ res = log2(value);
+ }
+ else if (indexFunc == 4) {
+ res = log(value);
+ }
+ else if (indexFunc == 5) {
+ res = ceil(value);
+ }
+ else if (indexFunc == 6) {
+ res = floor(value);
+ }
+ else if (indexFunc == 7) {
+ res = round(value);
+ }
+
+ return res;
+}
+
+double ArithmeticEvaluator::evaluate() throw(int) {
+ QStack<double> stack;
+ bool ok;
+ double value1,value2;
+ int index = 0;
+ QChar c;
+ foreach(QString elt, expression) {
+ c = elt.at(0);
+ /* CAUTION :
+ \x1bn, n must correspond to the order of QString in fctMarkers.
+ */
+ if (c == '\x1b') {
+ value1 = stack.pop();
+ elt.remove(0,1);
+ int idFunc = elt.toInt(&ok);
+ if ((!ok) || (idFunc < 0) || (idFunc >= fctMarkers.size())) throw(-index);
+ stack.push(evalFunction(idFunc,value1));
+ }
+ else if (varMarkers.contains(c)) {
+ if (!varValues.contains(elt)) throw(-index);
+ stack.push(varValues.value(elt));
+ }
+ else if (opMarkers.contains(c)) {
+ value2 = stack.pop();
+ value1 = stack.pop();
+ if (c == '+') {
+ stack.push(value1+value2);
+ }
+ else if (c == '-') {
+ stack.push(value1-value2);
+ }
+ else if (c == '*') {
+ stack.push(value1*value2);
+ }
+ else if (c == '/') {
+ stack.push(value1/value2);
+ }
+ }
+ else {
+ value1 = elt.toDouble(&ok);
+ if (!ok) throw(-index);
+ stack.push(value1);
+ }
+ index += 1;
+ }
+
+ value1 = stack.pop();
+ if (!stack.isEmpty()) throw(-1);
+ return value1;
+}
+
+/* NOTE :
+ expr is of form:
+ ([ value1 | var1 | func1 | expr1 ] op1 [ value2 | var2 | func2 | expr2 ] op2 ... [ valuen | varn | funcn | exprn ])
+
+ Thus, if the whole expression does not end with ), we encapsulate it with ( ).
+
+ If we don't consider priority among operators, then expression is converted into
+ A1 A2 op1 A3 op2 ... An opn-1
+
+ example : 1+2+3-4-5 -> 1 2 + 3 + 4 -
+
+ If there is priority : * > / > + or - or func, then it is more complex
+
+ example : 1+2+3/4*5-6 -> 1 2 + 3 4 5 * / + 6 -
+
+ with parenthesis, we can do the same recursively
+
+ example : 1+(2+3/4)*5-6 = 1 + expr1 * 5 - 6 -> 1 expr1 5 * + 6 -
+ but expr1 -> 2 3 4 / +, then we finally have 1 2 3 4 / + 5 * + 6 -
+
+ a func is of form:
+ func_name(expr)
+
+ example : ((1+3-sin(5/6))*(4+(7/3)))
+
+ recursive cross in-depth of the expression leads to do a recursive call each time a ( is encountered.
+ Return of the recursive call is done when ) is encountered.
+
+ */
+
+void ArithmeticEvaluator::convert(const QString& _expression) throw(int) {
+ QString expr = _expression;
+ QString result="";
+ expr.remove(QChar(' '), Qt::CaseInsensitive);
+ foreach(QString func, fctMarkers) {
+ QString rep = QString("\x1b%1").arg(fctMarkers.indexOf(QRegExp(func)));
+
+ expr.replace(QRegExp(func),rep);
+ }
+ //cout << "packed expr: " << qPrintable(expr) << endl;
+
+ int offset = 0;
+ try {
+ result = convertRecur(expr,&offset);
+ expression = result.split(",");
+ }
+ catch(int err) {
+ cerr << "error while recursive conversion: ";
+ throw(err);
+ }
+
+}
+
+QString ArithmeticEvaluator::convertRecur(const QString& _expression, int *offset) throw(int) {
+ QString result="";
+ QStack<QChar> pile;
+
+ int size;
+ QChar c;
+
+ QString number;
+ QString expr = _expression;
+
+ // testing if it starts by a (,number, variable or function
+ if (!checkAfterOp(expr,*offset-1)) throw(*offset);
+
+ // testing if it starts with a number
+ if ((expr[*offset] == '-') || (expr[*offset].isDigit())) {
+ number = getNumber(expr,*offset,&size);
+ result.append(number+",");
+ *offset += size;
+ }
+ // testing if it starts with a variable
+ else if (varMarkers.contains(expr[*offset])){
+ number = getVariable(expr,*offset,&size);
+ result.append(number+",");
+ *offset += size;
+ }
+
+ while (*offset<expr.size()) {
+
+ if ( expr[*offset] == '\x1b') {
+ int numFunc = getFunction(expr,*offset,&size);
+ if (numFunc == -1) throw(*offset);
+ *offset += size;
+ if (expr[*offset] != '(') throw(*offset);
+ *offset += 1;
+ result += convertRecur(expr,offset);
+ result += QString("\x1b%1,").arg(numFunc);
+ }
+ else if ( expr[*offset] == '(') {
+
+ *offset += 1;
+ result += convertRecur(expr,offset);
+ }
+
+ else if ( expr[*offset] == ')') {
+
+ if (!checkAfterPar(expr,*offset)) throw(*offset);
+
+ while (! pile.isEmpty()) {
+ c = pile.pop();
+ result.append(c).append(",");
+ }
+ *offset += 1;
+ return result;
+ }
+ else if ( (expr[*offset] == '+') || (expr[*offset] == '-')) {
+
+ if (!checkAfterOp(expr,*offset)) throw(*offset);
+
+ // destack operators with equal or greater priority
+ while (!pile.isEmpty()) {
+ c = pile.pop();
+ result.append(c).append(",");
+ }
+ pile.push(expr[*offset]);
+
+ // catch the function, number or variable after operator if next char is not (
+ if ( varMarkers.contains(expr[*offset+1])) {
+ number = getVariable(expr,*offset+1,&size);
+ result.append(number+",");
+ *offset += size+1;
+ }
+ else if (expr[*offset+1].isDigit()) {
+ number = getNumber(expr,*offset+1,&size);
+ result.append(number+",");
+ *offset += size+1;
+ }
+ else {
+ *offset += 1;
+ }
+ }
+ else if (expr[*offset] == '/') {
+
+ if (!checkAfterOp(expr,*offset)) throw(*offset);
+
+ // destack operator with equal or greater priority (/ and *)
+ c = '1';
+ while ( (pile.isEmpty() == false) && (c != '(') && (c != '+') && (c != '-')) {
+ c = pile.pop();
+ if ( (c=='*') || (c == '/')) {
+ result.append(c).append(",");
+ }
+ else {
+ pile.push(c);
+ }
+ }
+ pile.push(expr[*offset]);
+
+ // catch the number or variable after operator if next char is not (
+ if ( varMarkers.contains(expr[*offset+1])) {
+ number = getVariable(expr,*offset+1,&size);
+ result.append(number+",");
+ *offset += size+1;
+ }
+ else if ( expr[*offset+1].isDigit()) {
+ number = getNumber(expr,*offset+1,&size);
+ result.append(number+",");
+ *offset += size+1;
+ }
+ else {
+ *offset += 1;
+ }
+ }
+ /* CASES with * : a*b, (expra)*b, a*(exprb), (expra)*(exprb)
+ Since * has the most priority, then :
+ a*b and (expra)*b can be translate in ... b *
+ In the two other cases, the * is stacked.
+ */
+ else if ( expr[*offset] == '*') {
+
+ if (!checkAfterOp(expr,*offset)) throw(*offset);
+
+ // catch the number or variable after operator if next char is not (
+ if ( varMarkers.contains(expr[*offset+1])) {
+ number = getVariable(expr,*offset+1,&size);
+ result.append(number+",*,");
+ *offset += size+1;
+ }
+ else if ( expr[*offset+1].isDigit()) {
+ number = getNumber(expr,*offset+1,&size);
+ result.append(number+",*,");
+ *offset += size+1;
+ }
+ else {
+ *offset += 1;
+ pile.push('*');
+ }
+ }
+ }
+
+ while (pile.isEmpty() == false) {
+
+ c = pile.pop();
+ result.append(c).append(",");
+ }
+ result.chop(1);
+ return result;
+}
+
+QString ArithmeticEvaluator::getNumber(const QString& _expression, int offset, int *size) {
+ int i = offset;
+ QString number="";
+ *size = 0;
+ if (_expression[i] == '-') {
+ number.append('-');
+ i += 1;
+ *size = 1;
+ }
+
+ while (_expression[i].isDigit()) {
+ number.append(_expression[i]);
+ i += 1;
+ *size += 1;
+ }
+
+ // test if it's a floatting point value
+ if (_expression[i] == '.') {
+ number.append(".");
+ i += 1;
+ *size += 1;
+ while (_expression[i].isDigit()) {
+ number.append(_expression[i]);
+ i += 1;
+ *size += 1;
+ }
+ }
+ return number;
+}
+
+QString ArithmeticEvaluator::getVariable(const QString& _expression, int offset, int *size) {
+ int i = offset;
+ QString number="";
+ *size = 0;
+ if (varMarkers.contains(_expression[i])) {
+ number.append(_expression[i]);
+ i += 1;
+ *size = 1;
+ }
+
+ while ((_expression[i].isLetterOrNumber()) || (_expression[i] == '-') || (_expression[i] == '_')) {
+ number.append(_expression[i]);
+ i += 1;
+ *size += 1;
+ }
+
+ return number;
+}
+
+int ArithmeticEvaluator::getFunction(const QString& _expression, int offset, int *size) {
+ int numFunc = -1;
+ int i = offset;
+ QString number="";
+ *size = 0;
+ if (_expression[i] != '\x1b') return -1;
+ i+= 1;
+ *size += 1;
+
+ while (_expression[i].isDigit()) {
+ number.append(_expression[i]);
+ i += 1;
+ *size += 1;
+ }
+ bool ok;
+ numFunc = number.toInt(&ok);
+ if ((!ok) || (numFunc >= fctMarkers.size())) return -1;
+ return numFunc;
+}
+
+bool ArithmeticEvaluator::checkAfterOp(const QString& _expression, int offset) {
+ int size;
+ if (offset+1 >= _expression.size()) return false;
+
+ if (_expression[offset+1] == '(') return true;
+ else if (_expression[offset+1].isDigit()) return true;
+ else if (_expression[offset+1] == '-') {
+ if ((offset+2 < _expression.size()) && (_expression[offset+2].isDigit())) return true;
+ }
+ else if (varMarkers.contains(_expression[offset+1])) {
+ if ((offset+2 < _expression.size()) && (_expression[offset+2].isLetterOrNumber())) return true;
+ }
+ else if (getFunction(_expression, offset+1,&size) != -1) {
+ return true;
+ }
+
+ return false;
+}
+
+bool ArithmeticEvaluator::checkAfterPar(const QString& _expression, int offset) {
+ if (offset >= _expression.size()) return false;
+ // if ) is the last char of the expression : OK
+ if (offset == _expression.size()-1) return true;
+
+ if (_expression[offset+1] == ')') return true;
+ else if (_expression[offset+1] == '+') return true;
+ else if (_expression[offset+1] == '-') return true;
+ else if (_expression[offset+1] == '*') return true;
+ else if (_expression[offset+1] == '/') return true;
+
+ return false;
+}
--- /dev/null
+/*-==============================================================-
+
+file : ArithmeticEvaluator.h
+
+creation date : 19/05/2015
+
+author : S. Domas (sdomas@univ-fcomte.fr)
+
+description :
+
+supp. infos : saved in UTF-8 [éè]
+
+-==============================================================-*/
+#ifndef __ARITHMETICEVALUATOR_H__
+#define __ARITHMETICEVALUATOR_H__
+
+#include <iostream>
+#include <fstream>
+
+#include <QtCore>
+
+
+using namespace std;
+using namespace Qt;
+
+class ArithmeticEvaluator {
+
+public:
+
+ ArithmeticEvaluator();
+ ArithmeticEvaluator(const QString& _expression) throw(int);
+
+ void setExpression(const QString& _expression) throw(int);
+ inline void setVariablesValue(const QHash<QString,double>& _varValues) { varValues = _varValues; }
+ inline void setVariableValue(const QString& var, double value) { varValues.insert(var,value); }
+ inline void setVariableMarkers(const QString& _markers) { varMarkers = _markers; }
+
+ void print();
+ double evaluate() throw(int);
+
+protected:
+ QStringList expression;
+ QHash<QString,double> varValues;
+ QString varMarkers; // a sequence of symbols that are allowed to start a variable. $ is by default
+ QString opMarkers; // a sequence if symbols used as operators. +-*/ is the hard-coded default
+ QStringList fctMarkers;
+
+ void convert(const QString& _expression) throw(int);
+ QString convertRecur(const QString& _expression, int* offset) throw(int);
+ QString getNumber(const QString& _expression, int offset, int *size);
+ QString getVariable(const QString& _expression, int offset, int *size);
+ int getFunction(const QString& _expression, int offset, int *size);
+ bool checkAfterOp(const QString& _expression, int offset);
+ bool checkAfterPar(const QString& _expression, int offset);
+
+ double evalFunction(int indexFunc, double value);
+
+};
+
+#endif //__ARITHMETICEVALUATOR_H__
--- /dev/null
+#include "BlockCategory.h"\r
+\r
+BlockCategory::BlockCategory(QString _name, int _id, BlockCategory* _parent) {\r
+ name = _name;\r
+ id = _id;\r
+ parent = _parent;\r
+}\r
+\r
+void BlockCategory::addChild(BlockCategory* child) {\r
+ childs.append(child);\r
+}\r
+\r
+\r
+\r
+BlockCategory* BlockCategory::getChild(QString name) {\r
+ QListIterator<BlockCategory *> iter(childs);\r
+ BlockCategory* item = NULL;\r
+ while(iter.hasNext()) {\r
+ item = iter.next();\r
+ if (item->name == name) return item;\r
+ }\r
+ return NULL;\r
+}\r
+\r
+BlockCategory* BlockCategory::getChild(int index) {\r
+ if ((index >=0) && (index < childs.size()) ) {\r
+ return childs.at(index);\r
+ }\r
+ return NULL;\r
+}\r
+\r
+QList<BlockCategory *> BlockCategory::getAllChilds()\r
+{\r
+ return childs;\r
+}\r
+\r
+ReferenceBlock *BlockCategory::getBlock(int index) {\r
+ if ((index >=0) && (index < blocks.size()) ) {\r
+ return blocks.at(index);\r
+ }\r
+ cout << "block null!" << endl;\r
+ return NULL;\r
+}\r
+\r
+QDomElement BlockCategory::save(QDomDocument &doc) {\r
+}\r
+\r
--- /dev/null
+#ifndef BLOCKCATEGORY_H\r
+#define BLOCKCATEGORY_H\r
+\r
+#include <iostream>\r
+\r
+#include <QtCore>\r
+#include <QtXml>\r
+#include "ReferenceBlock.h"\r
+class ReferenceBlock;\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+class Block;\r
+\r
+class BlockCategory {\r
+\r
+public :\r
+ BlockCategory(QString _name, int _id, BlockCategory* _parent = NULL);\r
+ int id;\r
+ // getters\r
+ inline int getId() { return id; }\r
+ inline QString getName() { return name; }\r
+ inline BlockCategory* getParent() { return parent; }\r
+ inline QList<BlockCategory *> getChilds() { return childs; }\r
+ BlockCategory* getChild(QString name);\r
+ BlockCategory* getChild(int index);\r
+ QList<BlockCategory *> getAllChilds();\r
+ inline QList<ReferenceBlock*> getBlocks() { return blocks; }\r
+ ReferenceBlock *getBlock(int index);\r
+\r
+ // setters\r
+ void addChild(BlockCategory* child);\r
+ inline void setParent(BlockCategory* _parent) { parent = _parent; }\r
+\r
+ // I/O\r
+ QDomElement save(QDomDocument &doc); \r
+\r
+ BlockCategory *getRoot();\r
+\r
+ //int id;\r
+ QList<BlockCategory *> childs;\r
+ BlockCategory* parent;\r
+ QList<ReferenceBlock*> blocks;\r
+private:\r
+ QString name;\r
+\r
+};\r
+\r
+#endif // BLOCKCATEGORY_H\r
--- /dev/null
+#include "BlockImplementation.h"\r
+\r
+#include "FunctionalBlock.h"\r
+#include "ReferenceBlock.h"\r
+#include "ReferenceInterface.h"\r
+#include "FunctionalInterface.h"\r
+#include "BlockParameter.h"\r
+\r
+\r
+BlockImplementation::BlockImplementation(const QString& _xmlFile) {\r
+ xmlFile = _xmlFile; \r
+\r
+ evaluator = new ArithmeticEvaluator;\r
+ evaluator->setVariableMarkers("@$");\r
+}\r
+\r
+BlockImplementation::BlockImplementation(const QString& _xmlFile, const QString &_referenceXml, const QString &_referenceMd5) {\r
+ xmlFile = _xmlFile; \r
+ referenceXml = _referenceXml;\r
+ referenceMd5 = _referenceMd5;\r
+}\r
+\r
+void BlockImplementation::generateVHDL(FunctionalBlock* _block, const QString &path) throw(Exception) {\r
+\r
+ block = _block;\r
+\r
+ QFile implFile(xmlFile);\r
+\r
+ // reading in into QDomDocument\r
+ QDomDocument document("implFile");\r
+\r
+ if (!implFile.open(QIODevice::ReadOnly)) {\r
+ throw(Exception(IMPLFILE_NOACCESS));\r
+ }\r
+ if (!document.setContent(&implFile)) {\r
+ implFile.close();\r
+ throw(Exception(IMPLFILE_NOACCESS));\r
+ }\r
+ implFile.close();\r
+\r
+ bool genController = false;\r
+ QString coreFile = "";\r
+ QString controllerFile = "";\r
+\r
+ if (reference->isWBConfigurable()) {\r
+ genController = true;\r
+ controllerFile = path;\r
+ controllerFile.append(block->getName());\r
+ controllerFile.append("_ctrl.vhd"); \r
+ }\r
+ else {\r
+ controllerFile = "nofile.vhd"; \r
+ }\r
+ coreFile = path;\r
+ coreFile.append(block->getName());\r
+ coreFile.append(".vhd");\r
+\r
+ QFile vhdlCore(coreFile);\r
+ QFile vhdlController(controllerFile);\r
+\r
+ if (!vhdlCore.open(QIODevice::WriteOnly)) {\r
+ throw(Exception(VHDLFILE_NOACCESS));\r
+ }\r
+\r
+ if (genController) {\r
+ if (!vhdlController.open(QIODevice::WriteOnly)) {\r
+ throw(Exception(VHDLFILE_NOACCESS));\r
+ }\r
+ }\r
+ QTextStream outCore(&vhdlCore);\r
+ QTextStream outController;\r
+ if (genController) {\r
+ outController.setDevice(&vhdlController);\r
+ }\r
+\r
+ try {\r
+\r
+\r
+ //Get the root element\r
+ QDomElement impl = document.documentElement();\r
+ QDomElement eltComments = impl.firstChildElement("comments");\r
+ generateComments(eltComments, coreFile, outCore);\r
+ QDomElement eltLibs = eltComments.nextSiblingElement("libraries");\r
+ generateLibraries(eltLibs, outCore);\r
+ generateEntity(outCore, genController);\r
+ QDomElement eltArch = eltLibs.nextSiblingElement("architecture");\r
+ generateArchitecture(eltArch, outCore);\r
+ if (genController) {\r
+ generateController(outController);\r
+ }\r
+ }\r
+ catch(Exception err) {\r
+ throw(err);\r
+ }\r
+\r
+ vhdlCore.close();\r
+ vhdlController.close();\r
+}\r
+\r
+// This function generates the comments part of the VHDL document\r
+void BlockImplementation::generateComments(QDomElement &elt, QString coreFile, QTextStream& out) throw(Exception) {\r
+\r
+ for(int i = 0; i < 50; i++) {\r
+ out << "--";\r
+ }\r
+ out << "\n--\n";\r
+ QString fileName = coreFile;\r
+ out << "-- File : " << fileName << "\n";\r
+ out << "--\n";\r
+ QDomElement eltAuthor = elt.firstChildElement("author");\r
+ QString firstName = eltAuthor.attribute("firstname","");\r
+ QString lastName = eltAuthor.attribute("lastname","");\r
+ QString mail = eltAuthor.attribute("mail","");\r
+ out << "-- Author(s) : "<<firstName+" "<<lastName<<" ("<<mail<<")\n";\r
+ out << "--\n";\r
+ QDomElement eltDate = eltAuthor.nextSiblingElement("date");\r
+ QString crea = eltDate.attribute("creation","");\r
+ out << "-- Creation Date : "<<crea<<"\n";\r
+ out << "--\n";\r
+ QDomElement eltRelated = eltDate.nextSiblingElement("related_files");\r
+ QString relateds = eltRelated.attribute("list","");\r
+ out << "-- Related files :\n"<<relateds<<"\n";\r
+ out << "--\n";\r
+ QDomElement eltDesc = eltRelated.nextSiblingElement("description");\r
+ QDomElement desc = eltDesc.firstChildElement();\r
+ QString descTxt = desc.text();\r
+ out << "-- Decription :\n"<<descTxt<<"\n";\r
+ out << "--\n";\r
+ QDomElement eltNote = eltDesc.nextSiblingElement("description");\r
+ QDomElement note = eltNote.firstChildElement();\r
+ QString noteTxt = note.text();\r
+ out << "-- Note :\n"<<noteTxt<<"\n";\r
+ out << "--\n";\r
+ for(int i = 0; i < 50; i++) {\r
+ out << "--";\r
+ }\r
+ out << "\n\n";\r
+}\r
+\r
+// This function generates the library part of the VHDL document\r
+void BlockImplementation::generateLibraries(QDomElement &elt, QTextStream& out) throw(Exception) {\r
+\r
+ QDomNodeList listLib = elt.elementsByTagName("library");\r
+ for(int i = 0; i < listLib.length(); i++) {\r
+ QDomNode nodeLib = listLib.item(i);\r
+ QDomElement eltLib = nodeLib.toElement();\r
+ QString nameLib = eltLib.attribute("name", "");\r
+ out << "library " << nameLib << ";\n";\r
+ QDomNodeList listPack = eltLib.elementsByTagName("package");\r
+ for(int j = 0; j < listPack.length(); j++) {\r
+ QDomNode nodePack = listPack.item(j);\r
+ QDomElement eltPack = nodePack.toElement();\r
+ QString namePack = eltPack.attribute("name", "");\r
+ QString usePack = elt.attribute("use","");\r
+ out << "use " << nameLib << "." << namePack << "." << usePack << ";\n";\r
+ }\r
+ out << "\n";\r
+ }\r
+}\r
+\r
+// This function generates the entity part of the VHDL document\r
+void BlockImplementation::generateEntity(QTextStream& out, bool hasController) throw(Exception) {\r
+\r
+ int i=0;\r
+ nameEnt = reference->getName();\r
+ //QList<BlockParameter*> listParams = reference->getParameters();\r
+ QList<AbstractInterface*> listInputs = reference->getInputs();\r
+ QList<AbstractInterface*> listOutputs = reference->getOutputs();\r
+ QList<AbstractInterface*> listBidirs = reference->getBidirs();\r
+ QString typePort, namePort;\r
+\r
+ out << "entity " << nameEnt << " is\n";\r
+\r
+\r
+ /* TODO : rewrite the generation to take into acocunt the new object hierarchy */\r
+\r
+ // Generation of the generics\r
+ QList<BlockParameter*> listGenerics = reference->getGenericParameters();\r
+ if ((!listGenerics.isEmpty()) || (hasController)) {\r
+ out << " generic (" << endl;\r
+ if (hasController) {\r
+ out << " wb_data_width : integer = 16;" << endl;\r
+ out << " wb_addr_width : integer = 12";\r
+ if (!listGenerics.isEmpty()) out << ";";\r
+ out << endl;\r
+ }\r
+ for(i=0;i<listGenerics.size()-1;i++) {\r
+ out << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity, 0);\r
+ }\r
+ out << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma);\r
+\r
+ out << " );" << endl;\r
+ }\r
+\r
+ out << " port (" << endl;\r
+\r
+ // Generation of the clk & rst signals\r
+ out << " -- clk/rst" << endl;\r
+ for(int i = 0; i < listInputs.size(); i++) {\r
+ if(listInputs.at(i)->getPurpose() == AbstractInterface::Clock || listInputs.at(i)->getPurpose() == AbstractInterface::Reset) {\r
+ out << " " << listInputs.at(i)->getName() << " : in std_logic;" << endl;\r
+ }\r
+ }\r
+\r
+ if (hasController) {\r
+ // Generation of the wishbone signals\r
+ out << " -- registers r/w via wishbone" << endl;\r
+ QList<BlockParameter*> listWB = reference->getWishboneParameters();\r
+ for(i=0;i<listWB.size()-1;i++) {\r
+ out << " " << listWB.at(i)->toVHDL(BlockParameter::Entity, 0);\r
+ }\r
+ out << " " << listWB.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma);\r
+ }\r
+\r
+\r
+ // Generation of the data signals\r
+ out << "-- data ports\n";\r
+ for(int i = 0; i < listInputs.size(); i++) {\r
+ namePort = getIfaceUserName(reference->AbstractBlock::getIfaceFromName(listInputs.at(i)->getName()));\r
+ if(listInputs.at(i)->getWidth().compare("1"))\r
+ typePort = "std_logic";\r
+ else\r
+ typePort = calculateWidth(listInputs.at(i)->getWidth());\r
+ if(listInputs.at(i)->getPurpose() == 1)\r
+ out << namePort << " : in std_logic_vector(" << typePort << " -1 downto 0) ;\n";\r
+ }\r
+\r
+ for(int i = 0; i < listOutputs.size(); i++) {\r
+ namePort = getIfaceUserName(reference->AbstractBlock::getIfaceFromName(listOutputs.at(i)->getName()));\r
+ if(listOutputs.at(i)->getWidth().compare("1"))\r
+ typePort = "std_logic";\r
+ else\r
+ typePort = calculateWidth(listOutputs.at(i)->getWidth());\r
+ if(listOutputs.at(i)->getPurpose() == 1)\r
+ out << namePort << " : out std_logic_vector(" << typePort << " -1 downto 0) ;\n";\r
+ }\r
+\r
+ for(int i = 0; i < listBidirs.size(); i++) {\r
+ namePort = getIfaceUserName(reference->AbstractBlock::getIfaceFromName(listBidirs.at(i)->getName()));\r
+ if(listBidirs.at(i)->getWidth().compare(("1")))\r
+ typePort = "std_logic";\r
+ else\r
+ typePort = calculateWidth((listBidirs.at(i)->getWidth()));\r
+ if(listBidirs.at(i)->getPurpose() == 1)\r
+ out << namePort << " : inout std_logic_vector(" << typePort << " -1 downto 0) ;\n";\r
+ }\r
+}\r
+\r
+// This function generates the architecture part of the VHDL document\r
+void BlockImplementation::generateArchitecture(QDomElement &elt, QTextStream& out) throw(Exception) {\r
+\r
+ QString expr;\r
+ QDomElement eltArch = elt.nextSiblingElement("architecture");\r
+ out << "architecture " << nameEnt <<"_1 of " << nameEnt << "is\n";\r
+ QString implText = eltArch.text();\r
+ QStringList listLine = implText.split("\n");\r
+ for(int i =0; i < listLine.size(); i++) {\r
+ if(listLine.at(i).contains(QRegularExpression("@foreach{")) != -1) {\r
+ while(listLine.at(i).compare("@endforeach") != -1) {\r
+ expr = expr + listLine.at(i) + '\n';\r
+ i++;\r
+ }\r
+ expr = expr + listLine.at(i);\r
+ out << evalComplex(expr, 1) << '\n';\r
+ }\r
+ if(listLine.at(i).contains(QRegularExpression("@caseeach{")) != -1) {\r
+ while(listLine.at(i).compare("@endcaseeach") != -1) {\r
+ expr = expr + listLine.at(i) + '\n';\r
+ i++;\r
+ }\r
+ expr = expr + listLine.at(i);\r
+ out << evalComplex(expr, 2) << '\n';\r
+ }\r
+\r
+ if(listLine.at(i).contains('@') == -1)\r
+ out << listLine.at(i) << "\n";\r
+ else\r
+ out << eval(listLine.at(i), out) << "\n";\r
+ }\r
+}\r
+\r
+void BlockImplementation::generateController(QTextStream &out) throw(Exception) {\r
+}\r
+\r
+QString BlockImplementation::eval(QString line, QTextStream& out) {\r
+ QString res, s, begLine, endLine, expr;\r
+ evaluator->setExpression(line);\r
+ QRegExp *rxString = new QRegExp("(.*)@{(.*)}(.*)");\r
+ QRegExp *rxValue = new QRegExp("(.*)@val{(.*)}(.*)");\r
+ QRegExp *rxExpr = new QRegExp(".*@eval{(.*)}.*");\r
+\r
+ int nbAt = line.count('@');\r
+ while(nbAt != 0) {\r
+ for(int i = 0; i < line.size(); i++) {\r
+ if(rxString->indexIn(line)) {\r
+ begLine = rxString->cap(1);\r
+ s = rxString->cap(2);\r
+ endLine = rxString->cap(3);\r
+ res = begLine + evalString(s) + endLine + '\n';\r
+ nbAt --;\r
+ }\r
+ }\r
+ for(int i = 0; i < line.size(); i++) {\r
+ if(rxValue->indexIn(line)) {\r
+ begLine = rxValue->cap(1);\r
+ s = rxValue->cap(2);\r
+ endLine = rxValue->cap(3);\r
+ res = begLine + evalValue(s) + endLine + '\n';\r
+ nbAt --;\r
+ }\r
+ }\r
+ for(int i = 0; i < line.size(); i++) {\r
+ if(rxExpr->indexIn(line)) {\r
+ expr = rxExpr->cap(1);\r
+ if(expr.count('@') == 0) {\r
+ evaluator->setExpression(expr);\r
+ s = QString::number(evaluator->evaluate());\r
+ }\r
+ res = begLine + s + endLine + '\n';\r
+ nbAt --;\r
+ }\r
+ }\r
+ }\r
+ return res;\r
+}\r
+\r
+QString BlockImplementation::evalComplex(QString line, int id) {\r
+ QString res, s, begLine, endLine, expr;\r
+ QRegExp *rxString = new QRegExp("(.*)@{(.*)}(.*)");\r
+ QRegExp *rxValue = new QRegExp("(.*)@val{(.*)}(.*)");\r
+ QRegExp *rxExpr = new QRegExp(".*@eval{(.*)}.*");\r
+ QRegExp *rxFor = new QRegExp("@foreach{.*}(@{.*})(.*)@endforeach");\r
+ QRegExp *rxCase = new QRegExp("@caseeach{.*,(.*),(.*)}(@{.*})(.*)@endcaseeach");\r
+ QRegExp *rxCaseDown = new QRegExp("@#-:(.*)");\r
+ QRegExp *rxCaseUp = new QRegExp("@#:(.*)");\r
+ evaluator->setExpression(line);\r
+\r
+ int nbAt = line.count('@') - 2;\r
+ while(nbAt != 0) {\r
+ for(int i = 0; i < line.size(); i++) {\r
+ if(rxString->indexIn(line)) {\r
+ begLine = rxString->cap(1);\r
+ s = rxString->cap(2);\r
+ endLine = rxString->cap(3);\r
+ if(evalStringComplex(s)->size() == 0)\r
+ line = begLine + evalString(s) + endLine;\r
+ nbAt --;\r
+ }\r
+ }\r
+ for(int i = 0; i < line.size(); i++) {\r
+ if(rxValue->indexIn(line)) {\r
+ begLine = rxValue->cap(1);\r
+ s = rxValue->cap(2);\r
+ endLine = rxValue->cap(3);\r
+ line = begLine + evalValue(s) + endLine;\r
+ nbAt --;\r
+ }\r
+ }\r
+ for(int i = 0; i < line.size(); i++) {\r
+ if(rxExpr->indexIn(line)) {\r
+ expr = rxExpr->cap(1);\r
+ if(expr.count('@') == 0) {\r
+ evaluator->setExpression(expr);\r
+ s = QString::number(evaluator->evaluate());\r
+ }\r
+ res = begLine + s + endLine + '\n';\r
+ nbAt --;\r
+ }\r
+ }\r
+ }\r
+\r
+ if(id == 1) {\r
+ if(rxFor->indexIn(line)) {\r
+ QString intName, instruc;\r
+ intName = rxFor->cap(1);\r
+ instruc = rxFor->cap(2);\r
+ QList<AbstractInterface*> *intList = evalStringComplex(intName);\r
+ if(intList->size() != 0) {\r
+ for(int i = 0; i < intList->size(); i++) {\r
+ res = intList->at(i)->getName() + instruc + '\n';\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ else if(id == 2) {\r
+ if(rxCase->indexIn(line)) {\r
+ QString intName, sigName, cases, instruc;\r
+ int number;\r
+ sigName = rxCase->cap(1);\r
+ cases = rxCase->cap(2);\r
+ intName = rxCase->cap(3);\r
+ instruc = rxCase->cap(4);\r
+ QList<AbstractInterface*> *intList = evalStringComplex(intName);\r
+ int listSize = intList->count();\r
+ res = "case " + sigName + " is\n";\r
+ if(rxCaseUp->indexIn(cases)) {\r
+ number = rxCaseUp->cap(1).toInt();\r
+ for(int j = number; j < listSize; j++) {\r
+ if(listSize > 0) {\r
+ for(int i = 0; i < listSize; i++) {\r
+ res += "\twhen " + QString::number(number) + " " + intList->at(i)->getName() + instruc + "\n";\r
+ }\r
+ }\r
+ else\r
+ res += "\twhen " + number + ' ' + intName + instruc + "\n";\r
+ number++;\r
+ }\r
+ }\r
+ if(rxCaseDown->indexIn(cases)) {\r
+ number = rxCaseDown->cap(1).toInt();\r
+ for(int j = number; j < listSize; j++) {\r
+ if(listSize > 0) {\r
+ for(int i = 0; i < listSize; i++) {\r
+ res += "\twhen " + QString::number(number) + " " + intList->at(i)->getName() + instruc + "\n";\r
+ }\r
+ }\r
+ else\r
+ res += "\twhen " + number + ' ' + intName + instruc + "\n";\r
+ number--;\r
+ }\r
+ res += "end case ;\n";\r
+ }\r
+ }\r
+ }\r
+ return res;\r
+}\r
+\r
+QString BlockImplementation::evalString(QString s) {\r
+\r
+ QString name = getIfaceUserName(block->AbstractBlock::getIfaceFromName(s));\r
+ return name;\r
+}\r
+\r
+QList<AbstractInterface*>* BlockImplementation::evalStringComplex(QString s) {\r
+\r
+ int j = 0;\r
+ QList<AbstractInterface*> *listInterfaces = new QList<AbstractInterface*>();\r
+ AbstractInterface *inter = block->AbstractBlock::getIfaceFromName(s);\r
+ QList<AbstractInterface*> listIntBlock = block->getInterfaces();\r
+ for(int i = 0; i < listIntBlock.size(); i++) {\r
+ if(inter->getName().compare(listIntBlock.at(i)->getName()) < -1) {\r
+ listInterfaces->insert(j, inter);\r
+ j ++;\r
+ }\r
+ }\r
+ return listInterfaces;\r
+}\r
+\r
+QString BlockImplementation::evalValue(QString s) {\r
+\r
+ QString val = "";\r
+ if(paramMap.contains(s))\r
+ val = paramMap.value(s);\r
+ return val;\r
+}\r
+\r
+QString BlockImplementation::getIfaceUserName(AbstractInterface* refIface) {\r
+\r
+ if (! refIface->isReferenceInterface()) return "";\r
+\r
+ AbstractInterface* funcIface = NULL;\r
+\r
+ if (refIface->getDirection() == AbstractInterface::Input) {\r
+ foreach(AbstractInterface* iface, block->getInputs()) {\r
+ FunctionalInterface* fi = (FunctionalInterface*)iface;\r
+ if (fi->getReference() == refIface) {\r
+ funcIface = iface;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ else if (refIface->getDirection() == AbstractInterface::Output) {\r
+ foreach(AbstractInterface* iface, block->getOutputs()) {\r
+ FunctionalInterface* fi = (FunctionalInterface*)iface;\r
+ if (fi->getReference() == refIface) {\r
+ funcIface = iface;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ else if (refIface->getDirection() == AbstractInterface::InOut) {\r
+ foreach(AbstractInterface* iface, block->getBidirs()) {\r
+ FunctionalInterface* fi = (FunctionalInterface*)iface;\r
+ if (fi->getReference() == refIface) {\r
+ funcIface = iface;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if (funcIface == NULL) return "";\r
+\r
+ return funcIface->getName();\r
+}\r
+\r
+QDataStream& operator<<(QDataStream &out, const BlockImplementation &impl) {\r
+\r
+ out.setVersion(QDataStream::Qt_5_0);\r
+\r
+ QByteArray blockData;\r
+ QDataStream toWrite(&blockData, QIODevice::WriteOnly);\r
+\r
+ toWrite << impl.xmlFile;\r
+ toWrite << impl.referenceXml;\r
+ toWrite << impl.referenceMd5;\r
+\r
+ out << blockData;\r
+\r
+ return out;\r
+}\r
+\r
+QDataStream& operator>>(QDataStream &in, BlockImplementation &impl) {\r
+\r
+ quint32 blockSize;\r
+\r
+ in.setVersion(QDataStream::Qt_5_0);\r
+\r
+ in >> blockSize;\r
+\r
+ in >> impl.xmlFile;\r
+ in >> impl.referenceXml;\r
+ in >> impl.referenceMd5;\r
+\r
+ return in;\r
+}\r
+\r
+QString BlockImplementation::calculateWidth(QString s){\r
+ QRegExp *rxWidth = new QRegExp("$*([a-zA-Z0-9_-]*)");\r
+ QStringList matchList = s.split(" ");\r
+ int pos = 0;\r
+ QString res, line;\r
+ QList<BlockParameter*> listParams = reference->getParameters();\r
+\r
+ while ((pos = rxWidth->indexIn(s, pos)) != -1) {\r
+ matchList << rxWidth->cap(1);\r
+ pos += rxWidth->matchedLength();\r
+ }\r
+\r
+ for (int i = 0; i < matchList.size(); i++) {\r
+ QString match = matchList.at(i);\r
+ if(rxWidth->indexIn(match)) {\r
+ for(int j = 0; j < listParams.size(); j++) {\r
+ if(match.compare(listParams.at(j)->getName())) {\r
+ BlockParameter *param = listParams.at(i);\r
+ if(param->getContext() == "generic") {\r
+ match = match.remove('$');\r
+ }\r
+ else {\r
+ match = param->getValue().toString();\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ line = matchList.join(' ');\r
+ evaluator->setExpression(line);\r
+ res = evaluator->evaluate();\r
+ return res;\r
+}\r
+\r
--- /dev/null
+#ifndef __BLOCKIMPLEMENTATION_H__\r
+#define __BLOCKIMPLEMENTATION_H__\r
+\r
+#include <iostream>\r
+#include <fstream>\r
+\r
+#include <QtCore>\r
+#include <QtXml>\r
+\r
+class ReferenceBlock;\r
+class FunctionalBlock;\r
+class AbstractInterface;\r
+\r
+#include "ArithmeticEvaluator.h"\r
+class ArithmeticEvaluator;\r
+\r
+#include "Exception.h"\r
+class Exception;\r
+\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+class BlockImplementation {\r
+\r
+public:\r
+\r
+ BlockImplementation(const QString& _xmlFile);\r
+ BlockImplementation(const QString& _xmlFile, const QString& _referenceXml, const QString& _referenceMd5);\r
+\r
+ inline QString getXmlFile() { return xmlFile; }\r
+ inline QString getReferenceXml() { return referenceXml; }\r
+ inline QString getReferenceMd5() { return referenceMd5; }\r
+ QString eval(QString line, QTextStream& out);\r
+ QString evalComplex(QString line, int num);\r
+ QString evalString(QString s);\r
+ QList<AbstractInterface*>* evalStringComplex(QString s);\r
+ QString evalValue(QString s);\r
+ QString calculateWidth(QString s);\r
+\r
+ inline void setReference(ReferenceBlock* _reference) { reference = _reference; }\r
+\r
+ void generateVHDL(FunctionalBlock* _block, const QString& path) throw(Exception); // main entry to generate the VHDL code\r
+\r
+private: \r
+ QString xmlFile;\r
+ QString referenceXml;\r
+ QString referenceMd5;\r
+ QString nameEnt, line;\r
+ QMap<QString, int> paramMap;\r
+ ArithmeticEvaluator* evaluator;\r
+ ReferenceBlock* reference;\r
+ FunctionalBlock* block; // the current functional block for which this implementation is used.\r
+\r
+ void generateComments(QDomElement &elt,QString coreFile, QTextStream& out) throw(Exception); // generates comments from <comments> element\r
+ void generateLibraries(QDomElement &elt, QTextStream& out) throw(Exception); // generates libraries from <libraries> element\r
+ void generateEntity(QTextStream& out, bool hasController=false) throw(Exception); // generate the entity using reference\r
+ void generateArchitecture(QDomElement &elt, QTextStream& out) throw(Exception); // generate the architecture using <architecture> element\r
+ void generateController(QTextStream& out) throw(Exception); // generate the wishbone controller of the block\r
+\r
+ QString getIfaceUserName(AbstractInterface* refIface); // get the name of an interface given by the user, from the reference interface\r
+\r
+ friend QDataStream &operator<<(QDataStream &out, const BlockImplementation &impl);\r
+ friend QDataStream &operator>>(QDataStream &in, BlockImplementation &impl);\r
+};\r
+\r
+#endif // __BLOCKIMPLEMENTATION_H__\r
+\r
--- /dev/null
+#include "BlockLibraryTree.h"
+
+BlockLibraryTree::BlockLibraryTree() {
+ tabCategories = NULL;
+ tabIdParent = NULL;
+ nbCategories = 0;
+}
+
+BlockLibraryTree::~BlockLibraryTree() {
+ clear();
+}
+
+void BlockLibraryTree::clear() {
+
+ for(int i=0;i<nbCategories;i++) {
+ delete tabCategories[i];
+ }
+ delete [] tabCategories;
+ nbCategories = 0;
+}
+
+void BlockLibraryTree::clearBlocks() {
+
+ for(int i=0;i<nbCategories;i++) {
+ tabCategories[i]->blocks.clear();
+ }
+}
+
+void BlockLibraryTree::addItem(QXmlAttributes &attributes)
+{
+ nbCategories++;
+ if(tabCategories == NULL){
+ tabCategories = new BlockCategory* [1];
+ tabIdParent = new int[1];
+ }
+ else{
+ BlockCategory** tmpTabCat = new BlockCategory* [nbCategories];
+ int* tmpTabParent = new int[nbCategories];
+ for(int i=0; i< nbCategories; i++){
+ tmpTabCat[i] = tabCategories[i];
+ tmpTabParent[i] = tabIdParent[i];
+ }
+ tabCategories = tmpTabCat;
+ tabIdParent = tmpTabParent;
+ }
+
+ QString name = attributes.value(0);
+ int id = attributes.value(1).toInt();
+ int idParent = attributes.value(2).toInt();
+ BlockCategory* cat = new BlockCategory(name,id);
+ tabCategories[id] = cat;
+ tabIdParent[id] = idParent;
+}
+
+bool BlockLibraryTree::initChildParent()
+{
+ // initializing parent/childs
+ for(int i=0;i<nbCategories;i++) {
+ if (tabIdParent[i] != -1) {
+ if (tabIdParent[i] >= nbCategories) return false;
+ tabCategories[i]->setParent(tabCategories[tabIdParent[i]]);
+ tabCategories[tabIdParent[i]]->addChild(tabCategories[i]);
+ }
+ }
+ return true;
+}
+
+
+QDomElement BlockLibraryTree::save(QDomDocument &doc) {
+
+}
+
+/* NOTE : load() is the only way to initialize the tree.
+ It is done at the begining of the application, while reading
+ the configuration file.
+ elt MUST be the DOM element that corresponds to the tag <categories>
+ */
+void BlockLibraryTree::load(QDomElement &elt) throw(Exception) {
+
+ if (elt.tagName() != "categories") throw(Exception(CONFIGFILE_CORRUPTED));
+
+ QString nbStr = elt.attribute("nb","none");
+ bool ok;
+ int nb = nbStr.toInt(&ok);
+ QDomNodeList list = elt.elementsByTagName("category");
+ nbCategories = list.size();
+ if (nb != nbCategories) throw(Exception(CONFIGFILE_CORRUPTED));
+ QString name;
+ int id;
+ QString idStr;
+ int idParent;
+ QString idParentStr;
+
+ tabCategories = new BlockCategory* [nbCategories];
+ tabIdParent = new int[nbCategories];
+ BlockCategory* cat = NULL;
+
+ // creating all BlockCategory objects
+ for(int i=0;i<nbCategories;i++) {
+ QDomNode node = list.item(i);
+ QDomElement e = node.toElement();
+ name = e.attribute("name","none");
+ idStr = e.attribute("id","none");
+ idParentStr = e.attribute("parent","none");
+ id = idStr.toInt(&ok);
+ if ((!ok) || (id < 0) || (id >= nbCategories)) throw(Exception(CONFIGFILE_CORRUPTED));
+ idParent = idParentStr.toInt(&ok);
+ if ((!ok)|| (idParent < -1) || (idParent >= nbCategories)) throw(Exception(CONFIGFILE_CORRUPTED));
+ cat = new BlockCategory(name,id);
+ tabCategories[id] = cat;
+ tabIdParent[id] = idParent;
+ }
+
+ ok = initChildParent();
+ delete [] tabIdParent;
+ if (!ok) throw(Exception(CONFIGFILE_CORRUPTED));
+}
+
+BlockCategory* BlockLibraryTree::searchCategory(int id) {
+
+ if (tabCategories != NULL) {
+ if ((id>=0) && (id < nbCategories)) {
+ return tabCategories[id];
+ }
+ }
+
+ return NULL;
+}
+
+BlockCategory *BlockLibraryTree::getRoot() {
+ if (tabCategories != NULL) {
+ if (nbCategories > 0) {
+ return tabCategories[0];
+ }
+ }
+ return NULL;
+}
--- /dev/null
+#ifndef __BLOCKLIBRARYTREE_H__
+#define __BLOCKLIBRARYTREE_H__
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include <iostream>
+#include <fstream>
+
+#include <QtCore>
+
+#include "BlockCategory.h"
+#include "Exception.h"
+
+using namespace std;
+using namespace Qt;
+class BlockCategory;
+class BlockLibraryTree {
+
+public :
+ BlockLibraryTree();
+ ~BlockLibraryTree();
+
+ void clear(); // free thewhole tree
+ void clearBlocks(); // just remove the blocks from the BlockCateogry lists
+ void addItem(QXmlAttributes &attributes);
+ bool initChildParent();
+
+ BlockCategory *getRoot();
+ BlockCategory *searchCategory(int id);
+
+ QDomElement save(QDomDocument &doc);
+ void load(QDomElement &elt) throw(Exception);
+private:
+ /* NOTE :
+ This class builds a tree of BlockCategory, but it also stores all BlockCategory object
+ in an array so that access via an id is direct.
+
+ The root of the tree is in fact tabCategories[0]
+ */
+ BlockCategory** tabCategories;
+ int* tabIdParent;
+ int nbCategories;
+
+};
+
+
+#endif // BLOCKLIBRARYTREE_H
--- /dev/null
+#include "BlockLibraryWidget.h"
+#include "BlockLibraryTree.h"
+
+BlockLibraryWidget::BlockLibraryWidget(Dispatcher* _dispatcher,
+ Parameters* _params,
+ QWidget *parent) : QWidget(parent) {
+
+
+ dispatcher = _dispatcher;
+ params = _params;
+
+ // creating the widget : tree, buttons, ...
+ layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
+ tree = new QTreeWidget(this);
+ buttonAdd = new QPushButton("add", this);
+ buttonAdd->setEnabled(false);
+
+ connect(tree, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(clicked()));
+ connect(tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(doubleClicked()));
+ connect(buttonAdd, SIGNAL(clicked()), this, SLOT(addClicked()));
+
+ BlockCategory* cat = params->categoryTree->searchCategory(0);
+
+ QTreeWidgetItem* item = tree->invisibleRootItem();
+ tree->setHeaderLabel("Blocks list");
+
+
+ addChild(cat,item);
+
+ layout->addWidget(tree);
+ layout->addWidget(buttonAdd);
+ this->setLayout(layout);
+
+ this->setFixedSize(300,230);
+}
+
+
+BlockLibraryWidget::~BlockLibraryWidget() {
+}
+
+void BlockLibraryWidget::addChild(BlockCategory *catParent,QTreeWidgetItem* itemParent) {
+
+ QTreeWidgetItem* newItemCat = NULL;
+ QTreeWidgetItem* newItemBlock = NULL;
+
+ QList<BlockCategory *> childs = catParent->getAllChilds();
+ foreach(BlockCategory* cat, childs){
+ newItemCat = new QTreeWidgetItem(itemParent);
+ newItemCat->setData(0,Qt::DisplayRole, cat->getName());
+ QList<ReferenceBlock*> list = cat->getBlocks();
+ for(int i=0; i<list.length(); i++){
+ newItemBlock = new QTreeWidgetItem(newItemCat);
+ newItemBlock->setData(0,Qt::DisplayRole, list.at(i)->getName());
+ newItemBlock->setData(1,Qt::DisplayRole, cat->getId());
+ newItemBlock->setData(2,Qt::DisplayRole, i);
+ newItemBlock->setIcon(0,QIcon("icons/window_new.png"));
+ }
+ addChild(cat,newItemCat);
+ }
+ /* TO DO :
+ - getting the childs of catParent
+ - for each BlockCategory cat of that list :
+ - create an new TreeWidgetItem (newImteCat), with itemParent as a parent
+ - set the first column of that item with the categry name
+ - get the list of the blocks that are associated with cat
+ - for i = 0 to that list size.
+ - create a new TreeWidgetItem (newItemBlock), with newItemCat as a parent
+ - set the first column of that item with the block name
+ - set the second column of that item with the newItemCat id
+ - set the third column of that item with the value of i
+ - endfor
+ - call again addChild with cat and newImteCat as parameters
+ - end for
+ */
+}
+
+
+void BlockLibraryWidget::addClicked() {
+
+ QTreeWidgetItem *item = tree->selectedItems().at(0);
+ if(item->data(1,Qt::DisplayRole).isValid() && item->data(2,Qt::DisplayRole).isValid()){
+ int idParent = item->data(1,Qt::DisplayRole).toInt();
+ int idBlock = item->data(2,Qt::DisplayRole).toInt();
+ dispatcher->addBlock(idParent, idBlock);
+ }
+
+ // only take the first selected
+ // retrieve id of category and id of block
+ // calling dispatcher addBlock() method.
+}
+
+
+void BlockLibraryWidget::clicked()
+{
+ if(tree->selectedItems().length() > 0){
+ QTreeWidgetItem *item = tree->selectedItems().at(0);
+ if(item->data(1,Qt::DisplayRole).isValid())
+ buttonAdd->setEnabled(true);
+ else
+ buttonAdd->setEnabled(false);
+ }
+}
+
+void BlockLibraryWidget::doubleClicked()
+{
+ addClicked();
+}
--- /dev/null
+#ifndef __BLOCKLIBRARYWIDGET_H__
+#define __BLOCKLIBRARYWIDGET_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+
+#include "Dispatcher.h"
+class Dispatcher;
+#include "Parameters.h"
+class Parameters;
+#include "BlockCategory.h"
+class BlockCategory;
+
+using namespace std;
+using namespace Qt;
+
+class BlockLibraryWidget : public QWidget {
+ Q_OBJECT
+
+public:
+ explicit BlockLibraryWidget(Dispatcher* _dispatcher, Parameters* _params, QWidget *parent = 0);
+ ~BlockLibraryWidget();
+
+private slots:
+ void addClicked();
+ void clicked();
+ void doubleClicked();
+
+
+private:
+ Parameters* params;
+ Dispatcher* dispatcher;
+ QTreeWidget* tree;
+ QPushButton* buttonAdd;
+ QBoxLayout *layout;
+ // other attributes
+
+ void addChild(BlockCategory *catParent, QTreeWidgetItem* itemParent);
+ void addButtons();
+
+};
+
+#endif // __BLOCKLIBRARYWIDGET_H__
--- /dev/null
+#include "BlockParameter.h"\r
+\r
+BlockParameter::BlockParameter() {\r
+ owner = NULL;\r
+ name = ""; \r
+ type = BlockParameter::String;\r
+ defaultValue = QVariant();\r
+}\r
+\r
+BlockParameter::BlockParameter(AbstractBlock* _owner, const QString &_name, const QString &_type, const QString &_value) {\r
+ owner = _owner;\r
+ name =_name; \r
+ type = typeFromString(_type);\r
+ defaultValue = QVariant(_value);\r
+}\r
+\r
+BlockParameter::~BlockParameter(){\r
+\r
+}\r
+\r
+QVariant BlockParameter::getValue() {\r
+ return defaultValue;\r
+}\r
+\r
+bool BlockParameter::isUserParameter() {\r
+ return false;\r
+\r
+}\r
+\r
+bool BlockParameter::isGenericParameter() {\r
+ return false;\r
+}\r
+\r
+bool BlockParameter::isWishboneParameter() {\r
+ return false;\r
+}\r
+\r
+bool BlockParameter::isPortParameter() {\r
+ return false;\r
+}\r
+\r
+void BlockParameter::setValue(const QString& _value) {\r
+ defaultValue = QVariant(_value);\r
+}\r
+\r
+bool BlockParameter::isValueSet() {\r
+ if (defaultValue.isNull()) return false;\r
+ return true;\r
+}\r
+ \r
+QString BlockParameter::toVHDL(int context, int flags) {\r
+\r
+ QString ret=""; \r
+ return ret;\r
+}\r
+\r
+QString BlockParameter::getTypeString() {\r
+ if (type == BlockParameter::Bit) {\r
+ return "bit";\r
+ }\r
+ else if (type == BlockParameter::BitVector) {\r
+ return "bit_vector";\r
+ }\r
+ else if (type == BlockParameter::Boolean) {\r
+ return "boolean";\r
+ }\r
+ else if (type == BlockParameter::Integer) {\r
+ return "integer";\r
+ }\r
+ else if (type == BlockParameter::Natural) {\r
+ return "natural";\r
+ }\r
+ else if (type == BlockParameter::Positive) {\r
+ return "positive";\r
+ }\r
+ else if (type == BlockParameter::Real) {\r
+ return "real";\r
+ }\r
+ else if (type == BlockParameter::Character) {\r
+ return "character";\r
+ }\r
+ else if (type == BlockParameter::String) {\r
+ return "string";\r
+ }\r
+ else if (type == BlockParameter::Time) {\r
+ return "time";\r
+ }\r
+ return "undefined";\r
+}\r
+\r
+int BlockParameter::typeFromString(const QString &_type) {\r
+ int ret = BlockParameter::Expression;\r
+\r
+ if (_type == "string") {\r
+ ret = BlockParameter::String;\r
+ }\r
+ else if (_type == "expression") {\r
+ ret = BlockParameter::Expression;\r
+ }\r
+ else if (_type == "boolean") {\r
+ ret = BlockParameter::Boolean;\r
+ }\r
+ else if (_type == "integer") {\r
+ ret = BlockParameter::Integer;\r
+ }\r
+ else if (_type == "natural") {\r
+ ret = BlockParameter::Natural;\r
+ }\r
+ else if (_type == "positive") {\r
+ ret = BlockParameter::Positive;\r
+ }\r
+ else if (_type == "real") {\r
+ ret = BlockParameter::Real;\r
+ }\r
+ else if (_type == "time") {\r
+ ret = BlockParameter::Time;\r
+ }\r
+ return ret;\r
+}\r
+\r
+\r
--- /dev/null
+#ifndef __BLOCKPARAMETER_H__\r
+#define __BLOCKPARAMETER_H__\r
+\r
+#include <iostream>\r
+#include <fstream>\r
+\r
+#include <QtCore>\r
+\r
+#include "AbstractBlock.h"\r
+class AbstractBlock;\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+\r
+class BlockParameter {\r
+\r
+public :\r
+\r
+ enum ParamType { Expression = 1, Character, String, Bit, BitVector, Boolean, Integer, Natural, Positive, Real, Time};\r
+ // a bit ugly to put that here but more practical for using them\r
+ enum ParamWBAccess { Read = 1, Write = 2};\r
+ enum ParamWBDuration { Permanent = 1, Trigger = 2 };\r
+ enum ParamVHDLContext { Entity = 1, Component = 2, Architecture = 3 }; // NB : 3 is when creating an instance of the block that owns this iface\r
+ enum ParamVHDLFlags { NoComma = 1 };\r
+\r
+ BlockParameter();\r
+ BlockParameter(AbstractBlock* _owner, const QString& _name , const QString& _type, const QString& _value);\r
+\r
+ virtual ~BlockParameter();\r
+\r
+ // getters\r
+ inline AbstractBlock* getOwner() { return owner; }\r
+ inline QString getName() { return name; }\r
+ inline int getType() { return type; }\r
+ QString getTypeString();\r
+ virtual QVariant getValue(); // may be overriden\r
+ virtual QString getContext() = 0;\r
+\r
+ // setters\r
+ inline void setOwner(AbstractBlock* _owner) { owner = _owner; }\r
+ inline void setName(const QString& _name) { name = _name; }\r
+ inline void setType(int _type) { type = _type; }\r
+ virtual void setValue(const QString& _value);\r
+\r
+ // testers\r
+ virtual bool isValueSet(); // may be overridden for User and Generic parameters\r
+ virtual bool isUserParameter();\r
+ virtual bool isGenericParameter();\r
+ virtual bool isWishboneParameter();\r
+ virtual bool isPortParameter();\r
+\r
+ // others\r
+ virtual BlockParameter* clone() = 0;\r
+ virtual QString toVHDL(int context, int flags);\r
+ int typeFromString(const QString& _type);\r
+\r
+protected:\r
+\r
+ AbstractBlock* owner;\r
+ QString name; \r
+ int type;\r
+ QVariant defaultValue; // the value set during construction\r
+\r
+};\r
+\r
+#endif // __BLOCKPARAMETER_H__\r
+\r
--- /dev/null
+#include "BlockParameterGeneric.h"\r
+#include "GroupBlock.h"\r
+#include "FunctionalBlock.h"\r
+\r
+BlockParameterGeneric::BlockParameterGeneric() : BlockParameter() {\r
+ userValue = defaultValue;\r
+}\r
+\r
+BlockParameterGeneric::BlockParameterGeneric(AbstractBlock* _owner, const QString &_name, const QString &_type, const QString &_value) : BlockParameter(_owner, _name, _type, _value) {\r
+ userValue = defaultValue;\r
+}\r
+\r
+QVariant BlockParameterGeneric::getValue() {\r
+ if (isValueSet()) {\r
+ return userValue;\r
+ }\r
+ return defaultValue;\r
+}\r
+\r
+bool BlockParameterGeneric::isGenericParameter() {\r
+ return true;\r
+}\r
+\r
+void BlockParameterGeneric::setValue(const QString& _value) {\r
+ userValue = QVariant(_value);\r
+}\r
+\r
+\r
+bool BlockParameterGeneric::isValueSet() {\r
+ if (userValue.isNull()) return false;\r
+ return true;\r
+}\r
+\r
+bool BlockParameterGeneric::isDefaultValue() {\r
+ if (userValue == defaultValue) return true;\r
+ return false;\r
+}\r
+\r
+BlockParameter* BlockParameterGeneric::clone() { \r
+\r
+ BlockParameter* block = new BlockParameterGeneric(owner,name,getTypeString(),defaultValue.toString());\r
+ return block;\r
+}\r
+\r
+QString BlockParameterGeneric::toVHDL(int context, int flags) {\r
+\r
+ QString ret="";\r
+\r
+\r
+ if ((context == BlockParameter::Entity) || (context == BlockParameter::Component)) {\r
+\r
+ QString formatValue = "%1 : %2 := %3";\r
+ QString formatNoValue = "%1 : %2";\r
+ if ((flags & BlockParameter::NoComma) == 0) {\r
+ formatValue.append(";");\r
+ formatNoValue.append(";");\r
+ }\r
+\r
+ if (!userValue.isNull()) {\r
+ ret = formatValue.arg(name).arg(type).arg(userValue.toString());\r
+ }\r
+ else if (!defaultValue.isNull()) {\r
+ ret = formatValue.arg(name).arg(type).arg(defaultValue.toString());\r
+ }\r
+ else {\r
+ ret = formatNoValue.arg(name).arg(type);\r
+ }\r
+ }\r
+ else if (context == BlockParameter::Architecture) {\r
+ QString format = "%1 => %2";\r
+ if ((flags & BlockParameter::NoComma) == 0) {\r
+ format.append(";");\r
+ }\r
+ AbstractBlock* parent = owner->getParent();\r
+ BlockParameter* p = parent->getParameterFromName(name);\r
+ if (p != NULL) {\r
+ /* the parent group has a generic parameter with the same\r
+ name\r
+ */\r
+ ret = format.arg(name).arg(name);\r
+ }\r
+ else {\r
+ if (!userValue.isNull()) {\r
+ ret = format.arg(name).arg(userValue.toString());\r
+ }\r
+ else if (!defaultValue.isNull()) {\r
+ ret = format.arg(name).arg(defaultValue.toString());\r
+ }\r
+ else {\r
+ // abnormal case\r
+ ret = format.arg(name).arg("INVALID_VALUE");\r
+ }\r
+ }\r
+ }\r
+ return ret;\r
+}\r
+\r
--- /dev/null
+#ifndef __BLOCKPARAMETERGENERIC_H__\r
+#define __BLOCKPARAMETERGENERIC_H__\r
+\r
+#include <iostream>\r
+#include <fstream>\r
+\r
+#include <QtCore>\r
+\r
+#include "BlockParameter.h"\r
+class BlockParameter;\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+\r
+class BlockParameterGeneric : public BlockParameter {\r
+\r
+public : \r
+\r
+ BlockParameterGeneric();\r
+ BlockParameterGeneric(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _value);\r
+\r
+ // getters\r
+ QVariant getValue();\r
+ inline QString getContext() { return "generic";}\r
+ // setters\r
+ void setValue(const QString& _value);\r
+ inline void resetToDefaultValue() { userValue = defaultValue; }\r
+\r
+ // testers\r
+ bool isValueSet();\r
+ bool isDefaultValue();\r
+ bool isGenericParameter();\r
+\r
+ // others\r
+ BlockParameter* clone();\r
+ QString toVHDL(int context, int flags);\r
+\r
+private:\r
+\r
+ QVariant userValue;\r
+\r
+};\r
+\r
+#endif // __BLOCKPARAMETERGENERIC_H__\r
+\r
--- /dev/null
+#include "BlockParameterPort.h"\r
+#include "ArithmeticEvaluator.h"\r
+#include "FunctionalBlock.h"\r
+#include "FunctionalInterface.h"\r
+\r
+BlockParameterPort::BlockParameterPort() : BlockParameter() {\r
+ ifaceName = "";\r
+}\r
+\r
+BlockParameterPort::BlockParameterPort(AbstractBlock* _owner, const QString &_name, const QString &_value, const QString &_ifaceName) : BlockParameter(_owner, _name, "expression", _value) {\r
+ ifaceName = _ifaceName;\r
+}\r
+\r
+bool BlockParameterPort::isPortParameter() {\r
+ return true;\r
+}\r
+\r
+BlockParameter* BlockParameterPort::clone() {\r
+ BlockParameter* block = new BlockParameterPort(owner,name,defaultValue.toString(),ifaceName);\r
+ return block;\r
+}\r
+\r
+QString BlockParameterPort::toVHDL(int context, int flags) {\r
+ QString expr="";\r
+ QString ret="";\r
+ ArithmeticEvaluator evaluator;\r
+\r
+ if (!defaultValue.isNull()) {\r
+ expr = defaultValue.toString();\r
+ try {\r
+ evaluator.setVariableMarkers("$");\r
+ evaluator.setExpression(expr);\r
+\r
+ double ifaceNb = 0.0;\r
+ double ifaceWidth = 0.0;\r
+ FunctionalInterface* iface = (FunctionalInterface*)(owner->getIfaceFromName(ifaceName));\r
+ if (iface == NULL) return "INVALID_INTERFACE_NAME";\r
+\r
+ // must get the number of instance of\r
+ ifaceNb = iface->getInterfaceMultiplicity();\r
+\r
+ int result = 0;\r
+ evaluator.setVariableValue("$if_width",ifaceWidth);\r
+ evaluator.setVariableValue("$if_nb",ifaceNb);\r
+ result = (int)(evaluator.evaluate());\r
+ ret.setNum(result);\r
+ }\r
+ catch(int e) {\r
+ cerr << "invalid expression in port parameter " << qPrintable(name) << " at character " << e << endl;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+void BlockParameterPort::setIfaceName(const QString& _ifaceName) {\r
+ ifaceName = _ifaceName;\r
+}\r
--- /dev/null
+#ifndef __BLOCKPARAMETERPORT_H__\r
+#define __BLOCKPARAMETERPORT_H__\r
+\r
+#include <iostream>\r
+#include <fstream>\r
+\r
+#include <QtCore>\r
+\r
+#include "BlockParameter.h"\r
+class BlockParameter;\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+class BlockParameterPort : public BlockParameter {\r
+\r
+public : \r
+\r
+ BlockParameterPort();\r
+ BlockParameterPort(AbstractBlock* _owner, const QString& _name, const QString& _value, const QString& _ifaceName);\r
+\r
+ // getters\r
+ inline QString getIfaceName() { return ifaceName; }\r
+ inline QString getContext() { return "port";}\r
+ // setters\r
+ void setIfaceName(const QString& _ifaceName);\r
+\r
+ // testers\r
+ bool isPortParameter();\r
+\r
+ // others\r
+ BlockParameter* clone();\r
+ QString toVHDL(int context, int flags);\r
+\r
+private:\r
+\r
+ QString ifaceName;\r
+\r
+};\r
+\r
+#endif // __BLOCKPARAMETERPORT_H__\r
+\r
--- /dev/null
+#include "BlockParameterUser.h"\r
+\r
+BlockParameterUser::BlockParameterUser() : BlockParameter() {\r
+ userValue = defaultValue;\r
+}\r
+\r
+BlockParameterUser::BlockParameterUser(AbstractBlock* _owner, const QString &_name, const QString &_value) : BlockParameter(_owner, _name, "string", _value) {\r
+ userValue = defaultValue;\r
+}\r
+\r
+QVariant BlockParameterUser::getValue() {\r
+ if (isValueSet()) {\r
+ return userValue;\r
+ }\r
+ return defaultValue;\r
+}\r
+\r
+bool BlockParameterUser::isUserParameter() {\r
+ return true;\r
+}\r
+\r
+bool BlockParameterUser::isValueSet() {\r
+ if (userValue.isNull()) return false;\r
+ return true;\r
+}\r
+\r
+bool BlockParameterUser::isDefaultValue() {\r
+ if (userValue == defaultValue) return true;\r
+ return false;\r
+}\r
+\r
+BlockParameter* BlockParameterUser::clone() {\r
+ BlockParameter* block = new BlockParameterUser(owner,name,defaultValue.toString());\r
+ return block;\r
+}\r
+\r
+QString BlockParameterUser::toVHDL(int context, int flags) {\r
+\r
+ // NB : context and flags are purely ignored\r
+ QString ret="";\r
+ if (!userValue.isNull()) {\r
+ ret = userValue.toString();\r
+ }\r
+ if (!defaultValue.isNull()) {\r
+ ret = defaultValue.toString();\r
+ }\r
+ else {\r
+ ret = "";\r
+ }\r
+ return ret;\r
+}\r
+\r
+void BlockParameterUser::setValue(const QString& _value) {\r
+ userValue = QVariant(_value);\r
+}\r
+\r
--- /dev/null
+#ifndef __BLOCKPARAMETERUSER_H__\r
+#define __BLOCKPARAMETERUSER_H__\r
+\r
+#include <iostream>\r
+#include <fstream>\r
+\r
+#include <QtCore>\r
+\r
+#include "BlockParameter.h"\r
+class BlockParameter;\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+/* NOTES :\r
+\r
+ A BlockParameterUser represents string that will be put in the generated VHDL code\r
+ each time a @val{param_name} is encountered. The default value of the string is given\r
+ at construction. If it is empty, user will have to provide a value before VHDL generation.\r
+ If it's not empty, user can still change this value before generation.\r
+ Since this string can be almost everything, it may lead to incorrect VHDL code.\r
+ But no validity check is done !\r
+\r
+ The type of such a parameter is always "string".\r
+\r
+ */\r
+class BlockParameterUser : public BlockParameter {\r
+\r
+public :\r
+\r
+ BlockParameterUser();\r
+ BlockParameterUser(AbstractBlock* _owner, const QString& _name, const QString& _value);\r
+\r
+ // getters\r
+ QVariant getValue();\r
+ inline QString getContext() { return "user";}\r
+ // setters\r
+ void setValue(const QString& _value);\r
+ inline void resetToDefaultValue() { userValue = defaultValue; }\r
+\r
+ // testers\r
+ bool isValueSet();\r
+ bool isDefaultValue();\r
+ bool isUserParameter();\r
+\r
+ // others\r
+ BlockParameter* clone();\r
+ QString toVHDL(int context, int flags);\r
+\r
+private:\r
+\r
+ QVariant userValue;\r
+\r
+};\r
+\r
+#endif // __BLOCKPARAMETERUSER_H__\r
+\r
--- /dev/null
+#include "BlockParameterWishbone.h"\r
+\r
+BlockParameterWishbone::BlockParameterWishbone() : BlockParameter() {\r
+ userValue = defaultValue;\r
+ width = "0";\r
+ wbAccess = BlockParameter::Read;\r
+ wbValue = "0";\r
+ wbDuration = BlockParameter::Permanent;\r
+}\r
+\r
+BlockParameterWishbone::BlockParameterWishbone(AbstractBlock* _owner, const QString& _name , const QString& _type, const QString& _width, const QString& _value, int _wbAccess, QString _wbValue, int _wbDuration) : BlockParameter (_owner, _name, _type, _value) {\r
+ userValue = _value;\r
+ width = _width;\r
+ wbAccess = _wbAccess;\r
+ wbValue = _wbValue;\r
+ wbDuration = _wbDuration;\r
+}\r
+\r
+QVariant BlockParameterWishbone::getValue() {\r
+ if (isValueSet()) {\r
+ return userValue;\r
+ }\r
+ return defaultValue;\r
+}\r
+\r
+bool BlockParameterWishbone::isWishboneParameter() {\r
+ return true;\r
+}\r
+\r
+void BlockParameterWishbone::setValue(const QString& _value) {\r
+ userValue = QVariant(_value);\r
+}\r
+\r
+bool BlockParameterWishbone::isValueSet() {\r
+ if (userValue.isNull()) return false;\r
+ return true;\r
+}\r
+\r
+bool BlockParameterWishbone::isDefaultValue() {\r
+ if (userValue == defaultValue) return true;\r
+ return false;\r
+}\r
+\r
+BlockParameter* BlockParameterWishbone::clone() {\r
+ BlockParameter* block = new BlockParameterWishbone(owner,name,getTypeString(),width,defaultValue.toString(),wbAccess,wbValue,wbDuration);\r
+ return block;\r
+}\r
+\r
+QString BlockParameterWishbone::toVHDL(int context, int flags) {\r
+\r
+ QString ret="";\r
+ bool ok;\r
+ if ((context == BlockParameter::Entity) || (context == BlockParameter::Component)) {\r
+\r
+ QString formatBool = "%1 : %2 std_logic";\r
+ QString formatVector = "%1 : %2 std_logic_vector(%3 downto %4)";\r
+ if ((flags & BlockParameter::NoComma) == 0) {\r
+ formatBool.append(";");\r
+ formatVector.append(";");\r
+ }\r
+ QString orientation="";\r
+ if (wbAccess == Read) {\r
+ orientation = "out";\r
+ }\r
+ else {\r
+ orientation = "in";\r
+ }\r
+ if (type == Boolean) {\r
+ ret = formatVector.arg(name).arg(orientation);\r
+ }\r
+ else if (type == Natural) {\r
+ int w = width.toInt(&ok);\r
+ if (!ok) {\r
+ ret = formatVector.arg(name).arg(orientation).arg("INVALID SIZE").arg("0");\r
+ }\r
+ else {\r
+ w -= 1;\r
+ ret = formatVector.arg(name).arg(orientation).arg(w).arg("0");\r
+ }\r
+ }\r
+ else if (type == Expression) {\r
+ QString w = width.remove('$');\r
+ w.append("-1");\r
+ ret = formatVector.arg(name).arg(orientation).arg(w).arg("0");\r
+ }\r
+ }\r
+ return ret;\r
+}\r
+\r
+\r
--- /dev/null
+#ifndef __BLOCKPARAMETERWISHBONE_H__\r
+#define __BLOCKPARAMETERWISHBONE_H__\r
+\r
+#include <iostream>\r
+#include <fstream>\r
+\r
+#include <QtCore>\r
+\r
+#include "BlockParameter.h"\r
+class BlockParameter;\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+class BlockParameterWishbone : public BlockParameter {\r
+\r
+public : \r
+\r
+ BlockParameterWishbone();\r
+ BlockParameterWishbone(AbstractBlock* _owner, const QString& _name , const QString& _type, const QString& _width, const QString& _value, int _wbAccess = BlockParameter::Read, QString _wbValue = QString(), int _wbDuration = BlockParameter::Permanent);\r
+\r
+ // getters\r
+ QVariant getValue();\r
+ inline QString getContext() { return "wb";}\r
+ inline QString getWidth() { return width; }\r
+ inline int getWBAccess() { return wbAccess; }\r
+ inline QString getWBValue() { return wbValue; }\r
+ inline int getWBDuration() { return wbDuration; }\r
+\r
+ // setters\r
+ void setValue(const QString& _value);\r
+ inline void resetToDefaultValue() { userValue = defaultValue; }\r
+ inline void setWBAccess(int _wbAccess) { wbAccess = _wbAccess; }\r
+ inline void setWBValue(QString _wbValue) { wbValue = _wbValue; }\r
+ inline void setWBDuration(int _wbDuration) { wbDuration = _wbDuration; }\r
+\r
+ // testers\r
+ bool isValueSet();\r
+ bool isDefaultValue();\r
+ bool isWishboneParameter();\r
+\r
+ // others\r
+ BlockParameter* clone();\r
+ QString toVHDL(int context, int flags);\r
+\r
+private:\r
+\r
+ QString width;\r
+ QVariant userValue;\r
+ int wbAccess;\r
+ QString wbValue;\r
+ int wbDuration;\r
+\r
+\r
+};\r
+\r
+#endif // __BLOCKPARAMETERWISHBONE_H__\r
+\r
--- /dev/null
+#include "BlockWidget.h"\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+BlockWidget::BlockWidget(QWidget *parent) : QWidget(parent)\r
+{\r
+\r
+ rxComment = new QRegExp("(.*)--.*");\r
+ rxComma = new QRegExp("(.*)[;]");\r
+ rxPort = new QRegExp("[\\s\\t]*(.*)[\\s\\t]*:[\\s\\t]*(in|out|inout)[\\s\\t]*(.*)",CaseInsensitive,QRegExp::RegExp);\r
+ rxEnt = new QRegExp("[\\s\\t]*entity[\\s\\t]*(.*)[\\s\\t]*is",CaseInsensitive,QRegExp::RegExp);\r
+ rxArch = new QRegExp("[\\s\\t]*architecture[\\s\\t]*(.*)[\\s\\t]*of (.*)[\\s\\t]*is",CaseInsensitive,QRegExp::RegExp);\r
+ rxComp = new QRegExp("[\\s\\t]*component[\\s\\t]*(.*)[\\s\\t]*",CaseInsensitive,QRegExp::RegExp);\r
+ rxEnd = new QRegExp("[\\s\\t]*end(.*)",CaseInsensitive,QRegExp::RegExp);\r
+ rxComp = new QRegExp("[\\s\\t]*end component;",CaseInsensitive,QRegExp::RegExp);\r
+ rxGeneric = new QRegExp("[\\s\\t]*generic[\\s\\t]*[(][\\s\\t]*",CaseInsensitive,QRegExp::RegExp);\r
+ rxEndGen = new QRegExp("[\\s\\t]*[)]",CaseInsensitive,QRegExp::RegExp);\r
+ rxGen = new QRegExp("[\\s\\t]*(.*)[\\s\\t]*:[\\s\\t]*(.*)[\\s\\t]*:=[\\s\\t]*(.*)",CaseInsensitive,QRegExp::RegExp);\r
+ rxConst = new QRegExp("[\\s\\t]*constant[\\s\\t]*(.*)[\\s\\t]*:[\\s\\t]*(.)*[\\s\\t]*:=[\\s\\t]*(.*)",CaseInsensitive,QRegExp::RegExp);\r
+ rxWidth = new QRegExp(".*[(](.*)(downto|to)(.*)[)]",CaseInsensitive,QRegExp::RegExp);\r
+\r
+ loadBt = new QPushButton("load VHDL");\r
+ genBt = new QPushButton("generate XML");\r
+ QHBoxLayout *widgetLayout = new QHBoxLayout;\r
+ QVBoxLayout *left = new QVBoxLayout;\r
+ QVBoxLayout *right = new QVBoxLayout;\r
+\r
+ scrollPort = new QScrollArea;\r
+ scrollPort->setWidgetResizable(true);\r
+ twPort = new QTableWidget(this);\r
+ scrollPort->setWidget(twPort);\r
+ scrollGen = new QScrollArea;\r
+ scrollGen->setWidgetResizable(true);\r
+ twGen = new QTableWidget(this);\r
+ scrollGen->setWidget(twGen);\r
+ teName = new QTextEdit;\r
+ teBrief = new QTextEdit;\r
+ teDesc = new QTextEdit;\r
+ lblName = new QLabel("Block name :");\r
+ lblBrief = new QLabel("Enter a brief description : ");\r
+ lblDesc = new QLabel("Enter a detailled description : ");\r
+ lblPort = new QLabel("Ports :");\r
+ lblGen = new QLabel("Generics :");\r
+\r
+ connect(loadBt, SIGNAL(clicked()),this, SLOT(loadCode()));\r
+ connect(genBt, SIGNAL(clicked()), this, SLOT(generateXml()));\r
+\r
+ left->addWidget(loadBt);\r
+ left->addWidget(lblPort);\r
+ left->addWidget(scrollPort);\r
+ left->addWidget(lblGen);\r
+ left->addWidget(scrollGen);\r
+\r
+ right->addWidget(lblName);\r
+ right->addWidget(teName);\r
+ right->addWidget(lblBrief);\r
+ right->addWidget(teBrief);\r
+ right->addWidget(lblDesc);\r
+ right->addWidget(teDesc);\r
+ right->addWidget(genBt);\r
+\r
+ widgetLayout->addLayout(left);\r
+ widgetLayout->addLayout(right);\r
+ setLayout(widgetLayout);\r
+ show();\r
+}\r
+\r
+BlockWidget::~BlockWidget()\r
+{\r
+\r
+}\r
+\r
+// This function opens a VHDL file and get the informations about the entity :\r
+// First the generics, then the signals.\r
+// You can edit the descriptions in the right, one for the brief description, the other for the detailled.\r
+void BlockWidget::loadCode() {\r
+\r
+ QString line, portName, portType, portId, genName, genType, genValue;\r
+ QStringList *portNameList, *portTypeList, *portIdList, *genNameList, *genTypeList, *genValueList;\r
+ cpt = 0;\r
+ twPort->setColumnCount(3);\r
+ twPort->setRowCount(cpt);\r
+ twGen->setColumnCount(3);\r
+ twGen->setRowCount(cpt);\r
+ portNameList = new QStringList;\r
+ portTypeList = new QStringList;\r
+ portIdList = new QStringList;\r
+ genNameList = new QStringList;\r
+ genTypeList = new QStringList;\r
+ genValueList = new QStringList;\r
+\r
+ fileName = QFileDialog::getOpenFileName(this,\r
+ tr("Open File"), "C:", tr("Files (*.txt *.vhd)"));\r
+ QFile file(fileName);\r
+\r
+ if(!file.open(QIODevice::ReadOnly | QIODevice::Text))\r
+ return;\r
+ QTextStream ts(&file);\r
+ while (!ts.atEnd())\r
+ {\r
+ line = ts.readLine();\r
+ if(rxComment->indexIn(line) != -1) {\r
+ line = rxComment->cap(1);\r
+ }\r
+\r
+ if(rxEnt->indexIn(line)!= -1) {\r
+\r
+ entName = rxEnt->cap(1);\r
+ teName->setText(entName);\r
+ QSize size = teName->document()->size().toSize();\r
+ teName->setMaximumSize(size);\r
+\r
+ while(rxEnd->indexIn(line) == -1) {\r
+ line = ts.readLine();\r
+ if(rxComment->indexIn(line) != -1) {\r
+ line = rxComment->cap(1);\r
+ }\r
+ if(rxComma->indexIn(line) != -1) {\r
+ line = rxComma->cap(1);\r
+ }\r
+ if(rxGeneric->indexIn(line) != -1) {\r
+ while(rxEndGen->indexIn(line) == -1) {\r
+ line = ts.readLine();\r
+ if(rxComment->indexIn(line) != -1) {\r
+ line = rxComment->cap(1);\r
+ }\r
+ if(rxComma->indexIn(line) != -1) {\r
+ line = rxComma->cap(1);\r
+ }\r
+ if(rxGen->indexIn(line) != -1) {\r
+ genName = rxGen->cap(1).simplified();\r
+ genType = rxGen->cap(2).simplified();\r
+ genValue = rxGen->cap(3).simplified();\r
+\r
+ genNameList->append(genName);\r
+ genTypeList->append(genType);\r
+ genValueList->append(genValue);\r
+ }\r
+ }\r
+ }\r
+ if(rxPort->indexIn(line) != -1) {\r
+ if(rxComment->indexIn(line) != -1) {\r
+ line = rxComment->cap(1);\r
+ }\r
+ if(rxComma->indexIn(line) != -1) {\r
+ line = rxComma->cap(1);\r
+ }\r
+ portName = rxPort->cap(1).simplified();\r
+ portId = rxPort->cap(2).simplified();\r
+ portType = rxPort->cap(3).simplified();\r
+ portNameList->append(portName);\r
+ portIdList->append(portId);\r
+ portTypeList->append(portType);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ twGen->setRowCount(genNameList->size());\r
+ for(int i = 0; i < genNameList->size(); i++) {\r
+ twGen->setItem(i, 0, new QTableWidgetItem(genNameList->at(i)));\r
+ twGen->setItem(i, 1, new QTableWidgetItem(genTypeList->at(i)));\r
+ twGen->setItem(i, 2, new QTableWidgetItem(genValueList->at(i)));\r
+ }\r
+ twPort->setRowCount(portNameList->size());\r
+ for(int i = 0; i < portNameList->size(); i++) {\r
+ twPort->setItem(i, 0, new QTableWidgetItem(portIdList->at(i)));\r
+ twPort->setItem(i, 1, new QTableWidgetItem(portNameList->at(i)));\r
+ twPort->setItem(i, 2, new QTableWidgetItem(portTypeList->at(i)));\r
+ }\r
+\r
+ file.close();\r
+ scrollPort->setWidget(twPort);\r
+ return;\r
+}\r
+\r
+// This function gets the informations in the table and the descriptions, and creates a XML file with this content\r
+void BlockWidget::generateXml() {\r
+\r
+ QString portName, portType, portId, genName, genType, genValue;\r
+ QStringList *portNameList, *portTypeList, *portIdList, *genNameList, *genTypeList, *genValueList;\r
+ int x, y, width;\r
+ brief = teBrief->toPlainText();\r
+ desc = teDesc->toPlainText();\r
+ entName = teName->toPlainText();\r
+\r
+ portNameList = new QStringList;\r
+ portTypeList = new QStringList;\r
+ portIdList = new QStringList;\r
+ genNameList = new QStringList;\r
+ genTypeList = new QStringList;\r
+ genValueList = new QStringList;\r
+ for(int i = 0; i < twGen->rowCount(); i++) {\r
+ genNameList->append(twGen->item(i,0)->text());\r
+ genTypeList->append(twGen->item(i,1)->text());\r
+ genValueList->append(twGen->item(i,2)->text());\r
+ }\r
+\r
+ for(int i = 0; i < twPort->rowCount(); i++) {\r
+ portIdList->append(twPort->item(i,0)->text());\r
+ portNameList->append(twPort->item(i,1)->text());\r
+ portTypeList->append(twPort->item(i,2)->text());\r
+ }\r
+\r
+ QDomDocument doc (entName);\r
+ QDomElement block = doc.createElement("block");\r
+ block.setAttribute("name",entName);\r
+ block.setAttribute("version", "0.1");\r
+ doc.appendChild(block);\r
+\r
+ QDomElement comments = doc.createElement("comments");\r
+ QDomElement category = doc.createElement("caterory");\r
+ category.setAttribute("ids","");\r
+ comments.appendChild(category);\r
+\r
+ QDomElement eBrief = doc.createElement("brief");\r
+ if(!brief.isEmpty()) {\r
+ QDomText txtBrief = doc.createTextNode(brief);\r
+ eBrief.appendChild(txtBrief);\r
+ comments.appendChild(eBrief);\r
+ }\r
+ QDomElement eDesc = doc.createElement("description");\r
+ if(!desc.isEmpty()) {\r
+ QDomText txtDesc = doc.createTextNode(desc);\r
+ eDesc.appendChild(txtDesc);\r
+ comments.appendChild(eDesc);\r
+ }\r
+ block.appendChild(comments);\r
+\r
+ QDomElement parameters = doc.createElement("parameters");\r
+ QDomElement interfaces = doc.createElement("interfaces");\r
+ QDomElement inputs = doc.createElement("inputs");\r
+ QDomElement outputs = doc.createElement("outputs");\r
+ QDomElement bidirs = doc.createElement("bidirs");\r
+ block.appendChild(parameters);\r
+ block.appendChild(interfaces);\r
+ interfaces.appendChild(inputs);\r
+ interfaces.appendChild(outputs);\r
+ interfaces.appendChild(bidirs);\r
+\r
+ for(int i = 0; i < twGen->rowCount(); i++) {\r
+ genName = genNameList->at(i);\r
+ genType = genTypeList->at(i);\r
+ genValue = genValueList->at(i);\r
+ QDomElement parameter = doc.createElement("parameter");\r
+ parameter.setAttribute("name",genName);\r
+ parameter.setAttribute("type",genType);\r
+ parameter.setAttribute("value",genValue);\r
+ parameter.setAttribute("context","generic");\r
+ parameters.appendChild(parameter);\r
+ }\r
+\r
+ for(int i = 0; i < portIdList->size(); i++) {\r
+ portId = portIdList->at(i);\r
+ portName = portNameList->at(i);\r
+ portType = portTypeList->at(i);\r
+ if(rxWidth->indexIn(portType) != -1) {\r
+ x = rxWidth->cap(1).toInt();\r
+ y = rxWidth->cap(3).toInt();\r
+ if(x < y)\r
+ width = y - x + 1;\r
+ else if(x > y)\r
+ width = x - y + 1;\r
+ else\r
+ width = 1;\r
+ }\r
+\r
+ if(portId.compare("in", CaseInsensitive) == 0) {\r
+ QDomElement input = doc.createElement("input");\r
+ input.setAttribute("name",portName);\r
+ input.setAttribute("width", width);\r
+ inputs.appendChild(input);\r
+ }\r
+ else if(portId.compare("out", CaseInsensitive) == 0) {\r
+ QDomElement output = doc.createElement("output");\r
+ output.setAttribute("name",portName);\r
+ output.setAttribute("width", width);\r
+ outputs.appendChild(output);\r
+ }\r
+ else if(portId.compare("inout", CaseInsensitive) == 0) {\r
+ QDomElement bidir = doc.createElement("bidir");\r
+ bidir.setAttribute("name",portName);\r
+ bidir.setAttribute("width", width);\r
+ bidirs.appendChild(bidir);\r
+ }\r
+ }\r
+\r
+ fileName = QFileDialog::getOpenFileName(this, tr("Open File"),\r
+ "C:", tr("Files (*.xml)"));\r
+ QFile file(fileName);\r
+ if(!file.open(QIODevice::WriteOnly | QIODevice::Text))\r
+ return;\r
+ QTextStream ts(&file);\r
+ doc.save(ts,QDomNode::EncodingFromTextStream);\r
+ file.close();\r
+\r
+ QLabel *popup = new QLabel("Votre fichier XML est rempli");\r
+ popup->show();\r
+}\r
--- /dev/null
+#ifndef ENTITYWIDGET_H\r
+#define ENTITYWIDGET_H\r
+\r
+#include <QtGui>\r
+#include <QtWidgets>\r
+#include <QtCore>\r
+#include <QtXml>\r
+#include <iostream>\r
+#include <fstream>\r
+#include <QTextStream>\r
+\r
+#include "Parameters.h"\r
+#include "BlockParameter.h"\r
+#include "Graph.h"\r
+\r
+class BlockWidget : public QWidget\r
+{\r
+ Q_OBJECT\r
+public:\r
+ explicit BlockWidget(QWidget *parent = 0);\r
+ ~BlockWidget();\r
+\r
+private:\r
+ QPushButton *loadBt, *genBt;\r
+ int cptIn, cptOut, cptInout, cpt;\r
+ QRegExp *rxPort, *rxEnt, *rxArch, *rxComp, *rxComment, *rxComma,\r
+ *rxEndComp, *rxEnd, *rxGeneric, *rxEndGen, *rxGen, *rxConst, *rxWidth;\r
+ QString fileName, txt, s, entName, brief, desc;\r
+ QScrollArea *scrollPort, *scrollGen;\r
+ QWidget *wid;\r
+ QLabel *labelAppli, *lblBrief, *lblDesc, *lblName, *lblPort, *lblGen;\r
+ QTableWidget *twPort, *twGen;\r
+ QTextEdit *teBrief, *teDesc, *teName;\r
+\r
+signals:\r
+\r
+public slots:\r
+ void loadCode();\r
+ void generateXml();\r
+};\r
+\r
+#endif // ENTITYWIDGET_H\r
--- /dev/null
+#include "BlocksToConfigureWidget.h"
+#include <QTreeWidgetItem>
+#include "ParametersWindow.h"
+
+
+BlocksToConfigureWidget::BlocksToConfigureWidget(QList<AbstractBlock *> blocksList, Parameters *_params, QWidget *parent) :
+ QWidget(parent)
+{
+ blocks = blocksList;
+ params = _params;
+ layout = new QGridLayout;
+ tree = new QTreeWidget(this);
+ configureButton = new QPushButton("configure", this);
+ configureButton->setEnabled(false);
+
+ connect(tree, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(clicked()));
+ connect(tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(doubleClicked()));
+ connect(configureButton, SIGNAL(clicked()), this, SLOT(configure()));
+
+ updateNamesList();
+ tree->setHeaderLabel("blocks to configure");
+ layout->addWidget(tree);
+ layout->addWidget(configureButton);
+
+ this->setLayout(layout);
+ this->setFixedSize(300,230);
+}
+
+void BlocksToConfigureWidget::updateNamesList()
+{
+ tree->clear();
+ QTreeWidgetItem *item = NULL;
+ foreach(AbstractBlock *block, blocks){
+ item = new QTreeWidgetItem(tree->invisibleRootItem());
+ item->setData(0, Qt::DisplayRole, block->getName());
+ }
+
+}
+
+void BlocksToConfigureWidget::updateBlocksList()
+{
+ blocks = params->getBlocksToConfigure();
+ updateNamesList();
+}
+
+void BlocksToConfigureWidget::closeEvent(QCloseEvent *event)
+{
+ //when parameters validation is over,
+ //we start connections validation.
+ params->connectionsValidation();
+}
+
+void BlocksToConfigureWidget::clicked()
+{
+ if(tree->selectedItems().length() > 0)
+ configureButton->setEnabled(true);
+ else
+ configureButton->setEnabled(false);
+}
+
+void BlocksToConfigureWidget::doubleClicked()
+{
+ configure();
+}
+
+void BlocksToConfigureWidget::configure()
+{
+ if(tree->selectedItems().length() > 0){
+ bool firstItem = true; // We take only the first selected item
+ for (int i=0; i<tree->topLevelItemCount(); i++){
+ if(firstItem && tree->topLevelItem(i)->isSelected()){
+ firstItem = false;
+ new ParametersWindow(blocks.at(i), params, this);
+ }
+ }
+ }
+}
--- /dev/null
+#ifndef __BLOCKSTOCONFIGUREWIDGET_H__
+#define __BLOCKSTOCONFIGUREWIDGET_H__
+
+#include <QWidget>
+
+#include <QTreeWidget>
+#include <QGridLayout>
+#include "Parameters.h"
+#include "AbstractBlock.h"
+#include <QPushButton>
+
+class BlocksToConfigureWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ BlocksToConfigureWidget(QList<AbstractBlock *> blocksList, Parameters *_params, QWidget *parent=0);
+
+ void updateNamesList();
+ void updateBlocksList();
+
+ inline QTreeWidget *getTree() { return tree; }
+ inline QList<AbstractBlock*> getBlocks() { return blocks; }
+
+private:
+ void closeEvent(QCloseEvent * event);
+
+ QList<AbstractBlock*> blocks;
+ QTreeWidget *tree;
+ QGridLayout *layout;
+ QPushButton *configureButton;
+ Parameters *params;
+
+private slots:
+ void clicked();
+ void doubleClicked();
+ void configure();
+};
+
+#endif // BLOCKSTOCONFIGUREWIDGET_H
--- /dev/null
+#include "BoxItem.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"
+
+
+BoxItem::BoxItem(AbstractBlock *_refBlock,
+ Dispatcher *_dispatcher,
+ Parameters *_params, GroupItem *parent) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params, parent) {
+
+ /* NOTE :
+ _refBlock : mandatory a FunctionalBlock or a GroupBlock
+ */
+ if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
+
+ childGroupItem = NULL;
+ //boxWidth = params->defaultBlockWidth;
+ //boxHeight = params->defaultBlockHeight;
+ currentBorder = NoBorder;
+ selected = false;
+
+ setZValue(100);
+ setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
+
+ initInterfaces();
+ updateGeometry();
+ 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() {
+}
+
+void BoxItem::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::yellow);
+
+ 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 BoxItem::moveTo(QPointF dest) {
+ setPos(dest);
+ currentPosition = dest;
+}
+
+bool BoxItem::isBoxItem() {
+ return true;
+}
+
+void BoxItem::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->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 BoxItem::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;
+
+ if ((type == Resize) || (type == InterfaceMove)) {
+ updateMinimumSize();
+ }
+
+ if (type == Resize) {
+ prepareGeometryChange();
+ updateInterfacesAndConnections();
+ boxSizeChanged = true;
+ }
+ 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 BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
+
+ if(params->editState == Parameters::EditBlockMove) {
+ QPointF absPos = currentPosition + originPoint;
+ int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
+ int gapX = event->scenePos().x() - cursorPosition.x();
+ int gapY = event->scenePos().y() - cursorPosition.y();
+
+ //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->setPathes();
+ }
+ }
+ 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()) {
+ (getScene()->getGroupItem())->updateShape();
+ }
+
+ cursorPosition = event->scenePos();
+ }
+ else if(params->editState == Parameters::EditInterfaceMove) {
+ prepareGeometryChange();
+ deplaceInterface(event->pos());
+ // recompute the geometry of the block
+ if (updateGeometry()) {
+ 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->setPathes();
+ }
+ }
+ }
+}
+
+void BoxItem::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()->getGroupWindow());
+
+ 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 BoxItem::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->connect(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 {
+ 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 BoxItem::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 BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
+
+ QMenu menu;
+ QAction* removeAction = menu.addAction("Remove");
+ QAction* duplicateAction = menu.addAction("Duplicate");
+ QAction* renameAction = menu.addAction("Rename");
+ QAction* connectToGroup = NULL;
+ QAction* disconnectFromGroup = NULL;
+ QAction* showProperties = NULL;
+ QAction* cloneInterface = NULL;
+ QAction* openWindow = NULL;
+ QAction* showRstClkInter = NULL;
+ QAction* showParameters = NULL;
+
+ InterfaceItem* ifaceItem = getInterfaceFromCursor(event->pos().x(), event->pos().y());
+ if( ifaceItem != NULL){
+ showProperties = menu.addAction("Show properties");
+
+ ConnectedInterface* iface = ifaceItem->refInter;
+ if ((iface->getDirection() == AbstractInterface::Input) && (iface->getConnectedFrom() == NULL)) {
+ connectToGroup = menu.addAction("Connect to group input");
+ }
+ else if ((iface->getDirection() == AbstractInterface::Output) && (!iface->isConnectedTo())) {
+ connectToGroup = menu.addAction("Connect to group output");
+ }
+ else if ((iface->getConnectionFromParentGroup() != NULL) || (iface->getConnectionToParentGroup() != NULL)) {
+ disconnectFromGroup = menu.addAction("Disconnect from group");
+ }
+
+ if (iface->isFunctionalInterface()) {
+ FunctionalInterface* fi = AI_TO_FUN(ifaceItem->refInter);
+ ReferenceInterface* ri = (ReferenceInterface*)(fi->getReference());
+ if(ri->getMultiplicity() == -1 || ri->getMultiplicity() > 1){
+ cloneInterface = menu.addAction("Clone interface");
+ }
+ }
+ }
+ if(refBlock->isGroupBlock()){
+ openWindow = menu.addAction("Open/show group window");
+ } else {
+ showRstClkInter = menu.addAction("Show reset/clock interfaces");
+ showRstClkInter->setCheckable(true);
+ showRstClkInter->setChecked(rstClkVisible);
+
+ showParameters = menu.addAction("Show parameters");
+ }
+
+ QAction* selectedAction = NULL;
+ selectedAction = menu.exec(event->screenPos());
+
+ if(selectedAction == NULL) return ;
+
+ if (selectedAction == removeAction) {
+ dispatcher->removeBlock(this);
+ }
+ else if (selectedAction == duplicateAction) {
+ dispatcher->duplicateBlock(this);
+ }
+ else if(selectedAction == renameAction){
+ if(ifaceItem != NULL)
+ dispatcher->rename(ifaceItem);
+ else
+ dispatcher->rename(this);
+ }
+ else if(selectedAction == showProperties){
+ dispatcher->showProperties(ifaceItem);
+ }
+ else if (selectedAction == connectToGroup){
+ dispatcher->connectInterToGroup(ifaceItem);
+ }
+ else if (selectedAction == disconnectFromGroup) {
+ dispatcher->disconnectInterFromGroup(ifaceItem);
+ }
+ else if (selectedAction == cloneInterface){
+ dispatcher->duplicateInterface(ifaceItem);
+ }
+ else if (selectedAction == openWindow){
+ dispatcher->showRaiseWindow(this);
+ }
+ else if(selectedAction == showRstClkInter){
+ dispatcher->showRstClkInter(this);
+ }
+ else if(selectedAction == showParameters){
+ new ParametersWindow(refBlock, params, NULL);
+ }
+}
+
+void BoxItem::save(QXmlStreamWriter &writer) {
+ if (refBlock->isFunctionalBlock()) {
+ writer.writeStartElement("bi_functional");
+
+ 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(pos().x()).append(",").append(QString::number(pos().y()));
+ writer.writeAttribute("position",attrPos);
+ QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
+ writer.writeAttribute("dimension",attrDim);
+
+ writer.writeStartElement("bif_parameters");
+ foreach(BlockParameter *param,refBlock->getParameters()){
+ writer.writeStartElement("bif_parameter");
+
+ writer.writeAttribute("name",param->getName());
+ writer.writeAttribute("value",param->getValue().toString());
+ /*
+ writer.writeAttribute("context",param->getStrContext());
+ writer.writeAttribute("type",param->getTypeString());
+ */
+ writer.writeEndElement(); //</bif_parameter>
+ }
+ writer.writeEndElement(); //</bif_parameters>
+
+ writer.writeStartElement("bif_ifaces");
+ writer.writeAttribute("count",QString::number(interfaces.length()));
+ foreach(InterfaceItem* inter, interfaces){
+ writer.writeStartElement("bif_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(); //</bif_iface>
+ }
+ writer.writeEndElement(); //</bif_ifaces>
+
+ writer.writeEndElement(); //</bi_functional>
+ }
+ else {
+ writer.writeStartElement("bi_group");
+
+ writer.writeAttribute("id",QString::number(id));
+ writer.writeAttribute("inside_group",QString::number(childGroupItem->getId()));
+ QString attrPos = QString::number(pos().x()).append(",").append(QString::number(pos().y()));
+ writer.writeAttribute("position",attrPos);
+ QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
+ writer.writeAttribute("dimension",attrDim);
+
+ writer.writeStartElement("big_ifaces");
+ writer.writeAttribute("count",QString::number(interfaces.length()));
+ foreach(InterfaceItem* inter, interfaces){
+ writer.writeStartElement("big_iface");
+
+ writer.writeAttribute("id",QString::number(inter->getId()));
+ writer.writeAttribute("ref_name",inter->refInter->getName());
+ writer.writeAttribute("orientation",inter->getStrOrientation());
+ writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
+
+ writer.writeEndElement(); //</big_iface>
+ }
+
+ writer.writeEndElement(); //</big_ifaces>
+ writer.writeEndElement(); //</bi_group>
+ }
+}
+
+QDataStream &operator <<(QDataStream &out, BoxItem &b) {
+ out.setVersion(QDataStream::Qt_4_8);
+
+ QByteArray blockData;
+ QDataStream toWrite(&blockData, QIODevice::WriteOnly);
+
+ QString refXml = ((FunctionalBlock*)b.refBlock)->getReferenceXmlFile();
+ QByteArray xmlFile = QByteArray(refXml.toStdString().c_str());
+ toWrite << xmlFile;
+
+ toWrite << b.id;
+ toWrite << (int)b.x();
+ toWrite << (int)b.y();
+ toWrite << b.boxWidth;
+ toWrite << b.boxHeight;
+ toWrite << b.getInterfaces().length();
+
+ for(int i=0; i<b.getInterfaces().length(); i++){
+ InterfaceItem *inter = b.getInterfaces().at(i);
+ toWrite << inter->getId();
+ toWrite << inter->getName();
+ toWrite << inter->getPositionRatio();
+ toWrite << inter->getOrientation();
+ }
+
+ out << blockData;
+
+ return out;
+}
+
+QDataStream &operator >>(QDataStream &in, BoxItem &b)
+{
+
+ in.setVersion(QDataStream::Qt_4_8);
+
+ int x,y,nbInter;
+
+ in >> b.id;
+ in >> x;
+ in >> y;
+
+ b.setX(x);
+ b.setY(y);
+
+ in >> b.boxWidth;
+ in >> b.boxHeight;
+ in >> nbInter;
+
+ cout << "nbInter:" << nbInter << endl;
+ for(int i=0; i<nbInter; i++){
+
+ int id, orientation;
+ double positionRatio;
+ QString name;
+
+ InterfaceItem *inter = b.getInterfaces().at(i);
+ in >> id;
+ in >> name;
+ in >> positionRatio;
+ in >> orientation;
+
+ inter->setId(id);
+ inter->setName(name);
+ inter->setPositionRatio(positionRatio);
+ inter->setOrientation(orientation);
+ inter->updatePosition();
+
+ }
+
+ return in;
+}
--- /dev/null
+#ifndef __BLOCKITEM_H__
+#define __BLOCKITEM_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+
+
+#include "AbstractBoxItem.h"
+class AbstractBoxItem;
+
+class GroupItem;
+class Parameters;
+class Dispacther;
+
+#include "Exception.h"
+
+using namespace std;
+using namespace Qt;
+
+/* NOTE :
+
+ A BoxItem may represent a functional block or a group block within a group item, itslef
+ within a scene. What says what it represents is refBlock, i.e. if refBlock->isFunctionalBlock()
+ or refBlock->isGroupBlock() returns true.
+ */
+class BoxItem : public AbstractBoxItem {
+
+public:
+ BoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, GroupItem* parent) throw(Exception);
+ ~BoxItem();
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+ // getters
+ inline GroupItem *getChildGroupItem() { return childGroupItem; }
+
+ // setters
+ inline void setChildGroupItem(GroupItem* item) { childGroupItem = item; }
+
+ // testers
+ bool isBoxItem();
+
+ // others
+ void moveTo(QPointF dest);
+ void save(QXmlStreamWriter& writer);
+
+protected:
+
+ void updateMinimumSize(); // modify the minimum size
+ bool updateGeometry(ChangeType type); // modify the originPoint and the total dimension
+
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
+ void hoverMoveEvent( QGraphicsSceneHoverEvent *event);
+
+private:
+
+ /* NOTE :
+ A BlockItem is always graphically within a GroupItem, inside the same scene.
+
+ A BlockItem may also be the graphical view of a GroupBlock. In this case, there exists a child scene
+ containing a GroupItem. insideGroup atribute refers to this GroupItem and thus, may be NULL if the current
+ blockItem represents a functional block
+ */
+ GroupItem *childGroupItem;
+
+
+ friend QDataStream &operator<<(QDataStream &out, BoxItem &b);
+ friend QDataStream &operator>>(QDataStream &in, BoxItem &b);
+
+signals:
+ void itemMustBeDeleted(QGraphicsItem*);
+
+};
+
+QDataStream & operator <<(QDataStream &out, BoxItem &b);
+QDataStream & operator >>(QDataStream &in, BoxItem &b);
+
+#endif // __BLOCKITEM_H__
--- /dev/null
+#include "ArithmeticEvaluator.h"\r
+#include "ConnectedInterface.h"\r
+#include "FunctionalBlock.h"\r
+#include "GroupBlock.h"\r
+\r
+\r
+ConnectedInterface::ConnectedInterface(AbstractBlock* _owner) : AbstractInterface(_owner) {\r
+ connectedFrom = NULL;\r
+}\r
+\r
+ConnectedInterface::ConnectedInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose, int _level) : AbstractInterface(_owner, _name, _type, _width, _direction, _purpose, _level) {\r
+ connectedFrom = NULL;\r
+}\r
+\r
+void ConnectedInterface::removeConnectedTo(ConnectedInterface *iface) {\r
+ connectedTo.removeOne(iface);\r
+}\r
+\r
+void ConnectedInterface::clearConnections() {\r
+ connectedFrom = NULL;\r
+ connectedTo.clear();\r
+}\r
+\r
+void ConnectedInterface::clearConnectedTo() {\r
+ connectedTo.clear();\r
+}\r
+\r
+bool ConnectedInterface::connectTo(ConnectedInterface *iface) {\r
+\r
+ if (canConnectTo(iface)) {\r
+ connectedTo.append(iface);\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+bool ConnectedInterface::connectFrom(ConnectedInterface *iface) {\r
+ if (canConnectFrom(iface)) {\r
+ connectedFrom = iface;\r
+ return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+/* getConnectionToParentGroup() :\r
+ if an interface among connectedTo is an interface of the parent group\r
+ returns it.\r
+*/\r
+ConnectedInterface* ConnectedInterface::getConnectionToParentGroup() {\r
+ foreach(ConnectedInterface *iface, connectedTo) {\r
+ if (owner->getParent() == iface->owner) {\r
+ return iface;\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+/* getConnectionFromParentGroup() :\r
+ if connectedFrom is an interface of the parent group\r
+ returns it.\r
+*/\r
+ConnectedInterface *ConnectedInterface::getConnectionFromParentGroup() {\r
+ if ((connectedFrom != NULL) && (owner->getParent() == connectedFrom->owner)) {\r
+ return connectedFrom;\r
+ }\r
+ return NULL;\r
+}\r
--- /dev/null
+#ifndef __CONNECTEDINTERFACE_H__
+#define __CONNECTEDINTERFACE_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+
+#include "AbstractInterface.h"
+class ReferenceInterface;
+
+#include "Exception.h"
+
+using namespace std;
+using namespace Qt;
+
+
+class ConnectedInterface : public AbstractInterface {
+
+public :
+
+ ConnectedInterface(AbstractBlock* _owner);
+ ConnectedInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose, int _level);
+ // getters
+ inline QList<ConnectedInterface*> getConnectedTo() { return connectedTo;}
+ inline ConnectedInterface* getConnectedFrom() { return connectedFrom;}
+
+ // setters
+
+ // testers
+ inline bool isConnectedTo(){return connectedTo.length() != 0;}
+ inline bool isConnectedFrom(){return connectedFrom != NULL;}
+ virtual bool canConnectTo(AbstractInterface* iface) = 0;
+ virtual bool canConnectFrom(AbstractInterface* iface) = 0;
+
+ // others
+ bool connectTo(ConnectedInterface* iface);
+ bool connectFrom(ConnectedInterface* iface);
+ ConnectedInterface* getConnectionToParentGroup();
+ ConnectedInterface* getConnectionFromParentGroup();
+
+ virtual AbstractInterface *clone() = 0;
+
+ void removeConnectedTo(ConnectedInterface *inter);
+
+ virtual void clearConnectedTo();
+ inline void clearConnectedFrom() { connectedFrom = NULL; }
+ virtual void clearConnections();
+ //virtual void connectionsValidation(QStack<AbstractInterface*> *interfacetoValidate, QList<AbstractInterface*> *validatedInterfaces) throw(Exception) = 0;
+
+protected:
+ QList<ConnectedInterface*> connectedTo;
+ ConnectedInterface* connectedFrom;
+
+};
+
+
+#endif // __CONNECTEDINTERFACE_H__
--- /dev/null
+#include "ConnectionItem.h"
+
+#include "Dispatcher.h"
+#include "Parameters.h"
+#include "AbstractBoxItem.h"
+#include "ConnectedInterface.h"
+#include "InterfaceItem.h"
+#include "AbstractBlock.h"
+
+//int ConnectionItem::counter = 0;
+
+ConnectionItem::ConnectionItem(InterfaceItem* _iface1,
+ InterfaceItem* _iface2,
+ Dispatcher* _dispatcher,
+ Parameters* _params,
+ QGraphicsItem *_parent) : QGraphicsItem(_parent) {
+
+
+ dispatcher = _dispatcher;
+ params = _params;
+
+ ConnectedInterface* ref1 = _iface1->refInter;
+ ConnectedInterface* ref2 = _iface2->refInter;
+ /* ref. note in .h
+ case 1 : ref1 is group interface, and ref2 block interface of a block within the group
+ case 2 : the opposite of case 1
+ case 3 : ref1 and ref2 are block interface of blocks that are both within the same parent group.
+ */
+ if (ref1->getOwner() == ref2->getOwner()->getParent()) {
+
+ if (ref1->getDirection() == AbstractInterface::Input) {
+ fromInterfaceItem = _iface1;
+ toInterfaceItem = _iface2;
+ }
+ else if (ref1->getDirection() == AbstractInterface::InOut) {
+ fromInterfaceItem = _iface1;
+ toInterfaceItem = _iface2;
+ }
+ else if (ref1->getDirection() == AbstractInterface::Output) {
+ toInterfaceItem = _iface1;
+ fromInterfaceItem = _iface2;
+ }
+ }
+ else if (ref1->getOwner()->getParent() == ref2->getOwner()) {
+
+ if (ref1->getDirection() == AbstractInterface::Input) {
+ fromInterfaceItem = _iface2;
+ toInterfaceItem = _iface1;
+ }
+ else if (ref1->getDirection() == AbstractInterface::InOut) {
+ fromInterfaceItem = _iface2;
+ toInterfaceItem = _iface1;
+ }
+ else if (ref1->getDirection() == AbstractInterface::Output) {
+ toInterfaceItem = _iface2;
+ fromInterfaceItem = _iface1;
+ }
+ }
+ // NB : this case is in fact similar to the previous. Kept here for clarity
+ else if (ref1->getOwner()->getParent() == ref2->getOwner()->getParent()) {
+
+ if (ref1->getDirection() == AbstractInterface::Input) {
+ fromInterfaceItem = _iface2;
+ toInterfaceItem = _iface1;
+ }
+ else if (ref1->getDirection() == AbstractInterface::InOut) {
+ fromInterfaceItem = _iface2;
+ toInterfaceItem = _iface1;
+ }
+ else if (ref1->getDirection() == AbstractInterface::Output) {
+ toInterfaceItem = _iface2;
+ fromInterfaceItem = _iface1;
+ }
+ }
+ // adding this to interface items
+ fromInterfaceItem->addConnectionItem(this);
+ toInterfaceItem->addConnectionItem(this);
+
+ selected = false;
+ marginConn = params->arrowLineLength+params->arrowWidth;
+
+ setFlag(ItemIsSelectable);
+ setAcceptHoverEvents(true);
+ setFlag(ItemSendsGeometryChanges);
+ setCursor(Qt::PointingHandCursor);
+ setZValue(0);
+
+ setPathes();
+}
+
+
+ConnectionItem::ConnectionItem(const ConnectionItem ©) {
+ pointFrom = copy.pointFrom;
+ pointTo = copy.pointTo;
+ interPoint1 = copy.interPoint1;
+ interPoint2 = copy.interPoint2;
+ interPoint3 = copy.interPoint3;
+ interPoint4 = copy.interPoint4;
+}
+
+ConnectionItem::~ConnectionItem() {
+}
+
+ConnectionItem::ConnectionItem() {
+}
+
+QPainterPath ConnectionItem::shape() const {
+ return pathShape;
+}
+
+QRectF ConnectionItem::boundingRect() const {
+
+ QPointF start, end;
+
+ if(pointFrom.x() < pointTo.x()){
+ start.setX(pointFrom.x()-20);
+ end.setX(pointTo.x()+20);
+ } else {
+ start.setX(pointTo.x()-20);
+ end.setX(pointFrom.x()+20);
+ }
+ if(pointFrom.y() < pointTo.y()){
+ start.setY(pointFrom.y()-20);
+ end.setY(pointTo.y()+20);
+ } else {
+ start.setY(pointTo.y()-20);
+ end.setY(pointFrom.y()+20);
+ }
+ return QRectF(start, end);
+}
+
+void ConnectionItem::paint(QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget) {
+
+ painter->setPen(Qt::blue);
+ if(selected){
+ painter->setPen(Qt::red);
+ }
+
+ painter->drawPath(pathPaint);
+}
+
+void ConnectionItem::addInterPoint(QPointF point) {
+
+}
+
+void ConnectionItem::setPathes() {
+
+ prepareGeometryChange();
+
+ pointFrom = fromInterfaceItem->getEndPointInGroup();
+ pointTo = toInterfaceItem->getEndPointInGroup();
+
+ int oriFrom, oriTo;
+ oriFrom = fromInterfaceItem->getOrientation();
+ oriTo = toInterfaceItem->getOrientation();
+
+/* NB: if src or dest is onwed by a GroupItem the orientation
+ must be changed as it is a block.
+ */
+ if(fromInterfaceItem->owner->isGroupItem()){
+ switch(fromInterfaceItem->getOrientation()){
+ case Parameters::North :
+ oriFrom = Parameters::South;
+ break;
+ case Parameters::South :
+ oriFrom = Parameters::North;
+ break;
+ case Parameters::East :
+ oriFrom = Parameters::West;
+ break;
+ case Parameters::West :
+ oriFrom = Parameters::East;
+ break;
+ }
+ }
+ if(toInterfaceItem->owner->isGroupItem()){
+ switch(toInterfaceItem->getOrientation()){
+ case Parameters::North :
+ oriTo = Parameters::South;
+ break;
+ case Parameters::South :
+ oriTo = Parameters::North;
+ break;
+ case Parameters::East :
+ oriTo = Parameters::West;
+ break;
+ case Parameters::West :
+ oriTo = Parameters::East;
+ break;
+ }
+ }
+ double gap1 = 0.0;
+ double gap2 = 0.0;
+
+ if(oriFrom == Parameters::South) {
+
+ // FROM SOUTH TO SOUTH
+ if(oriTo == Parameters::South) {
+ computeElle(oriFrom);
+ }
+ // FROM SOUTH TO NORTH
+ else if(oriTo == Parameters::North) {
+ gap1 = pointTo.y() - pointFrom.y();
+ if (gap1 > 2*marginConn) {
+ computeStaircase(oriFrom);
+ }
+ else {
+ computeEsse(oriFrom);
+ }
+ }
+ // FROM SOUTH TO EAST OR WEST
+ else if ((oriTo == Parameters::East) || (oriTo == Parameters::West)){
+
+ gap1 = pointTo.x() - pointFrom.x();
+ if (oriTo == Parameters::West) gap1 = -gap1;
+ gap2 = pointTo.y() - pointFrom.y();
+
+ if (gap1 > 0.0) {
+ if (gap2 > 0.0) {
+ computeHookSmallEnd(oriFrom,oriTo);
+ }
+ else {
+ computeOpenRect(oriFrom,oriTo);
+ }
+ }
+ else {
+ if (gap2 >= 0.0) {
+ computeCorner(oriFrom);
+ }
+ else {
+ computeHookSmallStart(oriFrom,oriTo);
+ }
+ }
+ }
+ }
+ else if(oriFrom == Parameters::North) {
+
+ // FROM NORTH TO SOUTH
+ if(oriTo == Parameters::South) {
+ gap1 = pointFrom.y() - pointTo.y();
+ if (gap1 > 2*marginConn) {
+ computeStaircase(oriFrom);
+ }
+ else {
+ computeEsse(oriFrom);
+ }
+ }
+ // FROM NORTH TO NORTH
+ else if(oriTo == Parameters::North) {
+ computeElle(oriFrom);
+ }
+ // FROM NORTH TO EAST OR WEST
+ else if ((oriTo == Parameters::East) || (oriTo == Parameters::West)){
+
+ gap1 = pointTo.x() - pointFrom.x();
+ if (oriTo == Parameters::West) gap1 = -gap1;
+ gap2 = pointFrom.y() - pointTo.y();
+
+ if (gap1 > 0.0) {
+ if (gap2 > 0.0) {
+ computeHookSmallEnd(oriFrom,oriTo);
+ }
+ else {
+ computeOpenRect(oriFrom,oriTo);
+ }
+ }
+ else {
+ if (gap2 >= 0.0) {
+ computeCorner(oriFrom);
+ }
+ else {
+ computeHookSmallStart(oriFrom,oriTo);
+ }
+ }
+ }
+ }
+ else if(oriFrom == Parameters::East) {
+ // FROM EAST TO NORTH OR SOUTH
+ if ((oriTo == Parameters::South) || (oriTo == Parameters::North)){
+
+ gap1 = pointFrom.x() - pointTo.x();
+ gap2 = pointFrom.y() - pointTo.y();
+ if (oriTo == Parameters::North) gap2 = -gap2;
+
+ if (gap1 > 0.0) {
+ if (gap2 > 0.0) {
+ computeHookSmallStart(oriFrom,oriTo);
+ }
+ else {
+ computeOpenRect(oriFrom,oriTo);
+ }
+ }
+ else {
+ if (gap2 >= 0.0) {
+ computeCorner(oriFrom);
+ }
+ else {
+ computeHookSmallEnd(oriFrom,oriTo);
+ }
+ }
+ }
+ else if(oriTo == Parameters::East) {
+ computeElle(oriFrom);
+ }
+ else if (oriTo == Parameters::West) {
+ gap1 = pointTo.x() - pointFrom.x();
+ if (gap1 > 2*marginConn) {
+ computeStaircase(oriFrom);
+ }
+ else {
+ computeEsse(oriFrom);
+ }
+ }
+ }
+ else if (oriFrom == Parameters::West) {
+
+ // FROM WEST TO NORTH OR SOUTH
+ if ((oriTo == Parameters::South) || (oriTo == Parameters::North)){
+
+ gap1 = pointTo.x() - pointFrom.x();
+ gap2 = pointFrom.y() - pointTo.y();
+ if (oriTo == Parameters::North) gap2 = -gap2;
+
+ if (gap1 > 0.0) {
+ if (gap2 > 0.0) {
+ computeHookSmallStart(oriFrom,oriTo);
+ }
+ else {
+ computeOpenRect(oriFrom,oriTo);
+ }
+ }
+ else {
+ if (gap2 >= 0.0) {
+ computeCorner(oriFrom);
+ }
+ else {
+ computeHookSmallEnd(oriFrom,oriTo);
+ }
+ }
+ }
+ else if(oriTo == Parameters::East) {
+ gap1 = pointFrom.x() - pointTo.x();
+ if (gap1 > 2*marginConn) {
+ computeStaircase(oriFrom);
+ }
+ else {
+ computeEsse(oriFrom);
+ }
+ }
+ else if (oriTo == Parameters::West) {
+ computeElle(oriFrom);
+ }
+ }
+
+ pps.setWidth(5);
+ pathShape = pps.createStroke(pathPaint);
+}
+
+
+void ConnectionItem::computeEsse(int orientationFrom) {
+
+ //cout << "drawing an esse" << endl;
+ pathPaint = QPainterPath(pointFrom);
+ interPoints.clear();
+ double gap = marginConn;
+ if ((orientationFrom == Parameters::North)||(orientationFrom == Parameters::West)) gap = -gap;
+ QPointF p(0.0,0.0);
+
+ if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
+ // must draw a complete esse
+ p = QPointF(pointFrom.x()+gap,pointFrom.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointFrom.x()+gap,(pointFrom.y()+pointTo.y())/2.0);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x()-gap,(pointFrom.y()+pointTo.y())/2.0);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x()-gap,pointTo.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ }
+ else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
+
+ // must draw a complete esse
+ p = QPointF(pointFrom.x(),pointFrom.y()+gap);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y()+gap);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y()-gap);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x(), pointTo.y()-gap);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ }
+}
+
+void ConnectionItem::computeStaircase(int orientationFrom) {
+
+ pathPaint = QPainterPath(pointFrom);
+ interPoints.clear();
+ QPointF p(0.0,0.0);
+
+ if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
+ if (pointFrom.y() == pointTo.y()) {
+ //cout << "drawing straight line" << endl;
+ pathPaint.lineTo(pointTo);
+ }
+ else {
+ //cout << "drawing a staircase" << endl;
+ // sufficient place to draw a simple staircase
+ p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ }
+ }
+ else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
+ if (pointFrom.x() == pointTo.x()) {
+ //cout << "drawing straight line" << endl;
+ pathPaint.lineTo(pointTo);
+ }
+ else {
+ //cout << "drawing a staircase" << endl;
+ // sufficient place to draw a simple staircase
+ p = QPointF(pointFrom.x(),(pointFrom.y()+pointTo.y())/2.0);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x(),(pointFrom.y()+pointTo.y())/2.0);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ }
+ }
+}
+
+/* drawCorner():
+
+ A Corner has the following shape :
+ |
+ |__
+
+*/
+void ConnectionItem::computeCorner(int orientationFrom) {
+
+ pathPaint = QPainterPath(pointFrom);
+ interPoints.clear();
+ QPointF p(0.0,0.0);
+ //cout << "drawing a corner" << endl;
+
+ if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
+ p = QPointF(pointTo.x(),pointFrom.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ }
+ else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
+ p = QPointF(pointFrom.x(),pointTo.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ }
+}
+
+/* drawOpenRect():
+
+ A OpenRect has the following shape :
+ __
+ |
+ |_|
+*/
+void ConnectionItem::computeOpenRect(int orientationFrom, int orientationTo) {
+ pathPaint = QPainterPath(pointFrom);
+ interPoints.clear();
+ QPointF p(0.0,0.0);
+ double gap1 = marginConn;
+ double gap2 = marginConn;
+ //cout << "drawing an OpenRect" << endl;
+
+ if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
+ if (orientationFrom == Parameters::West) {
+ gap1 = -gap1;
+ }
+ if (orientationTo == Parameters::North) {
+ gap2 = -gap2;
+ }
+ p = QPointF(pointFrom.x()+gap1,pointFrom.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointFrom.x()+gap1,pointTo.y()+gap2);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x(),pointTo.y()+gap2);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+
+ }
+ else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
+ if (orientationFrom == Parameters::North) {
+ gap1 = -gap1;
+ }
+ if (orientationTo == Parameters::West) {
+ gap2 = -gap2;
+ }
+ p = QPointF(pointFrom.x(),pointFrom.y()+gap1);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x()+gap2,pointFrom.y()+gap1);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x()+gap2,pointTo.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ }
+}
+
+/* drawHookSmallEnd():
+
+ A Hook has the following shape :
+ _
+ |
+ |_|
+ Its end has always a size of marginConn
+*/
+void ConnectionItem::computeHookSmallEnd(int orientationFrom, int orientationTo) {
+ pathPaint = QPainterPath(pointFrom);
+ interPoints.clear();
+ QPointF p(0.0,0.0);
+ double gap = marginConn;
+ //cout << "drawing a Hook with small end" << endl;
+
+ if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
+
+ if (orientationTo == Parameters::North) gap = -gap;
+
+ p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y()+gap);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x(),pointTo.y()+gap);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+
+ }
+ else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
+
+ if (orientationTo == Parameters::West) gap = -gap;
+
+ p = QPointF(pointFrom.x(),(pointFrom.y()+pointTo.y())/2.0);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x()+gap,(pointFrom.y()+pointTo.y())/2.0);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x()+gap,pointTo.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ }
+}
+
+/* drawHookSmallStart():
+
+ A Hook has the following shape :
+ _
+ |
+ |_|
+ Its start has always a size of marginConn
+*/
+void ConnectionItem::computeHookSmallStart(int orientationFrom, int orientationTo) {
+ pathPaint = QPainterPath(pointFrom);
+ interPoints.clear();
+ QPointF p(0.0,0.0);
+ double gap = marginConn;
+ //cout << "drawing a Hook with small start" << endl;
+
+ if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
+
+ if (orientationFrom == Parameters::West) gap = -gap;
+
+ p = QPointF(pointFrom.x()+gap,pointFrom.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointFrom.x()+gap,(pointFrom.y()+pointTo.y())/2.0);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x(),(pointFrom.y()+pointTo.y())/2.0);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ }
+ else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
+
+ if (orientationFrom == Parameters::North) gap = -gap;
+
+ p = QPointF(pointFrom.x(),pointFrom.y()+gap);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y()+gap);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ }
+}
+
+/* drawElle():
+
+ An Elle has the following shape :
+ |
+ |_|
+
+*/
+void ConnectionItem::computeElle(int orientationFrom) {
+
+ pathPaint = QPainterPath(pointFrom);
+ interPoints.clear();
+ QPointF p(0.0,0.0);
+ double x;
+ double y;
+ switch(orientationFrom){
+ case Parameters::North :
+ if(pointFrom.y() < pointTo.y()) {
+ y = pointFrom.y()-marginConn;
+ }
+ else {
+ y = pointTo.y()-marginConn;
+ }
+ p = QPointF(pointFrom.x(),y);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x(),y);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ break;
+ case Parameters::South :
+ if(pointFrom.y() > pointTo.y()) {
+ y = pointFrom.y()+marginConn;
+ }
+ else {
+ y = pointTo.y()+marginConn;
+ }
+ p = QPointF(pointFrom.x(),y);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x(),y);
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ break;
+ case Parameters::West :
+ if(pointFrom.x() < pointTo.x()) {
+ x = pointFrom.x()-marginConn;
+ }
+ else {
+ x = pointTo.x()-marginConn;
+ }
+ p = QPointF(x, pointFrom.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(x, pointTo.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ break;
+ case Parameters::East :
+ if(pointFrom.x() > pointTo.x()) {
+ x = pointFrom.x()+marginConn;
+ }
+ else {
+ x = pointTo.x()+marginConn;
+ }
+ p = QPointF(x, pointFrom.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(x, pointTo.y());
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ break;
+ }
+}
+
+void ConnectionItem::setSelected(bool selected) {
+ this->selected = selected;
+ if(selected){
+ setZValue(50);
+ } else {
+ setZValue(0);
+ }
+}
+
+void ConnectionItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
+ QGraphicsItem::mousePressEvent(event);
+ setZValue(zValue()+100);
+ setSelected(!selected);
+ update(boundingRect());
+}
+
+void ConnectionItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
+ QGraphicsItem::mouseReleaseEvent(event);
+ setZValue(zValue()-100);
+}
+
+void ConnectionItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
+ QGraphicsItem::mouseMoveEvent(event);
+}
+
+void ConnectionItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
+ QMenu menu;
+ QAction* removeAction = menu.addAction("Remove");
+ QAction * selectedAction= menu.exec(event->screenPos());
+
+ if(selectedAction == removeAction){
+ dispatcher->removeConnection(this);
+ dispatcher->removeUselessGroupInterfaces();
+ }
+}
+
+void ConnectionItem::prepareChange() {
+ prepareGeometryChange();
+}
+
+QDataStream &operator <<(QDataStream &out, ConnectionItem &c) {
+ out.setVersion(QDataStream::Qt_4_8);
+
+ QByteArray connData;
+ QDataStream toWrite(&connData, QIODevice::WriteOnly);
+
+ toWrite << c.id;
+ toWrite << c.getFromInterfaceItem()->getId();
+ toWrite << c.getToInterfaceItem()->getId();
+
+ out << connData;
+
+ return out;
+}
+
+QDataStream &operator >>(QDataStream &in, ConnectionItem &c) {
+ in.setVersion(QDataStream::Qt_4_8);
+
+ return in;
+}
--- /dev/null
+#ifndef __CONNECTIONITEM_H__
+#define __CONNECTIONITEM_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+#include <QGraphicsItem>
+
+class Dispatcher;
+class Parameters;
+class InterfaceItem;
+
+using namespace std;
+using namespace Qt;
+
+/* NOTES :
+
+ A connection item represent a graphical link between two interface items.
+ Even if it links two in/out interfaces, it is always oriented.
+ The orientation depends on the type and direction of linked interfaces :
+
+ If interfaces are owned by blocks (group or func) that are within the same
+ parent group, then src must be an output, and dest an input, or both are in/out
+ and src/dest may be interchanged.
+
+ If one interface I1 is owend by a block, and the other I2 by the parent group of that block,
+ then they have the same direction. If this direction is input, then src = I2 and dest = I1,
+ if it is output, then src = I1, dest = I2, and if it is in/out, no order matters.
+
+ In order to simplify other methods, the constructor of ConnectionItem
+ checks these cases in order to retrieve the good src and dest if they are
+ not provided in the good order.
+
+ */
+class ConnectionItem : public QGraphicsItem {
+
+public:
+
+ ConnectionItem(InterfaceItem* _iface1,
+ InterfaceItem* _iface2,
+ Dispatcher* _dispatcher,
+ Parameters* _params,
+ QGraphicsItem* _parent);
+ ConnectionItem (const ConnectionItem & copy);
+ ConnectionItem();
+ ~ConnectionItem();
+
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+
+ void prepareChange();
+
+ inline InterfaceItem* getToInterfaceItem(){ return toInterfaceItem; }
+ inline void setToInterfaceItem(InterfaceItem *iface){ toInterfaceItem = iface; }
+ inline InterfaceItem* getFromInterfaceItem(){ return fromInterfaceItem; }
+ inline void setFromInterfaceItem(InterfaceItem* iface){ fromInterfaceItem = iface; }
+ inline int getId(){ return id; }
+ inline void setId(int id){ this->id = id; }
+ inline bool isSelected() { return selected; }
+ void setSelected(bool selected);
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+ void setPathes();
+ void addInterPoint(QPointF point);
+
+ static int counter;
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
+
+private:
+
+ QPointF pointFrom;
+ QPointF pointTo;
+ QList<QPointF> interPoints;
+ QPointF interPoint1;
+ QPointF interPoint2;
+ QPointF interPoint3;
+ QPointF interPoint4;
+
+ QPainterPath pathPaint;
+ QPainterPath pathShape;
+ QPainterPathStroker pps;
+ Dispatcher* dispatcher;
+ Parameters* params;
+ InterfaceItem* fromInterfaceItem;
+ InterfaceItem* toInterfaceItem;
+ bool selected;
+ int id;
+ int marginConn;
+ void computeEsse(int orientationFrom);
+ void computeStaircase(int orientationFrom);
+ void computeHookSmallEnd(int orientationFrom, int orientationTo);
+ void computeHookSmallStart(int orientationFrom, int orientationTo);
+ void computeOpenRect(int orientationFrom, int orientationTo);
+ void computeElle(int orientationFrom);
+ void computeCorner(int orientationFrom);
+
+ friend QDataStream &operator << (QDataStream &out, ConnectionItem &c);
+ friend QDataStream &operator >> (QDataStream &in, ConnectionItem &c);
+};
+
+#endif //
--- /dev/null
+#include "Dispatcher.h"
+#include "Parameters.h"
+#include "MainWindow.h"
+
+#include "Graph.h"
+#include "ReferenceBlock.h"
+#include "GroupBlock.h"
+#include "FunctionalBlock.h"
+
+#include "ConnectedInterface.h"
+#include "ReferenceInterface.h"
+#include "GroupInterface.h"
+#include "FunctionalInterface.h"
+
+#include "GroupWidget.h"
+#include "GroupScene.h"
+#include "GroupItem.h"
+#include "BoxItem.h"
+#include "InterfaceItem.h"
+#include "ConnectionItem.h"
+
+#include "BlockLibraryWidget.h"
+#include "BlockLibraryTree.h"
+
+#include "InterfacePropertiesWindow.h"
+
+
+Dispatcher::Dispatcher(Parameters* _params, MainWindow* _window) {
+ params = _params;
+ mainWindow =_window;
+ params->setDispatcher(this);
+ currentGroup = NULL;
+ topGroup = NULL;
+}
+
+GroupWidget *Dispatcher::loadProject(const QString& filename) {
+
+ QDomElement root;
+ try {
+ root = params->openProjectFile(filename);
+ }
+ catch(Exception err) {
+ return NULL;
+ }
+
+ // creating the top widget/scene
+ topGroup = new GroupWidget(NULL,this,params);
+ currentGroup = topGroup;
+ // getting the newly created scene
+ GroupScene *scene = topGroup->getScene();
+ params->setTopScene(scene);
+ params->setCurrentScene(scene);
+
+ try {
+ params->loadProject(root);
+ }
+ catch(Exception e){
+ cerr << qPrintable(e.getDefaultMessage()) << endl;
+ cerr << "Aborting ..." << endl;
+ // TO DO : deleteting topGroup and all
+ return NULL;
+ }
+
+ return topGroup;
+}
+
+void Dispatcher::closeCurrentProject() {
+
+ foreach(GroupWidget* win, groupList) {
+ win->deleteLater();
+ }
+ params->destroyGraph();
+}
+
+bool Dispatcher::connect(InterfaceItem *iface1, InterfaceItem *iface2) {
+
+ ConnectedInterface* ref1 = iface1->refInter;
+ ConnectedInterface* ref2 = iface2->refInter;
+ // connect both interface
+
+ bool ok1 = false;
+ bool ok2 = false;
+
+ if (ref1->canConnectTo(ref2)) {
+ ok1 = ref1->connectTo(ref2);
+ ok1 = ok1 & ref2->connectFrom(ref1);
+ }
+ if (ref2->canConnectTo(ref1)) {
+ ok2 = ref2->connectTo(ref1);
+ ok2 = ok2 & ref1->connectFrom(ref2);
+ }
+ if ((ok1 == true) || (ok2 == true)) {
+
+ iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2);
+
+ unselectAllItems();
+ params->unsaveModif = true;
+ return true;
+ }
+ return false;
+}
+
+void Dispatcher::checkSelection(){
+ InterfaceItem *iface1 = NULL;
+ InterfaceItem *iface2 = NULL;
+
+ GroupScene *scene = params->getCurrentScene();
+ QList<AbstractBoxItem*> list = scene->getGroupAndBlocks();
+ foreach(AbstractBoxItem *block, list){
+ InterfaceItem *tmp = block->getCurrentInterface();
+ if (tmp != NULL) {
+ if (iface1 == NULL) {
+ iface1 = tmp;
+ }
+ else {
+ iface2 = tmp;
+ }
+ }
+ }
+ if(iface1 != NULL && iface2 != NULL){
+ connect(iface1,iface2);
+ }
+}
+
+void Dispatcher::unselectAllItems(int direction){
+
+ GroupScene *scene = params->getCurrentScene();
+
+ foreach(BoxItem* block, scene->getBlockItems()) {
+ block->setSelected(false);
+ block->setCurrentInterface(NULL);
+ }
+ scene->unselecteInterfaces();
+ scene->update();
+}
+
+void Dispatcher::setCurrentGroupWidget(GroupWidget *win){
+ win->setFocus();
+ win->changeConnectionMode(-1);
+ currentGroup = win;
+ params->setCurrentScene(win->getScene());
+}
+
+void Dispatcher::changeConnectionMode(int mode){
+
+ /*
+ foreach(GroupWidget* win, groupList){
+
+ QToolButton* buttonNewConnection = win->getButtonNewConnection();
+
+ QPalette pal = buttonNewConnection->palette();
+
+ if(mode == -1){
+ if(params->sceneMode != Parameters::EditOnConnection){
+ params->sceneMode = Parameters::EditOnConnection;
+ pal.setColor(QPalette::Button, QColor(Qt::lightGray));
+ } else {
+ params->sceneMode = Parameters::EditNoOperation;
+ pal.setColor(QPalette::Button, QColor("#edeceb"));
+ }
+ }
+ else if(mode == Parameters::EditOnConnection){
+ params->sceneMode = Parameters::EditOnConnection;
+ pal.setColor(QPalette::Button, QColor(Qt::lightGray));
+ }
+ else {
+ params->sceneMode = Parameters::EditNoOperation;
+ pal.setColor(QPalette::Button, QColor("#edeceb"));
+ }
+ unselectAllInterfaces();
+
+ buttonNewConnection->setAutoFillBackground(true);
+ buttonNewConnection->setPalette(pal);
+ buttonNewConnection->update();
+ }
+ */
+}
+
+void Dispatcher::rename(AbstractBoxItem *item){
+
+ bool ok;
+ QString text = QInputDialog::getText(NULL, "Rename an element",
+ "New name:", QLineEdit::Normal,
+ item->getRefBlock()->getName(), &ok);
+
+ if(ok){
+ if(!text.isEmpty() && text.length() < 30){
+ item->getRefBlock()->setName(text);
+ if(item->isGroupItem()){
+ if (currentGroup->isTopGroup()) {
+ mainWindow->setWindowTitle("blast - "+text);
+ }
+ else {
+ currentGroup->setWindowTitle("blast - "+text);
+ }
+ }
+ }
+ else {
+ QMessageBox::warning(NULL,"Error in given name",
+ "the element name must be shorter than 30 characters and can't be empty!",
+ QMessageBox::Ok);
+ rename(item);
+ }
+ }
+}
+
+void Dispatcher::rename(InterfaceItem *item){
+ bool ok;
+ QString text = QInputDialog::getText(NULL, "Rename an interface",
+ "New name:", QLineEdit::Normal,
+ item->refInter->getName(), &ok);
+
+ /* CAUTION: when renaming an interface item, there are two cases :
+ - it refers to a functional block interface (fbi): the fbi keeps its name
+ and the new name is given to item
+ - it refers to a group block interface (gbi) : both gbi and item store the new name
+
+ */
+ if(ok && !text.isEmpty() && text.length() < 30) {
+ if (item->refInter->getOwner()->isGroupBlock()) {
+ item->refInter->setName(text);
+ }
+ item->setName(text);
+ }
+ else {
+ QMessageBox::warning(NULL,"Error in given name",
+ "the interface name must be shorter than 30 characters and can't be empty!",
+ QMessageBox::Ok);
+ rename(item);
+ }
+}
+
+void Dispatcher::duplicateBlock(BoxItem *item){
+
+ GroupScene *scene = params->getCurrentScene();
+ AbstractBlock* block = item->getRefBlock();
+ AbstractBlock *newBlock;
+
+ // only duplicate functional blocks
+ if(block->isFunctionalBlock()) {
+
+ // adding to the model
+ FunctionalBlock* funBlock = (FunctionalBlock*)block;
+ newBlock = params->duplicateFunctionalBlock(funBlock);
+ // adding to the view
+ scene->createBlockItem(newBlock);
+
+ params->unsaveModif = true;
+ }
+}
+
+void Dispatcher::duplicateInterface(InterfaceItem *item){
+ AbstractInterface *refI = item->refInter;
+ if (! refI->isFunctionalInterface()) return;
+
+ AbstractBlock *refB = refI->getOwner();
+ if(! refB->isFunctionalBlock()) return;
+
+ FunctionalInterface* iface = (FunctionalInterface*)refI;
+ AbstractInterface *otherRef = iface->clone();
+ if (otherRef == NULL) {
+ QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
+ return;
+ }
+
+ refB->addInterface(otherRef);
+
+ InterfaceItem *otherIface = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)otherRef,item->getOwner(),params);
+ item->getOwner()->addInterface(otherIface,true);
+}
+
+
+void Dispatcher::addBlock(int idCategory, int idBlock) {
+
+ GroupScene *scene = params->getCurrentScene();
+ FunctionalBlock* newOne = params->addFunctionalBlock(idCategory, idBlock);
+ scene->createBlockItem(newOne);
+}
+
+
+GroupWidget *Dispatcher::createTopScene(){
+
+ // creating the model part of the group
+ Graph* graph = params->createGraph();
+ GroupBlock *refBlock = graph->getTopGroup();
+
+ // creating a fake and not connected interface
+ //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
+
+ // creating the group widget
+ topGroup = new GroupWidget(NULL,this,params);
+ currentGroup = topGroup;
+ // getting the newly created scene
+ GroupScene *scene = topGroup->getScene();
+ params->setTopScene(scene);
+ params->setCurrentScene(scene);
+ // creating the view part of the group
+ GroupItem *group = new GroupItem(NULL,refBlock,this,params);
+
+ // adding the fake interface to the top group item
+ //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
+ //group->addInterface(item,true);
+
+ scene->setGroupItem(group);
+
+ return topGroup;
+}
+
+GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
+
+ GroupBlock* parentBlock = NULL;
+ if (upperItemOfGroupItem != NULL) {
+ parentBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
+ }
+ // creating the model part of the group
+ GroupBlock *groupBlock = new GroupBlock(parentBlock);
+ groupBlock->setName("no name");
+ // 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();
+ // affecting group item to the scene
+ scene->setGroupItem(groupItem);
+
+ return group;
+}
+
+void Dispatcher::showRaiseWindow(AbstractBoxItem *item) {
+ GroupWidget* win = item->getScene()->getGroupWindow();
+ if (win->isTopGroup()) {
+ mainWindow->show();
+ mainWindow->raise();
+ }
+ else {
+ win->show();
+ win->raise();
+ }
+ currentGroup = win;
+ params->setCurrentScene(currentGroup->getScene());
+}
+
+void Dispatcher::showRstClkInter(AbstractBoxItem *item) {
+
+ item->setRstClkVisible(!item->isRstClkVisible());
+ item->resetInterfacesPosition();
+
+ item->getScene()->updateConnectionItemsShape();
+}
+
+void Dispatcher::addNewFullGroup() {
+
+#ifdef DEBUG_INCLFUN
+
+ QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
+ QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
+ QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
+
+ /* What must be done:
+ 1 - creating a new GroupBlock
+ 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
+ 3 - creating a BlockItem that references the new GroupBlock
+ 4 - creating a new GroupWidget
+ 5 - creating a new GroupItem added to the scene of the GroupWidget
+
+ */
+
+ /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
+ associated to the GroupItem of the current scene
+ */
+ GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
+ GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
+ /* step 2: moving selected blocks */
+ foreach(BlockItem* blockItem, listBlocks) {
+ parentBlock->removeBlock(blockItem->getRefBlock());
+ newGroupBlock->addBlock(blockItem->getRefBlock());
+ }
+
+ GroupItem *parent = currentGroup->getScene()->getGroupItem();
+ GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
+ BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
+ GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
+
+ //create the new window
+ GroupWidget* win = new GroupWidget(this,params);
+ win->getScene()->setGroupItem(groupItem);
+ win->getScene()->addItem(groupItem);
+ ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
+ params->addWindow(win);
+ win->show();
+
+ //add the new group
+ params->getCurrentScene()->addBlockItem(blockItem);
+ params->getCurrentScene()->addItem(blockItem);
+ ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
+
+ //replace selected blocks in the group
+ foreach(AbstractBoxItem *block, listBlocks){
+ ((GroupItem*)block->getParentItem())->removeBlockItem(block);
+ ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
+ params->getCurrentScene()->removeItem(block);
+ params->getCurrentScene()->removeBlockItem(block);
+
+ groupBlock->addBlock(block->getRefBlock());
+ listAbstractBlocks.append(block->getRefBlock());
+
+ block->setUpperItem(groupItem);
+ groupItem->addBlockItem(block);
+ win->getScene()->addItem(block);
+ win->getScene()->addBlockItem(block);
+ }
+
+ //replace connection between selected blocks in the group
+ foreach(ConnectionItem *conn, connections){
+ if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
+ if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
+ parent->removeConnection(conn);
+ params->getCurrentScene()->removeItem(conn);
+
+ groupItem->addConnection(conn);
+ win->getScene()->addItem(conn);
+ }
+ }
+ }
+
+ //create new interfaces and connections for the new group
+ foreach(AbstractBoxItem *block, listBlocks){
+ foreach(InterfaceItem *inter, block->getInterfaces()){
+ cout << "inter : " << inter->getName().toStdString() << endl;
+ if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
+ cout << "connected from non null" << endl;
+ if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
+
+ AbstractInterface *iface = inter->refInter->clone(0);
+ iface->setName(iface->getName()+"_group");
+ groupBlock->addInterface(iface);
+
+ InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
+ blockItem->addInterface(ifaceItem);
+ blockItem->resetInterfacesPosition();
+
+ InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
+ groupItem->addInterface(ifaceGroupItem);
+ groupItem->resetInterfacesPosition();
+ foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
+ if(conn->getToInterfaceItem() == inter){
+ conn->setToInterfaceItem(ifaceItem);
+ ifaceItem->refInter->setConnectedFrom(NULL);
+ conn->getFromInterfaceItem()->refInter->clearConnectedTo();
+ connect(ifaceItem,conn->getFromInterfaceItem());
+ }
+ }
+ params->setCurrentWindow(win);
+
+ inter->refInter->setConnectedFrom(NULL);
+ ifaceGroupItem->refInter->clearConnectedTo();
+ connect(inter,ifaceGroupItem);
+ params->setCurrentWindow(mainWindow);
+ }
+ }
+
+ if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
+ cout << "connected to non null" << endl;
+ foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
+ if(!listAbstractBlocks.contains(iface->getOwner())){
+
+ AbstractInterface *iface = inter->refInter->clone(0);
+ iface->setName(iface->getName()+"_group");
+ groupBlock->addInterface(iface);
+
+ InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
+ blockItem->addInterface(ifaceItem);
+ blockItem->resetInterfacesPosition();
+
+ foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
+ if(conn->getFromInterfaceItem() == inter){
+ conn->setFromInterfaceItem(ifaceItem);
+ iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
+ conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
+ }
+ }
+
+ InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
+ groupItem->addInterface(ifaceGroupItem);
+ groupItem->resetInterfacesPosition();
+ inter->refInter->clearConnectedTo();
+ ifaceGroupItem->refInter->setConnectedFrom(NULL);
+ connect(ifaceGroupItem,inter);
+ }
+ }
+ }
+ }
+ }
+
+ //update window
+
+ parent->updateShape();
+ currentGroup->getScene()->updateConnectionItemsShape();
+ currentGroup = win;
+ groupItem->updateShape();
+ win->getScene()->updateConnectionItemsShape();
+ groupItem->update(groupItem->boundingRect());
+
+#endif
+}
+
+void Dispatcher::removeBlock(AbstractBoxItem *item) {
+
+#ifdef DEBUG_INCLFUN
+
+ GroupScene *scene = params->getCurrentScene();
+ AbstractBlock* block = item->getRefBlock();
+ if (block->isReferenceBlock()) return;
+
+ GroupBlock* group = (GroupBlock*)item->getParentItem()->getRefBlock();
+
+ removeConnections(item);
+
+ //récupérer l'objet
+ group->removeBlock(block);
+
+ //remove the associated window
+ if(block->isGroupBlock()){
+ foreach(QWidget *window, params->windows){
+ if(!window->inherits("MainWindow")){
+ if(((GroupWidget*)window)->getScene()->getGroupItem()->getRefBlock() == block){
+ params->removeWindow(window);
+ delete window;
+ }
+ }
+ }
+ }
+
+ delete block;
+
+ //supprimer l'item de la scène
+ cout << "dispatcher : remove item of scene " << params->currentWindow << endl;
+ ((GroupItem *)scene->getGroupItem())->removeBlockItem(item);
+ scene->removeItem(item);
+ scene->removeBlockItem(item);
+ delete item;
+
+ ((GroupItem *)scene->getGroupItem())->updateShape();
+
+ params->updateToolbar();
+ params->unsaveModif = true;
+
+#endif
+}
+
+void Dispatcher::removeAllBlockConnections(AbstractBoxItem *block) {
+
+ GroupScene* scene = block->getScene();
+ // supprimer les connections associées au bloc
+ foreach (ConnectionItem *conn, scene->getConnectionItems()) {
+ if(conn->getToInterfaceItem()->owner == block || conn->getFromInterfaceItem()->owner == block){
+ removeConnection(conn);
+ }
+ }
+ scene->getGroupItem()->updateInterfacesAndConnections();
+}
+
+void Dispatcher::removeConnection(ConnectionItem *conn) {
+
+ GroupScene *scene = params->getCurrentScene();
+ GroupItem* currentGroup = scene->getGroupItem();
+
+ conn->getFromInterfaceItem()->unconnectTo(conn->getToInterfaceItem());
+
+ scene->removeConnectionItem(conn);
+ delete conn;
+
+ currentGroup->updateInterfacesAndConnections();
+ params->unsaveModif = true;
+}
+
+void Dispatcher::removeUselessGroupInterfaces() {
+
+ GroupScene *scene = params->getCurrentScene();
+ GroupItem* currentGroup = scene->getGroupItem();
+
+ foreach(InterfaceItem *inter, currentGroup->getInterfaces()) {
+ if(inter->refInter->getConnectedTo().length() == 0) {
+ // NB : remove from view also remove from model
+ currentGroup->removeInterface(inter);
+ }
+ }
+ scene->updateConnectionItemsShape();
+}
+
+void Dispatcher::showBlocksLibrary(){
+ cout << "showing block library" << endl;
+ mainWindow->getLibrary()->show();
+ mainWindow->getLibrary()->raise();
+}
+
+void Dispatcher::showProperties(InterfaceItem *inter)
+{
+ new InterfacePropertiesWindow(inter);
+}
+
+/* connectInterToGroup() :
+ The only way for a block (functional of group) within a GroupItem to be connected
+ to the latter is to right-click on one of its interfaces and to choose "connect to group".
+ That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
+ interfaces.
+*/
+void Dispatcher::connectInterToGroup(InterfaceItem *item){
+
+ // getting the GroupBlock and GroupItem that are parent of the block that owns item
+ ConnectedInterface *refInter = item->refInter;
+ GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
+ GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
+
+ // creating/adding the group interface in the graph model
+ GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getLevel());
+ groupInter->setType(refInter->getType());
+ groupInter->setWidth(refInter->getWidth());
+ groupInter->setPurpose(refInter->getPurpose());
+ parentItem->getRefBlock()->addInterface(groupInter);
+
+ // connect both interface
+ bool ok = true;
+ if (refInter->getDirection() == AbstractInterface::Output) {
+ ok = refInter->connectTo(groupInter);
+ ok = ok & groupInter->connectFrom(refInter);
+ }
+ else if (refInter->getDirection() == AbstractInterface::Input) {
+ ok = groupInter->connectTo(refInter);
+ ok = ok & refInter->connectFrom(groupInter);
+ }
+ else if (refInter->getDirection() == AbstractInterface::InOut) {
+ ok = refInter->connectTo(groupInter);
+ ok = ok & groupInter->connectFrom(refInter);
+ ok = ok & groupInter->connectTo(refInter);
+ ok = ok & refInter->connectFrom(groupInter);
+ }
+ if (!ok) {
+ cerr << "abnormal case while connecting a block iface to its parent group" << endl;
+ }
+ // creating/adding the group interface in the current scene model, and connection item
+ InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
+ parentItem->addInterface(groupIfaceItem,true);
+
+ parentItem->getScene()->createConnectionItem(item, groupIfaceItem);
+
+ // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
+ BoxItem* parent2Item = parentItem->getParentItem();
+ if(parent2Item != NULL){
+ InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
+ parent2Item->addInterface(blockIfaceItem,true);
+ }
+
+
+ parentItem->getScene()->updateConnectionItemsShape();
+ unselectAllItems();
+ params->unsaveModif = true;
+
+
+}
+
+void Dispatcher::disconnectInterFromGroup(InterfaceItem *item) {
+ static QString fctName = "Dispatcher::disconnectInterFromGroup()";
+#ifdef DEBUG_FCTNAME
+ cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
+ // getting the GroupBlock and GroupItem that are parent of the block that owns item
+ ConnectedInterface *refInter = item->refInter;
+ ConnectedInterface *groupInter = NULL;
+ GroupBlock* parentGroup = AB_TO_GRP(refInter->getOwner()->getParent());
+ GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
+
+ // removing the connection from graph
+#ifdef DEBUG
+ cout << "removing connections from graph ..." ;
+#endif
+
+ if (refInter->getDirection() == AbstractInterface::Output) {
+ groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
+ refInter->clearConnectedTo();
+ groupInter->clearConnectedFrom();
+ }
+ else if (refInter->getDirection() == AbstractInterface::Input) {
+ groupInter = refInter->getConnectedFrom();
+ refInter->clearConnectedFrom();
+ groupInter->clearConnectedTo();
+ }
+ else if (refInter->getDirection() == AbstractInterface::InOut) {
+ groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
+ refInter->clearConnectedTo();
+ refInter->clearConnectedFrom();
+ groupInter->clearConnectedTo();
+ groupInter->clearConnectedFrom();
+ }
+#ifdef DEBUG
+ cout << "done." << endl ;
+#endif
+
+ if (groupInter == NULL) {
+ cerr << "abnormal case 1 while removing an interface item of a block, linked to a parent group" << endl;
+ }
+
+#ifdef DEBUG
+ cout << "getting group interface item, and connection item ..." ;
+#endif
+
+
+ InterfaceItem* groupIfaceItem = parentItem->searchInterfaceByRef(groupInter);
+ if (groupIfaceItem == NULL) {
+ cerr << "abnormal case 2 while removing an interface item of a block, linked to a parent group" << endl;
+ }
+ ConnectionItem* conn = parentItem->getScene()->searchConnectionItem(item,groupIfaceItem);
+ if (conn == NULL) {
+ cerr << "abnormal case 3 while removing an interface item of a block, linked to a parent group" << endl;
+ }
+#ifdef DEBUG
+ cout << "done." << endl ;
+#endif
+
+ // removing the interface group item from the group item, and the connection item
+#ifdef DEBUG
+ cout << "removing group interface item, and connection item ..." ;
+#endif
+
+ item->removeConnectionItem(conn);
+ groupIfaceItem->removeConnectionItem(conn);
+ parentItem->removeInterface(groupIfaceItem); // CAUTION : this deletes the interface item.
+ parentItem->getScene()->removeConnectionItem(conn);
+#ifdef DEBUG
+ cout << "done." << endl ;
+#endif
+
+ // removing the interface box item in the parent scene
+#ifdef DEBUG
+ cout << "removing the inteeface item of box item in parent scene if needed ..." ;
+#endif
+
+ BoxItem* parent2Item = parentItem->getParentItem();
+ if (parent2Item != NULL) {
+ InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
+ parent2Item->removeInterface(group2IfaceItem);
+ }
+#ifdef DEBUG
+ cout << "done." << endl ;
+#endif
+
+ // removing the interface group from the group
+#ifdef DEBUG
+ cout << "removing group interface ..." ;
+#endif
+ parentGroup->removeInterface(groupInter);
+#ifdef DEBUG
+ cout << "done." << endl ;
+#endif
+
+}
+
+void Dispatcher::removeGroupInterface(InterfaceItem *item) {
+ static QString fctName = "Dispatcher::removeGroupInterface()";
+#ifdef DEBUG_FCTNAME
+ cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
+ /* NB: there is a single connection between item and another one that is owned
+ by a BoxItem. Thus, we just have to find it and to call disconnectInterFromGroup();
+ */
+ ConnectionItem* conn = item->connections.at(0);
+ if (conn->getFromInterfaceItem() == item) {
+ disconnectInterFromGroup(conn->getToInterfaceItem());
+ }
+ else {
+ disconnectInterFromGroup(conn->getFromInterfaceItem());
+ }
+}
+
+GroupScene* Dispatcher::searchSceneById(int id) {
+ foreach(GroupWidget *group, groupList){
+ if(group->getScene()->getId() == id)
+ return group->getScene();
+ }
+ cout << "search scene by id :" << id << " :: not found..." << endl;
+ return NULL;
+}
+
+GroupItem *Dispatcher::searchGroupItemById(int id) {
+ foreach(GroupWidget *group, groupList) {
+ GroupScene* scene = group->getScene();
+ if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
+ }
+ cout << "search GroupItem by id :" << id << " :: not found..." << endl;
+ return NULL;
+}
+
+BoxItem *Dispatcher::searchBlockItemById(int id) {
+ foreach(GroupWidget *group, groupList) {
+
+ GroupScene* scene = group->getScene();
+ foreach(BoxItem *item, scene->getBlockItems()){
+ if(item->getId() == id){
+ return item;
+ }
+ }
+ }
+ cout << "search BlockItem by id :" << id << " :: not found..." << endl;
+ return NULL;
+}
+
+InterfaceItem* Dispatcher::searchInterfaceItemById(int id) {
+
+ foreach(GroupWidget *group, groupList) {
+
+ GroupScene* scene = group->getScene();
+
+ foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
+ if(item->getId() == id){
+ return item;
+ }
+ }
+ foreach(BoxItem *block, scene->getBlockItems()){
+ foreach(InterfaceItem *item, block->getInterfaces()){
+ if(item->getId() == id){
+ return item;
+ }
+ }
+ }
+ }
+ cout << "search interface by id :" << id << " :: not found..." << endl;
+ return NULL;
+}
+
--- /dev/null
+#ifndef __DISPATCHER_H__
+#define __DISPATCHER_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtWidgets>
+
+class Graph;
+class Parameters;
+class MainWindow;
+class GroupWidget;
+class GroupScene;
+class AbstractBoxItem;
+class GroupItem;
+class BoxItem;
+class ConnectionItem;
+class InterfaceItem;
+
+
+
+using namespace std;
+using namespace Qt;
+
+class Dispatcher {
+
+public:
+ Dispatcher(Parameters* _params,
+ MainWindow* _window);
+
+ GroupWidget* loadProject(const QString& filename);
+
+ inline int getNumberOfScenes() { return groupList.length(); }
+ bool connect(InterfaceItem *iface1, InterfaceItem *iface2);
+ void checkSelection();
+ void unselectAllItems(int direction=0);
+ void setCurrentGroupWidget(GroupWidget *win);
+ void changeConnectionMode(int mode = -1);
+ void rename(AbstractBoxItem* item);
+ void rename(InterfaceItem* item);
+ GroupWidget* createTopScene();
+ GroupWidget* createChildScene(GroupWidget* parentWidget, BoxItem* upperItemOfGroupItem = NULL);
+ void showRaiseWindow(AbstractBoxItem *item);
+ void showRstClkInter(AbstractBoxItem *item);
+ void addNewFullGroup();
+
+ inline GroupWidget* getCurrentGroup() { return currentGroup; }
+
+ bool isCurrentProject;
+
+public slots:
+
+ GroupScene* searchSceneById(int id);
+ BoxItem* searchBlockItemById(int id);
+ GroupItem* searchGroupItemById(int id);
+ InterfaceItem* searchInterfaceItemById(int id);
+
+ void removeBlock(AbstractBoxItem* item);
+ void duplicateBlock(BoxItem* item);
+ void duplicateInterface(InterfaceItem* item);
+ void addBlock(int idCategory, int idBlock);
+ ConnectionItem *addConnection(InterfaceItem *input, InterfaceItem *output);
+ void removeAllBlockConnections(AbstractBoxItem *block);
+ void removeConnection(ConnectionItem *conn);
+ void removeUselessGroupInterfaces();
+ void showBlocksLibrary();
+ void showProperties(InterfaceItem *inter);
+ void connectInterToGroup(InterfaceItem* item);
+ void disconnectInterFromGroup(InterfaceItem* item);
+ void removeGroupInterface(InterfaceItem* item);
+
+ void addConnection();
+
+ void closeCurrentProject();
+
+private:
+
+ // the model
+ Parameters* params;
+
+ // attributes that corresponds to the views
+ MainWindow* mainWindow;
+ QList<GroupWidget*> groupList;
+ GroupWidget* currentGroup;
+ GroupWidget *topGroup;
+};
+
+#endif // __DISPATCHER_H__
--- /dev/null
+#include "Exception.h"
+
+Exception::Exception(int _id) {
+ id = _id;
+ message = getDefaultMessage();
+}
+
+
+Exception::Exception(const Exception& other) {
+ id = other.id;
+ message = other.message;
+}
+
+QString Exception::getDefaultMessage() {
+ QString ret="";
+ switch(id) {
+ case CONFIGFILE_CORRUPTED : ret = tr("Blast configuration file is corrupted"); break;
+ case CONFIGFILE_NOACCESS : ret = tr("Blast configuration file cannot be read"); break;
+ case PROJECTFILE_CORRUPTED : ret = tr("Project file is corrupted"); break;
+ case PROJECTFILE_NOACCESS : ret = tr("Project file cannot be read"); break;
+ case BLOCKPATH_NOACCESS : ret = tr("Directory containing references cannot be accessed (no rights/existence)"); break;
+ case IMPLPATH_NOACCESS : ret = tr("Directory containing implementations cannot be accessed (no rights/existence)"); break;
+ case BLOCKFILE_CORRUPTED : ret = tr("Block file is corrupted"); break;
+ case BLOCKFILE_NOACCESS : ret = tr("Block file cannot be read"); break;
+ case IMPLFILE_CORRUPTED : ret = tr("Implementation file is corrupted"); break;
+ case IMPLFILE_NOACCESS : ret = tr("Implementation file cannot be read"); break;
+ case BLOCK_NULL : ret = tr("A parameter of type AbstractBlock* has been provided with NULL value."); break;
+ case BLOCK_INVALID_TYPE : ret = tr("A parameter of type AbstractBlock* is used with an incorrect instance type."); break;
+ case IFACE_NULL : ret = tr("A parameter of type AbstractInterface* has been provided with NULL value."); break;
+ case IFACE_INVALID_TYPE : ret = tr("A parameter of type AbstractInterface* is used with an incorrect instance type."); break;
+ case IFACE_MULTIPLICITY_REACHED : ret = tr("Impossible to create another instance of a GraphInterface: the maximum multiplicity is reached."); break;
+ case BLOCKITEM_NULL : ret = tr("A parameter of type AbstractBlockItem* has been provided with NULL value."); break;
+ case BLOCKITEM_INVALID_TYPE : ret = tr("A parameter of type AbstractBlockItem* is used with an incorrect instance type."); break;
+ case WIDTHS_NOT_EQUALS : ret = tr("Two interfaces are connected but don't have the same widths."); break;
+ case INVALID_VALUE : ret = tr("parameter value is not correct (e.g. not numeric, invalid other parameter name, ...)."); break;
+ }
+
+ return ret;
+}
--- /dev/null
+/*-==============================================================-
+
+file : Exception.h
+
+creation date : 08/04/2015
+
+author : S. Domas (sdomas@iut-bm.univ-fcomte.fr)
+
+description :
+
+supp. infos : saved in UTF-8 [éè]
+
+-==============================================================-*/
+#ifndef __EXCEPTION_H__
+#define __EXCEPTION_H__
+
+#include <iostream>
+#include <fstream>
+
+#include <QtCore>
+
+// exceptions for file accesses
+#define CONFIGFILE_NOACCESS 1
+#define CONFIGFILE_CORRUPTED 2
+
+#define PROJECTFILE_NOACCESS 3
+#define PROJECTFILE_CORRUPTED 4
+
+#define BLOCKPATH_NOACCESS 5
+#define IMPLPATH_NOACCESS 6
+
+#define BLOCKFILE_NOACCESS 7
+#define BLOCKFILE_CORRUPTED 8
+
+#define IMPLFILE_NOACCESS 9
+#define IMPLFILE_CORRUPTED 10
+
+#define VHDLFILE_NOACCESS 11
+
+// exceptions for block manipulations
+#define BLOCK_NULL 100
+#define BLOCK_INVALID_TYPE 101
+
+// exceptions for interfaces manipulations
+#define IFACE_NULL 200
+#define IFACE_INVALID_TYPE 201
+#define IFACE_MULTIPLICITY_REACHED 202
+
+// exceptions for block items manipulations
+#define BLOCKITEM_NULL 300
+#define BLOCKITEM_INVALID_TYPE 301
+
+// exceptions for width interfaces validation
+#define WIDTHS_NOT_EQUALS 400
+
+// exceptions for VHDL generation
+#define INVALID_VALUE 500
+
+using namespace std;
+using namespace Qt;
+
+class Exception : public QObject {
+
+public:
+
+ Exception(int _id);
+ Exception(const Exception& other);
+
+ inline int getType() { return id; }
+ inline void setMessage(QString _message) { message = _message; }
+ inline QString getMessage() { return message; }
+ QString getDefaultMessage();
+
+private:
+ int id;
+ QString message;
+
+};
+
+#endif //__EXCEPTION_H__
--- /dev/null
+#include "FunctionalBlock.h"\r
+#include "ReferenceBlock.h"\r
+#include "GroupBlock.h"\r
+#include "AbstractInterface.h"\r
+#include "FunctionalInterface.h"\r
+#include "ReferenceInterface.h"\r
+#include "BlockParameter.h"\r
+\r
+\r
+FunctionalBlock::FunctionalBlock(GroupBlock *_parent, ReferenceBlock *_reference) throw(Exception) : AbstractBlock() {\r
+ //if (! _reference->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));\r
+ //if (! _group->isGroupBlock()) throw(Exception(BLOCK_INVALID_TYPE));\r
+ reference = _reference;\r
+ parent = _parent;\r
+ name = reference->getName();\r
+}\r
+\r
+\r
+void FunctionalBlock::parametersValidation(QList<AbstractBlock*>* checkedBlocks, QList<AbstractBlock *> *blocksToConfigure) {\r
+ /*\r
+ checkedBlocks->append(this);\r
+\r
+ foreach(BlockParameter* param, params){\r
+ if(param->isUserParameter() && !param->isValueSet()){\r
+ if(!blocksToConfigure->contains(param->getOwner())){\r
+ blocksToConfigure->append(param->getOwner());\r
+ }\r
+ }\r
+ }\r
+ foreach(AbstractInterface *inter, outputs){\r
+ foreach(AbstractInterface *connectedInter, inter->getConnectedTo()){\r
+ if(!checkedBlocks->contains(connectedInter->getOwner())){\r
+ connectedInter->getOwner()->parametersValidation(checkedBlocks, blocksToConfigure);\r
+ }\r
+ }\r
+ }\r
+ */\r
+}\r
+\r
+bool FunctionalBlock::isFunctionalBlock() {\r
+ return true;\r
+}\r
+\r
+void FunctionalBlock::populate() {\r
+ int i;\r
+ BlockParameter* p;\r
+ AbstractInterface* inter;\r
+\r
+ QList<BlockParameter*> lstParam = reference->getParameters();\r
+ for(i=0;i<lstParam.size();i++) {\r
+ p = lstParam.at(i)->clone();\r
+ addParameter(p);\r
+ }\r
+\r
+ QList<AbstractInterface *> lstInter = reference->getInterfaces();\r
+ for(i=0;i<lstInter.size();i++) {\r
+ try {\r
+ inter = new FunctionalInterface(this, (ReferenceInterface*)lstInter.at(i));\r
+ }\r
+ catch(Exception e) {\r
+ cerr << "Abnormal case: " << qPrintable(e.getDefaultMessage()) << endl << "Aborting execution." << endl;\r
+ exit(1);\r
+ }\r
+\r
+ addInterface(inter);\r
+ }\r
+\r
+}\r
+\r
+\r
+QString FunctionalBlock::getReferenceXmlFile() {\r
+ return ((ReferenceBlock *)reference)->getXmlFile();\r
+}\r
+\r
+QString FunctionalBlock::getReferenceHashMd5()\r
+{\r
+ return ((ReferenceBlock *)reference)->getHashMd5();\r
+}\r
--- /dev/null
+#ifndef __FUNCTIONALBLOCK_H__\r
+#define __FUNCTIONALBLOCK_H__\r
+\r
+#include <iostream>\r
+\r
+#include <QtCore>\r
+\r
+#include "AbstractBlock.h"\r
+class AbstractBlock;\r
+class ReferenceBlock;\r
+class GroupBlock;\r
+#include "Exception.h"\r
+class Exception;\r
+\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+/* NOTES :\r
+ - NEVER forget to call populate() after creating an instance of GraphBlock.\r
+ */\r
+\r
+class FunctionalBlock : public AbstractBlock {\r
+public:\r
+\r
+ FunctionalBlock(GroupBlock* _parent, ReferenceBlock* _reference) throw(Exception);\r
+\r
+ // getters\r
+ inline ReferenceBlock* getReference() { return reference; }\r
+\r
+ // setters\r
+\r
+ // testers\r
+ bool isFunctionalBlock();\r
+\r
+ // others\r
+\r
+ void populate(); // create parameters and interface from reference block\r
+ void parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock*>* blocksToConfigure);\r
+\r
+ QString getReferenceXmlFile();\r
+ QString getReferenceHashMd5();\r
+\r
+private: \r
+ ReferenceBlock* reference;\r
+\r
+};\r
+\r
+#endif // __FUNCTIONALBLOCK_H__\r
--- /dev/null
+#include "ArithmeticEvaluator.h"\r
+#include "FunctionalInterface.h"\r
+#include "ReferenceInterface.h"\r
+#include "GroupInterface.h"\r
+#include "FunctionalBlock.h"\r
+#include "GroupBlock.h"\r
+\r
+\r
+FunctionalInterface::FunctionalInterface(AbstractBlock* _owner, ReferenceInterface *_reference) throw(Exception) : ConnectedInterface(_owner) {\r
+\r
+ if (_owner == NULL) throw(Exception(BLOCK_NULL));\r
+ if (_reference == NULL) throw(Exception(IFACE_NULL));\r
+\r
+ if (! _owner->isFunctionalBlock()) throw(Exception(BLOCK_INVALID_TYPE));\r
+ if (! _reference->isReferenceInterface()) throw(Exception(IFACE_INVALID_TYPE));\r
+\r
+ reference = _reference;\r
+\r
+ name = reference->getName();\r
+ width = reference->getWidth();\r
+ direction = reference->getDirection();\r
+ purpose = reference->getPurpose();\r
+ level = reference->getLevel(); \r
+ connectedFrom = NULL;\r
+}\r
+\r
+bool FunctionalInterface::isFunctionalInterface() {\r
+ return true;\r
+}\r
+\r
+int FunctionalInterface::getInterfaceMultiplicity() {\r
+\r
+ int i=0;\r
+ int ifaceCount = 0;\r
+ FunctionalInterface* iface = NULL;\r
+\r
+ if (direction == AbstractInterface::Input) {\r
+ QList<AbstractInterface *> inputs = owner->getInputs();\r
+ for(i=0;i<inputs.size();i++) {\r
+ iface = AI_TO_FUN(inputs.at(i));\r
+ if (iface->getReference() == reference) {\r
+ ifaceCount += 1;\r
+ }\r
+ }\r
+ }\r
+ else if (direction == AbstractInterface::Output) {\r
+ QList<AbstractInterface *> outputs = owner->getOutputs();\r
+ for(i=0;i<outputs.size();i++) {\r
+ iface = AI_TO_FUN(outputs.at(i));\r
+ if (iface->getReference() == reference) {\r
+ ifaceCount += 1;\r
+ }\r
+ }\r
+ }\r
+ else if (direction == AbstractInterface::InOut) {\r
+ QList<AbstractInterface *> bidirs = owner->getBidirs();\r
+ for(i=0;i<bidirs.size();i++) {\r
+ iface = AI_TO_FUN(bidirs.at(i));\r
+ if (iface->getReference() == reference) {\r
+ ifaceCount += 1;\r
+ }\r
+ }\r
+ }\r
+ if (ifaceCount == 0) {\r
+ return -1;\r
+ }\r
+ else if ( reference->getMultiplicity() == -1) {\r
+ return ifaceCount+1;\r
+ }\r
+ else if ( reference->getMultiplicity() > ifaceCount) {\r
+ return ifaceCount+1;\r
+ }\r
+ return -1;\r
+}\r
+\r
+AbstractInterface *FunctionalInterface::clone() { \r
+ int id = getInterfaceMultiplicity();\r
+ if (id < 0) return NULL;\r
+ FunctionalInterface *inter = new FunctionalInterface(owner, reference);\r
+ inter->setWidth(width);\r
+ inter->setDirection(direction);\r
+ inter->setPurpose(purpose);\r
+ inter->setLevel(level); \r
+ inter->connectFrom(NULL);\r
+ inter->setName(reference->getName()+"_"+QString::number(id));\r
+ return inter;\r
+}\r
+\r
+bool FunctionalInterface::canConnectTo(AbstractInterface *iface) {\r
+\r
+ /* NOTE :\r
+ necessary conditions :\r
+ - this is an output or in/out interface\r
+ - iface type must be functional or group interface\r
+ - iface->connectedFrom must be NULL\r
+\r
+ valid cases:\r
+ 1 - iface is owned by a block (group or func) that is within the same group as the block that own this\r
+ 1.1 - this is output and iface is input\r
+ 1.2 - both are inout\r
+ 2 - iface is owned by the parent group of the block that owns this\r
+ 2.1 - this is an output, iface is an output of the group\r
+ 2.2 - both are inout\r
+\r
+ */\r
+ if (direction == Input) return false;\r
+ if (iface->isReferenceInterface()) return false;\r
+ if (iface->getConnectedFrom() != NULL) return false;\r
+\r
+ if (getOwner()->getParent() == iface->getOwner()->getParent()) {\r
+\r
+ if ((direction == Output) && (iface->getDirection() == Input)) return true;\r
+ if ((direction == InOut) && (iface->getDirection() == InOut)) return true;\r
+ }\r
+ else if (getOwner()->getParent() == iface->getOwner()) {\r
+ if ((direction == Output) && (iface->getDirection() == Output)) return true;\r
+ if ((direction == InOut) && (iface->getDirection() == InOut)) return true;\r
+ }\r
+\r
+ return false;\r
+\r
+}\r
+\r
+bool FunctionalInterface::canConnectFrom(AbstractInterface *iface) {\r
+\r
+ /* NOTE :\r
+ necessary conditions :\r
+ - this is an input or in/out interface\r
+ - iface type must be functional or group interface\r
+ - this connectedFrom must be NULL\r
+\r
+ valid cases:\r
+ 1 - iface is owned by a block (group or func) that is within the same group as the block that own this\r
+ 1.1 - this is input and iface is output\r
+ 1.2 - both are inout\r
+ 2 - iface is owned by the parent group of the block that owns this\r
+ 2.1 - this is an input, iface is an input of the group\r
+ 2.2 - both are inout\r
+ */\r
+ if (direction == Output) return false;\r
+ if (iface->isReferenceInterface()) return false;\r
+ if (connectedFrom != NULL) return false;\r
+\r
+ if (getOwner()->getParent() == iface->getOwner()->getParent()) {\r
+\r
+ if ((direction == Input) && (iface->getDirection() == Output)) return true;\r
+ if ((direction == InOut) && (iface->getDirection() == InOut)) return true;\r
+ }\r
+ else if (getOwner()->getParent() == iface->getOwner()) {\r
+ if ((direction == Input) && (iface->getDirection() == Input)) return true;\r
+ if ((direction == InOut) && (iface->getDirection() == InOut)) return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+\r
+void FunctionalInterface::connectionsValidation(QStack<AbstractInterface *> *interfacetoValidate, QList<AbstractInterface *> *validatedInterfaces) throw(Exception) {\r
+\r
+ /*\r
+ //inputs interfaces\r
+ double widthInput, widthOutput;\r
+ if(getDirection() == AbstractInterface::Input){\r
+ widthInput = getDoubleWidth();\r
+ widthOutput = getConnectedFrom()->getDoubleWidth();\r
+ if(widthInput != widthOutput){\r
+ throw new Exception(WIDTHS_NOT_EQUALS);\r
+ }\r
+ foreach(AbstractInterface *inter, getOwner()->getOutputs()){\r
+ if(inter->isConnectedTo()){\r
+ if((!interfacetoValidate->contains(inter)) && (!validatedInterfaces->contains(inter))){\r
+ interfacetoValidate->push(inter);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ //outputs interfaces\r
+ else if(getDirection() == AbstractInterface::Output){\r
+ widthOutput = getDoubleWidth();\r
+ foreach(AbstractInterface *inter, getConnectedTo()){\r
+ widthInput = inter->getDoubleWidth();\r
+ if(widthInput != widthOutput){\r
+ throw new Exception(WIDTHS_NOT_EQUALS);\r
+ }\r
+ }\r
+ foreach(AbstractInterface *inter, getConnectedTo()){\r
+ if((!interfacetoValidate->contains(inter)) && (!validatedInterfaces->contains(inter))){\r
+ interfacetoValidate->push(inter);\r
+ }\r
+ }\r
+ }\r
+ else if(getDirection() == AbstractInterface::InOut){\r
+\r
+ }\r
+\r
+ */\r
+}\r
--- /dev/null
+#ifndef __FUNCTIONALINTERFACE_H__\r
+#define __FUNCTIONALINTERFACE_H__\r
+\r
+#include <iostream>\r
+\r
+#include <QtCore>\r
+#include <QtGui>\r
+\r
+#include "ConnectedInterface.h"\r
+class ReferenceInterface;\r
+\r
+#include "Exception.h"\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+\r
+/* NOTES :\r
+\r
+ - A FunctionalInterface instance can be obtained by:\r
+ - cloning an existing ReferenceInterface when a new functionalBlock is created by cloning a ReferenceBlock\r
+ - cloning an existing FunctionalInterface when its reference has a multiplicity > 1\r
+\r
+ - For an Input, the list connectedFrom can contain ONLY ONE element\r
+ - For an Output, the list connectedTo can contain several element\r
+ - If connectedTo contains something, then connectedFrom is NULL\r
+ - If connectedFrom contains something, the connectedTo is empty.\r
+ */\r
+\r
+class FunctionalInterface : public ConnectedInterface {\r
+\r
+public :\r
+ FunctionalInterface();\r
+ FunctionalInterface(AbstractBlock* _owner, ReferenceInterface* _reference) throw(Exception); // create a default interface (see AbstractInterface)\r
+\r
+ // getters\r
+ inline ReferenceInterface* getReference() { return reference; }\r
+\r
+ // setters\r
+\r
+ // testers\r
+ bool isFunctionalInterface();\r
+ bool canConnectTo(AbstractInterface* iface);\r
+ bool canConnectFrom(AbstractInterface* iface);\r
+\r
+ // others\r
+\r
+ AbstractInterface* clone();\r
+\r
+ void connectionsValidation(QStack<AbstractInterface*> *interfacetoValidate, QList<AbstractInterface*> *validatedInterfaces) throw(Exception);\r
+ int getInterfaceMultiplicity();\r
+\r
+private:\r
+\r
+ ReferenceInterface* reference; \r
+\r
+};\r
+\r
+#endif // __FUNCTIONALINTERFACE_H__\r
--- /dev/null
+#include "Graph.h"
+#include "GroupBlock.h"
+#include "ReferenceBlock.h"
+#include "FunctionalBlock.h"
+
+Graph::Graph() {
+ topGroup = new GroupBlock(NULL);
+ topGroup->setName("top group");
+}
+
+Graph::~Graph() {
+ delete topGroup;
+}
+
+QList<AbstractInterface *> Graph::getOutsideInterfaces() {
+ return topGroup->getInterfaces();
+}
+
+GroupBlock* Graph::createChildBlock(GroupBlock* parent) {
+ GroupBlock* b = new GroupBlock(parent);
+ return b;
+}
+
+FunctionalBlock* Graph::addFunctionalBlock(GroupBlock* group, ReferenceBlock* ref) {
+
+ FunctionalBlock* newBlock = new FunctionalBlock(group,ref);
+ newBlock->populate();
+ group->addBlock(newBlock);
+
+ return newBlock;
+}
--- /dev/null
+#ifndef __GRAPH_H__
+#define __GRAPH_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+
+class GroupBlock;
+class ReferenceBlock;
+class FunctionalBlock;
+class AbstractInterface;
+
+using namespace std;
+using namespace Qt;
+
+
+class Graph {
+
+public:
+ Graph();
+ ~Graph();
+
+ QList<AbstractInterface *> getOutsideInterfaces();
+ inline GroupBlock* getTopGroup() { return topGroup; }
+
+ GroupBlock* createChildBlock(GroupBlock* parent);
+ FunctionalBlock* addFunctionalBlock(GroupBlock *group, ReferenceBlock *ref);
+
+private:
+ GroupBlock* topGroup;
+
+};
+
+#endif // __GRAPH_H__
--- /dev/null
+#include "GroupBlock.h"
+#include "BlockParameterGeneric.h"
+#include "AbstractInterface.h"
+#include "string.h"
+#include <sstream>
+
+int GroupBlock::counter = 1;
+
+GroupBlock::GroupBlock(GroupBlock *_parent) throw(Exception) : AbstractBlock() {
+
+ // force topGroup to false if this group has a parent
+ if (_parent != NULL) {
+ topGroup = false;
+ name = QString("sub_group")+"_"+QString::number(counter++);
+ }
+ else {
+ topGroup = true;
+ name = QString("top_group");
+ }
+ parent = _parent;
+ if (parent != NULL) {
+ // adding this to the child blocks of parent
+ AB_TO_GRP(parent)->addBlock(this);
+ }
+}
+
+GroupBlock::~GroupBlock() {
+ foreach(AbstractBlock* block, blocks) {
+ delete block;
+ }
+}
+
+bool GroupBlock::isGroupBlock() {
+ return true;
+}
+
+void GroupBlock::setParent(AbstractBlock *_parent) {
+ parent = _parent;
+ if (parent != NULL) {
+ topGroup = false;
+ }
+}
+
+void GroupBlock::removeBlock(AbstractBlock* block) {
+ blocks.removeAll(block);
+}
+
+void GroupBlock::parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock *> *blocksToConfigure) {
+
+ /*
+ checkedBlocks->append(this);
+
+ foreach(BlockParameter* param, params){
+ if(param->isUserParameter() && !param->isValueSet()){
+ if(!blocksToConfigure->contains(param->getOwner())){
+ blocksToConfigure->append(param->getOwner());
+ }
+ }
+ }
+ foreach(AbstractInterface *inter, outputs){
+ foreach(AbstractInterface *connectedInter, inter->getConnectedTo()){
+ if(!checkedBlocks->contains(connectedInter->getOwner())){
+ connectedInter->getOwner()->parametersValidation(checkedBlocks, blocksToConfigure);
+ }
+ }
+ }
+ */
+}
+
+void GroupBlock::addGenericParameter(QString name, QString type, QString value) {
+ BlockParameter* param = new BlockParameterGeneric(this, name, type, value);
+ params.append(param);
+}
+
+void GroupBlock::removeGenericParameter(QString name) {
+ BlockParameter* p = getParameterFromName(name);
+ if (p != NULL) params.removeAll(p);
+}
--- /dev/null
+#ifndef __GROUPBLOCK_H__
+#define __GROUPBLOCK_H__
+
+#include <iostream>
+
+#include <QtCore>
+
+#include "AbstractBlock.h"
+class AbstractBlock;
+#include "Exception.h"
+class Exception;
+
+using namespace std;
+using namespace Qt;
+
+
+class GroupBlock : public AbstractBlock {
+public:
+
+ GroupBlock(GroupBlock* _parent) throw(Exception);
+ virtual ~GroupBlock();
+
+ // getters
+
+ // setters
+ void setParent(AbstractBlock *_parent);
+
+ // testers
+ bool isGroupBlock();
+ inline bool isTop() { return topGroup; }
+
+ // others
+ inline void addBlock(AbstractBlock* block) { blocks.append(block); }
+ void removeBlock(AbstractBlock* block);
+ void parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock*>* blocksToConfigure);
+ void addGenericParameter(QString name, QString type, QString value);
+ void removeGenericParameter(QString name);
+ // public attributes
+ static int counter;
+
+private:
+ bool topGroup;
+ QList<AbstractBlock*> blocks; // contains instances of FunctionalBlock or GroupBlock
+
+};
+
+#endif // __GROUPBLOCK_H__
--- /dev/null
+#include "GroupInterface.h"
+#include "FunctionalInterface.h"
+#include "GroupBlock.h"
+
+GroupInterface::GroupInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _level) throw(Exception) : ConnectedInterface(_owner,_name,"expression","",_direction,AbstractInterface::Data,_level) {
+ if (! _owner->isGroupBlock()) throw(Exception(BLOCK_INVALID_TYPE));
+
+ /* If the owner group is the top group, then all its interfaces are at top level => force them to be top.
+ If not, force them to be basic
+ */
+ if (((GroupBlock*)_owner)->isTop()) {
+ level = AbstractInterface::Top;
+ }
+ else {
+ level = AbstractInterface::Basic;
+ }
+ connectedFrom = NULL;
+}
+
+bool GroupInterface::isGroupInterface() {
+ return true;
+}
+
+AbstractInterface *GroupInterface::clone() {
+ GroupInterface *inter = new GroupInterface(owner,name,direction,level);
+ inter->setWidth(width);
+ inter->setDirection(direction);
+ inter->setPurpose(purpose);
+ inter->setLevel(level);
+ inter->connectFrom(NULL);
+
+ return inter;
+}
+
+
+bool GroupInterface::canConnectTo(AbstractInterface *iface) {
+
+ /* NOTE :
+ necessary conditions :
+ - iface type must be functional or group interface
+ - iface->connectedFrom must be NULL
+
+ valid cases:
+ 1 - this is owned by the parent group of the block (group or func) that owns iface
+ 1.1 - this is input and iface is input
+ 1.2 - both are inout
+ 2 - this is owned by a group that has the same parent as the block (group or func) that owns iface
+ 2.1 - this is an output, iface is an input of the group
+ 2.2 - both are inout
+ 3 - this is owned by a group and iface by its parent group
+ 2.1 - this is an output, iface is an output of the group
+ 2.2 - both are inout
+
+
+ */
+ if (iface->isReferenceInterface()) return false;
+ if (iface->getConnectedFrom() != NULL) return false;
+
+ if (this->getOwner() == iface->getOwner()->getParent()) {
+ if ((direction == Input) && (iface->getDirection() == Input)) return true;
+ if ((direction == InOut) && (iface->getDirection() == InOut)) return true;
+
+ }
+ else if (this->getOwner()->getParent() == iface->getOwner()->getParent()) {
+ if ((direction == Output) && (iface->getDirection() == Input)) return true;
+ if ((direction == InOut) && (iface->getDirection() == InOut)) return true;
+ }
+ else if (this->getOwner()->getParent() == iface->getOwner()) {
+ if ((direction == Output) && (iface->getDirection() == Output)) return true;
+ if ((direction == InOut) && (iface->getDirection() == InOut)) return true;
+ }
+
+ return false;
+}
+
+bool GroupInterface::canConnectFrom(AbstractInterface *iface) {
+
+ /* NOTE :
+ necessary conditions :
+ - iface type must be functional or group interface
+ - this->connectedFrom must be NULL
+
+ valid cases:
+ 1 - this is owned by the parent group of the block (group or func) that owns iface
+ 1.1 - this is output and iface is output
+ 1.2 - both are inout
+ 2 - this is owned by a group that has the same parent as the block (group or func) that owns iface
+ 2.1 - this is an input, iface is an output of the group
+ 2.2 - both are inout
+ 3 - this is owned by a group and iface by its parent group
+ 2.1 - this is an input, iface is an input of the group
+ 2.2 - both are inout
+ */
+ if (iface->isReferenceInterface()) return false;
+ if (getConnectedFrom() != NULL) return false;
+
+ if (this->getOwner() == iface->getOwner()->getParent()) {
+ if ((direction == Output) && (iface->getDirection() == Output)) return true;
+ if ((direction == InOut) && (iface->getDirection() == InOut)) return true;
+
+ }
+ else if (this->getOwner()->getParent() == iface->getOwner()->getParent()) {
+ if ((direction == Input) && (iface->getDirection() == Output)) return true;
+ if ((direction == InOut) && (iface->getDirection() == InOut)) return true;
+ }
+ else if (this->getOwner()->getParent() == iface->getOwner()) {
+ if ((direction == Input) && (iface->getDirection() == Input)) return true;
+ if ((direction == InOut) && (iface->getDirection() == InOut)) return true;
+ }
+
+ return false;
+}
+
+void GroupInterface::connectionsValidation(QStack<AbstractInterface*> *interfacetoValidate, QList<AbstractInterface*> *validatedInterfaces) throw(Exception) {
+ cout << "group interface connection validation" << endl;
+}
--- /dev/null
+#ifndef __GROUPINTERFACE_H__
+#define __GROUPINTERFACE_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+
+#include "ConnectedInterface.h"
+#include "Exception.h"
+class Exception;
+
+using namespace std;
+using namespace Qt;
+
+/* NOTES :
+
+ - A GroupInterface instance can be obtained by linking it to an interface of an inner block, via a
+ contextual menu that appears when right clicking on the inner interface item.
+ Thus, it is impossible to create a "bypass": an input group interface, directly linked to an output
+ group interface.
+ - the direction (in/out/bi) of this interface is the same as that of the inner interface.
+ - except for the top group, a correct design will always have group interfaces that have
+ both connectedTo and connectedFrom containings something. Indeed, a group interface must be seen
+ as a tunnel to communicate data from outside the group to blocks within the group.
+ Thus, an input group interface has connectedFrom refering to an output interface of a block outside the group
+ and connectedTo listing input interfaces of blocks within the group.
+ An output group interface has connectedFrom refering to an output interface of a bock within the group,
+ and connectedTo listing input interface of blocks outside the group.
+
+ */
+
+
+class GroupInterface : public ConnectedInterface {
+
+public :
+ GroupInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _level = AbstractInterface::Basic) throw (Exception);
+
+ // getters
+
+ // setters
+
+ // testers
+ bool isGroupInterface();
+ bool canConnectTo(AbstractInterface* iface);
+ bool canConnectFrom(AbstractInterface* iface);
+
+ // others
+ AbstractInterface *clone();
+ void connectionsValidation(QStack<AbstractInterface *> *interfacetoValidate, QList<AbstractInterface *> *validatedInterfaces) throw(Exception);
+
+};
+
+#endif // __GROUPINTERFACE_H__
--- /dev/null
+#include "GroupItem.h"
+
+#include "ConnectionItem.h"
+#include "InterfaceItem.h"
+#include "Dispatcher.h"
+#include "Parameters.h"
+#include "BoxItem.h"
+#include "AbstractBlock.h"
+#include "AbstractInterface.h"
+#include "ConnectedInterface.h"
+#include "GroupScene.h"
+
+
+GroupItem::GroupItem(BoxItem *_parentItem,
+ AbstractBlock *_refBlock,
+ Dispatcher *_dispatcher,
+ Parameters *_params) throw(Exception) :AbstractBoxItem( _refBlock, _dispatcher, _params) {
+
+ parentItem = _parentItem;
+
+ /*
+ minimumBoxWidth = nameWidth+2*nameMargin;
+ minimumBoxHeight = 100;
+ boxHeight = minimumBoxHeight;
+ boxWidth = minimumBoxWidth;
+ */
+ rectTitle = QRectF(0,-(nameHeight+2*nameMargin),nameWidth+2*nameMargin,nameHeight+2*nameMargin);
+ /*
+ totalHeight = boxHeight + rectTitle.height();
+ totalWidth = boxWidth;
+*/
+ selected = false;
+
+
+ setZValue(-100);
+
+ setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
+
+ updateGeometry();
+ 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;
+}
+
+bool GroupItem::isGroupItem() {
+ return true;
+}
+
+BoxItem* GroupItem::getParentItem() {
+ return parentItem;
+}
+
+void GroupItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
+ if(boxWidth > 0 && boxHeight > 0){
+ if(selected)
+ painter->setPen(Qt::red);
+ else
+ painter->setPen(Qt::black);
+
+ painter->drawRect(0,0,boxWidth,boxHeight);
+ painter->drawRect(rectTitle);
+ painter->drawText(rectTitle,Qt::AlignCenter | Qt::TextWordWrap,refBlock->getName());
+ }
+ foreach(InterfaceItem *item, interfaces){
+ item->paint(painter);
+ }
+}
+
+/* NOTE:
+ Each time a new block is added in a GroupItem, it is placed
+ at an absolute position of (0,0) within the GroupItem. (NB: the absolute
+ position is computed by item.pos()+item.getOriginPoint()).
+ Thus, there are 3 cases :
+ - a single block is within the GroupItem
+ - several blocks already placed and a new one
+ - several blocks already placed and one is moving.
+
+ */
+void GroupItem::updateMinimumSize() {
+
+ // compute place taken by blocks.
+ int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
+ if (rectTitle.width() > 2*marginConn) {
+ minimumBoxWidth = rectTitle.width();
+ }
+ else {
+ minimumBoxWidth = 2*marginConn;
+ }
+ minimumBoxHeight = 2*marginConn;
+
+ if (getScene() == NULL) return;
+
+ QList<BoxItem *> blocks = getScene()->getBlockItems();
+ if(blocks.length() > 0) {
+ // first, search for blocks that are at (0,0)
+ int xMaxZero = 0;
+ int yMaxZero = 0;
+ int xMax = 0;
+ int yMax = 0;
+ bool isZeroBlocks = false;
+ bool isOtherBlocks = false;
+ foreach(BoxItem* item, blocks) {
+ QPointF p = item->pos() + item->getOriginPoint();
+ if ((p.x()==0.0) && (p.y()==0.0)) {
+ isZeroBlocks = true;
+ if (item->getTotalWidth() > xMaxZero) {
+ xMaxZero = item->getTotalWidth();
+ }
+ if (item->getTotalHeight() > yMaxZero) {
+ yMaxZero = item->getTotalHeight();
+ }
+ }
+ else {
+ isOtherBlocks = true;
+ if(p.x()+item->getTotalWidth() > xMax) {
+ xMax = p.x()+item->getTotalWidth();
+ }
+ if(p.y()+item->getTotalHeight() > yMax) {
+ yMax = p.y()+item->getTotalHeight();
+ }
+ }
+ }
+ if (isZeroBlocks) {
+ if (!isOtherBlocks) {
+ minimumBoxWidth = xMaxZero+2*marginConn;
+ minimumBoxHeight = yMaxZero+2*marginConn;
+ }
+ else {
+ if (xMaxZero+marginConn > xMax) {
+ minimumBoxWidth = xMaxZero+2*marginConn;
+ }
+ else {
+ minimumBoxWidth = xMax+marginConn;
+ }
+ if (yMaxZero+marginConn > yMax) {
+ minimumBoxHeight = yMaxZero+2*marginConn;
+ }
+ else {
+ minimumBoxHeight = yMax+marginConn;
+ }
+ }
+ }
+ else {
+ minimumBoxWidth = xMax+marginConn;
+ minimumBoxHeight = yMax+marginConn;
+ }
+ }
+ //cout << "min group size: " << minimumBoxWidth << "," << minimumBoxHeight << endl;
+}
+
+void GroupItem::updateShape() {
+ updateGeometry();
+}
+
+bool GroupItem::updateGeometry(ChangeType type) {
+
+ QPointF oldOrigin = originPoint;
+ QSize oldSize(totalWidth,totalHeight);
+
+ updateMinimumSize();
+ bool boxSizeChanged = false;
+ if (boxWidth < minimumBoxWidth) {
+ boxWidth = minimumBoxWidth;
+ boxSizeChanged = true;
+ }
+ if (boxHeight < minimumBoxHeight) {
+ boxHeight = minimumBoxHeight;
+ boxSizeChanged = true;
+ }
+ if (boxSizeChanged) {
+ updateInterfacesAndConnections();
+ }
+
+ // compute the max. width of interfaces' name for 4 orientations.
+ int maxSouth = 0;
+ int maxNorth = 0;
+ int maxEast = 0;
+ int maxWest = 0;
+ int ifaceWidth = 0;
+
+ foreach(InterfaceItem* iface, interfaces) {
+ ifaceWidth = iface->getNameWidth();
+ if (iface->getOrientation() == Parameters::South) {
+ if (ifaceWidth > maxSouth) maxSouth = ifaceWidth+ifaceMargin+params->arrowWidth+params->arrowLineLength;
+ }
+ else if (iface->getOrientation() == Parameters::North) {
+ if (ifaceWidth > maxNorth) maxNorth = ifaceWidth+ifaceMargin+params->arrowWidth+params->arrowLineLength;
+ }
+ else if (iface->getOrientation() == Parameters::East) {
+ if (ifaceWidth > maxEast) maxEast = ifaceWidth+ifaceMargin+params->arrowWidth+params->arrowLineLength;
+ }
+ else if (iface->getOrientation() == Parameters::West) {
+ if (ifaceWidth > maxWest) maxWest = ifaceWidth+ifaceMargin+params->arrowWidth+params->arrowLineLength;
+ }
+ }
+ double x = 0.0;
+ double y = 0.0;
+ totalWidth = boxWidth+maxEast;
+ totalHeight = boxHeight+maxSouth;
+
+ if (maxWest > 0) {
+ x -= maxWest;
+ totalWidth += maxWest;
+ }
+ if (maxNorth > (nameHeight+2*nameMargin)) {
+ y -= maxNorth;
+ totalHeight += maxNorth;
+ }
+ else {
+ y -= nameHeight+2*nameMargin;
+ totalHeight += nameHeight+2*nameMargin;
+ }
+ QSizeF newSize(totalWidth,totalHeight);
+ originPoint.setX(x);
+ originPoint.setY(y);
+
+ if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
+ //cout << "must change group item shape" << endl;
+ prepareGeometryChange();
+ return true;
+ }
+ return false;
+}
+
+void GroupItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
+
+ if(params->editState == Parameters::EditGroupMove) {
+ 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 < 0) {
+ gapX = -absPos.x();
+ }
+ if (absPos.y()+gapY < 0) {
+ gapY = -absPos.y();
+ }
+ */
+ //cout << "gap: " << gapX << "," << gapY << " | ";
+ //cout << "scene: " << getScene()->sceneRect().x() << "," << getScene()->sceneRect().y() << endl;
+ QPointF gap(gapX,gapY);
+ currentPosition = currentPosition+gap;
+ setPos(currentPosition);
+ cursorPosition = event->scenePos();
+ }
+ else if(params->editState == Parameters::EditGroupResize) {
+
+ 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;
+ }
+ updateGeometry();
+ /*
+ // recompute the geometry of the block
+ updateGeometry();
+ // update all interfaces positions
+ foreach(InterfaceItem *item, interfaces){
+ item->updatePosition();
+ }
+ // update all connections from/to this block
+ foreach(ConnectionItem *item, getScene()->getConnectionItems()){
+ if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
+ item->setPathes();
+ }
+ }
+ */
+ cursorPosition = event->scenePos();
+ }
+ else if(params->editState == Parameters::EditInterfaceMove) {
+ prepareGeometryChange();
+ deplaceInterface(event->pos());
+ // recompute the geometry of the block
+ updateGeometry();
+ // update connection from/to the selected interface
+ foreach(ConnectionItem *item, getScene()->getConnectionItems()){
+ if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
+ item->setPathes();
+ }
+ }
+ update();
+ }
+}
+
+void GroupItem::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()->getGroupWindow());
+
+ /* NOTE : commneted because group interface are normally
+ created and the connected directly to a block within
+ the group. Furthermore, there can be a single connection
+ from a groupe interface.
+
+ 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);
+ }
+ }
+ }
+ }
+ */
+ if (mode == GroupScene::ItemEdition) {
+
+ if (params->cursorState == Parameters::CursorOnInterface) {
+ InterfaceItem *inter = getInterfaceFromCursor(x,y);
+ if (inter != NULL) {
+ currentInterface = inter;
+ params->setEditState(Parameters::EditInterfaceMove);
+ }
+ }
+ else if (params->cursorState == Parameters::CursorInGroupTitle) {
+ params->setEditState(Parameters::EditGroupMove);
+ cursorPosition = event->scenePos();
+ }
+ else if (params->cursorState == Parameters::CursorOnBorder) {
+ setFlag(ItemIsMovable, false);
+ cursorPosition = event->scenePos();
+ params->setEditState(Parameters::EditGroupResize);
+ }
+ }
+}
+
+void GroupItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
+
+ int mode = getScene()->getEditionMode();
+
+ /* NOTE : commneted because group interface are normally
+ created and the connected directly to a block within
+ the group. Furthermore, there can be a single connection
+ from a groupe interface.
+
+ if (mode == GroupScene::AddConnection) {
+
+ if (params->editState == Parameters::EditStartConnection) {
+ params->setEditState(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->connect(iface1,iface2);
+ if (ok) {
+ iface1->selected = false;
+ update(iface1->boundingRect());
+ getScene()->setSelectedInterface(1,NULL);
+ getScene()->setSelectedInterface(2,NULL);
+ params->setEditState(Parameters::EditNoOperation);
+ }
+ }
+ }
+ */
+ if (mode == GroupScene::ItemEdition) {
+ currentInterface = NULL;
+ setFlag(ItemIsMovable, true);
+ params->editState = Parameters::EditNoOperation;
+ }
+ QGraphicsItem::mouseReleaseEvent(event);
+}
+
+void GroupItem::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 (rectTitle.contains(x,y)) {
+ params->cursorState = Parameters::CursorInGroupTitle;
+ setCursor(Qt::OpenHandCursor);
+ }
+ else {
+ params->cursorState = Parameters::CursorNowhere;
+ setCursor(Qt::ArrowCursor);
+ }
+ }
+ }
+ QGraphicsItem::hoverMoveEvent(event);
+}
+
+void GroupItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
+ QMenu menu;
+ QAction* showProperties = NULL;
+ QAction* removeAction = NULL;
+ QAction* renameAction = NULL;
+
+ InterfaceItem* ifaceItem = getInterfaceFromCursor(event->pos().x(), event->pos().y());
+ if( ifaceItem != NULL){
+ showProperties = menu.addAction("Show properties");
+ renameAction = menu.addAction("Rename");
+ menu.addSeparator();
+ /* CAUTION : the interface can be removed only if its
+ connected to only one side, i.e. connectedFrom is null
+ or connectedTo is empty.
+
+ */
+ ConnectedInterface* ref = ifaceItem->refInter;
+ if ((!ref->isConnectedFrom()) || (!ref->isConnectedTo())) {
+ removeAction = menu.addAction("Remove");
+ }
+ }
+ else {
+ renameAction = menu.addAction("Rename");
+ }
+ QAction* selectedAction = menu.exec(event->screenPos());
+
+ if(selectedAction == NULL) return;
+
+ if(selectedAction == renameAction){
+ if(ifaceItem != NULL)
+ dispatcher->rename(ifaceItem);
+ else
+ dispatcher->rename(this);
+ }
+ else if(selectedAction == showProperties){
+ dispatcher->showProperties(ifaceItem);
+ }
+ else if (selectedAction == removeAction) {
+ dispatcher->removeGroupInterface(ifaceItem);
+ }
+}
+
+InterfaceItem* GroupItem::isHoverInterface(QPointF point) {
+ foreach(InterfaceItem *inter, interfaces){
+ if(inter->boundingRect().contains(point))
+ return inter;
+ }
+ return NULL;
+}
+
+void GroupItem::save(QXmlStreamWriter &writer) {
+
+ writer.writeStartElement("group_item");
+
+ QString attrId = QString::number(id);
+ QString attrName(getRefBlock()->getName());
+ QString attrUpperItem = QString::number(-1);
+ if(parentItem != NULL){
+ attrUpperItem = QString::number(parentItem->getId());
+ }
+ QString attrPos = QString::number(pos().x()).append(",").append(QString::number(pos().y()));
+ QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
+
+
+ writer.writeAttribute("id",attrId);
+ writer.writeAttribute("upper_item",attrUpperItem);
+ writer.writeAttribute("name",attrName);
+ writer.writeAttribute("position", attrPos);
+ writer.writeAttribute("dimension", attrDim);
+
+ writer.writeStartElement("group_ifaces");
+
+ writer.writeAttribute("count",QString::number(interfaces.length()));
+
+ foreach(InterfaceItem *item, interfaces){
+ writer.writeStartElement("group_iface");
+
+ writer.writeAttribute("id",QString::number(item->getId()));
+ writer.writeAttribute("name",item->getName());
+ writer.writeAttribute("level",QString(item->refInter->getLevelString()));
+ writer.writeAttribute("direction",QString(item->refInter->getDirectionString()));
+ writer.writeAttribute("orientation",item->getStrOrientation());
+ writer.writeAttribute("position",QString::number(item->getPositionRatio()));
+
+ writer.writeEndElement();
+ }
+
+ writer.writeEndElement();//</interfaces>
+
+ writer.writeEndElement();//</group_item>
+}
--- /dev/null
+#ifndef __GROUPITEM_H__
+#define __GROUPITEM_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+
+#include "AbstractBoxItem.h"
+class AbstractBoxItem;
+
+class BoxItem;
+class InterfaceItem;
+class Dispatcher;
+class Parameters;
+
+#include "Exception.h"
+
+using namespace std;
+using namespace Qt;
+
+class GroupItem : public AbstractBoxItem {
+
+public:
+ /* CAUTION : the parentItem of a group block IS NOT the group item of the parent scene. It is a BlockItem that is
+ wihtin the parent scene. It is used when interfaceItem are added to the current GroupItem: they must be also added
+ to the parent BlockItem.
+
+ NB : this yields a problem when loading a project because scenes are created before creating group and then block.
+ thus, the parentItem must be initialized afterward when all block items have been created.
+
+ */
+ GroupItem(BoxItem* _parentItem, AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params) throw(Exception);
+ ~GroupItem();
+
+ // getters
+ BoxItem* getParentItem();
+
+ // setters
+
+ // testers
+ bool isGroupItem();
+
+ // others
+ void updateShape();
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+ void save(QXmlStreamWriter& writer);
+
+protected:
+
+ void updateMinimumSize(); // modify the minimum size
+ bool updateGeometry(ChangeType type);
+
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
+ void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
+
+
+
+private:
+ /* NOTE : parentItem attribute is never NULL except for the top GroupItem
+ in the top scene
+ */
+ BoxItem* parentItem;
+ QRectF rectTitle;
+
+
+ InterfaceItem *isHoverInterface(QPointF point);
+};
+
+#endif // __GROUPITEM_H__
--- /dev/null
+#include "GroupScene.h"
+
+#include "Dispatcher.h"
+#include "Parameters.h"
+#include "GroupWidget.h"
+#include "GroupItem.h"
+#include "BoxItem.h"
+#include "ConnectionItem.h"
+#include "InterfaceItem.h"
+#include "AbstractBlock.h"
+
+GroupScene::GroupScene(GroupScene *_parentScene, GroupWidget *_window, Dispatcher* _dispatcher, Parameters* _params, bool _topScene, QObject *parent) : QGraphicsScene(parent) {
+ dispatcher = _dispatcher;
+ params = _params;
+ parentScene = _parentScene;
+ if (parentScene != NULL) {
+ parentScene->addChildScene(this);
+ }
+ window = _window;
+ groupItem = NULL;
+ id = -1;
+ topScene = _topScene;
+ editMode = InitState;
+
+ selectedInterfaces[0] = NULL;
+ selectedInterfaces[1] = NULL;
+}
+
+GroupScene::~GroupScene() {
+ blockItems.clear();
+ connectionItems.clear();
+ groupItem = NULL;
+}
+
+void GroupScene::setSelectedInterface(int id, InterfaceItem* iface) {
+ if ((id < 1)|| (id > 2)) return;
+ selectedInterfaces[id-1] = iface;
+}
+
+InterfaceItem* GroupScene::getSelectedInterface(int id) {
+ if ((id < 1)|| (id > 2)) return NULL;
+ return selectedInterfaces[id-1];
+}
+
+QList<BoxItem *> GroupScene::getSelectedBlocks() {
+ QList<BoxItem*> lst;
+ foreach(BoxItem *item, blockItems){
+ if (item->isSelected()){
+ lst.append(item);
+ }
+ }
+ return lst;
+}
+
+int GroupScene::setItemsId(int countInit) {
+ int counter = countInit;
+ groupItem->setId(counter++);
+ foreach(BoxItem *item, blockItems){
+ item->setId(counter++);
+ }
+ return counter;
+}
+
+int GroupScene::setInterfacesId(int countInit) {
+ int counter = countInit;
+ foreach(InterfaceItem* inter, groupItem->getInterfaces()){
+ inter->setId(counter++);
+ }
+ foreach(BoxItem *item, blockItems){
+ foreach(InterfaceItem* inter, item->getInterfaces()){
+ inter->setId(counter++);
+ }
+ }
+ return counter;
+}
+
+QList<AbstractBoxItem*> GroupScene::getGroupAndBlocks() {
+
+ QList<AbstractBoxItem*> lst;
+ lst.append(groupItem);
+ foreach(BoxItem *item, blockItems){
+ lst.append(item);
+ }
+ return lst;
+}
+
+void GroupScene::createBlockItem(AbstractBlock *block) {
+
+ BoxItem* blockItem = new BoxItem(block,dispatcher,params,groupItem);
+ blockItem->setZValue(1);
+ addBlockItem(blockItem);
+}
+
+void GroupScene::addBlockItem(BoxItem* item) {
+ // add item from the viewport
+ //addItem(item);
+ // add item from the QList
+ blockItems.append(item);
+ // repainting the group
+ groupItem->updateShape();
+ // 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);
+}
+
+void GroupScene::removeBlockItem(BoxItem* item) {
+ // remove item from the viewport
+ removeItem(item);
+ // remove item from the QList
+ blockItems.removeAll(item);
+ // repainting the group
+ groupItem->updateShape();
+}
+
+void GroupScene::createConnectionItem(InterfaceItem *iface1, InterfaceItem *iface2) {
+ ConnectionItem* conn = new ConnectionItem(iface1,iface2, dispatcher, params, groupItem);
+ addConnectionItem(conn);
+}
+
+ConnectionItem* GroupScene::searchConnectionItem(InterfaceItem *iface1, InterfaceItem *iface2) {
+ foreach(ConnectionItem* conn , connectionItems) {
+ if ( ((conn->getFromInterfaceItem() == iface1) && (conn->getToInterfaceItem() == iface2)) ||
+ ((conn->getFromInterfaceItem() == iface2) && (conn->getToInterfaceItem() == iface1))) {
+ return conn;
+ }
+ }
+}
+
+void GroupScene::addConnectionItem(ConnectionItem* item) {
+ // add item from the viewport
+ //addItem(item);
+ // add item from the QList
+ connectionItems.append(item);
+}
+
+void GroupScene::removeConnectionItem(ConnectionItem* item) {
+ // remove item from the viewport
+ removeItem(item);
+ // remove item from the QList
+ connectionItems.removeAll(item);
+}
+
+void GroupScene::setGroupItem(GroupItem *group) {
+ if ((groupItem == NULL) && (group != NULL)) {
+ groupItem = group;
+ addItem(group);
+ }
+}
+
+void GroupScene::removeGroupItem() {
+ // remove item from the viewport
+ removeItem(groupItem);
+ groupItem = NULL;
+}
+
+QList<ConnectionItem *> GroupScene::getInterfaceConnections(InterfaceItem *item) {
+ QList<ConnectionItem*> list;
+ foreach(ConnectionItem *conn, connectionItems){
+ if(conn->getFromInterfaceItem() == item || conn->getToInterfaceItem() == item){
+ list.append(conn);
+ }
+ }
+ return list;
+}
+
+void GroupScene::unselecteInterfaces() {
+
+ if (selectedInterfaces[0] != NULL) {
+ selectedInterfaces[0]->selected = false;
+ selectedInterfaces[0] == NULL;
+ }
+ if (selectedInterfaces[1] != NULL) {
+ selectedInterfaces[1]->selected = false;
+ selectedInterfaces[1] == NULL;
+ }
+}
+
+void GroupScene::updateConnectionItemsShape() {
+
+ foreach(ConnectionItem* conn, connectionItems){
+ conn->setPathes();
+ }
+}
+
+void GroupScene::save(QXmlStreamWriter &writer) {
+ writer.writeStartElement("scene");
+ writer.writeAttribute("id",QString::number(id));
+ groupItem->save(writer);
+
+ writer.writeStartElement("block_items");
+
+ QList<BoxItem *> functionalBlocks;
+ QList<BoxItem *> groupBlocks;
+
+ foreach(BoxItem *item, blockItems){
+ if(item->getRefBlock()->isFunctionalBlock()){
+ functionalBlocks.append(item);
+ } else if(item->getRefBlock()->isGroupBlock()){
+ groupBlocks.append(item);
+ }
+ }
+ writer.writeAttribute("functional_count",QString::number(functionalBlocks.length()));
+ writer.writeAttribute("group_count",QString::number(groupBlocks.length()));
+
+ foreach(BoxItem* item, functionalBlocks) {
+ item->save(writer);
+ }
+ foreach(BoxItem* item, groupBlocks) {
+ item->save(writer);
+ }
+ writer.writeEndElement(); // block_items
+ writer.writeEndElement(); // scene
+}
+
--- /dev/null
+#ifndef __GROUPSCENE_H__
+#define __GROUPSCENE_H__
+
+#include <QtCore>
+#include <QtGui>
+#include <QtWidgets>
+
+class Dispatcher;
+class Parameters;
+class AbstractBlock;
+class GroupWidget;
+class GroupItem;
+class BoxItem;
+class AbstractBoxItem;
+class ConnectionItem;
+class InterfaceItem;
+
+using namespace std;
+using namespace Qt;
+
+/* NOTES :
+
+ - A GroupScene is composed of a single GroupItem that contains BlockItem and ConnectionItem
+ The GroupItem is stored in the mainGroup attribute
+
+ - A GroupScene is instanciated whenever there is a GroupItem that must be created, i.e.
+ for the top scene or for subgroups.
+
+ - This class is a subclass of QGraphicsScene by convenience but it's goal is more to list
+ the different inner items. Thus, all operations that add/remove items to the scene will also
+ add them in the QList
+ */
+
+class GroupScene : public QGraphicsScene {
+
+public:
+
+ /* edition mode of the window:
+ - AddBlock: can only add blocks to the scene
+ - AddConnection: can only add connections to the scene
+ - AddGroup: while a new group (empty or from selected blocks) is created
+ - ItemEdtion: can move/resize blocks/interfaces, remove blocks/interface/group, ...
+ */
+ enum EditMode { InitState, AddBlock, AddConnection, AddGroup, ItemEdition };
+
+ GroupScene(GroupScene* _parentScene, GroupWidget* _window, Dispatcher* _dispatcher, Parameters* _params, bool topScene = false, QObject *parent = 0);
+ ~GroupScene();
+
+ // attributes getters
+ inline GroupItem* getGroupItem() {return groupItem;}
+ inline QList<BoxItem*> getBlockItems() { return blockItems; }
+ inline QList<ConnectionItem*> getConnectionItems() { return connectionItems; }
+ inline QList<GroupScene*> getChildrenScene() { return childrenScene; }
+ inline GroupWidget* getGroupWindow() { return window; }
+ inline int getId() { return id; }
+ inline EditMode getEditionMode() { return editMode; }
+ InterfaceItem* getSelectedInterface(int id);
+
+ // attributes setters
+ inline void setWindow(GroupWidget* _window) { window = _window; }
+ void setGroupItem(GroupItem* group);
+ inline void setId(int id) { this->id = id; }
+ inline void setEditionMode(EditMode mode) { editMode = mode; }
+ void setSelectedInterface(int id, InterfaceItem* iface);
+
+ // attributes testers
+ inline bool isTopScene() { return topScene; }
+
+
+ // others
+ void createBlockItem(AbstractBlock* block);
+ void addBlockItem(BoxItem* item);
+ void removeBlockItem(BoxItem* item);
+ void createConnectionItem(InterfaceItem* iface1, InterfaceItem* iface2);
+ ConnectionItem* searchConnectionItem(InterfaceItem* iface1, InterfaceItem* iface2);
+ void addConnectionItem(ConnectionItem* item);
+ void removeConnectionItem(ConnectionItem* item);
+ void removeGroupItem();
+ inline void addChildScene(GroupScene* child) { childrenScene.append(child); }
+ void unselecteInterfaces();
+
+ QList<AbstractBoxItem*> getGroupAndBlocks();
+ QList<BoxItem *> getSelectedBlocks();
+
+ QList<ConnectionItem *> getInterfaceConnections(InterfaceItem *item);
+
+ int setItemsId(int countInit=1);
+ int setInterfacesId(int countInit=1);
+
+ void updateConnectionItemsShape();
+
+ void save(QXmlStreamWriter& writer);
+
+private:
+ Dispatcher *dispatcher;
+ Parameters *params;
+ GroupScene* parentScene; // the parnet scene, =NULL for top scene
+ GroupWidget* window; // the GroupWindow that contains that scene
+ int id;
+ GroupItem *groupItem; // mandatory to be an instance of GroupItem.
+ QList<ConnectionItem*> connectionItems;
+ QList<BoxItem*> blockItems;
+ QList<GroupScene*> childrenScene;
+ bool topScene;
+ EditMode editMode;
+ InterfaceItem* selectedInterfaces[2]; // selected iface 1 in AddConnection mode
+
+};
+
+#endif // __GROUPSCENE_H__
--- /dev/null
+#include "GroupWidget.h"
+
+#include "Dispatcher.h"
+#include "Parameters.h"
+
+#include "GroupScene.h"
+#include "GroupBlock.h"
+#include "BoxItem.h"
+#include "GroupItem.h"
+#include "ConnectionItem.h"
+#include "Graph.h"
+
+GroupWidget::GroupWidget(GroupWidget *_upperGroup, Dispatcher *_dispatcher,
+ Parameters *_params,
+ QWidget *parent) : QWidget(parent) {
+ upperGroup = _upperGroup;
+ dispatcher = _dispatcher;
+ params = _params;
+ if (upperGroup == NULL) {
+ topGroup = true;
+ scene = new GroupScene(NULL, this, dispatcher, params, true);
+ }
+ else {
+ topGroup = true;
+ scene = new GroupScene(upperGroup->getScene(), this, dispatcher, params, false);
+ }
+
+ layout = new QGridLayout;
+
+ QGraphicsView *view = new QGraphicsView(scene);
+ layout->addWidget(view,1,0,1,3);
+
+ createActions();
+ createToolbar();
+ setLayout(layout);
+ setFocusPolicy(Qt::StrongFocus);
+ setFocus();
+
+ scene->setEditionMode(GroupScene::ItemEdition);
+ updateBlockButton();
+
+}
+
+GroupWidget::~GroupWidget(){}
+
+void GroupWidget::changeConnectionMode(int mode) {
+ /*
+ QPalette pal = buttonNewConnection->palette();
+
+ if(mode == -1){
+
+ if(params->sceneMode != Parameters::EditOnConnection){
+ params->sceneMode = Parameters::EditOnConnection;
+ pal.setColor(QPalette::Button, QColor(Qt::lightGray));
+
+ } else {
+ params->sceneMode = Parameters::EditNoOperation;
+ pal.setColor(QPalette::Button, QColor("#edeceb"));
+ dispatcher->unselectAllInterfaces();
+ }
+ } else if(mode == Parameters::EditOnConnection){
+ params->sceneMode = Parameters::EditOnConnection;
+ pal.setColor(QPalette::Button, QColor(Qt::lightGray));
+ } else {
+ params->sceneMode = Parameters::EditNoOperation;
+ pal.setColor(QPalette::Button, QColor("#edeceb"));
+ }
+ dispatcher->unselectAllInterfaces();
+ buttonNewConnection->setAutoFillBackground(true);
+ buttonNewConnection->setPalette(pal);
+ buttonNewConnection->update();
+ */
+}
+
+
+void GroupWidget::enableGroupButton(bool b) {
+ newGroupAct->setEnabled(b);
+}
+
+
+void GroupWidget::mousePressEvent(QMouseEvent *e) {
+ dispatcher->setCurrentGroupWidget(this);
+ QWidget::mousePressEvent(e);
+}
+
+void GroupWidget::focusInEvent(QFocusEvent *e) {
+ /*
+ if(params->currentWindow != this){
+ params->setCurrentWindow(this);
+ changeConnectionMode(false);
+ }
+ */
+}
+
+void GroupWidget::closeEvent(QCloseEvent *e) {
+ clearFocus();
+ focusNextChild();
+}
+
+
+void GroupWidget::createActions() {
+
+ butAddConnection = new QToolButton(this);
+ butAddConnection->setIcon(QPixmap::fromImage(QImage("icons/add_connection.png")));
+ butAddConnection->setToolTip("Adding connections");
+ QPalette pal = butAddConnection->palette();
+ butBaseColor = pal.color(QPalette::Button);
+ connect(butAddConnection, SIGNAL(clicked()), this, SLOT(slotAddConnection()));
+
+ butEdit = new QToolButton(this);
+ butEdit->setIcon(QPixmap::fromImage(QImage("icons/edit_block.png")));
+ butEdit->setToolTip("Edit items");
+ connect(butEdit, SIGNAL(clicked()), this, SLOT(slotEdit()));
+
+ copyBlockAct = new QAction(tr("&Copy block"), this);
+ copyBlockAct->setIcon(QPixmap::fromImage(QImage("icons/copy.png")));
+ copyBlockAct->setStatusTip(tr("Copy the selected block"));
+ connect(copyBlockAct, SIGNAL(triggered()), this, SLOT(slotCopyBlock()));
+
+ newEmptyGroupAct = new QAction(tr("&Create a new empty group"), this);
+ newEmptyGroupAct->setIcon(QPixmap::fromImage(QImage("icons/add_group_void.png")));
+ newEmptyGroupAct->setStatusTip(tr("Create a new empty group"));
+ connect(newEmptyGroupAct, SIGNAL(triggered()), this, SLOT(slotNewEmptyGroup()));
+
+ newGroupAct = new QAction(tr("&Create a new group"), this);
+ newGroupAct->setIcon(QPixmap::fromImage(QImage("icons/add_group_select.png")));
+ newGroupAct->setStatusTip(tr("Create a new group"));
+ newGroupAct->setDisabled(true);
+ connect(newGroupAct, SIGNAL(triggered()), this, SLOT(slotNewGroup()));
+
+ deleteAct = new QAction(tr("&Delete selected elements"), this);
+ deleteAct->setIcon(QPixmap::fromImage(QImage("icons/delete.png")));
+ deleteAct->setStatusTip(tr("Delete selected elements"));
+ connect(deleteAct, SIGNAL(triggered()), this, SLOT(slotDeleteItems()));
+
+ selectAllAct = new QAction(tr("&Select all elements"), this);
+ selectAllAct->setIcon(QPixmap::fromImage(QImage("icons/delete.png")));
+ selectAllAct->setStatusTip(tr("Select all elements"));
+ connect(selectAllAct, SIGNAL(triggered()), this, SLOT(slotSelectAll()));
+
+ unselectAllAct = new QAction(tr("&unselect all elements"), this);
+ unselectAllAct->setIcon(QPixmap::fromImage(QImage("icons/delete.png")));
+ unselectAllAct->setStatusTip(tr("Unselect all elements"));
+ connect(unselectAllAct, SIGNAL(triggered()), this, SLOT(slotUnselectAll()));
+}
+
+void GroupWidget::createToolbar() {
+ toolbarEditMode = new QToolBar(tr("Mode"));
+ toolbarAdd = new QToolBar(tr("Group"));
+ toolbarTools = new QToolBar(tr("Tools"));
+
+ toolbarEditMode->addWidget(new QLabel("Mode"));
+ toolbarTools->addWidget(new QLabel("Tools"));
+
+ toolbarEditMode->addSeparator();
+ toolbarTools->addSeparator();
+
+ toolbarEditMode->addWidget(butAddConnection);
+ toolbarEditMode->addWidget(butEdit);
+
+ toolbarAdd->addAction(copyBlockAct);
+ toolbarAdd->addAction(newEmptyGroupAct);
+ toolbarAdd->addAction(newGroupAct);
+
+ toolbarTools->addAction(deleteAct);
+ toolbarTools->addAction(selectAllAct);
+ toolbarTools->addAction(unselectAllAct);
+
+ layout->addWidget(toolbarEditMode,0,0);
+ layout->addWidget(toolbarAdd,0,1);
+ layout->addWidget(toolbarTools,0,2);
+}
+
+void GroupWidget::slotEdit() {
+ dispatcher->unselectAllItems();
+ getScene()->setEditionMode(GroupScene::ItemEdition);
+ updateBlockButton();
+}
+
+void GroupWidget::slotCopyBlock() {
+ foreach (BoxItem *item, params->getCurrentScene()->getBlockItems()) {
+ if(item->isSelected()){
+ dispatcher->duplicateBlock(item);
+ }
+ }
+}
+
+void GroupWidget::slotAddConnection() {
+ dispatcher->unselectAllItems();
+ getScene()->setEditionMode(GroupScene::AddConnection);
+ updateBlockButton();
+}
+
+void GroupWidget::updateBlockButton() {
+
+ // reset all buttons to light gray
+ QPalette pal = butAddConnection->palette();
+ pal.setColor(QPalette::Button, butBaseColor);
+
+ butAddConnection->setAutoFillBackground(true);
+ butAddConnection->setPalette(pal);
+ butAddConnection->update();
+ butEdit->setAutoFillBackground(true);
+ butEdit->setPalette(pal);
+ butEdit->update();
+
+ // set the good one to dark gray
+ pal.setColor(QPalette::Button, QColor(Qt::darkGray));
+
+ if(getScene()->getEditionMode() == GroupScene::AddConnection) {
+ butAddConnection->setAutoFillBackground(true);
+ butAddConnection->setPalette(pal);
+ butAddConnection->update();
+ }
+ else if(getScene()->getEditionMode() == GroupScene::ItemEdition) {
+ butEdit->setAutoFillBackground(true);
+ butEdit->setPalette(pal);
+ butEdit->update();
+ }
+
+}
+
+void GroupWidget::slotNewEmptyGroup() {
+
+ // creating the GroupBlock in graph model
+ GroupBlock* groupBlock = params->addGroupBlock();
+ // creating the BlockItem in the inner scene
+ BoxItem* block = new BoxItem(groupBlock, dispatcher, params, scene->getGroupItem());
+
+ GroupWidget* child = dispatcher->createChildScene(this,block);
+ child->show();
+}
+
+void GroupWidget::slotNewGroup()
+{
+ dispatcher->addNewFullGroup();
+}
+
+void GroupWidget::slotDeleteItems() {
+ foreach (BoxItem *item, scene->getBlockItems()) {
+ if(item->isSelected()){
+ dispatcher->removeBlock(item);
+ }
+ }
+ foreach (ConnectionItem *item, scene->getConnectionItems()) {
+ if(item->isSelected()){
+ dispatcher->removeConnection(item);
+ }
+ }
+}
+
+void GroupWidget::slotSelectAll()
+{
+ foreach(QGraphicsItem *item, params->getCurrentScene()->items()){
+ if(item->data(0) == "block"){
+ BoxItem *b = dynamic_cast<BoxItem*>(item);
+ b->setSelected(true);
+ } else if(item->data(0) == "connection"){
+ ConnectionItem *c = dynamic_cast<ConnectionItem*>(item);
+ c->setSelected(true);
+ }
+ item->update(item->boundingRect());
+ }
+}
+
+void GroupWidget::slotUnselectAll()
+{
+ foreach(QGraphicsItem *item, params->getCurrentScene()->items()){
+ if(item->data(0) == "block"){
+ BoxItem *b = dynamic_cast<BoxItem*>(item);
+ b->setSelected(false);
+ } else if(item->data(0) == "connection"){
+ ConnectionItem *c = dynamic_cast<ConnectionItem*>(item);
+ c->setSelected(false);
+ }
+
+ item->update(item->boundingRect());
+ }
+}
--- /dev/null
+#ifndef __GROUPWIDGET_H__
+#define __GROUPWIDGET_H__
+
+#include <QtWidgets>
+
+class Dispatcher;
+class Parameters;
+class GroupScene;
+
+
+
+class GroupWidget : public QWidget {
+ Q_OBJECT
+public:
+
+ explicit GroupWidget(GroupWidget* _upperGroup, Dispatcher* _dispatcher, Parameters* _params, QWidget *parent = 0);
+
+ // getters
+ inline GroupScene *getScene() {return scene;}
+ inline QToolButton* getButtonNewConnection(){return butAddConnection;}
+
+ // testers
+ inline bool isTopGroup() { return topGroup;}
+
+ // others
+ void changeConnectionMode(int mode = -1);
+
+
+ ~GroupWidget();
+
+ void enableGroupButton(bool b);
+
+protected:
+ void mousePressEvent(QMouseEvent *e);
+ void focusInEvent(QFocusEvent *e);
+ void closeEvent(QCloseEvent *e);
+
+private:
+ GroupWidget* upperGroup; // NB:for convenience. NULL if it contains the top scene
+ bool topGroup;
+
+ GroupScene *scene;
+ Dispatcher *dispatcher;
+ Parameters *params;
+
+ void createActions();
+ void createToolbar();
+
+ QToolButton* butAddConnection;
+ QToolButton* butEdit;
+ void updateBlockButton();
+ QColor butBaseColor;
+
+ QAction *copyBlockAct;
+
+ QAction *newEmptyGroupAct;
+ QAction *newGroupAct;
+
+ QAction *deleteAct;
+ QAction *selectAllAct;
+ QAction *unselectAllAct;
+
+ QToolBar *toolbarEditMode;
+ QToolBar *toolbarAdd;
+ QToolBar *toolbarTools;
+
+
+ QGridLayout *layout;
+
+signals:
+
+private slots:
+ void slotCopyBlock();
+ void slotAddConnection();
+ void slotEdit();
+
+ void slotNewEmptyGroup();
+ void slotNewGroup();
+
+ void slotDeleteItems();
+ void slotSelectAll();
+ void slotUnselectAll();
+};
+
+#endif // __GROUPWIDGET_H__
--- /dev/null
+#include "InterfaceItem.h"
+
+#include "Parameters.h"
+#include "GroupInterface.h"
+#include "FunctionalInterface.h"
+#include "BoxItem.h"
+
+int InterfaceItem::counter = 0;
+
+InterfaceItem::InterfaceItem(double _position,
+ int _orientation,
+ ConnectedInterface *_refInter,
+ AbstractBoxItem* _owner,
+ Parameters* _params){
+ positionRatio = _position;
+ orientation = _orientation;
+ refInter = _refInter;
+
+ // CAUTION : the owner must add explicitely this item to its interface, calling addInterface()
+ owner = _owner;
+ params = _params;
+ selected = false;
+ name = refInter->getName();
+ QFontMetrics fmName(params->defaultIfaceFont);
+ nameWidth = fmName.width(name);
+ nameHeight = fmName.height();
+ // by default, only data interface are visible
+ if (refInter->getPurpose() == AbstractInterface::Data) {
+ visible = true;
+ }
+ else {
+ visible = false;
+ }
+
+ this->id = InterfaceItem::counter++;
+
+ updatePosition();
+}
+
+
+InterfaceItem::InterfaceItem(){
+ this->id = counter++;
+}
+
+/* boundingRect() : give the bounding rect in the blockitem coord. system */
+QRectF InterfaceItem::boundingRect() const {
+
+ QPointF pointHG;
+ QSizeF s;
+
+ switch(orientation){
+ case Parameters::East :
+ pointHG = QPointF(originPoint.x(),originPoint.y()-(params->arrowHeight/2.0));
+ s = QSizeF(params->arrowWidth+params->arrowLineLength, params->arrowHeight);
+ break;
+ case Parameters::North :
+ pointHG = QPointF(originPoint.x()-(params->arrowHeight/2.0),originPoint.y()-params->arrowWidth-params->arrowLineLength);
+ s = QSizeF(params->arrowHeight,params->arrowWidth+params->arrowLineLength);
+ break;
+ case Parameters::West :
+ pointHG = QPointF(originPoint.x()-params->arrowLineLength-params->arrowWidth,originPoint.y()-(params->arrowHeight/2.0));
+ s = QSizeF(params->arrowWidth+params->arrowLineLength, params->arrowHeight);
+ break;
+ case Parameters::South :
+ pointHG = QPointF(originPoint.x()-(params->arrowHeight/2.0),originPoint.y());
+ s = QSizeF(params->arrowHeight, params->arrowWidth+params->arrowLineLength);
+ break;
+ default :
+ pointHG = QPointF();
+ s = QSizeF();
+ break;
+ }
+
+ return QRectF(pointHG,s);
+}
+
+void InterfaceItem::paint(QPainter *painter) {
+
+ if(visible) {
+
+ painter->save();
+
+ if(selected) {
+ painter->setPen(QPen(Qt::red,2));
+ }
+ else if(refInter->getLevel() == AbstractInterface::Basic) {
+ painter->setPen(QPen(Qt::darkCyan,1));
+ }
+ else if(refInter->getLevel() == AbstractInterface::Top) {
+ painter->setPen(QPen(Qt::black,1));
+ }
+
+ painter->translate(originPoint);
+
+ switch(orientation) {
+ case Parameters::North:
+ painter->rotate(-90);
+ break;
+ case Parameters::West:
+ painter->rotate(180);
+ break;
+ case Parameters::South:
+ painter->rotate(90);
+ break;
+ }
+
+ // draw arrows
+ if(refInter->getDirection() == AbstractInterface::Input) {
+ painter->drawPath(params->inArrow);
+ }
+ else if(refInter->getDirection() == AbstractInterface::Output) {
+ painter->drawPath(params->outArrow);
+ } else if(refInter->getDirection() == AbstractInterface::InOut) {
+ painter->drawPath(params->inArrow);
+ painter->drawPath(params->outArrow);
+ }
+
+ // draw names
+
+ // reset to normal if at west
+ if(orientation == Parameters::West){
+ painter->rotate(180);
+ }
+
+ painter->setFont(params->defaultIfaceFont);
+
+ QFontMetrics fm = painter->fontMetrics();
+ int w = nameWidth + owner->getIfaceMargin();
+ int h = nameHeight;
+
+ if(orientation == Parameters::West){
+
+ if(owner->isGroupItem()){
+ painter->drawText(-(w+params->arrowWidth+params->arrowLineLength),-h/2,w,h,Qt::AlignLeft | Qt::TextWordWrap, refInter->getName());
+ }
+ else if(owner->isBoxItem()){
+ painter->drawText(0,-h/2,w,h,Qt::AlignRight | Qt::TextWordWrap, refInter->getName());
+ }
+ }
+ else {
+
+ if(owner->isGroupItem()) {
+ painter->drawText(params->arrowWidth+params->arrowLineLength,-h/2,w,h,Qt::AlignRight | Qt::TextWordWrap, refInter->getName());
+ }
+ else if(owner->isBoxItem()) {
+ painter->drawText(-w,-h/2,w,h,Qt::AlignLeft | Qt::TextWordWrap, refInter->getName());
+ }
+ }
+
+ painter->restore();
+ }
+}
+
+QPointF InterfaceItem::getEndPointInGroup() {
+ QPointF p;
+
+ if (owner->isGroupItem()) {
+ p = originPoint;
+ }
+ else {
+ double x = owner->x() + originPoint.x();
+ double y = owner->y() + originPoint.y();
+ switch(orientation){
+ case Parameters::East:
+ x += params->arrowWidth+params->arrowLineLength;
+ break;
+ case Parameters::North:
+ y -= params->arrowWidth+params->arrowLineLength;
+ break;
+ case Parameters::West:
+ x -= params->arrowWidth+params->arrowLineLength;
+ break;
+ case Parameters::South:
+ y += params->arrowWidth+params->arrowLineLength;
+ break;
+ }
+ p = QPointF(x,y);
+ }
+
+ //cout << "iface end point in group item: " << p.x() << "," << p.y() << endl;
+ return p;
+}
+
+void InterfaceItem::setOriginPoint() {
+ switch(orientation){
+ case Parameters::East:
+ originPoint = QPointF(owner->getWidth(),position);
+ break;
+ case Parameters::North:
+ originPoint = QPointF(position,0);
+ break;
+ case Parameters::West:
+ originPoint = QPointF(0,position);
+ break;
+ case Parameters::South:
+ originPoint = QPointF(position,owner->getHeight());
+ break;
+ }
+}
+
+QString InterfaceItem::getStrOrientation() {
+ QString str = NULL;
+ switch(orientation){
+ case Parameters::North :
+ str = QString("north");
+ break;
+ case Parameters::South :
+ str = QString("south");
+ break;
+ case Parameters::East :
+ str = QString("east");
+ break;
+ case Parameters::West :
+ str = QString("west");
+ break;
+ }
+
+ return str;
+}
+
+int InterfaceItem::getIntOrientation(QString str) {
+ if(str == "west") return Parameters::West;
+ if(str == "east") return Parameters::East;
+ if(str == "south") return Parameters::South;
+ if(str == "north") return Parameters::North;
+ return -1;
+}
+
+
+/* connectWith() :
+ - modify all necessary attributes in the model to create a connection
+ between current InterfaceItem and iface. Note that the source and destination
+ are deduced from the direction (In, Out) and the type of the owner (funcitonal, group)
+
+ CAUTION: No security checks are done. This method must be called only if canConnectWith has been called and returned true.
+
+ NOTE : conditions so that this InterfaceItem can be connected with inter.
+ (i.e. current one can connect to inter OR inter can connect to current)
+
+ Here are all the possible combinations, depending on the type of the
+ block/item and direction of the interface, which are :
+ GI/GB : a GroupItem referencing a GroupBlock (single solution for GI)
+ BI/FB : a BlockItem referencing a FunctionalBlock
+ BI/GB : a BlockItem referencing a GroupBlock
+
+ For GI/GB:
+ - Input can connect with BI/FB or BI/GB Input
+ - Output can connect with BI/FB or BI/GB Output
+
+ For BI/FB:
+ - Input can connect with:
+ GI/GB Input
+ BI/FB Output
+ BI/GB Output
+ - Output can connect with:
+ GI/GB Output
+ BI/FB Input
+ BI/GB Input
+
+ For BI/GB:
+ - Input can connect with:
+ GI/GB Input
+ BI/FB Output
+ BI/GB Output
+ - Output can connect with:
+ GI/GB Output
+ BI/FB Input
+ BI/GB Input
+
+ And whatever the case an InOut can only connect with an InOut
+ We note that:
+ - the IG does not allow the connect a GI/GB interface to an
+ interface of another GI/GB, thus the case is not considered above.
+ - BI/FB and BI/GB are the same.
+ - the cases where direction are the same only occur when
+ the 2 items are of different type (GI and BI)
+ - the cases where directions are different only occur when
+ the 2 are of both BlockItem
+
+*/
+bool InterfaceItem::connectWith(InterfaceItem *iface) {
+ ConnectedInterface* interThis = refInter; // the reference of this
+ ConnectedInterface* interOther = iface->refInter; // the reference of the other
+ ConnectedInterface* src = NULL, *dest = NULL;
+
+ if(interThis->getDirection() == AbstractInterface::InOut && interOther->getDirection() == AbstractInterface::InOut){
+ /* NOTE: InOut interfaces have both directions and thus are
+ connected from inter1 to inter2 AND inter2 to inter1
+ Another effect is that a InOut can be connected to/from a single
+ InOut.
+ */
+ if((interThis->getConnectedFrom() == NULL) && (interOther->getConnectedFrom() == NULL)) {
+
+ interOther->connectFrom(interThis);
+ interOther->getConnectedTo().append(interThis);
+ interThis->connectFrom(interOther);
+ interThis->getConnectedTo().append(interOther);
+
+ cout << "connecting 2 InOut"<< endl;
+ return true;
+ }
+ return false;
+ }
+ else if (interThis->getDirection() == interOther->getDirection()) {
+
+ // cannot connect GI to GI or 2 BI of the same direction.
+ if ((getOwner()->isGroupItem()) && (iface->getOwner()->isGroupItem())) return false;
+ if ((getOwner()->isBoxItem()) && (iface->getOwner()->isBoxItem())) return false;
+
+ if (interThis->getDirection() == AbstractInterface::Input) { // both are inputs
+ cout << "connecting GI to BI" << endl;
+ if(getOwner()->isGroupItem()) {
+ src = interThis;
+ dest = interOther;
+ }
+ else {
+ src = interOther;
+ dest = interThis;
+ }
+ }
+ else { // both are outputs
+ cout << "connecting BO to GO" << endl;
+ if(getOwner()->isGroupItem()){
+ src = interOther;
+ dest = interThis;
+ }
+ else {
+ src = interThis;
+ dest = interOther;
+ }
+ }
+ }
+ else {
+ if ((getOwner()->isGroupItem()) || (iface->getOwner()->isGroupItem())) return false;
+
+ cout << "connecting BO to BI" << endl;
+ if(interOther->getDirection() == AbstractInterface::Output) {
+ src = interOther;
+ dest = interThis;
+ }
+ else {
+ src = interThis;
+ dest = interOther;
+ }
+ }
+
+ if(dest != NULL && src != NULL){
+ // cannot overrive existing connectionFrom
+ if(dest->getConnectedFrom() == NULL) {
+ dest->connectFrom(src);
+ src->connectTo(dest);
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ return false;
+}
+
+void InterfaceItem::unconnectTo(InterfaceItem *iface)
+{
+ if(iface->refInter->getConnectedFrom() == refInter){
+ 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;
+ iface->refInter->removeConnectedTo(refInter);
+ }
+ if(refInter->getConnectedFrom() == iface->refInter) {
+ cout << "abnormal case while removing iface conn from " << qPrintable(name) << " to " << qPrintable(iface->name) << endl;
+ refInter->connectFrom(NULL);
+ }
+ if(refInter->getConnectedTo().contains(iface->refInter)){
+ refInter->removeConnectedTo(iface->refInter);
+ }
+}
+
+void InterfaceItem::updatePosition()
+{
+ if(orientation == Parameters::North || orientation == Parameters::South){
+ position = positionRatio * owner->getWidth();
+ } else {
+ position = positionRatio * owner->getHeight();
+ }
+ setOriginPoint();
+}
+
+void InterfaceItem::addConnectionItem(ConnectionItem* item) {
+ connections.append(item);
+}
+
+void InterfaceItem::removeConnectionItem(ConnectionItem* item) {
+ connections.removeOne(item);
+}
+
+QDataStream &operator <<(QDataStream &out, InterfaceItem *i) {
+
+#ifdef DEBUG_INCLFUN
+ out.setVersion(QDataStream::Qt_5);
+
+ QByteArray interfaceData;
+ QDataStream toWrite(&interfaceData, QIODevice::WriteOnly);
+
+ toWrite << i->getId();
+ toWrite << i->getName();
+ toWrite << i->getPositionRatio();
+ toWrite << i->getOrientation();
+
+ foreach(QGraphicsItem* item, i->params->getCurrentScene()->items()){
+ if(item->data(0) == "connection"){
+ ConnectionItem *conn = dynamic_cast<ConnectionItem*>(item);
+ if(conn->getFromInterfaceItem() == i || conn->getToInterfaceItem() == i){
+ toWrite << conn->getId();
+ cout << "id connection : " << conn->getId() << endl;
+ }
+ }
+ }
+ out << interfaceData;
+#endif
+ return out;
+}
+
+QDataStream &operator >>(QDataStream &in, InterfaceItem &i) {
+
+#ifdef DEBUG_INCLFUN
+ in.setVersion(QDataStream::Qt_5);
+
+ int id, orientation;
+ double positionRatio;
+ QString name;
+
+ in >> id;
+ in >> name;
+ in >> positionRatio;
+ in >> orientation;
+
+ i.setId(id);
+ i.setName(name);
+ i.setPositionRatio(positionRatio);
+ i.setOrientation(orientation);
+ i.updatePosition();
+#endif
+ return in;
+}
--- /dev/null
+#ifndef __INTERFACEITEM_H__
+#define __INTERFACEITEM_H__
+
+#include <QtCore>
+#include <QtGui>
+
+class Parameters;
+class ConnectedInterface;
+class AbstractBoxItem;
+class ConnectionItem;
+
+
+using namespace std;
+using namespace Qt;
+
+class InterfaceItem {
+
+public:
+
+
+
+ InterfaceItem(double _position,
+ int _orientation,
+ ConnectedInterface* _refInter,
+ AbstractBoxItem* _owner,
+ Parameters* _params);
+ InterfaceItem();
+ QRectF boundingRect() const;
+ void paint(QPainter *painter);
+
+ // getters
+ inline int getId() { return id; }
+ inline QString getName() { return name; }
+ inline double getPositionRatio() { return positionRatio; }
+ inline double getPosition() { return position; }
+ inline int getOrientation() { return orientation; }
+ inline AbstractBoxItem *getOwner() { return owner; }
+ inline int getNameWidth() { return nameWidth; }
+ inline int getNameHeight() { return nameHeight; }
+ QString getStrOrientation();
+ static int getIntOrientation(QString str);
+ QPointF getEndPointInGroup();
+
+ // setters
+ void setOriginPoint();
+ inline void setId(int id){ this->id = id; }
+ inline void setName(QString name){ this->name = name; }
+ inline void setPositionRatio(double ratio) { positionRatio = ratio; }
+ inline void setOrientation(int _orientation){ orientation = _orientation; }
+
+ // others
+ void addConnectionItem(ConnectionItem* item);
+ void removeConnectionItem(ConnectionItem* item);
+ bool canConnectWith(InterfaceItem* iface);
+ bool connectWith(InterfaceItem* iface);
+ void unconnectTo(InterfaceItem *iface);
+ void updatePosition();
+
+ AbstractBoxItem* owner;
+ ConnectedInterface* refInter;
+ Parameters* params;
+ bool selected;
+ bool visible;
+
+ static int counter;
+
+ QList<ConnectionItem*> connections; // the connection items that are bounded to this interface item
+
+
+private:
+ int id;
+ QString name;
+ double positionRatio;
+ int position; // position in pixels on the "orientation side" of the owner
+ int orientation; // north, south, east, west
+ QPointF originPoint; // the point where starts the drawing (along the box border) NB : in the owner coordinates
+ int nameWidth; // the graphical width of the name, computed from default font metrics
+ int nameHeight; // the graphical height of the name, computed from default font metrics
+
+ friend QDataStream &operator<<(QDataStream &out, InterfaceItem *b);
+ friend QDataStream &operator>>(QDataStream &in, InterfaceItem &b);
+};
+
+/*
+QDataStream & operator <<(QDataStream &out, InterfaceItem *b);
+QDataStream & operator >>(QDataStream &in, InterfaceItem &b);
+*/
+#endif
--- /dev/null
+#include "InterfacePropertiesWindow.h"
+
+#include "ConnectedInterface.h"
+
+InterfacePropertiesWindow::InterfacePropertiesWindow(InterfaceItem *_inter, QWidget *parent) :
+ QWidget(parent)
+{
+ inter = _inter;
+
+ layout = new QGridLayout;
+
+
+ layout->addWidget(new QLabel("Interface properties"), 0, 0);
+ layout->addWidget(new QLabel(" "), 1, 0);
+
+ layout->addWidget(new QLabel("Name :"), 2, 0);
+ layout->addWidget(new QLabel(inter->getName()), 2, 1);
+ layout->addWidget(new QLabel("Width :"), 3, 0);
+ layout->addWidget(new QLabel(inter->refInter->getWidth()), 3, 1);
+ layout->addWidget(new QLabel("Direction :"), 4, 0);
+ layout->addWidget(new QLabel(inter->refInter->getDirectionString()), 4, 1);
+ layout->addWidget(new QLabel("Purpose :"), 5, 0);
+ layout->addWidget(new QLabel(inter->refInter->getPurposeString()), 5, 1);
+ layout->addWidget(new QLabel("Level :"), 6, 0);
+ layout->addWidget(new QLabel(inter->refInter->getLevelString()), 6, 1);
+
+ this->setLayout(layout);
+
+ show();
+}
--- /dev/null
+#ifndef __INTERFACEPROPERTIESWINDOW_H__
+#define __INTERFACEPROPERTIESWINDOW_H__
+
+#include <QtWidgets>
+
+#include "InterfaceItem.h"
+
+class InterfacePropertiesWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit InterfacePropertiesWindow(InterfaceItem *_inter, QWidget *parent = 0);
+
+private:
+ QGridLayout *layout;
+ InterfaceItem *inter;
+
+
+
+};
+
+#endif // INTERFACEPROPERTIESWINDOW_H
--- /dev/null
+#include "MainWindow.h"
+#include "Dispatcher.h"
+#include "Parameters.h"
+#include "BlockLibraryWidget.h"
+#include "GroupWidget.h"
+#include "GroupScene.h"
+#include "BlockWidget.h"
+#include "AbstractBoxItem.h"
+#include "Graph.h"
+#include "GroupItem.h"
+#include <QDomDocument>
+#include <QDomElement>
+#include <QDomText>
+#include <sstream>
+
+MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
+
+ versionMaj = VERSION_MAJ;
+ versionMin = VERSION_MIN;
+ revision = REVISION;
+
+ // reading parameters
+ params = new Parameters();
+ try {
+ params->loadBlastConfiguration("blastconfig.xml");
+
+ if (!QFileInfo::exists(params->refLib)) {
+ params->loadReferencesFromXml();
+ int ret = QMessageBox::question(this,tr("Building references library"),tr("The reference block library does not exists.\n References have been read directly from the xml descriptions of blocks.\n It can be saved into a library in order to start application faster. "), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
+ if (ret == QMessageBox::Ok) {
+ params->saveReferencesToLib();
+ }
+ }
+ else {
+ params->loadReferencesFromLib();
+ }
+
+ if (!QFileInfo::exists(params->implLib)) {
+ params->loadImplementationsFromXml();
+ int ret = QMessageBox::question(this,tr("Building implementations library"),tr("The block implementations library does not exists.\nImplementations have been read directly from the xml descriptions.\n It can be saved into a library in order to start application faster. "), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
+ if (ret == QMessageBox::Ok) {
+ params->saveImplementationsToLib();
+ }
+ }
+ else {
+ params->loadImplementationsFromLib();
+ }
+ }
+ catch(Exception err) {
+ cerr << qPrintable(err.getDefaultMessage()) << endl;
+ cerr << "Aborting ..." << endl;
+ exit(1);
+ }
+
+ cout << "all references and implementations are loaded" << endl;
+
+ // create the menu, action, ...
+ dispatcher = new Dispatcher(params,this);
+ params->setDispatcher(dispatcher);
+
+ // creating block library
+ library = new BlockLibraryWidget(dispatcher,params);
+ isCurrentProject = false;
+
+ QLabel* labDefault = new QLabel("BLAST: BLock ASsembler Tool");
+ stackedWidget = new QStackedWidget;
+ stackedWidget->addWidget(labDefault);
+ stackedWidget->setCurrentIndex(0);
+ this->setCentralWidget(stackedWidget);
+ this->setMinimumSize(800,600);
+
+ createActions();
+ createMenus();
+ setWindowTitle("blast - top group");
+ setFocusPolicy(Qt::StrongFocus);
+ setFocus();
+
+ readSettings();
+
+ initialize();
+
+}
+
+MainWindow::~MainWindow() {}
+
+void MainWindow::initialize() {
+
+ projectMenuEnb = 0;
+
+ stackedWidget->setCurrentIndex(0);
+ enableProjectActions(true,PROJECT_NEW | PROJECT_OPEN, OP_RAZ);
+
+ stackedWidget->setCurrentIndex(0);
+
+ resize(500,300);
+}
+
+void MainWindow::readSettings() {
+ QSettings settings;
+ settings.beginGroup("init");
+ checkNewVersion = settings.value("check_new_version").toString();
+ settings.endGroup();
+ if (checkNewVersion.isEmpty()) {
+ checkNewVersion = "true";
+ }
+ /*
+ cout << "test nouvelle version : " << qPrintable(checkNewVersion) << endl;
+ QUrl url("http://www.hrafnheim.fr/download/Cartomagic/carto_currentversion.txt");
+ QNetworkRequest request(url);
+ manager = new QNetworkAccessManager(this);
+ connect(manager,SIGNAL(finished(QNetworkReply*)), this, SLOT(slotCheckNewVersion(QNetworkReply*)));
+ manager->get(request);
+ */
+}
+
+void MainWindow::writeSettings() {
+ QSettings settings;
+ settings.beginGroup("init");
+ settings.setValue("check_new_version",checkNewVersion);
+ settings.endGroup();
+}
+
+void MainWindow::slotCheckNewVersion(QNetworkReply *reply) {
+
+ if (reply->error() == QNetworkReply::NoError) {
+ QString txt = reply->readAll();
+ QString currentVer = QString("%1.%2.%3").arg(versionMaj).arg(versionMin).arg(revision);
+ if (txt.contains(currentVer)) {
+ cout << "a jour" << endl;
+ }
+ else {
+ cout << "dernière version : " << qPrintable(txt) << ", version actuelle = " << qPrintable(currentVer) << endl;
+ }
+ }
+ else {
+ cout << "erreur = " << qPrintable(reply->errorString()) << endl;
+ }
+ reply->deleteLater();
+}
+
+void MainWindow::enableProjectActions(bool enbMenu, quint16 mask, quint8 op) {
+ if (enbMenu) {
+ projectMenu->setEnabled(true);
+ }
+ else {
+ projectMenu->setEnabled(false);
+ }
+
+ if (op == OP_ADD) {
+ projectMenuEnb = projectMenuEnb | mask;
+ }
+ else if (op == OP_REM) {
+ projectMenuEnb = (projectMenuEnb | mask) ^ mask;
+ }
+ else if (op == OP_RAZ) {
+ projectMenuEnb = mask;
+ }
+
+
+ if (projectMenuEnb & PROJECT_NEW) {
+ newProject->setEnabled(true);
+ }
+ else {
+ newProject->setEnabled(false);
+ }
+ if (projectMenuEnb & PROJECT_OPEN) {
+ openProject->setEnabled(true);
+ }
+ else {
+ openProject->setEnabled(false);
+ }
+ if (projectMenuEnb & PROJECT_SAVE) {
+ saveProject->setEnabled(true);
+ }
+ else {
+ saveProject->setEnabled(false);
+ }
+ if (projectMenuEnb & PROJECT_SAVEAS) {
+ saveAsProject->setEnabled(true);
+ }
+ else {
+ saveAsProject->setEnabled(false);
+ }
+ if (projectMenuEnb & PROJECT_CLOSE) {
+ closeProject->setEnabled(true);
+ }
+ else {
+ closeProject->setEnabled(false);
+ }
+ if (projectMenuEnb & PROJECT_LIB) {
+ openLibrary->setEnabled(true);
+ }
+ else {
+ openLibrary->setEnabled(false);
+ }
+}
+
+void MainWindow::createMenus(){
+
+ allMenuBar = menuBar();
+
+ projectMenu = allMenuBar->addMenu(tr("&Project"));
+ toolsMenu = allMenuBar->addMenu(tr("&Tools"));
+
+ projectMenu->addAction(newProject);
+ projectMenu->addAction(openProject);
+ projectMenu->addAction(saveProject);
+ projectMenu->addAction(saveAsProject);
+ projectMenu->addAction(closeProject);
+ projectMenu->addAction(openLibrary);
+
+ toolsMenu->addAction(newBlockWidgetAct);
+ toolsMenu->addAction(graphValidation);
+
+}
+
+void MainWindow::createActions() {
+
+ newProject = new QAction(tr("&New project"), this);
+ newProject->setIcon(QPixmap::fromImage(QImage("icons/new.ico")));
+ newProject->setStatusTip(tr("Create a new project"));
+ connect(newProject, SIGNAL(triggered()), this, SLOT(slotNewProject()));
+
+ openProject = new QAction(tr("&Open project"), this);
+ openProject->setIcon(QPixmap::fromImage(QImage("icons/load.png")));
+ openProject->setStatusTip(tr("Open an existing project"));
+ connect(openProject, SIGNAL(triggered()), this, SLOT(slotLoadProject()));
+
+ saveProject = new QAction(tr("&Save project"), this);
+ saveProject->setIcon(QPixmap::fromImage(QImage("icons/save.png")));
+ saveProject->setStatusTip(tr("Save the current project"));
+ connect(saveProject, SIGNAL(triggered()), this, SLOT(slotSaveProject()));
+
+ saveAsProject = new QAction(tr("&Save project as..."), this);
+ saveAsProject->setIcon(QPixmap::fromImage(QImage("icons/save-as.png")));
+ saveAsProject->setStatusTip(tr("Save the current project as..."));
+ connect(saveAsProject, SIGNAL(triggered()), this, SLOT(slotSaveAsProject()));
+
+ closeProject = new QAction(tr("&Close project"), this);
+ closeProject->setIcon(QPixmap::fromImage(QImage("icons/close.png")));
+ closeProject->setStatusTip(tr("Close the current project"));
+ connect(closeProject, SIGNAL(triggered()), this, SLOT(slotCloseProject()));
+
+ openLibrary = new QAction(tr("Open block &Library"), this);
+ openLibrary->setIcon(QPixmap::fromImage(QImage("icons/add_block.png")));
+ openLibrary->setStatusTip(tr("Open block library window"));
+ connect(openLibrary, SIGNAL(triggered()), this, SLOT(slotOpenBlockLibrary()));
+
+ newBlockWidgetAct = new QAction(tr("&XML generator"), this);
+ newBlockWidgetAct->setIcon(QPixmap::fromImage(QImage("icons/new.ico")));
+ newBlockWidgetAct->setStatusTip(tr("Create a new XML generator"));
+ connect(newBlockWidgetAct, SIGNAL(triggered()), this, SLOT(slotNewBlockWidget()));
+
+ graphValidation = new QAction(tr("&graph validation"), this);
+ graphValidation->setIcon(QPixmap::fromImage(QImage("icons/new.ico")));
+ graphValidation->setStatusTip(tr("validate the graph"));
+ connect(graphValidation, SIGNAL(triggered()), this, SLOT(slotGraphValidation()));
+
+}
+
+void MainWindow::save(QString absoluteFilename) {
+ params->save(absoluteFilename);
+}
+
+void MainWindow::slotLoadProject(){
+
+ absoluteFilename = QFileDialog::getOpenFileName(0, "select a project file", "save/",tr("sauvegardes (*.xml)"));
+
+ if(! absoluteFilename.isEmpty()){
+ GroupWidget* topGroup = dispatcher->loadProject(absoluteFilename);
+ if (topGroup != NULL) {
+ addTopGroup(topGroup);
+ }
+ else {
+ QMessageBox msgBox;
+ msgBox.setText("Cannot open the project.");
+ msgBox.setInformativeText("Do you want to save your changes?");
+ msgBox.setStandardButtons(QMessageBox::Cancel);
+ msgBox.setDefaultButton(QMessageBox::Cancel);
+
+ int ret = msgBox.exec();
+ }
+ }
+}
+
+
+void MainWindow::slotNewProject(){
+
+ enableProjectActions(true, PROJECT_CLOSE | PROJECT_SAVE | PROJECT_SAVEAS | PROJECT_LIB, OP_RAZ);
+ GroupWidget* topGroup = dispatcher->createTopScene();
+ addTopGroup(topGroup);
+
+}
+
+void MainWindow::slotCloseProject(){
+
+ // removing the GroupWidget from stack
+ QWidget *widget = stackedWidget->widget(1);
+ stackedWidget->removeWidget(widget);
+ stackedWidget->setCurrentIndex(0);
+
+ dispatcher->closeCurrentProject();
+
+
+ isCurrentProject = false;
+ params->unsaveModif = false;
+ absoluteFilename = QString();
+
+ initialize();
+}
+
+
+void MainWindow::slotNewBlockWidget() {
+ new BlockWidget();
+}
+
+void MainWindow::slotSaveProject(){
+ if(absoluteFilename != QString()){
+ save(absoluteFilename);
+ } else {
+ slotSaveAsProject();
+ }
+}
+
+void MainWindow::slotSaveAsProject(){
+ if(isCurrentProject){
+ QFileDialog dial(0, "Select a file", "save/");
+ dial.setDefaultSuffix(".xml");
+ dial.setAcceptMode(QFileDialog::AcceptSave);
+ if(dial.exec() == QFileDialog::AcceptSave){
+ absoluteFilename = dial.selectedFiles().at(0);
+ if(absoluteFilename != QString())
+ save(absoluteFilename);
+ }
+ }
+}
+
+void MainWindow::slotOpenBlockLibrary() {
+ dispatcher->showBlocksLibrary();
+}
+
+
+void MainWindow::slotGraphValidation() {
+ params->parametersValidation();
+}
+
+void MainWindow::addTopGroup(GroupWidget *_topGroup) {
+ topGroup = _topGroup;
+ stackedWidget->addWidget(topGroup);
+ stackedWidget->setCurrentIndex(1);
+}
+
+void MainWindow::removeTopGroup() {
+ stackedWidget->removeWidget(topGroup);
+ topGroup->deleteLater();
+ stackedWidget->setCurrentIndex(0);
+}
+
+void MainWindow::closeEvent(QCloseEvent *event){
+ if(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;
+ }
+ event->ignore();
+ } else {
+ exit(0);
+ }
+}
+
+void MainWindow::mousePressEvent(QMouseEvent *e) {
+
+ if (dispatcher->getCurrentGroup() != NULL) {
+ dispatcher->setCurrentGroupWidget(dispatcher->getCurrentGroup());
+ }
+ QMainWindow::mousePressEvent(e);
+}
+
+void MainWindow::focusInEvent(QFocusEvent *e) {
+/*
+ if(params->currentWindow != this){
+ params->setCurrentWindow(this);
+ changeConnectionMode(false);
+ }
+ */
+}
--- /dev/null
+#ifndef __MAINWINDOW_H__
+#define __MAINWINDOW_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtNetwork>
+#include <QtWidgets>
+
+class Dispatcher;
+class Parameters;
+class BlockLibraryWidget;
+class GroupWidget;
+class BlockWidget;
+class Graph;
+
+// versioning related
+#define MAGIC_STRING "opentrace"
+#define VERSION_MAJ (quint8)0 // major version code
+#define VERSION_MIN (quint8)2 // minor version number
+#define REVISION (quint8)1 // revision number of current version
+
+
+// defines for menus
+#define TRACE_MENU (quint8)1
+
+// defines for actions
+#define NONE_ACT (quint16)0
+
+#define PROJECT_NEW (quint16)1
+#define PROJECT_OPEN (quint16)2
+#define PROJECT_SAVE (quint16)4
+#define PROJECT_SAVEAS (quint16)8
+#define PROJECT_CLOSE (quint16)16
+#define PROJECT_LIB (quint16)32
+
+#define OP_ADD (quint8)0
+#define OP_REM (quint8)1
+#define OP_RAZ (quint8)2
+
+using namespace std;
+using namespace Qt;
+
+
+class MainWindow : public QMainWindow {
+
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+ void initialize();
+
+ void addTopGroup(GroupWidget* _topGroup);
+ void removeTopGroup(); // called when closing project
+
+
+ inline BlockLibraryWidget *getLibrary(){return library;}
+
+
+protected:
+ void closeEvent(QCloseEvent *);
+ void mousePressEvent(QMouseEvent *e);
+ void focusInEvent(QFocusEvent *e);
+
+private:
+
+ GroupWidget* topGroup;
+ QStackedWidget *stackedWidget;
+ Dispatcher *dispatcher;
+ Parameters *params;
+ BlockLibraryWidget *library;
+
+ bool isCurrentProject;
+ QString absoluteFilename;
+
+ QString checkNewVersion;
+
+ void save(QString absoluteFilename);
+
+ void createActions();
+ void createMenus();
+
+ void readSettings();
+ void writeSettings();
+
+ /* Menus */
+ QMenuBar *allMenuBar;
+
+ QMenu* projectMenu;
+ quint16 projectMenuEnb;
+ QMenu* toolsMenu;
+
+ QAction* newProject;
+ QAction* openProject;
+ QAction* saveProject;
+ QAction* saveAsProject;
+ QAction* closeProject;
+ QAction* openLibrary;
+
+ QAction *newBlockWidgetAct;
+ QAction *graphValidation;
+
+
+ // versioning related
+ quint8 versionMaj;
+ quint8 versionMin;
+ quint8 revision;
+
+public slots:
+ void enableProjectActions(bool enbMenu, quint16 mask = 0, quint8 op = 0); // default : add nothing
+
+private slots:
+ void slotNewProject();
+ void slotLoadProject();
+ void slotSaveProject();
+ void slotSaveAsProject();
+ void slotCloseProject();
+ void slotOpenBlockLibrary();
+
+ void slotNewBlockWidget();
+ void slotGraphValidation();
+
+ void slotCheckNewVersion(QNetworkReply *reply);
+};
+
+#endif // MAINWINDOW_H
--- /dev/null
+#############################################################################
+# Makefile for building: @@APPNAME@@
+#############################################################################
+
+####### VERSION (modified by the configure script) ############
+APPNAME=@@APPNAME@@
+
+####### VERSION (modified by the configure script) ############
+VERSION=@@APPVER@@
+
+####### OS (modified by the configure script) ############
+OS=@@OS@@
+ARCH=@@ARCH@@
+
+####### Qt (modified by the configure script) ############
+QTVER=@@QTVER@@
+QTPATH=@@QTPATH@@
+
+####### PATHES ############
+BUILDDIR=build
+DISTDIR=dist
+BUILDPATH=$(BUILDDIR)/$(OS)$(ARCH)
+DISTPATH=$(DISTDIR)/$(OS)$(ARCH)/$(APPNAME)-$(VERSION)
+ARDIR=archive
+ARPATH=$(ARDIR)/$(APPNAME)/v$(VERSION)
+
+####### COMPILERS ############
+CC-lin32 = gcc
+CXX-lin32 = g++
+CC-lin64 = gcc
+CXX-lin64 = g++
+CC-win32 = i686-w64-mingw32-gcc-win32
+CXX-win32 = i686-w64-mingw32-g++-win32
+WINDRES-win32 = i686-w64-mingw32-windres
+CC-win64 = x86_64-w64-mingw32-gcc-win32
+CXX-win64 = x86_64-w64-mingw32-g++-win32
+WINDRES-win64 = x86_64-w64-mingw32-windres
+
+CC = $(CC-$(OS)$(ARCH))
+CXX = $(CXX-$(OS)$(ARCH))
+WINDRES = $(WINDRES-$(OS)$(ARCH))
+
+DEFINES-lin32 = -DDEBUG -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -D@@APPDEF@@_LIN
+DEFINES-lin64 = -DDEBUG -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -D@@APPDEF@@_LIN
+DEFINES-win32 = -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NEEDS_QMAIN -DQT_AXCONTAINER_LIB -DQT_PRINTSUPPORT_LIB -DQT_AXBASE_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_XML_LIB -D@@APPDEF@@_WIN
+
+DEFINES = $(DEFINES-$(OS)$(ARCH))
+
+CFLAGS-lin32 = @@DEBUG@@ -pipe -O2 -Wall -fPIC -D_REENTRANT $(DEFINES)
+CFLAGS-lin64 = @@DEBUG@@ -pipe -O2 -Wall -fPIC -D_REENTRANT $(DEFINES)
+CXXFLAGS-lin32 = @@DEBUG@@ -pipe -O2 -Wall -fPIC -D_REENTRANT $(DEFINES)
+CXXFLAGS-lin64 = @@DEBUG@@ -pipe -O2 -Wall -fPIC -D_REENTRANT $(DEFINES)
+CFLAGS-win32 = @@DEBUG@@ -pipe -fno-keep-inline-dllexport -O2 -Wall -Wextra $(DEFINES)
+CXXFLAGS-win32 = @@DEBUG@@ -pipe -fno-keep-inline-dllexport -O2 -frtti -Wall -Wextra -fexceptions -mthreads $(DEFINES)
+
+CFLAGS = $(CFLAGS-$(OS)$(ARCH))
+CXXFLAGS = $(CXXFLAGS-$(OS)$(ARCH))
+
+INCPATH-lin64-qt4 = -I/usr/share/qt4/mkspecs/linux-g++ -I$(QTPATH)/QtCore -I$(QTPATH)/QtGui -I$(QTPATH)/QtNetwork -I$(QTPATH)/QtXml -I$(QTPATH)/QtXmlPatterns -I$(QTPATH)
+INCPATH-lin64-qt5 = -I$(QTPATH)/mkspecs/linux-g++-64 -I$(QTPATH) -I$(QTPATH)/QtWidgets -I$(QTPATH)/QtCore -I$(QTPATH)/QtGui -I$(QTPATH)/QtPrintSupport -I$(QTPATH)/QtNetwork -I$(QTPATH)/QtXml -I$(QTPATH)/QtXmlPatterns
+INCPATH-win32-qt5 = -I$(QTPATH)/mkspecs/win32-g++ -I$(QTPATH)/include -I$(QTPATH)/include/ActiveQt -I$(QTPATH)/include/QtWidgets -I$(QTPATH)/include/QtGui -I$(QTPATH)/include/QtCore -I$(QTPATH)/include/QtXml -I$(QTPATH)/include/QtXmlPatterns -I$(QTPATH)/include/QtPrintSupport
+
+INCPATH = $(INCPATH-$(OS)$(ARCH)-qt$(QTVER)) -I.
+
+################## LINKER #####################
+LINK-lin32 = g++
+LINK-lin64 = g++
+LINK-win32 = i686-w64-mingw32-g++-win32
+LINK-win64 = x86_64-w64-mingw32-g++-win32
+
+LINK = $(LINK-$(OS)$(ARCH))
+
+LFLAGS-lin32 = -m32 -Wl,-O1
+LFLAGS-lin64 = -m64 -Wl,-O1
+LFLAGS-win32 = -Wl,-s -mthreads -Wl,-subsystem,console -mthreads -static-libgcc -static-libstdc++
+LFLAGS-win64 = -Wl,-s -mthreads -Wl,-subsystem,console -mthreads -static-libgcc -static-libstdc++
+
+LFLAGS = $(LFLAGS-$(OS)$(ARCH))
+
+LIBS-lin64-qt4 = -lQtCore -lQtGui -lQtXml -lQtXmlPatterns -lpthread -lm
+LIBS-lin64-qt5 = -lQt5Core -lQt5Gui -lQt5Xml -lQt5XmlPatterns -lQt5Widgets -lQt5PrintSupport -lQt5Network -lpthread -lm
+LIBS-win32-qt5 = -lmingw32 -L$(QTPATH)/lib -lqtmain -lQt5AxContainer -lQt5PrintSupport -lQt5AxBase -lglu32 -lopengl32 -lole32 -loleaut32 -luser32 -lgdi32 -ladvapi32 -luuid -lQt5Widgets -lQt5Gui -lQt5Core -lQt5Xml -lQt5XmlPatterns -lQt5Network -lm -lws2_32
+
+LIBS = $(LIBS-$(OS)$(ARCH)-qt$(QTVER))
+
+################## OBJECTS #####################
+include object-files.txt
+
+OBJ-lin = $(COMMON-OBJ)
+OBJ-win = $(COMMON-OBJ) $(BUILDPATH)/$(APPNAME)_res.o
+
+OBJ = $(OBJ-$(OS))
+
+################## EXECUTBALE ####################
+EXENAME-lin = $(APPNAME)
+EXENAME-win = $(APPNAME).exe
+
+EXENAME = $(EXENAME-$(OS))
+
+all: $(BUILDPATH)/$(EXENAME)
+
+$(BUILDPATH)/$(EXENAME) : $(OBJ)
+ $(LINK) $(LFLAGS) -o $@ $^ $(LIBS)
+ cp $(BUILDPATH)/$(EXENAME) .
+
+$(BUILDPATH)/$(APPNAME)_res.o: $(APPNAME).rc
+ $(WINDRES) -i $(APPNAME).rc -o $(BUILDPATH)/$(APPNAME)_res.o --include-dir=. $(DEFINES)
+
+################## DISTRIBUTION ARCHIVE #####################
+DISTNAME = dist-$(OS)
+
+dist : $(DISTNAME)
+
+dist-lin: $(BUILDPATH)/$(APPNAME)
+ @echo -n creating binary distribution archive for Linux ...
+ @-rm -rf $(DISTPATH)
+ @-mkdir -p $(DISTPATH)
+ @-mkdir -p $(DISTPATH)/locales
+ @cp $(BUILDPATH)/$(APPNAME) $(DISTPATH)
+ @if ls $(APPNAME)_*.qm 2>/dev/null 1>&2; then for loc in $(APPNAME)_*.qm; do cp $$loc $(DISTPATH)/locales; done; fi
+ @cp install.sh $(DISTPATH)
+ @if [ -d examples ]; then cp -r examples $(DISTPATH); fi
+ @cd $(DISTPATH); cd ..; tar zcf $(APPNAME)-$(VERSION)_$(OS)$(ARCH).tgz $(APPNAME)-$(VERSION); rm -rf $(APPNAME)-$(VERSION)
+ @echo done; echo result is in $(DISTDIR)/$(OS)$(ARCH)/$(APPNAME)-$(VERSION)_$(OS)$(ARCH).tgz
+
+dist-win: $(BUILDPATH)/$(EXENAME)
+ @echo -n creating binary distribution archive for Windows ...
+ @rm -rf $(DISTPATH)
+ @mkdir -p $(DISTPATH)
+ @cp $(BUILDPATH)/$(APPNAME).exe $(DISTPATH)
+ @cp -r lib/$(OS)$(ARCH)/* $(DISTPATH)
+ @if ls $(APPNAME)_*.qm 2>/dev/null 1>&2; then for loc in $(APPNAME)_*.qm; do cp $$loc $(DISTPATH); done; fi
+ @if [ -d examples ]; then cp -r examples $(DISTPATH); fi
+ @cd $(DISTPATH); cd ..; zip -r $(APPNAME)-$(VERSION)_$(OS)$(ARCH).zip $(APPNAME)-$(VERSION)/* ; rm -rf $(APPNAME)-$(VERSION)
+ @echo done; echo result is in $(DISTDIR)/$(OS)$(ARCH)/$(APPNAME)-$(VERSION)_$(OS)$(ARCH).zip
+
+src-dist:
+ @echo -n creating source archive ...
+ @rm -rf $(ARPATH)
+ @mkdir -p $(ARPATH)
+ @cp *.cpp $(ARPATH)
+ @cp *.h $(ARPATH)
+# copying various files: translations (.ts), locales (.qm), resources (.qrc), xml related (.xml,.xsd), config. files (.conf) ...
+ @if ls $(APPNAME)_*.ts 2>/dev/null 1>&2; then for loc in $(APPNAME)_*.ts; do cp $$loc $(ARPATH); done; fi
+ @if ls $(APPNAME)_*.qm 2>/dev/null 1>&2; then for loc in $(APPNAME)_*.qm; do cp $$loc $(ARPATH); done; fi
+ @if ls *.conf 2>/dev/null 1>&2; then for loc in *.conf; do cp $$loc $(ARPATH); done; fi
+ @if ls *.xml 2>/dev/null 1>&2; then for loc in *.xml; do cp $$loc $(ARPATH); done; fi
+ @if ls *.xsd 2>/dev/null 1>&2; then for loc in *.xsd; do cp $$loc $(ARPATH); done; fi
+ @if [ -f $(APPNAME).qrc ]; then cp $(APPNAME).qrc $(ARPATH); fi
+ @if [ -d icons ]; then cp -r icons $(ARPATH); fi
+ @if [ -d examples ]; then cp -r examples $(ARPATH); fi
+ @cp -r lib $(ARPATH)
+ @cp install.sh.in $(ARPATH)
+ @cp Makefile.in $(ARPATH)
+ @cp object-files.txt $(ARPATH)
+ @cp configure $(ARPATH)
+ @if [ -f $(APPNAME).rc ]; then cp $(APPNAME).rc $(ARPATH); fi
+ @if [ -f $(APPNAME).ico ]; then cp $(APPNAME).ico $(ARPATH); fi
+ @cp $(APPNAME).creator $(ARPATH)
+ @if [ -f $(APPNAME).creator.user ]; then cp $(APPNAME).creator.user $(ARPATH); fi
+ @cp $(APPNAME).files $(ARPATH)
+ @cp $(APPNAME).includes $(ARPATH)
+ @if [ -f $(APPNAME).config ]; then cp $(APPNAME).config $(ARPATH); fi
+ @cd $(ARPATH); cd ../..; tar zcf $(APPNAME)-$(VERSION)-src.tgz $(APPNAME); rm -rf $(APPNAME)
+ @echo done; echo result is in $(ARDIR)/$(APPNAME)-$(VERSION)-src.zip
+clean:
+ rm -f $(OBJ)
+ rm -f *~
+ rm -f moc_*.cpp
+ rm -f rcc_*.cpp
+ rm -f $(BUILDPATH)/$(EXENAME)
+ rm -f $(EXENAME)
+
+### NEW RULES ###
+$(BUILDPATH)/%.o : %.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+moc_%.cpp : %.h
+ moc -qt=$(QTVER) $(DEFINES) $(INCPATH) $< -o $@
+
+rcc_%.cpp : %.qrc
+ rcc -qt=$(QTVER) $< -o $@ -name $*
+
+### DEPENDENCIES OF EACH SOURCE FILE (auto-added by configure) ###
+
--- /dev/null
+#include "Parameters.h"\r
+\r
+#include "Dispatcher.h"\r
+#include "BlockLibraryTree.h"\r
+\r
+#include "BlockCategory.h"\r
+\r
+#include "GroupWidget.h"\r
+#include "GroupScene.h"\r
+#include "GroupItem.h"\r
+#include "BoxItem.h"\r
+#include "InterfaceItem.h"\r
+#include "ConnectionItem.h"\r
+\r
+#include "Graph.h"\r
+#include "ReferenceBlock.h"\r
+#include "GroupBlock.h"\r
+#include "FunctionalBlock.h"\r
+#include "ReferenceInterface.h"\r
+#include "GroupInterface.h"\r
+#include "FunctionalInterface.h"\r
+\r
+#include "Exception.h"\r
+#include "BlocksToConfigureWidget.h"\r
+\r
+Parameters::Parameters() {\r
+ categoryTree = NULL;\r
+ arrowWidth = 5;\r
+ arrowHeight = 10;\r
+ arrowLineLength = 10;\r
+\r
+ defaultBlockWidth = 100;\r
+ defaultBlockHeight = 100;\r
+ defaultBlockFont = QFont("Arial");\r
+ defaultBlockFontSize = 12;\r
+\r
+ setArrowPathes();\r
+\r
+ sceneMode = MODE_EDITION; // default mode\r
+ editState = Parameters::EditNoOperation;\r
+\r
+ unsaveModif = false;\r
+ isRstClkShown = false;\r
+\r
+ projectPath = QDir::currentPath();\r
+}\r
+\r
+Parameters::~Parameters() {\r
+ clear();\r
+}\r
+\r
+void Parameters::clear() {\r
+ delete categoryTree;\r
+ QListIterator<ReferenceBlock *> iter(availableBlocks);\r
+ while(iter.hasNext()) {\r
+ ReferenceBlock* item = iter.next();\r
+ delete item;\r
+ }\r
+ availableBlocks.clear();\r
+ refPathes.clear();\r
+}\r
+\r
+Graph* Parameters::createGraph() {\r
+ graph = new Graph();\r
+ return graph;\r
+}\r
+\r
+void Parameters::destroyGraph() {\r
+ delete graph;\r
+}\r
+\r
+GroupBlock* Parameters::addGroupBlock() {\r
+ GroupBlock* parent = AB_TO_GRP(currentScene->getGroupItem()->getRefBlock());\r
+ GroupBlock* newOne = graph->createChildBlock(parent);\r
+ return newOne;\r
+}\r
+\r
+FunctionalBlock* Parameters::addFunctionalBlock(int idCategory, int idBlock) {\r
+\r
+ BlockCategory* blockCat = categoryTree->searchCategory(idCategory);\r
+\r
+ if (blockCat == NULL) return NULL;\r
+ GroupBlock* group = AB_TO_GRP(currentScene->getGroupItem()->getRefBlock());\r
+ ReferenceBlock* ref = blockCat->getBlock(idBlock);\r
+ if (ref == NULL) return NULL;\r
+\r
+ FunctionalBlock* newOne = graph->addFunctionalBlock(group, ref);\r
+ unsaveModif = true;\r
+\r
+ return newOne;\r
+}\r
+\r
+FunctionalBlock* Parameters::duplicateFunctionalBlock(FunctionalBlock *block) {\r
+\r
+ ReferenceBlock* ref = block->getReference();\r
+ GroupBlock* group = AB_TO_GRP(block->getParent());\r
+\r
+ // adding to the group\r
+ FunctionalBlock* newBlock = new FunctionalBlock(group,ref);\r
+ newBlock->populate();\r
+ group->addBlock(newBlock);\r
+\r
+ return newBlock;\r
+}\r
+\r
+void Parameters::validateXmlFile(const QString& xmlFileName, const QString& xsdFileName, XmlFileType fileType) throw(Exception) {\r
+ // opening configFile\r
+ QFile xmlFile(xmlFileName);\r
+ if (!xmlFile.open(QIODevice::ReadOnly)) {\r
+ if (fileType == Configuration) {\r
+ throw(Exception(CONFIGFILE_NOACCESS));\r
+ }\r
+ else if (fileType == Reference) {\r
+ throw(Exception(BLOCKFILE_NOACCESS));\r
+ }\r
+ else if (fileType == Implementation) {\r
+ throw(Exception(IMPLFILE_NOACCESS));\r
+ }\r
+ else if (fileType == Project) {\r
+ throw(Exception(PROJECTFILE_NOACCESS));\r
+ }\r
+ }\r
+\r
+ QFile xsdFile(xsdFileName);\r
+ if (!xsdFile.open(QIODevice::ReadOnly)) {\r
+ xsdFile.close();\r
+ if (fileType == Configuration) {\r
+ throw(Exception(CONFIGFILE_NOACCESS));\r
+ }\r
+ else if (fileType == Reference) {\r
+ throw(Exception(BLOCKFILE_NOACCESS));\r
+ }\r
+ else if (fileType == Implementation) {\r
+ throw(Exception(IMPLFILE_NOACCESS));\r
+ }\r
+ else if (fileType == Project) {\r
+ throw(Exception(PROJECTFILE_NOACCESS));\r
+ }\r
+ }\r
+\r
+ if(validate(xmlFile,xsdFile) == false) {\r
+ xmlFile.close();\r
+ xsdFile.close();\r
+ if (fileType == Configuration) {\r
+ throw(Exception(CONFIGFILE_CORRUPTED));\r
+ }\r
+ else if (fileType == Reference) {\r
+ throw(Exception(BLOCKFILE_CORRUPTED));\r
+ }\r
+ else if (fileType == Implementation) {\r
+ throw(Exception(IMPLFILE_CORRUPTED));\r
+ }\r
+ else if (fileType == Project) {\r
+ throw(Exception(PROJECTFILE_CORRUPTED));\r
+ }\r
+ }\r
+ xmlFile.close();\r
+ xsdFile.close();\r
+}\r
+\r
+bool Parameters::validate(QFile& fileXml, QFile& fileSchema) {\r
+\r
+ // 2 files are supposed to be already opened\r
+ QXmlSchema schema;\r
+\r
+ if(! schema.load(&fileSchema)){\r
+ cout << "invalid schema" << endl;\r
+ return false;\r
+ }\r
+\r
+ QXmlSchemaValidator validator(schema);\r
+\r
+ if(! validator.validate(&fileXml)){\r
+ cout << "invalid xml" << endl;\r
+ return false;\r
+ }\r
+ return true;\r
+}\r
+\r
+QDomElement Parameters::openProjectFile(const QString& projectFileName) throw(Exception) {\r
+\r
+ try {\r
+ validateXmlFile(projectFileName,"projectfile.xsd",Project);\r
+ }\r
+ catch(Exception err) {\r
+ throw(err);\r
+ }\r
+\r
+ QFile projectFile(projectFileName);\r
+ QDomDocument doc("projectFile");\r
+\r
+ if(!projectFile.open(QIODevice::ReadOnly)) {\r
+ throw(Exception(PROJECTFILE_NOACCESS));\r
+ }\r
+ if(!doc.setContent(&projectFile)) {\r
+ projectFile.close();\r
+ throw(Exception(PROJECTFILE_CORRUPTED));\r
+ }\r
+ projectFile.close();\r
+\r
+ QDomElement root = doc.documentElement();\r
+\r
+ return root;\r
+}\r
+\r
+void Parameters::loadProject(QDomElement root) {\r
+\r
+#ifdef DEBUG_INCLFUN\r
+\r
+ bool ok = false;\r
+ GroupWidget* groupWidget = NULL;\r
+ GroupItem *groupItem = NULL;\r
+ GroupBlock *groupBlock = NULL;\r
+\r
+ /**********************************************************\r
+ 1 : getting scene and creating associated group widgets\r
+ ***********************************************************/\r
+ QDomNodeList scenesNodes = root.elementsByTagName("scene");\r
+\r
+ for(int i=0; i<scenesNodes.length(); i++) {\r
+ QDomElement currentSceneNode = scenesNodes.at(i).toElement();\r
+ int idScene = currentSceneNode.attribute("id","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int idUpperScene = currentSceneNode.attribute("upper_scene","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ if (idUpperScene == -1) {\r
+ dispatcher->createTopScene();\r
+ topScene->setId(idScene);\r
+ groupItem = topScene->getGroupItem();\r
+ groupBlock = AB_TO_GRP(groupItem->getRefBlock());\r
+ cout << "top group added to scene n°" << idScene << endl;\r
+ }\r
+ else {\r
+ GroupScene* scene = searchSceneById(idUpperScene, topScene);\r
+ GroupWidget* parent = scene->getGroupWindow();\r
+ groupWidget = dispatcher->createChildScene(parent);\r
+ groupItem = groupWidget->getScene()->getGroupItem();\r
+ groupBlock = AB_TO_GRP(groupItem->getRefBlock());\r
+ }\r
+ /**********************************************************\r
+ 1.1 : getting the group item\r
+ ***********************************************************/\r
+ QDomElement groupItemNode = currentSceneNode.firstChildElement("group_item");\r
+\r
+ int id = groupItemNode.attribute("id","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString name = groupItemNode.attribute("name","none");\r
+ if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QStringList positionStr = groupItemNode.attribute("position","none").split(",");\r
+ if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int posX = positionStr.at(0).toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int posY = positionStr.at(1).toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QStringList dimensionStr = groupItemNode.attribute("dimension","none").split(",");\r
+ if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int dimX = dimensionStr.at(0).toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int dimY = dimensionStr.at(1).toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ groupItem->setId(id);\r
+ groupItem->setPos(posX,posY);\r
+ groupItem->setDimension(dimX,dimY);\r
+ groupBlock->setName(name);\r
+\r
+ if (idUpperScene != -1) {\r
+ groupWidget->setWindowTitle(groupBlock->getName());\r
+ groupWidget->show();\r
+ }\r
+ cout << "group info : \n-id : " << id << "\n-pos : " << posX << ", " << posY << "\n-dim : " << dimX << ", " << dimY << "\n-name : " << name.toStdString() << endl;\r
+\r
+ QDomNodeList interfaces = groupItemNode.elementsByTagName("group_iface");\r
+ for(int j=0; j<interfaces.length(); j++){\r
+ QDomElement currentInterfaceNode = interfaces.at(j).toElement();\r
+\r
+ int id = currentInterfaceNode.attribute("id","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString name = currentInterfaceNode.attribute("name","none");\r
+ if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString levelStr = currentInterfaceNode.attribute("level","none");\r
+ int level = AbstractInterface::getIntLevel(levelStr);\r
+ if(level == -1) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString directionStr = currentInterfaceNode.attribute("direction","none");\r
+ int direction = AbstractInterface::getIntDirection(directionStr);\r
+ if(direction == -1) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString orientationStr = currentInterfaceNode.attribute("orientation","none");\r
+ int orientation = InterfaceItem::getIntOrientation(orientationStr);\r
+ if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ GroupInterface *groupInterface = new GroupInterface(groupBlock,name,direction,level);\r
+\r
+ InterfaceItem *interfaceItem = new InterfaceItem(position,orientation,groupInterface,groupItem,this);\r
+ interfaceItem->setId(id);\r
+\r
+ groupBlock->addInterface(groupInterface);\r
+ groupItem->addInterface(interfaceItem);\r
+ cout << "interface add to " << groupBlock->getName().toStdString() << endl;\r
+ }\r
+ }\r
+\r
+ cout << "groupItems loaded and windows created succefully!" << endl;\r
+\r
+\r
+ for(int i=0; i<scenesNodes.length(); i++){\r
+ QDomElement currentSceneNode = scenesNodes.at(i).toElement();\r
+ int idScene = currentSceneNode.attribute("id","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ cout << "SCENE : " << idScene << endl;\r
+ GroupScene *currentScene = searchSceneById(idScene,topScene);\r
+\r
+ if(currentScene == NULL) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QDomNodeList functionalBlockNodes = currentSceneNode.elementsByTagName("bi_functional");\r
+\r
+ for(int j=0; j<functionalBlockNodes.length(); j++){\r
+ QDomElement currentFBNode = functionalBlockNodes.at(j).toElement();\r
+\r
+ int id = currentFBNode.attribute("id","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString refXml = currentFBNode.attribute("ref_xml","none");\r
+ if(refXml == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString refMd5 = currentFBNode.attribute("ref_md5","none");\r
+ if(refMd5 == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ cout << "ref md5 : " << refMd5.toStdString() << "\nref xml : " << refXml.toStdString() << endl;\r
+\r
+ QString name = currentFBNode.attribute("name","none");\r
+ if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QStringList positionStr = currentFBNode.attribute("position","none").split(",");\r
+ if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int posX = positionStr.at(0).toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int posY = positionStr.at(1).toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QStringList dimensionStr = currentFBNode.attribute("dimension","none").split(",");\r
+ if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int dimX = dimensionStr.at(0).toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int dimY = dimensionStr.at(1).toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ AbstractBlock *reference;\r
+ /*if(refMd5 != "none"){\r
+ cout << "md5" << endl;\r
+ reference = searchBlockByMd5(refMd5);\r
+ }\r
+ else */if(refXml != "none"){\r
+ cout << "xml" << endl;\r
+ reference = searchBlockByXml(refXml);\r
+ }\r
+ else {\r
+ throw(Exception(PROJECTFILE_CORRUPTED));\r
+ }\r
+\r
+ FunctionalBlock *functionalBlock = new FunctionalBlock(currentScene->getGroupItem()->getRefBlock(),reference);\r
+ functionalBlock->setName(name);\r
+\r
+ ((GroupBlock*)currentScene->getGroupItem()->getRefBlock())->addBlock(functionalBlock);\r
+\r
+\r
+ BlockItem *blockItem = new BlockItem(currentScene->getGroupItem(),functionalBlock,dispatcher,this);\r
+ blockItem->setPos(posX,posY);\r
+ blockItem->setDimension(dimX,dimY);\r
+ blockItem->setId(id);\r
+ ((GroupItem*)currentScene->getGroupItem())->addBlockItem(blockItem);\r
+ currentScene->addItem(blockItem);\r
+ currentScene->addBlockItem(blockItem);\r
+\r
+ QDomNodeList blockParamNodes = currentFBNode.elementsByTagName("bif_parameter");\r
+\r
+ for(int i=0; i<blockParamNodes.length(); i++){\r
+ QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement();\r
+\r
+ QString name = currentBlockParamNode.attribute("name","none");\r
+ if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString value = currentBlockParamNode.attribute("value","none");\r
+ if(value == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString context = currentBlockParamNode.attribute("context","none");\r
+ if(context == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString type = currentBlockParamNode.attribute("type","none");\r
+ if(type == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+\r
+ BlockParameter *blockParam = new BlockParameter;\r
+ blockParam->setName(name);\r
+ blockParam->setValue(value);\r
+ blockParam->setType(type);\r
+ if(context == "constant") blockParam->setContext(BlockParameter::Constant);\r
+ if(context == "user") blockParam->setContext(BlockParameter::User);\r
+ if(context == "generic") blockParam->setContext(BlockParameter::Generic);\r
+ if(context == "wb") blockParam->setContext(BlockParameter::Wishbone);\r
+ if(context == "port") blockParam->setContext(BlockParameter::Port);\r
+\r
+ functionalBlock->addParameter(blockParam);\r
+ }\r
+\r
+\r
+ QDomNodeList interfaceNodes = currentFBNode.elementsByTagName("bif_iface");\r
+\r
+ for(int i=0; i<interfaceNodes.length(); i++){\r
+\r
+ QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();\r
+\r
+ int id = currentInterfaceNode.attribute("id","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString name = currentInterfaceNode.attribute("name","none");\r
+ if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString refName = currentInterfaceNode.attribute("ref_name","none");\r
+ if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString orientationStr = currentInterfaceNode.attribute("orientation","none");\r
+ int orientation = InterfaceItem::getIntOrientation(orientationStr);\r
+ if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ ReferenceInterface *refInter = (ReferenceInterface*)reference->getIfaceFromName(refName);\r
+ FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter);\r
+ functionalBlock->addInterface(functionalInterface);\r
+ functionalInterface->setName(refName);\r
+\r
+ InterfaceItem *interfaceItem = new InterfaceItem(position,orientation,functionalInterface,blockItem,this);\r
+ interfaceItem->setId(id);\r
+ interfaceItem->setName(name);\r
+\r
+ blockItem->addInterface(interfaceItem);\r
+\r
+ }\r
+ }\r
+ }\r
+ cout << "functionalBlocks loaded and created succefully!" << endl;\r
+\r
+\r
+ for(int i=0; i<scenesNodes.length(); i++){\r
+ QDomElement currentSceneNode = scenesNodes.at(i).toElement();\r
+ int idScene = currentSceneNode.attribute("id","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ GroupScene *currentScene = searchSceneById(idScene, topScene);\r
+ if(currentScene == NULL) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QDomNodeList biGroupNodes = currentSceneNode.elementsByTagName("bi_group");\r
+\r
+ for(int j=0; j<biGroupNodes.length(); j++){\r
+ QDomElement currentBiGroup = biGroupNodes.at(j).toElement();\r
+\r
+ int id = currentBiGroup.attribute("id","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ int idGroup = currentBiGroup.attribute("inside_group","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QStringList positionStr = currentBiGroup.attribute("position","none").split(",");\r
+ if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int posX = positionStr.at(0).toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int posY = positionStr.at(1).toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QStringList dimensionStr = currentBiGroup.attribute("dimension","none").split(",");\r
+ if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int dimX = dimensionStr.at(0).toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int dimY = dimensionStr.at(1).toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+\r
+ GroupItem *insideGroup = searchGroupItemById(idGroup, topScene);\r
+ if(insideGroup == NULL) cout << "group null" << endl;\r
+ BlockItem *blockItem = new BlockItem(insideGroup->getRefBlock(), dispatcher, this);\r
+ blockItem->setChildGroupItem(insideGroup);\r
+ blockItem->setId(id);\r
+ blockItem->setPos(posX,posY);\r
+ blockItem->setDimension(dimX,dimY);\r
+\r
+ ((GroupItem*)currentScene->getGroupItem())->addBlockItem(blockItem);\r
+ currentScene->addItem(blockItem);\r
+ currentScene->addBlockItem(blockItem);\r
+\r
+ QDomNodeList interfaceNodes = currentBiGroup.elementsByTagName("big_iface");\r
+\r
+ for(int k=0; k<interfaceNodes.length(); k++){\r
+ QDomElement currentInterfaceNode = interfaceNodes.at(k).toElement();\r
+\r
+ int id = currentInterfaceNode.attribute("id","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString refName = currentInterfaceNode.attribute("ref_name","none");\r
+ if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ QString orientationStr = currentInterfaceNode.attribute("orientation","none");\r
+ int orientation = InterfaceItem::getIntOrientation(orientationStr);\r
+ if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ GroupInterface *refInter = (GroupInterface*)insideGroup->searchInterfaceByName(refName)->refInter;\r
+ InterfaceItem *ifaceItem = new InterfaceItem(position, orientation, refInter, blockItem, this);\r
+ ifaceItem->setId(id);\r
+ blockItem->addInterface(ifaceItem);\r
+ }\r
+ }\r
+ }\r
+ cout << "blockItems \"group\" loaded and created succefully!" << endl;\r
+\r
+\r
+ for(int i=0; i<scenesNodes.length(); i++){\r
+ QDomElement currentSceneNode = scenesNodes.at(i).toElement();\r
+\r
+ QDomElement groupItemNode = currentSceneNode.firstChildElement("group_item");\r
+\r
+ int id = groupItemNode.attribute("id","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+ int idUpperItem = groupItemNode.attribute("upper_item","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ BlockItem *currentItem = searchBlockItemById(id,topScene);\r
+ GroupItem *upperItem = searchGroupItemById(idUpperItem, topScene);\r
+\r
+ if(currentItem != NULL && upperItem != NULL){\r
+ currentItem->setUpperItem(upperItem);\r
+ }\r
+ }\r
+\r
+ QDomNodeList connectionNodes = root.elementsByTagName("connection");\r
+\r
+ for(int i=0; i<connectionNodes.length(); i++){\r
+ QDomElement currentConnectionNode = connectionNodes.at(i).toElement();\r
+\r
+ int from = currentConnectionNode.attribute("from","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+ int to = currentConnectionNode.attribute("to","none").toInt(&ok);\r
+ if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));\r
+\r
+\r
+ InterfaceItem *iface1 = searchInterfaceItemById(from,topScene);\r
+ InterfaceItem *iface2 = searchInterfaceItemById(to,topScene);\r
+\r
+ if(iface1 != NULL && iface2 != NULL){\r
+ dispatcher->connect(iface1,iface2);\r
+ } else {\r
+ cout << "interfaces not found, connect canceled!" << endl;\r
+ }\r
+ }\r
+\r
+#endif\r
+}\r
+\r
+void Parameters::loadBlastConfiguration(QString confFile) throw(Exception) {\r
+\r
+ try {\r
+ validateXmlFile("blastconfig.xml", "blastconfig.xsd",Configuration);\r
+ }\r
+ catch(Exception err) {\r
+ throw(err);\r
+ }\r
+\r
+ bool ok;\r
+ // opening configFile\r
+ QFile configFile(confFile);\r
+ // reading in into QDomDocument\r
+ QDomDocument document("configFile");\r
+\r
+ if (!configFile.open(QIODevice::ReadOnly)) {\r
+ throw(Exception(CONFIGFILE_NOACCESS));\r
+ }\r
+ if (!document.setContent(&configFile)) {\r
+ configFile.close();\r
+ throw(Exception(CONFIGFILE_NOACCESS));\r
+ }\r
+ configFile.close();\r
+\r
+ //Get the root element\r
+ QDomElement config = document.documentElement();\r
+\r
+ QDomElement eltCat = config.firstChildElement("categories");\r
+ try {\r
+ categoryTree = new BlockLibraryTree();\r
+ categoryTree->load(eltCat);\r
+ }\r
+ catch(Exception err) {\r
+ throw(err);\r
+ }\r
+\r
+ QDomElement eltReferences = eltCat.nextSiblingElement("references");\r
+ refLib = eltReferences.attribute("lib_file","none");\r
+ cout << "references lib : " << qPrintable(refLib) << endl;\r
+ int nbPathes;\r
+ QString nbPathesStr;\r
+ nbPathesStr = eltReferences.attribute("nb","none");\r
+ nbPathes = nbPathesStr.toInt(&ok);\r
+ QDomNodeList listBlockDir = eltReferences.elementsByTagName("reference_lib");\r
+ if ((!ok) || (nbPathes != listBlockDir.size())) throw(Exception(CONFIGFILE_CORRUPTED));\r
+\r
+ for(int i=0;i<listBlockDir.size();i++) {\r
+ QDomNode nodeBlockDir = listBlockDir.at(i);\r
+ QDomElement eltBlockDir = nodeBlockDir.toElement();\r
+ if (eltBlockDir.isNull()) throw(Exception(CONFIGFILE_CORRUPTED));\r
+ QString path = eltBlockDir.attribute("path","none");\r
+ if (path == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
+ refPathes.append(path);\r
+ cout << "references path : " << qPrintable(path) << endl;\r
+ }\r
+\r
+ QDomElement eltImpl = eltReferences.nextSiblingElement("implementations");\r
+ implLib = eltImpl.attribute("lib_file","none");\r
+ cout << "implementation lib : " << qPrintable(implLib) << endl;\r
+ nbPathesStr = eltImpl.attribute("nb","none");\r
+ nbPathes = nbPathesStr.toInt(&ok);\r
+ QDomNodeList listImplDir = eltImpl.elementsByTagName("impl_lib");\r
+ if ((!ok) || (nbPathes != listImplDir.size())) throw(Exception(CONFIGFILE_CORRUPTED));\r
+\r
+ for(int i=0;i<listImplDir.size();i++) {\r
+ QDomNode nodeImplDir = listImplDir.at(i);\r
+ QDomElement eltImplDir = nodeImplDir.toElement();\r
+ if (eltImplDir.isNull()) throw(Exception(CONFIGFILE_CORRUPTED));\r
+ QString path = eltImplDir.attribute("path","none");\r
+ if (path == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
+ implPathes.append(path);\r
+ cout << "impl path : " << qPrintable(path) << endl << endl;\r
+ }\r
+ // getting elt = the element <defaults>\r
+ // for each child element, initialize the associated attributes of Parameters\r
+\r
+ QDomElement eltDefaults = eltImpl.nextSiblingElement("defaults");\r
+\r
+ QDomElement eltBlocks = eltDefaults.firstChildElement("blocks");\r
+ QString attributeStr = eltBlocks.attribute("width", "none");\r
+ defaultBlockWidth = attributeStr.toInt(&ok);\r
+ if (!ok || defaultBlockWidth < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
+ attributeStr = eltBlocks.attribute("height", "none");\r
+ defaultBlockHeight = attributeStr.toInt(&ok);\r
+ if (!ok || defaultBlockHeight < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
+ attributeStr = eltBlocks.attribute("font_size", "none");\r
+ defaultBlockFontSize = attributeStr.toFloat(&ok);\r
+ if (!ok || defaultBlockFontSize < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
+ attributeStr = eltBlocks.attribute("font", "none");\r
+ if (attributeStr == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
+ defaultBlockFontName = attributeStr;\r
+ defaultBlockFont = QFont(defaultBlockFontName, defaultBlockFontSize);\r
+\r
+ QDomElement eltInterfaces = eltBlocks.nextSiblingElement("interfaces");\r
+ attributeStr = eltInterfaces.attribute("width", "none");\r
+ arrowWidth = attributeStr.toInt(&ok);\r
+ if (!ok || arrowWidth < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
+ attributeStr = eltInterfaces.attribute("height", "none");\r
+ arrowHeight = attributeStr.toInt(&ok);\r
+ if (!ok || arrowHeight < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
+ attributeStr = eltInterfaces.attribute("linelength", "none");\r
+ arrowLineLength = attributeStr.toInt(&ok);\r
+ if (!ok || arrowLineLength < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
+ attributeStr = eltInterfaces.attribute("font_size", "none");\r
+ defaultIfaceFontSize = attributeStr.toFloat(&ok);\r
+ if (!ok || defaultIfaceFontSize < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
+ attributeStr = eltInterfaces.attribute("font", "none");\r
+ if (attributeStr == "none") throw(Exception(CONFIGFILE_CORRUPTED));\r
+ defaultIfaceFontName = attributeStr;\r
+ defaultIfaceFont = QFont(defaultIfaceFontName, defaultIfaceFontSize);\r
+\r
+ QDomElement eltConnections = eltInterfaces.nextSiblingElement("connections");\r
+ attributeStr = eltConnections.attribute("gaplength", "none");\r
+ connGapLength = attributeStr.toInt(&ok);\r
+ if (!ok || connGapLength < 1) throw(Exception(CONFIGFILE_CORRUPTED));\r
+}\r
+\r
+void Parameters::loadReferencesFromXml() throw(Exception) {\r
+ cout << "load references from xml" << endl;\r
+ for(int i=0;i<refPathes.size();i++) {\r
+ cout << "analyzing " << qPrintable(refPathes.at(i)) << endl;\r
+ QDir dir(refPathes.at(i));\r
+ QStringList filter;\r
+ filter << "*.xml";\r
+ dir.setNameFilters(filter);\r
+ QStringList list = dir.entryList();\r
+ for(int j=0;j<list.size();j++) {\r
+ QString fileName = dir.absolutePath();\r
+ fileName.append("/"+list.at(j));\r
+\r
+ QFile blockXML(fileName);\r
+ if (!blockXML.open(QIODevice::ReadOnly)) {\r
+ throw(Exception(BLOCKFILE_NOACCESS));\r
+ }\r
+ QTextStream in(&blockXML);\r
+ QString line = in.readLine();\r
+ line = in.readLine();\r
+\r
+ if (!line.contains("<block>")) {\r
+ blockXML.close();\r
+ continue;\r
+ }\r
+\r
+ blockXML.close();\r
+ try {\r
+ validateXmlFile(fileName,"block.xsd",Reference);\r
+ }\r
+ catch(Exception err) {\r
+ throw(err);\r
+ }\r
+\r
+ // reading in into QDomDocument\r
+ QDomDocument document ("FileXML");\r
+ if (!blockXML.open(QIODevice::ReadOnly)) {\r
+ throw(Exception(BLOCKFILE_NOACCESS));\r
+ }\r
+ if (!document.setContent(&blockXML)) {\r
+ blockXML.close();\r
+ throw(Exception(BLOCKFILE_NOACCESS));\r
+ }\r
+ blockXML.close();\r
+\r
+ QDomElement blockRoot = document.documentElement();\r
+ QString name = blockRoot.tagName();\r
+ if (name == "block") {\r
+\r
+ cout << "xml:" << fileName.toStdString() << endl;\r
+ ReferenceBlock* b = new ReferenceBlock(fileName);\r
+ try {\r
+ b->load(blockRoot);\r
+ b->setHashMd5();\r
+ }\r
+ catch(int err) {\r
+ throw(err);\r
+ }\r
+ cout << "xml:" << b->getXmlFile().toStdString() << endl;\r
+\r
+ availableBlocks.append(b);\r
+ foreach (int id,b->getCategories()) {\r
+ cout << "ajout du bloc dans cat n° : " << id << endl;\r
+ BlockCategory* cat = categoryTree->searchCategory(id);\r
+ cat->blocks.append(b);\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+void Parameters::loadReferencesFromLib() throw(Exception) {\r
+\r
+ cout << "loading references from lib" << endl;\r
+\r
+ // removing blocks from category tree if they exist\r
+ categoryTree->clearBlocks();\r
+ // deleting existings blocks\r
+ ReferenceBlock* b = NULL;\r
+ for(int i=0;i<availableBlocks.size();i++) {\r
+ b = availableBlocks.at(i);\r
+ delete b;\r
+ }\r
+ availableBlocks.clear();\r
+\r
+ QFile libFile(refLib);\r
+ if (!libFile.open(QIODevice::ReadOnly)) {\r
+ throw(Exception(BLOCKFILE_NOACCESS));\r
+ }\r
+ QDataStream in(&libFile);\r
+ quint32 size;\r
+\r
+ in >> size;\r
+\r
+ int nbBlocks;\r
+ in >> nbBlocks;\r
+ for(int i=0;i<nbBlocks;i++) {\r
+ b = new ReferenceBlock("");\r
+ in >> *b;\r
+ availableBlocks.append(b);\r
+ foreach (int id,b->getCategories()) {\r
+ BlockCategory* cat = categoryTree->searchCategory(id);\r
+ cat->blocks.append(b);\r
+ }\r
+ }\r
+ libFile.close();\r
+}\r
+\r
+void Parameters::saveReferencesToLib() throw(Exception) {\r
+\r
+ cout << "saving blocks in " << qPrintable(refLib) << endl;\r
+ QFile libFile(refLib);\r
+ if (!libFile.open(QIODevice::WriteOnly)) {\r
+ throw(Exception(BLOCKFILE_NOACCESS));\r
+ }\r
+ QDataStream out(&libFile);\r
+\r
+ out.setVersion(QDataStream::Qt_5_0);\r
+\r
+ QByteArray blockData;\r
+ QDataStream toWrite(&blockData, QIODevice::WriteOnly);\r
+\r
+ toWrite << availableBlocks.size();\r
+ for(int i=0;i<availableBlocks.size();i++) {\r
+ ReferenceBlock* b = availableBlocks.at(i);\r
+ toWrite << *b;\r
+ }\r
+\r
+ out << blockData;\r
+\r
+ libFile.close();\r
+\r
+}\r
+\r
+void Parameters::loadImplementationsFromXml() throw(Exception) {\r
+\r
+ for(int i=0;i<implPathes.size();i++) {\r
+ cout << "analyzing " << qPrintable(implPathes.at(i)) << endl;\r
+ QDir dir(implPathes.at(i));\r
+ QStringList filter;\r
+ filter << "*.xml";\r
+ dir.setNameFilters(filter);\r
+ QStringList list = dir.entryList();\r
+ for(int j=0;j<list.size();j++) {\r
+ QString fileName = dir.absolutePath();\r
+ fileName.append("/"+list.at(j));\r
+\r
+ cout << "checking " << qPrintable(fileName) << " is an implementation file ...";\r
+ QFile implXML(fileName);\r
+ if (!implXML.open(QIODevice::ReadOnly)) {\r
+ throw(Exception(IMPLFILE_NOACCESS));\r
+ }\r
+ QTextStream in(&implXML);\r
+ QString line = in.readLine();\r
+ line = in.readLine();\r
+\r
+ if (!line.contains("<block_impl")) {\r
+ implXML.close();\r
+ continue;\r
+ }\r
+\r
+ implXML.close();\r
+ cout << "OK" << endl;\r
+ cout << "reading " << qPrintable(fileName) << " content ...";\r
+ /*\r
+ try {\r
+ validateXmlFile(fileName,"block.xsd",Implementation);\r
+ }\r
+ catch(Exception e) {\r
+ throw(e);\r
+ }\r
+ */\r
+ // reading in into QDomDocument\r
+ QDomDocument document ("FileXML");\r
+ if (!implXML.open(QIODevice::ReadOnly)) {\r
+ throw(Exception(IMPLFILE_NOACCESS));\r
+ }\r
+ cout << "OK" << endl;\r
+ cout << "convert " << qPrintable(fileName) << " content into document...";\r
+ if (!document.setContent(&implXML)) {\r
+ implXML.close();\r
+ throw(Exception(IMPLFILE_NOACCESS));\r
+ }\r
+ implXML.close();\r
+\r
+ QDomElement implRoot = document.documentElement();\r
+ QString refXml = implRoot.attribute("ref_name","none");\r
+ QString refMd5 = implRoot.attribute("ref_md5","none");\r
+ BlockImplementation* impl = new BlockImplementation(fileName,refXml,refMd5);\r
+ availableImplementations.append(impl);\r
+\r
+ ReferenceBlock* ref = NULL;\r
+ if (! refMd5.isEmpty()) {\r
+ ref = searchBlockByMd5(refMd5);\r
+ }\r
+ if (ref == NULL) {\r
+ ref = searchBlockByXml(refXml);\r
+ }\r
+ if (ref == NULL) {\r
+ cout << "Cannot find a reference block for impl :" << qPrintable(fileName) << endl;\r
+ }\r
+ ref->addImplementation(impl);\r
+ impl->setReference(ref);\r
+ cout << "OK" << endl;\r
+ }\r
+ }\r
+}\r
+\r
+void Parameters::loadImplementationsFromLib() throw(Exception) {\r
+\r
+ cout << "loading implementations from lib" << endl;\r
+\r
+ BlockImplementation* impl = NULL;\r
+ ReferenceBlock* ref = NULL;\r
+ for(int i=0;i<availableImplementations.size();i++) {\r
+ impl = availableImplementations.at(i);\r
+ delete impl;\r
+ }\r
+ availableImplementations.clear();\r
+\r
+ QFile libFile(implLib);\r
+ if (!libFile.open(QIODevice::ReadOnly)) {\r
+ throw(Exception(IMPLFILE_NOACCESS));\r
+ }\r
+ QDataStream in(&libFile);\r
+ quint32 size;\r
+\r
+ in >> size;\r
+\r
+ int nbImpls;\r
+ in >> nbImpls;\r
+ for(int i=0;i<nbImpls;i++) {\r
+ impl = new BlockImplementation("");\r
+ in >> *impl;\r
+ availableImplementations.append(impl);\r
+ QString refMd5 = impl->getReferenceMd5();\r
+ QString refXml = impl->getReferenceXml();\r
+ ref = NULL;\r
+ if (! refMd5.isEmpty()) {\r
+ ref = searchBlockByMd5(refMd5);\r
+ }\r
+ if (ref == NULL) {\r
+ ref = searchBlockByXml(refXml);\r
+ }\r
+ if (ref == NULL) {\r
+ cout << "Cannot find a reference block for impl :" << qPrintable(impl->getXmlFile()) << endl;\r
+ }\r
+ ref->addImplementation(impl);\r
+ impl->setReference(ref);\r
+ }\r
+ libFile.close();\r
+}\r
+\r
+void Parameters::saveImplementationsToLib() throw(Exception) {\r
+\r
+ cout << "saving implementations in " << qPrintable(implLib) << endl;\r
+ QFile libFile(implLib);\r
+ if (!libFile.open(QIODevice::WriteOnly)) {\r
+ throw(Exception(IMPLFILE_NOACCESS));\r
+ }\r
+ QDataStream out(&libFile);\r
+\r
+ out.setVersion(QDataStream::Qt_5_0);\r
+\r
+ QByteArray blockData;\r
+ QDataStream toWrite(&blockData, QIODevice::WriteOnly);\r
+\r
+ toWrite << availableImplementations.size();\r
+ for(int i=0;i<availableImplementations.size();i++) {\r
+ BlockImplementation* impl = availableImplementations.at(i);\r
+ toWrite << *impl;\r
+ }\r
+\r
+ out << blockData;\r
+\r
+ libFile.close();\r
+\r
+}\r
+void Parameters::addAvailableBlock(ReferenceBlock *block) {\r
+ availableBlocks.append(block);\r
+ foreach (int id,block->getCategories()) {\r
+ cout << "ajout du bloc dans cat n° : " << id << endl;\r
+ BlockCategory* cat = categoryTree->searchCategory(id);\r
+ cat->blocks.append(block);\r
+ }\r
+}\r
+\r
+void Parameters::parametersValidation() {\r
+ QList<AbstractBlock*> blocksToConfigure = getBlocksToConfigure();\r
+\r
+ if(!blocksToConfigure.isEmpty()){\r
+ BlocksToConfigureWidget *widget = new BlocksToConfigureWidget(blocksToConfigure, this, NULL);\r
+ widget->show();\r
+ }\r
+}\r
+\r
+void Parameters::connectionsValidation() {\r
+\r
+#ifdef DEBUG_INCLFUN\r
+\r
+ QStack<AbstractInterface*> *interfaceToValidate = new QStack<AbstractInterface*>;\r
+ QList<AbstractInterface*> *validatedInterface = new QList<AbstractInterface*>;\r
+\r
+ foreach(AbstractInterface *inter, topWindow->getScene()->getGroupItem()->getRefBlock()->getInterfaces()){\r
+ foreach(AbstractInterface *connectedInter, inter->getConnectedTo()){\r
+\r
+ inter->setWidth(connectedInter->getWidth());\r
+ interfaceToValidate->push(connectedInter);\r
+ }\r
+ }\r
+\r
+\r
+ try{\r
+ while(!interfaceToValidate->isEmpty()){\r
+ interfaceToValidate->pop()->connectionsValidation(interfaceToValidate, validatedInterface);\r
+ }\r
+ }\r
+ catch(Exception e){\r
+ cerr << e.getMessage().toStdString() << endl;\r
+ }\r
+#endif\r
+}\r
+\r
+QList<AbstractBlock *> Parameters::getBlocksToConfigure() {\r
+\r
+#ifdef DEBUG_INCLFUN\r
+\r
+ QList<AbstractBlock*> *checkedBlocks = new QList<AbstractBlock*>;\r
+ QList<AbstractBlock*> *blocksToConfigure = new QList<AbstractBlock*>;\r
+\r
+ foreach(AbstractInterface *inter, topWindow->getScene()->getGroupItem()->getRefBlock()->getInterfaces()){\r
+ foreach(AbstractInterface *connectedInter, inter->getConnectedTo()){\r
+ if(!checkedBlocks->contains(connectedInter->getOwner())){\r
+ connectedInter->getOwner()->parametersValidation(checkedBlocks, blocksToConfigure);\r
+ }\r
+ }\r
+ }\r
+ return *blocksToConfigure;\r
+#endif\r
+}\r
+\r
+\r
+void Parameters::updateToolbar() {\r
+ int nb = currentScene->getBlockItems().length();\r
+ for(int i = 0; i<nb; i++){\r
+ if(currentScene->getBlockItems().at(i)->isSelected()){\r
+ currentScene->getGroupWindow()->enableGroupButton(true);\r
+ return;\r
+ }\r
+ }\r
+ currentScene->getGroupWindow()->enableGroupButton(false);\r
+}\r
+\r
+\r
+void Parameters::updateIds() {\r
+\r
+ /* a in-width cross of the graph must be done so that ids of GroupItem\r
+ are in the correct ordre when saving/loading a project\r
+ */\r
+ int countItem = 1;\r
+ int countIface = 1;\r
+ QList<GroupScene *> fifo;\r
+ fifo.append(topScene);\r
+ while (!fifo.isEmpty()) {\r
+ GroupScene* scene = fifo.takeFirst();\r
+ countItem = scene->setItemsId(countItem);\r
+ countIface = scene->setInterfacesId(countIface);\r
+ foreach(GroupScene* s, scene->getChildrenScene()) {\r
+ fifo.append(s);\r
+ }\r
+ }\r
+}\r
+\r
+\r
+ReferenceBlock *Parameters::searchBlockByXml(QString xmlName) {\r
+ foreach(ReferenceBlock *block, availableBlocks){\r
+ if(block->getXmlFile().contains(xmlName))\r
+ return block;\r
+ }\r
+ return NULL;\r
+}\r
+\r
+ReferenceBlock *Parameters::searchBlockByMd5(QString sumMd5) {\r
+ foreach(ReferenceBlock *block, availableBlocks){\r
+ if(block->getHashMd5() == sumMd5)\r
+ return block;\r
+ }\r
+ return NULL;\r
+}\r
+\r
+void Parameters::save(QString confFile) {\r
+\r
+//#ifdef DEBUG_INCLFUN\r
+\r
+ updateIds();\r
+ QList<ConnectionItem*> allConnections;\r
+ QFile file(confFile);\r
+ if(file.open(QIODevice::WriteOnly)){\r
+\r
+ QXmlStreamWriter writer(&file);\r
+\r
+ writer.setAutoFormatting(true);\r
+ writer.writeStartDocument();\r
+\r
+ writer.writeStartElement("blast_project");\r
+ writer.writeStartElement("scenes");\r
+\r
+ writer.writeAttribute("count",QString::number(dispatcher->getNumberOfScenes()));\r
+\r
+ // cross the scene level by level using a FIFO\r
+ QList<GroupScene*> fifoScene;\r
+ fifoScene.append(topScene);\r
+ foreach(ConnectionItem* item, topScene->getConnectionItems()) {\r
+ allConnections.append(item);\r
+ }\r
+\r
+ GroupScene *scene;\r
+ while (!fifoScene.isEmpty()) {\r
+ scene = fifoScene.takeFirst();\r
+ scene->save(writer);\r
+ foreach(GroupScene* s, scene->getChildrenScene()) {\r
+ fifoScene.append(s);\r
+ }\r
+ foreach(ConnectionItem* item, topScene->getConnectionItems()) {\r
+ allConnections.append(item);\r
+ }\r
+ }\r
+\r
+\r
+ writer.writeStartElement("connections");\r
+ foreach(ConnectionItem* item, allConnections) {\r
+\r
+ writer.writeStartElement("connection");\r
+\r
+ writer.writeAttribute("from",QString::number(item->getFromInterfaceItem()->getId()));\r
+ writer.writeAttribute("to", QString::number(item->getToInterfaceItem()->getId()));\r
+\r
+ writer.writeEndElement();\r
+ }\r
+\r
+ writer.writeEndElement(); //</connections>\r
+ writer.writeEndElement(); //</blast_project\r
+\r
+ writer.writeEndDocument();\r
+\r
+ file.close();\r
+ unsaveModif = false;\r
+ }\r
+//#endif\r
+}\r
+\r
+void Parameters::setArrowPathes() {\r
+ QPainterPath _inArrow;\r
+ _inArrow.lineTo(arrowLineLength,0);\r
+ _inArrow.lineTo(arrowLineLength+arrowWidth,-arrowHeight/2);\r
+ _inArrow.lineTo(arrowLineLength+arrowWidth,arrowHeight/2);\r
+ _inArrow.lineTo(arrowLineLength,0);\r
+ _inArrow.closeSubpath();\r
+ inArrow = _inArrow;\r
+\r
+ QPainterPath _outArrow;\r
+ _outArrow.lineTo(arrowLineLength,0);\r
+ _outArrow.lineTo(arrowLineLength,-arrowHeight/2);\r
+ _outArrow.lineTo(arrowLineLength+arrowWidth,0);\r
+ _outArrow.lineTo(arrowLineLength,arrowHeight/2);\r
+ _outArrow.lineTo(arrowLineLength,0);\r
+ _outArrow.closeSubpath();\r
+ outArrow = _outArrow;\r
+\r
+}\r
+\r
+GroupScene* Parameters::searchSceneById(int id, GroupScene *scene) {\r
+\r
+ if (scene->getId() == id) return scene;\r
+ GroupScene* sc = NULL;\r
+\r
+ foreach(GroupScene *s, scene->getChildrenScene()) {\r
+ sc = searchSceneById(id,s);\r
+ if (sc != NULL) return sc;\r
+ }\r
+ return NULL;\r
+}\r
+\r
+GroupItem* Parameters::searchGroupItemById(int id, GroupScene *scene) {\r
+\r
+ if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();\r
+\r
+ GroupItem* item = NULL;\r
+ foreach(GroupScene *s, scene->getChildrenScene()) {\r
+ item = searchGroupItemById(id,s);\r
+ if (item != NULL) return item;\r
+ }\r
+ return NULL;\r
+}\r
+\r
+BoxItem* Parameters::searchBlockItemById(int id, GroupScene *scene) {\r
+\r
+ foreach(BoxItem *item, scene->getBlockItems()){\r
+ if(item->getId() == id){\r
+ return item;\r
+ }\r
+ }\r
+\r
+ BoxItem* item = NULL;\r
+ foreach(GroupScene *s, scene->getChildrenScene()) {\r
+ item = searchBlockItemById(id,s);\r
+ if (item != NULL) return item;\r
+ }\r
+ return NULL;\r
+}\r
+\r
+InterfaceItem* Parameters::searchInterfaceItemById(int id, GroupScene* scene) {\r
+\r
+ foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){\r
+ if(item->getId() == id){\r
+ return item;\r
+ }\r
+ }\r
+ foreach(BoxItem *block, scene->getBlockItems()){\r
+ foreach(InterfaceItem *item, block->getInterfaces()){\r
+ if(item->getId() == id){\r
+ return item;\r
+ }\r
+ }\r
+ }\r
+ InterfaceItem* item = NULL;\r
+ foreach(GroupScene *s, scene->getChildrenScene()) {\r
+ item = searchInterfaceItemById(id,s);\r
+ if (item != NULL) return item;\r
+ }\r
+ return NULL;\r
+}\r
--- /dev/null
+#ifndef __PARAMETERS_H__\r
+#define __PARAMETERS_H__\r
+\r
+#include <iostream>\r
+\r
+#include <QtCore>\r
+#include <QtGui>\r
+#include <QtWidgets>\r
+#include <QtXml>\r
+#include <QtXmlPatterns>\r
+\r
+class Dispatcher;\r
+class BlockLibraryTree;\r
+class AbstractBlock;\r
+class ReferenceBlock;\r
+class GroupBlock;\r
+class FunctionalBlock;\r
+class GroupScene;\r
+class GroupItem;\r
+class BoxItem;\r
+class InterfaceItem;\r
+class Graph;\r
+\r
+#include "BlockImplementation.h"\r
+\r
+#include "Exception.h"\r
+class Exception;\r
+\r
+// defines for current mode\r
+#define MODE_EDITION 1\r
+#define MODE_ADDBLOC 2\r
+#define MODE_ADDCONN 3\r
+\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+class Parameters {\r
+\r
+public :\r
+\r
+ enum Direction { NoDirection, East, North, West, South};\r
+\r
+ /* state of cursorn:\r
+ - CursorInBlock: cursor is within the main box of a block/group item\r
+ - CursorOnBlockBorder: cursor is on a block/group item border\r
+ - CursorOnInterface: cursor is on a block/group item Interface\r
+ - CursorOnConnection: cursor is one a connection\r
+ - CursorNowhere: none of the previous cases\r
+ */\r
+ enum CursorState { CursorNowhere = 0, CursorInBlock, CursorInGroupTitle, CursorOnBorder, CursorOnInterface, CursorOnConnection };\r
+ /* state of edition:\r
+\r
+ */\r
+ enum EditState { EditNoOperation = 0, EditBlockMove, EditBlockResize, EditGroupMove, EditGroupResize, EditInterfaceMove, EditInterfaceDeselect, EditConnectionResize, EditStartConnection, EditCloseConnection, EditAbortConnection};\r
+\r
+ enum XmlFileType { Configuration = 1, Reference, Implementation, Project };\r
+ Parameters();\r
+ ~Parameters();\r
+\r
+ // getter\r
+ inline GroupScene* getCurrentScene() { return currentScene; }\r
+ inline GroupScene* getTopScene() { return topScene; }\r
+\r
+ // setter\r
+ inline void setTopScene(GroupScene* _topScene) { topScene = _topScene; }\r
+ inline void setCurrentScene(GroupScene* _currentScene) { currentScene = _currentScene; }\r
+ inline void setEditState(EditState state) { editState = state; }\r
+ inline void setCursorState(CursorState state) { cursorState = state; }\r
+ inline void setDispatcher(Dispatcher* _dispatcher) { dispatcher = _dispatcher;}\r
+\r
+ /***************************************************\r
+ attributes that are general to the application\r
+ ***************************************************/ \r
+ BlockLibraryTree* categoryTree;\r
+ QList<QString> refPathes;\r
+ QList<QString> implPathes;\r
+ QList<ReferenceBlock*> availableBlocks;\r
+ QList<BlockImplementation*> availableImplementations;\r
+\r
+\r
+ QString refLib;\r
+ QString implLib;\r
+\r
+ // defaults for vhdl\r
+ int wbDataWidth;\r
+ int wbAddressWidth;\r
+ // defaults for scene elements\r
+ int defaultBlockWidth;\r
+ int defaultBlockHeight;\r
+ QFont defaultBlockFont;\r
+ QString defaultBlockFontName;\r
+ int defaultBlockFontSize;\r
+ int arrowWidth;\r
+ int arrowHeight;\r
+ int arrowLineLength;\r
+ QFont defaultIfaceFont;\r
+ QString defaultIfaceFontName;\r
+ int defaultIfaceFontSize;\r
+ int connGapLength;\r
+ QPainterPath inArrow;\r
+ QPainterPath outArrow;\r
+\r
+ /***************************************************\r
+ attributes that are specific for the current project\r
+ ****************************************************/\r
+ int sceneMode; // takes values from MODE_XXX\r
+ CursorState cursorState;\r
+ EditState editState; // takes values from EDIT_STATE_XXX\r
+ bool unsaveModif;\r
+ bool isRstClkShown;\r
+\r
+ Graph* createGraph();\r
+ void destroyGraph();\r
+ inline Graph* getGraph() { return graph; }\r
+ GroupBlock* addGroupBlock(); // adding an empty GroupBlock to the current group\r
+ FunctionalBlock* addFunctionalBlock(int idCategory, int idBlock); // adding a functional block to current group\r
+ FunctionalBlock* duplicateFunctionalBlock(FunctionalBlock* block); // adding a copy of a functional block to current group\r
+\r
+\r
+ void clear();\r
+\r
+ QDomElement openProjectFile(const QString& projectFileName) throw(Exception);\r
+ void loadProject(QDomElement root);\r
+\r
+ void loadBlastConfiguration(QString confFile) throw(Exception);\r
+ void loadReferencesFromXml() throw(Exception);\r
+ void loadReferencesFromLib() throw(Exception);\r
+ void saveReferencesToLib() throw(Exception);\r
+\r
+ void loadImplementationsFromXml() throw(Exception);\r
+ void loadImplementationsFromLib() throw(Exception);\r
+ void saveImplementationsToLib() throw(Exception);\r
+\r
+ void addAvailableBlock(ReferenceBlock *block); \r
+ void parametersValidation();\r
+ void connectionsValidation();\r
+ QList<AbstractBlock *> getBlocksToConfigure();\r
+\r
+ void updateToolbar();\r
+\r
+\r
+ ReferenceBlock* searchBlockByXml(QString xmlName);\r
+ ReferenceBlock* searchBlockByMd5(QString sumMd5);\r
+\r
+ void save(QString confFile);\r
+\r
+\r
+ QString projectPath;\r
+\r
+private:\r
+ Graph* graph; // the graph model of blocks\r
+ Dispatcher* dispatcher;\r
+ GroupScene* topScene;\r
+ GroupScene* currentScene;\r
+\r
+ void setArrowPathes(); \r
+ void updateIds();\r
+\r
+ GroupScene* searchSceneById(int id, GroupScene* scene);\r
+ BoxItem* searchBlockItemById(int id, GroupScene* scene);\r
+ GroupItem* searchGroupItemById(int id, GroupScene* scene);\r
+ InterfaceItem* searchInterfaceItemById(int id, GroupScene *scene);\r
+\r
+ void validateXmlFile(const QString& xmlFileName, const QString& xsdFileName, XmlFileType fileType) throw(Exception);\r
+ bool validate(QFile& fileXml, QFile& fileSchema);\r
+\r
+};\r
+\r
+\r
+#endif // __PARAMETERS_H__\r
--- /dev/null
+#include "ParametersWindow.h"
+#include "Parameters.h"
+#include "BlocksToConfigureWidget.h"
+#include "BlockParameter.h"
+#include "AbstractBlock.h"
+
+ParametersWindow::ParametersWindow(AbstractBlock *_block, Parameters *_params, BlocksToConfigureWidget *btcw, QWidget *parent) :
+ QWidget(parent)
+{
+ block = _block;
+ confWidget = btcw;
+ params = _params;
+
+ layout = new QGridLayout;
+
+ name = new QLabel;
+ value = new QLineEdit;
+ context = new QLabel;
+ type = new QLabel;
+
+ comboBox = new QComboBox;
+
+ foreach(BlockParameter *param, block->getParameters()){
+ comboBox->addItem(param->getName());
+ }
+ connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateData()));
+ updateData();
+
+ saveButton = new QPushButton("Save");
+ connect(saveButton, SIGNAL(clicked()), this, SLOT(save()));
+
+ layout->addWidget(new QLabel("Parameters"), 0, 0);
+ layout->addWidget(comboBox, 0, 1);
+
+ layout->addWidget(new QLabel(" "), 1, 0);
+
+ layout->addWidget(new QLabel("Name"), 2, 0);
+ layout->addWidget(name, 2, 1);
+ layout->addWidget(new QLabel("Value"), 3, 0);
+ layout->addWidget(value, 3, 1);
+ layout->addWidget(new QLabel("Context"), 4, 0);
+ layout->addWidget(context, 4, 1);
+ layout->addWidget(new QLabel("Type"), 5, 0);
+ layout->addWidget(type, 5, 1);
+
+ layout->addWidget(saveButton, 6, 0);
+
+ this->setLayout(layout);
+
+ show();
+}
+
+void ParametersWindow::updateData()
+{
+ BlockParameter *param = block->getParameters().at(comboBox->currentIndex());
+ name->setText(param->getName());
+ value->setText(param->getValue().toString());
+ context->setText(param->getContext());
+ type->setText(param->getTypeString());
+}
+
+void ParametersWindow::save()
+{
+ BlockParameter *param = block->getParameters().at(comboBox->currentIndex());
+ param->setValue(value->text());
+
+ //params->parametersValidation();
+ if(confWidget != NULL){
+ confWidget->updateBlocksList();
+ }
+ close();
+}
--- /dev/null
+#ifndef __PARAMETERSWINDOW_H__
+#define __PARAMETERSWINDOW_H__
+
+#include <QtWidgets>
+
+class Parameters;
+class AbstractBlock;
+class BlocksToConfigureWidget;
+
+class ParametersWindow : public QWidget {
+ Q_OBJECT
+
+public:
+ ParametersWindow(AbstractBlock *block, Parameters *_params, BlocksToConfigureWidget *btcw=NULL, QWidget *parent=0);
+
+private:
+ AbstractBlock *block;
+ Parameters *params;
+ BlocksToConfigureWidget *confWidget;
+ QGridLayout *layout;
+ QComboBox *comboBox;
+ QLabel *name;
+ QLabel *context;
+ QLineEdit *value;
+ QLabel *type;
+ QPushButton *saveButton;
+
+private slots:
+ void updateData();
+ void save();
+
+};
+
+#endif // PARAMETERSWINDOW_H
--- /dev/null
+#include "ReferenceBlock.h"
+
+#include "ReferenceInterface.h"
+#include "BlockParameter.h"
+#include "BlockParameterUser.h"
+#include "BlockParameterGeneric.h"
+#include "BlockParameterPort.h"
+#include "BlockParameterWishbone.h"
+
+ReferenceBlock::ReferenceBlock(const QString _xmlFile) : AbstractBlock() {
+ xmlFile = _xmlFile;
+}
+
+void ReferenceBlock::addCategory(int id) {
+ categories.append(id);
+}
+
+void ReferenceBlock::setBriefDescription(const QString& str) {
+ if(str != NULL)
+ descriptionBrief = str;
+}
+
+void ReferenceBlock::setDetailedDescription(const QString& str) {
+ if(str != NULL)
+ descriptionDetail = str;
+}
+
+void ReferenceBlock::addImplementation(BlockImplementation *impl) {
+ implementations.append(impl);
+}
+
+void ReferenceBlock::setHashMd5() {
+ QFile file(xmlFile);
+ if (file.open(QIODevice::ReadOnly)) {
+ QByteArray fileData = file.readAll();
+ QByteArray hashData = QCryptographicHash::hash(fileData, QCryptographicHash::Md5);
+ hashMd5 = QString(hashData.toHex());
+ cout << qPrintable(xmlFile) << " has md5 hash : " << qPrintable(hashMd5) << endl;
+ }
+ else {
+ hashMd5 = "";
+ }
+}
+
+void ReferenceBlock::load(QDomElement &elt) throw(Exception) {
+
+
+ cout << "Block : get informations" << endl;
+ QDomElement eltInfo = elt.firstChildElement("informations");
+ try {
+ loadInformations(eltInfo);
+ }
+ catch(int err) {
+ throw(err);
+ }
+
+ cout << "Block : get params" << endl;
+ QDomElement eltParams = eltInfo.nextSiblingElement("parameters");
+ try {
+ loadParameters(eltParams);
+ }
+ catch(int err) {
+ throw(err);
+ }
+
+ cout << "Block : get interfaces" << endl;
+ QDomElement eltInter = eltParams.nextSiblingElement("interfaces");
+ try {
+ loadInterfaces(eltInter);
+ }
+ catch(int err) {
+ throw(err);
+ }
+}
+
+void ReferenceBlock::loadInformations(QDomElement &elt) throw(Exception) {
+
+ bool ok;
+ if ((elt.isNull()) || (elt.tagName() != "informations")) throw (Exception(BLOCKFILE_CORRUPTED));
+ // getting name
+ cout << "Block info : get name" << endl;
+ QDomNode nodeName = elt.firstChild();
+ QDomNode nodeNameTxt = nodeName.firstChild();
+ if (nodeNameTxt.isNull()) {
+ name = "no_name";
+ }
+ else {
+ QDomText txtName = nodeNameTxt.toText();
+ name = txtName.data().trimmed();
+ cout<< "block name : " << qPrintable(name) << endl;
+ }
+
+ // getting categories
+ cout << "Block info : get categories" << endl;
+ QDomElement eltCat = nodeName.nextSiblingElement("category");
+
+ QString idsStr = eltCat.attribute("ids","none");
+ if (idsStr == "none") throw (Exception(BLOCKFILE_CORRUPTED));
+ QStringList listCat = idsStr.split(",");
+ foreach(QString str, listCat)
+ {
+ int idCat = str.toInt(&ok);
+ categories.append(idCat);
+ }
+
+ // getting description
+ cout << "Block info : get description" << endl;
+ QDomElement eltDesc = eltCat.nextSiblingElement("description");
+ // getting brief
+ QDomElement eltBrief = eltDesc.firstChildElement("brief");
+ QDomNode nodeBriefTxt = eltBrief.firstChild();
+ if (nodeBriefTxt.isNull()) {
+ descriptionBrief = "no brief description";
+ }
+ else {
+ QDomText txtBrief = nodeBriefTxt.toText();
+ descriptionBrief = txtBrief.data().trimmed();
+ cout << "block brief desc : " << qPrintable(descriptionBrief) << endl;
+ }
+ // getting detailed
+ QDomElement eltDetail = eltBrief.nextSiblingElement("detailed");
+ QDomNode nodeDetailTxt = eltDetail.firstChild();
+ if (nodeDetailTxt.isNull()) {
+ descriptionDetail = "no detailed description";
+ }
+ else {
+ QDomText txtDetail = nodeDetailTxt.toText();
+ descriptionDetail = txtDetail.data().trimmed();
+ cout << "block detail desc : " << qPrintable(descriptionDetail) << endl;
+ }
+}
+
+void ReferenceBlock::loadParameters(QDomElement &elt) throw(Exception) {
+
+ if ((elt.isNull()) || (elt.tagName() != "parameters")) throw (Exception(BLOCKFILE_CORRUPTED));
+
+ QDomNodeList listNodeParam = elt.elementsByTagName("parameter");
+ for(int i=0; i<listNodeParam.size(); i++) {
+ QDomNode node = listNodeParam.at(i);
+ QDomElement elt = node.toElement();
+ QString nameStr = elt.attribute("name","none");
+ QString contextStr = elt.attribute("context","none");
+ QString typeStr = elt.attribute("type","none");
+ QString valueStr = elt.attribute("value","none");
+ BlockParameter *param = NULL;
+
+ if(valueStr == "none"){
+ if (contextStr == "generic") throw (Exception(BLOCKFILE_CORRUPTED)); // set is required for generics
+ valueStr = "";
+ }
+ if (contextStr == "user") {
+ param = new BlockParameterUser(this,nameStr,valueStr);
+ }
+ else if (contextStr == "generic") {
+ param = new BlockParameterGeneric(this,nameStr,typeStr,valueStr);
+ }
+ else if (contextStr == "wb") {
+ QString widthStr = elt.attribute("width","none");
+ QString wbStr = elt.attribute("wishbone","none");
+ int access = 0;
+ int duration = 0;
+ QString wbValue = "";
+ QStringList listWb = wbStr.split(",");
+
+ if (listWb.at(0) == "r") {
+ access = BlockParameter::Read;
+ }
+ else if (wbStr == "w") {
+ access = BlockParameter::Write;
+ bool ok;
+ wbValue = listWb.at(1).toInt(&ok);
+ if(!ok){
+ if(listWb.at(1) == "true" || listWb.at(1) == "false"){
+ wbValue = listWb.at(1);
+ } else {
+ wbValue = "data";
+ }
+ }
+ if(listWb.at(2) == "trigger") {
+ duration = BlockParameter::Trigger;
+ }
+ else if(listWb.at(2) == "perm") {
+ duration = BlockParameter::Permanent;
+ }
+ }
+ param = new BlockParameterWishbone(this,nameStr,typeStr,widthStr,valueStr,access,wbValue,duration);
+ }
+ else if (contextStr == "port") {
+ QString ifaceStr = elt.attribute("iface","none");
+ param = new BlockParameterPort(this,nameStr,valueStr,ifaceStr);
+
+ }
+ else {
+ throw (Exception(BLOCKFILE_CORRUPTED));
+ }
+ params.append(param);
+ }
+}
+
+void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) {
+
+ QString nameStr;
+ QString typeStr;
+ QString widthStr;
+ QString purposeStr;
+ int purpose;
+ QString levelStr;
+ int level;
+ QString multStr;
+ int mult;
+ AbstractInterface* inter;
+
+ if ((elt.isNull()) || (elt.tagName() != "interfaces")) throw (Exception(BLOCKFILE_CORRUPTED));
+
+ QDomElement eltInputs = elt.firstChildElement("inputs");
+ QDomNodeList listNodeInputs = eltInputs.elementsByTagName("input");
+ for(int i=0;i<listNodeInputs.size();i++) {
+ QDomNode node = listNodeInputs.at(i);
+ QDomElement eltInput = node.toElement();
+ nameStr = eltInput.attribute("name","none");
+ typeStr = eltInput.attribute("type","none");
+ widthStr = eltInput.attribute("width","none");
+ purposeStr = eltInput.attribute("purpose","none");
+ cout << "block : " << this->getName().toStdString() << endl;
+ cout << "purpose for " << nameStr.toStdString() << " : " << purposeStr.toStdString() << endl;
+ purpose = ReferenceInterface::translatePurpose(purposeStr);
+ cout << "translated purpose : " << purpose << endl;
+ levelStr = eltInput.attribute("level","none");
+ level = ReferenceInterface::translateLevel(levelStr);
+ multStr = eltInput.attribute("multiplicity","none");
+ mult = ReferenceInterface::translateMultiplicity(multStr);
+
+ inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::Input, purpose, level, mult);
+ inputs.append(inter);
+ }
+
+ QDomElement eltOutputs = eltInputs.nextSiblingElement("outputs");
+ QDomNodeList listNodeOutputs = eltOutputs.elementsByTagName("output");
+ for(int i=0;i<listNodeOutputs.size();i++) {
+ QDomNode node = listNodeOutputs.at(i);
+ QDomElement eltOutput = node.toElement();
+ nameStr = eltOutput.attribute("name","none");
+ typeStr = eltOutput.attribute("type","none");
+ widthStr = eltOutput.attribute("width","none");
+ purposeStr = eltOutput.attribute("type","none");
+ purpose = ReferenceInterface::translatePurpose(purposeStr);
+ levelStr = eltOutput.attribute("level","none");
+ level = ReferenceInterface::translateLevel(levelStr);
+ multStr = eltOutput.attribute("multiplicity","none");
+ mult = ReferenceInterface::translateMultiplicity(multStr);
+
+ inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::Output, purpose, level, mult);
+ outputs.append(inter);
+ }
+
+ QDomElement eltBidirs = eltInputs.nextSiblingElement("bidirs");
+ QDomNodeList listNodeBidirs = eltBidirs.elementsByTagName("bidir");
+ for(int i=0;i<listNodeBidirs.size();i++) {
+ QDomNode node = listNodeBidirs.at(i);
+ QDomElement eltBidir = node.toElement();
+ nameStr = eltBidir.attribute("name","none");
+ typeStr = eltBidir.attribute("type","none");
+ widthStr = eltBidir.attribute("width","none");
+ purposeStr = eltBidir.attribute("type","none");
+ purpose = ReferenceInterface::translatePurpose(purposeStr);
+ levelStr = eltBidir.attribute("level","none");
+ level = ReferenceInterface::translateLevel(levelStr);
+ multStr = eltBidir.attribute("multiplicity","none");
+ mult = ReferenceInterface::translateMultiplicity(multStr);
+
+ inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::InOut, purpose, level, mult);
+ bidirs.append(inter);
+ }
+}
+
+void ReferenceBlock::parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock *> *blocksToConfigure)
+{
+ return;
+}
+
+/* operator<<() :
+ only used to save all ReferenceBlock in a library in binary format, so that reference blocks
+ are read very fast at application startup.
+
+ */
+QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) {
+
+ out.setVersion(QDataStream::Qt_5_0);
+
+ QByteArray blockData;
+ QDataStream toWrite(&blockData, QIODevice::WriteOnly);
+
+ toWrite << b.name;
+ toWrite << b.xmlFile;
+ toWrite << b.descriptionBrief;
+ toWrite << b.descriptionDetail;
+ toWrite << b.categories;
+ toWrite << b.hashMd5;
+ toWrite << b.params.size();
+ BlockParameter* p;
+ for(int i=0;i<b.params.size();i++) {
+ p = b.params.at(i);
+ toWrite << p->getContext();
+ toWrite << p->getName();
+ toWrite << p->getTypeString();
+ toWrite << p->getValue().toString();
+ if (p->isPortParameter()) {
+ toWrite << ((BlockParameterPort*)p)->getIfaceName();
+ }
+ else if (p->isWishboneParameter()) {
+ BlockParameterWishbone* pwb = (BlockParameterWishbone*)p;
+ toWrite << pwb->getWidth();
+ toWrite << pwb->getWBAccess();
+ toWrite << pwb->getWBValue();
+ toWrite << pwb->getWBDuration();
+ }
+
+ }
+
+ toWrite << b.inputs.size();
+ for(int i=0; i<b.inputs.size(); i++){
+ ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
+ toWrite << iface->getName();
+ toWrite << iface->getWidth();
+ toWrite << iface->getPurpose();
+ toWrite << iface->getDirection();
+ toWrite << iface->getLevel();
+ toWrite << iface->getMultiplicity();
+ }
+ toWrite << b.outputs.size();
+ for(int i=0; i<b.outputs.size(); i++){
+ ReferenceInterface *iface = (ReferenceInterface *)(b.outputs.at(i));
+ toWrite << iface->getName();
+ toWrite << iface->getWidth();
+ toWrite << iface->getPurpose();
+ toWrite << iface->getDirection();
+ toWrite << iface->getLevel();
+ toWrite << iface->getMultiplicity();
+ }
+ toWrite << b.bidirs.size();
+ for(int i=0; i<b.bidirs.size(); i++){
+ ReferenceInterface *iface = (ReferenceInterface *)(b.bidirs.at(i));
+ toWrite << iface->getName();
+ toWrite << iface->getWidth();
+ toWrite << iface->getPurpose();
+ toWrite << iface->getDirection();
+ toWrite << iface->getLevel();
+ toWrite << iface->getMultiplicity();
+ }
+
+ out << blockData;
+
+ return out;
+}
+
+QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
+
+ quint32 blockSize;
+ ReferenceInterface* iface;
+ BlockParameter* p;
+ int val;
+ QString txt="";
+
+ in.setVersion(QDataStream::Qt_5_0);
+
+ in >> blockSize;
+
+ in >> b.name;
+ in >> b.xmlFile;
+ in >> b.descriptionBrief;
+ in >> b.descriptionDetail;
+ in >> b.categories;
+ in >> b.hashMd5;
+ b.params.clear();
+ int nb;
+ in >> nb;
+ cout << qPrintable(b.name) << " has " << nb << " parameters" << endl;
+ for(int i=0;i<nb;i++) {
+ QString contextStr = "";
+ QString nameStr= "";
+ QString typeStr = "";
+ QString valueStr = "";
+ in >> contextStr;
+ in >> nameStr;
+ in >> typeStr;
+ in >> valueStr;
+
+ if (contextStr == "user") {
+ p = new BlockParameterUser(&b,nameStr,valueStr);
+ }
+ else if (contextStr == "generic") {
+ p = new BlockParameterGeneric(&b,nameStr,typeStr,valueStr);
+ }
+ else if (contextStr == "port") {
+ QString ifaceStr = "";
+ in >> ifaceStr;
+ p = new BlockParameterPort(&b,nameStr,valueStr,ifaceStr);
+ }
+ else if (contextStr == "wb") {
+ QString widthStr = "";
+ int wbAccess;
+ QString wbValue;
+ int wbDuration;
+ in >> widthStr;
+ in >> wbAccess;
+ in >> wbValue;
+ in >> wbDuration;
+ p = new BlockParameterWishbone(&b,nameStr,typeStr,widthStr,valueStr,wbAccess,wbValue,wbDuration);
+ }
+ b.params.append(p);
+ }
+
+ b.inputs.clear();
+ in >> nb;
+ for(int i=0;i<nb;i++) {
+ iface = new ReferenceInterface(&b);
+ in >> txt;
+ iface->setName(txt);
+ in >> txt;
+ iface->setWidth(txt);
+ in >> val;
+ iface->setPurpose(val);
+ in >> val;
+ iface->setDirection(val);
+ in >> val;
+ iface->setLevel(val);
+ in >> val;
+ iface->setMultiplicity(val);
+ b.inputs.append(iface);
+ }
+
+ b.outputs.clear();
+ in >> nb;
+ for(int i=0;i<nb;i++) {
+ iface = new ReferenceInterface(&b);
+ in >> txt;
+ iface->setName(txt);
+ in >> txt;
+ iface->setWidth(txt);
+ in >> val;
+ iface->setPurpose(val);
+ in >> val;
+ iface->setDirection(val);
+ in >> val;
+ iface->setLevel(val);
+ in >> val;
+ iface->setMultiplicity(val);
+ b.outputs.append(iface);
+ }
+
+ b.bidirs.clear();
+ in >> nb;
+ for(int i=0;i<nb;i++) {
+ iface = new ReferenceInterface(&b);
+ in >> txt;
+ iface->setName(txt);
+ in >> txt;
+ iface->setWidth(txt);
+ in >> val;
+ iface->setPurpose(val);
+ in >> val;
+ iface->setDirection(val);
+ in >> val;
+ iface->setLevel(val);
+ in >> val;
+ iface->setMultiplicity(val);
+ b.bidirs.append(iface);
+ }
+
+ return in;
+}
--- /dev/null
+#ifndef __REFERENCEBLOCK_H__
+#define __REFERENCEBLOCK_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtWidgets>
+#include <QtXml>
+
+#include "AbstractBlock.h"
+class AbstractBlock;
+
+#include "BlockImplementation.h"
+
+#include "Exception.h"
+class Exception;
+
+using namespace std;
+using namespace Qt;
+
+
+class ReferenceBlock : public AbstractBlock {
+
+public:
+
+ ReferenceBlock(const QString _xmlFile);
+
+ int getType();
+ inline QString getXmlFile() { return xmlFile; }
+ inline QString getBriefDescription() { return descriptionBrief; }
+ inline QString getDetailedDescription() { return descriptionDetail; }
+ inline QList<int> getCategories() { return categories; }
+ inline QList<BlockImplementation *> getImplementations() { return implementations; }
+ inline QString getHashMd5() { return hashMd5; }
+
+ inline AbstractBlock* getParent() { return NULL; }
+
+ void addCategory(int id);
+ void setBriefDescription(const QString& str);
+ void setDetailedDescription(const QString& str);
+ void addImplementation(BlockImplementation* impl);
+
+ void load(QDomElement &elt) throw(Exception);
+ void setHashMd5();
+
+private:
+ QString xmlFile; // the xml file from which attributes are initialized.
+ QString hashMd5;
+ QString descriptionBrief;
+ QString descriptionDetail;
+ QList<int> categories;
+ QList<BlockImplementation *> implementations; // set when implementations are read
+
+ // loading methods for the different tags in the XML desc.
+ void loadInformations(QDomElement &elt) throw(Exception);
+ void loadParameters(QDomElement &elt) throw(Exception);
+ void loadInterfaces(QDomElement &elt) throw(Exception);
+
+ friend QDataStream &operator<<(QDataStream &out, const ReferenceBlock &b);
+ friend QDataStream &operator>>(QDataStream &in, ReferenceBlock &b);
+
+
+ // AbstractBlock interface
+public:
+ void parametersValidation(QList<AbstractBlock*>* checkedBlocks, QList<AbstractBlock*>* blocksToConfigure);
+};
+
+#endif // __REFERENCEBLOCK_H__
--- /dev/null
+#include "ReferenceInterface.h"
+#include "AbstractBlock.h"
+
+ReferenceInterface::ReferenceInterface(AbstractBlock* _owner) throw(Exception) : AbstractInterface(_owner) {
+ if (_owner->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
+ multiplicity = 1;
+}
+
+ReferenceInterface::ReferenceInterface(AbstractBlock* _owner,
+ const QString& _name, const QString&_type,
+ const QString& _width,
+ int _direction,
+ int _purpose,
+ int _level,
+ int _multiplicity)
+throw (Exception) : AbstractInterface(_owner, _name, _type, _width, _direction, _purpose, _level) {
+
+ if (_owner->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
+
+ multiplicity = _multiplicity;
+ if (direction == InOut) {
+ multiplicity = 1;
+ }
+}
+
+bool ReferenceInterface::isReferenceInterface() {
+ return true;
+}
+
+void ReferenceInterface::setMultiplicity(int _multiplicity) {
+ if (direction == InOut) {
+ multiplicity = 1;
+ }
+ else {
+ multiplicity = _multiplicity;
+ }
+}
+
+int ReferenceInterface::translatePurpose(const QString& txt) {
+ if (txt == "clock") {
+ return Clock;
+ }
+ else if (txt == "reset") {
+ return Reset;
+ }
+ if (txt == "wb") {
+ return Wishbone;
+ }
+ return Data;
+}
+
+int ReferenceInterface::translateLevel(const QString& txt) {
+
+ if (txt == "top") {
+ return Top;
+ }
+ return Basic;
+}
+
+int ReferenceInterface::translateMultiplicity(const QString& txt) {
+ bool ok;
+ int mult;
+ if (txt == "*") {
+ mult = -1;
+ }
+ else {
+ mult = txt.toInt(&ok);
+ if (!ok) {
+ mult = 1;
+ }
+ }
+ return mult;
+}
--- /dev/null
+#ifndef __REFERENCEINTERFACE_H__
+#define __REFERENCEINTERFACE_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+
+#include "AbstractInterface.h"
+
+#include "Exception.h"
+
+using namespace std;
+using namespace Qt;
+
+
+class ReferenceInterface : public AbstractInterface {
+
+public :
+
+ ReferenceInterface(AbstractBlock *_owner) throw(Exception);
+ ReferenceInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose, int _level, int _multiplicity=1) throw (Exception);
+
+ // getters
+ inline int getMultiplicity() { return multiplicity; }
+ inline AbstractInterface* getConnectedFrom() { return NULL; }
+ // setters
+ void setMultiplicity(int _multiplicity);
+
+ // testers
+ bool isReferenceInterface();
+
+ // others
+
+ static int translatePurpose(const QString& txt);
+ static int translateLevel(const QString& txt);
+ static int translateMultiplicity(const QString& txt);
+
+ inline AbstractInterface *clone(){ return NULL; }
+
+
+private:
+ int multiplicity; // -1 means infinite multiplicity, and X>1, the max. number of instances
+
+
+};
+
+#endif // __REFERENCEINTERFACE_H__
--- /dev/null
+#include "Toto.h"
+
+#include "FunctionalBlock.h"
+#include "ReferenceBlock.h"
+#include "ReferenceInterface.h"
+#include "FunctionalInterface.h"
+#include "BlockParameter.h"
+
+
+Toto::Toto(const QString& msg) {
+ v = msg;
+}
--- /dev/null
+#ifndef __TOTO_H__\r
+#define __TOTO_H__\r
+\r
+#include <iostream>\r
+#include <fstream>\r
+\r
+#include <QtCore>\r
+#include <QtXml>\r
+\r
+class ReferenceBlock;\r
+class FunctionalBlock;\r
+class AbstractInterface;\r
+\r
+\r
+#include "ArithmeticEvaluator.h"\r
+class ArithmeticEvaluator;\r
+\r
+#include "Exception.h"\r
+class Exception;\r
+\r
+using namespace std;\r
+using namespace Qt;\r
+\r
+class Toto {\r
+\r
+public:\r
+\r
+ Toto(const QString& msg);\r
+\r
+private:\r
+ QString v;\r
+};\r
+\r
+#endif // __TOTO_H__\r
+\r
--- /dev/null
+// Add predefined macros for your project here. For example:
+// #define THE_ANSWER 42
--- /dev/null
+#include <QtCore>
+#include <QtGui>
+#include "MainWindow.h"
+#include <iostream>
+
+using namespace std;
+using namespace Qt;
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ MainWindow w;
+
+ w.show();
+
+ return a.exec();
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 3.2.1, 2017-04-26T13:47:31. -->
+<qtcreator>
+ <data>
+ <variable>EnvironmentId</variable>
+ <value type="QByteArray">{3701e197-5b6c-48ea-9e98-a6cf6de18672}</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.ActiveTarget</variable>
+ <value type="int">0</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.EditorSettings</variable>
+ <valuemap type="QVariantMap">
+ <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+ <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+ <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+ <value type="QString" key="language">Cpp</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+ </valuemap>
+ </valuemap>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+ <value type="QString" key="language">QmlJS</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+ </valuemap>
+ </valuemap>
+ <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
+ <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+ <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+ <value type="int" key="EditorConfiguration.IndentSize">4</value>
+ <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+ <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+ <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+ <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+ <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+ <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+ <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+ <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+ <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+ <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+ <value type="int" key="EditorConfiguration.TabSize">8</value>
+ <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+ <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+ <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+ <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+ <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+ <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.PluginSettings</variable>
+ <valuemap type="QVariantMap"/>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Target.0</variable>
+ <valuemap type="QVariantMap">
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{ed04208c-8774-456b-99b9-4a02094ca7a4}</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/sdomas/Projet/Blast/code/v0.2</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
+ <value type="QString">all</value>
+ </valuelist>
+ <value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
+ <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
+ <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Compiler</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
+ <value type="QString">clean</value>
+ </valuelist>
+ <value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">true</value>
+ <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
+ <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Nettoyer</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Défaut</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Défaut</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Déploiement</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Déployer localement</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+ <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+ <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+ <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+ <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+ <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+ <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+ <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+ <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+ <value type="int">0</value>
+ <value type="int">1</value>
+ <value type="int">2</value>
+ <value type="int">3</value>
+ <value type="int">4</value>
+ <value type="int">5</value>
+ <value type="int">6</value>
+ <value type="int">7</value>
+ <value type="int">8</value>
+ <value type="int">9</value>
+ <value type="int">10</value>
+ <value type="int">11</value>
+ <value type="int">12</value>
+ <value type="int">13</value>
+ <value type="int">14</value>
+ </valuelist>
+ <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+ <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+ <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments"></value>
+ <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value>
+ <value type="bool" key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal">false</value>
+ <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">%{buildDir}</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Exécutable personnalisé</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
+ <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+ <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+ <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.TargetCount</variable>
+ <value type="int">1</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+ <value type="int">16</value>
+ </data>
+ <data>
+ <variable>Version</variable>
+ <value type="int">16</value>
+ </data>
+</qtcreator>
--- /dev/null
+Exception.h
+Exception.cpp
+AbstractBlock.h
+AbstractBlock.cpp
+AbstractBoxItem.h
+AbstractBoxItem.cpp
+FunctionalBlock.cpp
+FunctionalBlock.h
+GroupBlock.h
+GroupBlock.cpp
+BlockImplementation.h
+BlockImplementation.cpp
+GroupScene.cpp
+GroupScene.h
+ReferenceBlock.cpp
+ReferenceBlock.h
+AbstractInterface.h
+AbstractInterface.cpp
+ConnectedInterface.h
+ConnectedInterface.cpp
+ReferenceInterface.h
+ReferenceInterface.cpp
+FunctionalInterface.cpp
+FunctionalInterface.h
+GroupInterface.h
+GroupInterface.cpp
+BlockLibraryWidget.cpp
+BlockLibraryWidget.h
+blast.cpp
+BlockCategory.cpp
+BlockCategory.h
+BoxItem.cpp
+BoxItem.h
+BlockLibraryTree.cpp
+BlockLibraryTree.h
+BlockParameter.cpp
+BlockParameter.h
+BlockParameterUser.h
+BlockParameterUser.cpp
+BlockParameterGeneric.h
+BlockParameterGeneric.cpp
+BlockParameterWishbone.h
+BlockParameterWishbone.cpp
+BlockParameterPort.h
+BlockParameterPort.cpp
+Dispatcher.cpp
+Dispatcher.h
+Graph.cpp
+Graph.h
+MainWindow.cpp
+MainWindow.h
+Parameters.cpp
+Parameters.h
+ConnectionItem.h
+ConnectionItem.cpp
+InterfaceItem.h
+InterfaceItem.cpp
+GroupItem.h
+GroupItem.cpp
+Abstractblockitem.h
+Abstractblockitem.cpp
+GroupWidget.h
+GroupWidget.cpp
+BlockWidget.cpp
+BlockWidget.h
+BlocksToConfigureWidget.h
+BlocksToConfigureWidget.cpp
+ParametersWindow.h
+ParametersWindow.cpp
+ArithmeticEvaluator.cpp
+ArithmeticEvaluator.h
+InterfacePropertiesWindow.h
+InterfacePropertiesWindow.cpp
--- /dev/null
+.
+/usr/include/x86_64-linux-gnu/qt5/QtCore
+/usr/include/x86_64-linux-gnu/qt5/QtGui
+/usr/include/x86_64-linux-gnu/qt5/QtWidgets
+/usr/include/x86_64-linux-gnu/qt5/QtNetwork
+/usr/include/x86_64-linux-gnu/qt5/QtXml
+/usr/include/x86_64-linux-gnu/qt5/QtXmlPatterns
+/usr/include/x86_64-linux-gnu/qt5/QtPrintSupport
+C:\Qt\5.4\mingw491_32\include\QtCore
+C:\Qt\5.4\mingw491_32\include\QtGui
+C:\Qt\5.4\mingw491_32\include\QtWidgets
+C:\Qt\5.4\mingw491_32\include\QtXml
+C:\Qt\5.4\mingw491_32\include\QtXmlPatterns
+C:\Qt\5.4\mingw491_32\include\QtPrintSupport
+C:\MinGW\include
--- /dev/null
+<RCC>
+ <qresource>
+ <file>icons/copy.png</file>
+ <file>icons/cut.png</file>
+ <file>icons/delete.png</file>
+ <file>icons/inter_add.png</file>
+ <file>icons/link.png</file>
+ <file>icons/paste.png</file>
+ <file>icons/save.png</file>
+ <file>icons/redo-icon.png</file>
+ <file>icons/undo.png</file>
+ <file>icons/save-as.png</file>
+ <file>icons/open.png</file>
+ <file>icons/load.png</file>
+ <file>icons/window_new.png</file>
+ <file>icons/new.ico</file>
+ <file>icons/folder_add_16.png</file>
+ <file>icons/add_block.png</file>
+ <file>icons/edit_block.png</file>
+ <file>icons/add_group_void.png</file>
+ <file>icons/add_group_select.png</file>
+ <file>icons/add_connection.png</file>
+ </qresource>
+</RCC>
--- /dev/null
+IDI_ICON1 ICON DISCARDABLE "blast.ico"
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<config>
+ <categories nb="6">
+ <category name="root" id="0" parent="-1"/>
+ <category name="math" id="1" parent="0"/>
+ <category name="trigonemetric" id="2" parent="1"/>
+ <category name="multadd" id="3" parent="1"/>
+ <category name="dsp" id="4" parent="0"/>
+ <category name="user" id="5" parent="0"/>
+ </categories>
+
+ <references nb="2" lib_file="/home/sdomas/Projet/Blast/code/v0.2/lib/references/references.bmf" >
+ <reference_lib path="/home/sdomas/Projet/Blast/code/v0.2/" />
+ <reference_lib path="/home/sdomas/Projet/Blast/code/v0.2/lib/references" />
+ </references>
+
+ <implementations nb="1" lib_file="/home/sdomas/Projet/Blast/code/v0.2/lib/implementations/impls.bmf" >
+ <impl_lib path="/home/sdomas/Projet/Blast/code/v0.2/lib/implementations" />
+ </implementations>
+
+ <defaults>
+ <blocks width="175" height="125" font="Helvetica" font_size="14" />
+ <interfaces linelength="10" width="5" height="10" font="Helvetica" font_size="10" />
+ <connections gaplength="20" />
+ </defaults>
+</config>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+
+ <!-- déclaration des groupes d'attributs -->
+
+ <xs:attributeGroup name="categoryAttrGroup">
+ <xs:attribute ref="name" use="required"/>
+ <xs:attribute ref="id" use="required"/>
+ <xs:attribute ref="parent" use="required"/>
+ </xs:attributeGroup>
+
+ <xs:attributeGroup name="blocksAttrGroup">
+ <xs:attribute ref="width" use="required"/>
+ <xs:attribute ref="height" use="required"/>
+ <xs:attribute ref="font" use="required" />
+ <xs:attribute ref="font_size" use="required" />
+ </xs:attributeGroup>
+
+ <xs:attributeGroup name="interfacesAttrGroup">
+ <xs:attribute ref="linelength" use="required" />
+ <xs:attribute ref="width" use="required" />
+ <xs:attribute ref="height" use="required" />
+ <xs:attribute ref="font" use="required" />
+ <xs:attribute ref="font_size" use="required" />
+ </xs:attributeGroup>
+
+
+ <!-- déclaration des attributs -->
+
+ <xs:attribute name="nb">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="name" type="xs:string"/>
+
+ <xs:attribute name="id">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="parent">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer">
+ <xs:minInclusive value="-1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="path" type="xs:string"/>
+
+ <xs:attribute name="lib_file" type="xs:string"/>
+
+ <xs:attribute name="width">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="1"/>
+ <xs:maxInclusive value="1000"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="height">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="1"/>
+ <xs:maxInclusive value="1000"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="font" type="xs:string"/>
+
+ <xs:attribute name="font_size">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="linelength">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="1"/>
+ <xs:maxInclusive value="100"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="gaplength">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="1"/>
+ <xs:maxInclusive value="100"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+
+ <!-- déclaration des groupes d'éléments -->
+
+ <xs:group name="configElmtGroup">
+ <xs:sequence>
+ <xs:element ref="categories"/>
+ <xs:element ref="references"/>
+ <xs:element ref="implementations"/>
+ <xs:element ref="defaults" />
+ </xs:sequence>
+ </xs:group>
+
+ <xs:group name="defaultsElmtGroup">
+ <xs:sequence>
+ <xs:element ref="blocks"/>
+ <xs:element ref="interfaces"/>
+ <xs:element ref="connections" />
+ </xs:sequence>
+ </xs:group>
+
+
+ <!-- déclaration des éléments -->
+
+ <xs:element name="category">
+ <xs:complexType>
+ <xs:attributeGroup ref="categoryAttrGroup" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="reference_lib">
+ <xs:complexType>
+ <xs:attribute ref="path" use="required"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="impl_lib">
+ <xs:complexType>
+ <xs:attribute ref="path" use="required"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="blocks">
+ <xs:complexType>
+ <xs:attributeGroup ref="blocksAttrGroup" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="interfaces">
+ <xs:complexType>
+ <xs:attributeGroup ref="interfacesAttrGroup" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="connections">
+ <xs:complexType>
+ <xs:attribute ref="gaplength" use="required"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="categories">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="category" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute ref="nb" use="required"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="references">
+ <xs:complexType >
+ <xs:sequence>
+ <xs:element ref="reference_lib" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute ref="nb" use="required"/>
+ <xs:attribute ref="lib_file" use="required"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="implementations">
+ <xs:complexType >
+ <xs:sequence>
+ <xs:element ref="impl_lib" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute ref="nb" use="required"/>
+ <xs:attribute ref="lib_file" use="required"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="defaults">
+ <xs:complexType>
+ <xs:group ref="defaultsElmtGroup" />
+ </xs:complexType>
+ </xs:element>
+
+
+ <!-- Racine du document -->
+
+ <xs:element name="config">
+ <xs:complexType>
+ <xs:group ref="configElmtGroup" />
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block>
+ <informations>
+ <name>
+ block-1I1O
+ </name>
+ <category ids="1,4" />
+ <description>
+ <brief>
+ A testing block with 1 input, 1 output
+ </brief>
+ <detailed>
+ A testing block with 1 input, 1 output
+ </detailed>
+ </description>
+ </informations>
+
+ <parameters>
+ <parameter name="data_width" type="string" value="8" context="user"/>
+ </parameters>
+
+ <interfaces>
+ <inputs>
+ <input name="clk" width="1" purpose="clock" />
+ <input name="rst" width="1" purpose="reset" />
+
+ <input name="data_i" width="$data_width"/>
+ </inputs>
+ <outputs>
+ <output name="data_o" width="$data_width"/>
+ </outputs>
+ </interfaces>
+
+</block>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block>
+ <informations>
+ <name>
+ block-2I2O
+ </name>
+ <category ids="1,4" />
+ <description>
+ <brief>
+ A testing block with 2 inputs, 2 outputs
+ </brief>
+ <detailed>
+ A testing block with 2 inputs, 2 outputs
+ </detailed>
+ </description>
+ </informations>
+
+ <parameters>
+ <parameter name="data_width" type="string" value="8" context="user"/>
+ </parameters>
+
+ <interfaces>
+ <inputs>
+ <input name="clk" width="1" purpose="clock" />
+ <input name="rst" width="1" purpose="reset" />
+
+ <input name="data1_i" width="$data_width"/>
+ <input name="data2_i" width="$data_width"/>
+ </inputs>
+ <outputs>
+ <output name="data1_o" width="$data_width"/>
+ <output name="data2_o" width="$data_width"/>
+ </outputs>
+ </interfaces>
+
+</block>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block>
+ <informations>
+ <name>
+ block-2INO
+ </name>
+ <category ids="1,4" />
+ <description>
+ <brief>
+ A testing block with 2 inputs, N outputs
+ </brief>
+ <detailed>
+ A testing block with 2 inputs, N outputs
+ </detailed>
+ </description>
+ </informations>
+
+ <parameters>
+ <parameter name="data_width" type="string" value="8" context="user"/>
+ </parameters>
+
+ <interfaces>
+ <inputs>
+ <input name="clk" width="1" purpose="clock" />
+ <input name="rst" width="1" purpose="reset" />
+
+ <input name="data1_i" width="$data_width"/>
+ <input name="data2_i" width="$data_width"/>
+ </inputs>
+ <outputs>
+ <output name="data_o" width="$data_width" multiplicity="*"/>
+ </outputs>
+ </interfaces>
+
+</block>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <!-- déclaration des groupes d'attributs -->
+
+ <xs:attributeGroup name="parameterAttrGroup">
+ <xs:attribute ref="name" use="required"/>
+ <xs:attribute ref="type" use="required"/>
+ <xs:attribute ref="wishbone" use="optional"/>
+ <xs:attribute ref="core" use="optional"/>
+ <xs:attribute ref="value" use="optional"/>
+ <xs:attribute ref="iface" use="optional"/>
+ <xs:attribute ref="width" use="optional"/>
+ <xs:attribute ref="context" use="required"/>
+ </xs:attributeGroup>
+
+ <xs:attributeGroup name="inOutAttrGroup">
+ <xs:attribute ref="name" use="required"/>
+ <xs:attribute ref="width" use="required"/>
+ <xs:attribute ref="type"/>
+ <xs:attribute ref="level"/>
+ <xs:attribute ref="purpose"/>
+ <xs:attribute ref="multiplicity"/>
+ </xs:attributeGroup>
+
+
+ <!-- déclaration des attributs -->
+
+ <xs:attribute name="ids" type="xs:string"/>
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="type" type="xs:string"/>
+ <xs:attribute name="core" type="xs:string"/>
+ <xs:attribute name="wishbone" type="xs:string"/>
+ <xs:attribute name="context" type="xs:string" />
+ <xs:attribute name="level" type="xs:string" />
+ <xs:attribute name="multiplicity" type="xs:string" />
+ <xs:attribute name="width" type="xs:string"/>
+ <xs:attribute name="purpose" type="xs:string"/>
+ <xs:attribute name="value" type="xs:string"/>
+ <xs:attribute name="iface" type="xs:string"/>
+ <xs:attribute name="path" type="xs:string" />
+
+
+ <!-- déclaration des groupes d'éléments -->
+
+ <xs:group name="blockElmtGroup">
+ <xs:sequence>
+ <xs:element ref="informations"/>
+ <xs:element ref="parameters"/>
+ <xs:element ref="interfaces"/>
+ <xs:element ref="implementations" minOccurs="0"/>
+ </xs:sequence>
+ </xs:group>
+
+ <xs:group name="informationsElmtGroup">
+ <xs:sequence>
+ <xs:element ref="name"/>
+ <xs:element ref="category"/>
+ <xs:element ref="description"/>
+ </xs:sequence>
+ </xs:group>
+
+ <xs:group name="descriptionElmtGroup">
+ <xs:sequence>
+ <xs:element ref="brief"/>
+ <xs:element ref="detailed"/>
+ </xs:sequence>
+ </xs:group>
+
+ <xs:group name="interfacesElmtGroup">
+ <xs:sequence>
+ <xs:element ref="inputs" minOccurs="0"/>
+ <xs:element ref="outputs" minOccurs="1"/>
+ <xs:element ref="bidirs" minOccurs="0"/>
+ </xs:sequence>
+ </xs:group>
+
+
+ <!-- déclaration des éléments -->
+
+ <xs:element name="informations">
+ <xs:complexType>
+ <xs:group ref="informationsElmtGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="name" type="xs:string" />
+
+ <xs:element name="category">
+ <xs:complexType>
+ <xs:attribute ref="ids" use="required"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="description">
+ <xs:complexType>
+ <xs:group ref="descriptionElmtGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="brief" type="xs:string" />
+
+ <xs:element name="detailed" type="xs:string" />
+
+ <xs:element name="parameters">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="parameter">
+ <xs:complexType>
+ <xs:attributeGroup ref="parameterAttrGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="interfaces">
+ <xs:complexType>
+ <xs:group ref="interfacesElmtGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="inputs">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="input" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="input">
+ <xs:complexType>
+ <xs:attributeGroup ref="inOutAttrGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="outputs">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="output" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="output">
+ <xs:complexType>
+ <xs:attributeGroup ref="inOutAttrGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="bidirs">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="bidir" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="bidir">
+ <xs:complexType>
+ <xs:attributeGroup ref="inOutAttrGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="implementations">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="implementation" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="implementation">
+ <xs:complexType>
+ <xs:attribute ref="path" use="required" />
+ </xs:complexType>
+ </xs:element>
+
+
+ <!-- Racine du document -->
+
+ <xs:element name="block">
+ <xs:complexType>
+ <xs:group ref="blockElmtGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
--- /dev/null
+\documentclass[12pt,fleqn,a4paper]{article}
+\usepackage[latin1]{inputenc}
+%\usepackage[cyr]{aeguill}
+\usepackage{xspace}
+\usepackage{amsmath}
+\usepackage{amsfonts}
+\usepackage[english]{babel}
+\usepackage{url}
+\usepackage{multirow}
+\let\urlorig\url
+\renewcommand{\url}[1]{%
+ \begin{otherlanguage}{english}\urlorig{#1}\end{otherlanguage}%
+}
+
+%\usepackage{pstricks,pst-node,pst-text,pst-3d}
+\usepackage{graphicx}
+\usepackage{thumbpdf}
+\usepackage{color}
+\usepackage{moreverb}
+%\usepackage{commath}
+\usepackage{subfigure}
+%\input{psfig.sty}
+\usepackage{fullpage}
+\usepackage{fancybox}
+
+\usepackage[ruled,lined,linesnumbered]{algorithm2e}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
+\newcommand{\noun}[1]{\textsc{#1}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%% my own LaTeX commands.
+%\newcommand{\bibpath}[1]
+% {/home/sdomas/rapport/eigenjace/ipdps/#1}
+
+\newcommand{\tab}{\ \ \ }
+\newcommand{\ot}[1]{{\tt #1}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%% my bib path.
+
+
+\title{BLAST: classes and xml files for blocks (models, implementations and view)}
+
+\author{St\'ephane Domas\\
+Laboratoire d'Informatique
+de l'Universit\'e de Franche-Comt\'e, \\
+BP 527, \\
+90016~Belfort CEDEX, France\\}
+
+
+
+\begin{document}
+
+\maketitle
+
+\thispagestyle{empty}
+\section{What are blocks and items ?}
+A block is the main unit to build a design in Blast. From the user
+point of view, a block represents a process with inputs to consume
+data, outputs to produce results. It may have some parameters
+(e.g. the input/output data size). Thus, the user is not concerned
+about how the block is really implemented in VHDL, just about the
+"function" of the block. Some blocks are predefined, but the user can
+also build them by composing predefined ones.
+
+For the first type, the user has to choose the predefined blocks from
+a library of "reference blocks" that do a particular processing
+(i.e. a multiplication, a filter, ...), with default interface names
+and parameter values. To add such a block to the design, a reference
+block is cloned to obtain a "functional" block. It is similar to the
+instanciation in object oriented programming: reference block
+corresponds to the class, and functional block to the instance of that
+class. Thus, a design may contain several functional blocks that
+correspond to the same reference block. A reference block is
+associated to one or several implementations that are in fact patterns
+of VHDL code. One of them will be chosen more or less automatically by
+Blast to produce the final VHDL code. The representation of an
+implementation as a class and the structure of the files that contain
+patterns are discussed in details in Section \ref{Implementations}.
+
+The second type is named a "group" block. It is created empty or with
+a set of existing functional blocks. For example, when a void design
+is created, a group block is also created, that will represent the top
+component in the VHDL code. User can add predefined blocks or even
+other group blocks within a group very easily. There main purpose is
+to make the design clearer and the VHDL more readable. Indeed, each
+group will be translated into a VHDL component. Thus, instead of
+having a single top component with a bunch of predefined blocks
+within, they can be spread within groups to build a design
+hierachically.
+
+These three types of block are represented by a hierarchy of classes
+that is described in details in Section \ref{sec:blocks_class}.\\
+
+Reference, functional and group blocks are just containers of data,
+i.e. they are part of the Model in MVC paradigm). The two latter have
+a graphical counter part, named items, so that they can be represented
+in the graphical interface. The hierarchy of classes
+that represents the items is described in details in Section \ref{sec:items_class}.\\
+
+\section{Class hierarchy for blocks}
+\label{sec:blocks_class}
+
+\subsection{the top class}
+\label{sec:abstract_block_class}
+
+The top class for describing block is {\tt AbstractBlock}, derived in
+three subclasses: {\tt ReferenceBlock}, {\tt FunctionalBlock}, {\tt
+ GroupBlock}.
+
+Some attributes are common to every types, and defined in {\tt AbstractBlock}:
+\begin{itemize}
+\item a name,
+\item parameters,
+\item input/output/bidirectional interfaces.
+\end{itemize}
+
+Parameters and interfaces are complex to represent and thus, are also
+described by a hierarchy of classes in Section
+\ref{sec:parameters_class} and \ref{sec:interfaces_class}.
+
+\subsection{reference blocks}
+\label{sec:reference_block_class}
+
+A reference block is created taking informations in an XML file that
+describes it, providing its parameters and interfaces. The structure
+of that file is described in details in Section
+\ref{sec:references_xml}.
+
+A reference block also contains a list of {\tt
+ BlockImplementation}. Each of them represents a pattern of VHDL code
+that implements the function of the block.
+
+\subsection{functional blocks}
+\label{sec:functional_block_class}
+
+A functional block has two attributes {\tt reference} and {\tt group}
+that respectively refer to the reference block that has been cloned to
+create that functional block, and the group block that contains it.
+
+
+\subsection{group blocks}
+\label{sec:group_block_class}
+
+A group block has mainly two attributes {\tt parent} and {\tt
+ blocks}. The first one is a pointer to the group that contains that
+group (or {\tt NULL} if it is the top group). The second one is the
+list of the functional or group blocks that are within this group.
+
+{\bf Important: } a group block has no interface by itself. In fact,
+they are created when the user wants to connect an interface of a
+inner block to the outside of the block. Note that there is a 1:1
+relation between a group interface and an interface of an inner
+block. Nevertheless, an output group interface can still be connected
+to several input interfaces.
+
+{\bf Important: } a group block has no parameters by itself, except
+if it contains blocks that may be configured via a wishbone. In this
+case, the generic parameters to manage the wishbone are atuomaticcaly
+added to the group.
+
+\subsection{interfaces classes}
+\label{sec:interfaces_class}
+
+As for blocks, a top class {\tt AbstractInterface} represents the
+common features of all interfaces and it is derived in three
+subclasses: {\tt ReferenceInterface}, {\tt FunctionalInterface} and
+{\tt GroupInterface}.
+
+\subsection{parameters classes}
+\label{sec:parameters_class}
+
+
+There are four types of parameters for a block:
+\begin{itemize}
+\item user,
+\item generic,
+\item port,
+\item wishbone.
+\end{itemize}
+
+These are represented by the top class {\tt BlockParameter} and four
+subclasses: ({\tt BlockParameterUSer}, {\tt BlockParameterGeneric},
+{\tt BlockParameterPort}, {\tt BlockParameterWishbone}.
+
+Four attributes are common to all, and defined in {\tt BlockParameter}:
+\begin{itemize}
+\item \ot{owner}: a pointer to the block instance (reference/functional) that ``owns'' this parameter,
+\item \ot{name}: the name of the parameter (NB: cannot be changed by the user of BLAST),
+\item \ot{type}: the type of the value,
+\item \ot{value}: the default value of the parameter, given as a \ot{QString} but stored as a \ot{QVariant}.
+\end{itemize}
+
+\ot{type} value (int) must be set with one of those in \ot{ParamType} enum (cf. \ot{BlockParameter.h}):
+
+\begin{verbatim}
+enum ParamType { Undefined = -1, Expression = 1, Character,
+ String, Bit, BitVector, Boolean,
+ Integer, Natural, Positive, Real, Time};
+\end{verbatim}
+Except the two first, these values correspond to predefined types in
+VHDL. \ot{Expression} correspond to an arithmetic expression and must
+be used only for port and wishbone parameters. Thus, its syntax will
+be presented in the associated sections (\ref{sec:parameters_port} and
+\ref{parameters_wb}).\\
+
+Whatever the case, parameters will be used during VHDL generation but at different phases, depending on the class.
+
+\subsubsection{user parameters}
+\label{sec:parameters_user}
+User parameters have a type equals to \ot{String}. A default value
+must be given at construction but a \ot{userValue} can be defined via
+setters.\\
+
+A user parameter is only used when generating the VHDL code of the
+architecture section of a block (cf. section
+\ref{sec:impls_xml}). Each time the generator encounters an escape
+sequence: \ot{@val\{user\_parameter\_name\}}, it replaces it with
+\ot{userValue} if defined, or with the default value.\\
+
+{\bf CAUTION:} No validity check are done by BLAST on default and user
+value strings. Thus, they can be anything and can lead to incorrect
+VHDL.
+
+\subsubsection{generic parameters}
+\label{sec:parameters_generic}
+
+Generic parameters have a type equals to any predefined VHDL type (i.e. all
+defined above except \ot{Undefined} and \ot{Expression}). A default
+value must be given at construction but a \ot{userValue} can be
+defined via setters.\\
+
+A generic parameter is used during the generation of:
+\begin{itemize}
+\item the entity section,
+\item the component section when the owner block is used within another block,
+\item the generic map of when instanciating owner block is used within another block,
+\item the architecture section.
+\end{itemize}
+
+In the two first cases, it leads to lines like
+
+\ot{d\_width : integer := 16;}, using the \ot{name}, \ot{type} and default value.
+
+In the third case, it leads to lines like
+
+\ot{d\_width => 10,}, using the \ot{name} and \ot{userValue},
+or default value if not defined.
+
+\ot{d\_width => d\_width,}, using only the
+\ot{name}. This case occurs when the owner is instanciated within a
+block that has a generic parameter with the same name.
+
+In the last case, each time the generator encounters an escape
+sequence: \ot{@val\{generic\_parameter\_name\}}, it replaces it with
+\ot{userValue} if defined, or with the default value.\\
+
+{\bf IMPORTANT:} a block that defines wishbone parameters will be
+generated with 2 generic parameters with predefined names:
+\ot{wb\_data\_width} and \ot{wb\_addr\_width}. They correspond to the
+width of the address and data buses of the wishbone and are used
+during the generation of the controller of the block
+(cf. \ref{sec:parameters_wb}).
+
+\subsubsection{port parameters}
+\label{sec:parameters_port}
+A port parameter can be used to obtain a value associated to an
+interface of the block. Indeed, it is possible to create several
+instances of the same interface, when its multiplicity given in the
+reference model is greater than 1. For example, it is used for block
+that may have a variable number of inputs/outputs, like a
+multiplexer. Instead fo creating a bunch of multiplexers with 2, 3, 4,
+$\ldots$ data inputs, it is possible to generate one for any
+amount. In BLAST, this amount is given by the number of instances of
+the data input the user has created. It implies that the selector
+input has a variable range and thus needs a variable number of bits to
+be expressed. If $N$ is the number of instances of the data input,
+then the selector size is $log_2(N)$. A port parameter is used to
+express such a value.\\
+
+A port parameters have a supplementary attribute \ot{ifaceName} that
+must correspond to an existing interface of the block. \ot{type} is
+equal to \ot{Expression} and \ot{value} contains this expression,
+using variables with a predefined name \ot{\$if\_nb} and
+\ot{\$if\_width} that will be respectively replace during VHDL
+generation by the number of instances of \ot{ifaceName}, and its
+width.
+
+A port parameter is used during the generation of:
+\begin{itemize}
+\item the entity section,
+\item the component section when the owner block is used within another block,
+\item the architecture section.
+\end{itemize}
+
+In every case, each time the generator encounters an escape sequence:
+\ot{@val\{port\_parameter\_name\}}, it replaces it with the computed
+value of the parameter using the expression and the interface name.
+
+
+\subsubsection{wishbone parameters}
+\label{sec:parameters_wb}
+
+A wishbone parameter corresponds to a register that can be read/write
+via the wishbone bus. Nevertheless, the GUI allows the user to disable
+the wishbone access and replace it by a fixed value or a port that is
+assign to the register.
+
+Since a register has a width, \ot{type} gives its type. Valid types are:
+\begin{itemize}
+\item \ot{boolean} if the register is an \ot{std\_logic},
+\item \ot{natural} if the register has a fixed width and is a \ot{std\_logic\_vector},
+\item \ot{expression} if the register has a variable width and is a \ot{std\_logic\_vector},
+\end{itemize}
+The width is given in a supplementary attribute \ot{width}. Note that:
+\begin{itemize}
+\item if the type is boolean, width should be equal to 1 but in fact is not used.
+
+\item if the type is natural and width is equal to 1, it leads to
+\ot{std\_logic\_vector(0 downto 0)}, which is sometimes usefull for
+memory accesses.
+
+\item if the type is an expression, width must contains an expression
+ using only +,-,*, numbers and generic parameter references
+ (i.e. parameter name prepend with a $). No check is done thus, the
+ model must be correct so that valid VHDL will be produced.
+\end{itemize}
+
+In the second case, the expression may use predefined names
+\ot{wb\_data\_width} and \ot{wb\_addr\_width}.
+
+Whatever the case, during VHDL generation, the final width will be
+compared to the wishbone data bus width. If the bus width is lesser
+than the register width, then several wishbone accesses are needed to
+read/write the register. For example, if wishbone width is 16 and a
+register has a width of 20, we need to define two addresses, one to
+access to bits 0 to 15, and one for bits 16 to 19. The total number of
+needed addresses gives the minimal width of the address bus (i.e. log2(nb addr)).\\
+
+The value is a initialization value. If not provided, it is 0 by
+default.\\
+
+Three other attributes are declared:
+\begin{itemize}
+\item \ot{wbAccess}: indicates if the register is written or read by
+ the wishbone bus. Thus, if it is written, the register is an input
+ of the block and if it is read, the block provides its value.
+\item \ot{wbValue}: it may be a natural, a boolean, or the word
+ data. In the two first cases, the given value is affected to the
+ register as soon as the register is accessed in writing. In the
+ third case, the register is affected with the value that is provided
+ on the wishbone data bus.
+\item \ot{wbDuration} : indicates if the affectation is permanent or
+ just a trigger. In the second case, the value is set for just one
+ clock cycle and then reset to the initialization value given by the
+ \ot{value} attribute.\\
+\end{itemize}
+
+A wishbone parameter is used during the generation of:
+\begin{itemize}
+\item the controller of the block (NB: this generation is done at the block level),
+\item the entity section, because register values are in fact read/write by the block via input/output ports,
+\item the component section when the owner block is used within another block.
+\end{itemize}
+
+\section{Implementations XML description}
+\label{sec:impls_xml}
+
+\section{Implementations class hierarchy}
+\label{sec:impls_class}
+
+
+\end{document}
+
+
+
+
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="54.086605"
+ height="39"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.5 r10040"
+ sodipodi:docname="add_block.svg"
+ inkscape:export-filename="/home/sdomas/Projet/Blast/code/v0.2/icons/add_block.png"
+ inkscape:export-xdpi="300"
+ inkscape:export-ydpi="300">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient5732">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop5734" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.78195488;"
+ offset="1"
+ id="stop5736" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4248">
+ <stop
+ style="stop-color:#205026;stop-opacity:1;"
+ offset="0"
+ id="stop4250" />
+ <stop
+ id="stop4256"
+ offset="1"
+ style="stop-color:#285e31;stop-opacity:0.49803922;" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="11.313708"
+ inkscape:cx="46.8372"
+ inkscape:cy="26.47285"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1454"
+ inkscape:window-height="800"
+ inkscape:window-x="435"
+ inkscape:window-y="130"
+ inkscape:window-maximized="0"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ borderlayer="true"
+ inkscape:showpageshadow="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid5846"
+ units="px"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true"
+ spacingx="1px"
+ spacingy="1px"
+ originx="0.543305px"
+ originy="-7.4999995px" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-50.550445,-21.358244)">
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987"
+ width="26.574802"
+ height="32.401573"
+ x="64.117371"
+ y="22.858244" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 91.235473,37.858244 8.858277,0"
+ id="path3757"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 55.09375,30.858244 8.858268,0"
+ id="path4203"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 100.09375,36.086591 0,3.543307 3.5433,-1.771654 z"
+ id="path4205"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 51.550445,29.086591 0,3.543307 3.543305,-1.771654 z"
+ id="path4205-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 55.259102,48.173205 8.858268,0"
+ id="path4203-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 51.715795,46.401549 0,3.543307 3.543305,-1.771654 z"
+ id="path4205-7-0"
+ inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Wingdings;-inkscape-font-specification:Wingdings"
+ x="77.09375"
+ y="31.858244"
+ id="text5848"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan5850"
+ x="77.09375"
+ y="31.858244"
+ style="font-size:6px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Wingdings;-inkscape-font-specification:Wingdings">bloc</tspan></text>
+ <path
+ style="color:#000000;fill:#3bb21f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 81.09375,35.858244 c -1.108,0 -2,0.892 -2,2 l 0,6 -6,0 c -1.108,0 -2,0.892 -2,2 l 0,4 c 0,1.108 0.892,2 2,2 l 6,0 0,6 c 0,1.108 0.892,2 2,2 l 4,0 c 1.108,0 2,-0.892 2,-2 l 0,-6 6,0 c 1.108,0 2,-0.892 2,-2 l 0,-4 c 0,-1.108 -0.892,-2 -2,-2 l -6,0 0,-6 c 0,-1.108 -0.892,-2 -2,-2 l -4,0 z"
+ id="rect4258-34"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="39.03125"
+ height="32.875"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.5 r10040"
+ sodipodi:docname="add_connection.svg"
+ inkscape:export-filename="/home/sdomas/Projet/Blast/code/v0.2/icons/add_connection.png"
+ inkscape:export-xdpi="300"
+ inkscape:export-ydpi="300">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient5732">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop5734" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.78195488;"
+ offset="1"
+ id="stop5736" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4248">
+ <stop
+ style="stop-color:#205026;stop-opacity:1;"
+ offset="0"
+ id="stop4250" />
+ <stop
+ id="stop4256"
+ offset="1"
+ style="stop-color:#285e31;stop-opacity:0.49803922;" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="11.313708"
+ inkscape:cx="34.613044"
+ inkscape:cy="13.989927"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1454"
+ inkscape:window-height="800"
+ inkscape:window-x="435"
+ inkscape:window-y="129"
+ inkscape:window-maximized="0"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ borderlayer="true"
+ inkscape:showpageshadow="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid5846"
+ units="px"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true"
+ spacingx="1px"
+ spacingy="1px"
+ originx="-15.46875px"
+ originy="-10.514493px" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-66.5625,-24.46875)">
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 98.55045,26.08659 0,3.543307 3.5433,-1.771654 z"
+ id="path4205"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 67.550445,36.08659 0,3.543307 3.543305,-1.771654 z"
+ id="path4205-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 20.543305,16.499999 15,0 0,-10.0000003 15,8e-7"
+ id="path6694"
+ inkscape:connector-curvature="0"
+ transform="translate(50.550445,21.358244)"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="color:#000000;fill:#3bb21f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 91.09375,32.858243 c -1.108,0 -2,0.892001 -2,2 l 0,6 -6,0 c -1.108,0 -2,0.892001 -2,2 l 0,4 c 0,1.108 0.892,2 2,2 l 6,0 0,6 c 0,1.108 0.892,2 2,2 l 4,0 c 1.108,0 2,-0.892 2,-2 l 0,-6 6,0 c 1.108,0 2,-0.892 2,-2 l 0,-4 c 0,-1.107999 -0.892,-2 -2,-2 l -6,0 0,-6 c 0,-1.107999 -0.892,-2 -2,-2 l -4,0 z"
+ id="rect4258-34"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="49"
+ height="50.401577"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.5 r10040"
+ sodipodi:docname="add_group.svg"
+ inkscape:export-filename="/home/sdomas/Projet/Blast/code/v0.2/icons/add_group_select.png"
+ inkscape:export-xdpi="300.06253"
+ inkscape:export-ydpi="300.06253">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient5732">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop5734" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.78195488;"
+ offset="1"
+ id="stop5736" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4248">
+ <stop
+ style="stop-color:#205026;stop-opacity:1;"
+ offset="0"
+ id="stop4250" />
+ <stop
+ id="stop4256"
+ offset="1"
+ style="stop-color:#285e31;stop-opacity:0.49803922;" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="8"
+ inkscape:cx="55.945956"
+ inkscape:cy="29.358358"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1454"
+ inkscape:window-height="800"
+ inkscape:window-x="425"
+ inkscape:window-y="32"
+ inkscape:window-maximized="0"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid5846"
+ units="px"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true"
+ spacingx="1px"
+ spacingy="1px"
+ originx="-3px"
+ originy="-0.99999815px" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-54.09375,-16.456669)">
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987-5-4"
+ width="11.000002"
+ height="8.9999981"
+ x="83.09375"
+ y="37.858246" />
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987"
+ width="44.000004"
+ height="35"
+ x="55.09375"
+ y="26.858242" />
+ <rect
+ style="color:#000000;fill:#3bb21f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect4258"
+ width="6"
+ height="20"
+ x="90.09375"
+ y="46.858246"
+ rx="2"
+ ry="2" />
+ <rect
+ style="color:#000000;fill:#3bb21f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect4258-3"
+ width="6"
+ height="20"
+ x="53.858246"
+ y="-103.09375"
+ rx="2"
+ ry="2"
+ transform="matrix(0,1,-1,0,0,0)" />
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Wingdings;-inkscape-font-specification:Wingdings"
+ x="70.09375"
+ y="23.858244"
+ id="text5848"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan5850"
+ x="70.09375"
+ y="23.858244"
+ style="font-size:6px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Wingdings;-inkscape-font-specification:Wingdings">group</tspan></text>
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987-2"
+ width="31.000004"
+ height="9.4015751"
+ x="55.09375"
+ y="17.456669" />
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987-5"
+ width="16.000002"
+ height="8.9999981"
+ x="60.09375"
+ y="31.858244" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 76.09375,35.858244 3,0 0,4 4,0"
+ id="path5925"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987-5-8"
+ width="16.000002"
+ height="8.9999981"
+ x="60.09375"
+ y="46.858246" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 25,39 3,0 0,-8 4,0"
+ id="path5945"
+ inkscape:connector-curvature="0"
+ transform="translate(51.09375,13.858244)"
+ sodipodi:nodetypes="cccc" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="51"
+ height="51.401577"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.5 r10040"
+ sodipodi:docname="add_group_void.svg"
+ inkscape:export-filename="/home/sdomas/Projet/Blast/code/v0.2/icons/add_group_void.png"
+ inkscape:export-xdpi="300.06253"
+ inkscape:export-ydpi="300.06253">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient5732">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop5734" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.78195488;"
+ offset="1"
+ id="stop5736" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4248">
+ <stop
+ style="stop-color:#205026;stop-opacity:1;"
+ offset="0"
+ id="stop4250" />
+ <stop
+ id="stop4256"
+ offset="1"
+ style="stop-color:#285e31;stop-opacity:0.49803922;" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="8"
+ inkscape:cx="36.894824"
+ inkscape:cy="23.63185"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1454"
+ inkscape:window-height="800"
+ inkscape:window-x="425"
+ inkscape:window-y="32"
+ inkscape:window-maximized="0"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid5846"
+ units="px"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true"
+ spacingx="1px"
+ spacingy="1px"
+ originx="-2.5px"
+ originy="-0.50000015px" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-53.59375,-15.956669)">
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987-5-4"
+ width="11.000002"
+ height="8.9999981"
+ x="83.09375"
+ y="37.858246" />
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987"
+ width="44.000004"
+ height="35"
+ x="55.09375"
+ y="26.858242" />
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Wingdings;-inkscape-font-specification:Wingdings"
+ x="70.09375"
+ y="23.858244"
+ id="text5848"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan5850"
+ x="70.09375"
+ y="23.858244"
+ style="font-size:6px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Wingdings;-inkscape-font-specification:Wingdings">group</tspan></text>
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987-2"
+ width="31.000004"
+ height="9.4015751"
+ x="55.09375"
+ y="17.456669" />
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987-5"
+ width="16.000002"
+ height="8.9999981"
+ x="60.09375"
+ y="31.858244" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 76.09375,35.858244 3,0 0,4 4,0"
+ id="path5925"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987-5-8"
+ width="16.000002"
+ height="8.9999981"
+ x="60.09375"
+ y="46.858246" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 25,39 3,0 0,-8 4,0"
+ id="path5945"
+ inkscape:connector-curvature="0"
+ transform="translate(51.09375,13.858244)"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="color:#000000;fill:#3bb21f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 90.09375,42.858244 c -1.108,0 -2,0.892 -2,2 l 0,6 -6,0 c -1.108,0 -2,0.892 -2,2 l 0,4 c 0,1.108 0.892,2 2,2 l 6,0 0,6 c 0,1.108 0.892,2 2,2 l 4,0 c 1.108,0 2,-0.892 2,-2 l 0,-6 6,0 c 1.108,0 2,-0.892 2,-2 l 0,-4 c 0,-1.108 -0.892,-2 -2,-2 l -6,0 0,-6 c 0,-1.108 -0.892,-2 -2,-2 l -4,0 z"
+ id="rect4258"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="51"
+ height="51.401577"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.5 r10040"
+ sodipodi:docname="add_group_void.svg"
+ inkscape:export-filename="/home/sdomas/Projet/Blast/code/v0.2/icons/add_group_select.png"
+ inkscape:export-xdpi="300.06253"
+ inkscape:export-ydpi="300.06253">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient5732">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop5734" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.78195488;"
+ offset="1"
+ id="stop5736" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4248">
+ <stop
+ style="stop-color:#205026;stop-opacity:1;"
+ offset="0"
+ id="stop4250" />
+ <stop
+ id="stop4256"
+ offset="1"
+ style="stop-color:#285e31;stop-opacity:0.49803922;" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="8"
+ inkscape:cx="36.894824"
+ inkscape:cy="23.63185"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1454"
+ inkscape:window-height="800"
+ inkscape:window-x="425"
+ inkscape:window-y="32"
+ inkscape:window-maximized="0"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid5846"
+ units="px"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true"
+ spacingx="1px"
+ spacingy="1px"
+ originx="-2.5px"
+ originy="-0.50000015px" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-53.59375,-15.956669)">
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987"
+ width="44.000004"
+ height="35"
+ x="55.09375"
+ y="26.858242" />
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Wingdings;-inkscape-font-specification:Wingdings"
+ x="70.09375"
+ y="23.858244"
+ id="text5848"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan5850"
+ x="70.09375"
+ y="23.858244"
+ style="font-size:6px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Wingdings;-inkscape-font-specification:Wingdings">group</tspan></text>
+ <rect
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987-2"
+ width="31.000004"
+ height="9.4015751"
+ x="55.09375"
+ y="17.456669" />
+ <path
+ style="color:#000000;fill:#3bb21f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 90.09375,42.858244 c -1.108,0 -2,0.892 -2,2 l 0,6 -6,0 c -1.108,0 -2,0.892 -2,2 l 0,4 c 0,1.108 0.892,2 2,2 l 6,0 0,6 c 0,1.108 0.892,2 2,2 l 4,0 c 1.108,0 2,-0.892 2,-2 l 0,-6 6,0 c 1.108,0 2,-0.892 2,-2 l 0,-4 c 0,-1.108 -0.892,-2 -2,-2 l -6,0 0,-6 c 0,-1.108 -0.892,-2 -2,-2 l -4,0 z"
+ id="rect4258"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
--- /dev/null
+#!/bin/sh
+
+####################################
+# blast installation script
+###################################
+
+if ! [ -f ./blast ]; then
+ echo "Impossible de trouver l'executable dans le répertoire courant. Arret"
+ exit 1
+fi
+if ! [ -d ./locales ]; then
+ echo "Impossible de trouver les fichiers de langue dans le répertoire courant. Arret"
+ exit 1
+fi
+
+if ! [ -d /usr/local/bin ]; then
+ mkdir -p /usr/local/bin
+fi
+
+if ! [ -d /usr/local/share/blast ]; then
+ mkdir -p /usr/local/share/blast
+else
+ rm -rf /usr/local/share/blast
+ mkdir -p /usr/local/share/blast
+fi
+
+if [ -f /usr/local/bin/blast ]; then
+ echo "Suppression de la version actuellement installée"
+ rm -f /usr/local/bin/blast
+fi
+echo "Installation :"
+echo "binaries"
+cp blast /usr/local/bin
+echo "locales"
+cp -r locales /usr/local/share/blast/
+echo "examples"
+cp -r examples /usr/local/share/blast/
+echo "done."
--- /dev/null
+#!/bin/sh
+
+####################################
+# @@APPNAME@@ installation script
+###################################
+
+if ! [ -f ./@@APPNAME@@ ]; then
+ echo "Impossible de trouver l'executable dans le répertoire courant. Arret"
+ exit 1
+fi
+if ! [ -d ./locales ]; then
+ echo "Impossible de trouver les fichiers de langue dans le répertoire courant. Arret"
+ exit 1
+fi
+
+if ! [ -d /usr/local/bin ]; then
+ mkdir -p /usr/local/bin
+fi
+
+if ! [ -d /usr/local/share/@@APPNAME@@ ]; then
+ mkdir -p /usr/local/share/@@APPNAME@@
+else
+ rm -rf /usr/local/share/@@APPNAME@@
+ mkdir -p /usr/local/share/@@APPNAME@@
+fi
+
+if [ -f /usr/local/bin/@@APPNAME@@ ]; then
+ echo "Suppression de la version actuellement installée"
+ rm -f /usr/local/bin/@@APPNAME@@
+fi
+echo "Installation :"
+echo "binaries"
+cp @@APPNAME@@ /usr/local/bin
+echo "locales"
+cp -r locales /usr/local/share/@@APPNAME@@/
+echo "examples"
+cp -r examples /usr/local/share/@@APPNAME@@/
+echo "done."
--- /dev/null
+------------------------------------
+XML description of a block model :
+------------------------------------
+
+<parameter> attributes :
+ - name : required
+ - type : required
+ - value : required if context = constant/generic, optionnal if context = wb, optional but not used if context = user/port
+ - context : required
+ - core : required if context = wb, not used for others. Possibles values : r or w. Specify if the parameter will be a register
+ that is read by the core, i.e. an input port of the core, or written by the core.
+
+<inputs>, <outputs> attributes :
+ - name : required
+ - width : required
+ - purpose : optional. Possible values : clock, reset, wb, data, ... Default value is data
+ - level : optional. Possible values : basic, top, ... Default value is basic
+ - multiplicity : optional. Possible values : *, a number. Default value is 1.
+
+<bidirs> attributes :
+ - name : required
+ - width : required
+ - purpose : optional but forced to data
+ - level : optional but forced to top
+ - multiplicity : optional. Possible values : *, a number. Default value is 1.
+ If an interface has a multiplicity > 1, the user will be able to create several
+ instances of that interface. Their default name will be the reference name
+ followed by _X, where X = 1, ..., N, and N the number of instances.
+
+
+--------------------------------------------
+XML description of an implementation model :
+--------------------------------------------
+
+<block_impl> attributes:
+ - ref_name: the name of an XML file that contains the block model associated to this implementation. Normally, it should be unique over all available blocks.
+ - ref_id : the md5 hashsum of the xml file given in ref_name. It is used to quickly retrieve the block model in the applciation.
+
+<comments> block:
+ - all elements and their attributes are amndatory but they can be void.
+
+<libraries> block:
+ - used to generate the library and use instructions.
+ - in case of using a standard package (from work or std), only use clauses will be generated.
+
+<architecture> block:
+ - constains only the architecture part of the implementation
+ - the name of the architecture will be determined automatically from the number of existing implementations for the block model. The name will be the name of the block followed by _X, where X is the rank of the implementation found when directories are parsed to found implementations.
+
+syntax:
+
+ - @{input/output/bidir} is replaced by the "real" name in the pgrah
+ of blocks. It is because the reference name given in the reference
+ block may be changed by the user for a specific instance of that
+ block in the graph. Using @{name} will lead to do produce a VHDL
+ code with the name given by the user and not the reference name.
+
+ - @{param} is replaced by the name of the parameter as given in the reference
+ blokc, which cannot be changed by the user.
+
+ - @val{param} is replaced by the value of the parameter. This value may be
+ constant, given by user, or sometimes computed according to number of
+ instances of an interface with multiplicitiy>1.
+
+ - @eval(expression) is replaced by the result of the evaluation of th arithmetic expression.
+ This expression can use +,-,*,/,(,), numbers and values of params, i.e. @val{param} expressions.
+ BEWARE : using a generic param value in an @eval{} is inadvisable, since it breaks the principles of
+ the generic use.
+
+ - @foreach{interface}
+ // instructions
+ @endforeach
+
+ only applicable to interfaces with multiplicity>1. Used to produce
+ a sequence of instruction X times, where X is the number of
+ interface instances created by the user. For each of those interfaces,
+ instructions will be generated. If ${interface} is used
+ within the instructions, it will be replaced by the actual evaluated interface.
+
+ Example : let val_o an output interface with multiplicity="*"
+ Supposing the user created 3 instances, leaving the two first with their default name (i.e. val_o_1 val_o_2) and the last one with name val_o_last.
+ Then, if an implementation contains :
+ @foreach{val_o}
+ signal @{val_o}_enb : std_logic;
+ @endforeach
+
+ Then the generated VHDL is :
+ signal val_o_1_enb : std_logic;
+ signal val_o_2_enb : std_logic;
+ signal val_o_last_enb : std_logic;
+
+ - @caseeach{interface,signal,cases}
+ // instructions
+ @endcaseeach
+
+ similar to foreach but to produce a case statement. signal is the
+ signal used to test against the cases. Obviously, there should be
+ as much cases as the number of interface instances. If not, the
+ generation will not be complete.
+ cases may be a predefined variables (see below) or a list of values.
+
+ Example : with the same assumptions as in foreach example,
+
+ @caseeach(val_o,sel_s,@#:1)
+ @{val_o}_enb <= '1';
+ @endcaseeach
+
+ will produce
+ case sel_s is
+ when 1 => val_o_1_enb <= '1';
+ when 2 => val_o_2_enb <= '1';
+ when 3 => val_o_last_enb <= '1';
+ end case;
+
+ - @#[-]:number : only usefull within foreach, caseeach, ... Produces an output
+ that starts at number and increments or decrements (with #-) at each case.
+
+ Example : @#-:3 will produce 3, 2, 1, 0, -1, ...
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block_impl ref_name="apf27-wb-master.xml" ref_md5="">
+ <comments>
+ <author firstname="stephane" lastname="Domas" mail="sdomas@univ-fcomte.fr" />
+ <date creation="2015/04/27" />
+ <related_files list="interconn.vhd,clkrstgen.vhd"/>
+ <description>
+ This component is an interface between i.MX signals
+ and the interconnector component.
+ </description>
+ <notes>
+ On i.MX<->FPGA connection : the WEIM part of i.MX has a 16 bits bus address
+ but only [1:12] bits are connected to FPGA pins. From the i.MX point of view
+ it means that reading in memory mapped address 0x0002 or 0x0003 gives the same
+ result since the LSB bit of the address is not transmited.
+
+ These 12 bits are forwarded to the interconnector which is responsible to
+ determine for what IP the data and addr signals must be routed.
+
+ </notes>
+ </comments>
+
+ <libraries>
+ <library name="IEEE">
+ <package name="std_logic_1164" use="all"/>
+ <package name="numeric_std" use="all"/>
+ </library>
+ </libraries>
+
+ <architecture>
+
+ signal write : std_logic;
+ signal read : std_logic;
+ signal strobe : std_logic;
+ signal writedata : std_logic_vector(@{wb_data_width}-1 downto 0);
+ signal address : std_logic_vector(@{wb_addr_width}-1 downto 0);
+
+begin
+
+-- ----------------------------------------------------------------------------
+-- External signals synchronization process
+-- ----------------------------------------------------------------------------
+ process(@{clk}, @{reset})
+ begin
+ if(@{reset}='1') then
+ write <= '0';
+ read <= '0';
+ strobe <= '0';
+ writedata <= (others => '0');
+ address <= (others => '0');
+ elsif(rising_edge(@{clk})) then
+ strobe <= not (@{imx_cs_n}) and not(@{imx_oe_n} and @{imx_eb3_n});
+ write <= not (@{imx_cs_n} or @{imx_eb3_n});
+ read <= not (@{imx_cs_n} or @{imx_oe_n});
+ address <= @{imx_addr};
+ writedata <= @{imx_data};
+ end if;
+ end process;
+
+ @{addr_o} <= address when (strobe = '1') else (others => '0');
+ @{dat_o} <= writedata when (write = '1') else (others => '0');
+ @{stb_o} <= strobe;
+ @{we_o} <= write;
+ @{cyc_o} <= strobe;
+
+ @{imx_data} <= @{dat_i} when(read = '1' ) else (others => 'Z');
+
+ </architecture>
+</block_impl>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block_impl ref_name="demux.xml" ref_md5="">
+ <comments>
+ <author firstname="stephane" lastname="Domas" mail="sdomas@univ-fcomte.fr" />
+ <date creation="2015/04/27" />
+ <related_files list=""/>
+ <description>
+ This component is a synchronous demultiplixer with variable number of outputs
+ </description>
+ <notes>
+ No notes
+ </notes>
+ </comments>
+
+ <libraries>
+ <library name="IEEE">
+ <package name="std_logic_1164" use="all"/>
+ <package name="numeric_std" use="all"/>
+ </library>
+ </libraries>
+
+ <architecture>
+
+ signal sel_s : unsigned(@eval{@val{sel_width}-1} downto 0);
+ signal val_i_dly : std_logic_vector(@eval{@val{val_width}-1} downto 0};
+
+ @foreach{val_o}
+ signal @{val_o}_enb : std_logic;
+ @endforeach
+
+ begin
+
+ sel_s <= @{sel_i};
+
+ delay_input : process(@{clk}, @{rst})
+ begin
+ if(@{rst}='1') then
+ val_i_dly <= (others => '0');
+ elsif(rising_edge(@{clk})) then
+ val_i_dly <= @{val_i};
+ end if;
+ end process delay_input;
+
+
+ demux : process(@{clk}, @{rst})
+ begin
+ if(@{rst}='1') then
+
+ @foreach{val_o}
+ @{val_o}_enb <= '0';
+ @endforeach
+
+ elsif(rising_edge(@{clk})) then
+
+ @foreach{val_o}
+ @{val_o}_enb <= '0';
+ @endforeach
+
+ @caseeach{val_o,sel_s,@#:1}
+ @{val_o}_enb <= '1';
+ @endcaseeach
+
+ end if;
+ end process demux;
+
+ @foreach{val_o}
+ @{val_o} <= val_i_dly when (@{val_o}_enb = '1') else (others => '0');
+ @endforeach
+
+ </architecture>
+</block_impl>
--- /dev/null
+-------------------------------------------------------------------------------
+--
+-- File : multadd.vhd
+-- Related files :
+--
+-- Author(s) : stephane Domas (sdomas@univ-fcomte.fr)
+--
+-- Creation Date : 2015/04/27
+--
+-- Description : This component is a multadd
+--
+-- Note : No notes
+--
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity multadd is
+ generic (
+ wb_data_width : integer := 16;
+ wb_addr_width : integer := 12
+ );
+ port (
+ -- clk/rst from multadd wrapper
+ rst : in std_logic;
+ clk : in std_logic;
+
+ -- registers r/w via wishbone
+ wb_do_op : in std_logic;
+ wb_c : in std_logic_vector(wb_data_width-1 downto 0);
+ wb_d : out std_logic_vector(2*wb_data_width-1 downto 0);
+
+ -- data ports
+ val1_i : in std_logic_vector(17 downto 0);
+ val2_i : in std_logic_vector(17 downto 0);
+ res_o : out std_logic_vector(35 downto 0)
+ );
+end multadd;
+
+
+architecture multadd_1 of multadd is
+
+ -- Signals
+ signal a_s : signed(17 downto 0);
+ signal b_s : signed(17 downto 0);
+ signal c_s : signed(35 downto 0);
+ signal result : signed(35 downto 0);
+
+begin
+
+ a_s <= signed(val1_i);
+ b_s <= signed(val2_i);
+ c_s <= resize(signed(wb_c), 36);
+
+ do_mult_process : process (clk, rst)
+ begin
+ if rst = '1' then
+
+ result <= to_signed(0, 36);
+
+ elsif (rising_edge(clk)) then
+
+ if wb_do_op = '1' then
+ result <= a_s * b_s + c_s;
+ end if;
+
+ end if;
+ end process do_mult_process;
+
+ res_o <= std_logic_vector(result);
+ wb_d <= std_logic_vector(resize(result, 2*wb_data_width));
+
+end multadd_1;
+
--- /dev/null
+-------------------------------------------------------------------------------
+--
+-- File : multadd_core.vhd
+-- Related files :
+--
+-- Author(s) : stephane Domas (sdomas@univ-fcomte.fr)
+--
+-- Creation Date : 2015/04/27
+--
+-- Description : This component is a multadd
+--
+-- Note : No notes
+--
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity multadd_core is
+ generic (
+ wb_data_width : integer := 16;
+ wb_addr_width : integer := 12
+ );
+ port (
+ -- clk/rst from multadd wrapper
+ rst : in std_logic;
+ clk : in std_logic;
+
+ -- registers r/w via wishbone
+ wb_do_op : in std_logic;
+ wb_c : in std_logic_vector(wb_data_width-1 downto 0);
+ wb_d : out std_logic_vector(2*wb_data_width-1 downto 0);
+
+ -- data ports
+ val1_i : in std_logic_vector(17 downto 0);
+ val2_i : in std_logic_vector(17 downto 0);
+ res_o : out std_logic_vector(35 downto 0)
+ );
+end multadd_core;
+
+
+architecture multadd_core_1 of multadd_core is
+
+ -- Signals
+ signal a_s : signed(17 downto 0);
+ signal b_s : signed(17 downto 0);
+ signal c_s : signed(35 downto 0);
+ signal result : signed(35 downto 0);
+
+begin
+
+ a_s <= signed(val1_i);
+ b_s <= signed(val2_i);
+ c_s <= resize(signed(wb_c),36);
+
+ do_mult_process : process (clk, rst)
+ begin
+ if rst = '1' then
+
+ result <= to_signed(0,36);
+
+ elsif (rising_edge(clk)) then
+
+ if wb_do_op = '1' then
+ result <= a_s * b_s + c_s;
+ end if;
+
+ end if;
+ end process do_mult_process;
+
+ res_o <= std_logic_vector(result);
+ wb_d <= std_logic_vector(resize(result,32);
+
+end multadd_core_1;
+
--- /dev/null
+-------------------------------------------------------------------------------
+--
+-- File : multadd_ctrl.vhd
+-- Related files : multadd.vhd
+--
+-- Author(s) : stephane Domas (sdomas@univ-fcomte.fr)
+--
+-- Creation Date : 2015/04/27
+--
+-- Description : This component is generated automatically.
+-- It contains processes to r/w registers defined for multadd
+-- via wishbone.
+--
+-- Note : No notes
+--
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+-------------------------------------------------------------------------------
+-- wishbone registers
+-------------------------------------------------------------------------------
+-- name bits address R/W
+-- wb_do_op 0 0x0000 W
+-- wb_c (15 downto 0) 0x0001 W
+-- wb_d (15 downto 0) 0x0002 R
+-- wb_d (31 downto 0) 0x0003 R
+--
+-------------------------------------------------------------------------------
+
+entity multadd_ctrl is
+ generic (
+ wb_data_width : integer := 16;
+ wb_addr_width : integer := 2
+ );
+ port (
+ -- clk/rst from interconnector
+ rst : in std_logic;
+ clk : in std_logic;
+
+ -- addr/data from interconnector
+ addr_i : in std_logic_vector(wb_addr_width-1 downto 0);
+ dat_i : in std_logic_vector(wb_data_width-1 downto 0);
+ dat_o : out std_logic_vector(wb_data_width-1 downto 0);
+ cyc_i : in std_logic;
+ stb_i : in std_logic;
+ we_i : in std_logic;
+ ack_o : out std_logic;
+
+ -- registers r/w via wishbone that are forwarded to the block
+ wb_do_op : out std_logic;
+ wb_c : out std_logic_vector(wb_data_width-1 downto 0);
+ wb_d : in std_logic_vector(2*wb_data_width-1 downto 0)
+
+ );
+end multadd_ctrl;
+
+
+architecture multadd_ctrl1 of multadd_ctrl is
+
+ -- signals : registers r/w via wishbone
+ signal wb_do_op_s : std_logic;
+ signal wb_c_s : std_logic_vector(wb_data_width-1 downto 0);
+ signal wb_d_s : std_logic_vector(2*wb_data_width-1 downto 0);
+
+ -- signals : wishbone related
+ signal read_data : std_logic_vector(wb_data_width-1 downto 0);
+ signal read_ack : std_logic;
+ signal write_ack : std_logic;
+ signal write_rise : std_logic;
+
+begin
+-- ----------------------------------------------------------------------------
+-- signals from/to ports
+-- ----------------------------------------------------------------------------
+ wb_d_s <= wb_d;
+ wb_c <= wb_c_s;
+ wb_do_op <= wb_do_op_s;
+
+-- ----------------------------------------------------------------------------
+-- write rising edge detection
+-- ----------------------------------------------------------------------------
+ detection_front : process(gls_clk, gls_reset)
+ variable signal_old : std_logic;
+ begin
+ if (gls_reset = '1') then
+ signal_old := '0';
+ write_rise <= '0';
+ elsif rising_edge(gls_clk) then
+ if (signal_old = '0' and stb_i = '1' and cyc_i = '1' and we_i = '1') then
+ write_rise <= '1';
+ else
+ write_rise <= '0';
+ end if;
+ signal_old := we_i;
+ end if;
+ end process detection_front;
+
+-- ----------------------------------------------------------------------------
+-- Register reading process
+-- ----------------------------------------------------------------------------
+ reading_reg : process(clk, rst)
+ begin
+ if(rst = '1') then
+ read_ack <= '0';
+ read_data <= (others => '0');
+ elsif(rising_edge(clk)) then
+ read_ack <= '0';
+ if (stb_i = '1' and cyc_i = '1' and we_i = '0') then
+ read_ack <= '1';
+ if(addr_i = "10") then
+ read_data <= wb_d_s(15 downto 0);
+ elsif(addr_i = "11") then
+ read_data <= wb_d_s(31 downto 16);
+ else
+ read_data <= (others => '0');
+ end if;
+ end if;
+ end if;
+ end process reading_reg;
+
+-- ----------------------------------------------------------------------------
+-- Register writing process
+-- ----------------------------------------------------------------------------
+ writing_reg : process(clk, rst)
+ begin
+ if(rst = '1') then
+ write_ack <= '0';
+ wb_do_op_s <= '0';
+ wb_c_s <= (others => '0');
+ elsif(rising_edge(clk)) then
+ write_ack <= '0';
+ wb_do_op_s <= '0';
+ if (write_rise = '1') then
+ write_ack <= '1';
+ if (addr_i = "00") then
+ wb_do_op_s <= '1';
+ elsif (addr_i = "01") then
+ wb_c_s <= dat_i;
+ end if;
+ end if;
+ end if;
+ end process writing_reg;
+
+-- ----------------------------------------------------------------------------
+-- assignations for wishbone outputs
+-- ----------------------------------------------------------------------------
+ ack_o <= read_ack or write_ack;
+ dat_o <= read_data when (stb_i = '1' and cyc_i = '1' and we_i = '0') else (others => '0');
+
+end multadd_ctrl1;
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\r
+<block_impl ref_name="multadd.xml" ref_md5="">\r
+ <comments>\r
+ <author firstname="stephane" lastname="Domas" mail="sdomas@univ-fcomte.fr" />\r
+ <date creation="2015/04/27" />\r
+ <related_files list=""/>\r
+ <description>\r
+ This component is a multadd\r
+ </description>\r
+ <notes>\r
+ No notes\r
+ </notes>\r
+ </comments>\r
+\r
+ <libraries>\r
+ <library name="IEEE">\r
+ <package name="std_logic_1164" use="all"/>\r
+ <package name="numeric_std" use="all"/>\r
+ </library>\r
+ </libraries>\r
+\r
+ <architecture>\r
+\r
+ -- Signals\r
+ signal a_s : signed(@eval{@val{in_width}-1} downto 0);\r
+ signal b_s : signed(@eval{@val{in_width}-1} downto 0);\r
+ signal c_s : signed(@eval{2*@val{in_width}-1} downto 0);\r
+ signal result : signed(@eval{2*@val{in_width}-1} downto 0);\r
+\r
+begin\r
+\r
+ a_s <= signed(@{a});\r
+ b_s <= signed(@{b});\r
+ c_s <= resize(signed(@{wb_c}),@eval{2*@val{in_width}});\r
+ \r
+ do_mult_process : process (@{clk}, @{rst})\r
+ begin\r
+ if @{rst} = '1' then\r
+ \r
+ result <= to_signed(0,@eval{2*@val{in_width});\r
+ \r
+ elsif (rising_edge(@{clk})) then\r
+\r
+ if @{wb_do_op} = '1' then\r
+ result <= a_s * b_s + c_s;\r
+ end if;\r
+ \r
+ end if;\r
+ end process do_mult_process;\r
+\r
+ @{d} <= std_logic_vector(result);\r
+ @{wb_d} <= std_logic_vector(resize(result,2*wb_data_width));\r
+ \r
+ </architecture>\r
+\r
+ <patterns>\r
+ <parameters>\r
+ <parameter name="m" value="1" />\r
+ </parameters> \r
+ <delta value="1" />\r
+ </patterns>\r
+ \r
+</block_impl>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block>
+ <informations>
+ <name>
+ wishbone master for apf27
+ </name>
+ <category ids="1,4" />
+ <description>
+ <brief>
+ This block is the wishbone master of the design, connected to the i.MX of APF27
+ </brief>
+ <detailed>
+ This block is the wishbone master of the design, connected to the i.MX of APF27
+ </detailed>
+ </description>
+ </informations>
+
+ <parameters>
+ </parameters>
+
+ <interfaces>
+ <inputs>
+ <input name="clk" type="boolean" width="1" purpose="clock" />
+ <input name="rst" type="boolean" width="1" purpose="reset" />
+
+ <input name="imx_addr" type="expression" width="$wb_addr_width" level="top"/>
+ <input name="imx_cs_n" type="boolean" width="1" level="top"/>
+ <input name="imx_oe_n" type="boolean" width="1" level="top"/>
+ <input name="imx_eb3_n" type="boolean" width="1" level="top"/>
+
+ <input name="ack_i" type="boolean" width="1" purpose="wb" />
+ <input name="dat_i" width="$wb_data_width" purpose="wb" />
+ </inputs>
+ <outputs>
+ <output name="addr_o" type="expression" width="$wb_addr_width" purpose="wb" />
+ <output name="dat_o" type="expression" width="$wb_data_width" purpose="wb" />
+ <output name="cyc_o" type="boolean" width="1" purpose="wb" />
+ <output name="stb_o" type="boolean" width="1" purpose="wb" />
+ <output name="we_o" type="boolean" width="1" purpose="wb" />
+ </outputs>
+ <bidirs>
+ <bidir name="imx_data" width="$wb_data_width" level="top"/>
+ </bidirs>
+ </interfaces>
+
+</block>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\r
+<block>\r
+ <informations>\r
+ <name>\r
+ block demultiplexer\r
+ </name>\r
+ <category ids="1,4" /> \r
+ <description>\r
+ <brief>\r
+ This block demux an entry presented on FPGA pins over a variable number of outputs\r
+ </brief>\r
+ <detailed>\r
+ This block demux an entry presented on FPGA pins over a variable number of outputs\r
+ </detailed> \r
+ </description> \r
+ </informations>\r
+\r
+ <parameters>\r
+ <parameter name="val_width" type="string" value="0" context="user"/>\r
+ <parameter name="sel_width" type="expression" value="$if_nb" iface="val_o" context="port"/>\r
+ </parameters>\r
+\r
+ <interfaces>\r
+ <inputs>\r
+ <input name="clk" type="boolean" width="1" purpose="clock" />\r
+ <input name="rst" type="boolean" width="1" purpose="reset" />\r
+ \r
+ <input name="val_i" type="expression" width="$val_width" level="top"/>\r
+ <input name="sel_i" type="expression" width="$sel_width" />\r
+ </inputs>\r
+ <outputs>\r
+ <output name="val_o" type="expression" width="$val_width" multiplicity="*"/>\r
+ </outputs> \r
+ </interfaces>\r
+\r
+</block>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\r
+<block>\r
+ <informations>\r
+ <name>\r
+ block multiply/add\r
+ </name>\r
+ <category ids="2,5" /> \r
+ <description>\r
+ <brief>\r
+ This block multiplies 2 input values, adding the result to a third one.\r
+ </brief>\r
+ <detailed>\r
+ This block does d=a*b+c.\r
+ a/b are provided by input port.\r
+ c is set via the wishbone interconnector\r
+ d is forwarded to an output port and can be retrieved via the wishbone interconnector\r
+ </detailed> \r
+ </description> \r
+ </informations>\r
+\r
+ <parameters>\r
+ \r
+ <parameter name="wb_c" type="expression" width="$wb_data_width" value="0" context="wb" wishbone="w,data,perm"/>\r
+ <parameter name="wb_d" type="expression" width="2*$wb_data_width" value="0" context="wb" wishbone="r"/>\r
+ <parameter name="wb_do_op" type="boolean" width="1" value="false" context="wb" wishbone="w,true,trigger"/>\r
+ \r
+ <parameter name="in_width" type="string" value="10" context="user"/>\r
+ \r
+ </parameters>\r
+\r
+ <interfaces>\r
+ <inputs>\r
+ <input name="clk" type="boolean" width="1" purpose="clock" />\r
+ <input name="rst" type="boolean" width="1" purpose="reset" />\r
+ <input name="a" type="expression" width="$in_width" />\r
+ <input name="b" type="expression" width="$in_width" />\r
+ \r
+ </inputs>\r
+ <outputs>\r
+ <output name="d" type="expression" width="2*$in_width" />\r
+ </outputs> \r
+ </interfaces>\r
+</block>\r
--- /dev/null
+COMMON-OBJ = $(BUILDPATH)/AbstractBlock.o \
+ $(BUILDPATH)/FunctionalBlock.o \
+ $(BUILDPATH)/ReferenceBlock.o \
+ $(BUILDPATH)/GroupBlock.o \
+ $(BUILDPATH)/AbstractInterface.o \
+ $(BUILDPATH)/ConnectedInterface.o \
+ $(BUILDPATH)/FunctionalInterface.o \
+ $(BUILDPATH)/GroupInterface.o \
+ $(BUILDPATH)/ReferenceInterface.o \
+ $(BUILDPATH)/BlockImplementation.o \
+ $(BUILDPATH)/Graph.o \
+ $(BUILDPATH)/AbstractBoxItem.o \
+ $(BUILDPATH)/BoxItem.o \
+ $(BUILDPATH)/GroupItem.o \
+ $(BUILDPATH)/BlockCategory.o \
+ $(BUILDPATH)/BlockLibraryTree.o \
+ $(BUILDPATH)/BlockLibraryWidget.o \
+ $(BUILDPATH)/moc_BlockLibraryWidget.o \
+ $(BUILDPATH)/BlockParameter.o \
+ $(BUILDPATH)/BlockParameterUser.o \
+ $(BUILDPATH)/BlockParameterGeneric.o \
+ $(BUILDPATH)/BlockParameterPort.o \
+ $(BUILDPATH)/BlockParameterWishbone.o \
+ $(BUILDPATH)/ConnectionItem.o \
+ $(BUILDPATH)/Dispatcher.o \
+ $(BUILDPATH)/Exception.o \
+ $(BUILDPATH)/Graph.o \
+ $(BUILDPATH)/GroupScene.o \
+ $(BUILDPATH)/InterfaceItem.o \
+ $(BUILDPATH)/MainWindow.o \
+ $(BUILDPATH)/moc_MainWindow.o \
+ $(BUILDPATH)/ArithmeticEvaluator.o \
+ $(BUILDPATH)/moc_ArithmeticEvaluator.o \
+ $(BUILDPATH)/BlockWidget.o \
+ $(BUILDPATH)/moc_BlockWidget.o \
+ $(BUILDPATH)/GroupWidget.o \
+ $(BUILDPATH)/moc_GroupWidget.o \
+ $(BUILDPATH)/Parameters.o \
+ $(BUILDPATH)/moc_Parameters.o \
+ $(BUILDPATH)/rcc_blast.o \
+ $(BUILDPATH)/BlocksToConfigureWidget.o \
+ $(BUILDPATH)/moc_BlocksToConfigureWidget.o \
+ $(BUILDPATH)/ParametersWindow.o \
+ $(BUILDPATH)/moc_ParametersWindow.o \
+ $(BUILDPATH)/InterfacePropertiesWindow.o \
+ $(BUILDPATH)/moc_InterfacePropertiesWindow.o \
+ $(BUILDPATH)/blast.o
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+
+ <!-- déclaration des groupes d'attributs -->
+
+ <xs:attributeGroup name="group_itemAttrGroup">
+ <xs:attribute ref="id"/>
+ <xs:attribute ref="name"/>
+ <xs:attribute ref="upper_group"/>
+ <xs:attribute ref="upper_item"/>
+ <xs:attribute ref="position"/>
+ <xs:attribute ref="dimension"/>
+ </xs:attributeGroup>
+
+ <xs:attributeGroup name="group_ifaceAttrGroup">
+ <xs:attribute ref="id"/>
+ <xs:attribute ref="name"/>
+ <xs:attribute ref="level"/>
+ <xs:attribute ref="direction"/>
+ <xs:attribute ref="orientation"/>
+ <xs:attribute ref="position"/>
+ </xs:attributeGroup>
+
+ <xs:attributeGroup name="block_itemsAttrGroup">
+ <xs:attribute ref="functional_count" />
+ <xs:attribute ref="group_count" />
+ </xs:attributeGroup>
+
+ <xs:attributeGroup name="bi_functionalAttrGroup">
+ <xs:attribute ref="id" />
+ <xs:attribute ref="ref_xml" />
+ <xs:attribute ref="ref_md5" />
+ <xs:attribute ref="name" />
+ <xs:attribute ref="position" />
+ <xs:attribute ref="dimension" />
+ </xs:attributeGroup>
+
+ <xs:attributeGroup name="bif_parameterAttrGroup">
+ <xs:attribute ref="name" />
+ <xs:attribute ref="value" />
+ <xs:attribute ref="context" />
+ <xs:attribute ref="type" />
+
+ </xs:attributeGroup>
+
+ <xs:attributeGroup name="bif_ifaceAttrGroup">
+ <xs:attribute ref="id" />
+ <xs:attribute ref="name" />
+ <xs:attribute ref="ref_name" />
+ <xs:attribute ref="orientation" />
+ <xs:attribute ref="position" />
+ </xs:attributeGroup>
+
+ <xs:attributeGroup name="bi_groupAttrGroup">
+ <xs:attribute ref="id" />
+ <xs:attribute ref="inside_group" />
+ <xs:attribute ref="position" />
+ <xs:attribute ref="dimension" />
+ </xs:attributeGroup>
+
+ <xs:attributeGroup name="big_ifaceAttrGroup">
+ <xs:attribute ref="id" />
+ <xs:attribute ref="ref_name" />
+ <xs:attribute ref="orientation" />
+ <xs:attribute ref="position" />
+ </xs:attributeGroup>
+
+ <xs:attributeGroup name="connectionAttrGroup">
+ <xs:attribute ref="from" />
+ <xs:attribute ref="to" />
+ </xs:attributeGroup>
+
+
+ <!-- déclaration des attributs -->
+
+ <xs:attribute name="count">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="id">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="upper_group">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer">
+ <xs:minInclusive value="-1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="upper_item">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer">
+ <xs:minInclusive value="-1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="inside_group">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="functional_count">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="group_count">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="value">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="from">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="to">
+ <xs:simpleType>
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:minInclusive value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="position" type="xs:string"/>
+ <xs:attribute name="dimension" type="xs:string"/>
+ <xs:attribute name="level" type="xs:string"/>
+ <xs:attribute name="direction" type="xs:string"/>
+ <xs:attribute name="orientation" type="xs:string"/>
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="ref_name" type="xs:string"/>
+ <xs:attribute name="ref_xml" type="xs:string"/>
+ <xs:attribute name="ref_md5" type="xs:string"/>
+ <xs:attribute name="context" type="xs:string"/>
+ <xs:attribute name="type" type="xs:string"/>
+
+
+ <!-- déclaration des groupes d'éléments -->
+
+ <xs:group name="rootElmtGroup">
+ <xs:sequence>
+ <xs:element ref="scenes"/>
+ <xs:element ref="connections"/>
+ </xs:sequence>
+ </xs:group>
+
+ <xs:group name="sceneElmtGroup">
+ <xs:sequence>
+ <xs:element ref="group_item"/>
+ <xs:element ref="block_items"/>
+ </xs:sequence>
+ </xs:group>
+
+ <xs:group name="block_itemsElmtGroup">
+ <xs:sequence>
+ <xs:element ref="bi_functional" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element ref="bi_group" minOccurs="0"/>
+ </xs:sequence>
+ </xs:group>
+
+ <xs:group name="bi_functionalElmtGroup">
+ <xs:sequence>
+ <xs:element ref="bif_parameters"/>
+ <xs:element ref="bif_ifaces"/>
+ </xs:sequence>
+ </xs:group>
+
+
+ <!-- déclaration des éléments -->
+
+ <xs:element name="scenes">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="scene" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute ref="count"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="scene">
+ <xs:complexType>
+ <xs:group ref="sceneElmtGroup"/>
+ <xs:attribute ref="id"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="group_item">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="group_ifaces" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attributeGroup ref="group_itemAttrGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="group_ifaces">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="group_iface" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute ref="count"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="group_iface">
+ <xs:complexType>
+ <xs:attributeGroup ref="group_ifaceAttrGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="block_items">
+ <xs:complexType>
+ <xs:group ref="block_itemsElmtGroup"/>
+ <xs:attributeGroup ref="block_itemsAttrGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="bi_functional">
+ <xs:complexType>
+ <xs:group ref="bi_functionalElmtGroup"/>
+ <xs:attributeGroup ref="bi_functionalAttrGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="bif_parameters">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="bif_parameter" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="bif_parameter">
+ <xs:complexType>
+ <xs:attributeGroup ref="bif_parameterAttrGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="bif_ifaces">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="bif_iface" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute ref="count"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="bif_iface">
+ <xs:complexType>
+ <xs:attributeGroup ref="bif_ifaceAttrGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="bi_group">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="big_ifaces"/>
+ </xs:sequence>
+ <xs:attributeGroup ref="bi_groupAttrGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="big_ifaces">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="big_iface" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute ref="count" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="big_iface">
+ <xs:complexType>
+ <xs:attributeGroup ref="big_ifaceAttrGroup" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="connections">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="connection" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute ref="count" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="connection">
+ <xs:complexType>
+ <xs:attributeGroup ref="connectionAttrGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+ <!-- racine du document -->
+
+ <xs:element name="blast_project">
+ <xs:complexType>
+ <xs:group ref="rootElmtGroup"/>
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<blast_project>
+ <scenes count="1">
+ <scene id="0">
+ <group_item id="1" upper_group="-1" upper_item="-1" name="top group" position="-35,-35" dimension="245,195">
+ <group_ifaces count="0"/>
+ </group_item>
+ <block_items functional_count="1" group_count="0">
+ <bi_functional id="2" ref_xml="/home/ecollot/BLAST/block-1I1O.xml" ref_md5="ed0f80f406ce40c7e33ed205c8cf6002" name="block-1I1O" position="0,0" dimension="175,125">
+ <bif_parameters>
+ <bif_parameter name="data_width" value="8" context="user" type="string"/>
+ </bif_parameters>
+ <bif_ifaces count="4">
+ <bif_iface id="0" name="clk" ref_name="clk" orientation="west" position="0"/>
+ <bif_iface id="1" name="rst" ref_name="rst" orientation="west" position="0"/>
+ <bif_iface id="2" name="data_i" ref_name="data_i" orientation="west" position="0.5"/>
+ <bif_iface id="3" name="data_o" ref_name="data_o" orientation="east" position="0.5"/>
+ </bif_ifaces>
+ </bi_functional>
+ </block_items>
+ </scene>
+ </scenes>
+ <connections/>
+</blast_project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<blast_project>
+ <scenes count="3">
+ <scene id="0" upper_scene="-1">
+ <group_item id="2" upper_item="-1" name="top group" position="-61,-306" dimension="750,483">
+ <group_ifaces count="0"/>
+ </group_item>
+ <block_items functional_count="3" group_count="1">
+ <bi_functional id="3" ref_xml="/home/ecollot/BLAST/block-1I1O.xml" ref_md5="ed0f80f406ce40c7e33ed205c8cf6002" name="block-1I1O" position="221,-271" dimension="175,125">
+ <bif_parameters>
+ <bif_parameter name="data_width" value="8" context="user" type="string"/>
+ </bif_parameters>
+ <bif_ifaces count="4">
+ <bif_iface id="0" name="clk" ref_name="clk" orientation="west" position="0"/>
+ <bif_iface id="1" name="rst" ref_name="rst" orientation="west" position="0"/>
+ <bif_iface id="2" name="data_i" ref_name="data_i" orientation="west" position="0.5"/>
+ <bif_iface id="3" name="data_o" ref_name="data_o" orientation="east" position="0.5"/>
+ </bif_ifaces>
+ </bi_functional>
+ <bi_functional id="4" ref_xml="/home/ecollot/BLAST/block-2I2O.xml" ref_md5="96de345f776f4fabd53b74fc7625e694" name="block-2I2O" position="313,17" dimension="175,125">
+ <bif_parameters>
+ <bif_parameter name="data_width" value="8" context="user" type="string"/>
+ </bif_parameters>
+ <bif_ifaces count="6">
+ <bif_iface id="4" name="clk" ref_name="clk" orientation="west" position="0"/>
+ <bif_iface id="5" name="rst" ref_name="rst" orientation="west" position="0"/>
+ <bif_iface id="6" name="data1_i" ref_name="data1_i" orientation="west" position="0.333333"/>
+ <bif_iface id="7" name="data2_i" ref_name="data2_i" orientation="west" position="0.666667"/>
+ <bif_iface id="8" name="data1_o" ref_name="data1_o" orientation="east" position="0.333333"/>
+ <bif_iface id="9" name="data2_o" ref_name="data2_o" orientation="east" position="0.666667"/>
+ </bif_ifaces>
+ </bi_functional>
+ <bi_functional id="5" ref_xml="/home/ecollot/BLAST/block-1I1O.xml" ref_md5="ed0f80f406ce40c7e33ed205c8cf6002" name="block-1I1O" position="-26,-71" dimension="175,125">
+ <bif_parameters>
+ <bif_parameter name="data_width" value="8" context="user" type="string"/>
+ </bif_parameters>
+ <bif_ifaces count="4">
+ <bif_iface id="10" name="clk" ref_name="clk" orientation="west" position="0"/>
+ <bif_iface id="11" name="rst" ref_name="rst" orientation="west" position="0"/>
+ <bif_iface id="12" name="data_i" ref_name="data_i" orientation="west" position="0.5"/>
+ <bif_iface id="13" name="data_o" ref_name="data_o" orientation="east" position="0.5"/>
+ </bif_ifaces>
+ </bi_functional>
+ <bi_group id="6" inside_group="7" position="479,-180" dimension="175,125">
+ <big_ifaces count="0"/>
+ </bi_group>
+ </block_items>
+ </scene>
+ <scene id="1" upper_scene="0">
+ <group_item id="7" upper_item="6" name="sub_group_2" position="-35,-35" dimension="245,195">
+ <group_ifaces count="0"/>
+ </group_item>
+ <block_items functional_count="0" group_count="1">
+ <bi_group id="8" inside_group="9" position="0,0" dimension="175,125">
+ <big_ifaces count="0"/>
+ </bi_group>
+ </block_items>
+ </scene>
+ <scene id="2" upper_scene="1">
+ <group_item id="9" upper_item="8" name="sub_group_3" position="0,0" dimension="150,150">
+ <group_ifaces count="0"/>
+ </group_item>
+ <block_items functional_count="0" group_count="0"/>
+ </scene>
+ </scenes>
+ <connections>
+ <connection from="13" to="2"/>
+ </connections>
+</blast_project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\r
+<blast_project>\r
+ <scenes count="2">\r
+ \r
+ <scene id="0">\r
+ \r
+ <group_item id="1" name="top" upper_group="-1" upper_item="-1" position="20,30" dimension="800,600">\r
+ <group_ifaces count="4">\r
+ <group_iface id="1" name="in_1" level="top" direction="input" orientation="west" position="0.3" />\r
+ <group_iface id="2" name="in_2" level="top" direction="input" orientation="west" position="0.6" />\r
+ <group_iface id="3" name="out_1" level="top" direction="output" orientation="south" position="0.5" />\r
+ <group_iface id="4" name="out_2" level="top" direction="output" orientation="east" position="0.5" />\r
+ </group_ifaces>\r
+ </group_item>\r
+ \r
+ <block_items functional_count="1" group_count="1">\r
+ \r
+ <bi_functional id="2" ref_xml="block-1I1O.xml" ref_md5="" name="block-1I1O_1" position="120,130" dimension="200,200">\r
+ <bif_parameters>\r
+ <bif_parameter name="data_width" value="8" />\r
+ </bif_parameters>\r
+ <bif_ifaces count="2">\r
+ <bif_iface id="5" name="in_1" ref_name="data_i" orientation="west" position="0.5" />\r
+ <bif_iface id="6" name="out_1" ref_name="data_o" orientation="east" position="0.5" />\r
+ </bif_ifaces>\r
+ </bi_functional>\r
+\r
+ <bi_group id="3" inside_group="4" position="160,150" dimension="200,200">\r
+ <big_ifaces count="4">\r
+ <big_iface id="7" ref_name="in_1" orientation="west" position="0.3" />\r
+ <big_iface id="8" ref_name="in_2" orientation="west" position="0.6" />\r
+ <big_iface id="9" ref_name="out_1" orientation="east" position="0.3" />\r
+ <big_iface id="10" ref_name="out_2" orientation="east" position="0.6" />\r
+ </big_ifaces>\r
+ </bi_group>\r
+ \r
+ </block_items>\r
+\r
+ </scene>\r
+\r
+ <scene id="1">\r
+ \r
+ <group_item id="4" upper_group="1" upper_item="3" name="subgroup_1" position="20,30" dimension="400,400">\r
+ <group_ifaces count="4">\r
+ <group_iface id="11" name="in_1" level="basic" direction="input" orientation="west" position="0.3" />\r
+ <group_iface id="12" name="in_2" level="basic" direction="input" orientation="west" position="0.6" />\r
+ <group_iface id="13" name="out_1" level="basic" direction="output" orientation="east" position="0.3" />\r
+ <group_iface id="14" name="out_2" level="basic" direction="output" orientation="east" position="0.6" />\r
+ </group_ifaces>\r
+ </group_item>\r
+ \r
+ <block_items functional_count="1" group_count="0">\r
+\r
+ <bi_functional id="5" ref_xml="block-2INO.xml" ref_md5="" name="block-2INO_1" position="120,130" dimension="200,200">\r
+ <bif_parameters>\r
+ <bif_parameter name="data_width" value="8" />\r
+ </bif_parameters>\r
+ <bif_ifaces count="4">\r
+ <bif_iface id="15" name="in_1" refname="data1_i" orientation="west" position="0.3" />\r
+ <bif_iface id="16" name="in_2" refname="data2_i" orientation="west" position="0.6" />\r
+ <bif_iface id="17" name="out_1" refname="data_o" orientation="east" position="0.3" />\r
+ <bif_iface id="18" name="out_2" refname="data_o" orientation="east" position="0.6" />\r
+ </bif_ifaces>\r
+ </bi_functional>\r
+\r
+ </block_items>\r
+\r
+ </scene>\r
+\r
+ </scenes> \r
+\r
+ <connections>\r
+ <connection from="1" to="5" />\r
+ <connection from="2" to="8" />\r
+ <connection from="3" to="10" />\r
+ <connection from="4" to="9" />\r
+ <connection from="6" to="7" />\r
+ <connection from="11" to="15" />\r
+ <connection from="12" to="16" />\r
+ <connection from="13" to="17" />\r
+ <connection from="14" to="18" /> \r
+ </connections>\r
+\r
+</blast_project>\r