]> AND Private Git Repository - blast.git/commitdiff
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
added source items
authorstephane Domas <stephane.domas@univ-fcomte.fr>
Tue, 9 May 2017 17:55:28 +0000 (19:55 +0200)
committerstephane Domas <stephane.domas@univ-fcomte.fr>
Tue, 9 May 2017 17:55:28 +0000 (19:55 +0200)
26 files changed:
AbstractBlock.cpp
AbstractBlock.h
AbstractBoxItem.cpp
AbstractBoxItem.h
BoxItem.cpp
BoxItem.h
Dispatcher.cpp
Dispatcher.h
Graph.cpp
Graph.h
GroupBlock.cpp
GroupBlock.h
GroupItem.cpp
GroupItem.h
GroupScene.cpp
GroupScene.h
GroupWidget.cpp
InterfaceItem.cpp
Parameters.cpp
SourceItem.cpp [new file with mode: 0644]
SourceItem.h [new file with mode: 0644]
blast.creator.user
blast.files
blastconfig.xml
lib/references/references.bmf
object-files.txt

index d316800e91e43534ed43d2d6ef5bbd3b7bca723f..ba1c17915444b5a30cc5a99808ae33d761ea3ddf 100644 (file)
@@ -119,6 +119,16 @@ QList<AbstractInterface *> AbstractBlock::getInterfaces() {
   return list;\r
 }\r
 \r
+QList<AbstractInterface *> AbstractBlock::getDataInputs() {\r
+  QList<AbstractInterface *> list;\r
+  foreach(AbstractInterface* iface, inputs) {\r
+    if (iface->getPurpose() == AbstractInterface::Data) {\r
+      list.append(iface);\r
+    }\r
+  }\r
+  return list;\r
+}\r
+\r
 AbstractInterface* AbstractBlock::getIfaceFromName(QString name) {\r
 \r
   foreach(AbstractInterface* iface, inputs) {\r
index acdc1c8ab8771953a7c180b1d72656ed299b8a76..28e8b7a1d26b98f91b3a6ec13b54c0d86eb4745e 100644 (file)
@@ -54,7 +54,8 @@ public:
   void removeAllInterfaces();\r
   void defineBlockParam(BlockParameter *param);\r
 \r
-  QList<AbstractInterface *> getInterfaces();\r
+  QList<AbstractInterface *> getInterfaces(); //! return all interfaces\r
+  QList<AbstractInterface *> getDataInputs(); //! return all inputs of type data\r
   AbstractInterface* getIfaceFromName(QString name);\r
   BlockParameter* getParameterFromName(QString name);\r
 \r
index b76bf667b798e2190e7c9af53a0ffd596758fa18..8ef607a6aa1af618a3c4d39bcb21408dec394b10 100644 (file)
@@ -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) {
index ed3e1ee74060ae0f0c696304d5068ae900cc220a..132adc996f7f1ef979c4d97932adbff30713841e 100644 (file)
@@ -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
index a107198654913fdc6badc66bc19ed9b13f784d47..6e6f15aace5731771cc753171d3b0af4ba77877a 100644 (file)
@@ -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.
   */
index a80f9f03078fae6dd0c3e1cefe5cd27a626d8126..c8a942e8590a9f8c6ad6566a0516706f28dce73a 100644 (file)
--- 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);
index ac0862ca64a60e8508b411643a8c3b08f3e0b49a..bbbb945399fec32d5221e8b6f608b3a2867dd871 100644 (file)
@@ -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<AbstractBoxItem*> list = scene->getGroupAndBlocks();
-  foreach(AbstractBoxItem *block, list){
-    InterfaceItem *tmp = block->getCurrentInterface();
-    if (tmp != NULL) {
-      if (iface1 == NULL) {
-        iface1 = tmp;
-      }
-      else {
-        iface2 = tmp;
-      }
-    }
-  }
-  if(iface1 != NULL && iface2 != NULL){
-    connect(iface1,iface2);
-  }
-}
 
 void Dispatcher::unselectAllItems(int direction){
 
   GroupScene *scene = params->getCurrentScene();
 
-  foreach(BoxItem* block, scene->getBlockItems()) {
+  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<int, QString> 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;
index 8ffce457a598e488e5a284f13407b1e66882f9f6..0ddba40cfcd221d46594c81dd6785f9a9b97da16 100644 (file)
@@ -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<int, QString> 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);
 
 
index 8cd0f99904f7f31f764810ce8a03d9e7615f8bf2..a4dd676142370731391ddb74333e256195e6ea90 100644 (file)
--- 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<AbstractInterface *> 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 723e8eb33aaa232fa52ea9144c4f3b72bd02f292..7be35c27523d24f91d2a0534c0f8397620150731 100644 (file)
--- a/Graph.h
+++ b/Graph.h
@@ -21,16 +21,35 @@ public:
   Graph();
   ~Graph();
 
-  QList<AbstractInterface *> 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<GroupBlock*> 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<AbstractInterface *> getOutsideInterfaces();  
+  
+  
 private:  
   GroupBlock* topGroup;
+  QList<GroupBlock *> groups; //! usefull to avoid recursive methods to find a particular group.
+  QList<FunctionalBlock*> sources; //! source for the top group
 
 };
 
index 74ec197086d458f9e7e0ddb3f2033c6aaba1bb8e..e5d3b21f8a2880216365d69d575f2b5824f859e2 100644 (file)
@@ -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<AbstractBlock *> *checkedBlocks, QList<AbstractBlock *> *blocksToConfigure) {
 
   /*
index 5a032368946e548d802f251c91931624d4137f49..e07fd90e312fe15313a4775c173d34eded01fafe 100644 (file)
@@ -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<AbstractBlock *> *checkedBlocks, QList<AbstractBlock*>* blocksToConfigure);  
   void addGenericParameter(QString name, QString type, QString value);
index 5d843811941a6bbd3334858beab637d8f6ac5232..c965452a932cbb99fd288e55d70ace9f575a83e4 100644 (file)
@@ -125,7 +125,7 @@ void GroupItem::updateMinimumSize() {
 
   if (getScene() == NULL) return;
 
-  QList<BoxItem *> blocks = getScene()->getBlockItems();
+  QList<BoxItem *> 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);
index 881180ccc17f00bd0dca72edb5f71502b6f2e2fe..8ab486ad64731b6fcba927e2df692258946171c4 100644 (file)
@@ -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);
index e8c9e842ecb9454925fef709f5d6b6d199cfffd7..b24c39cf48bdcbbbfeab3a956635e1f6395878c6 100644 (file)
@@ -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<BoxItem *> GroupScene::getSelectedBlocks() {
   QList<BoxItem*> lst;
-  foreach(BoxItem *item, blockItems){
+  foreach(BoxItem *item, boxItems){
     if (item->isSelected()){
       lst.append(item);
     }
@@ -55,7 +61,7 @@ QList<BoxItem *> 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<AbstractBoxItem*> GroupScene::getGroupAndBlocks() {
-
-  QList<AbstractBoxItem*> 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<ConnectionItem *> GroupScene::getInterfaceConnections(InterfaceItem *item) {
-  QList<ConnectionItem*> list;
-  foreach(ConnectionItem *conn, connectionItems){
-    if(conn->getFromInterfaceItem() == item || conn->getToInterfaceItem() == item){
-      list.append(conn);
-    }
-  }
-  return list;
-}
-
 void GroupScene::unselecteInterfaces() {
 
   if (selectedInterfaces[0] != NULL) {
@@ -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<BoxItem *> functionalBlocks;
   QList<BoxItem *> groupBlocks;
 
-  foreach(BoxItem *item, blockItems){
+  foreach(BoxItem *item, boxItems){
     if(item->getRefBlock()->isFunctionalBlock()){
       functionalBlocks.append(item);
     } else if(item->getRefBlock()->isGroupBlock()){
index a14ef0b873cc0f3f92db7bf73dc0a4bcc7900e71..19185a1f6787b730929c6a5ebc0a4784bc688485 100644 (file)
@@ -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<BoxItem*> getBlockItems() { return blockItems; }
+  inline QList<BoxItem*> getBoxItems() { return boxItems; }
   inline QList<ConnectionItem*> getConnectionItems() { return connectionItems; }
   inline QList<GroupScene*> 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<AbstractBoxItem*> getGroupAndBlocks();
-  QList<BoxItem *> getSelectedBlocks();
-
-  QList<ConnectionItem *> getInterfaceConnections(InterfaceItem *item);
+  
+  QList<BoxItem *> 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<ConnectionItem*> connectionItems;
-  QList<BoxItem*> blockItems;
-  QList<GroupScene*> childrenScene;
+  GroupItem *groupItem; //! for convenience, the group item is directly accessible via this attribute
+  QList<ConnectionItem*> connectionItems; //! for convenience, connections are directly accessible via this attribute
+  QList<BoxItem*> boxItems; //! for convenience, box items are directly accessible via this attribute
+  QList<SourceItem*> sourceItems; //! for convenience, box items are directly accessible via this attribute. Only usefull for top scene
+  QList<GroupScene*> childrenScene;//! for convenience, children scenes are directly accessible via this attribute
   bool topScene;
   EditMode editMode;
   InterfaceItem* selectedInterfaces[2]; // selected iface 1 in AddConnection mode
index 2ef7cd1884766de657c2083314afef71d3df05d3..0705632c241d51757658fd6768a23567f79e0607 100644 (file)
@@ -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()) {
index 0047e16f5a810aef7e76f06d88f251e40cf15953..ff6329e113039a86eb87e25cee0e5e48a148edd8 100644 (file)
@@ -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());
       }
     }    
index af8eb220462f28523e0584f026633c7300659ba3..001fdc3e0921b568ec2311557d8d96ed2125a60a 100644 (file)
@@ -79,15 +79,6 @@ ReferenceBlock* Parameters::getReferenceBlock(int idCategory, int idBlock) {
 }\r
 \r
 \r
-FunctionalBlock* Parameters::duplicateFunctionalBlock(FunctionalBlock *block) {\r
-\r
-  ReferenceBlock* ref = block->getReference();\r
-  GroupBlock* group = AB_TO_GRP(block->getParent());\r
-\r
-  // adding to the graph\r
-  FunctionalBlock* newBlock = graph->addFunctionalBlock(group,ref);\r
-  return newBlock;\r
-}\r
 \r
 void Parameters::validateXmlFile(const QString& xmlFileName, const QString& xsdFileName, XmlFileType fileType) throw(Exception) {\r
   // opening configFile\r
@@ -269,7 +260,7 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) {
         throw(err);\r
       }\r
       // add the block to the GroupScene\r
-      currentScene->addBlockItem(funcItem);\r
+      currentScene->addBoxItem(funcItem);\r
     }\r
   }\r
   cout << "functional blocks loaded and created succefully!" << endl;\r
@@ -315,7 +306,7 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) {
       BoxItem* upperItem = NULL;\r
       if(insideGroup == NULL) cout << "group null" << endl;\r
       // now search within the scene which BoxItem has a childItem that is = to insideGroup\r
-      QList<BoxItem *> lst = currentScene->getBlockItems();\r
+      QList<BoxItem *> lst = currentScene->getBoxItems();\r
       foreach(BoxItem* item, lst) {\r
         if (item->getChildGroupItem() == insideGroup) {\r
           upperItem = item;\r
@@ -374,7 +365,7 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) {
     InterfaceItem *iface2 = searchInterfaceItemById(to,topScene);\r
 \r
     if(iface1 != NULL && iface2 != NULL){\r
-      dispatcher->connect(iface1,iface2);\r
+      dispatcher->createConnectionItem(iface1,iface2);\r
     } else {\r
       cout << "interfaces not found, connect canceled!" << endl;\r
     }\r
@@ -844,9 +835,9 @@ QList<AbstractBlock *> Parameters::getBlocksToConfigure() {
 \r
 \r
 void Parameters::updateToolbar() {\r
-  int nb = currentScene->getBlockItems().length();\r
+  int nb = currentScene->getBoxItems().length();\r
   for(int i = 0; i<nb; i++){\r
-    if(currentScene->getBlockItems().at(i)->isSelected()){\r
+    if(currentScene->getBoxItems().at(i)->isSelected()){\r
       currentScene->getGroupWidget()->enableGroupButton(true);\r
       return;\r
     }\r
@@ -996,7 +987,7 @@ GroupItem* Parameters::searchGroupItemById(int id, GroupScene *scene) {
 \r
 BoxItem* Parameters::searchBlockItemById(int id, GroupScene *scene) {\r
 \r
-  foreach(BoxItem *item, scene->getBlockItems()){\r
+  foreach(BoxItem *item, scene->getBoxItems()){\r
     if(item->getId() == id){\r
       return item;\r
     }\r
@@ -1017,7 +1008,7 @@ InterfaceItem* Parameters::searchInterfaceItemById(int id, GroupScene* scene) {
       return item;\r
     }\r
   }\r
-  foreach(BoxItem *block, scene->getBlockItems()){\r
+  foreach(BoxItem *block, scene->getBoxItems()){\r
     foreach(InterfaceItem *item, block->getInterfaces()){\r
       if(item->getId() == id){\r
         return item;\r
diff --git a/SourceItem.cpp b/SourceItem.cpp
new file mode 100644 (file)
index 0000000..82a41b0
--- /dev/null
@@ -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)&&(x<boxWidth)) {
+
+      params->cursorState = Parameters::CursorOnBorder;
+
+      if ((y>boxHeight-2*marginS)&&(y<boxHeight)) {
+        currentBorder = CornerSouthEast;
+        setCursor(Qt::SizeFDiagCursor);
+      }
+      else {
+        currentBorder = BorderEast;
+        setCursor(Qt::SizeHorCursor);
+      }
+    }
+    else if ((y>boxHeight-marginS)&&(y<boxHeight)) {
+
+      params->cursorState = Parameters::CursorOnBorder;
+
+      if ((x>boxWidth-2*marginE)&&(x<boxWidth)) {
+        currentBorder = CornerSouthEast;
+        setCursor(Qt::SizeFDiagCursor);
+      }
+      else {
+        currentBorder = BorderSouth;
+        setCursor(Qt::SizeVerCursor);
+      }
+    }
+    else {
+      if ((x>0) && (x<boxWidth-marginE) && (y>0) && (y<boxHeight-marginS)) {
+        params->cursorState = Parameters::CursorInBlock;
+        setCursor(Qt::OpenHandCursor);
+      }
+      else {
+        params->cursorState = Parameters::CursorNowhere;
+        setCursor(Qt::ArrowCursor);
+      }
+    }
+  }
+  QGraphicsItem::hoverMoveEvent(event);
+}
+
+
+void SourceItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
+
+  event->accept();
+
+  QMenu menu;
+  QAction* titleAction = NULL;
+  QAction* removeAction = NULL;
+  QAction* duplicateAction = NULL;
+  QAction* renameAction = NULL;
+  QAction* showProperties = NULL;
+  QAction* showParameters = NULL;
+
+
+  InterfaceItem* ifaceItem = getInterfaceFromCursor(event->pos().x(), event->pos().y());
+  // menu for interface
+  if( ifaceItem != NULL){
+
+    titleAction = menu.addAction("Interface operations");
+    titleAction->setEnabled(false);
+    menu.addSeparator();
+
+
+    showProperties = menu.addAction("Show properties");
+    renameAction = menu.addAction("Rename");
+
+  }
+  // menu for block
+  else {
+    titleAction = menu.addAction("Block operations");
+    titleAction->setEnabled(false);
+    menu.addSeparator();
+
+    if (refBlock->nbParameters() > 0) {
+      showParameters = menu.addAction("Show parameters");
+    }
+    renameAction = menu.addAction("Rename");
+
+    duplicateAction = menu.addAction("Duplicate");
+    removeAction = menu.addAction("Remove");
+  }
+
+  QAction* selectedAction = NULL;
+  selectedAction = menu.exec(event->screenPos());
+
+  if(selectedAction == NULL) return ;
+
+  if (selectedAction == removeAction) {    
+    dispatcher->removeSourceItem(this);    
+  }
+  else if (selectedAction == duplicateAction) {
+    dispatcher->duplicateSourceItem(this);
+  }
+  else if(selectedAction == renameAction){
+    if(ifaceItem != NULL) {
+      dispatcher->renameInterface(ifaceItem);
+    }
+    else {      
+      dispatcher->renameSourceBlock(this);      
+    }   
+  }
+  else if(selectedAction == showProperties){
+    dispatcher->showProperties(ifaceItem);
+  }  
+  else if(selectedAction == showParameters){
+    new ParametersWindow(refBlock, params, NULL);
+  }      
+}
+
+void SourceItem::load(QDomElement funcElement) throw(Exception) {
+
+  bool ok = false;
+
+  int id = funcElement.attribute("id","none").toInt(&ok);
+  if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+  QString refXml = funcElement.attribute("ref_xml","none");
+  if(refXml == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+  QString refMd5 = funcElement.attribute("ref_md5","none");
+  if(refMd5 == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+  cout << "ref md5 : " << refMd5.toStdString() << "\nref xml : " << refXml.toStdString() << endl;
+
+  QString name = funcElement.attribute("name","none");
+  if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+  QStringList positionStr = funcElement.attribute("position","none").split(",");
+  if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
+  int posX = positionStr.at(0).toInt(&ok);
+  if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+  int posY = positionStr.at(1).toInt(&ok);
+  if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+  QStringList dimensionStr = funcElement.attribute("dimension","none").split(",");
+  if(dimensionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
+  int dimX = dimensionStr.at(0).toInt(&ok);
+  if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+  int dimY = dimensionStr.at(1).toInt(&ok);
+  if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+  
+  ReferenceBlock *referenceMd5 = NULL;
+  ReferenceBlock *referenceXml = NULL;
+  ReferenceBlock *reference = NULL;
+  if(refMd5 != "none") {
+    referenceMd5 = params->searchBlockByMd5(refMd5);
+  }
+  if(refXml != "none"){
+    referenceXml = params->searchBlockByXml(refXml);
+  }
+  if ((referenceMd5 == NULL) && (referenceXml == NULL)) {
+    throw(Exception(PROJECTFILE_CORRUPTED));
+  }
+  if (referenceMd5 != referenceXml) {
+    throw(Exception(PROJECTFILE_CORRUPTED));
+  }
+  else {
+    reference = referenceMd5;
+  }
+  
+  GroupBlock* parentGroupBlock = AB_TO_GRP(((GroupItem *)parentItem())->getRefBlock());
+  FunctionalBlock* functionalBlock = params->getGraph()->createFunctionalBlock(parentGroupBlock, reference);
+  /* NB: addFunctionalBlock creates all interfaces from the reference, which is annoying when
+    reading bif_iface tags. Thus interface are all removed.
+  */
+  functionalBlock->setName(name);
+  setRefBlock(functionalBlock);
+
+  setPos(posX,posY);
+  setDimension(dimX,dimY);
+  setId(id);
+
+
+  QDomNodeList blockParamNodes = funcElement.elementsByTagName("bif_parameter");
+  // setting parameters value
+  for(int i=0; i<blockParamNodes.length(); i++){
+    QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement();
+
+    QString name = currentBlockParamNode.attribute("name","none");
+    if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+    QString value = currentBlockParamNode.attribute("value","none");
+    if(value == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+    BlockParameter *blockParam = NULL;
+    blockParam = functionalBlock->getParameterFromName(name);
+    if (blockParam == NULL) throw(Exception(PROJECTFILE_CORRUPTED));
+    blockParam->setValue(value);
+  }  
+
+  // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars
+  functionalBlock->removeAllInterfaces();
+  QDomNodeList interfaceNodes = funcElement.elementsByTagName("bif_iface");
+  // setting interfaces (user name, and for multiplicity>1 may be create some new ones)
+  for(int i=0; i<interfaceNodes.length(); i++) {
+
+    QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
+
+    QString name = currentInterfaceNode.attribute("name","none");
+    if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+    QString refName = currentInterfaceNode.attribute("ref_name","none");
+    if(refName == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+    ReferenceInterface* refInter = AI_TO_REF(reference->getIfaceFromName(refName));
+    cout << "creating iface from reference named " << qPrintable(refName) << endl;
+    FunctionalInterface *functionalInterface = new FunctionalInterface(functionalBlock,refInter);
+    functionalInterface->setName(name);
+    functionalBlock->addInterface(functionalInterface);
+    
+    // searching for control interface
+    QString ctlRefName = refName+"_ctl";
+    ReferenceInterface* ctlRefIface = AI_TO_REF(reference->getIfaceFromName(ctlRefName));
+    
+    if (ctlRefIface != NULL) {
+      cout << "found a control iface:" << qPrintable(ctlRefName) << endl;
+      FunctionalInterface *ctlIface = new FunctionalInterface(functionalBlock,ctlRefIface);      
+      if (! ctlIface->setAssociatedIface(functionalInterface)) {
+        throw(Exception(PROJECTFILE_CORRUPTED));
+      }      
+      ctlIface->setName(name+"_ctl");
+      functionalBlock->addInterface(ctlIface);
+    }    
+  }
+  
+  // creating InterfaceItem
+  initInterfaces();
+  // setting them with saved values
+  for(int i=0; i<interfaceNodes.length(); i++){
+
+    QDomElement currentInterfaceNode = interfaceNodes.at(i).toElement();
+
+    int id = currentInterfaceNode.attribute("id","none").toInt(&ok);
+    if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+    QString name = currentInterfaceNode.attribute("name","none");
+    if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+
+    QString orientationStr = currentInterfaceNode.attribute("orientation","none");
+    int orientation = InterfaceItem::getIntOrientation(orientationStr);
+    if(orientation == -1) throw(Exception(PROJECTFILE_CORRUPTED));
+
+    double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);
+    if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
+
+    InterfaceItem *interfaceItem = searchInterfaceByName(name);
+    interfaceItem->setId(id);
+    interfaceItem->setOrientation(orientation);
+    interfaceItem->setPositionRatio(position);
+  }
+  updateGeometry(Resize);
+}
+
+void SourceItem::save(QXmlStreamWriter &writer) {
+  
+  writer.writeStartElement("source_item");
+  
+  writer.writeAttribute("id",QString::number(id));
+  writer.writeAttribute("ref_xml", ((FunctionalBlock*)refBlock)->getReferenceXmlFile());
+  writer.writeAttribute("ref_md5", ((FunctionalBlock*)refBlock)->getReferenceHashMd5());
+  writer.writeAttribute("name",refBlock->getName());
+  QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
+  writer.writeAttribute("position",attrPos);
+  QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
+  writer.writeAttribute("dimension",attrDim);
+  
+  writer.writeStartElement("source_parameters");
+  foreach(BlockParameter *param,refBlock->getParameters()){
+    writer.writeStartElement("source_parameter");
+    
+    writer.writeAttribute("name",param->getName());
+    writer.writeAttribute("value",param->getValue().toString());
+    /*
+      writer.writeAttribute("context",param->getStrContext());
+      writer.writeAttribute("type",param->getTypeString());
+      */
+    writer.writeEndElement();   //</source_parameter>
+  }
+  writer.writeEndElement();   //</source_parameters>
+  
+  writer.writeStartElement("source_ifaces");
+  writer.writeAttribute("count",QString::number(interfaces.length()));
+  foreach(InterfaceItem* inter, interfaces){
+    writer.writeStartElement("source_iface");
+    
+    writer.writeAttribute("id",QString::number(inter->getId()));
+    writer.writeAttribute("name",inter->getName());
+    writer.writeAttribute("ref_name",inter->refInter->getName());
+    writer.writeAttribute("orientation",inter->getStrOrientation());
+    writer.writeAttribute("position",QString::number(inter->getPositionRatio()));
+    
+    writer.writeEndElement();   //</source_iface>
+  }
+  writer.writeEndElement();   //</source_ifaces>
+  
+  writer.writeEndElement();   //</source_item>
+  
+}
diff --git a/SourceItem.h b/SourceItem.h
new file mode 100644 (file)
index 0000000..72ebede
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef __SOURCEITEM_H__
+#define __SOURCEITEM_H__
+
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtXml>
+#include <QtXmlPatterns>
+
+
+#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__
index 51f5a11003127ff8adaf38bc5e87e4b28ef67021..9f8479e10fe0e6b3901a65e752fd826c729e482b 100755 (executable)
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 3.2.1, 2017-05-08T20:46:10. -->
+<!-- Written by QtCreator 3.2.1, 2017-05-09T19:54:54. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>
-  <value type="QByteArray">{c8006d66-d34f-42be-ad10-d0207752286d}</value>
+  <value type="QByteArray">{1d077e47-e3a1-47fd-8b12-4de650e39df5}</value>
  </data>
  <data>
   <variable>ProjectExplorer.Project.ActiveTarget</variable>
   <valuemap type="QVariantMap">
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
-   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{2c9bf876-3476-44eb-8065-1f0844704dda}</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{451ee8a3-56ff-4aba-8a8e-3da882cc142e}</value>
    <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
    <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
    <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
-    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/sdomas/Projet/Blast/code/blast</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/localhome/sdomas/Projet/Blast/code/blast</value>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
       <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
index 7b2dd43dc8a56caae87e4875ffcbc732077c1467..3975c5fbba1463b07c7547c715b66c8c298496aa 100755 (executable)
@@ -29,6 +29,8 @@ BlockLibraryWidget.h
 blast.cpp
 BlockCategory.cpp
 BlockCategory.h
+SourceItem.cpp
+SourceItem.h
 BoxItem.cpp
 BoxItem.h
 BlockLibraryTree.cpp
index f827695ee8a3d418ef9c2156520a19d188fd0323..bc2d2bcce346bc4bdc04cd3f81041ca5df4b3470 100644 (file)
@@ -7,8 +7,8 @@
     <category name="arithmetics" id="3" parent="1"/>
     <category name="filters" id="4" parent="0"/>
     <category name="wishbone" id="5" parent="0"/>
-    <category name="sources" id="6" parent="0"/>
-    <category name="scopes" id="7" parent="0"/>
+    <category name="generators" id="6" parent="0"/>
+    <category name="observers" id="7" parent="0"/>
     <category name="user" id="8" parent="0"/>    
   </categories>
 
index 66b4efeca106b928c4db56993e77f2055a2238e1..432ac5d4306e7bace654a8404fe6dbeb74199ac6 100644 (file)
Binary files a/lib/references/references.bmf and b/lib/references/references.bmf differ
index 806c34661bbef98a3898ff1997602e32650575fd..704e9218b1acfba300052bdb364533714be52ea2 100644 (file)
@@ -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 \