Salome HOME
Remove unused variables
[modules/visu.git] / src / VISU_I / VISU_Table_i.cc
index 1aba7769853f9f8acfc4b4e79796a825a25071fc..d588e45c279085e0ab0ec3e629e6c18b58fc14f9 100644 (file)
@@ -1,26 +1,53 @@
-using namespace std;
-// File:       VISU_Table_i.cc
-// Created:    Thu Feb 13 17:57:39 2003
-// Author:     Vadim SANDLER
-//             <vsr@rolex.nnov.matra-dtv.fr>
+//  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 
+//
+//
+//  File   : VISU_Table_i.cc
+//  Author : Vadim SANDLER
+//  Module : VISU
 
 #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 <memory>      
 #include <fstream>     
 #include <strstream>
+
 #include <qfileinfo.h>
-#include <qstringlist.h>
-#include <memory>      
+#include <qstring.h>
+#include <qfile.h>
+
+using namespace std;
 
-#ifdef DEBUG
-static int MYDEBUG = 1;
+#ifdef _DEBUG_
+static int MYDEBUG = 0;
 #else
 static int MYDEBUG = 0;
 #endif
-
 //----------------------------------------------------------------
 //                      Table Object
 //----------------------------------------------------------------
@@ -46,7 +73,7 @@ const char* VISU::Table_i::GetComment() const
 VISU::Table_i::Table_i( SALOMEDS::Study_ptr theStudy, const char* theObjectEntry )
      : PrsObject_i(theStudy)
 {
-  myObjectEntry = theObjectEntry; 
+  mySObj = SALOMEDS::SObject::_duplicate((theStudy->FindObjectID(theObjectEntry)));
   myOrientation = VISU::Table::HORIZONTAL;
 }
 /*!
@@ -54,19 +81,20 @@ VISU::Table_i::Table_i( SALOMEDS::Study_ptr theStudy, const char* theObjectEntry
 */
 VISU::Table_i::~Table_i()
 {
+  MESSAGE("Table_i::~Table_i");
 }
 /*!
   Gets number of rows in table
 */
 CORBA::Long VISU::Table_i::GetNbRows()
 {
-  SALOMEDS::SObject_var SO = myStudy->FindObjectID( myObjectEntry.c_str() );
+  SALOMEDS::SObject_var SO = mySObj;
   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
   if ( !SO->_is_nil() ) {
     SALOMEDS::GenericAttribute_var        anAttr;
     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
       SALOMEDS::AttributeTableOfInteger_var anInt =  SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
-      return anInt->GetNbRows();
+       return anInt->GetNbRows();
     }
     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
       SALOMEDS::AttributeTableOfReal_var aReal =  SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
@@ -80,7 +108,7 @@ CORBA::Long VISU::Table_i::GetNbRows()
 */
 CORBA::Long VISU::Table_i::GetNbColumns()
 {
-  SALOMEDS::SObject_var SO = myStudy->FindObjectID( myObjectEntry.c_str() );
+  SALOMEDS::SObject_var SO = mySObj;
   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
   if ( !SO->_is_nil() ) {
     SALOMEDS::GenericAttribute_var        anAttr;
@@ -101,7 +129,24 @@ CORBA::Long VISU::Table_i::GetNbColumns()
 VISU::Storable* VISU::Table_i::Create()
 {
   // generate name ... 
-  myName = GenerateName();
+  myName = GetTableTitle(); 
+
+  // mpv (PAL 5357): if name attribute already exist at this label, use it as name of table
+  if ( myName == "" )
+    if ( !mySObj->_is_nil() ) {
+      CutLines_i* pCutLines = NULL;
+      CORBA::Object_var anObj = SObjectToObject(mySObj);
+      if(!CORBA::is_nil(anObj)){
+       VISU::CutLines_var aCutLines = VISU::CutLines::_narrow(anObj);
+         if(!aCutLines->_is_nil())
+           pCutLines = dynamic_cast<CutLines_i*>(GetServant(aCutLines).in());
+       }
+      if (!pCutLines)
+       if (mySObj->GetName()) myName = mySObj->GetName();
+    }
+
+  if ( myName == "" )
+    myName = GenerateName();
   // ... and build the object
   return Build( false );
 }
@@ -110,74 +155,103 @@ VISU::Storable* VISU::Table_i::Create()
 */
 VISU::Storable* VISU::Table_i::Build( int theRestoring ) 
 {
+  
   // look for reference SObject with table attribute
-  SALOMEDS::SObject_var SO = myStudy->FindObjectID( myObjectEntry.c_str() );
+  SALOMEDS::SObject_var SO = mySObj;
+
   if ( !SO->_is_nil() ) {
+    CutLines_i* pCutLines = NULL;
+    CORBA::Object_var anObj = SObjectToObject(SO);
+    if(!CORBA::is_nil(anObj)){
+      VISU::CutLines_var aCutLines = VISU::CutLines::_narrow(anObj);
+      if(!aCutLines->_is_nil())
+       pCutLines = dynamic_cast<CutLines_i*>(GetServant(aCutLines).in());
+    }
     SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
     SALOMEDS::GenericAttribute_var anAttr;
-    if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) || 
-        Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
-      // look for component
-      if ( !theRestoring ) {
+    // look for component
+    if ( !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, 
-                                          SComponent->GetID(),
-                                          "",
-                                          GetID(),
-                                          GetName(),
-                                          "",
-                                          aComment.latin1(), 
-                                          true );
+                                         SO->GetID(),//SComponent->GetID(),
+                                         "",
+                                         GetID(),
+                                         GetName(),
+                                         "",
+                                         aComment.latin1(), 
+                                         pCutLines );
        // create SObject referenced to real table object
-       SALOMEDS::SObject_var newSO = myStudy->FindObjectID( anEntry.c_str() );
-       SALOMEDS::SObject_var refSO = Builder->NewObject( newSO );
-       Builder->Addreference( refSO, SO );
+       mySObj = SALOMEDS::SObject::_duplicate(myStudy->FindObjectID( anEntry.c_str() ));
+       if(pCutLines) {
+         pCutLines->BuildTableOfReal(mySObj);
+       }
+       // mpv (PAL5357): reference attributes are unnecessary now
+       //SALOMEDS::SObject_var refSO = Builder->NewObject( mySObj );
+       //Builder->Addreference( refSO, SO );
       }
-      return this;
-    }
+    return this;
   }
   return NULL;
 }
 /*!
   Restores table object from stream
 */
-VISU::Storable* VISU::Table_i::Restore( const Storable::TRestoringMap& theMap )
-     throw( std::logic_error& )
+VISU::Storable* VISU::Table_i::Restore( const Storable::TRestoringMap& theMap, SALOMEDS::SObject_ptr SO)
 {
   if(MYDEBUG) MESSAGE(GetComment());
-  myName = VISU::Storable::FindValue(theMap,"myName");
-  myObjectEntry = VISU::Storable::FindValue(theMap,"myObjectEntry");
-  myTitle = VISU::Storable::FindValue(theMap,"myTitle");
+  myName = (const char*)(VISU::Storable::FindValue(theMap,"myName"));
+  myTitle = (const char*)(VISU::Storable::FindValue(theMap,"myTitle"));
   myOrientation = ( VISU::Table::Orientation )( VISU::Storable::FindValue(theMap,"myOrientation").toInt() );
+  mySObj = SALOMEDS::SObject::_duplicate(SO);
   return Build( true );
 }
 /*!
   Flushes table data into stream
 */
-void VISU::Table_i::ToStream( ostrstream& theStr )
+void VISU::Table_i::ToStream( std::ostringstream& theStr )
 {
   Storable::DataToStream( theStr, "myName",        myName.c_str() );
-  Storable::DataToStream( theStr, "myObjectEntry", myObjectEntry.c_str() );
   Storable::DataToStream( theStr, "myTitle",       myTitle.c_str() );
   Storable::DataToStream( theStr, "myOrientation", myOrientation );
-
-//  theStr<<"\n myName ="<<myName;
-//  theStr<<" myObjectEntry "<<myObjectEntry;
-//  theStr<<" myTitle "<<myTitle;
-//  theStr<<" myOrientation "<<myOrientation;
 }
 /*!
   Called from engine to restore table from the file
 */
-VISU::Storable* VISU::TableRestore(SALOMEDS::SObject_ptr theSObject, 
-                                  const string& thePrefix, const Storable::TRestoringMap& theMap)
+VISU::Storable* VISU::Table_i::Restore(SALOMEDS::SObject_ptr theSObject, 
+                                      const string& thePrefix, const Storable::TRestoringMap& theMap)
 {
   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
   VISU::Table_i* pResent = new VISU::Table_i( aStudy, "" );
-  return pResent->Restore( theMap );
+  return pResent->Restore( theMap, theSObject);
+}
+/*!
+  Gets title for the original table object
+*/
+const char* VISU::Table_i::GetTableTitle()
+{
+  SALOMEDS::SObject_var SO = mySObj;
+  SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
+  SALOMEDS::GenericAttribute_var        anAttr;
+  SALOMEDS::AttributeTableOfInteger_var anInt;
+  SALOMEDS::AttributeTableOfReal_var    aReal;
+  if ( !SO->_is_nil() ) { 
+    if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
+      anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
+      return anInt->GetTitle();
+    }
+    else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
+      aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
+      return aReal->GetTitle();
+    }
+  }
+  return ""; 
+}
+
+void VISU::Table_i::RemoveFromStudy(){
+  VISU::RemoveFromStudy(mySObj,false);
 }
 
 //----------------------------------------------------------------
@@ -186,14 +260,12 @@ VISU::Storable* VISU::TableRestore(SALOMEDS::SObject_ptr theSObject,
 /*!
   Restores table object from the stream [ static ]
 */
-static VISU::Table_i* GetTable( SALOMEDS::Study_var& theStudy, const VISU::Storable::TRestoringMap& theMap ) {
-  string anEntry = VISU::Storable::FindValue( theMap, "TableID" ).latin1();
-  SALOMEDS::SObject_var aSObject = theStudy->FindObjectID( anEntry.c_str() );
-  CORBA::Object_var anObject = VISU::SObjectToObject( aSObject );
+static VISU::Table_i* GetTable( SALOMEDS::Study_ptr theStudy, SALOMEDS::SObject_ptr theSO ) {
+  CORBA::Object_var anObject = VISU::SObjectToObject( theSO );
   if( !CORBA::is_nil( anObject ) ) {
     CORBA::Object_ptr aTable = VISU::Table::_narrow( anObject );
     if( !CORBA::is_nil( aTable ) )
-      return dynamic_cast<VISU::Table_i*>( VISU::GetServant( aTable ) );
+      return dynamic_cast<VISU::Table_i*>(VISU::GetServant(aTable).in());
   }
   return NULL;
 }
@@ -232,6 +304,7 @@ VISU::Curve_i::Curve_i(SALOMEDS::Study_ptr theStudy, Table_i* theTable, CORBA::L
 */
 VISU::Curve_i::~Curve_i()
 {
+  MESSAGE("Curve_i::~Curve_i");
 }
 /*!
   Creates curve object
@@ -239,20 +312,21 @@ VISU::Curve_i::~Curve_i()
 VISU::Storable* VISU::Curve_i::Create()
 {
   // generate name ... 
-  myName = GenerateName();
+  myName = GetVerTitle(); 
+  if ( myName == "" )
+    myName = GenerateName();
   // ... and build the object
   return Build( false );
 }
 /*!
   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
-    SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetEntry() );
     int nbRows = myTable->GetNbRows();
-    if ( !SO->_is_nil() && myHRow > 0 && myHRow <= nbRows && myVRow > 0 && myVRow <= nbRows ) {
+    if ( myHRow > 0 && myHRow <= nbRows && myVRow > 0 && myVRow <= nbRows ) {
       if ( !theRestoring ) {
        // look for component
        SALOMEDS::SComponent_var SComponent = VISU::FindOrCreateVisuComponent( myStudy );
@@ -260,13 +334,15 @@ VISU::Storable* VISU::Curve_i::Build( int theRestoring )
        QString aComment;
        aComment.sprintf("myComment=%s;myType=%d",GetComment(),VISU::TCURVE);
        string anEntry = CreateAttributes( myStudy, 
-                                          myTable->GetEntry(),
-                                          "",
-                                          GetID(),
-                                          GetName(),
-                                          "",
-                                          aComment.latin1(),
-                                          true );
+                                         myTable->GetObjectEntry(),
+                                         "",
+                                         GetID(),
+                                         GetName(),
+                                         "",
+                                         aComment.latin1(),
+                                         true );
+       // create SObject referenced to real table object
+       mySObj = SALOMEDS::SObject::_duplicate(myStudy->FindObjectID(anEntry.c_str()));
       }
       return this;
     }
@@ -280,7 +356,7 @@ VISU::Storable* VISU::Curve_i::Build( int theRestoring )
 CORBA::Boolean VISU::Curve_i::IsValid()
 {
   // getting table SObject by it's entry
-  SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetObjectEntry() );
+  SALOMEDS::SObject_var SO = myStudy->FindObjectID(myTable->GetObjectEntry());
   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
@@ -308,7 +384,7 @@ string VISU::Curve_i::GetHorTitle()
 {
   string title;
   // getting table SObject by it's entry
-  SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetObjectEntry() );
+  SALOMEDS::SObject_var SO = myStudy->FindObjectID(myTable->GetObjectEntry());
   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
@@ -318,14 +394,14 @@ string VISU::Curve_i::GetHorTitle()
       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 ];
       }
     }
   }
@@ -338,7 +414,7 @@ string VISU::Curve_i::GetVerTitle()
 {
   string title;
   // getting table SObject by it's entry
-  SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetObjectEntry() );
+  SALOMEDS::SObject_var SO = myStudy->FindObjectID(myTable->GetObjectEntry());
   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
@@ -348,13 +424,13 @@ string VISU::Curve_i::GetVerTitle()
       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;
@@ -366,7 +442,7 @@ string VISU::Curve_i::GetHorUnits()
 {
   string units;
   // getting table SObject by it's entry
-  SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetObjectEntry() );
+  SALOMEDS::SObject_var SO = myStudy->FindObjectID(myTable->GetObjectEntry());
   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
@@ -376,13 +452,13 @@ string VISU::Curve_i::GetHorUnits()
       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;
@@ -394,7 +470,7 @@ string VISU::Curve_i::GetVerUnits()
 {
   string units;
   // getting table SObject by it's entry
-  SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetObjectEntry() );
+  SALOMEDS::SObject_var SO = myStudy->FindObjectID(myTable->GetObjectEntry());
   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
@@ -404,13 +480,13 @@ string VISU::Curve_i::GetVerUnits()
       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;
@@ -422,7 +498,7 @@ int VISU::Curve_i::GetData( double*& theHorList, double*& theVerList )
 {
   theHorList = 0; theVerList = 0;
   // getting table SObject by it's entry
-  SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetObjectEntry() );
+  SALOMEDS::SObject_var SO = myStudy->FindObjectID(myTable->GetObjectEntry());
   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
   SALOMEDS::GenericAttribute_var        anAttr;
   SALOMEDS::AttributeTableOfInteger_var anInt;
@@ -440,10 +516,12 @@ int VISU::Curve_i::GetData( double*& theHorList, double*& theVerList )
        if ( nbPoints > 0 ) {
          theHorList = new double[ nbPoints ];
          theVerList = new double[ nbPoints ];
+         int k = 0;
          for ( int j = 1; j <= nbCols; j++ ) {
            if ( anInt->HasValue( myHRow, j ) && anInt->HasValue( myVRow, j ) ) {
-             theHorList[j-1] = anInt->GetValue( myHRow, j );
-             theVerList[j-1] = anInt->GetValue( myVRow, j );
+             theHorList[k] = anInt->GetValue( myHRow, j );
+             theVerList[k] = anInt->GetValue( myVRow, j );
+             k++;
            }
          }
        }
@@ -462,10 +540,12 @@ int VISU::Curve_i::GetData( double*& theHorList, double*& theVerList )
        if ( nbPoints > 0 ) {
          theHorList = new double[ nbPoints ];
          theVerList = new double[ nbPoints ];
+         int k = 0;
          for ( int j = 1; j <= nbCols; j++ ) {
            if ( aReal->HasValue( myHRow, j ) && aReal->HasValue( myVRow, j ) ) {
-             theHorList[j-1] = aReal->GetValue( myHRow, j );
-             theVerList[j-1] = aReal->GetValue( myVRow, j );
+             theHorList[k] = aReal->GetValue( myHRow, j );
+             theVerList[k] = aReal->GetValue( myVRow, j );
+             k++;
            }
          }
        }
@@ -481,33 +561,43 @@ int VISU::Curve_i::GetData( double*& theHorList, double*& theVerList )
 Plot2d_Curve* VISU::Curve_i::CreatePresentation()
 {
   Plot2d_Curve* crv = new Plot2d_Curve();
-  crv->setHorTitle( strdup( GetHorTitle().c_str() ) );
+  crv->setHorTitle( GetHorTitle().c_str() );
+  string tlt = GetTitle(); 
+  if ( tlt.length() <= 0 )
+    tlt = GetVerTitle();
   //crv->setVerTitle( strdup( GetVerTitle().c_str() ) );
-  crv->setVerTitle( strdup( GetName() ) );
-  crv->setHorUnits( strdup( GetHorUnits().c_str() ) );
-  crv->setVerUnits( strdup( GetVerUnits().c_str() ) );
+  //crv->setVerTitle( strdup( GetName() ) );
+  crv->setVerTitle( tlt.c_str() );
+  crv->setHorUnits( GetHorUnits().c_str() );
+  crv->setVerUnits( GetVerUnits().c_str() );
   double* xList = 0;
   double* yList = 0;
   int     nbPoints = GetData( xList, yList );
   if ( nbPoints > 0 && xList && yList ) {
     crv->setData( xList, yList, nbPoints );
   }
+  //cout << "********** Number of points: " << nbPoints <<endl;
+  //for ( int i =0 ; i < nbPoints; i++ ) {
+  //  cout << i<<"\t"<<xList[i] << "\t"<< yList[i] << endl;
+  //}
   crv->setLine( (Plot2d_Curve::LineType)GetLine(), GetLineWidth() );
   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(GetEntry()),"VISU",strdup(GetName()))); 
+  crv->setIO(new SALOME_InteractiveObject(mySObj->GetID(),"VISU",GetName()));
+  if ( myTable )
+    crv->setTableIO(new SALOME_InteractiveObject(myTable->GetObjectEntry(),"VISU",myTable->GetName()));
   return crv;
 }
 /*!
   Restores curve object from stream
 */
-VISU::Storable* VISU::Curve_i::Restore( const Storable::TRestoringMap& theMap )
-     throw( std::logic_error& )
+VISU::Storable* VISU::Curve_i::Restore( const Storable::TRestoringMap& theMap, SALOMEDS::SObject_ptr theSO)
 {
   if(MYDEBUG) MESSAGE(GetComment());
-  myName = VISU::Storable::FindValue(theMap,"myName");
+  mySObj = SALOMEDS::SObject::_duplicate(theSO);
+  myName = VISU::Storable::FindValue(theMap,"myName").latin1();
   myHRow = VISU::Storable::FindValue(theMap,"myHRow").toInt();
   myVRow = VISU::Storable::FindValue(theMap,"myVRow").toInt();
   myColor.R = VISU::Storable::FindValue(theMap,"myColor.R").toDouble();
@@ -515,44 +605,51 @@ VISU::Storable* VISU::Curve_i::Restore( const Storable::TRestoringMap& theMap )
   myColor.B = VISU::Storable::FindValue(theMap,"myColor.B").toDouble();
   myMarker = ( VISU::Curve::MarkerType )( VISU::Storable::FindValue(theMap,"myMarker").toInt() );
   myLine = ( VISU::Curve::LineType )( VISU::Storable::FindValue(theMap,"myLine").toInt() );
+  myLineWidth = VISU::Storable::FindValue(theMap,"myLineWidth").toInt();
+  myAuto = VISU::Storable::FindValue(theMap,"myAuto").toInt();
   return Build( true );
 }
 /*!
   Flushes curve data into stream
 */
-void VISU::Curve_i::ToStream( ostrstream& theStr )
+void VISU::Curve_i::ToStream( std::ostringstream& theStr )
 {
-  Storable::DataToStream( theStr, "TableID",   GetTableID() );
-  Storable::DataToStream( theStr, "myName",    myName.c_str() );
-  Storable::DataToStream( theStr, "myHRow",    myHRow );
-  Storable::DataToStream( theStr, "myVRow",    myVRow );
-  Storable::DataToStream( theStr, "myColor.R", myColor.R );
-  Storable::DataToStream( theStr, "myColor.G", myColor.G );
-  Storable::DataToStream( theStr, "myColor.B", myColor.B );
-  Storable::DataToStream( theStr, "myMarker",  myMarker );
-  Storable::DataToStream( theStr, "myLine",    myLine );
+  Storable::DataToStream( theStr, "myName",      myName.c_str() );
+  Storable::DataToStream( theStr, "myHRow",      myHRow );
+  Storable::DataToStream( theStr, "myVRow",      myVRow );
+  Storable::DataToStream( theStr, "myColor.R",   myColor.R );
+  Storable::DataToStream( theStr, "myColor.G",   myColor.G );
+  Storable::DataToStream( theStr, "myColor.B",   myColor.B );
+  Storable::DataToStream( theStr, "myMarker",    myMarker );
+  Storable::DataToStream( theStr, "myLine",      myLine );
+  Storable::DataToStream( theStr, "myLineWidth", myLineWidth );
+  Storable::DataToStream( theStr, "myAuto",      myAuto );
 }
 /*!
   Gets reference table's entry
 */
 const char* VISU::Curve_i::GetTableID() { 
-  return myTable->GetEntry();
+  return myTable->GetObjectEntry();
 }
 /*!
   Called from engine to restore curve from the file
 */
-VISU::Storable* VISU::CurveRestore(SALOMEDS::SObject_ptr theSObject, 
-                                  const string& thePrefix, const Storable::TRestoringMap& theMap)
+VISU::Storable* VISU::Curve_i::Restore(SALOMEDS::SObject_ptr theSObject, 
+                                      const string& thePrefix, const Storable::TRestoringMap& theMap)
 {
   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
-  VISU::Table_i* pTable = GetTable( aStudy, theMap );
+  VISU::Table_i* pTable = GetTable(aStudy, theSObject->GetFather());
   if( pTable != NULL ) {
     VISU::Curve_i* pResent = new VISU::Curve_i( aStudy, pTable, 0, 0 );
-    return pResent->Restore( theMap );
+    return pResent->Restore( theMap, theSObject);
   }
   return NULL;
 }
 
+void VISU::Curve_i::RemoveFromStudy(){
+  VISU::RemoveFromStudy(mySObj,false);
+}
+
 //----------------------------------------------------------------
 //                      Container Object
 //----------------------------------------------------------------
@@ -563,7 +660,7 @@ const string VISU::Container_i::myComment  = "CONTAINER";
 */
 const char* VISU::Container_i::GenerateName() 
 { 
-  return VISU::GenerateName( "Container", ++myNbPresent ); 
+  return VISU::GenerateName( "Plot2DView", ++myNbPresent ); 
 }
 /*!
   Gets comment string
@@ -584,6 +681,7 @@ VISU::Container_i::Container_i( SALOMEDS::Study_ptr theStudy )
 */
 VISU::Container_i::~Container_i()
 {
+  MESSAGE("Container_i::~Container_i");
   myCurves.clear();
 }
 /*!
@@ -596,7 +694,7 @@ void VISU::Container_i::AddCurve( Curve_ptr theCurve )
   SALOMEDS::SObject_var mySO = myStudy->FindObjectID( GetEntry() );
   if ( mySO->_is_nil() )
     return;
-  PortableServer::POA_var aPOA = GetPOA();
+  PortableServer::POA_ptr aPOA = GetPOA();
   Curve_i* pCurve = dynamic_cast<Curve_i*>( aPOA->reference_to_servant( theCurve ) );
   if( pCurve ) {
     QString entry = pCurve->GetEntry();
@@ -619,7 +717,7 @@ void VISU::Container_i::RemoveCurve( Curve_ptr theCurve )
   SALOMEDS::SObject_var mySO = myStudy->FindObjectID( GetEntry() );
   if ( mySO->_is_nil() )
     return;
-  PortableServer::POA_var aPOA = GetPOA();
+  PortableServer::POA_ptr aPOA = GetPOA();
   Curve_i* pCurve = dynamic_cast<Curve_i*>( aPOA->reference_to_servant( theCurve ) );
   if( pCurve ) {
     QString entry = pCurve->GetEntry();
@@ -643,6 +741,7 @@ void VISU::Container_i::RemoveCurve( Curve_ptr theCurve )
 */
 CORBA::Long VISU::Container_i::GetNbCurves()
 {
+  Update();
   return myCurves.count();
 }
 /*!
@@ -696,6 +795,7 @@ VISU::Storable* VISU::Container_i::Build( int theRestoring )
                                       "",
                                       aComment.latin1(),
                                       true );
+    mySObj = SALOMEDS::SObject::_duplicate(myStudy->FindObjectID(anEntry.c_str()));
   }
   return this;
 }
@@ -775,7 +875,7 @@ VISU::Curve_i* VISU::Container_i::GetCurve( CORBA::Long theIndex )
       // 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 ) );
+      return dynamic_cast<VISU::Curve_i*>(VISU::GetServant(aCurve).in());
     }
   }
   return NULL;
@@ -783,11 +883,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 )
-     throw( std::logic_error& )
+VISU::Storable* VISU::Container_i::Restore( const Storable::TRestoringMap& theMap, SALOMEDS::SObject_ptr SO )
 {
   if(MYDEBUG) MESSAGE(GetComment());
-  myName = VISU::Storable::FindValue( theMap, "myName" ); 
+  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 );
@@ -795,7 +895,7 @@ VISU::Storable* VISU::Container_i::Restore( const Storable::TRestoringMap& theMa
 /*!
   Flushes container data into the stream
 */
-void VISU::Container_i::ToStream( ostrstream& theStr )
+void VISU::Container_i::ToStream( std::ostringstream& theStr )
 {
   Storable::DataToStream( theStr, "myName",   myName.c_str() );
   Storable::DataToStream( theStr, "myCurves", myCurves.join( QString( "*" ) ) );
@@ -805,18 +905,23 @@ void VISU::Container_i::ToStream( ostrstream& theStr )
 /*!
   Called from engine to restore container from the file
 */
-VISU::Storable* VISU::ContainerRestore(SALOMEDS::SObject_ptr theSObject, 
-                                      const string& thePrefix, const Storable::TRestoringMap& theMap)
+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 vector<float> TValues;
+typedef string TValue;
+typedef vector<TValue> TValues;
 
 struct TRow{
   string myTitle;
@@ -826,7 +931,7 @@ struct TRow{
 
 typedef vector<TRow> TRows;
 
-struct TTable2D{
+struct TTable2D {
   string myTitle;
   vector<string> myColumnUnits;
   vector<string> myColumnTitles;
@@ -839,7 +944,8 @@ 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) return 0;
+      if(myRows[j].myValues.size() != iEnd) 
+       return 0;
     return 1;
   }
   void getColumns(TTable2D& theTable2D) const {
@@ -879,85 +985,132 @@ int getLine(ifstream& theStmIn, QString& theString){
     if(tmp == '\n') break;
   }
   aStrOut<<ends;
-  auto_ptr<char> aRet(aStrOut.str());
-  theString = aRet.get();
+  theString = aStrOut.str();
   return !theStmIn.eof();
 }
 
 void ImportTables(const char* theFileName, TTableCont& theTableCont){
   ifstream aStmIn;
-  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");
-    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;
-       cout<<aTitle<<endl;
-      }else if(aTmp.find("#COLUMN_TITLES:") == 0){
-       int aLen = aTmp.find(":") + 1;
-       aTmp.remove(0,aLen);
-       QStringList aStrList = QStringList::split("|",aTmp);
-       cout<<"Its Column Titles : ";
-       for(int i = 0; i < aStrList.count(); i++){
-         aTmp = aStrList[i].stripWhiteSpace();
-         aTable2D.myColumnTitles.push_back(aTmp.latin1());
-         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();
+         }
        }
-       cout<<endl;
-      }else if(aTmp.find("#COLUMN_UNITS:") == 0){
-       int aLen = aTmp.find(":") + 1;
-       aTmp.remove(0,aLen);
-       QStringList aStrList = QStringList::split(" ",aTmp);
-       cout<<"Its Column Units : ";
-       for(int i = 0; i < aStrList.count(); i++){
-         aTmp = aStrList[i].stripWhiteSpace();
-         aTable2D.myColumnUnits.push_back(aTmp.latin1());
-         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;
+         }
        }
-       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;
-       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);
-         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);
-       cout<<endl;
-      }else{
-       QStringList aValList = QStringList::split(" ",aTmp);
+      }
+      // if data is not empty, try to process it
+      else {
        TRow aRow; 
-       for(int i = 0; i < aValList.count(); i++){
-         float aVal = aValList[i].toFloat();
-         aRow.myValues.push_back(aVal);
-         cout<<"\t"<<aVal;
+       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( data );
+       aStream.precision( STRPRECISION );
+       while( aStream >> aVal ) {
+         aRow.myValues.push_back( aVal );
        }
-       aTable2D.myRows.push_back(aRow);
-       cout<<endl;
+       if( aRow.myValues.size() > 0 )
+         aTable2D.myRows.push_back( aRow );
+       */
+       // ************** OLD CODE ******************
       }
-      getLine(aStmIn,aTmp);
+      getLine( aStmIn, aTmp );
     }
-    if(aTable2D.Check()){
-      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();
-  cout<<"After close"<<endl;
+  if(MYDEBUG) cout << "After close" << endl;
 }
 
 SALOMEDS::SObject_var VISU::ImportTables(const char* theFileName, SALOMEDS::Study_ptr theStudy){
@@ -972,52 +1125,12 @@ SALOMEDS::SObject_var VISU::ImportTables(const char* theFileName, SALOMEDS::Stud
   SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
   QFileInfo aFileInfo(theFileName);
   aName->SetValue(aFileInfo.fileName().latin1());
-  int iEnd = aTableCont.size();
-  /*
-  for(int i = 0, iEnd = aTableCont.size(); i < iEnd; i++){
-    const TTable2D& aTable2D = aTableCont[i];
-    SALOMEDS::SObject_var aRealObject = aStudyBuilder->NewObject(aFileObject);
-    anAttr = aStudyBuilder->FindOrCreateAttribute(aRealObject, "AttributeName");
-    aName = SALOMEDS::AttributeName::_narrow(anAttr);
-    cout<<"aTable2D.myTitle = "<<aTable2D.myTitle<<endl;
-    if(aTable2D.myTitle != "")
-      aName->SetValue(aTable2D.myTitle.c_str());
-    else{
-      QString aNewName;
-      aNewName.sprintf("Table:%d",i);
-      aName->SetValue(aNewName.latin1());
-    }
-    anAttr = aStudyBuilder->FindOrCreateAttribute(aRealObject, "AttributeTableOfReal");
-    SALOMEDS::AttributeTableOfReal_var aTableOfReal = SALOMEDS::AttributeTableOfReal::_narrow(anAttr);
-    aTableOfReal->SetTitle(aTable2D.myTitle.c_str());
-    const TRows& aRows = aTable2D.myRows;
-    //aTable2D.getColumns(aRows);
-    int kEnd = aRows[0].myValues.size();
-    aTableOfReal->SetNbColumns(kEnd);
-    for(int j = 0, jEnd = aRows.size(); j < jEnd; j++){
-      cout<<"j = "<<j<<endl;
-      const TRow& aRow = aRows[j];
-      SALOMEDS::DoubleSeq_var aDoubleSeq = new SALOMEDS::DoubleSeq();
-      int kEnd = aRow.myValues.size();
-      aDoubleSeq->length(kEnd);
-      cout<<"kEnd = "<<kEnd<<endl;
-      for(int k = 0; k < kEnd; k++) aDoubleSeq[k] = aRow.myValues[k];
-      aTableOfReal->AddRow(aDoubleSeq.in());
-      aTableOfReal->SetRowTitle(j+1,aRow.myTitle.c_str());
-      aTableOfReal->SetRowUnit(j+1,aRow.myUnit.c_str());
-    }
-    for(int k = 0; k < kEnd; k++){
-      aTableOfReal->SetColumnTitle(k+1,aTable2D.myColumnTitles[k].c_str());
-      //aTableOfReal->SetColumnUnit(k+1,aTable2D.myColumnUnits[k].c_str());
-    }
-  }
-  */
   for(int i = 0, iEnd = aTableCont.size(); i < iEnd; i++){
     const TTable2D& aTable2D = aTableCont[i];
     SALOMEDS::SObject_var aRealObject = aStudyBuilder->NewObject(aFileObject);
     anAttr = aStudyBuilder->FindOrCreateAttribute(aRealObject, "AttributeName");
     aName = SALOMEDS::AttributeName::_narrow(anAttr);
-    cout<<"aTable2D.myTitle = "<<aTable2D.myTitle<<endl;
+    if(MYDEBUG) cout<<"aTable2D.myTitle = "<<aTable2D.myTitle<<endl;
     if(aTable2D.myTitle != "")
       aName->SetValue(aTable2D.myTitle.c_str());
     else{
@@ -1033,19 +1146,112 @@ 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++){
-      cout<<"j = "<<j<<endl;
-      SALOMEDS::DoubleSeq_var aDoubleSeq = new SALOMEDS::DoubleSeq();
-      aDoubleSeq->length(kEnd);
-      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());
     }
-    for(int k = 0; k < kEnd; k++){
+    for(int k = 0; k < kEnd; k++)
       aTableOfReal->SetColumnTitle(k+1,aNewTable2D.myColumnTitles[k].c_str());
-      //aTableOfReal->SetColumnUnit(k+1,aTable2D.myColumnUnits[k].c_str());
-    }
   }
   return aFileObject;
 }
+
+template<class TTableAttr> bool ExportTableToFile(const TTableAttr& aTabAttr,  
+                                                 const char* theFileName)
+{
+  if (!CORBA::is_nil(aTabAttr)) {
+    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();       
+
+    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();                      
+
+       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_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;    
+  }                 
+  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); 
+      return ExportTableToFile ( aTabAttr , theFileName);
+      
+    }
+  else if (theTable->FindAttribute(anAttr, "AttributeTableOfInteger")) {
+
+    SALOMEDS::AttributeTableOfInteger_var aTabAttr = SALOMEDS::AttributeTableOfInteger ::_narrow(anAttr); 
+    return ExportTableToFile ( aTabAttr , theFileName);
+    
+  }
+  return false;
+}