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