Salome HOME
Fix pb with Animation
[modules/visu.git] / src / VISU_I / VISU_Table_i.cc
1 //  VISU OBJECT : interactive object for VISU entities implementation
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //  File   : VISU_Table_i.cc
24 //  Author : Vadim SANDLER
25 //  Module : VISU
26
27 #include "VISU_Table_i.hh"
28
29 #include "VISU_CutLines_i.hh"
30 #include "VISU_Result_i.hh"
31 #include "VISU_ViewManager_i.hh"
32
33 #include "SPlot2d_Curve.h"
34
35 #include <memory>
36 #include <fstream>
37 #include <strstream>
38
39 #include <qfileinfo.h>
40 #include <qstring.h>
41 #include <qfile.h>
42
43 using namespace std;
44
45 #ifdef _DEBUG_
46 static int MYDEBUG = 0;
47 #else
48 static int MYDEBUG = 0;
49 #endif
50 //----------------------------------------------------------------
51 //                      Table Object
52 //----------------------------------------------------------------
53 int VISU::Table_i::myNbPresent = 0;
54 const string VISU::Table_i::myComment  = "TABLE";
55 /*!
56   Generate unique name
57 */
58 const char* VISU::Table_i::GenerateName()
59 {
60   return VISU::GenerateName( "Table", ++myNbPresent );
61 }
62 /*!
63   Gets comment string
64 */
65 const char* VISU::Table_i::GetComment() const
66 {
67   return myComment.c_str();
68 }
69 /*!
70   Constructor
71 */
72 VISU::Table_i::Table_i( SALOMEDS::Study_ptr theStudy, const char* theObjectEntry )
73      : PrsObject_i(theStudy)
74 {
75   mySObj = SALOMEDS::SObject::_duplicate((theStudy->FindObjectID(theObjectEntry)));
76   myOrientation = VISU::Table::HORIZONTAL;
77 }
78 /*!
79   Destructor
80 */
81 VISU::Table_i::~Table_i()
82 {
83   MESSAGE("Table_i::~Table_i");
84 }
85 /*!
86   Gets number of rows in table
87 */
88 CORBA::Long VISU::Table_i::GetNbRows()
89 {
90   SALOMEDS::SObject_var SO = mySObj;
91   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
92   if ( !SO->_is_nil() ) {
93     SALOMEDS::GenericAttribute_var        anAttr;
94     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
95       SALOMEDS::AttributeTableOfInteger_var anInt =  SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
96         return anInt->GetNbRows();
97     }
98     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
99       SALOMEDS::AttributeTableOfReal_var aReal =  SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
100       return aReal->GetNbRows();
101     }
102   }
103   return 0;
104 }
105 /*!
106   Gets number of columns in table
107 */
108 CORBA::Long VISU::Table_i::GetNbColumns()
109 {
110   SALOMEDS::SObject_var SO = mySObj;
111   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
112   if ( !SO->_is_nil() ) {
113     SALOMEDS::GenericAttribute_var        anAttr;
114     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
115       SALOMEDS::AttributeTableOfInteger_var anInt =  SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
116       return anInt->GetNbColumns();
117     }
118     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
119       SALOMEDS::AttributeTableOfReal_var aReal =  SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
120       return aReal->GetNbColumns();
121     }
122   }
123   return 0;
124 }
125 /*!
126   Creates table object
127 */
128 VISU::Storable* VISU::Table_i::Create()
129 {
130   // generate name ...
131   myName = GetTableTitle();
132
133   // mpv (PAL 5357): if name attribute already exist at this label, use it as name of table
134   if ( myName == "" )
135     if ( !mySObj->_is_nil() ) {
136       CutLines_i* pCutLines = NULL;
137       CORBA::Object_var anObj = SObjectToObject(mySObj);
138       if(!CORBA::is_nil(anObj)){
139         VISU::CutLines_var aCutLines = VISU::CutLines::_narrow(anObj);
140           if(!aCutLines->_is_nil())
141             pCutLines = dynamic_cast<CutLines_i*>(GetServant(aCutLines).in());
142         }
143       if (!pCutLines)
144         if (mySObj->GetName()) myName = mySObj->GetName();
145     }
146
147   if ( myName == "" )
148     myName = GenerateName();
149   // ... and build the object
150   return Build( false );
151 }
152 /*!
153   Builds presentation of table
154 */
155 VISU::Storable* VISU::Table_i::Build( int theRestoring )
156 {
157
158   // look for reference SObject with table attribute
159   SALOMEDS::SObject_var SO = mySObj;
160
161   if ( !SO->_is_nil() ) {
162     CutLines_i* pCutLines = NULL;
163     CORBA::Object_var anObj = SObjectToObject(SO);
164     if(!CORBA::is_nil(anObj)){
165       VISU::CutLines_var aCutLines = VISU::CutLines::_narrow(anObj);
166       if(!aCutLines->_is_nil())
167         pCutLines = dynamic_cast<CutLines_i*>(GetServant(aCutLines).in());
168     }
169     SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
170     SALOMEDS::GenericAttribute_var anAttr;
171     // look for component
172     if ( !theRestoring ) {
173         SALOMEDS::SComponent_var SComponent = VISU::FindOrCreateVisuComponent( myStudy );
174         // create SObject and set attributes
175         QString aComment;
176         if(pCutLines)
177           aComment.sprintf("myComment=%s;myType=%d;mySourceId=CutLines",GetComment(),VISU::TTABLE);
178         else{
179           aComment.sprintf("myComment=%s;myType=%d;mySourceId=TableAttr",GetComment(),VISU::TTABLE);
180           SALOMEDS::SObject_var aFatherSObject = SO->GetFather();
181           if(aFatherSObject->FindAttribute(anAttr,"AttributeComment")){
182             SALOMEDS::AttributeComment_var aCommentAttr =
183               SALOMEDS::AttributeComment::_narrow(anAttr);
184             CORBA::String_var aValue = aCommentAttr->Value();
185             Storable::TRestoringMap aMap;
186             Storable::StrToMap(aValue.in(),aMap);
187             bool anIsExist;
188             QString aMethodName = VISU::Storable::FindValue(aMap,"myComment",&anIsExist);
189             if(anIsExist){
190               if(strcmp(aMethodName.latin1(),"ImportTables") == 0){
191                 aComment.sprintf("myComment=%s;myType=%d;mySourceId=TableFile",GetComment(),VISU::TTABLE);
192               }
193             }
194           }
195         }
196
197         string anEntry = CreateAttributes( myStudy,
198                                           SO->GetID(),//SComponent->GetID(),
199                                           "",
200                                           GetID(),
201                                           GetName(),
202                                           "",
203                                           aComment.latin1(),
204                                           pCutLines );
205         // create SObject referenced to real table object
206         mySObj = SALOMEDS::SObject::_duplicate(myStudy->FindObjectID( anEntry.c_str() ));
207         if(pCutLines) {
208           pCutLines->BuildTableOfReal(mySObj);
209         }
210         // mpv (PAL5357): reference attributes are unnecessary now
211         //SALOMEDS::SObject_var refSO = Builder->NewObject( mySObj );
212         //Builder->Addreference( refSO, SO );
213       }
214     return this;
215   }
216   return NULL;
217 }
218 /*!
219   Restores table object from stream
220 */
221 VISU::Storable* VISU::Table_i::Restore( const Storable::TRestoringMap& theMap, SALOMEDS::SObject_ptr SO)
222 {
223   if(MYDEBUG) MESSAGE(GetComment());
224   myName = (const char*)(VISU::Storable::FindValue(theMap,"myName"));
225   myTitle = (const char*)(VISU::Storable::FindValue(theMap,"myTitle"));
226   myOrientation = ( VISU::Table::Orientation )( VISU::Storable::FindValue(theMap,"myOrientation").toInt() );
227   mySObj = SALOMEDS::SObject::_duplicate(SO);
228   return Build( true );
229 }
230 /*!
231   Flushes table data into stream
232 */
233 void VISU::Table_i::ToStream( std::ostringstream& theStr )
234 {
235   Storable::DataToStream( theStr, "myName",        myName.c_str() );
236   Storable::DataToStream( theStr, "myTitle",       myTitle.c_str() );
237   Storable::DataToStream( theStr, "myOrientation", myOrientation );
238 }
239 /*!
240   Called from engine to restore table from the file
241 */
242 VISU::Storable* VISU::Table_i::Restore(SALOMEDS::SObject_ptr theSObject,
243                                        const string& thePrefix, const Storable::TRestoringMap& theMap)
244 {
245   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
246   VISU::Table_i* pResent = new VISU::Table_i( aStudy, "" );
247   return pResent->Restore( theMap, theSObject);
248 }
249 /*!
250   Gets title for the original table object
251 */
252 const char* VISU::Table_i::GetTableTitle()
253 {
254   SALOMEDS::SObject_var SO = mySObj;
255   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
256   SALOMEDS::GenericAttribute_var        anAttr;
257   SALOMEDS::AttributeTableOfInteger_var anInt;
258   SALOMEDS::AttributeTableOfReal_var    aReal;
259   if ( !SO->_is_nil() ) {
260     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
261       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
262       return anInt->GetTitle();
263     }
264     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
265       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
266       return aReal->GetTitle();
267     }
268   }
269   return "";
270 }
271
272 void VISU::Table_i::RemoveFromStudy()
273 {
274   // Remove the table with all curves
275   VISU::RemoveFromStudy(mySObj,false);
276 }
277
278 //----------------------------------------------------------------
279 //                      Curve Object
280 //----------------------------------------------------------------
281 /*!
282   Restores table object from the stream [ static ]
283 */
284 static VISU::Table_i* GetTable( SALOMEDS::Study_ptr theStudy, SALOMEDS::SObject_ptr theSO ) {
285   CORBA::Object_var anObject = VISU::SObjectToObject( theSO );
286   if( !CORBA::is_nil( anObject ) ) {
287     CORBA::Object_ptr aTable = VISU::Table::_narrow( anObject );
288     if( !CORBA::is_nil( aTable ) )
289       return dynamic_cast<VISU::Table_i*>(VISU::GetServant(aTable).in());
290   }
291   return NULL;
292 }
293
294 int VISU::Curve_i::myNbPresent = 0;
295 const string VISU::Curve_i::myComment  = "CURVE";
296 /*!
297   Generate unique name
298 */
299 const char* VISU::Curve_i::GenerateName()
300 {
301   return VISU::GenerateName( "Curve", ++myNbPresent );
302 }
303 /*!
304   Gets comment string
305 */
306 const char* VISU::Curve_i::GetComment() const
307 {
308   return myComment.c_str();
309 }
310 /*!
311   Constructor
312   NB : theHRow, theVRow are the indexes of rows in the Table object and numbered from the 1 to GetNbRows()
313 */
314 VISU::Curve_i::Curve_i(SALOMEDS::Study_ptr theStudy, Table_i* theTable, CORBA::Long theHRow, CORBA::Long theVRow )
315      : PrsObject_i(theStudy), myTable( theTable ), myHRow( theHRow ), myVRow( theVRow )
316 {
317   myAuto = true;
318   myLine = VISU::Curve::SOLIDLINE;
319   myLineWidth = 0;
320   myMarker = VISU::Curve::CIRCLE;
321   myColor.R = 0.0; myColor.G = 0.0; myColor.B = 0.0;
322 }
323 /*!
324   Destructor
325 */
326 VISU::Curve_i::~Curve_i()
327 {
328   MESSAGE("Curve_i::~Curve_i");
329 }
330 /*!
331   Creates curve object
332 */
333 VISU::Storable* VISU::Curve_i::Create()
334 {
335   // generate name ...
336   myName = GetVerTitle();
337   if ( myName == "" )
338     myName = GenerateName();
339   // ... and build the object
340   return Build( false );
341 }
342 /*!
343   Builds presentation of curve
344 */
345 VISU::Storable* VISU::Curve_i::Build(int theRestoring )
346 {
347   if ( myTable != NULL ) {
348     // getting table SObject by it's entry
349     int nbRows = myTable->GetNbRows();
350     if ( myHRow > 0 && myHRow <= nbRows && myVRow > 0 && myVRow <= nbRows ) {
351       if ( !theRestoring ) {
352         // look for component
353         SALOMEDS::SComponent_var SComponent = VISU::FindOrCreateVisuComponent( myStudy );
354         // create SObject and set attributes
355         QString aComment;
356         aComment.sprintf("myComment=%s;myType=%d",GetComment(),VISU::TCURVE);
357         string anEntry = CreateAttributes( myStudy,
358                                           myTable->GetObjectEntry(),
359                                           "",
360                                           GetID(),
361                                           GetName(),
362                                           "",
363                                           aComment.latin1(),
364                                           true );
365         // create SObject referenced to real table object
366         mySObj = SALOMEDS::SObject::_duplicate(myStudy->FindObjectID(anEntry.c_str()));
367       }
368       return this;
369     }
370   }
371   return NULL;
372 }
373
374 /*!
375   Returns CORBA::True if curve refers to valid table data
376 */
377 CORBA::Boolean VISU::Curve_i::IsValid()
378 {
379   // getting table SObject by it's entry
380   SALOMEDS::SObject_var SO = myStudy->FindObjectID(myTable->GetObjectEntry());
381   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
382   SALOMEDS::GenericAttribute_var        anAttr;
383   SALOMEDS::AttributeTableOfInteger_var anInt;
384   SALOMEDS::AttributeTableOfReal_var    aReal;
385   if ( !SO->_is_nil() ) {
386     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
387       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
388       if ( myHRow > 0 && myHRow <= anInt->GetNbRows() && myVRow > 0 && myVRow <= anInt->GetNbRows() ) {
389         return true;
390       }
391     }
392     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
393       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
394       if ( myHRow > 0 && myHRow <= aReal->GetNbRows() && myVRow > 0 && myVRow <= aReal->GetNbRows() ) {
395         return true;
396       }
397     }
398   }
399   return false;
400 }
401 /*!
402   Returns hor.axis title
403 */
404 string VISU::Curve_i::GetHorTitle()
405 {
406   string title;
407   // getting table SObject by it's entry
408   SALOMEDS::SObject_var SO = myStudy->FindObjectID(myTable->GetObjectEntry());
409   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
410   SALOMEDS::GenericAttribute_var        anAttr;
411   SALOMEDS::AttributeTableOfInteger_var anInt;
412   SALOMEDS::AttributeTableOfReal_var    aReal;
413   if ( !SO->_is_nil() ) {
414     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
415       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
416       SALOMEDS::StringSeq_var rowTitles = anInt->GetRowTitles();
417       if ( rowTitles->length() > 0 && myHRow > 0 && myHRow <= anInt->GetNbRows() ) {
418         title = rowTitles[ myHRow-1 ];
419       }
420     }
421     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
422       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
423       SALOMEDS::StringSeq_var rowTitles = aReal->GetRowTitles();
424       if ( rowTitles->length() > 0 && myHRow > 0 && myHRow <= aReal->GetNbRows() ) {
425         title = rowTitles[ myHRow-1 ];
426       }
427     }
428   }
429   return title;
430 }
431 /*!
432   Returns ver.axis title
433 */
434 string VISU::Curve_i::GetVerTitle()
435 {
436   string title;
437   // getting table SObject by it's entry
438   SALOMEDS::SObject_var SO = myStudy->FindObjectID(myTable->GetObjectEntry());
439   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
440   SALOMEDS::GenericAttribute_var        anAttr;
441   SALOMEDS::AttributeTableOfInteger_var anInt;
442   SALOMEDS::AttributeTableOfReal_var    aReal;
443   if ( !SO->_is_nil() ) {
444     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
445       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
446       SALOMEDS::StringSeq_var rowTitles = anInt->GetRowTitles();
447       if ( rowTitles->length() > 0 && myVRow > 0 && myVRow <= anInt->GetNbRows() )
448         title = rowTitles[ myVRow-1 ];
449     }
450     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
451       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
452       SALOMEDS::StringSeq_var rowTitles = aReal->GetRowTitles();
453       if ( rowTitles->length() > 0 && myVRow > 0 && myVRow <= aReal->GetNbRows() )
454         title = rowTitles[ myVRow-1 ];
455     }
456   }
457   return title;
458 }
459 /*!
460   Returns hor.axis units
461 */
462 string VISU::Curve_i::GetHorUnits()
463 {
464   string units;
465   // getting table SObject by it's entry
466   SALOMEDS::SObject_var SO = myStudy->FindObjectID(myTable->GetObjectEntry());
467   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
468   SALOMEDS::GenericAttribute_var        anAttr;
469   SALOMEDS::AttributeTableOfInteger_var anInt;
470   SALOMEDS::AttributeTableOfReal_var    aReal;
471   if ( !SO->_is_nil()  ) {
472     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
473       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
474       SALOMEDS::StringSeq_var rowUnits = anInt->GetRowUnits();
475       if ( rowUnits->length() > 0 && myHRow > 0 && myHRow <= anInt->GetNbRows() )
476         units = rowUnits[ myHRow-1 ];
477     }
478     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
479       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
480       SALOMEDS::StringSeq_var rowUnits = aReal->GetRowUnits();
481       if ( rowUnits->length() > 0 && myHRow > 0 && myHRow <= aReal->GetNbRows() )
482         units = rowUnits[ myHRow-1 ];
483     }
484   }
485   return units;
486 }
487 /*!
488   Returns ver.axis units
489 */
490 string VISU::Curve_i::GetVerUnits()
491 {
492   string units;
493   // getting table SObject by it's entry
494   SALOMEDS::SObject_var SO = myStudy->FindObjectID(myTable->GetObjectEntry());
495   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
496   SALOMEDS::GenericAttribute_var        anAttr;
497   SALOMEDS::AttributeTableOfInteger_var anInt;
498   SALOMEDS::AttributeTableOfReal_var    aReal;
499   if ( !SO->_is_nil() ) {
500     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
501       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
502       SALOMEDS::StringSeq_var rowUnits = anInt->GetRowUnits();
503       if ( rowUnits->length() > 0 && myVRow > 0 && myVRow <= anInt->GetNbRows() )
504         units = rowUnits[ myVRow-1];
505     }
506     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
507       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
508       SALOMEDS::StringSeq_var rowUnits = aReal->GetRowUnits();
509       if ( rowUnits->length() > 0 && myVRow > 0 && myVRow <= aReal->GetNbRows() )
510         units = rowUnits[ myVRow-1 ];
511     }
512   }
513   return units;
514 }
515 /*!
516   Gets curve data
517 */
518 int VISU::Curve_i::GetData( double*& theHorList, double*& theVerList )
519 {
520   theHorList = 0; theVerList = 0;
521   // getting table SObject by it's entry
522   SALOMEDS::SObject_var SO = myStudy->FindObjectID(myTable->GetObjectEntry());
523   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
524   SALOMEDS::GenericAttribute_var        anAttr;
525   SALOMEDS::AttributeTableOfInteger_var anInt;
526   SALOMEDS::AttributeTableOfReal_var    aReal;
527   if ( !SO->_is_nil() ) {
528     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
529       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
530       int nbCols = anInt->GetNbColumns() ;
531       if ( nbCols > 0 && myHRow > 0 && myHRow <= anInt->GetNbRows() && myVRow > 0 && myVRow <= anInt->GetNbRows() ) {
532         int nbPoints = 0;
533         for ( int j = 1; j <= nbCols; j++ ) {
534           if ( anInt->HasValue( myHRow, j ) && anInt->HasValue( myVRow, j ) )
535             nbPoints++;
536         }
537         if ( nbPoints > 0 ) {
538           theHorList = new double[ nbPoints ];
539           theVerList = new double[ nbPoints ];
540           int k = 0;
541           for ( int j = 1; j <= nbCols; j++ ) {
542             if ( anInt->HasValue( myHRow, j ) && anInt->HasValue( myVRow, j ) ) {
543               theHorList[k] = anInt->GetValue( myHRow, j );
544               theVerList[k] = anInt->GetValue( myVRow, j );
545               k++;
546             }
547           }
548         }
549         return nbPoints;
550       }
551     }
552     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
553       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
554       int nbCols = aReal->GetNbColumns() ;
555       if ( nbCols > 0 && myHRow > 0 && myHRow <= aReal->GetNbRows() && myVRow > 0 && myVRow <= aReal->GetNbRows() ) {
556         int nbPoints = 0;
557         for ( int j = 1; j <= nbCols; j++ ) {
558           if ( aReal->HasValue( myHRow, j ) && aReal->HasValue( myVRow, j ) )
559             nbPoints++;
560         }
561         if ( nbPoints > 0 ) {
562           theHorList = new double[ nbPoints ];
563           theVerList = new double[ nbPoints ];
564           int k = 0;
565           for ( int j = 1; j <= nbCols; j++ ) {
566             if ( aReal->HasValue( myHRow, j ) && aReal->HasValue( myVRow, j ) ) {
567               theHorList[k] = aReal->GetValue( myHRow, j );
568               theVerList[k] = aReal->GetValue( myVRow, j );
569               k++;
570             }
571           }
572         }
573         return nbPoints;
574       }
575     }
576   }
577   return 0;
578 }
579 /*!
580   Creates curve Plot2d presentation object
581 */
582 SPlot2d_Curve* VISU::Curve_i::CreatePresentation()
583 {
584   SPlot2d_Curve* crv = new SPlot2d_Curve();
585   crv->setHorTitle( GetHorTitle().c_str() );
586   string tlt = GetTitle();
587   if ( tlt.length() <= 0 )
588     tlt = GetVerTitle();
589   //crv->setVerTitle( strdup( GetVerTitle().c_str() ) );
590   //crv->setVerTitle( strdup( GetName() ) );
591   crv->setVerTitle( tlt.c_str() );
592   crv->setHorUnits( GetHorUnits().c_str() );
593   crv->setVerUnits( GetVerUnits().c_str() );
594   double* xList = 0;
595   double* yList = 0;
596   int     nbPoints = GetData( xList, yList );
597   if ( nbPoints > 0 && xList && yList ) {
598     crv->setData( xList, yList, nbPoints );
599   }
600   //cout << "********** Number of points: " << nbPoints <<endl;
601   //for ( int i =0 ; i < nbPoints; i++ ) {
602   //  cout << i<<"\t"<<xList[i] << "\t"<< yList[i] << endl;
603   //}
604   crv->setLine( (Plot2d_Curve::LineType)GetLine(), GetLineWidth() );
605   crv->setMarker( (Plot2d_Curve::MarkerType)GetMarker() );
606   SALOMEDS::Color color = GetColor();
607   crv->setColor( QColor( (int)(color.R*255.), (int)(color.G*255.), (int)(color.B*255.) ) );
608   crv->setAutoAssign( IsAuto() );
609   crv->setIO(new SALOME_InteractiveObject(mySObj->GetID(),"VISU",GetName()));
610   if ( myTable )
611     crv->setTableIO(new SALOME_InteractiveObject(myTable->GetObjectEntry(),"VISU",myTable->GetName()));
612   return crv;
613 }
614 /*!
615   Restores curve object from stream
616 */
617 VISU::Storable* VISU::Curve_i::Restore( const Storable::TRestoringMap& theMap, SALOMEDS::SObject_ptr theSO)
618 {
619   if(MYDEBUG) MESSAGE(GetComment());
620   mySObj = SALOMEDS::SObject::_duplicate(theSO);
621   myName = VISU::Storable::FindValue(theMap,"myName").latin1();
622   myHRow = VISU::Storable::FindValue(theMap,"myHRow").toInt();
623   myVRow = VISU::Storable::FindValue(theMap,"myVRow").toInt();
624   myColor.R = VISU::Storable::FindValue(theMap,"myColor.R").toDouble();
625   myColor.G = VISU::Storable::FindValue(theMap,"myColor.G").toDouble();
626   myColor.B = VISU::Storable::FindValue(theMap,"myColor.B").toDouble();
627   myMarker = ( VISU::Curve::MarkerType )( VISU::Storable::FindValue(theMap,"myMarker").toInt() );
628   myLine = ( VISU::Curve::LineType )( VISU::Storable::FindValue(theMap,"myLine").toInt() );
629   myLineWidth = VISU::Storable::FindValue(theMap,"myLineWidth").toInt();
630   myAuto = VISU::Storable::FindValue(theMap,"myAuto").toInt();
631   return Build( true );
632 }
633 /*!
634   Flushes curve data into stream
635 */
636 void VISU::Curve_i::ToStream( std::ostringstream& theStr )
637 {
638   Storable::DataToStream( theStr, "myName",      myName.c_str() );
639   Storable::DataToStream( theStr, "myHRow",      myHRow );
640   Storable::DataToStream( theStr, "myVRow",      myVRow );
641   Storable::DataToStream( theStr, "myColor.R",   myColor.R );
642   Storable::DataToStream( theStr, "myColor.G",   myColor.G );
643   Storable::DataToStream( theStr, "myColor.B",   myColor.B );
644   Storable::DataToStream( theStr, "myMarker",    myMarker );
645   Storable::DataToStream( theStr, "myLine",      myLine );
646   Storable::DataToStream( theStr, "myLineWidth", myLineWidth );
647   Storable::DataToStream( theStr, "myAuto",      myAuto );
648 }
649 /*!
650   Gets reference table's entry
651 */
652 const char* VISU::Curve_i::GetTableID() {
653   return myTable->GetObjectEntry();
654 }
655 /*!
656   Called from engine to restore curve from the file
657 */
658 VISU::Storable* VISU::Curve_i::Restore(SALOMEDS::SObject_ptr theSObject,
659                                        const string& thePrefix, const Storable::TRestoringMap& theMap)
660 {
661   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
662   VISU::Table_i* pTable = GetTable(aStudy, theSObject->GetFather());
663   if( pTable != NULL ) {
664     VISU::Curve_i* pResent = new VISU::Curve_i( aStudy, pTable, 0, 0 );
665     return pResent->Restore( theMap, theSObject);
666   }
667   return NULL;
668 }
669
670 void VISU::Curve_i::RemoveFromStudy()
671 {
672   VISU::DeleteActors(this);
673   VISU::RemoveFromStudy(mySObj,false);
674 }
675
676 SALOMEDS::SObject_var VISU::Curve_i::GetSObject()
677 {
678   return mySObj;
679 }
680
681 //----------------------------------------------------------------
682 //                      Container Object
683 //----------------------------------------------------------------
684 int VISU::Container_i::myNbPresent = 0;
685 const string VISU::Container_i::myComment  = "CONTAINER";
686 /*!
687   Generate unique name
688 */
689 const char* VISU::Container_i::GenerateName()
690 {
691   return VISU::GenerateName( "Plot2DView", ++myNbPresent );
692 }
693 /*!
694   Gets comment string
695 */
696 const char* VISU::Container_i::GetComment() const
697 {
698   return myComment.c_str();
699 }
700 /*!
701   Constructor
702 */
703 VISU::Container_i::Container_i( SALOMEDS::Study_ptr theStudy )
704      : PrsObject_i( theStudy )
705 {
706 }
707 /*!
708   Destructor
709 */
710 VISU::Container_i::~Container_i()
711 {
712   MESSAGE("Container_i::~Container_i");
713   myCurves.clear();
714 }
715 /*!
716   Inserts curve into the container
717 */
718 void VISU::Container_i::AddCurve( Curve_ptr theCurve )
719 {
720   if ( myStudy->_is_nil() )
721     return;
722   SALOMEDS::SObject_var mySO = myStudy->FindObjectID( GetEntry() );
723   if ( mySO->_is_nil() )
724     return;
725   PortableServer::POA_ptr aPOA = GetPOA();
726   Curve_i* pCurve = dynamic_cast<Curve_i*>( aPOA->reference_to_servant( theCurve ) );
727   if( pCurve ) {
728     QString entry = pCurve->GetEntry();
729     SALOMEDS::SObject_var SO = myStudy->FindObjectID( entry.latin1() );
730     if ( !SO->_is_nil() && myCurves.find( entry ) == myCurves.end() ) {
731       myCurves.append( entry );
732       SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
733       SALOMEDS::SObject_var newSO = Builder->NewObject( mySO );
734       Builder->Addreference( newSO, SO );
735     }
736   }
737 }
738 /*!
739   Removes curve from the container
740 */
741 void VISU::Container_i::RemoveCurve( Curve_ptr theCurve )
742 {
743   if ( myStudy->_is_nil() )
744     return;
745   SALOMEDS::SObject_var mySO = myStudy->FindObjectID( GetEntry() );
746   if ( mySO->_is_nil() )
747     return;
748   PortableServer::POA_ptr aPOA = GetPOA();
749   Curve_i* pCurve = dynamic_cast<Curve_i*>( aPOA->reference_to_servant( theCurve ) );
750   if( pCurve ) {
751     QString entry = pCurve->GetEntry();
752     if ( myCurves.find( entry ) != myCurves.end() ) {
753       // found !!!
754       myCurves.remove( entry );
755       SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
756       SALOMEDS::ChildIterator_var CI = myStudy->NewChildIterator( mySO );
757       for ( ; CI->More(); CI->Next() ) {
758         SALOMEDS::SObject_var childSO = CI->Value();
759         SALOMEDS::SObject_var refSO;
760         if ( childSO->ReferencedObject( refSO ) && !refSO->_is_nil() && entry == QString( refSO->GetID() ) ) {
761           Builder->RemoveObject( childSO );
762         }
763       }
764     }
765   }
766 }
767 /*!
768   Gets number of curves in the container
769 */
770 CORBA::Long VISU::Container_i::GetNbCurves()
771 {
772   Update();
773   return myCurves.count();
774 }
775 /*!
776   Clears container
777 */
778 void VISU::Container_i::Clear()
779 {
780   if ( myStudy->_is_nil() )
781     return;
782   SALOMEDS::SObject_var mySO = myStudy->FindObjectID( GetEntry() );
783   if ( mySO->_is_nil() )
784     return;
785   QStringList toDelete;
786   SALOMEDS::ChildIterator_var CI = myStudy->NewChildIterator( mySO );
787   for ( ; CI->More(); CI->Next() ) {
788     toDelete.append( CI->Value()->GetID() );
789   }
790   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
791   for ( int i = 0; i < toDelete.count(); i++ ) {
792     SALOMEDS::SObject_var SO = myStudy->FindObjectID( toDelete[i].latin1() );
793     Builder->RemoveObject( SO );
794   }
795   myCurves.clear();
796 }
797 /*!
798   Creates container object
799 */
800 VISU::Storable* VISU::Container_i::Create()
801 {
802   // generate name ...
803   myName = GenerateName();
804   // ... and build the object
805   return Build( false );
806 }
807 /*!
808   Builds presentation of container
809 */
810 VISU::Storable* VISU::Container_i::Build( int theRestoring )
811 {
812   if ( !theRestoring ) {
813     // looking for component
814     SALOMEDS::SComponent_var SComponent = VISU::FindOrCreateVisuComponent( myStudy );
815     // create SObject and set attributes
816     QString aComment;
817     aComment.sprintf("myComment=%s;myType=%d",GetComment(),VISU::TCONTAINER);
818     string anEntry = CreateAttributes( myStudy,
819                                        SComponent->GetID(),
820                                        "",
821                                        GetID(),
822                                        GetName(),
823                                        "",
824                                        aComment.latin1(),
825                                        true );
826     mySObj = SALOMEDS::SObject::_duplicate(myStudy->FindObjectID(anEntry.c_str()));
827   }
828   return this;
829 }
830 /*!
831   Updates presentation of container
832 */
833 void VISU::Container_i::Update()
834 {
835   if ( myStudy->_is_nil() )
836     return;
837   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
838   SALOMEDS::SObject_var mySO = myStudy->FindObjectID( GetEntry() );
839   SALOMEDS::GenericAttribute_var anAttr;
840   if ( !mySO->_is_nil() ) {
841     QStringList toDelete;
842     int i;
843     for ( i = 0; i < myCurves.count(); i++ ) {
844       SALOMEDS::SObject_var SO = myStudy->FindObjectID( myCurves[i].latin1() );
845       if ( !SO->_is_nil() && Builder->FindAttribute( SO, anAttr, "AttributeIOR" ) ) {
846         // if real Curve Object still exists
847         SALOMEDS::ChildIterator_var CI = myStudy->NewChildIterator( mySO );
848         bool bFound = false;
849         for ( ; CI->More(); CI->Next() ) {
850           SALOMEDS::SObject_var childSO = CI->Value();
851           SALOMEDS::SObject_var refSO;
852           if ( childSO->ReferencedObject( refSO ) && !refSO->_is_nil() && myCurves[i] == QString( refSO->GetID() ) ) {
853             bFound = true; break;
854           }
855         }
856         if (! bFound ) {
857           // create SObject referenced to real curve object if is not yet added
858           SALOMEDS::SObject_var newSO = Builder->NewObject( mySO );
859           Builder->Addreference( newSO, SO );
860         }
861       }
862       else {
863         // real Curve Object doesn't exist (might be removed)
864         toDelete.append( myCurves[i] );
865       }
866     }
867     for ( i = 0; i < toDelete.count(); i++ ) {
868       myCurves.remove( toDelete[i] );
869     }
870     toDelete.clear();
871     SALOMEDS::ChildIterator_var CI = myStudy->NewChildIterator( mySO );
872     for ( ; CI->More(); CI->Next() ) {
873       SALOMEDS::SObject_var childSO = CI->Value();
874       SALOMEDS::SObject_var refSO;
875       if ( childSO->ReferencedObject( refSO ) && ( refSO->_is_nil() || !Builder->FindAttribute( refSO, anAttr, "AttributeIOR" ) ||
876                                                    myCurves.find( refSO->GetID() ) == myCurves.end() ) ) {
877         toDelete.append( childSO->GetID() );
878       }
879     }
880     for ( i = 0; i < toDelete.count(); i++ ) {
881       SALOMEDS::ChildIterator_var CI = myStudy->NewChildIterator( mySO );
882       for ( ; CI->More(); CI->Next() ) {
883         SALOMEDS::SObject_var childSO = CI->Value();
884         if ( toDelete[i] == CI->Value()->GetID() ) {
885           Builder->RemoveObject( childSO );
886         }
887       }
888     }
889   }
890 }
891 /*!
892   Gets curve from container by index
893   NB : curves are numbered from 1
894 */
895 VISU::Curve_i* VISU::Container_i::GetCurve( CORBA::Long theIndex )
896 {
897   if ( theIndex > 0 && theIndex <= myCurves.count()  ) {
898     SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
899     SALOMEDS::GenericAttribute_var anAttr;
900     SALOMEDS::SObject_var SO = myStudy->FindObjectID( myCurves[  theIndex-1 ].latin1() );
901     CORBA::Object_var anObject = VISU::SObjectToObject( SO );
902     if( !CORBA::is_nil( anObject ) ) {
903       // if real Curve Object exists
904       CORBA::Object_ptr aCurve = VISU::Curve::_narrow( anObject );
905       if( !CORBA::is_nil( aCurve ) )
906       return dynamic_cast<VISU::Curve_i*>(VISU::GetServant(aCurve).in());
907     }
908   }
909   return NULL;
910 }
911 /*!
912   Restores container data from the stream
913 */
914 VISU::Storable* VISU::Container_i::Restore( const Storable::TRestoringMap& theMap, SALOMEDS::SObject_ptr SO )
915 {
916   if(MYDEBUG) MESSAGE(GetComment());
917   mySObj = SALOMEDS::SObject::_duplicate(SO);
918   myName = VISU::Storable::FindValue( theMap, "myName" ).latin1();
919   QString val = VISU::Storable::FindValue( theMap, "myCurves" );
920   myCurves = QStringList::split( QString( "*" ), val, false );
921   return Build( true );
922 }
923 /*!
924   Flushes container data into the stream
925 */
926 void VISU::Container_i::ToStream( std::ostringstream& theStr )
927 {
928   Storable::DataToStream( theStr, "myName",   myName.c_str() );
929   Storable::DataToStream( theStr, "myCurves", myCurves.join( QString( "*" ) ) );
930 //  theStr<<" myName "<<myName;
931 //  theStr<<" myCurves "<<myCurves.join( QString( "*" ) ).latin1()<<"* ";
932 }
933 /*!
934   Called from engine to restore container from the file
935 */
936 VISU::Storable* VISU::Container_i::Restore(SALOMEDS::SObject_ptr theSObject,
937                                            const string& thePrefix, const Storable::TRestoringMap& theMap)
938 {
939   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
940   VISU::Container_i* pResent = new VISU::Container_i( aStudy );
941   return pResent->Restore( theMap, theSObject );
942 }
943
944 void VISU::Container_i::RemoveFromStudy()
945 {
946   VISU::RemoveFromStudy(mySObj,false);
947 }
948
949 //-------------------------------------------------------------
950 //             Implementation of reading from file
951 //-------------------------------------------------------------
952 typedef string TValue;
953 typedef vector<TValue> TValues;
954
955 struct TRow{
956   string myTitle;
957   string myUnit;
958   TValues myValues;
959 };
960
961 typedef vector<TRow> TRows;
962
963 struct TTable2D {
964   string myTitle;
965   vector<string> myColumnUnits;
966   vector<string> myColumnTitles;
967   TRows myRows;
968   int Check(){
969     if(myRows.empty()) return 0;
970     int iEnd = myRows[0].myValues.size();
971     if(iEnd == 0) return 0;
972     if(myColumnTitles.size() != iEnd) myColumnTitles.resize(iEnd);
973     if(myColumnUnits.size() != iEnd) myColumnUnits.resize(iEnd);
974     int jEnd = myRows.size();
975     for(int j = 0; j < jEnd; j++)
976       if(myRows[j].myValues.size() != iEnd)
977         return 0;
978     return 1;
979   }
980   void getColumns(TTable2D& theTable2D) const {
981     TRows& aRows = theTable2D.myRows;
982     aRows.clear();
983     if(myRows.empty()) return;
984     int jEnd = myRows.size();
985     //Define Titles & Units
986     theTable2D.myColumnTitles.resize(jEnd);
987     theTable2D.myColumnUnits.resize(jEnd);
988     for(int j = 0; j < jEnd; j++){
989       theTable2D.myColumnTitles[j] = myRows[j].myTitle;
990       theTable2D.myColumnUnits[j] = myRows[j].myUnit;
991     }
992     //Define Rows
993     int iEnd = myRows[0].myValues.size();
994     for(int i = 0; i < iEnd; i++){
995       TRow aNewRow;
996       aNewRow.myTitle = myColumnTitles[i];
997       aNewRow.myUnit = myColumnUnits[i];
998       aNewRow.myValues.resize(jEnd);
999       for(int j = 0; j < jEnd; j++){
1000         aNewRow.myValues[j] = myRows[j].myValues[i];
1001       }
1002       aRows.push_back(aNewRow);
1003     }
1004   }
1005 };
1006
1007 typedef vector<TTable2D> TTableCont;
1008
1009 int getLine(ifstream& theStmIn, QString& theString){
1010   char tmp;
1011   ostrstream aStrOut;
1012   while(theStmIn.get(tmp)){
1013     aStrOut<<tmp;
1014     if(tmp == '\n') break;
1015   }
1016   aStrOut<<ends;
1017   theString = aStrOut.str();
1018   return !theStmIn.eof();
1019 }
1020
1021 void ImportTables(const char* theFileName, TTableCont& theTableCont){
1022   ifstream aStmIn;
1023   QFileInfo aFileInfo( theFileName );
1024   if( !aFileInfo.isFile() || !aFileInfo.isReadable() || !aFileInfo.size() )
1025     return;
1026   aStmIn.open( theFileName );
1027   QString aTmp;
1028   do {
1029     // find beginning of table (tables are separated by empty lines)
1030     while( getLine( aStmIn, aTmp ) && aTmp.stripWhiteSpace() == "");
1031     TTable2D aTable2D;
1032     if(MYDEBUG) cout << "New table is found" << endl;
1033     while( !aStmIn.eof() && aTmp.stripWhiteSpace() != "" ){
1034       QString data = aTmp.stripWhiteSpace();
1035       QString cmt = "";
1036       QString keyword = "";
1037       // split string to data and comment (comment starts from '#' symbol)
1038       int index = aTmp.find( "#" );
1039       if ( index >= 0 ) {
1040         data = aTmp.left( index ).stripWhiteSpace();
1041         cmt = aTmp.mid( index+1 ).stripWhiteSpace();
1042       }
1043       // if comment is not empty, try to get keyword from it (separated by ':' symbol)
1044       if ( !cmt.isEmpty() ) {
1045         int index1 = cmt.find( ":" );
1046         if ( index1 >= 0 ) {
1047           QString tmpstr = cmt.left( index1 ).stripWhiteSpace();
1048           if ( tmpstr == QString( "TITLE" ) ||
1049                tmpstr == QString( "COLUMN_TITLES" ) ||
1050                tmpstr == QString( "COLUMN_UNITS" ) ||
1051                tmpstr == QString( "COMMENT" ) ) {
1052             keyword = tmpstr;
1053             cmt = cmt.mid( index1+1 ).stripWhiteSpace();
1054           }
1055         }
1056       }
1057       // if data is empty, process only comment
1058       if ( data.isEmpty() ) {
1059         // if keyword is found, try to process it
1060         // elsewise it is a simple comment, just ignore it
1061         if ( !keyword.isEmpty() ) {
1062           if ( keyword == QString( "TITLE" ) ) {
1063             QString title = cmt;
1064             if ( aTable2D.myTitle != "" )
1065               title = QString( aTable2D.myTitle.c_str() ) + QString( " " ) + title;
1066             if(MYDEBUG) cout << "...Table TITLE is: " << title.latin1() << endl;
1067             aTable2D.myTitle = title.latin1();
1068           }
1069           else if ( keyword == QString( "COLUMN_TITLES" ) ) {
1070             // comment may contain column headers
1071             QStringList aStrList = QStringList::split( "|", cmt );
1072             if(MYDEBUG) cout << "...Column TITLES are: ";
1073             for ( int i = 0; i < aStrList.count(); i++ ) {
1074               QString tmpstr = aStrList[ i ].stripWhiteSpace();
1075               if(MYDEBUG) cout << tmpstr.latin1() << " ";
1076               aTable2D.myColumnTitles.push_back( tmpstr.latin1() );
1077             }
1078             if(MYDEBUG) cout << endl;
1079           }
1080           else if ( keyword == QString( "COLUMN_UNITS" ) ) {
1081             // comment may contain column units
1082             QStringList aStrList = QStringList::split( " ", cmt );
1083             if(MYDEBUG) cout << "...Column UNITS are: ";
1084             for ( int i = 0; i < aStrList.count(); i++ ) {
1085               QString tmpstr = aStrList[ i ].stripWhiteSpace();
1086               if(MYDEBUG) cout << tmpstr.latin1() << " ";
1087               aTable2D.myColumnUnits.push_back( tmpstr.latin1() );
1088             }
1089             if(MYDEBUG) cout << endl;
1090           }
1091           else if ( keyword == QString( "COMMENT" ) ) {
1092             // keyword 'COMMENT' processing can be here
1093             // currently it is ignored
1094             if(MYDEBUG) cout << "...COMMENT: " << cmt.latin1() << endl;
1095           }
1096         }
1097         else {
1098           if(MYDEBUG) cout << "...comment: " << cmt.latin1() << endl;
1099           // simple comment processing can be here
1100           // currently it is ignored
1101         }
1102       }
1103       // if data is not empty, try to process it
1104       else {
1105         TRow aRow;
1106         if(MYDEBUG) cout << "...New row is found: " << endl;
1107         if ( !cmt.isEmpty() ) {
1108           aRow.myTitle = cmt.latin1();
1109           if(MYDEBUG) cout << "......ROW TITLE is: " << cmt.latin1() << endl;
1110         }
1111         QStringList aValList = QStringList::split( " ", data );
1112         for ( int i = 0; i < aValList.count(); i++ ) {
1113           if ( aValList[i].stripWhiteSpace() != "" ) {
1114             TValue aVal = aValList[i].stripWhiteSpace().latin1();
1115             aRow.myValues.push_back( aVal );
1116           }
1117         }
1118         if( aRow.myValues.size() > 0 )
1119           aTable2D.myRows.push_back( aRow );
1120         // ************** OLD CODE ******************
1121         /*
1122         TValue aVal;
1123         istrstream aStream( data );
1124         aStream.precision( STRPRECISION );
1125         while( aStream >> aVal ) {
1126           aRow.myValues.push_back( aVal );
1127         }
1128         if( aRow.myValues.size() > 0 )
1129           aTable2D.myRows.push_back( aRow );
1130         */
1131         // ************** OLD CODE ******************
1132       }
1133       getLine( aStmIn, aTmp );
1134     }
1135     if( aTable2D.Check() ) {
1136       if(MYDEBUG) cout << "aTable2D is checked OK " << aTable2D.myTitle << endl;
1137       theTableCont.push_back( aTable2D );
1138     }
1139   }
1140   while( !aStmIn.eof() );
1141   aStmIn.close();
1142   if(MYDEBUG) cout << "After close" << endl;
1143 }
1144
1145 SALOMEDS::SObject_var VISU::ImportTables(const char* theFileName, SALOMEDS::Study_ptr theStudy){
1146   TTableCont aTableCont;
1147   ImportTables(theFileName,aTableCont);
1148   if(aTableCont.empty()) return SALOMEDS::SObject::_nil();
1149   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1150   SALOMEDS::SComponent_var theSComponent = VISU::FindOrCreateVisuComponent(theStudy);
1151   SALOMEDS::SObject_var aFileObject = aStudyBuilder->NewObject(theSComponent);
1152   SALOMEDS::GenericAttribute_var anAttr =
1153     aStudyBuilder->FindOrCreateAttribute(aFileObject, "AttributeName");
1154   SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
1155   QFileInfo aFileInfo(theFileName);
1156   aName->SetValue(aFileInfo.fileName().latin1());
1157   anAttr = aStudyBuilder->FindOrCreateAttribute(aFileObject, "AttributeComment");
1158   SALOMEDS::AttributeComment_var aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
1159   QString aString;
1160   aString.sprintf("myComment=ImportTables;myFileName=%s",
1161                   aFileInfo.absFilePath().latin1());
1162   aComment->SetValue(aString.latin1());
1163   for(int i = 0, iEnd = aTableCont.size(); i < iEnd; i++){
1164     const TTable2D& aTable2D = aTableCont[i];
1165     SALOMEDS::SObject_var aRealObject = aStudyBuilder->NewObject(aFileObject);
1166     anAttr = aStudyBuilder->FindOrCreateAttribute(aRealObject, "AttributeName");
1167     aName = SALOMEDS::AttributeName::_narrow(anAttr);
1168     if(MYDEBUG) cout<<"aTable2D.myTitle = "<<aTable2D.myTitle<<endl;
1169     if(aTable2D.myTitle != "")
1170       aName->SetValue(aTable2D.myTitle.c_str());
1171     else{
1172       QString aNewName;
1173       aNewName.sprintf("Table:%d",i);
1174       aName->SetValue(aNewName.latin1());
1175     }
1176     anAttr = aStudyBuilder->FindOrCreateAttribute(aRealObject, "AttributeTableOfReal");
1177     SALOMEDS::AttributeTableOfReal_var aTableOfReal = SALOMEDS::AttributeTableOfReal::_narrow(anAttr);
1178     aTableOfReal->SetTitle(aTable2D.myTitle.c_str());
1179     TTable2D aNewTable2D;
1180     aTable2D.getColumns(aNewTable2D);
1181     int kEnd = aNewTable2D.myRows[0].myValues.size();
1182     aTableOfReal->SetNbColumns(kEnd);
1183     for(int j = 0, jEnd = aNewTable2D.myRows.size(); j < jEnd; j++){
1184       if(MYDEBUG) cout<<"j = "<<j<<"; kEnd = "<<kEnd<<endl;
1185
1186       for(int k = 0; k < kEnd; k++){
1187         QString aVal = aNewTable2D.myRows[j].myValues[k].c_str();
1188         bool anIsOk = false;
1189         double aValue = aVal.toDouble(&anIsOk);
1190         if(anIsOk && !aVal.contains("NAN",false) && !aVal.contains("INF",false))
1191           aTableOfReal->PutValue(aValue,j+1,k+1);
1192       }
1193
1194       aTableOfReal->SetRowTitle(j+1,aNewTable2D.myRows[j].myTitle.c_str());
1195       aTableOfReal->SetRowUnit(j+1,aNewTable2D.myRows[j].myUnit.c_str());
1196     }
1197     for(int k = 0; k < kEnd; k++)
1198       aTableOfReal->SetColumnTitle(k+1,aNewTable2D.myColumnTitles[k].c_str());
1199   }
1200   return aFileObject;
1201 }
1202
1203 template<class TTableAttr> bool ExportTableToFile(const TTableAttr& aTabAttr,
1204                                                   const char* theFileName)
1205 {
1206   if (!CORBA::is_nil(aTabAttr)) {
1207     QFile aFile(theFileName);
1208     aFile.open(IO_WriteOnly);
1209
1210     /* extract the tabe info and write it into file */
1211
1212     QString aTitle(aTabAttr->GetTitle()); /*Table title*/
1213     int aRowsNb = aTabAttr->GetNbRows();
1214     int aColNb  = aTabAttr->GetNbColumns();
1215
1216     SALOMEDS::StringSeq_var aRowTitles = aTabAttr->GetRowTitles();
1217     QString anAbscissTitle(aRowTitles[0]); /*Absciss row title (X coord)*/
1218     anAbscissTitle.stripWhiteSpace();
1219
1220     SALOMEDS::StringSeq_var aRowUnits = aTabAttr->GetRowUnits();
1221     QString anAbscissUnit(aRowUnits[0]);
1222     anAbscissUnit.stripWhiteSpace();
1223
1224     SALOMEDS::StringSeq_var aColumnTitles = aTabAttr->GetColumnTitles();
1225     if (aRowsNb > 2 && aTitle.length() )  aTitle = aTitle + " - ";
1226
1227     QString aLine;
1228     for (int i = 2; i <= aRowsNb; i++ )
1229       {
1230         /* TITLE */
1231         QString anOrdinate(aRowTitles[i-1]), aTail;
1232         anOrdinate.stripWhiteSpace();
1233
1234         aLine = "#TITLE: " + aTitle +
1235           ((anOrdinate.length())?  anOrdinate :
1236                                   (aRowsNb>2)? aTail.sprintf("%d",i-1) : aTail.sprintf("") ) + "\n";
1237         aFile.writeBlock(aLine, aLine.length() );
1238
1239         /* COLUMN_TITLES */
1240         if ( anAbscissTitle.length() || anOrdinate.length() ) {
1241           aLine = "#COLUMN_TITLES: " + anAbscissTitle + " | " + anOrdinate + "\n";
1242           aFile.writeBlock(aLine, aLine.length() );
1243         }
1244
1245         /* COLUMN_UNITS */
1246         aLine = anAbscissUnit + " " +aRowUnits[i-1];
1247         if (!aLine.stripWhiteSpace().isEmpty()) {
1248           aLine = "#COLUMN_UNITS: " + aLine  + "\n";
1249           aFile.writeBlock(aLine, aLine.length() );
1250         }
1251
1252         /* CURVE COORDINATES */
1253         for (int j = 1; j <= aColNb; j++)
1254           {
1255             if ( aTabAttr -> HasValue(i,j) &&  aTabAttr -> HasValue(1, j)) {
1256               aLine = aLine.sprintf("%.16g %.16g",
1257                                     (double)(aTabAttr->GetValue(1,j)),
1258                                     (double)(aTabAttr->GetValue(i,j)));  /* aTabAttr->GetValue(1,j) - X coord */
1259               if ( !aLine.stripWhiteSpace().isEmpty() ) {
1260                 QString aColTitle(aColumnTitles[j-1]);
1261                 if ( !aColTitle.stripWhiteSpace().isEmpty() )
1262                   aLine = aLine + "  #TITLE: " + aColTitle ;
1263                 aFile.writeBlock(aLine + "\n", aLine.length() + 1);
1264               }
1265             }
1266           }
1267         aFile.writeBlock("\n", 1);
1268       }
1269     aFile.close();
1270     return true;
1271   }
1272   return false;
1273 }
1274
1275 bool VISU::ExportTableToFile(SALOMEDS::SObject_ptr theTable, const char* theFileName)
1276 {
1277   //Find table
1278   SALOMEDS::GenericAttribute_var anAttr ;
1279   if (theTable->FindAttribute(anAttr, "AttributeTableOfReal"))
1280     {
1281       SALOMEDS::AttributeTableOfReal_var aTabAttr = SALOMEDS::AttributeTableOfReal ::_narrow(anAttr);
1282       return ExportTableToFile ( aTabAttr , theFileName);
1283
1284     }
1285   else if (theTable->FindAttribute(anAttr, "AttributeTableOfInteger")) {
1286
1287     SALOMEDS::AttributeTableOfInteger_var aTabAttr = SALOMEDS::AttributeTableOfInteger ::_narrow(anAttr);
1288     return ExportTableToFile ( aTabAttr , theFileName);
1289
1290   }
1291   return false;
1292 }