Salome HOME
Update Help for VISU module.
[modules/visu.git] / src / VISU_I / VISU_Table_i.cc
index 0c683dc3bf98503b26ae309d2d45bdde33ec8abc..dfe598c17574bfcdcd45796b99cff850082fe3c1 100644 (file)
@@ -1,23 +1,23 @@
 //  VISU OBJECT : interactive object for VISU entities implementation
 //
 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
-// 
-//  This library is free software; you can redistribute it and/or 
-//  modify it under the terms of the GNU Lesser General Public 
-//  License as published by the Free Software Foundation; either 
-//  version 2.1 of the License. 
-// 
-//  This library is distributed in the hope that it will be useful, 
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
-//  Lesser General Public License for more details. 
-// 
-//  You should have received a copy of the GNU Lesser General Public 
-//  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 
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  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
 //
 //
 //  File   : VISU_Table_i.cc
 
 #include "VISU_Table_i.hh"
 
-#include "QAD_Application.h"
-#include "QAD_Desktop.h"
-#include "QAD_Study.h"
-
 #include "VISU_CutLines_i.hh"
+#include "VISU_Result_i.hh"
+#include "VISU_ViewManager_i.hh"
 
-#include <memory>      
-#include <fstream>     
+#include "SPlot2d_Curve.h"
+
+#include <memory>
+#include <fstream>
 #include <strstream>
 
 #include <qfileinfo.h>
+#include <qstring.h>
 #include <qfile.h>
 
 using namespace std;
@@ -51,19 +52,19 @@ static int MYDEBUG = 0;
 //----------------------------------------------------------------
 int VISU::Table_i::myNbPresent = 0;
 const string VISU::Table_i::myComment  = "TABLE";
-/*! 
+/*!
   Generate unique name
 */
-const char* VISU::Table_i::GenerateName() 
-{ 
-  return VISU::GenerateName( "Table", ++myNbPresent ); 
+const char* VISU::Table_i::GenerateName()
+{
+  return VISU::GenerateName( "Table", ++myNbPresent );
 }
 /*!
   Gets comment string
 */
-const char* VISU::Table_i::GetComment() const 
-{ 
-  return myComment.c_str(); 
+const char* VISU::Table_i::GetComment() const
+{
+  return myComment.c_str();
 }
 /*!
   Constructor
@@ -126,8 +127,8 @@ CORBA::Long VISU::Table_i::GetNbColumns()
 */
 VISU::Storable* VISU::Table_i::Create()
 {
-  // generate name ... 
-  myName = GetTableTitle(); 
+  // generate name ...
+  myName = GetTableTitle();
 
   // mpv (PAL 5357): if name attribute already exist at this label, use it as name of table
   if ( myName == "" )
@@ -151,9 +152,9 @@ VISU::Storable* VISU::Table_i::Create()
 /*!
   Builds presentation of table
 */
-VISU::Storable* VISU::Table_i::Build( int theRestoring ) 
+VISU::Storable* VISU::Table_i::Build( int theRestoring )
 {
-  
+
   // look for reference SObject with table attribute
   SALOMEDS::SObject_var SO = mySObj;
 
@@ -172,14 +173,34 @@ VISU::Storable* VISU::Table_i::Build( int theRestoring )
        SALOMEDS::SComponent_var SComponent = VISU::FindOrCreateVisuComponent( myStudy );
        // create SObject and set attributes
        QString aComment;
-       aComment.sprintf("myComment=%s;myType=%d",GetComment(),VISU::TTABLE);
-       string anEntry = CreateAttributes( myStudy, 
+       if(pCutLines)
+         aComment.sprintf("myComment=%s;myType=%d;mySourceId=CutLines",GetComment(),VISU::TTABLE);
+       else{
+         aComment.sprintf("myComment=%s;myType=%d;mySourceId=TableAttr",GetComment(),VISU::TTABLE);
+         SALOMEDS::SObject_var aFatherSObject = SO->GetFather();
+         if(aFatherSObject->FindAttribute(anAttr,"AttributeComment")){
+           SALOMEDS::AttributeComment_var aCommentAttr =
+             SALOMEDS::AttributeComment::_narrow(anAttr);
+           CORBA::String_var aValue = aCommentAttr->Value();
+           Storable::TRestoringMap aMap;
+           Storable::StrToMap(aValue.in(),aMap);
+           bool anIsExist;
+           QString aMethodName = VISU::Storable::FindValue(aMap,"myComment",&anIsExist);
+           if(anIsExist){
+             if(strcmp(aMethodName.latin1(),"ImportTables") == 0){
+               aComment.sprintf("myComment=%s;myType=%d;mySourceId=TableFile",GetComment(),VISU::TTABLE);
+             }
+           }
+         }
+       }
+
+       string anEntry = CreateAttributes( myStudy,
                                          SO->GetID(),//SComponent->GetID(),
                                          "",
                                          GetID(),
                                          GetName(),
                                          "",
-                                         aComment.latin1(), 
+                                         aComment.latin1(),
                                          pCutLines );
        // create SObject referenced to real table object
        mySObj = SALOMEDS::SObject::_duplicate(myStudy->FindObjectID( anEntry.c_str() ));
@@ -218,7 +239,7 @@ void VISU::Table_i::ToStream( std::ostringstream& theStr )
 /*!
   Called from engine to restore table from the file
 */
-VISU::Storable* VISU::Table_i::Restore(SALOMEDS::SObject_ptr theSObject, 
+VISU::Storable* VISU::Table_i::Restore(SALOMEDS::SObject_ptr theSObject,
                                       const string& thePrefix, const Storable::TRestoringMap& theMap)
 {
   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
@@ -235,7 +256,7 @@ const char* VISU::Table_i::GetTableTitle()
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
   SALOMEDS::AttributeTableOfReal_var    aReal;
-  if ( !SO->_is_nil() ) { 
+  if ( !SO->_is_nil() ) {
     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
       return anInt->GetTitle();
@@ -245,7 +266,13 @@ const char* VISU::Table_i::GetTableTitle()
       return aReal->GetTitle();
     }
   }
-  return ""; 
+  return "";
+}
+
+void VISU::Table_i::RemoveFromStudy()
+{
+  // Remove the table with all curves
+  VISU::RemoveFromStudy(mySObj,false);
 }
 
 //----------------------------------------------------------------
@@ -266,19 +293,19 @@ static VISU::Table_i* GetTable( SALOMEDS::Study_ptr theStudy, SALOMEDS::SObject_
 
 int VISU::Curve_i::myNbPresent = 0;
 const string VISU::Curve_i::myComment  = "CURVE";
-/*! 
+/*!
   Generate unique name
 */
-const char* VISU::Curve_i::GenerateName() 
-{ 
-  return VISU::GenerateName( "Curve", ++myNbPresent ); 
+const char* VISU::Curve_i::GenerateName()
+{
+  return VISU::GenerateName( "Curve", ++myNbPresent );
 }
 /*!
   Gets comment string
 */
-const char* VISU::Curve_i::GetComment() const 
-{ 
-  return myComment.c_str(); 
+const char* VISU::Curve_i::GetComment() const
+{
+  return myComment.c_str();
 }
 /*!
   Constructor
@@ -305,8 +332,8 @@ VISU::Curve_i::~Curve_i()
 */
 VISU::Storable* VISU::Curve_i::Create()
 {
-  // generate name ... 
-  myName = GetVerTitle(); 
+  // generate name ...
+  myName = GetVerTitle();
   if ( myName == "" )
     myName = GenerateName();
   // ... and build the object
@@ -315,7 +342,7 @@ VISU::Storable* VISU::Curve_i::Create()
 /*!
   Builds presentation of curve
 */
-VISU::Storable* VISU::Curve_i::Build(int theRestoring ) 
+VISU::Storable* VISU::Curve_i::Build(int theRestoring )
 {
   if ( myTable != NULL ) {
     // getting table SObject by it's entry
@@ -327,7 +354,7 @@ VISU::Storable* VISU::Curve_i::Build(int theRestoring )
        // create SObject and set attributes
        QString aComment;
        aComment.sprintf("myComment=%s;myType=%d",GetComment(),VISU::TCURVE);
-       string anEntry = CreateAttributes( myStudy, 
+       string anEntry = CreateAttributes( myStudy,
                                          myTable->GetObjectEntry(),
                                          "",
                                          GetID(),
@@ -355,7 +382,7 @@ CORBA::Boolean VISU::Curve_i::IsValid()
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
   SALOMEDS::AttributeTableOfReal_var    aReal;
-  if ( !SO->_is_nil() ) { 
+  if ( !SO->_is_nil() ) {
     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
       if ( myHRow > 0 && myHRow <= anInt->GetNbRows() && myVRow > 0 && myVRow <= anInt->GetNbRows() ) {
@@ -383,19 +410,19 @@ string VISU::Curve_i::GetHorTitle()
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
   SALOMEDS::AttributeTableOfReal_var    aReal;
-  if ( !SO->_is_nil() ) { 
+  if ( !SO->_is_nil() ) {
     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
       SALOMEDS::StringSeq_var rowTitles = anInt->GetRowTitles();
       if ( rowTitles->length() > 0 && myHRow > 0 && myHRow <= anInt->GetNbRows() ) {
-       title = strdup( rowTitles[ myHRow-1 ] );
+       title = rowTitles[ myHRow-1 ];
       }
     }
     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
       SALOMEDS::StringSeq_var rowTitles = aReal->GetRowTitles();
       if ( rowTitles->length() > 0 && myHRow > 0 && myHRow <= aReal->GetNbRows() ) {
-       title = strdup( rowTitles[ myHRow-1 ] );
+       title = rowTitles[ myHRow-1 ];
       }
     }
   }
@@ -413,18 +440,18 @@ string VISU::Curve_i::GetVerTitle()
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
   SALOMEDS::AttributeTableOfReal_var    aReal;
-  if ( !SO->_is_nil() ) { 
+  if ( !SO->_is_nil() ) {
     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
       SALOMEDS::StringSeq_var rowTitles = anInt->GetRowTitles();
       if ( rowTitles->length() > 0 && myVRow > 0 && myVRow <= anInt->GetNbRows() )
-       title = strdup( rowTitles[ myVRow-1 ] );
+       title = rowTitles[ myVRow-1 ];
     }
     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
       SALOMEDS::StringSeq_var rowTitles = aReal->GetRowTitles();
       if ( rowTitles->length() > 0 && myVRow > 0 && myVRow <= aReal->GetNbRows() )
-       title = strdup( rowTitles[ myVRow-1 ] );
+       title = rowTitles[ myVRow-1 ];
     }
   }
   return title;
@@ -441,18 +468,18 @@ string VISU::Curve_i::GetHorUnits()
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
   SALOMEDS::AttributeTableOfReal_var    aReal;
-  if ( !SO->_is_nil()  ) { 
+  if ( !SO->_is_nil()  ) {
     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
       SALOMEDS::StringSeq_var rowUnits = anInt->GetRowUnits();
       if ( rowUnits->length() > 0 && myHRow > 0 && myHRow <= anInt->GetNbRows() )
-       units = strdup( rowUnits[ myHRow-1 ] );
+       units = rowUnits[ myHRow-1 ];
     }
     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
       SALOMEDS::StringSeq_var rowUnits = aReal->GetRowUnits();
       if ( rowUnits->length() > 0 && myHRow > 0 && myHRow <= aReal->GetNbRows() )
-       units = strdup( rowUnits[ myHRow-1 ] );
+       units = rowUnits[ myHRow-1 ];
     }
   }
   return units;
@@ -469,18 +496,18 @@ string VISU::Curve_i::GetVerUnits()
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
   SALOMEDS::AttributeTableOfReal_var    aReal;
-  if ( !SO->_is_nil() ) { 
+  if ( !SO->_is_nil() ) {
     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
       SALOMEDS::StringSeq_var rowUnits = anInt->GetRowUnits();
       if ( rowUnits->length() > 0 && myVRow > 0 && myVRow <= anInt->GetNbRows() )
-       units = strdup( rowUnits[ myVRow-1] );
+       units = rowUnits[ myVRow-1];
     }
     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
       SALOMEDS::StringSeq_var rowUnits = aReal->GetRowUnits();
       if ( rowUnits->length() > 0 && myVRow > 0 && myVRow <= aReal->GetNbRows() )
-       units = strdup( rowUnits[ myVRow-1 ] );
+       units = rowUnits[ myVRow-1 ];
     }
   }
   return units;
@@ -497,10 +524,10 @@ int VISU::Curve_i::GetData( double*& theHorList, double*& theVerList )
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
   SALOMEDS::AttributeTableOfReal_var    aReal;
-  if ( !SO->_is_nil() ) { 
+  if ( !SO->_is_nil() ) {
     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
-      int nbCols = anInt->GetNbColumns() ; 
+      int nbCols = anInt->GetNbColumns() ;
       if ( nbCols > 0 && myHRow > 0 && myHRow <= anInt->GetNbRows() && myVRow > 0 && myVRow <= anInt->GetNbRows() ) {
        int nbPoints = 0;
        for ( int j = 1; j <= nbCols; j++ ) {
@@ -524,7 +551,7 @@ int VISU::Curve_i::GetData( double*& theHorList, double*& theVerList )
     }
     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
-      int nbCols = aReal->GetNbColumns() ; 
+      int nbCols = aReal->GetNbColumns() ;
       if ( nbCols > 0 && myHRow > 0 && myHRow <= aReal->GetNbRows() && myVRow > 0 && myVRow <= aReal->GetNbRows() ) {
        int nbPoints = 0;
        for ( int j = 1; j <= nbCols; j++ ) {
@@ -552,11 +579,11 @@ int VISU::Curve_i::GetData( double*& theHorList, double*& theVerList )
 /*!
   Creates curve Plot2d presentation object
 */
-Plot2d_Curve* VISU::Curve_i::CreatePresentation()
+SPlot2d_Curve* VISU::Curve_i::CreatePresentation()
 {
-  Plot2d_Curve* crv = new Plot2d_Curve();
+  SPlot2d_Curve* crv = new SPlot2d_Curve();
   crv->setHorTitle( GetHorTitle().c_str() );
-  string tlt = GetTitle(); 
+  string tlt = GetTitle();
   if ( tlt.length() <= 0 )
     tlt = GetVerTitle();
   //crv->setVerTitle( strdup( GetVerTitle().c_str() ) );
@@ -575,13 +602,13 @@ Plot2d_Curve* VISU::Curve_i::CreatePresentation()
   //  cout << i<<"\t"<<xList[i] << "\t"<< yList[i] << endl;
   //}
   crv->setLine( (Plot2d_Curve::LineType)GetLine(), GetLineWidth() );
-  crv->setMarker( (Plot2d_Curve::MarkerType)GetMarker() ); 
+  crv->setMarker( (Plot2d_Curve::MarkerType)GetMarker() );
   SALOMEDS::Color color = GetColor();
   crv->setColor( QColor( (int)(color.R*255.), (int)(color.G*255.), (int)(color.B*255.) ) );
   crv->setAutoAssign( IsAuto() );
-  crv->setIO(new SALOME_InteractiveObject(strdup(mySObj->GetID()),"VISU",strdup(GetName()))); 
+  crv->setIO(new SALOME_InteractiveObject(mySObj->GetID(),"VISU",GetName()));
   if ( myTable )
-    crv->setTableIO(new SALOME_InteractiveObject(strdup(myTable->GetObjectEntry()),"VISU",strdup(myTable->GetName()))); 
+    crv->setTableIO(new SALOME_InteractiveObject(myTable->GetObjectEntry(),"VISU",myTable->GetName()));
   return crv;
 }
 /*!
@@ -622,13 +649,13 @@ void VISU::Curve_i::ToStream( std::ostringstream& theStr )
 /*!
   Gets reference table's entry
 */
-const char* VISU::Curve_i::GetTableID() { 
-  return CORBA::string_dup(myTable->GetObjectEntry());
+const char* VISU::Curve_i::GetTableID() {
+  return myTable->GetObjectEntry();
 }
 /*!
   Called from engine to restore curve from the file
 */
-VISU::Storable* VISU::Curve_i::Restore(SALOMEDS::SObject_ptr theSObject, 
+VISU::Storable* VISU::Curve_i::Restore(SALOMEDS::SObject_ptr theSObject,
                                       const string& thePrefix, const Storable::TRestoringMap& theMap)
 {
   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
@@ -640,24 +667,35 @@ VISU::Storable* VISU::Curve_i::Restore(SALOMEDS::SObject_ptr theSObject,
   return NULL;
 }
 
+void VISU::Curve_i::RemoveFromStudy()
+{
+  VISU::DeleteActors(this);
+  VISU::RemoveFromStudy(mySObj,false);
+}
+
+SALOMEDS::SObject_var VISU::Curve_i::GetSObject()
+{
+  return mySObj;
+}
+
 //----------------------------------------------------------------
 //                      Container Object
 //----------------------------------------------------------------
 int VISU::Container_i::myNbPresent = 0;
 const string VISU::Container_i::myComment  = "CONTAINER";
-/*! 
+/*!
   Generate unique name
 */
-const char* VISU::Container_i::GenerateName() 
-{ 
-  return VISU::GenerateName( "Plot2DView", ++myNbPresent ); 
+const char* VISU::Container_i::GenerateName()
+{
+  return VISU::GenerateName( "Plot2DView", ++myNbPresent );
 }
 /*!
   Gets comment string
 */
-const char* VISU::Container_i::GetComment() const 
-{ 
-  return myComment.c_str(); 
+const char* VISU::Container_i::GetComment() const
+{
+  return myComment.c_str();
 }
 /*!
   Constructor
@@ -761,7 +799,7 @@ void VISU::Container_i::Clear()
 */
 VISU::Storable* VISU::Container_i::Create()
 {
-  // generate name ... 
+  // generate name ...
   myName = GenerateName();
   // ... and build the object
   return Build( false );
@@ -769,7 +807,7 @@ VISU::Storable* VISU::Container_i::Create()
 /*!
   Builds presentation of container
 */
-VISU::Storable* VISU::Container_i::Build( int theRestoring ) 
+VISU::Storable* VISU::Container_i::Build( int theRestoring )
 {
   if ( !theRestoring ) {
     // looking for component
@@ -777,7 +815,7 @@ VISU::Storable* VISU::Container_i::Build( int theRestoring )
     // create SObject and set attributes
     QString aComment;
     aComment.sprintf("myComment=%s;myType=%d",GetComment(),VISU::TCONTAINER);
-    string anEntry = CreateAttributes( myStudy, 
+    string anEntry = CreateAttributes( myStudy,
                                       SComponent->GetID(),
                                       "",
                                       GetID(),
@@ -785,6 +823,7 @@ VISU::Storable* VISU::Container_i::Build( int theRestoring )
                                       "",
                                       aComment.latin1(),
                                       true );
+    mySObj = SALOMEDS::SObject::_duplicate(myStudy->FindObjectID(anEntry.c_str()));
   }
   return this;
 }
@@ -804,7 +843,7 @@ void VISU::Container_i::Update()
     for ( i = 0; i < myCurves.count(); i++ ) {
       SALOMEDS::SObject_var SO = myStudy->FindObjectID( myCurves[i].latin1() );
       if ( !SO->_is_nil() && Builder->FindAttribute( SO, anAttr, "AttributeIOR" ) ) {
-       // if real Curve Object still exists 
+       // if real Curve Object still exists
        SALOMEDS::ChildIterator_var CI = myStudy->NewChildIterator( mySO );
        bool bFound = false;
        for ( ; CI->More(); CI->Next() ) {
@@ -825,7 +864,7 @@ void VISU::Container_i::Update()
        toDelete.append( myCurves[i] );
       }
     }
-    for ( i = 0; i < toDelete.count(); i++ ) { 
+    for ( i = 0; i < toDelete.count(); i++ ) {
       myCurves.remove( toDelete[i] );
     }
     toDelete.clear();
@@ -838,7 +877,7 @@ void VISU::Container_i::Update()
        toDelete.append( childSO->GetID() );
       }
     }
-    for ( i = 0; i < toDelete.count(); i++ ) { 
+    for ( i = 0; i < toDelete.count(); i++ ) {
       SALOMEDS::ChildIterator_var CI = myStudy->NewChildIterator( mySO );
       for ( ; CI->More(); CI->Next() ) {
        SALOMEDS::SObject_var childSO = CI->Value();
@@ -861,7 +900,7 @@ VISU::Curve_i* VISU::Container_i::GetCurve( CORBA::Long theIndex )
     SALOMEDS::SObject_var SO = myStudy->FindObjectID( myCurves[  theIndex-1 ].latin1() );
     CORBA::Object_var anObject = VISU::SObjectToObject( SO );
     if( !CORBA::is_nil( anObject ) ) {
-      // if real Curve Object exists 
+      // if real Curve Object exists
       CORBA::Object_ptr aCurve = VISU::Curve::_narrow( anObject );
       if( !CORBA::is_nil( aCurve ) )
       return dynamic_cast<VISU::Curve_i*>(VISU::GetServant(aCurve).in());
@@ -872,10 +911,11 @@ VISU::Curve_i* VISU::Container_i::GetCurve( CORBA::Long theIndex )
 /*!
   Restores container data from the stream
 */
-VISU::Storable* VISU::Container_i::Restore( const Storable::TRestoringMap& theMap )
+VISU::Storable* VISU::Container_i::Restore( const Storable::TRestoringMap& theMap, SALOMEDS::SObject_ptr SO )
 {
   if(MYDEBUG) MESSAGE(GetComment());
-  myName = VISU::Storable::FindValue( theMap, "myName" ).latin1(); 
+  mySObj = SALOMEDS::SObject::_duplicate(SO);
+  myName = VISU::Storable::FindValue( theMap, "myName" ).latin1();
   QString val = VISU::Storable::FindValue( theMap, "myCurves" );
   myCurves = QStringList::split( QString( "*" ), val, false );
   return Build( true );
@@ -893,18 +933,23 @@ void VISU::Container_i::ToStream( std::ostringstream& theStr )
 /*!
   Called from engine to restore container from the file
 */
-VISU::Storable* VISU::Container_i::Restore(SALOMEDS::SObject_ptr theSObject, 
+VISU::Storable* VISU::Container_i::Restore(SALOMEDS::SObject_ptr theSObject,
                                           const string& thePrefix, const Storable::TRestoringMap& theMap)
 {
   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
   VISU::Container_i* pResent = new VISU::Container_i( aStudy );
-  return pResent->Restore( theMap );
+  return pResent->Restore( theMap, theSObject );
+}
+
+void VISU::Container_i::RemoveFromStudy()
+{
+  VISU::RemoveFromStudy(mySObj,false);
 }
 
 //-------------------------------------------------------------
 //             Implementation of reading from file
 //-------------------------------------------------------------
-typedef double TValue;
+typedef string TValue;
 typedef vector<TValue> TValues;
 
 struct TRow{
@@ -928,7 +973,7 @@ struct TTable2D {
     if(myColumnUnits.size() != iEnd) myColumnUnits.resize(iEnd);
     int jEnd = myRows.size();
     for(int j = 0; j < jEnd; j++)
-      if(myRows[j].myValues.size() != iEnd) 
+      if(myRows[j].myValues.size() != iEnd)
        return 0;
     return 1;
   }
@@ -974,84 +1019,127 @@ int getLine(ifstream& theStmIn, QString& theString){
 }
 
 void ImportTables(const char* theFileName, TTableCont& theTableCont){
-  static int STRPRECISION = 12;
   ifstream aStmIn;
-  QFileInfo aFileInfo(theFileName);
-  if(!aFileInfo.isFile() || !aFileInfo.isReadable() || !aFileInfo.size()) return;
-  aStmIn.open(theFileName);
+  QFileInfo aFileInfo( theFileName );
+  if( !aFileInfo.isFile() || !aFileInfo.isReadable() || !aFileInfo.size() )
+    return;
+  aStmIn.open( theFileName );
   QString aTmp;
-  do{
-    //Find beginning of Table
-    while(getLine(aStmIn,aTmp) && aTmp == "\n");
-    if(MYDEBUG) cout<<"\n There is new Table2D with Title = ";
+  do {
+    // find beginning of table (tables are separated by empty lines)
+    while( getLine( aStmIn, aTmp ) && aTmp.stripWhiteSpace() == "");
     TTable2D aTable2D;
-    while(!aStmIn.eof() && aTmp != "\n"){
-      if(aTmp.find("#TITLE:") == 0){
-       int aLen = aTmp.find(":") + 1;
-       aTmp.remove(0,aLen);
-       QString aTitle = aTmp.stripWhiteSpace();
-       aTable2D.myTitle = aTitle.latin1();
-       if(MYDEBUG) cout<<aTitle<<endl;
-      }else if(aTmp.find("#COLUMN_TITLES:") == 0){
-       int aLen = aTmp.find(":") + 1;
-       aTmp.remove(0,aLen);
-       QStringList aStrList = QStringList::split("|",aTmp);
-       if(MYDEBUG) cout<<"Its Column Titles : ";
-       for(int i = 0; i < aStrList.count(); i++){
-         aTmp = aStrList[i].stripWhiteSpace();
-         aTable2D.myColumnTitles.push_back(aTmp.latin1());
-         if(MYDEBUG) cout<<"\t"<<aTmp;
+    if(MYDEBUG) cout << "New table is found" << endl;
+    while( !aStmIn.eof() && aTmp.stripWhiteSpace() != "" ){
+      QString data = aTmp.stripWhiteSpace();
+      QString cmt = "";
+      QString keyword = "";
+      // split string to data and comment (comment starts from '#' symbol)
+      int index = aTmp.find( "#" );
+      if ( index >= 0 ) {
+       data = aTmp.left( index ).stripWhiteSpace();
+       cmt = aTmp.mid( index+1 ).stripWhiteSpace();
+      }
+      // if comment is not empty, try to get keyword from it (separated by ':' symbol)
+      if ( !cmt.isEmpty() ) {
+       int index1 = cmt.find( ":" );
+       if ( index1 >= 0 ) {
+         QString tmpstr = cmt.left( index1 ).stripWhiteSpace();
+         if ( tmpstr == QString( "TITLE" ) ||
+              tmpstr == QString( "COLUMN_TITLES" ) ||
+              tmpstr == QString( "COLUMN_UNITS" ) ||
+              tmpstr == QString( "COMMENT" ) ) {
+           keyword = tmpstr;
+           cmt = cmt.mid( index1+1 ).stripWhiteSpace();
+         }
        }
-       if(MYDEBUG) cout<<endl;
-      }else if(aTmp.find("#COLUMN_UNITS:") == 0){
-       int aLen = aTmp.find(":") + 1;
-       aTmp.remove(0,aLen);
-       QStringList aStrList = QStringList::split(" ",aTmp);
-       if(MYDEBUG) cout<<"Its Column Units : ";
-       for(int i = 0; i < aStrList.count(); i++){
-         aTmp = aStrList[i].stripWhiteSpace();
-         aTable2D.myColumnUnits.push_back(aTmp.latin1());
-         if(MYDEBUG) cout<<"\t"<<aTmp;
+      }
+      // if data is empty, process only comment
+      if ( data.isEmpty() ) {
+       // if keyword is found, try to process it
+       // elsewise it is a simple comment, just ignore it
+       if ( !keyword.isEmpty() ) {
+         if ( keyword == QString( "TITLE" ) ) {
+           QString title = cmt;
+           if ( aTable2D.myTitle != "" )
+             title = QString( aTable2D.myTitle.c_str() ) + QString( " " ) + title;
+           if(MYDEBUG) cout << "...Table TITLE is: " << title.latin1() << endl;
+           aTable2D.myTitle = title.latin1();
+         }
+         else if ( keyword == QString( "COLUMN_TITLES" ) ) {
+           // comment may contain column headers
+           QStringList aStrList = QStringList::split( "|", cmt );
+           if(MYDEBUG) cout << "...Column TITLES are: ";
+           for ( int i = 0; i < aStrList.count(); i++ ) {
+             QString tmpstr = aStrList[ i ].stripWhiteSpace();
+             if(MYDEBUG) cout << tmpstr.latin1() << " ";
+             aTable2D.myColumnTitles.push_back( tmpstr.latin1() );
+           }
+           if(MYDEBUG) cout << endl;
+         }
+         else if ( keyword == QString( "COLUMN_UNITS" ) ) {
+           // comment may contain column units
+           QStringList aStrList = QStringList::split( " ", cmt );
+           if(MYDEBUG) cout << "...Column UNITS are: ";
+           for ( int i = 0; i < aStrList.count(); i++ ) {
+             QString tmpstr = aStrList[ i ].stripWhiteSpace();
+             if(MYDEBUG) cout << tmpstr.latin1() << " ";
+             aTable2D.myColumnUnits.push_back( tmpstr.latin1() );
+           }
+           if(MYDEBUG) cout << endl;
+         }
+         else if ( keyword == QString( "COMMENT" ) ) {
+           // keyword 'COMMENT' processing can be here
+           // currently it is ignored
+           if(MYDEBUG) cout << "...COMMENT: " << cmt.latin1() << endl;
+         }
        }
-       if(MYDEBUG) cout<<endl;
-      }else if(aTmp.find("#") == 0){
-       //It is a comment
-      }else if(aTmp.find("#TITLE:") > 0){
-       QStringList aStrList = QStringList::split("#TITLE:",aTmp);
-       QString aTitle = aStrList[1].stripWhiteSpace();
-       TRow aRow; 
-       aRow.myTitle = aTitle.latin1();
-       if(MYDEBUG) cout<<aTitle<<" : ";
-       QStringList aValList = QStringList::split(" ",aStrList[0]);
-       for(int i = 0; i < aValList.count(); i++){
-         float aVal = aValList[i].toFloat();
-         aRow.myValues.push_back(aVal);
-         if(MYDEBUG) cout<<"\t"<<aVal;
+       else {
+         if(MYDEBUG) cout << "...comment: " << cmt.latin1() << endl;
+         // simple comment processing can be here
+         // currently it is ignored
        }
-       aTable2D.myRows.push_back(aRow);
-       if(MYDEBUG) cout<<endl;
-      }else{
+      }
+      // if data is not empty, try to process it
+      else {
        TRow aRow;
+       if(MYDEBUG) cout << "...New row is found: " << endl;
+       if ( !cmt.isEmpty() ) {
+         aRow.myTitle = cmt.latin1();
+         if(MYDEBUG) cout << "......ROW TITLE is: " << cmt.latin1() << endl;
+       }
+       QStringList aValList = QStringList::split( " ", data );
+       for ( int i = 0; i < aValList.count(); i++ ) {
+         if ( aValList[i].stripWhiteSpace() != "" ) {
+           TValue aVal = aValList[i].stripWhiteSpace().latin1();
+           aRow.myValues.push_back( aVal );
+         }
+       }
+       if( aRow.myValues.size() > 0 )
+         aTable2D.myRows.push_back( aRow );
+       // ************** OLD CODE ******************
+       /*
        TValue aVal;
-       istrstream aStream(aTmp);
-       aStream.precision(STRPRECISION);
-       while(aStream>>aVal){
-         aRow.myValues.push_back(aVal);
-         if(MYDEBUG) cout<<"\t"<<aVal;
+       istrstream aStream( data );
+       aStream.precision( STRPRECISION );
+       while( aStream >> aVal ) {
+         aRow.myValues.push_back( aVal );
        }
-       if(aRow.myValues.size() > 0)
-         aTable2D.myRows.push_back(aRow);
-       if(MYDEBUG) cout<<endl;
+       if( aRow.myValues.size() > 0 )
+         aTable2D.myRows.push_back( aRow );
+       */
+       // ************** OLD CODE ******************
       }
-      getLine(aStmIn,aTmp);
+      getLine( aStmIn, aTmp );
     }
-    if(aTable2D.Check()){
-      if(MYDEBUG) cout<<"aTable2D checked "<<aTable2D.myTitle<<endl;
-      theTableCont.push_back(aTable2D);
+    if( aTable2D.Check() ) {
+      if(MYDEBUG) cout << "aTable2D is checked OK " << aTable2D.myTitle << endl;
+      theTableCont.push_back( aTable2D );
     }
-  }while(!aStmIn.eof());
+  }
+  while( !aStmIn.eof() );
   aStmIn.close();
-  if(MYDEBUG) cout<<"After close"<<endl;
+  if(MYDEBUG) cout << "After close" << endl;
 }
 
 SALOMEDS::SObject_var VISU::ImportTables(const char* theFileName, SALOMEDS::Study_ptr theStudy){
@@ -1061,12 +1149,17 @@ SALOMEDS::SObject_var VISU::ImportTables(const char* theFileName, SALOMEDS::Stud
   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
   SALOMEDS::SComponent_var theSComponent = VISU::FindOrCreateVisuComponent(theStudy);
   SALOMEDS::SObject_var aFileObject = aStudyBuilder->NewObject(theSComponent);
-  SALOMEDS::GenericAttribute_var anAttr = 
+  SALOMEDS::GenericAttribute_var anAttr =
     aStudyBuilder->FindOrCreateAttribute(aFileObject, "AttributeName");
   SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
   QFileInfo aFileInfo(theFileName);
   aName->SetValue(aFileInfo.fileName().latin1());
-  int iEnd = aTableCont.size();
+  anAttr = aStudyBuilder->FindOrCreateAttribute(aFileObject, "AttributeComment");
+  SALOMEDS::AttributeComment_var aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
+  QString aString;
+  aString.sprintf("myComment=ImportTables;myFileName=%s",
+                 aFileInfo.absFilePath().latin1());
+  aComment->SetValue(aString.latin1());
   for(int i = 0, iEnd = aTableCont.size(); i < iEnd; i++){
     const TTable2D& aTable2D = aTableCont[i];
     SALOMEDS::SObject_var aRealObject = aStudyBuilder->NewObject(aFileObject);
@@ -1088,12 +1181,16 @@ SALOMEDS::SObject_var VISU::ImportTables(const char* theFileName, SALOMEDS::Stud
     int kEnd = aNewTable2D.myRows[0].myValues.size();
     aTableOfReal->SetNbColumns(kEnd);
     for(int j = 0, jEnd = aNewTable2D.myRows.size(); j < jEnd; j++){
-      if(MYDEBUG) cout<<"j = "<<j<<endl;
-      SALOMEDS::DoubleSeq_var aDoubleSeq = new SALOMEDS::DoubleSeq();
-      aDoubleSeq->length(kEnd);
-      if(MYDEBUG) cout<<"kEnd = "<<kEnd<<endl;
-      for(int k = 0; k < kEnd; k++) aDoubleSeq[k] = aNewTable2D.myRows[j].myValues[k];
-      aTableOfReal->AddRow(aDoubleSeq.in());
+      if(MYDEBUG) cout<<"j = "<<j<<"; kEnd = "<<kEnd<<endl;
+
+      for(int k = 0; k < kEnd; k++){
+       QString aVal = aNewTable2D.myRows[j].myValues[k].c_str();
+       bool anIsOk = false;
+       double aValue = aVal.toDouble(&anIsOk);
+       if(anIsOk && !aVal.contains("NAN",false) && !aVal.contains("INF",false))
+         aTableOfReal->PutValue(aValue,j+1,k+1);
+      }
+
       aTableOfReal->SetRowTitle(j+1,aNewTable2D.myRows[j].myTitle.c_str());
       aTableOfReal->SetRowUnit(j+1,aNewTable2D.myRows[j].myUnit.c_str());
     }
@@ -1103,93 +1200,93 @@ SALOMEDS::SObject_var VISU::ImportTables(const char* theFileName, SALOMEDS::Stud
   return aFileObject;
 }
 
-template<class TTableAttr> bool ExportTableToFile(const TTableAttr& aTabAttr,  
+template<class TTableAttr> bool ExportTableToFile(const TTableAttr& aTabAttr,
                                                  const char* theFileName)
 {
   if (!CORBA::is_nil(aTabAttr)) {
-    QFile aFile(theFileName);  
-    aFile.open(IO_WriteOnly);  
+    QFile aFile(theFileName);
+    aFile.open(IO_WriteOnly);
 
-    /* extract the tabe info and write it into file */ 
-    
-    QString aTitle(aTabAttr->GetTitle()); /*Table title*/ 
-    int aRowsNb = aTabAttr->GetNbRows();  
-    int aColNb  = aTabAttr->GetNbColumns(); 
-    
-    SALOMEDS::StringSeq_var aRowTitles = aTabAttr->GetRowTitles(); 
-    QString anAbscissTitle(aRowTitles[0]); /*Absciss row title (X coord)*/ 
-    anAbscissTitle.stripWhiteSpace();       
+    /* extract the tabe info and write it into file */
 
-    SALOMEDS::StringSeq_var aRowUnits = aTabAttr->GetRowUnits(); 
-    QString anAbscissUnit(aRowUnits[0]); 
-    anAbscissUnit.stripWhiteSpace();     
-    
-    SALOMEDS::StringSeq_var aColumnTitles = aTabAttr->GetColumnTitles(); 
+    QString aTitle(aTabAttr->GetTitle()); /*Table title*/
+    int aRowsNb = aTabAttr->GetNbRows();
+    int aColNb  = aTabAttr->GetNbColumns();
+
+    SALOMEDS::StringSeq_var aRowTitles = aTabAttr->GetRowTitles();
+    QString anAbscissTitle(aRowTitles[0]); /*Absciss row title (X coord)*/
+    anAbscissTitle.stripWhiteSpace();
+
+    SALOMEDS::StringSeq_var aRowUnits = aTabAttr->GetRowUnits();
+    QString anAbscissUnit(aRowUnits[0]);
+    anAbscissUnit.stripWhiteSpace();
+
+    SALOMEDS::StringSeq_var aColumnTitles = aTabAttr->GetColumnTitles();
     if (aRowsNb > 2 && aTitle.length() )  aTitle = aTitle + " - ";
 
-    QString aLine;                      
-    for (int i = 2; i <= aRowsNb; i++ ) 
-      {                                 
-       /* TITLE */                     
-       QString anOrdinate(aRowTitles[i-1]), aTail; 
-       anOrdinate.stripWhiteSpace();                      
+    QString aLine;
+    for (int i = 2; i <= aRowsNb; i++ )
+      {
+       /* TITLE */
+       QString anOrdinate(aRowTitles[i-1]), aTail;
+       anOrdinate.stripWhiteSpace();
+
+       aLine = "#TITLE: " + aTitle +
+         ((anOrdinate.length())?  anOrdinate :
+                                 (aRowsNb>2)? aTail.sprintf("%d",i-1) : aTail.sprintf("") ) + "\n";
+       aFile.writeBlock(aLine, aLine.length() );
 
-       aLine = "#TITLE: " + aTitle +                              
-         ((anOrdinate.length())?  anOrdinate : 
-                                 (aRowsNb>2)? aTail.sprintf("%d",i-1) : aTail.sprintf("") ) + "\n"; 
-       aFile.writeBlock(aLine, aLine.length() );                               
-                                                                                   
-       /* COLUMN_TITLES */                                                     
-       if ( anAbscissTitle.length() || anOrdinate.length() ) {                    
-         aLine = "#COLUMN_TITLES: " + anAbscissTitle + " | " + anOrdinate + "\n";    
-         aFile.writeBlock(aLine, aLine.length() );                                
-       }                                                                          
+       /* COLUMN_TITLES */
+       if ( anAbscissTitle.length() || anOrdinate.length() ) {
+         aLine = "#COLUMN_TITLES: " + anAbscissTitle + " | " + anOrdinate + "\n";
+         aFile.writeBlock(aLine, aLine.length() );
+       }
 
-       /* COLUMN_UNITS */                           
-       aLine = anAbscissUnit + " " +aRowUnits[i-1]; 
-       if (!aLine.stripWhiteSpace().isEmpty()) {    
-         aLine = "#COLUMN_UNITS: " + aLine  + "\n"; 
-         aFile.writeBlock(aLine, aLine.length() );  
-       }    
+       /* COLUMN_UNITS */
+       aLine = anAbscissUnit + " " +aRowUnits[i-1];
+       if (!aLine.stripWhiteSpace().isEmpty()) {
+         aLine = "#COLUMN_UNITS: " + aLine  + "\n";
+         aFile.writeBlock(aLine, aLine.length() );
+       }
 
-       /* CURVE COORDINATES */                      
-       for (int j = 1; j <= aColNb; j++)            
-         {                                          
-           if ( aTabAttr -> HasValue(i,j) &&  aTabAttr -> HasValue(1, j)) { 
-             aLine = aLine.sprintf("%.16g %.16g",            
-                                   (double)(aTabAttr->GetValue(1,j)),  
-                                   (double)(aTabAttr->GetValue(i,j)));  /* aTabAttr->GetValue(1,j) - X coord */ 
-             if ( !aLine.stripWhiteSpace().isEmpty() ) {     
-               QString aColTitle(aColumnTitles[j-1]);        
-               if ( !aColTitle.stripWhiteSpace().isEmpty() ) 
-                 aLine = aLine + "  #TITLE: " + aColTitle ;  
-               aFile.writeBlock(aLine + "\n", aLine.length() + 1); 
-             }     
-           }       
-         }   
-       aFile.writeBlock("\n", 1); 
-      }             
-    aFile.close();  
-    return true;    
-  }                 
+       /* CURVE COORDINATES */
+       for (int j = 1; j <= aColNb; j++)
+         {
+           if ( aTabAttr -> HasValue(i,j) &&  aTabAttr -> HasValue(1, j)) {
+             aLine = aLine.sprintf("%.16g %.16g",
+                                   (double)(aTabAttr->GetValue(1,j)),
+                                   (double)(aTabAttr->GetValue(i,j)));  /* aTabAttr->GetValue(1,j) - X coord */
+             if ( !aLine.stripWhiteSpace().isEmpty() ) {
+               QString aColTitle(aColumnTitles[j-1]);
+               if ( !aColTitle.stripWhiteSpace().isEmpty() )
+                 aLine = aLine + "  #TITLE: " + aColTitle ;
+               aFile.writeBlock(aLine + "\n", aLine.length() + 1);
+             }
+           }
+         }
+       aFile.writeBlock("\n", 1);
+      }
+    aFile.close();
+    return true;
+  }
   return false;
 }
+
 bool VISU::ExportTableToFile(SALOMEDS::SObject_ptr theTable, const char* theFileName)
 {
   //Find table
   SALOMEDS::GenericAttribute_var anAttr ;
   if (theTable->FindAttribute(anAttr, "AttributeTableOfReal"))
     {
-      SALOMEDS::AttributeTableOfReal_var aTabAttr = SALOMEDS::AttributeTableOfReal ::_narrow(anAttr); 
+      SALOMEDS::AttributeTableOfReal_var aTabAttr = SALOMEDS::AttributeTableOfReal ::_narrow(anAttr);
       return ExportTableToFile ( aTabAttr , theFileName);
-      
+
     }
   else if (theTable->FindAttribute(anAttr, "AttributeTableOfInteger")) {
 
-    SALOMEDS::AttributeTableOfInteger_var aTabAttr = SALOMEDS::AttributeTableOfInteger ::_narrow(anAttr); 
+    SALOMEDS::AttributeTableOfInteger_var aTabAttr = SALOMEDS::AttributeTableOfInteger ::_narrow(anAttr);
     return ExportTableToFile ( aTabAttr , theFileName);
-    
+
   }
   return false;
 }