Salome HOME
Bug fix: don't set "Loading" state for MacroNodes in InitialState() function (called...
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_Service.cxx
index 017ddebe8dc2f0a64a52a2ed3b9bb7495020dffd..6213aa42ed97c30cc6dc590b4cafcdb612a3eab1 100644 (file)
@@ -35,6 +35,7 @@ using namespace std;
 #include "SALOME_NamingService.hxx"
 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
 #include <qlayout.h>
+#include <qhbox.h>
 #include <qtextstream.h>
 
 
@@ -152,14 +153,13 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns):
   QHGroupBox* aAddBox2 = new QHGroupBox(tr("TIT_ADDNODE"), aPythonPane);
   aAddBox2->setInsideSpacing(20);
 
-  QLabel* aTypeLbl = new QLabel(tr("LBL_NODETYPE"), aAddBox2);
+  /*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);
@@ -395,7 +395,10 @@ void SUPERVGUI_Service::addComputeNode() {
              QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));    
              return;
            }
-           node->Coords(myX, myY);
+           //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));
@@ -441,13 +444,16 @@ void SUPERVGUI_Service::addFactoryNode() {
            
            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;
              }
-             node->Coords(myX, myY);
+             //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));
@@ -457,7 +463,9 @@ void SUPERVGUI_Service::addFactoryNode() {
                QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));          
                return;
              }
-             node->Coords(myX, myY);
+             //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));
@@ -492,6 +500,7 @@ void SUPERVGUI_Service::addInlineNode() {
     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));        
   } else {
     int aSel = myTypeCombo->currentItem();
+    int cx, cy;
     switch (aSel) {
     case 0: // Computation
       if (myScriptPane->isDefined()) { 
@@ -501,7 +510,9 @@ void SUPERVGUI_Service::addInlineNode() {
          QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
          return;
        }
-       aNode->Coords(myX, myY);
+       //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));
@@ -518,8 +529,10 @@ void SUPERVGUI_Service::addInlineNode() {
          QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
          return;
        }
-       aStartNode->Coords(myX, myY);
-       aEndNode->Coords(myX + LABEL_WIDTH*2, myY);
+       //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);
@@ -537,8 +550,10 @@ void SUPERVGUI_Service::addInlineNode() {
          QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
          return;
        }
-       aStartNode->Coords(myX, myY);
-       aEndNode->Coords(myX + LABEL_WIDTH*2, myY);
+       //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);
@@ -557,7 +572,9 @@ void SUPERVGUI_Service::addInlineNode() {
          QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
          return;
        }
-       aGotoNode->Coords(myX, myY);
+       //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));
@@ -591,7 +608,10 @@ void SUPERVGUI_Service::addMacroNode() {
        QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));         
        return;
       }
-      aNode->Coords(myX, myY);
+      //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));
@@ -606,7 +626,7 @@ void SUPERVGUI_Service::loadGraph() {
        if ( getenv( "ENABLE_MACRO_NODE" ) == NULL )
        // error! if ENABLE_MACRO_NODE is set - we should NOT get here by any means..
        {
-               //cout << "Error: ENABLE_MACRO_NODE is not set, but loadGraph() was called!" << endl;
+               //MESSAGE("Error: ENABLE_MACRO_NODE is not set, but loadGraph() was called!");
                return;
        }
 
@@ -663,7 +683,8 @@ void SUPERVGUI_Service::choose() {
 void SUPERVGUI_Service::showEvent(QShowEvent* theEvent) {
   SUPERVGUI_Main* aMain = Supervision.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);
 }
@@ -679,8 +700,7 @@ void SUPERVGUI_Service::tabChanged(QWidget* theWidget) {
 //  Pane for Python script editing
 //*****************************************************
 SUPERVGUI_PythonEditPane::SUPERVGUI_PythonEditPane(QWidget* theParent) 
-  : QFrame(theParent),
-    myIStream(0)
+  : QFrame(theParent)
 {
   QGridLayout* aEditLayout = new QGridLayout(this, 2, 4);
 
@@ -704,6 +724,45 @@ SUPERVGUI_PythonEditPane::SUPERVGUI_PythonEditPane(QWidget* theParent)
   aEditLayout->addMultiCellWidget(myText, 1, 1, 0, 3);
 }
    
+/**
+ * Searches for text beginning with "def" and ending with any meanful character at 
+ * beginning of line.  Starts searching with current position of given stream.
+ * Fills the myPyFunctions with strings corresponding to found fucntions.
+ */
+void SUPERVGUI_PythonEditPane::initPyFunctions( QTextStream& theStream ) {
+
+  if ( theStream.atEnd() )
+    return;
+
+  QString aPyFunction;
+  QString aLine = theStream.readLine(); 
+
+  while ( !theStream.atEnd() ) { // not EOF
+
+    // asv : 23.11.04 : fix for PAL6870 : skip empty lines in the beginning or  between functions
+    //       find("def)==0 -> analizing only global function definitions which start with 0 indentation
+    while ( !aLine.isNull() && aLine.find( "def" ) != 0 ) 
+      aLine = theStream.readLine();
+    
+    if ( !aLine.isNull() && aLine.find("def") == 0 ) { 
+      aPyFunction += aLine;
+      aPyFunction += '\n'; 
+
+      // read function body
+      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() ) ) {
+       aPyFunction += aLine;
+       aPyFunction += '\n'; 
+       aLine = theStream.readLine();
+      }
+
+      myPyFunctions << aPyFunction;
+      aPyFunction.setLength( 0 );
+    }
+  }
+}
 
 /**
  * Load existing Python script
@@ -716,77 +775,50 @@ void SUPERVGUI_PythonEditPane::loadFile() {
                                               true);
   if (aFileName.isEmpty()) return;
 
-  myFile = new QFile(aFileName);
-  if (!myFile->open(IO_ReadOnly)) {
+  QFile aFile( aFileName );
+  if (!aFile.open(IO_ReadOnly)) {
     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), 
                         tr("MSG_CANT_LOADSCRIPT"));
     return;
   }
-  myIStream = new QTextStream(myFile);
 
-  if (myIStream->atEnd()) {
-    QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), 
-                        tr("MSG_EMTY_FILE"));
-    myNextBtn->setEnabled(false);
-    delete myIStream;
-    myIStream = 0;
-    myFile->close();
-    delete myFile;
+  myPyFunctions.clear();
+  myPyIndex = -1;
+  myNextBtn->setEnabled( false );
+  myText->clear();
+
+  QTextStream aFileReader(&aFile);
+  if ( aFileReader.atEnd() ) {
+    QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_EMTY_FILE"));
+    aFile.close();
     return;
   }
-  myNextBtn->setEnabled(true);
-  readFunction();
+
+  initPyFunctions( aFileReader );
+
+  if ( myPyFunctions.size() ) {
+    myNextBtn->setEnabled( true );
+    myPyIndex = 0;
+    readFunction();
+  }
 }
   
-
 /**
  * Finds and Reads a function from current position in the opened file
+ * 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() {
-  if (!myIStream) return;
-
-  while (!myIStream->atEnd()) {
-    QString aLine = myIStream->readLine();
-    if (aLine.isNull()) return;
-
-    // find first function
-    int aDefPos = aLine.find("def");
-    if (aDefPos == 0) { // only not a class members
-      myText->clear();
-      // find name
-      /*int aStart = aLine.find(" ", aDefPos);
-      int aEnd = aLine.find("(", aStart);
-      QString aName = aLine.mid(aStart, (aEnd-aStart));
-      aName = aName.stripWhiteSpace();
-      myNameEdt->setText(aName);*/
-      
-      // find input params
-      /*aStart = aEnd+1;
-      aEnd = aLine.find(")", aStart);
-      QString aParams = aLine.mid(aStart, (aEnd-aStart));
-      aParams = aParams.stripWhiteSpace();
-      myParamEdt->setText(aParams);*/
-
-      myText->append(aLine);
-      // read body
-      QString aBodyLine = myIStream->readLine();
-      while ((!aBodyLine.isNull()) && aBodyLine[0].isSpace()) {
-       myText->append(aBodyLine);
-       aBodyLine = myIStream->readLine();
-      }
-      return;
-    }
-  }
-  QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), 
-                        tr("MSG_NOMORE_FUNCTIONS"));
-  delete myIStream;
-  myIStream = 0;
-  myNextBtn->setEnabled(false);
-  myFile->close();
-  delete myFile;
+  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 );
 }
 
-
+/**
+ * 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++) {
@@ -802,12 +834,21 @@ QString SUPERVGUI_PythonEditPane::getFuncName() {
   return aName;
 }
 
-
+/**
+ * Returns the contents of the myText widget without trailing spacing 
+ */
 SUPERV_Strings SUPERVGUI_PythonEditPane::getFunction() {
   SUPERV_Strings aStrings = new SUPERV::ListOfStrings();
   aStrings->length(myText->paragraphs());
   for (int i=0; i < myText->paragraphs(); i++) {
-    aStrings[i] = CORBA::string_dup(myText->text(i).latin1());
+    QString aLine = myText->text(i);
+    // asv : 30.11.04 - why do we have to remove trailing spaces??  
+    // 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);
+    aStrings[i] = CORBA::string_dup(aLine.latin1());
   }
   return aStrings._retn();
 }
@@ -817,6 +858,12 @@ void SUPERVGUI_PythonEditPane::setFunction(SUPERV_Strings theStr) {
   int aLen = theStr->length();
   for (int i=0; i < aLen; i++)
     myText->append(QString(theStr[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 );
 }