X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/d30c9cf675ad7141d1c8e31d2e72315267d45cf2..1df76ccc8673a2760af17b88ebfba4bfd7f5c11d:/Dispatcher.cpp?ds=sidebyside diff --git a/Dispatcher.cpp b/Dispatcher.cpp index 810396e..b6495bb 100644 --- a/Dispatcher.cpp +++ b/Dispatcher.cpp @@ -44,6 +44,7 @@ GroupWidget *Dispatcher::loadProject(const QString& filename) { return NULL; } + /* // creating the top widget/scene topGroup = new GroupWidget(NULL,this,params); currentGroup = topGroup; @@ -52,9 +53,9 @@ GroupWidget *Dispatcher::loadProject(const QString& filename) { params->setTopScene(scene); params->setCurrentScene(scene); - +*/ try { - params->loadProject(root); + topGroup = params->loadProject(root); } catch(Exception e){ cerr << qPrintable(e.getDefaultMessage()) << endl; @@ -72,7 +73,11 @@ void Dispatcher::closeCurrentProject() { foreach(GroupWidget* win, groupList) { win->deleteLater(); } + groupList.clear(); params->destroyGraph(); + topGroup = NULL; + currentGroup = NULL; + sceneCounter = 0; } bool Dispatcher::connect(InterfaceItem *iface1, InterfaceItem *iface2) { @@ -179,10 +184,14 @@ void Dispatcher::changeConnectionMode(int mode){ */ } -void Dispatcher::rename(AbstractBoxItem *item){ +void Dispatcher::renameBlockOrGroup(AbstractBoxItem *item){ + static QString fctName = "Dispatcher::renameBlockOrGroup()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif bool ok; - QString text = QInputDialog::getText(NULL, "Rename an element", + QString text = QInputDialog::getText(NULL, "Rename an block/group", "New name:", QLineEdit::Normal, item->getRefBlock()->getName(), &ok); @@ -204,12 +213,17 @@ void Dispatcher::rename(AbstractBoxItem *item){ 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); + renameBlockOrGroup(item); } } } -void Dispatcher::rename(InterfaceItem *item){ +void Dispatcher::renameInterface(InterfaceItem *item) { + static QString fctName = "Dispatcher::renameInterface()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + bool ok; QString text = QInputDialog::getText(NULL, "Rename an interface", "New name:", QLineEdit::Normal, @@ -225,20 +239,22 @@ void Dispatcher::rename(InterfaceItem *item){ 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); + renameInterface(item); } } void Dispatcher::duplicateBlock(BoxItem *item){ + static QString fctName = "Dispatcher::duplicateBlock()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif - GroupScene *scene = params->getCurrentScene(); + GroupScene *scene = item->getScene(); AbstractBlock* block = item->getRefBlock(); AbstractBlock *newBlock; @@ -255,7 +271,12 @@ void Dispatcher::duplicateBlock(BoxItem *item){ } } -void Dispatcher::duplicateInterface(InterfaceItem *item){ +void Dispatcher::duplicateInterface(InterfaceItem *item) { + static QString fctName = "Dispatcher::duplicateInterface()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + AbstractInterface *refI = item->refInter; if (! refI->isFunctionalInterface()) return; @@ -277,14 +298,25 @@ void Dispatcher::duplicateInterface(InterfaceItem *item){ void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) { + static QString fctName = "Dispatcher::addBlock()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif GroupScene *scene = searchSceneById(idScene); - FunctionalBlock* newOne = params->addFunctionalBlock(idCategory, idBlock); + ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock); + GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock()); + FunctionalBlock* newOne = params->getGraph()->addFunctionalBlock(group, ref); scene->createBlockItem(newOne); + params->unsaveModif = true; } GroupWidget *Dispatcher::createTopScene(){ + static QString fctName = "Dispatcher::createTopScene()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif // creating the model part of the group Graph* graph = params->createGraph(); @@ -314,52 +346,134 @@ GroupWidget *Dispatcher::createTopScene(){ return topGroup; } -GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) { +GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) { + static QString fctName = "Dispatcher::addNewEmptyGroup();"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif - // getting back the goup block already created - GroupBlock* groupBlock = NULL; - if (upperItemOfGroupItem != NULL) { - groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock()); - } - // creating the view part of the group - GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params); - // creating the group widget - GroupWidget* group = new GroupWidget(parentWidget, this, params); - // getting the newly created scene - GroupScene *scene = group->getScene(); - scene->setId(sceneCounter++); - // affecting group item to the scene - scene->setGroupItem(groupItem); - groupList.append(group); + // 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); + 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); - mainWindow->getLibrary()->updateComboScene(); + params->unsaveModif = true; + + GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem); + if (show) child->show(); + return child; + +} + +GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) { + static QString fctName = "Dispatcher::createChildScene()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + GroupWidget* group = NULL; + /* NB: this method may be called during design process or when loading + a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things + cannot be initialized yet. This is why there are 2 cases below + */ + + if (upperItemOfGroupItem != NULL) { + // getting back the goup block already created + GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock()); + // creating the view part of the group + GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params); + // creating the group widget + group = new GroupWidget(parentWidget, this, params); + // getting the newly created scene + GroupScene *scene = group->getScene(); + scene->setId(sceneCounter++); + // affecting group item to the scene + scene->setGroupItem(groupItem); + groupList.append(group); + + mainWindow->getLibrary()->updateComboScene(); + } + else { + GroupItem *groupItem = new GroupItem(this,params); + // creating the group widget + group = new GroupWidget(parentWidget, this, params); + // getting the newly created scene + GroupScene *scene = group->getScene(); + // affecting group item to the scene + scene->setGroupItem(groupItem); + groupList.append(group); + } return group; } -void Dispatcher::showRaiseWindow(AbstractBoxItem *item) { - GroupWidget* win = item->getScene()->getGroupWindow(); - if (win->isTopGroup()) { - mainWindow->show(); - mainWindow->raise(); +void Dispatcher::destroyScene(GroupScene *scene) { + foreach(GroupScene* s, scene->getChildrenScene()) { + destroyScene(s); + } + + if (scene->getNbChildScene() == 0) { + // remove scene from the parent list + scene->getParentScene()->removeChildScene(scene); + // destroy the GroupWidget + groupList.removeAll(scene->getGroupWidget()); + scene->getGroupWidget()->deleteLater(); } else { - win->show(); - win->raise(); + cerr << "Abnormal case when destroying a scene" << endl; } +} + +void Dispatcher::showRaiseWindow(BoxItem *item) { + static QString fctName = "Dispatcher::showRaiseWindow()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl; + GroupItem* child = item->getChildGroupItem(); + if (child == NULL) { + cerr << "abnormal case: child group item is null " << endl; + return; + } + + GroupWidget* win = child->getScene()->getGroupWidget(); + + win->showNormal(); + win->raise(); + win->activateWindow(); + currentGroup = win; params->setCurrentScene(currentGroup->getScene()); } -void Dispatcher::showRstClkInter(AbstractBoxItem *item) { +void Dispatcher::showRstClkIface(AbstractBoxItem *item) { + static QString fctName = "Dispatcher::showRstClkIface()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif item->setRstClkVisible(!item->isRstClkVisible()); - item->resetInterfacesPosition(); + +} - item->getScene()->updateConnectionItemsShape(); +void Dispatcher::showWishboneIface(AbstractBoxItem *item) { + static QString fctName = "Dispatcher::showWishboneIface()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + item->setWishboneVisible(!item->isWishboneVisible()); } void Dispatcher::addNewFullGroup() { + static QString fctName = "Dispatcher::addNewFullGroup()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + #ifdef DEBUG_INCLFUN @@ -515,88 +629,162 @@ void Dispatcher::addNewFullGroup() { #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(); +void Dispatcher::removeBlock(BoxItem *item) { + static QString fctName = "Dispatcher::removeBlock()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif - removeConnections(item); + /* a BoxItem (group of func) can be removed only if none of its + interfaces is connected to a group interface that is itself + connected to another one. + */ + bool canRemove = true; - //récupérer l'objet - group->removeBlock(block); + foreach(InterfaceItem* ifaceItem, item->getInterfaces()) { + foreach(ConnectionItem* conn, ifaceItem->connections) { + InterfaceItem* other = NULL; + if (conn->getFromInterfaceItem() == ifaceItem) { + other = conn->getToInterfaceItem(); + } + else { + other = conn->getFromInterfaceItem(); + } - //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; + if (other->getOwner()->isGroupItem()) { + ConnectedInterface* ref = other->refInter; + if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) { + canRemove = false; } } } } + if (!canRemove) { + QMessageBox::warning(NULL,"Forbidden operation", + "The block has at least one connection to a group interface that is totally connected.", + QMessageBox::Ok); + return; + } - delete block; + QString msg = ""; + if (item->getRefBlock()->isFunctionalBlock()) { + msg = "Removing block "; + } + else { + msg = "Removing group "; + } + msg += item->getRefBlock()->getName(); + msg += " and all its connections.\n\nAre you sure ?"; - //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; + int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok); + if (ret == QMessageBox::Cancel) { + return; + } + removeAllBlockConnections(item); - ((GroupItem *)scene->getGroupItem())->updateShape(); + 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); + } + else if (item->getRefBlock()->isGroupBlock()) { - params->updateToolbar(); - params->unsaveModif = true; + GroupBlock* group = AB_TO_GRP(item->getRefBlock()); -#endif + // remove all child scenes recursively + GroupItem* subgroup = item->getChildGroupItem(); + destroyScene(subgroup->getScene()); + // remove the BoxItem + item->getScene()->removeBlockItem(item); + // remove the group from the graph + params->getGraph()->removeGroupBlock(group); + } } -void Dispatcher::removeAllBlockConnections(AbstractBoxItem *block) { +void Dispatcher::removeAllBlockConnections(BoxItem *item) { + static QString fctName = "Dispatcher::removeAllBlockConnection()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif - 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){ + foreach(InterfaceItem* ifaceItem, item->getInterfaces()) { + foreach(ConnectionItem* conn, ifaceItem->connections) { removeConnection(conn); } } - scene->getGroupItem()->updateInterfacesAndConnections(); } void Dispatcher::removeConnection(ConnectionItem *conn) { + static QString fctName = "Dispatcher::removeConnection()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + InterfaceItem* fromIfaceItem = conn->getFromInterfaceItem(); + InterfaceItem* toIfaceItem = conn->getToInterfaceItem(); - GroupScene *scene = params->getCurrentScene(); - GroupItem* currentGroup = scene->getGroupItem(); +#ifdef DEBUG + cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl; +#endif - conn->getFromInterfaceItem()->unconnectTo(conn->getToInterfaceItem()); + InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem + GroupItem* groupItem = NULL; - scene->removeConnectionItem(conn); - delete conn; + if (fromIfaceItem->getOwner()->isGroupItem()) { + groupIfaceItem = fromIfaceItem; + groupItem = toIfaceItem->getOwner()->getScene()->getGroupItem(); + } + else if (toIfaceItem->getOwner()->isGroupItem()) { + groupIfaceItem = toIfaceItem; + groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem(); + } + else { + groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem(); + } - currentGroup->updateInterfacesAndConnections(); - params->unsaveModif = true; -} + // removing the connection from graph +#ifdef DEBUG + cout << "removing connections from graph ..." ; +#endif + ConnectedInterface *fromInter = fromIfaceItem->refInter; + ConnectedInterface *toInter = toIfaceItem->refInter; + if (fromInter->getDirection() == AbstractInterface::InOut) { + fromInter->clearConnectedTo(); + fromInter->clearConnectedFrom(); + toInter->clearConnectedTo(); + toInter->clearConnectedFrom(); + } + else { + fromInter->removeConnectedTo(toInter); + toInter->clearConnectedFrom(); + } +#ifdef DEBUG + cout << "done." << endl ; +#endif -void Dispatcher::removeUselessGroupInterfaces() { + // removing the connection from scene +#ifdef DEBUG + cout << "removing connections from scene ..." ; +#endif + fromIfaceItem->removeConnectionItem(conn); + toIfaceItem->removeConnectionItem(conn); + groupItem->getScene()->removeConnectionItem(conn); - GroupScene *scene = params->getCurrentScene(); - GroupItem* currentGroup = scene->getGroupItem(); +#ifdef DEBUG + cout << "done." << endl ; +#endif - foreach(InterfaceItem *inter, currentGroup->getInterfaces()) { - if(inter->refInter->getConnectedTo().length() == 0) { - // NB : remove from view also remove from model - currentGroup->removeInterface(inter); + if (groupIfaceItem != NULL) { + ConnectedInterface* groupInter = groupIfaceItem->refInter; + groupItem->removeInterface(groupIfaceItem); + + BoxItem* parent2Item = groupItem->getParentItem(); + if (parent2Item != NULL) { + InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter); + parent2Item->removeInterface(group2IfaceItem); } + groupInter->getOwner()->removeInterface(groupInter); } - scene->updateConnectionItemsShape(); } void Dispatcher::showBlocksLibrary(){ @@ -626,7 +814,7 @@ void Dispatcher::connectInterToGroup(InterfaceItem *item){ 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()); + GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection()); groupInter->setType(refInter->getType()); groupInter->setWidth(refInter->getWidth()); groupInter->setPurpose(refInter->getPurpose()); @@ -691,7 +879,7 @@ void Dispatcher::disconnectInterFromGroup(InterfaceItem *item) { if (refInter->getDirection() == AbstractInterface::Output) { groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to - refInter->clearConnectedTo(); + refInter->removeConnectedTo(groupInter); groupInter->clearConnectedFrom(); } else if (refInter->getDirection() == AbstractInterface::Input) { @@ -768,6 +956,28 @@ void Dispatcher::disconnectInterFromGroup(InterfaceItem *item) { #endif } +void Dispatcher::removeBlockInterface(InterfaceItem *item) { + static QString fctName = "Dispatcher::removeBlockInterface()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + /* first, remove all connections from item + NB: if there is a connection to a group interface, then this + method should not be called if the group interface is also + connected to another interface. Normally, this is not possible + because such a check is done when creating the contextual menu + that allows to remove an interface. + */ + foreach(ConnectionItem* conn, item->connections) { + removeConnection(conn); + } + + ConnectedInterface* ref = item->refInter; + item->getOwner()->removeInterface(item); + FunctionalBlock* fun = AB_TO_FUN(ref->getOwner()); + fun->removeInterface(ref); +} void Dispatcher::removeGroupInterface(InterfaceItem *item) { static QString fctName = "Dispatcher::removeGroupInterface()";