From 0d3590739ff5a4ca9e87c052ac142f5d1d3a68ab Mon Sep 17 00:00:00 2001 From: stephane Domas Date: Tue, 9 May 2017 19:55:28 +0200 Subject: [PATCH] added source items --- AbstractBlock.cpp | 10 + AbstractBlock.h | 3 +- AbstractBoxItem.cpp | 7 +- AbstractBoxItem.h | 9 +- BoxItem.cpp | 39 +- BoxItem.h | 6 +- Dispatcher.cpp | 303 ++++++++++---- Dispatcher.h | 38 +- Graph.cpp | 82 +++- Graph.h | 31 +- GroupBlock.cpp | 10 + GroupBlock.h | 2 + GroupItem.cpp | 21 +- GroupItem.h | 2 +- GroupScene.cpp | 96 +++-- GroupScene.h | 41 +- GroupWidget.cpp | 16 +- InterfaceItem.cpp | 11 +- Parameters.cpp | 23 +- SourceItem.cpp | 737 ++++++++++++++++++++++++++++++++++ SourceItem.h | 62 +++ blast.creator.user | 8 +- blast.files | 2 + blastconfig.xml | 4 +- lib/references/references.bmf | Bin 6608 -> 7216 bytes object-files.txt | 3 +- 26 files changed, 1358 insertions(+), 208 deletions(-) create mode 100644 SourceItem.cpp create mode 100644 SourceItem.h diff --git a/AbstractBlock.cpp b/AbstractBlock.cpp index d316800..ba1c179 100644 --- a/AbstractBlock.cpp +++ b/AbstractBlock.cpp @@ -119,6 +119,16 @@ QList AbstractBlock::getInterfaces() { return list; } +QList AbstractBlock::getDataInputs() { + QList list; + foreach(AbstractInterface* iface, inputs) { + if (iface->getPurpose() == AbstractInterface::Data) { + list.append(iface); + } + } + return list; +} + AbstractInterface* AbstractBlock::getIfaceFromName(QString name) { foreach(AbstractInterface* iface, inputs) { diff --git a/AbstractBlock.h b/AbstractBlock.h index acdc1c8..28e8b7a 100644 --- a/AbstractBlock.h +++ b/AbstractBlock.h @@ -54,7 +54,8 @@ public: void removeAllInterfaces(); void defineBlockParam(BlockParameter *param); - QList getInterfaces(); + QList getInterfaces(); //! return all interfaces + QList getDataInputs(); //! return all inputs of type data AbstractInterface* getIfaceFromName(QString name); BlockParameter* getParameterFromName(QString name); diff --git a/AbstractBoxItem.cpp b/AbstractBoxItem.cpp index b76bf66..8ef607a 100644 --- a/AbstractBoxItem.cpp +++ b/AbstractBoxItem.cpp @@ -20,7 +20,7 @@ AbstractBoxItem:: AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispat QFontMetrics fmId(params->defaultBlockFont); nameWidth = fmId.width(refBlock->getName()); nameHeight = fmId.height(); - nameMargin = 10; + nameMargin = 5; ifaceMargin = 10; // the six following values will be override in subclass constructors @@ -86,6 +86,11 @@ bool AbstractBoxItem::isBoxItem() { bool AbstractBoxItem::isGroupItem() { return false; } + +bool AbstractBoxItem::isSourceItem() { + return false; +} + void AbstractBoxItem::setRstClkVisible(bool b) { rstClkVisible = b; foreach(InterfaceItem* ifaceItem, interfaces) { diff --git a/AbstractBoxItem.h b/AbstractBoxItem.h index ed3e1ee..132adc9 100644 --- a/AbstractBoxItem.h +++ b/AbstractBoxItem.h @@ -51,7 +51,8 @@ public: // testers virtual bool isBoxItem(); - virtual bool isGroupItem(); + virtual bool isGroupItem(); + virtual bool isSourceItem(); inline bool isSelected() { return selected; } inline bool isRstClkVisible(){ return rstClkVisible;} inline bool isWishboneVisible(){ return wishboneVisible;} @@ -59,7 +60,7 @@ public: // others - virtual void interfaceRenamed() = 0; + virtual void nameChanged() = 0; // called when an interface or box name have changed void addInterface(InterfaceItem* i, bool resetPosition = false); void removeInterface(InterfaceItem* i); void resetInterfacesPosition(); @@ -116,13 +117,13 @@ protected: 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 + QPointF originPoint; // the left-top point that is the origin of the bounding box, in the item coordinates bool selected; bool rstClkVisible; //! true if clock/reset interfaces are visible bool wishboneVisible; //! true if wishbone interfaces are visible - QPointF currentPosition; // the start point for resize + QPointF currentPosition; // the start point for resize, i.e. the position of the lef-top corner of the box, in the scene coordinates virtual void updateMinimumSize() = 0; // modify the minimum size virtual bool updateGeometry(ChangeType type) = 0; // modify the originPoint and the total dimension diff --git a/BoxItem.cpp b/BoxItem.cpp index a107198..6e6f15a 100644 --- a/BoxItem.cpp +++ b/BoxItem.cpp @@ -207,11 +207,18 @@ bool BoxItem::updateGeometry(ChangeType type) { return false; } -void BoxItem::interfaceRenamed() { +void BoxItem::nameChanged() { + + QFontMetrics fmId(params->defaultBlockFont); + nameWidth = fmId.width(refBlock->getName()); + nameHeight = fmId.height(); + if (updateGeometry(InterfaceMove)) { //cout << "must recompute group item geometry" << endl; (getScene()->getGroupItem())->updateShape(); - } + } + // force the update in case of size has not changed + update(); } void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { @@ -387,7 +394,7 @@ void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { else if (params->editState == Parameters::EditCloseConnection) { InterfaceItem* iface1 = getScene()->getSelectedInterface(1); InterfaceItem* iface2 = getScene()->getSelectedInterface(2); - bool ok = dispatcher->connect(iface1,iface2); + bool ok = dispatcher->createConnectionItem(iface1,iface2); if (ok) { iface1->selected = false; // no update needed since the whole scene will be repainted @@ -482,6 +489,8 @@ void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) { void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { + event->accept(); + QMenu menu; QAction* titleAction = NULL; QAction* removeAction = NULL; @@ -587,17 +596,24 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { dispatcher->removeFunctionalInterface(ifaceItem); } else { - dispatcher->removeBlock(this); + dispatcher->removeBoxItem(this); } } else if (selectedAction == duplicateAction) { - dispatcher->duplicateBlock(this); + dispatcher->duplicateBoxItem(this); } else if(selectedAction == renameAction){ - if(ifaceItem != NULL) + if(ifaceItem != NULL) { dispatcher->renameInterface(ifaceItem); - else - dispatcher->renameBlockOrGroup(this); + } + else { + if (refBlock->isFunctionalBlock()) { + dispatcher->renameFunctionalBlock(this); + } + else if (refBlock->isGroupBlock()) { + dispatcher->renameGroupBlock(childGroupItem); + } + } } else if(selectedAction == showProperties){ dispatcher->showProperties(ifaceItem); @@ -609,7 +625,7 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { dispatcher->disconnectInterFromGroup(ifaceItem); } else if (selectedAction == cloneInterface){ - dispatcher->duplicateInterface(ifaceItem); + dispatcher->duplicateInterfaceItem(ifaceItem); } else if (selectedAction == openWindow){ dispatcher->showRaiseWindow(this); @@ -622,8 +638,9 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { } else if(selectedAction == showParameters){ new ParametersWindow(refBlock, params, NULL); - } + } } + void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) { bool ok = false; @@ -676,7 +693,7 @@ void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) { } GroupBlock* parentGroupBlock = AB_TO_GRP(((GroupItem *)parentItem())->getRefBlock()); - FunctionalBlock* functionalBlock = params->getGraph()->addFunctionalBlock(parentGroupBlock, reference); + FunctionalBlock* functionalBlock = params->getGraph()->createFunctionalBlock(parentGroupBlock, reference); /* NB: addFunctionalBlock creates all interfaces from the reference, which is annoying when reading bif_iface tags. Thus interface are all removed. */ diff --git a/BoxItem.h b/BoxItem.h index a80f9f0..c8a942e 100644 --- a/BoxItem.h +++ b/BoxItem.h @@ -46,7 +46,7 @@ public: bool isBoxItem(); // others - void interfaceRenamed(); + void nameChanged(); void moveTo(QPointF dest); void loadFunctional(QDomElement funcElement) throw(Exception); void save(QXmlStreamWriter& writer); @@ -77,9 +77,11 @@ private: friend QDataStream &operator<<(QDataStream &out, BoxItem &b); friend QDataStream &operator>>(QDataStream &in, BoxItem &b); +/* signals: void itemMustBeDeleted(QGraphicsItem*); - +*/ + }; QDataStream & operator <<(QDataStream &out, BoxItem &b); diff --git a/Dispatcher.cpp b/Dispatcher.cpp index ac0862c..bbbb945 100644 --- a/Dispatcher.cpp +++ b/Dispatcher.cpp @@ -16,6 +16,7 @@ #include "GroupScene.h" #include "GroupItem.h" #include "BoxItem.h" +#include "SourceItem.h" #include "InterfaceItem.h" #include "ConnectionItem.h" @@ -80,7 +81,7 @@ void Dispatcher::closeCurrentProject() { sceneCounter = 0; } -bool Dispatcher::connect(InterfaceItem *iface1, InterfaceItem *iface2) { +bool Dispatcher::createConnectionItem(InterfaceItem *iface1, InterfaceItem *iface2) { ConnectedInterface* ref1 = iface1->refInter; ConnectedInterface* ref2 = iface2->refInter; @@ -108,33 +109,12 @@ bool Dispatcher::connect(InterfaceItem *iface1, InterfaceItem *iface2) { return false; } -void Dispatcher::checkSelection(){ - InterfaceItem *iface1 = NULL; - InterfaceItem *iface2 = NULL; - - GroupScene *scene = params->getCurrentScene(); - QList 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()) { + foreach(BoxItem* block, scene->getBoxItems()) { block->setSelected(false); block->setCurrentInterface(NULL); } @@ -184,50 +164,143 @@ void Dispatcher::changeConnectionMode(int mode){ */ } -void Dispatcher::renameBlockOrGroup(AbstractBoxItem *item){ - static QString fctName = "Dispatcher::renameBlockOrGroup()"; +void Dispatcher::renameFunctionalBlock(BoxItem *item){ + static QString fctName = "Dispatcher::renameFunctionalBlock()"; #ifdef DEBUG_FCTNAME cout << "call to " << qPrintable(fctName) << endl; #endif - - bool ok; - QString text = QInputDialog::getText(NULL, "Rename an block/group", + + GroupWidget* win = item->getScene()->getGroupWidget(); + + bool ok = false; + QString text = ""; + while (!ok) { + text = QInputDialog::getText(win, "Rename a functional block", "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); - } + if (!ok) return; + + if (text == item->getRefBlock()->getName()) return; + + if( (text.isEmpty()) || (text.length() > 30)) { + QMessageBox::warning(win,"Error in given name", + "the block name must be shorter than 30 characters, cannot be empty", + QMessageBox::Ok); + ok = false; + } + else { + FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent())); + if (block != NULL) { + QMessageBox::warning(win,"Error in given name", + "the name provided is similar to that of another functional block within the group", + QMessageBox::Ok); + ok = false; } + } + } + + item->getRefBlock()->setName(text); + item->nameChanged(); +} - mainWindow->getLibrary()->updateComboScene(); +void Dispatcher::renameGroupBlock(GroupItem *item){ + static QString fctName = "Dispatcher::renameGroupBlock()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + GroupWidget* win = item->getScene()->getGroupWidget(); + + bool ok = false; + QString text = ""; + while (!ok) { + text = QInputDialog::getText(win, "Rename a group", + "New name:", QLineEdit::Normal, + item->getRefBlock()->getName(), &ok); + if (!ok) return; + + if (text == item->getRefBlock()->getName()) return; + + if( (text.isEmpty()) || (text.length() > 30)) { + QMessageBox::warning(win,"Error in given name", + "the block name must be shorter than 30 characters, cannot be empty", + QMessageBox::Ok); + ok = false; } else { - QMessageBox::warning(NULL,"Error in given name", - "the element name must be shorter than 30 characters and can't be empty!", + GroupBlock* block = params->getGraph()->getGroupBlockByName(text); + if (block != NULL) { + QMessageBox::warning(win,"Error in given name", + "the name provided is similar to that of another group", + QMessageBox::Ok); + ok = false; + } + } + } + + item->getRefBlock()->setName(text); + if(item->getScene()->getGroupWidget()->isTopGroup()) { + mainWindow->setWindowTitle("blast - "+text); + } + else { + item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text); + } + item->nameChanged(); + mainWindow->getLibrary()->updateComboScene(); +} + +void Dispatcher::renameSourceBlock(SourceItem *item){ + static QString fctName = "Dispatcher::renameSourceBlock()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + GroupWidget* win = item->getScene()->getGroupWidget(); + + bool ok = false; + QString text = ""; + while (!ok) { + text = QInputDialog::getText(win, "Rename a source", + "New name:", QLineEdit::Normal, + item->getRefBlock()->getName(), &ok); + if (!ok) return; + + if (text == item->getRefBlock()->getName()) return; + + if( (text.isEmpty()) || (text.length() > 30)) { + QMessageBox::warning(win,"Error in given name", + "the block name must be shorter than 30 characters, cannot be empty", QMessageBox::Ok); - renameBlockOrGroup(item); + ok = false; } - } + else { + FunctionalBlock* block = params->getGraph()->getSourceBlockByName(text); + if (block != NULL) { + QMessageBox::warning(win,"Error in given name", + "the name provided is similar to that of another source block within the top group", + QMessageBox::Ok); + ok = false; + } + } + } + + item->getRefBlock()->setName(text); + item->nameChanged(); } + void Dispatcher::renameInterface(InterfaceItem *item) { static QString fctName = "Dispatcher::renameInterface()"; #ifdef DEBUG_FCTNAME cout << "call to " << qPrintable(fctName) << endl; #endif + GroupWidget* win = item->getOwner()->getScene()->getGroupWidget(); + bool ok = false; QString text = ""; while (!ok) { - text = QInputDialog::getText(NULL, "Rename an interface", + text = QInputDialog::getText(win, "Rename an interface", "New name:", QLineEdit::Normal, item->refInter->getName(), &ok); @@ -236,7 +309,7 @@ void Dispatcher::renameInterface(InterfaceItem *item) { if (text == item->refInter->getName()) return; if( (text.isEmpty()) || (text.length() > 30)) { - QMessageBox::warning(NULL,"Error in given name", + QMessageBox::warning(win,"Error in given name", "the interface name must be shorter than 30 characters, cannot be empty", QMessageBox::Ok); ok = false; @@ -244,7 +317,7 @@ void Dispatcher::renameInterface(InterfaceItem *item) { else { AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text); if (iface != NULL) { - QMessageBox::warning(NULL,"Error in given name", + QMessageBox::warning(win,"Error in given name", "the name provided is similar to that of another interface", QMessageBox::Ok); ok = false; @@ -257,11 +330,34 @@ void Dispatcher::renameInterface(InterfaceItem *item) { assoIface->setName(text+"_ctl"); } item->updateName(text); - item->getOwner()->interfaceRenamed(); + item->getOwner()->nameChanged(); +} + +void Dispatcher::duplicateBoxItem(BoxItem *item){ + static QString fctName = "Dispatcher::duplicateBoxItem()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + GroupScene *scene = item->getScene(); + AbstractBlock* block = item->getRefBlock(); + AbstractBlock *newBlock; + + // only duplicate functional blocks + if(block->isFunctionalBlock()) { + + // adding to the model + FunctionalBlock* funBlock = (FunctionalBlock*)block; + newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock); + // adding to the view + scene->createBoxItem(newBlock); + + params->unsaveModif = true; + } } -void Dispatcher::duplicateBlock(BoxItem *item){ - static QString fctName = "Dispatcher::duplicateBlock()"; +void Dispatcher::duplicateSourceItem(SourceItem *item) { + static QString fctName = "Dispatcher::duplicateSourceItem()"; #ifdef DEBUG_FCTNAME cout << "call to " << qPrintable(fctName) << endl; #endif @@ -275,16 +371,16 @@ void Dispatcher::duplicateBlock(BoxItem *item){ // adding to the model FunctionalBlock* funBlock = (FunctionalBlock*)block; - newBlock = params->duplicateFunctionalBlock(funBlock); + newBlock = params->getGraph()->duplicateSourceBlock(funBlock); // adding to the view - scene->createBlockItem(newBlock); + scene->createSourceItem(newBlock); params->unsaveModif = true; } } -void Dispatcher::duplicateInterface(InterfaceItem *item) { - static QString fctName = "Dispatcher::duplicateInterface()"; +void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) { + static QString fctName = "Dispatcher::duplicateInterfaceItem()"; #ifdef DEBUG_FCTNAME cout << "call to " << qPrintable(fctName) << endl; #endif @@ -324,12 +420,25 @@ void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) { #ifdef DEBUG_FCTNAME cout << "call to " << qPrintable(fctName) << endl; #endif - - GroupScene *scene = searchSceneById(idScene); + bool newSource = false; + GroupScene *scene = getSceneById(idScene); ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock); - GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock()); - FunctionalBlock* newOne = params->getGraph()->addFunctionalBlock(group, ref); - scene->createBlockItem(newOne); + // if block has no inputs, propose to add it as a source to top scene + if ((scene->isTopScene()) && (ref->getDataInputs().isEmpty())) { + int ret = QMessageBox::question(NULL,"Adding a block to top scene","Selected block may be used as a source for the top scene. Do you want to add it as a source ?"); + if (ret == QMessageBox::Yes) { + newSource = true; + } + } + if (newSource) { + FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref); + scene->createSourceItem(newOne); + } + else { + GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock()); + FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref); + scene->createBoxItem(newOne); + } params->unsaveModif = true; } @@ -377,10 +486,10 @@ GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) { // getting the parent block in the graph GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock()); cout << "new group : parent = "<< qPrintable(parent->getName()) << endl; - GroupBlock* groupBlock = params->getGraph()->createChildBlock(parent); + GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent); cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl; // creating the BlockItem in the scene - BoxItem* newItem = scene->createBlockItem(groupBlock); + BoxItem* newItem = scene->createBoxItem(groupBlock); params->unsaveModif = true; @@ -437,8 +546,10 @@ void Dispatcher::destroyScene(GroupScene *scene) { } if (scene->getNbChildScene() == 0) { - // remove scene from the parent list - scene->getParentScene()->removeChildScene(scene); + // remove scene from the parent list, if possible + if (scene->getParentScene() != NULL) { + scene->getParentScene()->removeChildScene(scene); + } // destroy the GroupWidget groupList.removeAll(scene->getGroupWidget()); scene->getGroupWidget()->deleteLater(); @@ -651,8 +762,8 @@ void Dispatcher::addNewFullGroup() { #endif } -void Dispatcher::removeBlock(BoxItem *item) { - static QString fctName = "Dispatcher::removeBlock()"; +void Dispatcher::removeBoxItem(BoxItem *item) { + static QString fctName = "Dispatcher::removeBoxItem()"; #ifdef DEBUG_FCTNAME cout << "call to " << qPrintable(fctName) << endl; #endif @@ -707,8 +818,8 @@ void Dispatcher::removeBlock(BoxItem *item) { if (item->getRefBlock()->isFunctionalBlock()) { FunctionalBlock* block = AB_TO_FUN(item->getRefBlock()); GroupBlock* group = AB_TO_GRP(block->getParent()); - item->getScene()->removeBlockItem(item); - params->getGraph()->removeFunctionalBlock(block,group); + item->getScene()->removeBoxItem(item); + params->getGraph()->removeFunctionalBlock(block); } else if (item->getRefBlock()->isGroupBlock()) { @@ -718,13 +829,13 @@ void Dispatcher::removeBlock(BoxItem *item) { GroupItem* subgroup = item->getChildGroupItem(); destroyScene(subgroup->getScene()); // remove the BoxItem - item->getScene()->removeBlockItem(item); + item->getScene()->removeBoxItem(item); // remove the group from the graph params->getGraph()->removeGroupBlock(group); } } -void Dispatcher::removeAllBlockConnections(BoxItem *item) { +void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) { static QString fctName = "Dispatcher::removeAllBlockConnection()"; #ifdef DEBUG_FCTNAME cout << "call to " << qPrintable(fctName) << endl; @@ -737,6 +848,29 @@ void Dispatcher::removeAllBlockConnections(BoxItem *item) { } } +void Dispatcher::removeSourceItem(SourceItem *item) { + static QString fctName = "Dispatcher::removeSourceItem()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + QString msg = "Removing source "; + + msg += item->getRefBlock()->getName(); + msg += " and all its connections.\n\nAre you sure ?"; + + int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok); + if (ret == QMessageBox::Cancel) { + return; + } + removeAllBlockConnections(item); + + FunctionalBlock* block = AB_TO_FUN(item->getRefBlock()); + item->getScene()->removeSourceItem(item); + params->getGraph()->removeSourceBlock(block); +} + + void Dispatcher::removeConnection(ConnectionItem *conn) { static QString fctName = "Dispatcher::removeConnection()"; #ifdef DEBUG_FCTNAME @@ -752,6 +886,21 @@ void Dispatcher::removeConnection(ConnectionItem *conn) { InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem GroupItem* groupItem = NULL; + ConnectedInterface *fromInter = fromIfaceItem->refInter; + ConnectedInterface *toInter = toIfaceItem->refInter; + // process the speical case source->group apart + if (fromIfaceItem->getOwner()->isSourceItem()) { + // remove from graph + fromInter->removeConnectedTo(toInter); + toInter->clearConnectedFrom(); + // remove from scene + fromIfaceItem->removeConnectionItem(conn); + toIfaceItem->removeConnectionItem(conn); + groupItem->getScene()->removeConnectionItem(conn); + return; + } + + if (fromIfaceItem->getOwner()->isGroupItem()) { groupIfaceItem = fromIfaceItem; groupItem = toIfaceItem->getOwner()->getScene()->getGroupItem(); @@ -767,9 +916,7 @@ void Dispatcher::removeConnection(ConnectionItem *conn) { // removing the connection from graph #ifdef DEBUG cout << "removing connections from graph ..." ; -#endif - ConnectedInterface *fromInter = fromIfaceItem->refInter; - ConnectedInterface *toInter = toIfaceItem->refInter; +#endif if (fromInter->getDirection() == AbstractInterface::InOut) { fromInter->clearConnectedTo(); fromInter->clearConnectedFrom(); @@ -1028,7 +1175,7 @@ QMap Dispatcher::getAllGroupNames() { return list; } -GroupScene* Dispatcher::searchSceneById(int id) { +GroupScene* Dispatcher::getSceneById(int id) { foreach(GroupWidget *group, groupList){ if(group->getScene()->getId() == id) return group->getScene(); @@ -1037,7 +1184,7 @@ GroupScene* Dispatcher::searchSceneById(int id) { return NULL; } -GroupItem *Dispatcher::searchGroupItemById(int id) { +GroupItem *Dispatcher::getGroupItemById(int id) { foreach(GroupWidget *group, groupList) { GroupScene* scene = group->getScene(); if (scene->getGroupItem()->getId() == id) return scene->getGroupItem(); @@ -1046,11 +1193,11 @@ GroupItem *Dispatcher::searchGroupItemById(int id) { return NULL; } -BoxItem *Dispatcher::searchBlockItemById(int id) { +BoxItem *Dispatcher::getBoxItemById(int id) { foreach(GroupWidget *group, groupList) { GroupScene* scene = group->getScene(); - foreach(BoxItem *item, scene->getBlockItems()){ + foreach(BoxItem *item, scene->getBoxItems()){ if(item->getId() == id){ return item; } @@ -1060,7 +1207,7 @@ BoxItem *Dispatcher::searchBlockItemById(int id) { return NULL; } -InterfaceItem* Dispatcher::searchInterfaceItemById(int id) { +InterfaceItem* Dispatcher::getInterfaceItemById(int id) { foreach(GroupWidget *group, groupList) { @@ -1071,7 +1218,7 @@ InterfaceItem* Dispatcher::searchInterfaceItemById(int id) { return item; } } - foreach(BoxItem *block, scene->getBlockItems()){ + foreach(BoxItem *block, scene->getBoxItems()){ foreach(InterfaceItem *item, block->getInterfaces()){ if(item->getId() == id){ return item; diff --git a/Dispatcher.h b/Dispatcher.h index 8ffce45..0ddba40 100644 --- a/Dispatcher.h +++ b/Dispatcher.h @@ -15,14 +15,22 @@ class GroupScene; class AbstractBoxItem; class GroupItem; class BoxItem; +class SourceItem; class ConnectionItem; class InterfaceItem; +class GroupBlock; +class FunctionalBlock; using namespace std; using namespace Qt; +/*! + * \brief The Dispatcher class + * The Dispatcher class represents the control part (in MVC) of the application. It relays + * user's interactions with the GUI into model's modifications and feeds back them onto the view. + */ class Dispatcher { public: @@ -32,8 +40,7 @@ public: 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); @@ -56,17 +63,22 @@ public: public slots: QMap getAllGroupNames(); - GroupScene* searchSceneById(int id); - GroupScene* searchSceneByName(QString name); - BoxItem* searchBlockItemById(int id); - GroupItem* searchGroupItemById(int id); - InterfaceItem* searchInterfaceItemById(int id); + GroupScene* getSceneById(int id); + GroupScene* getSceneByName(QString name); + BoxItem* getBoxItemById(int id); + GroupItem* getGroupItemById(int id); + InterfaceItem* getInterfaceItemById(int id); + // block ops void addBlock(int idCategory, int idBlock, int idScene); - void removeBlock(BoxItem* item); - void duplicateBlock(BoxItem* item); - void renameBlockOrGroup(AbstractBoxItem* item); + void removeBoxItem(BoxItem* item); + void duplicateBoxItem(BoxItem* item); + void renameFunctionalBlock(BoxItem* item); + void renameGroupBlock(GroupItem* item); + void renameSourceBlock(SourceItem* item); + void removeSourceItem(SourceItem* item); + void duplicateSourceItem(SourceItem* item); // interface ops /*! @@ -107,13 +119,13 @@ public slots: * Thus, parameter item is always owned by a GroupItem */ void removeGroupInterface(InterfaceItem* item); - void duplicateInterface(InterfaceItem* item); + void duplicateInterfaceItem(InterfaceItem* item); void showProperties(InterfaceItem *inter); void renameInterface(InterfaceItem* item); // connection ops - ConnectionItem *addConnection(InterfaceItem *input, InterfaceItem *output); - void removeAllBlockConnections(BoxItem *item); + bool createConnectionItem(InterfaceItem *iface1, InterfaceItem *iface2); + void removeAllBlockConnections(AbstractBoxItem *item); void removeConnection(ConnectionItem *conn); diff --git a/Graph.cpp b/Graph.cpp index 8cd0f99..a4dd676 100644 --- a/Graph.cpp +++ b/Graph.cpp @@ -6,9 +6,11 @@ Graph::Graph() { topGroup = new GroupBlock(NULL); topGroup->setName("top group"); + groups.append(topGroup); } Graph::~Graph() { + delete topGroup; } @@ -16,12 +18,27 @@ QList Graph::getOutsideInterfaces() { return topGroup->getInterfaces(); } -GroupBlock* Graph::createChildBlock(GroupBlock* parent) { +GroupBlock* Graph::createChildGroupBlock(GroupBlock* parent) { GroupBlock* b = new GroupBlock(parent); + groups.append(b); return b; } -FunctionalBlock* Graph::addFunctionalBlock(GroupBlock* group, ReferenceBlock* ref) { +bool Graph::removeGroupBlock(GroupBlock *group) { + group->removeAllBlocks(); + GroupBlock* parent = AB_TO_GRP(group->getParent()); + parent->removeBlock(group); + groups.removeAll(group); +} + +GroupBlock* Graph::getGroupBlockByName(QString name) { + foreach(GroupBlock* group, groups) { + if (group->getName() == name) return group; + } + return NULL; +} + +FunctionalBlock* Graph::createFunctionalBlock(GroupBlock* group, ReferenceBlock* ref) { FunctionalBlock* newBlock = new FunctionalBlock(group,ref); newBlock->populate(); @@ -30,12 +47,63 @@ FunctionalBlock* Graph::addFunctionalBlock(GroupBlock* group, ReferenceBlock* re return newBlock; } -bool Graph::removeFunctionalBlock(FunctionalBlock* block, GroupBlock *group) { +FunctionalBlock* Graph::duplicateFunctionalBlock(FunctionalBlock *block) { + + ReferenceBlock* ref = block->getReference(); + GroupBlock* group = AB_TO_GRP(block->getParent()); + + // adding to the graph + FunctionalBlock* newBlock = createFunctionalBlock(group,ref); + return newBlock; +} + + +bool Graph::removeFunctionalBlock(FunctionalBlock* block) { + GroupBlock* group = AB_TO_GRP(block->getParent()); group->removeBlock(block); + return true; } -bool Graph::removeGroupBlock(GroupBlock *group) { - group->removeAllBlocks(); - GroupBlock* parent = AB_TO_GRP(group->getParent()); - parent->removeBlock(group); +FunctionalBlock* Graph::getFunctionalBlockByName(QString name, GroupBlock* parent) { + FunctionalBlock* block = NULL; + if (parent != NULL) { + block = AB_TO_FUN(parent->getFunctionalBlockByName(name)); + } + else { + foreach(GroupBlock* group, groups) { + block = AB_TO_FUN(group->getFunctionalBlockByName(name)); + if (block != NULL) return block; + } + } + return block; +} + +FunctionalBlock* Graph::createSourceBlock(ReferenceBlock* ref) { + + FunctionalBlock* newBlock = new FunctionalBlock(NULL,ref); + newBlock->populate(); + sources.append(newBlock); + return newBlock; +} + +FunctionalBlock* Graph::duplicateSourceBlock(FunctionalBlock *block) { + + ReferenceBlock* ref = block->getReference(); + GroupBlock* group = AB_TO_GRP(block->getParent()); + + // adding to the graph + FunctionalBlock* newBlock = createSourceBlock(ref); + return newBlock; +} + +FunctionalBlock* Graph::getSourceBlockByName(QString name) { + foreach(FunctionalBlock* block, sources) { + if (block->getName() == name) return block; + } + return NULL; +} + +bool Graph::removeSourceBlock(FunctionalBlock *block) { + sources.removeAll(block); + return true; } diff --git a/Graph.h b/Graph.h index 723e8eb..7be35c2 100644 --- a/Graph.h +++ b/Graph.h @@ -21,16 +21,35 @@ public: Graph(); ~Graph(); - QList getOutsideInterfaces(); + // getters inline GroupBlock* getTopGroup() { return topGroup; } - - GroupBlock* createChildBlock(GroupBlock* parent); - FunctionalBlock* addFunctionalBlock(GroupBlock *group, ReferenceBlock *ref); - bool removeFunctionalBlock(FunctionalBlock* block, GroupBlock *group); + inline QList getAllGroups() { return groups; } + + // methods for group blocks + GroupBlock* createChildGroupBlock(GroupBlock* parent); bool removeGroupBlock(GroupBlock *group); - + GroupBlock* getGroupBlockByName(QString name); + + // methods for functional blocks + FunctionalBlock* createFunctionalBlock(GroupBlock *group, ReferenceBlock *ref); + FunctionalBlock* duplicateFunctionalBlock(FunctionalBlock *block); + bool removeFunctionalBlock(FunctionalBlock* block); + FunctionalBlock* getFunctionalBlockByName(QString name, GroupBlock* parent = NULL); //! if parent = NULL, search in the whole graph + + // methods for source blocks + FunctionalBlock* createSourceBlock(ReferenceBlock *ref); + FunctionalBlock* duplicateSourceBlock(FunctionalBlock *block); + FunctionalBlock* getSourceBlockByName(QString name); + bool removeSourceBlock(FunctionalBlock* block); + + // others + QList getOutsideInterfaces(); + + private: GroupBlock* topGroup; + QList groups; //! usefull to avoid recursive methods to find a particular group. + QList sources; //! source for the top group }; diff --git a/GroupBlock.cpp b/GroupBlock.cpp index 74ec197..e5d3b21 100644 --- a/GroupBlock.cpp +++ b/GroupBlock.cpp @@ -40,6 +40,7 @@ void GroupBlock::setParent(AbstractBlock *_parent) { topGroup = false; } } + void GroupBlock::removeAllBlocks() { foreach(AbstractBlock* block, blocks) { if (block->isGroupBlock()) { @@ -58,6 +59,15 @@ void GroupBlock::removeBlock(AbstractBlock* block) { delete block; } +AbstractBlock *GroupBlock::getFunctionalBlockByName(QString name) { + foreach(AbstractBlock* block, blocks) { + if (block->isFunctionalBlock()) { + if (block->getName() == name) return block; + } + } + return NULL; +} + void GroupBlock::parametersValidation(QList *checkedBlocks, QList *blocksToConfigure) { /* diff --git a/GroupBlock.h b/GroupBlock.h index 5a03236..e07fd90 100644 --- a/GroupBlock.h +++ b/GroupBlock.h @@ -32,6 +32,8 @@ public: // others inline void addBlock(AbstractBlock* block) { blocks.append(block); } void removeBlock(AbstractBlock* block); + AbstractBlock* getFunctionalBlockByName(QString name); + void removeAllBlocks(); void parametersValidation(QList *checkedBlocks, QList* blocksToConfigure); void addGenericParameter(QString name, QString type, QString value); diff --git a/GroupItem.cpp b/GroupItem.cpp index 5d84381..c965452 100644 --- a/GroupItem.cpp +++ b/GroupItem.cpp @@ -125,7 +125,7 @@ void GroupItem::updateMinimumSize() { if (getScene() == NULL) return; - QList blocks = getScene()->getBlockItems(); + QList blocks = getScene()->getBoxItems(); if(blocks.length() > 0) { // first, search for blocks that are at (0,0) int xMaxZero = 0; @@ -259,15 +259,26 @@ bool GroupItem::updateGeometry(ChangeType type) { originPoint.setY(y); if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) { - cout << "must change group item shape" << endl; + cout << "GroupItem: must change group item shape" << endl; prepareGeometryChange(); return true; } return false; } -void GroupItem::interfaceRenamed() { - updateGeometry(InterfaceMove); +void GroupItem::nameChanged() { + + + QFontMetrics fmId(params->defaultBlockFont); + nameWidth = fmId.width(refBlock->getName()); + nameHeight = fmId.height(); + // changing the BoxItem in the upperscene + if (parentItem != NULL) { + parentItem->nameChanged(); + } + updateGeometry(InterfaceMove); + // force the update in case of the size has not changed + update(); } @@ -577,7 +588,7 @@ void GroupItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { if(ifaceItem != NULL) dispatcher->renameInterface(ifaceItem); else - dispatcher->renameBlockOrGroup(this); + dispatcher->renameGroupBlock(this); } else if(selectedAction == showProperties){ dispatcher->showProperties(ifaceItem); diff --git a/GroupItem.h b/GroupItem.h index 881180c..8ab486a 100644 --- a/GroupItem.h +++ b/GroupItem.h @@ -47,7 +47,7 @@ public: bool isGroupItem(); // others - void interfaceRenamed(); + void nameChanged(); void updateShape(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); void load(QDomElement groupElement) throw(Exception); diff --git a/GroupScene.cpp b/GroupScene.cpp index e8c9e84..b24c39c 100644 --- a/GroupScene.cpp +++ b/GroupScene.cpp @@ -5,6 +5,7 @@ #include "GroupWidget.h" #include "GroupItem.h" #include "BoxItem.h" +#include "SourceItem.h" #include "ConnectionItem.h" #include "InterfaceItem.h" #include "AbstractBlock.h" @@ -27,7 +28,12 @@ GroupScene::GroupScene(GroupScene *_parentScene, GroupWidget *_window, Dispatche } GroupScene::~GroupScene() { - blockItems.clear(); + static QString fctName = "GroupScene::~GroupScene()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + boxItems.clear(); connectionItems.clear(); groupItem = NULL; } @@ -44,7 +50,7 @@ InterfaceItem* GroupScene::getSelectedInterface(int id) { QList GroupScene::getSelectedBlocks() { QList lst; - foreach(BoxItem *item, blockItems){ + foreach(BoxItem *item, boxItems){ if (item->isSelected()){ lst.append(item); } @@ -55,7 +61,7 @@ QList GroupScene::getSelectedBlocks() { int GroupScene::setItemsId(int countInit) { int counter = countInit; groupItem->setId(counter++); - foreach(BoxItem *item, blockItems){ + foreach(BoxItem *item, boxItems){ item->setId(counter++); } return counter; @@ -66,7 +72,7 @@ int GroupScene::setInterfacesId(int countInit) { foreach(InterfaceItem* inter, groupItem->getInterfaces()){ inter->setId(counter++); } - foreach(BoxItem *item, blockItems){ + foreach(BoxItem *item, boxItems){ foreach(InterfaceItem* inter, item->getInterfaces()){ inter->setId(counter++); } @@ -74,22 +80,12 @@ int GroupScene::setInterfacesId(int countInit) { return counter; } -QList GroupScene::getGroupAndBlocks() { - - QList lst; - lst.append(groupItem); - foreach(BoxItem *item, blockItems){ - lst.append(item); - } - return lst; -} - -BoxItem *GroupScene::createBlockItem(AbstractBlock *block) { +BoxItem *GroupScene::createBoxItem(AbstractBlock *block) { BoxItem* item = new BoxItem(block,dispatcher,params,groupItem); item->setZValue(1); // add item from the QList - blockItems.append(item); + boxItems.append(item); // repainting the group groupItem->updateShape(); // center the new block @@ -100,24 +96,59 @@ BoxItem *GroupScene::createBlockItem(AbstractBlock *block) { return item; } -void GroupScene::addBlockItem(BoxItem* item) { +void GroupScene::addBoxItem(BoxItem* item) { // add item from the QList - blockItems.append(item); + boxItems.append(item); // repainting the group groupItem->updateShape(); } -void GroupScene::removeBlockItem(BoxItem* item) { +void GroupScene::removeBoxItem(BoxItem* item) { // remove item from the viewport removeItem(item); // remove item from the QList - blockItems.removeAll(item); + boxItems.removeAll(item); // repainting the group groupItem->updateShape(); } -void GroupScene::createConnectionItem(InterfaceItem *iface1, InterfaceItem *iface2) { - ConnectionItem* conn = new ConnectionItem(iface1,iface2, dispatcher, params, groupItem); +SourceItem *GroupScene::createSourceItem(AbstractBlock *block) { + + SourceItem* item = new SourceItem(block,dispatcher,params); + // adding item to the scene + addItem(item); + item->setZValue(1); + // add item from the QList + sourceItems.append(item); + // center the new block + QPointF groupPos = groupItem->pos(); + QPointF newPos(groupPos.x()-item->getTotalWidth()-50, groupPos.y()); + newPos = newPos-item->getOriginPoint(); + item->moveTo(newPos); + return item; +} + +void GroupScene::addSourceItem(SourceItem* item) { + // add item from the QList + sourceItems.append(item); +} + +void GroupScene::removeSourceItem(SourceItem* item) { + // remove item from the viewport + removeItem(item); + // remove item from the QList + sourceItems.removeAll(item); +} + +void GroupScene::createConnectionItem(InterfaceItem *iface1, InterfaceItem *iface2, bool withinGroup) { + ConnectionItem* conn = NULL; + if (withinGroup) { + conn = new ConnectionItem(iface1,iface2, dispatcher, params, groupItem); + } + else { + conn = new ConnectionItem(iface1,iface2, dispatcher, params, NULL); + addItem(conn); + } addConnectionItem(conn); } @@ -128,6 +159,7 @@ ConnectionItem* GroupScene::searchConnectionItem(InterfaceItem *iface1, Interfac return conn; } } + return NULL; } void GroupScene::addConnectionItem(ConnectionItem* item) { @@ -157,16 +189,6 @@ void GroupScene::removeGroupItem() { groupItem = NULL; } -QList GroupScene::getInterfaceConnections(InterfaceItem *item) { - QList list; - foreach(ConnectionItem *conn, connectionItems){ - if(conn->getFromInterfaceItem() == item || conn->getToInterfaceItem() == item){ - list.append(conn); - } - } - return list; -} - void GroupScene::unselecteInterfaces() { if (selectedInterfaces[0] != NULL) { @@ -197,12 +219,20 @@ void GroupScene::save(QXmlStreamWriter &writer) { } groupItem->save(writer); + if (isTopScene()) { + writer.writeStartElement("source_items"); + writer.writeAttribute("count",QString::number(sourceItems.length())); + foreach(SourceItem* item, sourceItems) { + item->save(writer); + } + writer.writeEndElement(); // source_items + } writer.writeStartElement("block_items"); QList functionalBlocks; QList groupBlocks; - foreach(BoxItem *item, blockItems){ + foreach(BoxItem *item, boxItems){ if(item->getRefBlock()->isFunctionalBlock()){ functionalBlocks.append(item); } else if(item->getRefBlock()->isGroupBlock()){ diff --git a/GroupScene.h b/GroupScene.h index a14ef0b..19185a1 100644 --- a/GroupScene.h +++ b/GroupScene.h @@ -11,6 +11,7 @@ class AbstractBlock; class GroupWidget; class GroupItem; class BoxItem; +class SourceItem; class AbstractBoxItem; class ConnectionItem; class InterfaceItem; @@ -48,7 +49,7 @@ public: // attributes getters inline GroupItem* getGroupItem() {return groupItem;} - inline QList getBlockItems() { return blockItems; } + inline QList getBoxItems() { return boxItems; } inline QList getConnectionItems() { return connectionItems; } inline QList getChildrenScene() { return childrenScene; } inline GroupScene* getParentScene() { return parentScene; } @@ -67,25 +68,34 @@ public: // attributes testers inline bool isTopScene() { return topScene; } - // others - BoxItem* createBlockItem(AbstractBlock* block); //! create a new BoxItem and place it at the center of the scene - void addBlockItem(BoxItem* item); //! add an already configured BoxItem in the scene. - void removeBlockItem(BoxItem* item); - void createConnectionItem(InterfaceItem* iface1, InterfaceItem* iface2); + + // BoxItem related + BoxItem* createBoxItem(AbstractBlock* block); //! create a new BoxItem and place it at the center of the scene + void addBoxItem(BoxItem* item); //! add an already configured BoxItem in the scene. + void removeBoxItem(BoxItem* item); + + // ConnectionItem related + void createConnectionItem(InterfaceItem* iface1, InterfaceItem* iface2, bool withinGroup = true); ConnectionItem* searchConnectionItem(InterfaceItem* iface1, InterfaceItem* iface2); void addConnectionItem(ConnectionItem* item); void removeConnectionItem(ConnectionItem* item); + + // GroupItem related void removeGroupItem(); + + // SourceItem related + SourceItem* createSourceItem(AbstractBlock* block); //! create a new SourceItem and place it around the group item + void addSourceItem(SourceItem* item); //! add an already configured SourceItem in the scene. + void removeSourceItem(SourceItem* item); + + // child scenes related inline void addChildScene(GroupScene* child) { childrenScene.append(child); } inline void removeChildScene(GroupScene* child) { childrenScene.removeAll(child); } inline int getNbChildScene() { return childrenScene.size(); } void unselecteInterfaces(); - - QList getGroupAndBlocks(); - QList getSelectedBlocks(); - - QList getInterfaceConnections(InterfaceItem *item); + + QList getSelectedBlocks(); int setItemsId(int countInit=1); int setInterfacesId(int countInit=1); @@ -100,10 +110,11 @@ private: GroupScene* parentScene; // the parent 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 connectionItems; - QList blockItems; - QList childrenScene; + GroupItem *groupItem; //! for convenience, the group item is directly accessible via this attribute + QList connectionItems; //! for convenience, connections are directly accessible via this attribute + QList boxItems; //! for convenience, box items are directly accessible via this attribute + QList sourceItems; //! for convenience, box items are directly accessible via this attribute. Only usefull for top scene + QList childrenScene;//! for convenience, children scenes are directly accessible via this attribute bool topScene; EditMode editMode; InterfaceItem* selectedInterfaces[2]; // selected iface 1 in AddConnection mode diff --git a/GroupWidget.cpp b/GroupWidget.cpp index 2ef7cd1..0705632 100644 --- a/GroupWidget.cpp +++ b/GroupWidget.cpp @@ -41,7 +41,13 @@ GroupWidget::GroupWidget(GroupWidget *_upperGroup, Dispatcher *_dispatcher, } -GroupWidget::~GroupWidget(){} +GroupWidget::~GroupWidget(){ + static QString fctName = "GroupWidget::~GroupWidget()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + // delete scene; // TO DO: must check if it is needed +} void GroupWidget::changeConnectionMode(int mode) { /* @@ -179,9 +185,9 @@ void GroupWidget::slotEdit() { } void GroupWidget::slotCopyBlock() { - foreach (BoxItem *item, params->getCurrentScene()->getBlockItems()) { + foreach (BoxItem *item, params->getCurrentScene()->getBoxItems()) { if(item->isSelected()){ - dispatcher->duplicateBlock(item); + dispatcher->duplicateBoxItem(item); } } } @@ -233,9 +239,9 @@ void GroupWidget::slotNewGroup() } void GroupWidget::slotDeleteItems() { - foreach (BoxItem *item, scene->getBlockItems()) { + foreach (BoxItem *item, scene->getBoxItems()) { if(item->isSelected()){ - dispatcher->removeBlock(item); + dispatcher->removeBoxItem(item); } } foreach (ConnectionItem *item, scene->getConnectionItems()) { diff --git a/InterfaceItem.cpp b/InterfaceItem.cpp index 0047e16..ff6329e 100644 --- a/InterfaceItem.cpp +++ b/InterfaceItem.cpp @@ -95,7 +95,12 @@ void InterfaceItem::paint(QPainter *painter) { painter->setPen(QPen(Qt::red,2)); } else { - painter->setPen(QPen(Qt::black,1)); + if(owner->isBoxItem()) { + painter->setPen(QPen(Qt::black,1)); + } + else if(owner->isSourceItem()) { + painter->setPen(QPen(Qt::darkCyan,1)); + } } painter->translate(originPoint); @@ -141,7 +146,7 @@ void InterfaceItem::paint(QPainter *painter) { if(owner->isGroupItem()){ painter->drawText(-(w+params->arrowWidth+params->arrowLineLength),-h/2,w,h,Qt::AlignLeft | Qt::TextWordWrap, refInter->getName()); } - else if(owner->isBoxItem()){ + else if((owner->isBoxItem()) || (owner->isSourceItem())){ painter->drawText(0,-h/2,w,h,Qt::AlignRight | Qt::TextWordWrap, refInter->getName()); } } @@ -150,7 +155,7 @@ void InterfaceItem::paint(QPainter *painter) { if(owner->isGroupItem()) { painter->drawText(params->arrowWidth+params->arrowLineLength,-h/2,w,h,Qt::AlignRight | Qt::TextWordWrap, refInter->getName()); } - else if(owner->isBoxItem()) { + else if((owner->isBoxItem()) || (owner->isSourceItem())){ painter->drawText(-w,-h/2,w,h,Qt::AlignLeft | Qt::TextWordWrap, refInter->getName()); } } diff --git a/Parameters.cpp b/Parameters.cpp index af8eb22..001fdc3 100644 --- a/Parameters.cpp +++ b/Parameters.cpp @@ -79,15 +79,6 @@ ReferenceBlock* Parameters::getReferenceBlock(int idCategory, int idBlock) { } -FunctionalBlock* Parameters::duplicateFunctionalBlock(FunctionalBlock *block) { - - ReferenceBlock* ref = block->getReference(); - GroupBlock* group = AB_TO_GRP(block->getParent()); - - // adding to the graph - FunctionalBlock* newBlock = graph->addFunctionalBlock(group,ref); - return newBlock; -} void Parameters::validateXmlFile(const QString& xmlFileName, const QString& xsdFileName, XmlFileType fileType) throw(Exception) { // opening configFile @@ -269,7 +260,7 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { throw(err); } // add the block to the GroupScene - currentScene->addBlockItem(funcItem); + currentScene->addBoxItem(funcItem); } } cout << "functional blocks loaded and created succefully!" << endl; @@ -315,7 +306,7 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { BoxItem* upperItem = NULL; if(insideGroup == NULL) cout << "group null" << endl; // now search within the scene which BoxItem has a childItem that is = to insideGroup - QList lst = currentScene->getBlockItems(); + QList lst = currentScene->getBoxItems(); foreach(BoxItem* item, lst) { if (item->getChildGroupItem() == insideGroup) { upperItem = item; @@ -374,7 +365,7 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { InterfaceItem *iface2 = searchInterfaceItemById(to,topScene); if(iface1 != NULL && iface2 != NULL){ - dispatcher->connect(iface1,iface2); + dispatcher->createConnectionItem(iface1,iface2); } else { cout << "interfaces not found, connect canceled!" << endl; } @@ -844,9 +835,9 @@ QList Parameters::getBlocksToConfigure() { void Parameters::updateToolbar() { - int nb = currentScene->getBlockItems().length(); + int nb = currentScene->getBoxItems().length(); for(int i = 0; igetBlockItems().at(i)->isSelected()){ + if(currentScene->getBoxItems().at(i)->isSelected()){ currentScene->getGroupWidget()->enableGroupButton(true); return; } @@ -996,7 +987,7 @@ GroupItem* Parameters::searchGroupItemById(int id, GroupScene *scene) { BoxItem* Parameters::searchBlockItemById(int id, GroupScene *scene) { - foreach(BoxItem *item, scene->getBlockItems()){ + foreach(BoxItem *item, scene->getBoxItems()){ if(item->getId() == id){ return item; } @@ -1017,7 +1008,7 @@ InterfaceItem* Parameters::searchInterfaceItemById(int id, GroupScene* scene) { return item; } } - foreach(BoxItem *block, scene->getBlockItems()){ + foreach(BoxItem *block, scene->getBoxItems()){ foreach(InterfaceItem *item, block->getInterfaces()){ if(item->getId() == id){ return item; diff --git a/SourceItem.cpp b/SourceItem.cpp new file mode 100644 index 0000000..82a41b0 --- /dev/null +++ b/SourceItem.cpp @@ -0,0 +1,737 @@ +#include "SourceItem.h" +#include "GroupScene.h" +#include "ConnectionItem.h" +#include "InterfaceItem.h" +#include "GroupItem.h" +#include "Parameters.h" +#include "Exception.h" +#include "Dispatcher.h" +#include "FunctionalBlock.h" +#include "FunctionalInterface.h" +#include "ReferenceInterface.h" +#include "ReferenceBlock.h" +#include "ParametersWindow.h" +#include "BlockParameter.h" +#include "Graph.h" + + +SourceItem::SourceItem(AbstractBlock *_refBlock, + Dispatcher *_dispatcher, + Parameters *_params) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params) { + + /* NOTE : + _refBlock : mandatory a FunctionalBlock or a GroupBlock + */ + if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE)); + + currentBorder = NoBorder; + selected = false; + + setZValue(100); + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges); + + initInterfaces(); + updateGeometry(InterfaceMove); + resetInterfacesPosition(); + QPointF initPos = QPointF(0.0,0.0) - originPoint; + setPos(initPos); + //cout << "total size of block: " << totalWidth << "," << totalHeight << endl; + //cout << "pos in group: " << x() << "," << y() << endl; +} + +SourceItem::SourceItem(Dispatcher *_dispatcher, Parameters *_params) throw(Exception) : AbstractBoxItem(_dispatcher, _params) { + + refBlock = NULL; + currentBorder = NoBorder; + selected = false; + + setZValue(100); + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges); + + boxWidth = params->defaultBlockWidth; + boxHeight = params->defaultBlockHeight; +} + +SourceItem::~SourceItem() { +} + +void SourceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + QPen pen(Qt::black, 3); + if(selected) + pen.setColor(Qt::red); + + painter->setPen(pen); + painter->setBrush(Qt::darkCyan); + + painter->drawRect(0,0,boxWidth, boxHeight); + painter->drawText(0,0,boxWidth, boxHeight,Qt::AlignCenter | Qt::TextWordWrap,QString(refBlock->getName())); + foreach(InterfaceItem *inter, interfaces) { + + inter->paint(painter); + } +} + +void SourceItem::moveTo(QPointF dest) { + setPos(dest); + currentPosition = dest; +} + +bool SourceItem::isSourceItem() { + return true; +} + +void SourceItem::nameChanged() { + + + QFontMetrics fmId(params->defaultBlockFont); + nameWidth = fmId.width(refBlock->getName()); + nameHeight = fmId.height(); + updateGeometry(InterfaceMove); + // force the update in case of the size has not changed + update(); +} + +void SourceItem::updateMinimumSize() { + + int maxSouth = 0; + int maxNorth = 0; + int maxEast = 0; + int maxWest = 0; + int nbSouth = nbInterfacesByOrientation(Parameters::South); + int nbNorth = nbInterfacesByOrientation(Parameters::North); + int nbMaxSN = nbNorth; + if (nbSouth > nbNorth) nbMaxSN = nbSouth; + int nbEast = nbInterfacesByOrientation(Parameters::East); + int nbWest = nbInterfacesByOrientation(Parameters::West); + int nbMaxEW = nbEast; + if (nbWest > nbEast) { + nbMaxEW = nbWest; + } + + int ifaceWidth = 0; + int ifaceHeight = 0; + + foreach(InterfaceItem* iface, interfaces) { + ifaceWidth = iface->getNameWidth(); + ifaceHeight = iface->getNameHeight(); + if (iface->visible) { + if (iface->getOrientation() == Parameters::South) { + if (ifaceWidth > maxSouth) maxSouth = ifaceWidth; + } + else if (iface->getOrientation() == Parameters::North) { + if (ifaceWidth > maxNorth) maxNorth = ifaceWidth; + } + else if (iface->getOrientation() == Parameters::East) { + if (ifaceWidth > maxEast) maxEast = ifaceWidth; + } + else if (iface->getOrientation() == Parameters::West) { + if (ifaceWidth > maxWest) maxWest = ifaceWidth; + } + } + } + + /* NB: the width layout is the following + ifaceMargin | maxWest | nameMargin | name | nameMargin | maxEast | ifaceMargin + */ + minimumBoxWidth = maxWest+maxEast+nameWidth+2*(ifaceMargin+nameMargin); + // if the minimum is not sufficent taking into account N/S interfaces + if (minimumBoxWidth < (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1))) { + minimumBoxWidth = (nbMaxSN*ifaceHeight+ifaceMargin*(nbMaxSN+1)); + } + minimumBoxHeight = maxNorth+maxSouth+3*ifaceMargin; + if (minimumBoxHeight < (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1))) { + minimumBoxHeight = (nbMaxEW*ifaceHeight+ifaceMargin*(nbMaxEW+1)); + } +} + + +/* updateGeometry() : + + */ +bool SourceItem::updateGeometry(ChangeType type) { + + currentPosition = pos(); + //cout << "current pos of block: " << currentPosition.x() << "," << currentPosition.y() << endl; + QPointF oldOrigin = originPoint; + QSize oldSize(totalWidth,totalHeight); + + bool boxSizeChanged = false; + + // whatever the change, the minimum size may have changed + updateMinimumSize(); + + if (type == Resize) { + // resize implies to move interfaces and to update connections + boxSizeChanged = true; + } + else if (type == InterfaceMove) { + // if an interface moves, it may change the box size + if (boxWidth < minimumBoxWidth) { + boxWidth = minimumBoxWidth; + boxSizeChanged = true; + } + if (boxHeight < minimumBoxHeight) { + boxHeight = minimumBoxHeight; + boxSizeChanged = true; + } + } + if (boxSizeChanged) { + updateInterfacesAndConnections(); + } + + + double x = 0.0; + double y = 0.0; + totalWidth = boxWidth; + totalHeight = boxHeight; + + if(isInterfaces(Parameters::East)){ + totalWidth += params->arrowWidth+params->arrowLineLength; + } + if(isInterfaces(Parameters::West)){ + totalWidth += params->arrowWidth+params->arrowLineLength; + x -= params->arrowWidth+params->arrowLineLength; + } + if(isInterfaces(Parameters::South)){ + totalHeight += params->arrowWidth+params->arrowLineLength; + } + if(isInterfaces(Parameters::North)){ + totalHeight += params->arrowWidth+params->arrowLineLength; + y -= params->arrowWidth+params->arrowLineLength; + } + QSizeF newSize(totalWidth,totalHeight); + originPoint.setX(x); + originPoint.setY(y); + + if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) { + prepareGeometryChange(); + return true; + } + return false; +} + +void SourceItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { + + if(params->editState == Parameters::EditBlockMove) { + QPointF absPos = currentPosition + originPoint; + + int gapX = event->scenePos().x() - cursorPosition.x(); + int gapY = event->scenePos().y() - cursorPosition.y(); + + //cout << "block abs. pos: " << absPos.x() << "," << absPos.y() << " | "; + //cout << "block current. pos: " << currentPosition.x() << "," << currentPosition.y() << " | "; + + /* + if (absPos.x()+gapX < marginConn) { + gapX = marginConn-absPos.x(); + } + if (absPos.y()+gapY < marginConn) { + gapY = marginConn-absPos.y(); + } + */ + //cout << "gap: " << gapX << "," << gapY << endl; + QPointF gap(gapX,gapY); + currentPosition = currentPosition+gap; + setPos(currentPosition); + // update all connections from/to this block + foreach(ConnectionItem *item, getScene()->getConnectionItems()){ + if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) { + item->setPath(); + } + } + cursorPosition = event->scenePos(); + + // udpate the groupitem + (getScene()->getGroupItem())->updateShape(); + } + else if(params->editState == Parameters::EditBlockResize) { + + int gapX = event->scenePos().x() - cursorPosition.x(); + int gapY = event->scenePos().y() - cursorPosition.y(); + //cout << "gap: " << gapX << "," << gapY << endl; + switch(currentBorder){ + case BorderEast: { + if(boxWidth+gapX > minimumBoxWidth){ + boxWidth += gapX; + } + break; + } + case BorderSouth: { + if(boxHeight+gapY > minimumBoxHeight){ + boxHeight += gapY; + } + break; + } + case CornerSouthEast: { + if(boxWidth+gapX > minimumBoxWidth){ + boxWidth += gapX; + } + if(boxHeight+gapY > minimumBoxHeight){ + boxHeight += gapY; + } + break; + } + case NoBorder: + cout << "abnormal case while resizing block" << endl; + break; + } + // recompute the geometry of the block and possibly the group item + if (updateGeometry(Resize)) { + (getScene()->getGroupItem())->updateShape(); + } + + cursorPosition = event->scenePos(); + } + else if(params->editState == Parameters::EditInterfaceMove) { + prepareGeometryChange(); + moveInterfaceTo(event->pos()); + // recompute the geometry of the block + if (updateGeometry(InterfaceMove)) { + //cout << "must recompute group item geometry" << endl; + (getScene()->getGroupItem())->updateShape(); + } + // update connection from/to the selected interface + foreach(ConnectionItem *item, getScene()->getConnectionItems()){ + if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) { + item->setPath(); + } + } + } +} + +void SourceItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { + + QPointF pos = event->pos(); + qreal x = pos.x(); + qreal y = pos.y(); + + //QGraphicsItem::mousePressEvent(event); + + if(event->button() == Qt::RightButton) return; + + int mode = getScene()->getEditionMode(); + + dispatcher->setCurrentGroupWidget(getScene()->getGroupWidget()); + + if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) { + InterfaceItem *inter = getInterfaceFromCursor(x,y); + if (inter != NULL) { + + if (params->editState == Parameters::EditNoOperation) { + getScene()->setSelectedInterface(1,inter); + params->setEditState(Parameters::EditStartConnection); + } + else if (params->editState == Parameters::EditStartConnection) { + if (inter == getScene()->getSelectedInterface(1)) { + params->setEditState(Parameters::EditAbortConnection); + } + else { + getScene()->setSelectedInterface(2,inter); + params->setEditState(Parameters::EditCloseConnection); + } + } + } + } + else if (mode == GroupScene::ItemEdition) { + setZValue(zValue()+100); + if (params->cursorState == Parameters::CursorOnInterface) { + InterfaceItem *inter = getInterfaceFromCursor(x,y); + if (inter != NULL) { + if (inter == currentInterface) { + params->setEditState(Parameters::EditInterfaceDeselect); + } + else { + setFlag(ItemIsMovable, false); + currentInterface = inter; + params->setEditState(Parameters::EditInterfaceMove); + } + } + } + else if (params->cursorState == Parameters::CursorInBlock) { + selected = !selected; + params->setEditState(Parameters::EditBlockMove); + cursorPosition = event->scenePos(); + //cout << "cursor current pos. in scene " << cursorPosition.x() << "," << cursorPosition.y() << endl; + update(); + } + else if (params->cursorState == Parameters::CursorOnBorder) { + setFlag(ItemIsMovable, false); + cursorPosition = event->scenePos(); + params->setEditState(Parameters::EditBlockResize); + } + } +} + +void SourceItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { + + setZValue(zValue()-100); + + int mode = getScene()->getEditionMode(); + + if (mode == GroupScene::AddConnection) { + + if (params->editState == Parameters::EditStartConnection) { + InterfaceItem* iface = getScene()->getSelectedInterface(1); + iface->selected = true; + update(iface->boundingRect()); + } + else if (params->editState == Parameters::EditAbortConnection) { + InterfaceItem* iface = getScene()->getSelectedInterface(1); + iface->selected = false; + update(iface->boundingRect()); + getScene()->setSelectedInterface(1,NULL); + params->setEditState(Parameters::EditNoOperation); + } + else if (params->editState == Parameters::EditCloseConnection) { + InterfaceItem* iface1 = getScene()->getSelectedInterface(1); + InterfaceItem* iface2 = getScene()->getSelectedInterface(2); + bool ok = dispatcher->createConnectionItem(iface1,iface2); + if (ok) { + iface1->selected = false; + // no update needed since the whole scene will be repainted + getScene()->setSelectedInterface(1,NULL); + getScene()->setSelectedInterface(2,NULL); + params->setEditState(Parameters::EditNoOperation); + } + else { + //QMessageBox::warning(NULL,"Error","Cannot connect selected interfaces", QMessageBox::Ok); + getScene()->setSelectedInterface(2,NULL); + params->setEditState(Parameters::EditStartConnection); + } + } + } + else if (mode == GroupScene::ItemEdition) { + currentInterface = NULL; + params->editState = Parameters::EditNoOperation; + setFlag(ItemIsMovable); + } + + QGraphicsItem::mouseReleaseEvent(event); +} + +void SourceItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) { + + QPointF pos = event->pos(); + qreal x = pos.x(); + qreal y = pos.y(); + currentBorder = NoBorder; + int mode = getScene()->getEditionMode(); + + if (mode == GroupScene::AddConnection) { + InterfaceItem* iface = getInterfaceFromCursor(x,y); + if (iface != NULL) { + params->cursorState = Parameters::CursorOnInterface; + setCursor(Qt::PointingHandCursor); + } + else { + params->cursorState = Parameters::CursorNowhere; + setCursor(Qt::ArrowCursor); + } + } + else if (mode == GroupScene::ItemEdition) { + int marginE = 5; + int marginS = 5; + + InterfaceItem* iface = getInterfaceFromCursor(x,y); + if (iface != NULL) { + params->cursorState = Parameters::CursorOnInterface; + setCursor(Qt::PointingHandCursor); + } + else if ((x>boxWidth-marginE)&&(xcursorState = Parameters::CursorOnBorder; + + if ((y>boxHeight-2*marginS)&&(yboxHeight-marginS)&&(ycursorState = Parameters::CursorOnBorder; + + if ((x>boxWidth-2*marginE)&&(x0) && (x0) && (ycursorState = Parameters::CursorInBlock; + setCursor(Qt::OpenHandCursor); + } + else { + params->cursorState = Parameters::CursorNowhere; + setCursor(Qt::ArrowCursor); + } + } + } + QGraphicsItem::hoverMoveEvent(event); +} + + +void SourceItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { + + event->accept(); + + QMenu menu; + QAction* titleAction = NULL; + QAction* removeAction = NULL; + QAction* duplicateAction = NULL; + QAction* renameAction = NULL; + QAction* showProperties = NULL; + QAction* showParameters = NULL; + + + InterfaceItem* ifaceItem = getInterfaceFromCursor(event->pos().x(), event->pos().y()); + // menu for interface + if( ifaceItem != NULL){ + + titleAction = menu.addAction("Interface operations"); + titleAction->setEnabled(false); + menu.addSeparator(); + + + showProperties = menu.addAction("Show properties"); + renameAction = menu.addAction("Rename"); + + } + // menu for block + else { + titleAction = menu.addAction("Block operations"); + titleAction->setEnabled(false); + menu.addSeparator(); + + if (refBlock->nbParameters() > 0) { + showParameters = menu.addAction("Show parameters"); + } + renameAction = menu.addAction("Rename"); + + duplicateAction = menu.addAction("Duplicate"); + removeAction = menu.addAction("Remove"); + } + + QAction* selectedAction = NULL; + selectedAction = menu.exec(event->screenPos()); + + if(selectedAction == NULL) return ; + + if (selectedAction == removeAction) { + dispatcher->removeSourceItem(this); + } + else if (selectedAction == duplicateAction) { + dispatcher->duplicateSourceItem(this); + } + else if(selectedAction == renameAction){ + if(ifaceItem != NULL) { + dispatcher->renameInterface(ifaceItem); + } + else { + dispatcher->renameSourceBlock(this); + } + } + else if(selectedAction == showProperties){ + dispatcher->showProperties(ifaceItem); + } + else if(selectedAction == showParameters){ + new ParametersWindow(refBlock, params, NULL); + } +} + +void SourceItem::load(QDomElement funcElement) throw(Exception) { + + bool ok = false; + + int id = funcElement.attribute("id","none").toInt(&ok); + if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); + + QString refXml = funcElement.attribute("ref_xml","none"); + if(refXml == "none") throw(Exception(PROJECTFILE_CORRUPTED)); + + QString refMd5 = funcElement.attribute("ref_md5","none"); + if(refMd5 == "none") throw(Exception(PROJECTFILE_CORRUPTED)); + + cout << "ref md5 : " << refMd5.toStdString() << "\nref xml : " << refXml.toStdString() << endl; + + QString name = funcElement.attribute("name","none"); + if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED)); + + QStringList positionStr = funcElement.attribute("position","none").split(","); + if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED)); + int posX = positionStr.at(0).toInt(&ok); + if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); + int posY = positionStr.at(1).toInt(&ok); + if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); + + QStringList dimensionStr = funcElement.attribute("dimension","none").split(","); + if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED)); + int dimX = dimensionStr.at(0).toInt(&ok); + if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); + int dimY = dimensionStr.at(1).toInt(&ok); + if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); + + ReferenceBlock *referenceMd5 = NULL; + ReferenceBlock *referenceXml = NULL; + ReferenceBlock *reference = NULL; + if(refMd5 != "none") { + referenceMd5 = params->searchBlockByMd5(refMd5); + } + if(refXml != "none"){ + referenceXml = params->searchBlockByXml(refXml); + } + if ((referenceMd5 == NULL) && (referenceXml == NULL)) { + throw(Exception(PROJECTFILE_CORRUPTED)); + } + if (referenceMd5 != referenceXml) { + throw(Exception(PROJECTFILE_CORRUPTED)); + } + else { + reference = referenceMd5; + } + + GroupBlock* parentGroupBlock = AB_TO_GRP(((GroupItem *)parentItem())->getRefBlock()); + FunctionalBlock* functionalBlock = params->getGraph()->createFunctionalBlock(parentGroupBlock, reference); + /* NB: addFunctionalBlock creates all interfaces from the reference, which is annoying when + reading bif_iface tags. Thus interface are all removed. + */ + functionalBlock->setName(name); + setRefBlock(functionalBlock); + + setPos(posX,posY); + setDimension(dimX,dimY); + setId(id); + + + QDomNodeList blockParamNodes = funcElement.elementsByTagName("bif_parameter"); + // setting parameters value + for(int i=0; igetParameterFromName(name); + if (blockParam == NULL) throw(Exception(PROJECTFILE_CORRUPTED)); + blockParam->setValue(value); + } + + // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars + functionalBlock->removeAllInterfaces(); + QDomNodeList interfaceNodes = funcElement.elementsByTagName("bif_iface"); + // setting interfaces (user name, and for multiplicity>1 may be create some new ones) + for(int i=0; igetIfaceFromName(refName)); + cout << "creating iface from reference named " << qPrintable(refName) << endl; + FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter); + functionalInterface->setName(name); + functionalBlock->addInterface(functionalInterface); + + // searching for control interface + QString ctlRefName = refName+"_ctl"; + ReferenceInterface* ctlRefIface = AI_TO_REF(reference->getIfaceFromName(ctlRefName)); + + if (ctlRefIface != NULL) { + cout << "found a control iface:" << qPrintable(ctlRefName) << endl; + FunctionalInterface *ctlIface = new FunctionalInterface(functionalBlock,ctlRefIface); + if (! ctlIface->setAssociatedIface(functionalInterface)) { + throw(Exception(PROJECTFILE_CORRUPTED)); + } + ctlIface->setName(name+"_ctl"); + functionalBlock->addInterface(ctlIface); + } + } + + // creating InterfaceItem + initInterfaces(); + // setting them with saved values + for(int i=0; isetId(id); + interfaceItem->setOrientation(orientation); + interfaceItem->setPositionRatio(position); + } + updateGeometry(Resize); +} + +void SourceItem::save(QXmlStreamWriter &writer) { + + writer.writeStartElement("source_item"); + + writer.writeAttribute("id",QString::number(id)); + writer.writeAttribute("ref_xml", ((FunctionalBlock*)refBlock)->getReferenceXmlFile()); + writer.writeAttribute("ref_md5", ((FunctionalBlock*)refBlock)->getReferenceHashMd5()); + writer.writeAttribute("name",refBlock->getName()); + QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y()))); + writer.writeAttribute("position",attrPos); + QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight())); + writer.writeAttribute("dimension",attrDim); + + writer.writeStartElement("source_parameters"); + foreach(BlockParameter *param,refBlock->getParameters()){ + writer.writeStartElement("source_parameter"); + + writer.writeAttribute("name",param->getName()); + writer.writeAttribute("value",param->getValue().toString()); + /* + writer.writeAttribute("context",param->getStrContext()); + writer.writeAttribute("type",param->getTypeString()); + */ + writer.writeEndElement(); // + } + writer.writeEndElement(); // + + writer.writeStartElement("source_ifaces"); + writer.writeAttribute("count",QString::number(interfaces.length())); + foreach(InterfaceItem* inter, interfaces){ + writer.writeStartElement("source_iface"); + + writer.writeAttribute("id",QString::number(inter->getId())); + writer.writeAttribute("name",inter->getName()); + writer.writeAttribute("ref_name",inter->refInter->getName()); + writer.writeAttribute("orientation",inter->getStrOrientation()); + writer.writeAttribute("position",QString::number(inter->getPositionRatio())); + + writer.writeEndElement(); // + } + writer.writeEndElement(); // + + writer.writeEndElement(); // + +} diff --git a/SourceItem.h b/SourceItem.h new file mode 100644 index 0000000..72ebede --- /dev/null +++ b/SourceItem.h @@ -0,0 +1,62 @@ +#ifndef __SOURCEITEM_H__ +#define __SOURCEITEM_H__ + +#include + +#include +#include +#include +#include + + +#include "AbstractBoxItem.h" +class AbstractBoxItem; + +class Parameters; +class Dispacther; + +#include "Exception.h" + +using namespace std; +using namespace Qt; + +/*! + * \brief The SourceItem class + * A SourceItem represents a special type of block that is added only + * to the top scene, in order to simulate inputs on the FPGA input + * pins. This, the reference block used as a source must be chosen + * among blocks that have no inputs and only outputs (with multiplicity + * = 1) + */ +class SourceItem : public AbstractBoxItem { + +public: + SourceItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params) throw(Exception); + SourceItem(Dispatcher *_dispatcher, Parameters *_params) throw(Exception); + ~SourceItem(); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + + // testers + bool isSourceItem(); + + // others + void nameChanged(); + void moveTo(QPointF dest); + void load(QDomElement funcElement) throw(Exception); + 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); + +}; + +#endif // __SOURCEITEM_H__ diff --git a/blast.creator.user b/blast.creator.user index 51f5a11..9f8479e 100755 --- a/blast.creator.user +++ b/blast.creator.user @@ -1,10 +1,10 @@ - + EnvironmentId - {c8006d66-d34f-42be-ad10-d0207752286d} + {1d077e47-e3a1-47fd-8b12-4de650e39df5} ProjectExplorer.Project.ActiveTarget @@ -60,12 +60,12 @@ Desktop Desktop - {2c9bf876-3476-44eb-8065-1f0844704dda} + {451ee8a3-56ff-4aba-8a8e-3da882cc142e} 0 0 0 - /home/sdomas/Projet/Blast/code/blast + /localhome/sdomas/Projet/Blast/code/blast diff --git a/blast.files b/blast.files index 7b2dd43..3975c5f 100755 --- a/blast.files +++ b/blast.files @@ -29,6 +29,8 @@ BlockLibraryWidget.h blast.cpp BlockCategory.cpp BlockCategory.h +SourceItem.cpp +SourceItem.h BoxItem.cpp BoxItem.h BlockLibraryTree.cpp diff --git a/blastconfig.xml b/blastconfig.xml index f827695..bc2d2bc 100644 --- a/blastconfig.xml +++ b/blastconfig.xml @@ -7,8 +7,8 @@ - - + + diff --git a/lib/references/references.bmf b/lib/references/references.bmf index 66b4efeca106b928c4db56993e77f2055a2238e1..432ac5d4306e7bace654a8404fe6dbeb74199ac6 100644 GIT binary patch delta 245 zcmca$yupHlfk8%xfq{WzBgZ3l8KxK@Q;4CMA)ld?p@<=wA(cUw!HB^hD4H^Pf`B(a zn#{x&Wo2X`1%@Ps9H8c8hHM5M1_g$4hD?SMhK$L2%;FO#iV>^SlM!ei8xT7HjWc5~ zW=Lc(WH1LBn!;cK6iEYOBL+*L2#A#gluZTVM4&p5xH*uQ1|$tZ`X(P>b7W+i>>zAC N`8-Sc=2z^`1ObzpFd_f| delta 22 ecmdmBalx2_fkE;N0|Nv5Mvh19o4vT62?78}zXpH+ diff --git a/object-files.txt b/object-files.txt index 806c346..704e921 100644 --- a/object-files.txt +++ b/object-files.txt @@ -11,7 +11,8 @@ COMMON-OBJ = $(BUILDPATH)/AbstractBlock.o \ $(BUILDPATH)/Graph.o \ $(BUILDPATH)/AbstractBoxItem.o \ $(BUILDPATH)/BoxItem.o \ - $(BUILDPATH)/GroupItem.o \ + $(BUILDPATH)/GroupItem.o \ + $(BUILDPATH)/SourceItem.o \ $(BUILDPATH)/BlockCategory.o \ $(BUILDPATH)/BlockLibraryTree.o \ $(BUILDPATH)/BlockLibraryWidget.o \ -- 2.39.5