Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / gui / YACSGui_Node.cxx
index 4e2bc5e2e6f63e590dc2253b5cb0e5c7b55a9837..cbe45d536b85e5f73b83129949892989b726be06 100644 (file)
@@ -18,6 +18,9 @@
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
+#include <Python.h>
+#include <PythonNode.hxx>
+
 #include <YACSGui_Node.h>
 #include <YACSGui_Graph.h>
 
 #include <ComposedNode.hxx>
 #include <Bloc.hxx>
 #include <Proc.hxx>
+#include <guiObservers.hxx>
+#include <CORBANode.hxx>
+#include <CppNode.hxx>
+#include <SalomePythonNode.hxx>
+#include <XMLNode.hxx>
+#include <Switch.hxx>
+#include <ForLoop.hxx>
+#include <WhileLoop.hxx>
+//#include <OptimizerLoop.hxx>
+#include <ForEachLoop.hxx>
 
 #include <QxGraph_Canvas.h>
 #include <QxGraph_Prs.h>
 #include <SUIT_ResourceMgr.h>
 #include <SUIT_Session.h>
 
+//#define _DEVDEBUG_
+#include "YacsTrace.hxx"
+
+using namespace YACS::ENGINE;
+using namespace YACS::HMI;
+
 /*!
  * =========================== YACSGui_Node ===========================
  !*/
@@ -71,7 +90,9 @@ SUIT_ResourceMgr* YACSGui_Node::resMgr() const
  *  New graphic items should be created with a null canvas pointer.
  *  They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide().
  */
-void YACSGui_Node::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem )
+void YACSGui_Node::update(YACS::ENGINE::Node* theEngine, 
+                         YACS::HMI::SubjectComposedNode* theParent, 
+                         YACSPrs_ElementaryNode*& theItem )
 {
   if ( !myGraph )
     return;
@@ -107,14 +128,22 @@ YACSGui_ServiceNode::~YACSGui_ServiceNode()
  *  New graphic items should be created with a null canvas pointer.
  *  They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide().
  */
-void YACSGui_ServiceNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem )
+void YACSGui_ServiceNode::update(YACS::ENGINE::Node* theEngine, 
+                                YACS::HMI::SubjectComposedNode* theParent,
+                                YACSPrs_ElementaryNode*& theItem )
 {
+  DEBTRACE("YACSGui_ServiceNode::update " << theItem);
   if ( !graph() )
     return;
 
   if ( !theItem ) {
-    theItem = new YACSPrs_ServiceNode( resMgr(), 0, theEngine);
-    graph()->registerStatusObserverWithNode(theEngine);
+    SubjectNode* aSNode = theParent->getChild(theEngine);
+    DEBTRACE(aSNode);
+    if ( aSNode )
+    {
+      theItem = new YACSPrs_ServiceNode( resMgr(), graph()->getCanvas(), aSNode );
+      graph()->registerStatusObserverWithNode(theEngine);
+    }
   }
   else
   {
@@ -147,14 +176,20 @@ YACSGui_InlineNode::~YACSGui_InlineNode()
  *  New graphic items should be created with a null canvas pointer.
  *  They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide().
  */
-void YACSGui_InlineNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem )
+void YACSGui_InlineNode::update(YACS::ENGINE::Node* theEngine,
+                               YACS::HMI::SubjectComposedNode* theParent,
+                               YACSPrs_ElementaryNode*& theItem )
 {
   if ( !graph() )
     return;
 
   if ( !theItem ) {
-    theItem = new YACSPrs_InlineNode( resMgr(), 0, theEngine);
-    graph()->registerStatusObserverWithNode(theEngine);
+    SubjectNode* aINode = theParent->getChild(theEngine);
+    if ( aINode )
+    {
+      theItem = new YACSPrs_InlineNode( resMgr(), graph()->getCanvas(), aINode );
+      graph()->registerStatusObserverWithNode(theEngine);
+    }
   }
   else
   {
@@ -187,14 +222,21 @@ YACSGui_IfNode::~YACSGui_IfNode()
  *  New graphic items should be created with a null canvas pointer.
  *  They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide().
  */
-void YACSGui_IfNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem )
+void YACSGui_IfNode::update(YACS::ENGINE::Node* theEngine,
+                           YACS::HMI::SubjectComposedNode* theParent,
+                           YACSPrs_ElementaryNode*& theItem )
 {
   if ( !graph() )
     return;
 
   if ( !theItem ) {
-    theItem = new YACSPrs_IfNode( resMgr(), 0, theEngine);
-    graph()->registerStatusObserverWithNode(theEngine);
+    SubjectComposedNode* aCNode = dynamic_cast<SubjectComposedNode*>( theParent->getChild(theEngine) );
+    if ( aCNode )
+    {
+      theItem = new YACSPrs_IfNode( resMgr(), graph()->getCanvas(), aCNode );
+      graph()->registerStatusObserverWithNode(theEngine);
+      graph()->createChildNodesPresentations( aCNode );
+    }
   }
   else
   {
@@ -227,14 +269,22 @@ YACSGui_SwitchNode::~YACSGui_SwitchNode()
  *  New graphic items should be created with a null canvas pointer.
  *  They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide().
  */
-void YACSGui_SwitchNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem )
+void YACSGui_SwitchNode::update(YACS::ENGINE::Node* theEngine,
+                               YACS::HMI::SubjectComposedNode* theParent,
+                               YACSPrs_ElementaryNode*& theItem )
 {
   if ( !graph() )
     return;
 
   if ( !theItem ) {
-    theItem = new YACSPrs_SwitchNode( resMgr(), 0, theEngine);
-    graph()->registerStatusObserverWithNode(theEngine);
+    SubjectSwitch* aSNode = dynamic_cast<SubjectSwitch*>( theParent->getChild(theEngine) );
+    if ( aSNode )
+    {
+      theItem = new YACSPrs_SwitchNode( resMgr(), graph()->getCanvas(), aSNode );
+      graph()->registerStatusObserverWithNode(theEngine);
+      graph()->createChildNodesPresentations( aSNode );
+      aSNode->attach( graph() );
+    }
   }
   else
   {
@@ -267,14 +317,22 @@ YACSGui_LoopNode::~YACSGui_LoopNode()
  *  New graphic items should be created with a null canvas pointer.
  *  They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide().
  */
-void YACSGui_LoopNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem )
+void YACSGui_LoopNode::update(YACS::ENGINE::Node* theEngine,
+                             YACS::HMI::SubjectComposedNode* theParent,
+                             YACSPrs_ElementaryNode*& theItem )
 {
   if ( !graph() )
     return;
 
   if ( !theItem ) {
-    theItem = new YACSPrs_LoopNode( resMgr(), 0, theEngine);
-    graph()->registerStatusObserverWithNode(theEngine);
+    SubjectComposedNode* aLNode = dynamic_cast<SubjectComposedNode*>( theParent->getChild(theEngine) );
+    if ( aLNode )
+    {
+      theItem = new YACSPrs_LoopNode( resMgr(), graph()->getCanvas(), aLNode );
+      graph()->registerStatusObserverWithNode(theEngine);
+      graph()->createChildNodesPresentations( aLNode );
+      aLNode->attach( graph() );
+    }
   }
   else
   {
@@ -307,14 +365,22 @@ YACSGui_ForEachLoopNode::~YACSGui_ForEachLoopNode()
  *  New graphic items should be created with a null canvas pointer.
  *  They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide().
  */
-void YACSGui_ForEachLoopNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem )
+void YACSGui_ForEachLoopNode::update(YACS::ENGINE::Node* theEngine,
+                                    YACS::HMI::SubjectComposedNode* theParent,
+                                    YACSPrs_ElementaryNode*& theItem )
 {
   if ( !graph() )
     return;
 
   if ( !theItem ) {
-    theItem = new YACSPrs_ForEachLoopNode( resMgr(), 0, theEngine);
-    graph()->registerStatusObserverWithNode(theEngine);
+    SubjectComposedNode* aFELNode = dynamic_cast<SubjectComposedNode*>( theParent->getChild(theEngine) );
+    if ( aFELNode )
+    {
+      theItem = new YACSPrs_ForEachLoopNode( resMgr(), graph()->getCanvas(), aFELNode );
+      graph()->registerStatusObserverWithNode(theEngine);
+      graph()->createChildNodesPresentations( aFELNode );
+      aFELNode->attach( graph() );
+    }
   }
   else
   {
@@ -347,38 +413,112 @@ YACSGui_BlocNode::~YACSGui_BlocNode()
  *  New graphic items should be created with a null canvas pointer.
  *  They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide().
  */
-void YACSGui_BlocNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem )
+void YACSGui_BlocNode::update(YACS::ENGINE::Node* theEngine,
+                             YACS::HMI::SubjectComposedNode* theParent,
+                             YACSPrs_ElementaryNode*& theItem )
 {
+  DEBTRACE("YACSGui_BlocNode::update");
   if ( !graph() )
     return;
 
   if ( !theItem )
   {
-    YACSPrs_BlocNode* aBlocPrs = new YACSPrs_BlocNode( resMgr(), 0, theEngine,
-                                                      YACSPrs_BlocNode::Expanded, level(theEngine) );
+    DEBTRACE("YACSGui_BlocNode::update");
     YACS::ENGINE::Bloc* aBloc = dynamic_cast<YACS::ENGINE::Bloc*>( theEngine );
     if ( aBloc )
     {
+      SubjectBloc* aBNode = dynamic_cast<SubjectBloc*>( theParent->getChild(theEngine) );
+      if ( aBNode )
+      {
+       // create children presentations (and, of course, subjects)
+       graph()->createChildNodesPresentations( aBNode );
+
+       // collect created children presentations in the list
+       std::set<YACSPrs_ElementaryNode*> aNodePrsSet;
+       std::set<YACS::ENGINE::Node*> aNodeSet;
+       graph()->getAllBlocChildren(aBloc, aNodeSet);
+       for ( std::set<YACS::ENGINE::Node*>::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ )
+         if ( graph()->getItem( *it ) )
+           aNodePrsSet.insert( graph()->getItem( *it ) );
+       
+       YACSPrs_BlocNode* aBlocPrs = new YACSPrs_BlocNode( resMgr(), graph()->getCanvas(),
+                                                          aBNode,
+                                                          YACSPrs_BlocNode::Expanded,
+                                                          level(theEngine) );
+       aBlocPrs->setChildren( aNodePrsSet );
+       
+       theItem = aBlocPrs;
+       
+       graph()->registerStatusObserverWithNode(theEngine);
+       aBNode->attach( graph() );
+      }
+    }
+  }
+  else
+  {
+    // TODO - Here any parameters of exisiting items should be updated
+    // ...
+
+    // NB: this case is actual if the content of the block node (i.e. the set of child nodes) was changed
+    YACSPrs_BlocNode* aBlocPrs = dynamic_cast<YACSPrs_BlocNode*>( theItem );
+    YACS::ENGINE::Bloc* aBloc = dynamic_cast<YACS::ENGINE::Bloc*>( theEngine );
+    DEBTRACE("YACSGui_BlocNode::update "<< aBlocPrs <<","<< aBloc);
+    if ( aBlocPrs && aBloc )
+    {
+      // get old set of children: make it independent from the block
+      std::set<YACSPrs_ElementaryNode*> anOldChildren = aBlocPrs->getChildren();
+      DEBTRACE(anOldChildren.size());
+      for ( std::set<YACSPrs_ElementaryNode*>::iterator it = anOldChildren.begin(); it != anOldChildren.end(); it++ )
+      {
+        DEBTRACE(*it);
+       (*it)->setIsInBloc(false);
+       (*it)->setSelfMoving(true);
+      }
+      
+      // collect presentations of the new children in the list: set new children list to the block
       std::set<YACSPrs_ElementaryNode*> aNodePrsSet;
       std::set<YACS::ENGINE::Node*> aNodeSet;
       graph()->getAllBlocChildren(aBloc, aNodeSet);
+      DEBTRACE(aNodeSet.size());
       for ( std::set<YACS::ENGINE::Node*>::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ )
+       if ( graph()->getItem( *it ) )
+         aNodePrsSet.insert( graph()->getItem( *it ) );
+      
+      DEBTRACE(aNodePrsSet.size());
+      aBlocPrs->setChildren( aNodePrsSet );
+
+      // remove control links of the new children
+      for ( std::set<YACSPrs_ElementaryNode*>::iterator childIt = aNodePrsSet.begin(); childIt != aNodePrsSet.end(); childIt++ )
+      {  
+       YACSPrs_ElementaryNode* aPrs = *childIt;
+       if( anOldChildren.count( aPrs ) )
+         continue;
+       std::list<SubjectControlLink*> aControlLinks = aPrs->getSEngine()->getSubjectControlLinks();
+       for( std::list<SubjectControlLink*>::iterator iter = aControlLinks.begin(); iter != aControlLinks.end(); iter++ )
+       {
+         SubjectControlLink* aControlLink = *iter;
+         if( SubjectNode* anOutNode = aControlLink->getSubjectOutNode() )
+           if( YACSPrs_ElementaryNode* aParentPrs = graph()->getItem( anOutNode->getNode() ) )
+             aParentPrs->removeLinkPrs( aControlLink );
+       }
+      }
+
+      Bloc* aFather = aBloc;
+      bool isNeedToArrange = true;
+      if ( !anOldChildren.empty() || aNodeSet.empty() )
+       isNeedToArrange = graph()->isNeededToIncreaseBlocSize(aFather);
+      while ( isNeedToArrange && aFather && !dynamic_cast<Proc*>(aFather) )
       {
-       if ( !graph()->getItem( *it ) ) graph()->update( *it );
-       aNodePrsSet.insert( graph()->getItem( *it ) );
+       graph()->arrangeNodesWithinBloc(aFather);
+       aFather = dynamic_cast<Bloc*>(aFather->getFather());
+       isNeedToArrange = graph()->isNeededToIncreaseBlocSize(aFather);
       }
-      aBlocPrs->setChildren( aNodePrsSet );
+      graph()->getCanvas()->update();
 
       theItem = aBlocPrs;
-
-      graph()->registerStatusObserverWithNode(theEngine);
     }
-  }
-  else
-  {
-    // TODO - Here any parameters of exisiting items should be updated
-    // ...
-    theItem->update();
+    
+    //theItem->update();
   }
 }