Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_Service.cxx
index e43928e2510955a3da6f7cafe3392f6c2363fe57..9d9c9d27d673c1f7401c3e4f1f88b1571ab627a3 100644 (file)
@@ -17,7 +17,7 @@
 //  License along with this library; if not, write to the Free Software 
 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
 // 
-//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 //
 //
 //  Author : Francis KLOSS
 //  Module : SUPERV
 
-using namespace std;
 #include "SUPERVGUI_Service.h"
 #include "SUPERVGUI_Main.h"
+#include "SUPERVGUI_Library.h"
 #include "SUPERVGUI.h"
-#include "QAD_Tools.h"
-#include "QAD_FileDlg.h"
+
+#include "CAM_Application.h"
+#include "SUIT_Desktop.h"
+#include "SUIT_FileDlg.h"
+#include "SUIT_Session.h"
+#include "SUIT_Tools.h"
 
 #include "SALOME_NamingService.hxx"
 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
+#include <qlabel.h>
 #include <qlayout.h>
+#include <qhbox.h>
 #include <qtextstream.h>
-
+#include <qregexp.h>
 
 static const char * ComponentIcon[] = {
 "20 20 2 1",
@@ -93,7 +99,7 @@ static const char * InterfaceIcon[] = {
 
 
 SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns):
-    QDialog(QAD_Application::getDesktop(), 0, false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
+    QDialog(SUIT_Session::session()->activeApplication()->desktop(), 0, false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
     naming(ns), myMFile(0)
 {
   setSizeGripEnabled( true );
@@ -111,6 +117,8 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns):
   aBaseLayoutV->setSpacing(10);
 
   QHBoxLayout* aBaseLayout = new QHBoxLayout(aCorbaPane); //!!
+  aBaseLayout->setMargin(5);
+  aBaseLayout->setSpacing(10);
  
   components = new QListView(aCorbaPane);
   components->addColumn(tr("COL_COMPONENTS"));
@@ -121,6 +129,7 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns):
   components->setColumnAlignment(3, AlignLeft);
   components->setSelectionMode(QListView::Extended);
   components->setRootIsDecorated(true);
+
 //  aBaseLayout->addWidget(components);
   aBaseLayoutV->addWidget(components); //!!
 
@@ -131,11 +140,16 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns):
 //NRI   connect(aComputeCBtn, SIGNAL(clicked()), this, SLOT(addComputeNode())); //!!
 //NRI   aComputeCBtn->setDefault(false); 
 
-  QPushButton* aComputeBtn = new QPushButton(tr("TIT_ADDFNODE"), aCorbaPane);
-  connect(aComputeBtn, SIGNAL(clicked()), this, SLOT(addFactoryNode()));
-  aComputeBtn->setDefault(true); 
+  QPushButton* aComputeBtnDef = new QPushButton(tr("TIT_ADDFNODE"), aCorbaPane);
+  connect(aComputeBtnDef, SIGNAL(clicked()), this, SLOT(addFactoryNodeDef()));
+  aComputeBtnDef->setDefault(true); 
 
-  aBaseLayout->addWidget(aComputeBtn);
+  QPushButton* aComputeBtnCust = new QPushButton(tr("TIT_ADDFNODE_CUST"), aCorbaPane);
+  connect(aComputeBtnCust, SIGNAL(clicked()), this, SLOT(addFactoryNodeCust()));
+  aComputeBtnCust->setDefault(true); 
+
+  aBaseLayout->addWidget(aComputeBtnDef);
+  aBaseLayout->addWidget(aComputeBtnCust);
   //NRI  aBaseLayout->addWidget(aComputeCBtn); //!!
 
   aBaseLayoutV->insertLayout(-1, aBaseLayout);
@@ -155,11 +169,10 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns):
   /*QLabel* aTypeLbl = */new QLabel(tr("LBL_NODETYPE"), aAddBox2);
 
   myTypeCombo = new QComboBox(aAddBox2);
-  myTypeCombo->insertItem("Computation");
-  myTypeCombo->insertItem("Switch");
-  myTypeCombo->insertItem("Loop");
-  myTypeCombo->insertItem("GoTo");
-  //myTypeCombo->insertItem("Label");
+  myTypeCombo->insertItem( tr( "INLINE_COMP" ) );
+  myTypeCombo->insertItem( tr( "INLINE_SWTC" ) );
+  myTypeCombo->insertItem( tr( "INLINE_LOOP" ) );
+  myTypeCombo->insertItem( tr( "INLINE_GOTO") );
   connect(myTypeCombo, SIGNAL(activated(int)), this, SLOT(typeNodeSelected(int)));
 
   aPythonLayout->addWidget(aAddBox2);
@@ -168,18 +181,18 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns):
   myStackWidget = new QWidgetStack(aPythonPane);
 
   // other pane
-  myScriptPane = new SUPERVGUI_PythonEditPane(myStackWidget);
+  myScriptPane = new SUPERVGUI_PythonEditPane( myStackWidget, true, myX, myY );
   myOtherId = myStackWidget->addWidget(myScriptPane);
 
   // loop pane
   QTabWidget* aLoopTabPane = new QTabWidget(myStackWidget);
-  myInitPane = new SUPERVGUI_PythonEditPane(myStackWidget); 
+  myInitPane = new SUPERVGUI_PythonEditPane( myStackWidget, true, myX, myY ); 
   aLoopTabPane->addTab(myInitPane, "Init");
 
-  myMorePane = new SUPERVGUI_PythonEditPane(myStackWidget);
+  myMorePane = new SUPERVGUI_PythonEditPane( myStackWidget, true, myX, myY );
   aLoopTabPane->addTab(myMorePane, "More");
 
-  myNextPane = new SUPERVGUI_PythonEditPane(myStackWidget);
+  myNextPane = new SUPERVGUI_PythonEditPane( myStackWidget, true, myX, myY );
   aLoopTabPane->addTab(myNextPane, "Next");
   myLoopId = myStackWidget->addWidget(aLoopTabPane);
 
@@ -195,43 +208,42 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns):
   myTabPane->addTab(aPythonPane, tr("INLINE_PANE"));
 
   // Create Tab for Macro node only if environmental variable ENABLE_MACRO_NODE is set
-       if ( getenv( "ENABLE_MACRO_NODE" ) != NULL )
-       {
-       QWidget* aMacroPane = new QWidget(myTabPane);
-       QVBoxLayout* aMacroLayout = new QVBoxLayout(aMacroPane, 0, 4);
-       aMacroLayout->setMargin(5);
-       aMacroLayout->setSpacing(10);
-
-       QHBoxLayout* aLoadLayout = new QHBoxLayout(aMacroPane); //!!
-       aLoadLayout->addStretch();
-
-       QPushButton* aLoadBtn = new QPushButton(tr("BUT_LOAD"), aMacroPane);
-       connect(aLoadBtn, SIGNAL(clicked()), this, SLOT(loadGraph()));
+  if ( getenv( "ENABLE_MACRO_NODE" ) != NULL ) {
+    QWidget* aMacroPane = new QWidget(myTabPane);
+    QVBoxLayout* aMacroLayout = new QVBoxLayout(aMacroPane, 0, 4);
+    aMacroLayout->setMargin(5);
+    aMacroLayout->setSpacing(10);
+    
+    QHBoxLayout* aLoadLayout = new QHBoxLayout(aMacroPane); //!!
+    aLoadLayout->addStretch();
+    
+    QPushButton* aLoadBtn = new QPushButton(tr("BUT_LOAD"), aMacroPane);
+    connect(aLoadBtn, SIGNAL(clicked()), this, SLOT(loadGraph()));
 
-       aLoadLayout->addWidget(aLoadBtn);
+    aLoadLayout->addWidget(aLoadBtn);
 
-       aMacroLayout->addLayout(aLoadLayout);
+    aMacroLayout->addLayout(aLoadLayout);
  
-       myMacroPane = new QListView(aMacroPane);
-       myMacroPane->addColumn(tr("COL_COMPONENTS"));
-       myMacroPane->addColumn(tr("COL_PORTTYPE"));
-       myMacroPane->addColumn(tr("COL_PORTWAY"));
-       myMacroPane->setColumnAlignment(1, AlignLeft);
-       myMacroPane->setColumnAlignment(2, AlignLeft);
-       myMacroPane->setColumnAlignment(3, AlignLeft);
-       myMacroPane->setSelectionMode(QListView::Extended);
-       myMacroPane->setRootIsDecorated(true);
-       aMacroLayout->addWidget(myMacroPane); //!!
-
-       QPushButton* aAddBtn = new QPushButton(tr("TIT_ADDFNODE"), aMacroPane);
-       connect(aAddBtn, SIGNAL(clicked()), this, SLOT(addMacroNode()));
-       aAddBtn->setDefault(true); 
-
-       aMacroLayout->addWidget(aAddBtn);
-
-       myTabPane->addTab(aMacroPane, tr("MACRO_PANE"));
-       }
+    myMacroPane = new QListView(aMacroPane);
+    myMacroPane->addColumn(tr("COL_COMPONENTS"));
+    myMacroPane->addColumn(tr("COL_PORTTYPE"));
+    myMacroPane->addColumn(tr("COL_PORTWAY"));
+    myMacroPane->setColumnAlignment(1, AlignLeft);
+    myMacroPane->setColumnAlignment(2, AlignLeft);
+    myMacroPane->setColumnAlignment(3, AlignLeft);
+    myMacroPane->setSelectionMode(QListView::Extended);
+    myMacroPane->setRootIsDecorated(true);
+    aMacroLayout->addWidget(myMacroPane); //!!
+    
+    QPushButton* aAddBtn = new QPushButton(tr("TIT_ADDFNODE"), aMacroPane);
+    connect(aAddBtn, SIGNAL(clicked()), this, SLOT(addMacroNode()));
+    aAddBtn->setDefault(true); 
+    
+    aMacroLayout->addWidget(aAddBtn);
 
+    myTabPane->addTab(aMacroPane, tr("MACRO_PANE"));
+  }
+  
   aMainLayout->addWidget(myTabPane);
 
   // Close button
@@ -251,22 +263,22 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns):
 }
 
 
-char* getDataStreamParameterName(int aType)
+char* getDataStreamParameterName(const char * aType)
 {
-  switch(aType) {
-  case 1:
+  QString type (aType);
+
+  if (aType == "int") // 1
     return "integer";
-  case 2:
+  if (aType == "float") // 2
     return "float";
-  case 3:
+  if (aType == "double") // 3
     return "double";
-  case 4:
+  if (aType == "string") // 4
     return "string";
-  case 6:
+  if (aType == "bool") // 6 ??
     return "boolean";
-  default:
-    return "unknown";
-  }
+
+  return "unknown";
 }
 
 void SUPERVGUI_Service::initialise() {
@@ -278,7 +290,7 @@ void SUPERVGUI_Service::initialise() {
     return;
   }
   
-  QAD_ResourceMgr* aResMgr = QAD_Desktop::createResourceManager();
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
 
   SALOME_ModuleCatalog::ListOfComponents_var lComponents = (*aModuleCatalog)->GetComponentList();
   long nbComp = lComponents->length();
@@ -288,10 +300,9 @@ void SUPERVGUI_Service::initialise() {
     myComponentItem->setSelectable(false);
     QString aIconName = C->component_icone();
     if (!aIconName.isEmpty()) {
-      QString resDir = aResMgr->findFile(aIconName, C->componentname()) ;
-      if (resDir) {
-       resDir = QAD_Tools::addSlash(resDir);
-       QPixmap aIcone(resDir + aIconName);
+      QString resFilePath = aResMgr->path(aResMgr->resSection(), C->componentname(), aIconName) ;
+      if ( resFilePath ) {
+       QPixmap aIcone(resFilePath);
        QIconSet aIconSet(aIcone);
        myComponentItem->setPixmap(0, aIconSet.pixmap(QIconSet::Small, QIconSet::Normal));
       } else {
@@ -313,7 +324,7 @@ void SUPERVGUI_Service::initialise() {
        SALOME_ModuleCatalog::Service* Service = &(Interface->interfaceservicelist[k]);
        QListViewItem* myServiceItem = new QListViewItem(myInterfaceItem, (char*)Service->ServiceName);
        myServiceItem->setSelectable(true);
-       components->ensureItemVisible(myServiceItem);
+       //components->ensureItemVisible(myServiceItem);
        
        long nbPortsOut = Service->ServiceoutParameter.length();
        for (int m=0; m<nbPortsOut; m++) {
@@ -325,10 +336,11 @@ void SUPERVGUI_Service::initialise() {
 
        long nbStreamPortsOut = Service->ServiceoutDataStreamParameter.length();
        for (int m=0; m<nbStreamPortsOut; m++) {
-         SALOME_ModuleCatalog::ServicesDataStreamParameter* PortOut = &(Service->ServiceoutDataStreamParameter[m]);
+         SALOME_ModuleCatalog::ServicesDataStreamParameter* PortOut =
+            &(Service->ServiceoutDataStreamParameter[m]);
          QListViewItem* myPortOutItem = 
            new QListViewItem(myServiceItem, (char*)PortOut->Parametername, 
-                             getDataStreamParameterName(PortOut->Parametertype), "DataStream Out");
+                              getDataStreamParameterName(PortOut->Parametertype), "DataStream Out");
          myPortOutItem->setSelectable(false);
        }
        
@@ -361,8 +373,17 @@ SUPERVGUI_Service::~SUPERVGUI_Service() {
 }
 
 void SUPERVGUI_Service::addComputeNode() {
-  QAD_Desktop* aDesktop = QAD_Application::getDesktop();
-  SUPERVGUI_Main* aMain = Supervision.getMain();
+  SUIT_Desktop* aDesktop = SUIT_Session::session()->activeApplication()->desktop();
+  CAM_Application* anApp = ( CAM_Application* )(SUIT_Session::session()->activeApplication());
+  if ( !anApp ) return;
+  
+  SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
+  if ( !aSupMod ) {
+    MESSAGE("NULL Supervision module!");
+    return;
+  }
+
+  SUPERVGUI_Main* aMain = aSupMod->getMain();
   if (aMain==0) {
     QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
   } else if (!aMain->isEditable()) {
@@ -383,38 +404,43 @@ void SUPERVGUI_Service::addComputeNode() {
          const char* service   = item->text(0).latin1();
          const char* interface = item->parent()->text(0).latin1();
          const char* component = item->parent()->parent()->text(0).latin1();
-         SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(aDesktop->getComponentName(component));
-         if (myComponent==NULL) {
+         SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(anApp->moduleName(component));
+         if ( myComponent == NULL ) {
            QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
-         } else {
+         } 
+         else {
            const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service);
-           b  = true;
-           
-           SUPERV_CNode node = aMain->getDataflow()->CNode(*myService);
-           if (CORBA::is_nil(node)) {
+           SUPERV_CNode aNode = aMain->getDataflow()->CNode(*myService);
+           if ( CORBA::is_nil( aNode ) ) {
              QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));    
              return;
            }
-           //to appear a new node in the top-left corner of the current viewport
-           int cx, cy;
-           aMain->getCanvasView()->viewportToContents(myX, myY, cx, cy);
-           node->Coords(cx, cy);
-           myX += NODE_DX;
-           myY += NODE_DY;
-           aMain->addComputeNode(SUPERV::CNode::_narrow(node));
+
+           SUPERV::INode_var aDummyEndNode;
+           addNode( aNode, aDummyEndNode, myX, myY );
+           b = true; // at least one node was added
          }
        }
       }
-      if (!b) {
+      if ( !b ) {
        QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NONODE_TOADD"));
       }
     }
   }
 }
 
-void SUPERVGUI_Service::addFactoryNode() {
-  QAD_Desktop* aDesktop = QAD_Application::getDesktop();
-  SUPERVGUI_Main* aMain = Supervision.getMain();
+void SUPERVGUI_Service::addFactoryNodeDef() {
+  SUIT_Desktop* aDesktop = SUIT_Session::session()->activeApplication()->desktop();
+  CAM_Application* anApp = ( CAM_Application* )(SUIT_Session::session()->activeApplication());
+  if ( !anApp ) return;
+
+  SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
+  if ( !aSupMod ) {
+    MESSAGE("NULL Supervision module!");
+    return;
+  }
+
+  SUPERVGUI_Main* aMain = aSupMod->getMain();
   if (aMain==0) {
     QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
   } else if (!aMain->isEditable()) {
@@ -434,135 +460,231 @@ void SUPERVGUI_Service::addFactoryNode() {
        if (item->isSelected()) {
          const char* service   = item->text(0).latin1();
          const char* interface = item->parent()->text(0).latin1();
-         const char* component = aDesktop->getComponentName(item->parent()->parent()->text(0).latin1());
-         SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(component);
-         if (myComponent==NULL) {
-           QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
-         } else {
-           const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service);
-           b  = true;
-           
-           MESSAGE ( " myService->TypeOfNode == " << myService->TypeOfNode ) 
-
-           int cx, cy;
-           if ( myService->TypeOfNode == 0 ) { // ComputeNode
-             SUPERV_CNode node = aMain->getDataflow()->CNode(*myService);
-             if (CORBA::is_nil(node)) {
-               QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));          
-               return;
-             }
-             //to appear a new node in the top-left corner of the current viewport
-             aMain->getCanvasView()->viewportToContents(myX, myY, cx, cy);
-             node->Coords(cx, cy);
-             myX += NODE_DX;
-             myY += NODE_DY;
-             aMain->addComputeNode(SUPERV::CNode::_narrow(node));
-           } else { // Factory Node
-             SUPERV_FNode node = aMain->getDataflow()->FNode(component, interface, *myService);
-             if (CORBA::is_nil(node)) {
-               QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));          
-               return;
+         //const char* component = anApp->moduleName(item->parent()->parent()->text(0).latin1());
+         // mkr : PAL13135 -->
+         if ( aSupMod->getInterfaceNameMap().contains(item->parent()->parent()->text(0)) ) {
+           const char* component = aSupMod->getInterfaceNameMap().find(item->parent()->parent()->text(0)).data();
+           // mkr : PAL13135 <--
+
+           SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(component);
+           if (myComponent==NULL) {
+             QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
+           } 
+           else {
+             const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service);
+             SUPERV_CNode aNode;
+             if ( myService->TypeOfNode == 0 ) { // ComputeNode
+               aNode = aMain->getDataflow()->CNode(*myService);
+               if (CORBA::is_nil( aNode ) ) {
+                 QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));        
+                 return;
+               }
+             } 
+             else { // Factory Node
+               aNode = aMain->getDataflow()->FNode(component, interface, *myService, myComponent->implementation_type()); // mkr : PAL11273
+               if ( CORBA::is_nil( aNode ) ) {
+                 QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));        
+                 return;
+               }
              }
-             //to appear a new node in the top-left corner of the current viewport
-             aMain->getCanvasView()->viewportToContents(myX, myY, cx, cy);
-             node->Coords(cx, cy);
-             myX += NODE_DX;
-             myY += NODE_DY;
-             aMain->addComputeNode(SUPERV::CNode::_narrow(node));
-             
+             SUPERV::INode_var aDummyEndNode;
+             addNode( aNode, aDummyEndNode, myX, myY );
+             b = true;
            }
-
-//         SUPERV_FNode node = aMain->getDataflow()->FNode(component, interface, *myService);
-//         if (CORBA::is_nil(node)) {
-//           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));   
-//           return;
-//         }
-//         node->Coords(myX, myY);
-//         myX += NODE_DX;
-//         myY += NODE_DY;
-//         aMain->addComputeNode(SUPERV::CNode::_narrow(node));
-         }
+         }
        }
       }
-      if (!b) {
+      if ( !b ) {
        QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NONODE_TOADD"));
       }
     }
   }
 }
 
+void SUPERVGUI_Service::addFactoryNodeCust() {
+  SUIT_Desktop* aDesktop = SUIT_Session::session()->activeApplication()->desktop();
+  CAM_Application* anApp = ( CAM_Application* )(SUIT_Session::session()->activeApplication());
+  if ( !anApp ) return;
 
-void SUPERVGUI_Service::addInlineNode() {
-  SUPERVGUI_Main* aMain = Supervision.getMain();
+  SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
+  if ( !aSupMod ) {
+    MESSAGE("NULL Supervision module!");
+    return;
+  }
+
+  SUPERVGUI_Main* aMain = aSupMod->getMain();
   if (aMain==0) {
-    QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
+    QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
   } else if (!aMain->isEditable()) {
-    QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));        
+    QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));     
   } else {
+    CORBA::Object_ptr obj  = naming->Resolve("/Kernel/ModulCatalog");
+    SALOME_ModuleCatalog::ModuleCatalog_var* aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
+    *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
+    if (CORBA::is_nil(*aModuleCatalog)) {
+      QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
+    } else {
+      QListViewItem*        item;
+      bool                  b = false;
+      
+      QListViewItemIterator iSel(components);
+      int count = 0;
+      for (; iSel.current(); ++iSel) { // check : how many objects are selected (single or multi)
+       item = iSel.current();
+       if (item->isSelected()) count++;
+       if ( count > 1) break;
+      }
+          
+      QListViewItemIterator i(components);
+      QString anAuthor, aContainer, aComment;
+      bool DoneSetting = false;
+      int aRes = 0;
+      for (; i.current(); ++i) {
+       item = i.current();
+       if (item->isSelected()) {
+         const char* service   = item->text(0).latin1();
+         const char* interface = item->parent()->text(0).latin1();
+         //const char* component = anApp->moduleName(item->parent()->parent()->text(0).latin1());
+         // mkr : PAL13135 -->
+         if ( aSupMod->getInterfaceNameMap().contains(item->parent()->parent()->text(0)) ) {
+           const char* component = aSupMod->getInterfaceNameMap().find(item->parent()->parent()->text(0)).data();
+           // mkr : PAL13135 <--
+
+           SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(component);
+           if (myComponent==NULL) {
+             QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
+           } 
+           else {
+             const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service);
+             SUPERV_CNode aNode;
+             if ( myService->TypeOfNode == 0 ) { // ComputeNode
+               aNode = aMain->getDataflow()->CNode(*myService);
+               if (CORBA::is_nil( aNode ) ) {
+                 QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));        
+                 return;
+               }
+             } 
+             else { // Factory Node
+
+               SUPERVGUI_CustomSettings* aCSDialog = 0;
+               if ( count > 1 && !DoneSetting) { // multi selection
+                 DoneSetting = true;
+                 aCSDialog = new SUPERVGUI_CustomSettings(item, true, myComponent->implementation_type());
+               }
+               else if ( count == 1 ) // single selection
+                 aCSDialog = new SUPERVGUI_CustomSettings(item, false, myComponent->implementation_type());
+               
+               if ( aCSDialog ) {
+                 aRes = aCSDialog->exec();
+                 if (aRes) {
+                   anAuthor = aCSDialog->Author();
+                   aContainer = aCSDialog->Container();
+                   aComment = aCSDialog->Comment();
+                 }
+                 delete aCSDialog;
+               }
+               
+               aNode = aMain->getDataflow()->FNode(component, interface, *myService, myComponent->implementation_type()); // mkr : PAL11273
+               if ( CORBA::is_nil( aNode ) ) {
+                 QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));        
+                 return;
+               }
+
+               if (aRes) {
+                 aNode->SetAuthor(anAuthor.latin1());
+                 SUPERV::FNode::_narrow(aNode)->SetContainer(aContainer.latin1());
+                 aNode->SetComment(aComment.latin1());
+               }
+               
+             }
+             SUPERV::INode_var aDummyEndNode;
+             addNode( aNode, aDummyEndNode, myX, myY );
+             b = true;
+           }
+         }
+       }
+      }
+      if ( !b ) {
+       QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NONODE_TOADD"));
+      }
+    }
+  }
+}
+
+void SUPERVGUI_Service::addInlineNode() {
+  SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
+  if ( !aSupMod ) {
+    MESSAGE("NULL Supervision module!");
+    return;
+  }
+
+  SUPERVGUI_Main* aMain = aSupMod->getMain();
+  if (aMain==0) {
+    QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
+  } 
+  else if (!aMain->isEditable()) {
+    QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));      
+  } 
+  else {
     int aSel = myTypeCombo->currentItem();
-    int cx, cy;
     switch (aSel) {
     case 0: // Computation
-      if (myScriptPane->isDefined()) { 
-       SUPERV_INode aNode = aMain->getDataflow()->INode(myScriptPane->getFuncName().latin1(), 
-                                                        (myScriptPane->getFunction()).in());
+      {        
+       SUPERV_CNode aNode = 
+         aMain->getDataflow()->INode(myScriptPane->getFuncName().isEmpty() ? "" : myScriptPane->getFuncName().latin1(), 
+                                     (myScriptPane->getFunction()).in());
        if (CORBA::is_nil(aNode)) {
          QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
          return;
        }
-       //to appear a new node in the top-left corner of the current viewport
-       aMain->getCanvasView()->viewportToContents(myX, myY, cx, cy);
-       aNode->Coords(cx, cy);
-       myX += NODE_DX;
-       myY += NODE_DY;
-       aMain->addComputeNode(SUPERV::CNode::_narrow(aNode));
+       SUPERV::INode_var aDummyEndNode;
+       // here we have to 
+       // 1) parse nodes' python function to find ports names
+       // 2) create ports for engine node with found names and "undefined" types
+       //    ( aNode->InPort(name,type), aNode->OutPort(name,type) )
+       // P.S. CanvasNode->createPort(...) for create presentation of port
+       //      will be called from addNode(...) (inside CanvasNode constructor)
+       addNode( aNode, aDummyEndNode, myX, myY );
       }
       break;
       
     case 1: // Switch
-      if (myScriptPane->isDefined()) {
+      {
        SUPERV_INode aEndNode;
-       SUPERV_SNode aStartNode = aMain->getDataflow()->SNode(myScriptPane->getFuncName().latin1(),
-                                                             (myScriptPane->getFunction()).in(),
-                                                             aEndNode);
+       SUPERV_CNode aStartNode = 
+         aMain->getDataflow()->SNode(myScriptPane->getFuncName().isEmpty() ? "" : myScriptPane->getFuncName().latin1(),
+                                     (myScriptPane->getFunction()).in(),
+                                     aEndNode);
        if (CORBA::is_nil(aStartNode) || CORBA::is_nil(aEndNode)) {
          QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
          return;
        }
-       //to appear a new node in the top-left corner of the current viewport
-       aMain->getCanvasView()->viewportToContents(myX, myY, cx, cy);
-       aStartNode->Coords(cx, cy);
-       aEndNode->Coords(cx + LABEL_WIDTH*2, cy);
-       myX += NODE_DX;
-       myY += NODE_DY;
-       aMain->addControlNode(SUPERV::CNode::_narrow(aStartNode), SUPERV::CNode::_narrow(aEndNode), true);
+       addNode( aStartNode, aEndNode, myX, myY );
       }
       break;
       
     case 2: // Loop
       {
        SUPERV_INode aEndNode;
-       SUPERV_LNode aStartNode = aMain->getDataflow()->LNode(myInitPane->getFuncName().latin1(), (myInitPane->getFunction()).in(),
-                                                             myMorePane->getFuncName().latin1(), (myMorePane->getFunction()).in(),
-                                                             myNextPane->getFuncName().latin1(), (myNextPane->getFunction()).in(),
-                                                             aEndNode);
+       SUPERV_CNode aStartNode = 
+         aMain->getDataflow()->LNode(myInitPane->getFuncName().isEmpty() ? "" : myInitPane->getFuncName().latin1(), 
+                                     (myInitPane->getFunction()).in(),
+                                     myMorePane->getFuncName().isEmpty() ? "" : myMorePane->getFuncName().latin1(), 
+                                     (myMorePane->getFunction()).in(),
+                                     myNextPane->getFuncName().isEmpty() ? "" : myNextPane->getFuncName().latin1(), 
+                                     (myNextPane->getFunction()).in(),
+                                     aEndNode);
        if (CORBA::is_nil(aStartNode) || CORBA::is_nil(aEndNode)) {
          QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
          return;
        }
-       //to appear a new node in the top-left corner of the current viewport
-       aMain->getCanvasView()->viewportToContents(myX, myY, cx, cy);
-       aStartNode->Coords(cx, cy);
-       aEndNode->Coords(cx + LABEL_WIDTH*2, cy);
-       myX += NODE_DX;
-       myY += NODE_DY;
-       aMain->addControlNode(SUPERV::CNode::_narrow(aStartNode), SUPERV::CNode::_narrow(aEndNode), true);
+       addNode( aStartNode, aEndNode, myX, myY );
       }
       break;
       
     case 3: // GoTo
       {
-       SUPERV_GNode aGotoNode;
+       SUPERV_CNode aGotoNode;
        if (myScriptPane->isDefined()) 
          aGotoNode = aMain->getDataflow()->GNode(myScriptPane->getFuncName().latin1(), 
                                                  (myScriptPane->getFunction()).in(), "");
@@ -572,12 +694,8 @@ void SUPERVGUI_Service::addInlineNode() {
          QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
          return;
        }
-       //to appear a new node in the top-left corner of the current viewport
-       aMain->getCanvasView()->viewportToContents(myX, myY, cx, cy);
-       aGotoNode->Coords(cx, cy);
-       myX += NODE_DX;
-       myY += NODE_DY;
-       aMain->addGOTONode(SUPERV::GNode::_narrow(aGotoNode));
+       SUPERV::INode_var aDummyEndNode;
+       addNode( aGotoNode, aDummyEndNode, myX, myY );
       }
       break;
     }
@@ -585,14 +703,22 @@ void SUPERVGUI_Service::addInlineNode() {
 }
 
 void SUPERVGUI_Service::addMacroNode() {
-  SUPERVGUI_Main* aMain = Supervision.getMain();
+  SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
+  if ( !aSupMod ) {
+    MESSAGE("NULL Supervision module!");
+    return;
+  }
+
+  SUPERVGUI_Main* aMain = aSupMod->getMain();
   if (aMain==0) {
-    QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
-  } else if (!aMain->isEditable()) {
-    QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));        
-  } else {
-    if (myMFile) {
-      SUPERV_Graph aNode;
+    QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
+  } 
+  else if (!aMain->isEditable()) {
+    QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));      
+  } 
+  else {
+    if ( myMFile ) {
+      SUPERV_CNode aNode;
       if (aMain->getDataflow()->IsStreamGraph()) {
        SUPERV_StreamGraph aSGraph = aMain->getDataflow()->ToStreamGraph();
        if (!SUPERV_isNull(aSGraph)) 
@@ -608,16 +734,12 @@ void SUPERVGUI_Service::addMacroNode() {
        QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));         
        return;
       }
-      //to appear a new node in the top-left corner of the current viewport
-      int cx, cy;
-      aMain->getCanvasView()->viewportToContents(myX, myY, cx, cy);
-      aNode->Coords(cx, cy);
-      myX += NODE_DX;
-      myY += NODE_DY;
-      aMain->addMacroNode(SUPERV::CNode::_narrow(aNode));
+
+      SUPERV::INode_var aDummyEndNode;
+      addNode( aNode, aDummyEndNode, myX, myY );
     }
     else {
-      QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NONODE_TOADD"));
+      QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NONODE_TOADD"));
     }
   }
 }
@@ -630,18 +752,18 @@ void SUPERVGUI_Service::loadGraph() {
                return;
        }
 
-  QString aFileName = QAD_FileDlg::getFileName(QAD_Application::getDesktop(),
-                                              "",
-                                              "*.xml",
-                                              tr("MSG_GRAPH_INSERT"),
-                                              true);
+  QString aFileName = SUIT_FileDlg::getFileName(SUIT_Session::session()->activeApplication()->desktop(),
+                                               "",
+                                               "*.xml",
+                                               tr("MSG_GRAPH_INSERT"),
+                                               true);
   if (aFileName.isEmpty()) return;
 
   myMacroPane->clear();
 
   myMFile = new QFile(aFileName);
   if (!myMFile->open(IO_ReadOnly)) {
-    QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), 
+    QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), 
                         tr("MSG_CANT_LOADSCRIPT"));
     delete myMFile; myMFile = 0;
     return;
@@ -649,7 +771,7 @@ void SUPERVGUI_Service::loadGraph() {
 
   QTextStream* aStream = new QTextStream(myMFile);
   if (aStream->atEnd()) {
-    QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), 
+    QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), 
                         tr("MSG_EMTY_FILE"));
     delete aStream;
     myMFile->close();
@@ -681,9 +803,16 @@ void SUPERVGUI_Service::choose() {
     
 
 void SUPERVGUI_Service::showEvent(QShowEvent* theEvent) {
-  SUPERVGUI_Main* aMain = Supervision.getMain();
+  SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
+  if ( !aSupMod ) {
+    MESSAGE("NULL Supervision module!");
+    return;
+  }
+
+  SUPERVGUI_Main* aMain = aSupMod->getMain();
   if (aMain && (!aMain->isArrayShown())) {
-    aMain->getGraph()->viewportToContents(0, 0, myX, myY);
+    aMain->getArrayView()->viewportToContents(0, 0, myX, myY);
+    //aMain->getGraph()->viewportToContents(0, 0, myX, myY);
   }
   QDialog::showEvent(theEvent);
 }
@@ -695,32 +824,57 @@ void SUPERVGUI_Service::tabChanged(QWidget* theWidget) {
 
 
 
-//*****************************************************
+//*****************************************************/
 //  Pane for Python script editing
-//*****************************************************
-SUPERVGUI_PythonEditPane::SUPERVGUI_PythonEditPane(QWidget* theParent) 
-  : QFrame(theParent)
+//*****************************************************/
+SUPERVGUI_PythonEditPane::SUPERVGUI_PythonEditPane( QWidget* theParent, const bool isNodeCreation, int& theX, int& theY ) 
+  : myIsWithLibrary( isNodeCreation ), 
+    QFrame( theParent ),
+    myX( theX ), myY( theY )
 {
-  QGridLayout* aEditLayout = new QGridLayout(this, 2, 4);
+  QGridLayout* aEditLayout = new QGridLayout( this, 2, 8, 0, 6 );
 
   // First row
+  if ( myIsWithLibrary ) {
+    QPushButton* aLibBtn = new QPushButton(tr("BUT_LIBRARY"), this);
+    connect(aLibBtn, SIGNAL(clicked()), this, SLOT(library()));
+    aEditLayout->addMultiCellWidget( aLibBtn, 0, 0, 1, 2 );
+  }
+
   QPushButton* aLoadBtn = new QPushButton(tr("BUT_LOAD"), this);
   connect(aLoadBtn, SIGNAL(clicked()), this, SLOT(loadFile()));
   
-  aEditLayout->addWidget(aLoadBtn, 0, 2);
+  aEditLayout->addMultiCellWidget( aLoadBtn, 0, 0, 3, 4 );
 
-  myNextBtn = new QPushButton(tr("BUT_NEXT"), this);
-  myNextBtn->setEnabled(false);
-  connect(myNextBtn, SIGNAL(clicked()), this, SLOT(readFunction()));
+  myFunctionsCombo = new QComboBox( this );
+  connect( myFunctionsCombo, SIGNAL( activated( int ) ), this, SLOT( readFunction( int ) ) );
   
-  aEditLayout->addWidget(myNextBtn, 0, 3);
+  aEditLayout->addMultiCellWidget( myFunctionsCombo, 0, 0, 5, 7 );
   
   //Second row
   myText = new QTextEdit(this);
-  myText->setWordWrap(QTextEdit::FixedColumnWidth);
-  myText->setWrapColumnOrWidth(80);
+  myText->setTextFormat( Qt::PlainText ); // NOT rich text, so text() returns plain text
+  myText->setWordWrap( QTextEdit::FixedColumnWidth );
+  myText->setWrapColumnOrWidth( 80 );
+  connect( myText, SIGNAL( returnPressed() ), this, SLOT( autoIndentLine() ) );
 
-  aEditLayout->addMultiCellWidget(myText, 1, 1, 0, 3);
+  aEditLayout->addMultiCellWidget( myText, 1, 1, 0, 7 );
+  //aEditLayout->setColStretch( 3, 1 ); // to allow myFunctionsCombo be larger when needed
+}
+
+/**
+ * Return a text between "def" and "("
+ * "def" must begin with position 0, which means that only global function definitions are possible
+ */ 
+QString getFunctionName( const QString& aLine ) {
+  int aDefPos = aLine.find("def");
+  if ( aDefPos == 0 ) { // only global function definitions!
+    int aStart = aLine.find(" ", aDefPos);
+    int aEnd = aLine.find("(", aStart);
+    QString aName = aLine.mid(aStart, (aEnd-aStart));
+    return aName.stripWhiteSpace();
+  }
+  return QString();
 }
    
 /**
@@ -744,6 +898,8 @@ void SUPERVGUI_PythonEditPane::initPyFunctions( QTextStream& theStream ) {
       aLine = theStream.readLine();
     
     if ( !aLine.isNull() && aLine.find("def") == 0 ) { 
+      myFunctionsCombo->insertItem( getFunctionName( aLine ) ); // aLine now == function name 
+
       aPyFunction += aLine;
       aPyFunction += '\n'; 
 
@@ -751,7 +907,9 @@ void SUPERVGUI_PythonEditPane::initPyFunctions( QTextStream& theStream ) {
       aLine = theStream.readLine();
       // asv : 23.11.04 : added "|| aLine.isEmpty()" - fix for PAL6870. readLine() returns an empty
       //       string for "\n" string, it trails \n caracter.  but we accept such lines..
-      while ( !aLine.isNull() && ( aLine.isEmpty() || aLine[0].isSpace() ) ) {
+      // asv : 22.12.04 : aLine[0].isSpace() || aLine[0]=='#' -> line must begin with space or tab
+      //       (a normal code with indentation) or comment sign.
+      while ( !aLine.isNull() && ( aLine.isEmpty() || aLine[0].isSpace() || aLine[0] == '#' ) ) {
        aPyFunction += aLine;
        aPyFunction += '\n'; 
        aLine = theStream.readLine();
@@ -767,39 +925,35 @@ void SUPERVGUI_PythonEditPane::initPyFunctions( QTextStream& theStream ) {
  * Load existing Python script
  */
 void SUPERVGUI_PythonEditPane::loadFile() {
-  QString aFileName = QAD_FileDlg::getFileName(QAD_Application::getDesktop(),
-                                              "",
-                                              "*.py",
-                                              tr("TIT_LOADSCRIPT"),
-                                              true);
+  QString aFileName = SUIT_FileDlg::getFileName(SUIT_Session::session()->activeApplication()->desktop(),
+                                               "",
+                                               "*.py",
+                                               tr("TIT_LOADSCRIPT"),
+                                               true);
   if (aFileName.isEmpty()) return;
 
   QFile aFile( aFileName );
   if (!aFile.open(IO_ReadOnly)) {
-    QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), 
+    QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), 
                         tr("MSG_CANT_LOADSCRIPT"));
     return;
   }
 
   myPyFunctions.clear();
-  myPyIndex = -1;
-  myNextBtn->setEnabled( false );
+  myFunctionsCombo->clear();
   myText->clear();
 
   QTextStream aFileReader(&aFile);
   if ( aFileReader.atEnd() ) {
-    QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_EMTY_FILE"));
+    QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_EMTY_FILE"));
     aFile.close();
     return;
   }
 
   initPyFunctions( aFileReader );
 
-  if ( myPyFunctions.size() ) {
-    myNextBtn->setEnabled( true );
-    myPyIndex = 0;
-    readFunction();
-  }
+  if ( myPyFunctions.size() )
+    readFunction( 0 );
 }
   
 /**
@@ -807,30 +961,28 @@ void SUPERVGUI_PythonEditPane::loadFile() {
  * asv : Comment above is old! Present model: just take an already read string = PyFunction
  * from the list which is filled in loadFile().
  */
-void SUPERVGUI_PythonEditPane::readFunction() {
+void SUPERVGUI_PythonEditPane::readFunction( int i ) {
   myText->clear();
-  if ( myPyIndex != -1 && myPyFunctions.size() && myPyFunctions.size() > myPyIndex )
-    myText->append( myPyFunctions[ myPyIndex++ ] );
-  if ( myPyFunctions.size() <= myPyIndex ) // last index was reached
-    myNextBtn->setEnabled( false );
+  if ( i != -1 && myPyFunctions.size() && myPyFunctions.size() > i )
+    myText->append( myPyFunctions[ i ] );
+
+  // asv : 30.11.04 : 2.7 - Inline node function editor improvement
+  // 2.7.1 - set focus to editor widget on editor window opening
+  // 2.7.2 - scroll to the beginning of function on editor window opening
+  myText->setFocus();
+  myText->ensureVisible( 0,0 );
 }
 
 /**
  * Returns the text after "def" and before "(" -- first defined function name
  */
 QString SUPERVGUI_PythonEditPane::getFuncName() {
-  QString aName("");
   for (int i=0; i < myText->paragraphs(); i++) {
-    QString aLine = myText->text(i);
-    int aDefPos = aLine.find("def");
-    if (aDefPos == 0) {
-      int aStart = aLine.find(" ", aDefPos);
-      int aEnd = aLine.find("(", aStart);
-      QString aName = aLine.mid(aStart, (aEnd-aStart));
-      return aName.stripWhiteSpace();
-    }
+    QString aName = getFunctionName( myText->text(i) );
+    if ( !aName.isEmpty() )
+      return aName;
   }
-  return aName;
+  return QString();
 }
 
 /**
@@ -845,8 +997,10 @@ SUPERV_Strings SUPERVGUI_PythonEditPane::getFunction() {
     // it's user's responsibility to enter correct Python code, we don't do anything with it.
     // if (..) -- initial, while(..) -- my improvement, but also commented out -- needless.
     //if (!aLine.right(1).compare(" ")) // replaced with the line below -- loop
-    //while (aLine.at(aLine.length()-1).isSpace()) // remove trailing spaces
-    //  aLine = aLine.remove(aLine.length()-1,1);
+    // uncommented by mkr to fix bugs IPAL12363, IPAL12885 -->
+    while (aLine.at(aLine.length()-1).isSpace()) // remove trailing spaces
+      aLine = aLine.remove(aLine.length()-1,1);
+    // <--
     aStrings[i] = CORBA::string_dup(aLine.latin1());
   }
   return aStrings._retn();
@@ -854,8 +1008,8 @@ SUPERV_Strings SUPERVGUI_PythonEditPane::getFunction() {
 
 
 void SUPERVGUI_PythonEditPane::setFunction(SUPERV_Strings theStr) {
-  int aLen = theStr->length();
-  for (int i=0; i < aLen; i++)
+  myText->clear();
+  for ( int i=0, aLen = theStr->length(); i < aLen; i++ )
     myText->append(QString(theStr[i]));
 
   // asv : 30.11.04 : 2.7 - Inline node function editor improvement
@@ -865,32 +1019,82 @@ void SUPERVGUI_PythonEditPane::setFunction(SUPERV_Strings theStr) {
   myText->ensureVisible( 0,0 );
 }
 
+/**
+ * Automatic indentation rule: if a previous line ended with 
+ * ':', then add N additional spaces in the current line.  If no ':' found, then 
+ * the same amount of spaces as in the previous line is added. Connected to 
+ * "returnPressed" signal of myText text edit.
+*/
+void SUPERVGUI_PythonEditPane::autoIndentLine() {
+  const int N = 4; // width of indentation "tab"
+  if ( myText && myText->paragraphs() ) {
+
+    // get current cursor position and previous line (the one to be analized) 
+    int pos, para, i;
+    QString spacesStr;
+    myText->getCursorPosition( &para, &pos ); // pos==0, beginning of line
+    if ( myText->paragraphLength(para-1) > 0 ) { // mkr : IPAL9817
+      QString line = myText->text( para-1 ); // previous paragraph line
+
+      // construct a string containing all leading space characters of previous line (tabs, etc.)
+      i = -1;
+      while ( line[++i].isSpace() ) // append all isSpace() characters at beginning of line to spacesStr
+       spacesStr += line[i];
+
+      // if ':' was found -- add more spaces to spacesStr
+      line = line.stripWhiteSpace();
+      if ( line[ line.length()-1 ] == ':' ) {
+       i = 0;
+       while ( i++ < N ) 
+         spacesStr += ' ';
+      }
+    }
+
+    // ok, append spacesStr at the beginning of the current line = make indentation
+    myText->insertAt( spacesStr, para, pos );
+    myText->setCursorPosition( para, pos+spacesStr.length() );
+  }
+}
 
+/**
+ * Create a node by loading it from an external XML library file
+ * This slot opens a dialog box which then "lives" by itself..
+ */
+void SUPERVGUI_PythonEditPane::library() {
+  // if CanImport() returns false, it displays an error message box, so there is no need to
+  // display such message here ("library file not found", etc.).
+  if ( SUPERVGUI_Library::getLibrary()->CanImport() ) {
+    SUPERVGUI_LibDlg* aDlg = new SUPERVGUI_LibDlg( this, myX, myY );
+    aDlg->exec();
+  }
+}
 
 /*!
  * Edit Python dialog
  */
-SUPERVGUI_EditPythonDlg::SUPERVGUI_EditPythonDlg(bool isLoop)
-  :QDialog(QAD_Application::getDesktop(), 0, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
+SUPERVGUI_EditPythonDlg::SUPERVGUI_EditPythonDlg( bool isLoop )
+  :QDialog(SUIT_Session::session()->activeApplication()->desktop(), 0, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu) 
 {
   setSizeGripEnabled( true );
   setCaption(tr("TIT_FUNC_PYTHON"));
   resize( 500, 250 );
   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 4);
+  int a,b; // dummies for PythonEditPane, not used, since library = false and myX, myY are not used in PythonEditPane
+  myIsLoop = isLoop; // mkr : PAL12236
   if (isLoop) {
     QTabWidget* aLoopTabPane = new QTabWidget(this);
-    myInitPane = new SUPERVGUI_PythonEditPane(this); 
+    myInitPane = new SUPERVGUI_PythonEditPane( this, false, a, b ); // library == false, since no creation of a node is needed here
     aLoopTabPane->addTab(myInitPane, "Init");
     
-    myMorePane = new SUPERVGUI_PythonEditPane(this);
+    myMorePane = new SUPERVGUI_PythonEditPane( this, false, a, b );
     aLoopTabPane->addTab(myMorePane, "More");
     
-    myNextPane = new SUPERVGUI_PythonEditPane(this);
+    myNextPane = new SUPERVGUI_PythonEditPane( this, false, a, b );
     aLoopTabPane->addTab(myNextPane, "Next");
 
     aMainLayout->addWidget(aLoopTabPane);    
   } else {
-    myEditPane = new SUPERVGUI_PythonEditPane(this);
+    myEditPane = new SUPERVGUI_PythonEditPane( this, false, a, b );
     aMainLayout->addWidget(myEditPane);
   }
   QGroupBox* aBtnBox = new QGroupBox( this );
@@ -901,7 +1105,7 @@ SUPERVGUI_EditPythonDlg::SUPERVGUI_EditPythonDlg(bool isLoop)
   aBtnLayout->setSpacing( 6 ); aBtnLayout->setMargin( 11 );
   
   QPushButton* aOKBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
-  connect( aOKBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
+  connect( aOKBtn, SIGNAL( clicked() ), this, SLOT( clickOnOk() ) );
   aBtnLayout->addWidget( aOKBtn );
 
   aBtnLayout->addStretch();
@@ -912,3 +1116,229 @@ SUPERVGUI_EditPythonDlg::SUPERVGUI_EditPythonDlg(bool isLoop)
 
   aMainLayout->addWidget(aBtnBox);
 }
+
+// mkr : IPAL9817 : to avoid a SIGSEGV when INode_Impl::SetPyFunction(...)
+//                  will call with null python function name
+void SUPERVGUI_EditPythonDlg::clickOnOk()
+{
+  // mkr : PAL12236
+  bool hasEmptyName = myIsLoop ? 
+    ( getInitFuncName().isEmpty() || getMoreFuncName().isEmpty() || getNextFuncName().isEmpty() ) :
+    getFuncName().isEmpty();
+
+  if ( hasEmptyName )
+    QMessageBox::warning( SUIT_Session::session()->activeApplication()->desktop(), tr( "ERROR" ), tr( "MSG_INCORRECT_INDENT" ) );
+  else  
+    accept();
+}
+
+/**
+ * Do the following actions for newly created Engine's CNode:
+ * 1. Create a presentation for it (CanvasNode)
+ * 2. Place the CanvasNode to the current top-left corner or the current viewport
+ * 3. Increment the coordinates of the next CanvasNode (new nodes are "cascaded" when several of them are created at once)
+ * PS theEndNode is passed only for Loop and Switch nodes (EndLoop and EndSwitch)
+ */ 
+void SUPERVGUI_Service::addNode( SUPERV::CNode_var theNode, SUPERV::INode_var theEndNode, int& theX, int& theY )  {
+  SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
+  if ( !aSupMod ) {
+    MESSAGE("NULL Supervision module!");
+    return;
+  }
+  
+  SUPERVGUI_Main* aMain = aSupMod->getMain();
+
+  if ( !CORBA::is_nil( theNode ) && aMain ) {
+    
+    aMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag, why here? -> PAL7960
+
+    int cx, cy;   //to appear a new node in the top-left corner of the current viewport
+
+    //2.8 point of improvements: Adding node to graph window with taking into account zoom factor
+    QWMatrix aWM = aMain->getCanvasView()->worldMatrix();
+    aMain->getCanvasView()->viewportToContents(theX, theY, cx, cy);
+
+    //2.8 point of improvements:
+    cx = (int)((double)cx/aWM.m11());
+    cy = (int)((double)cy/aWM.m22());
+    theNode->Coords(cx, cy);
+    if ( !CORBA::is_nil( theEndNode ) )
+      theEndNode->Coords(cx + LABEL_WIDTH*2, cy);
+    theX += (int)(NODE_DX*aWM.m11());
+    theY += (int)(NODE_DY*aWM.m22());
+
+    if ( theNode->IsGOTO() )
+      aMain->addGOTONode( theNode );
+    else if ( theNode->IsMacro() )
+      aMain->addMacroNode( theNode );
+    else if ( theNode->IsLoop() || theNode->IsSwitch() )
+      aMain->addControlNode( theNode, SUPERV::CNode::_narrow( theEndNode ), true );
+    else 
+      aMain->addComputeNode( theNode );
+    aSupMod->nullifyInitialVF();
+  }
+}
+
+/*!
+  Constructor
+*/
+SUPERVGUI_CustomSettings::SUPERVGUI_CustomSettings(QListViewItem* theItem,
+                                                  bool isMultiSel,
+                                                  bool isCimpl)
+     : QDialog( SUIT_Session::session()->activeApplication()->desktop(), "", true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) 
+{
+  Trace("SUPERVGUI_CustomSettings::SUPERVGUI_CustomSettings");
+
+  SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
+  if ( !aSupMod ) {
+    MESSAGE("NULL Supervision module!");
+    return;
+  }
+
+  SUIT_Desktop* aDesktop = SUIT_Session::session()->activeApplication()->desktop();
+
+  setSizeGripEnabled( true );
+
+  QGridLayout* TopLayout = new QGridLayout( this );
+  TopLayout->setSpacing( 6 );
+  TopLayout->setMargin( 11 );
+    
+  QGroupBox* TopGroup = new QGroupBox( this, "TopGroup" );
+  TopGroup->setColumnLayout(0, Qt::Vertical );
+  TopGroup->layout()->setSpacing( 0 );
+  TopGroup->layout()->setMargin( 0 );
+  QGridLayout* TopGroupLayout = new QGridLayout( TopGroup->layout() );
+  TopGroupLayout->setAlignment( Qt::AlignTop );
+  TopGroupLayout->setSpacing( 6 );
+  TopGroupLayout->setMargin( 11 );
+
+  QLabel* authL = new QLabel( tr( "AUTHOR_LBL" ), TopGroup); 
+  authV = new QLineEdit( TopGroup );
+  authV->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  authV->setMinimumSize( 200, 0 );
+  authV->setText( "" );
+
+  contL = new QLabel( tr( "CONTAINER_LBL" ), TopGroup ); 
+  contV = new QLineEdit( TopGroup );
+  contV->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  contV->setMinimumSize( 200, 0 );
+  
+  QLabel* commL = new QLabel( tr( "COMMENT_LBL" ), TopGroup); 
+  commV = new QMultiLineEdit( TopGroup );
+  commV->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
+  commV->setMinimumSize( 200, 100 );
+
+  if ( !aSupMod->getInterfaceNameMap().contains(theItem->parent()->parent()->text(0)) ) {
+    QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NONODE_TOADD"));
+    return;
+  }
+  const char* component = aSupMod->getInterfaceNameMap().find(theItem->parent()->parent()->text(0)).data();
+
+  QString aNodeDefComment;
+  if ( !isMultiSel ) {
+    // 1) set caption
+    const char* service = theItem->text(0).latin1();
+    aNodeDefComment = QString(service) + QString(tr("COMMENT_FROM")) + QString(component);
+    setCaption( tr( "TLT_CUSTOMPARAMETERS_SINGLE" ) + aNodeDefComment );
+  }
+  else {
+    // 1) set caption
+    aNodeDefComment = QString("Factory Node");
+    setCaption( tr( "TLT_CUSTOMPARAMETERS_MULTI" ) );
+  }
+  
+  // 2) set Container
+  SUPERVGUI_Main* aMain = aSupMod->getMain();
+  if (aMain==0) {
+    QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
+    return;
+  }
+  const char* aContainer = aMain->getDataflow()->ContainerNameForComponent(component);
+  if ( aContainer && strlen(aContainer) > 0 )
+    contV->setText( QString(aContainer) );
+  else if ( isCimpl ) // C++ implementation
+    contV->setText( QString(aMain->getDataflow()->DefaultCContainerName()) );
+  else // Python implementation
+    contV->setText( QString(aMain->getDataflow()->DefaultPythonContainerName()) );
+
+  // 3) set comment
+  commV->setText( aNodeDefComment );
+
+  TopGroupLayout->addWidget( authL, 1, 0 );
+  TopGroupLayout->addWidget( authV, 1, 1 );
+  TopGroupLayout->addWidget( contL, 2, 0 );
+  TopGroupLayout->addWidget( contV, 2, 1 );
+  TopGroupLayout->addWidget( commL, 7, 0 );
+  TopGroupLayout->addMultiCellWidget( commV, 7, 8, 1, 1 );
+  TopGroupLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding  ), 8, 0 );
+  TopGroupLayout->setColStretch( 1, 5 );
+
+  QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
+  GroupButtons->setColumnLayout(0, Qt::Vertical );
+  GroupButtons->layout()->setSpacing( 0 );
+  GroupButtons->layout()->setMargin( 0 );
+  QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
+  GroupButtonsLayout->setAlignment( Qt::AlignTop );
+  GroupButtonsLayout->setSpacing( 6 );
+  GroupButtonsLayout->setMargin( 11 );
+
+  QPushButton* okB = new QPushButton( tr( "BUT_OK" ), GroupButtons );
+  connect( okB,     SIGNAL( clicked() ), this, SLOT( okButton() ) );
+  QPushButton* cancelB = new QPushButton( tr( "BUT_CANCEL" ), GroupButtons );
+  connect( cancelB, SIGNAL( clicked() ), this, SLOT( koButton() ) );
+
+  GroupButtonsLayout->addWidget( okB, 0, 0 );
+  GroupButtonsLayout->addItem  ( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
+  GroupButtonsLayout->addWidget( cancelB, 0, 2 );
+
+  TopLayout->addWidget( TopGroup,     0, 0 );
+  TopLayout->addWidget( GroupButtons, 1, 0 );
+  TopLayout->setRowStretch( 0, 1 );
+  TopLayout->setRowStretch( 1, 0 );
+
+  resize(370,200);
+}
+
+/*!
+  Destructor
+*/
+SUPERVGUI_CustomSettings::~SUPERVGUI_CustomSettings() {
+  Trace("SUPERVGUI_CustomSettings::~SUPERVGUI_CustomSettings");
+}
+
+/*!
+  Get author
+*/
+QString SUPERVGUI_CustomSettings::Author() {
+  return authV->text();
+}
+
+/*!
+  Get container
+*/
+QString SUPERVGUI_CustomSettings::Container() {
+  return contV->text();
+}
+
+/*!
+  Get comment
+*/
+QString SUPERVGUI_CustomSettings::Comment() {
+  return commV->text();
+}
+
+/*!
+  <OK> button slot
+*/
+void SUPERVGUI_CustomSettings::okButton() {
+  Trace("SUPERVGUI_CustomSettings::okButton");
+  accept();
+}
+
+/*!
+  <Cancel> button slot
+*/
+void SUPERVGUI_CustomSettings::koButton() {
+  Trace("SUPERVGUI_CustomSettings::koButton");
+  reject();
+}