]> SALOME platform Git repositories - modules/visu.git/blob - src/VISU_I/VISU_Table_i.cc
Salome HOME
sources v1.2c
[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 "QAD_Application.h"
30 #include "QAD_Desktop.h"
31 #include "QAD_Study.h"
32
33 #include "VISU_CutLines_i.hh"
34
35 #include <memory>       
36 #include <fstream>      
37 #include <strstream>
38
39 #include <qfileinfo.h>
40
41 using namespace std;
42
43 #ifdef _DEBUG_
44 static int MYDEBUG = 0;
45 #else
46 static int MYDEBUG = 0;
47 #endif
48
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   myObjectEntry = theObjectEntry; 
75   myOrientation = VISU::Table::HORIZONTAL;
76 }
77 /*!
78   Destructor
79 */
80 VISU::Table_i::~Table_i()
81 {
82 }
83 /*!
84   Gets number of rows in table
85 */
86 CORBA::Long VISU::Table_i::GetNbRows()
87 {
88   SALOMEDS::SObject_var SO = myStudy->FindObjectID( myObjectEntry.c_str() );
89   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
90   if ( !SO->_is_nil() ) {
91     SALOMEDS::GenericAttribute_var        anAttr;
92     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
93       SALOMEDS::AttributeTableOfInteger_var anInt =  SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
94       return anInt->GetNbRows();
95     }
96     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
97       SALOMEDS::AttributeTableOfReal_var aReal =  SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
98       return aReal->GetNbRows();
99     }
100   }
101   return 0;
102 }
103 /*!
104   Gets number of columns in table
105 */
106 CORBA::Long VISU::Table_i::GetNbColumns()
107 {
108   SALOMEDS::SObject_var SO = myStudy->FindObjectID( myObjectEntry.c_str() );
109   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
110   if ( !SO->_is_nil() ) {
111     SALOMEDS::GenericAttribute_var        anAttr;
112     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
113       SALOMEDS::AttributeTableOfInteger_var anInt =  SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
114       return anInt->GetNbColumns();
115     }
116     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
117       SALOMEDS::AttributeTableOfReal_var aReal =  SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
118       return aReal->GetNbColumns();
119     }
120   }
121   return 0;
122 }
123 /*!
124   Creates table object
125 */
126 VISU::Storable* VISU::Table_i::Create()
127 {
128   // generate name ... 
129   myName = GetTableTitle(); 
130   if ( myName == "" )
131     myName = GenerateName();
132   // ... and build the object
133   return Build( false );
134 }
135 /*!
136   Builds presentation of table
137 */
138 VISU::Storable* VISU::Table_i::Build( int theRestoring ) 
139 {
140   // look for reference SObject with table attribute
141   SALOMEDS::SObject_var SO = myStudy->FindObjectID( myObjectEntry.c_str() );
142   if ( !SO->_is_nil() ) {
143     CutLines_i* pCutLines = NULL;
144     CORBA::Object_var anObj = SObjectToObject(SO);
145     if(!CORBA::is_nil(anObj)){
146       VISU::CutLines_var aCutLines = VISU::CutLines::_narrow(anObj);
147       if(!aCutLines->_is_nil())
148         pCutLines = dynamic_cast<CutLines_i*>(GetServant(aCutLines));
149     }
150     SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
151     SALOMEDS::GenericAttribute_var anAttr;
152     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) || 
153          Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) || pCutLines) {
154       // look for component
155       if ( !theRestoring ) {
156         SALOMEDS::SComponent_var SComponent = VISU::FindOrCreateVisuComponent( myStudy );
157         // create SObject and set attributes
158         QString aComment;
159         aComment.sprintf("myComment=%s;myType=%d",GetComment(),VISU::TTABLE);
160         string anEntry = CreateAttributes( myStudy, 
161                                            SComponent->GetID(),
162                                            "",
163                                            GetID(),
164                                            GetName(),
165                                            "",
166                                            aComment.latin1(), 
167                                            true );
168         // create SObject referenced to real table object
169         SALOMEDS::SObject_var newSO = myStudy->FindObjectID( anEntry.c_str() );
170         if(pCutLines) {
171           pCutLines->BuildTableOfReal(newSO);
172           myObjectEntry = anEntry;
173         }
174         SALOMEDS::SObject_var refSO = Builder->NewObject( newSO );
175         Builder->Addreference( refSO, SO );
176       }
177       return this;
178     }
179   }
180   return NULL;
181 }
182 /*!
183   Restores table object from stream
184 */
185 VISU::Storable* VISU::Table_i::Restore( const Storable::TRestoringMap& theMap )
186      throw( std::logic_error& )
187 {
188   if(MYDEBUG) MESSAGE(GetComment());
189   myName = (const char*)(VISU::Storable::FindValue(theMap,"myName"));
190   myObjectEntry = (const char *)(VISU::Storable::FindValue(theMap,"myObjectEntry"));
191   myTitle = (const char*)(VISU::Storable::FindValue(theMap,"myTitle"));
192   myOrientation = ( VISU::Table::Orientation )( VISU::Storable::FindValue(theMap,"myOrientation").toInt() );
193   return Build( true );
194 }
195 /*!
196   Flushes table data into stream
197 */
198 void VISU::Table_i::ToStream( std::ostringstream& theStr )
199 {
200   Storable::DataToStream( theStr, "myName",        myName.c_str() );
201   Storable::DataToStream( theStr, "myObjectEntry", myObjectEntry.c_str() );
202   Storable::DataToStream( theStr, "myTitle",       myTitle.c_str() );
203   Storable::DataToStream( theStr, "myOrientation", myOrientation );
204 }
205 /*!
206   Called from engine to restore table from the file
207 */
208 VISU::Storable* VISU::Table_i::Restore(SALOMEDS::SObject_ptr theSObject, 
209                                        const string& thePrefix, const Storable::TRestoringMap& theMap)
210   throw(std::logic_error&)
211 {
212   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
213   VISU::Table_i* pResent = new VISU::Table_i( aStudy, "" );
214   return pResent->Restore( theMap );
215 }
216 /*!
217   Gets title for the original table object
218 */
219 const char* VISU::Table_i::GetTableTitle()
220 {
221   SALOMEDS::SObject_var SO = myStudy->FindObjectID( GetObjectEntry() );
222   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
223   SALOMEDS::GenericAttribute_var        anAttr;
224   SALOMEDS::AttributeTableOfInteger_var anInt;
225   SALOMEDS::AttributeTableOfReal_var    aReal;
226   if ( !SO->_is_nil() ) { 
227     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
228       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
229       return anInt->GetTitle();
230     }
231     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
232       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
233       return aReal->GetTitle();
234     }
235   }
236   return ""; 
237 }
238
239 //----------------------------------------------------------------
240 //                      Curve Object
241 //----------------------------------------------------------------
242 /*!
243   Restores table object from the stream [ static ]
244 */
245 static VISU::Table_i* GetTable( SALOMEDS::Study_var& theStudy, const VISU::Storable::TRestoringMap& theMap ) {
246   string anEntry = VISU::Storable::FindValue( theMap, "TableID" ).latin1();
247   SALOMEDS::SObject_var aSObject = theStudy->FindObjectID( anEntry.c_str() );
248   CORBA::Object_var anObject = VISU::SObjectToObject( aSObject );
249   if( !CORBA::is_nil( anObject ) ) {
250     CORBA::Object_ptr aTable = VISU::Table::_narrow( anObject );
251     if( !CORBA::is_nil( aTable ) )
252       return dynamic_cast<VISU::Table_i*>( VISU::GetServant( aTable ) );
253   }
254   return NULL;
255 }
256
257 int VISU::Curve_i::myNbPresent = 0;
258 const string VISU::Curve_i::myComment  = "CURVE";
259 /*! 
260   Generate unique name
261 */
262 const char* VISU::Curve_i::GenerateName() 
263
264   return VISU::GenerateName( "Curve", ++myNbPresent ); 
265 }
266 /*!
267   Gets comment string
268 */
269 const char* VISU::Curve_i::GetComment() const 
270
271   return myComment.c_str(); 
272 }
273 /*!
274   Constructor
275   NB : theHRow, theVRow are the indexes of rows in the Table object and numbered from the 1 to GetNbRows()
276 */
277 VISU::Curve_i::Curve_i(SALOMEDS::Study_ptr theStudy, Table_i* theTable, CORBA::Long theHRow, CORBA::Long theVRow )
278      : PrsObject_i(theStudy), myTable( theTable ), myHRow( theHRow ), myVRow( theVRow )
279 {
280   myAuto = true;
281   myLine = VISU::Curve::SOLIDLINE;
282   myLineWidth = 0;
283   myMarker = VISU::Curve::CIRCLE;
284   myColor.R = 0.0; myColor.G = 0.0; myColor.B = 0.0;
285 }
286 /*!
287   Destructor
288 */
289 VISU::Curve_i::~Curve_i()
290 {
291 }
292 /*!
293   Creates curve object
294 */
295 VISU::Storable* VISU::Curve_i::Create()
296 {
297   // generate name ... 
298   myName = GetVerTitle(); 
299   if ( myName == "" )
300     myName = GenerateName();
301   // ... and build the object
302   return Build( false );
303 }
304 /*!
305   Builds presentation of curve
306 */
307 VISU::Storable* VISU::Curve_i::Build( int theRestoring ) 
308 {
309   if ( myTable != NULL ) {
310     // getting table SObject by it's entry
311     SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetEntry() );
312     int nbRows = myTable->GetNbRows();
313     if ( !SO->_is_nil() && myHRow > 0 && myHRow <= nbRows && myVRow > 0 && myVRow <= nbRows ) {
314       if ( !theRestoring ) {
315         // look for component
316         SALOMEDS::SComponent_var SComponent = VISU::FindOrCreateVisuComponent( myStudy );
317         // create SObject and set attributes
318         QString aComment;
319         aComment.sprintf("myComment=%s;myType=%d",GetComment(),VISU::TCURVE);
320         string anEntry = CreateAttributes( myStudy, 
321                                            myTable->GetEntry(),
322                                            "",
323                                            GetID(),
324                                            GetName(),
325                                            "",
326                                            aComment.latin1(),
327                                            true );
328       }
329       return this;
330     }
331   }
332   return NULL;
333 }
334
335 /*!
336   Returns CORBA::True if curve refers to valid table data
337 */
338 CORBA::Boolean VISU::Curve_i::IsValid()
339 {
340   // getting table SObject by it's entry
341   SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetObjectEntry() );
342   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
343   SALOMEDS::GenericAttribute_var        anAttr;
344   SALOMEDS::AttributeTableOfInteger_var anInt;
345   SALOMEDS::AttributeTableOfReal_var    aReal;
346   if ( !SO->_is_nil() ) { 
347     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
348       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
349       if ( myHRow > 0 && myHRow <= anInt->GetNbRows() && myVRow > 0 && myVRow <= anInt->GetNbRows() ) {
350         return true;
351       }
352     }
353     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
354       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
355       if ( myHRow > 0 && myHRow <= aReal->GetNbRows() && myVRow > 0 && myVRow <= aReal->GetNbRows() ) {
356         return true;
357       }
358     }
359   }
360   return false;
361 }
362 /*!
363   Returns hor.axis title
364 */
365 string VISU::Curve_i::GetHorTitle()
366 {
367   string title;
368   // getting table SObject by it's entry
369   SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetObjectEntry() );
370   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
371   SALOMEDS::GenericAttribute_var        anAttr;
372   SALOMEDS::AttributeTableOfInteger_var anInt;
373   SALOMEDS::AttributeTableOfReal_var    aReal;
374   if ( !SO->_is_nil() ) { 
375     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
376       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
377       SALOMEDS::StringSeq_var rowTitles = anInt->GetRowTitles();
378       if ( rowTitles->length() > 0 && myHRow > 0 && myHRow <= anInt->GetNbRows() ) {
379         title = strdup( rowTitles[ myHRow-1 ] );
380       }
381     }
382     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
383       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
384       SALOMEDS::StringSeq_var rowTitles = aReal->GetRowTitles();
385       if ( rowTitles->length() > 0 && myHRow > 0 && myHRow <= aReal->GetNbRows() ) {
386         title = strdup( rowTitles[ myHRow-1 ] );
387       }
388     }
389   }
390   return title;
391 }
392 /*!
393   Returns ver.axis title
394 */
395 string VISU::Curve_i::GetVerTitle()
396 {
397   string title;
398   // getting table SObject by it's entry
399   SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetObjectEntry() );
400   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
401   SALOMEDS::GenericAttribute_var        anAttr;
402   SALOMEDS::AttributeTableOfInteger_var anInt;
403   SALOMEDS::AttributeTableOfReal_var    aReal;
404   if ( !SO->_is_nil() ) { 
405     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
406       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
407       SALOMEDS::StringSeq_var rowTitles = anInt->GetRowTitles();
408       if ( rowTitles->length() > 0 && myVRow > 0 && myVRow <= anInt->GetNbRows() )
409         title = strdup( rowTitles[ myVRow-1 ] );
410     }
411     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
412       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
413       SALOMEDS::StringSeq_var rowTitles = aReal->GetRowTitles();
414       if ( rowTitles->length() > 0 && myVRow > 0 && myVRow <= aReal->GetNbRows() )
415         title = strdup( rowTitles[ myVRow-1 ] );
416     }
417   }
418   return title;
419 }
420 /*!
421   Returns hor.axis units
422 */
423 string VISU::Curve_i::GetHorUnits()
424 {
425   string units;
426   // getting table SObject by it's entry
427   SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetObjectEntry() );
428   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
429   SALOMEDS::GenericAttribute_var        anAttr;
430   SALOMEDS::AttributeTableOfInteger_var anInt;
431   SALOMEDS::AttributeTableOfReal_var    aReal;
432   if ( !SO->_is_nil()  ) { 
433     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
434       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
435       SALOMEDS::StringSeq_var rowUnits = anInt->GetRowUnits();
436       if ( rowUnits->length() > 0 && myHRow > 0 && myHRow <= anInt->GetNbRows() )
437         units = strdup( rowUnits[ myHRow-1 ] );
438     }
439     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
440       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
441       SALOMEDS::StringSeq_var rowUnits = aReal->GetRowUnits();
442       if ( rowUnits->length() > 0 && myHRow > 0 && myHRow <= aReal->GetNbRows() )
443         units = strdup( rowUnits[ myHRow-1 ] );
444     }
445   }
446   return units;
447 }
448 /*!
449   Returns ver.axis units
450 */
451 string VISU::Curve_i::GetVerUnits()
452 {
453   string units;
454   // getting table SObject by it's entry
455   SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetObjectEntry() );
456   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
457   SALOMEDS::GenericAttribute_var        anAttr;
458   SALOMEDS::AttributeTableOfInteger_var anInt;
459   SALOMEDS::AttributeTableOfReal_var    aReal;
460   if ( !SO->_is_nil() ) { 
461     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
462       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
463       SALOMEDS::StringSeq_var rowUnits = anInt->GetRowUnits();
464       if ( rowUnits->length() > 0 && myVRow > 0 && myVRow <= anInt->GetNbRows() )
465         units = strdup( rowUnits[ myVRow-1] );
466     }
467     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
468       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
469       SALOMEDS::StringSeq_var rowUnits = aReal->GetRowUnits();
470       if ( rowUnits->length() > 0 && myVRow > 0 && myVRow <= aReal->GetNbRows() )
471         units = strdup( rowUnits[ myVRow-1 ] );
472     }
473   }
474   return units;
475 }
476 /*!
477   Gets curve data
478 */
479 int VISU::Curve_i::GetData( double*& theHorList, double*& theVerList )
480 {
481   theHorList = 0; theVerList = 0;
482   // getting table SObject by it's entry
483   SALOMEDS::SObject_var SO = myStudy->FindObjectID( myTable->GetObjectEntry() );
484   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
485   SALOMEDS::GenericAttribute_var        anAttr;
486   SALOMEDS::AttributeTableOfInteger_var anInt;
487   SALOMEDS::AttributeTableOfReal_var    aReal;
488   if ( !SO->_is_nil() ) { 
489     if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfInteger" ) ) {
490       anInt = SALOMEDS::AttributeTableOfInteger::_narrow( anAttr );
491       int nbCols = anInt->GetNbColumns() ; 
492       if ( nbCols > 0 && myHRow > 0 && myHRow <= anInt->GetNbRows() && myVRow > 0 && myVRow <= anInt->GetNbRows() ) {
493         int nbPoints = 0;
494         for ( int j = 1; j <= nbCols; j++ ) {
495           if ( anInt->HasValue( myHRow, j ) && anInt->HasValue( myVRow, j ) )
496             nbPoints++;
497         }
498         if ( nbPoints > 0 ) {
499           theHorList = new double[ nbPoints ];
500           theVerList = new double[ nbPoints ];
501           int k = 0;
502           for ( int j = 1; j <= nbCols; j++ ) {
503             if ( anInt->HasValue( myHRow, j ) && anInt->HasValue( myVRow, j ) ) {
504               theHorList[k] = anInt->GetValue( myHRow, j );
505               theVerList[k] = anInt->GetValue( myVRow, j );
506               k++;
507             }
508           }
509         }
510         return nbPoints;
511       }
512     }
513     else if ( Builder->FindAttribute( SO, anAttr, "AttributeTableOfReal" ) ) {
514       aReal = SALOMEDS::AttributeTableOfReal::_narrow( anAttr );
515       int nbCols = aReal->GetNbColumns() ; 
516       if ( nbCols > 0 && myHRow > 0 && myHRow <= aReal->GetNbRows() && myVRow > 0 && myVRow <= aReal->GetNbRows() ) {
517         int nbPoints = 0;
518         for ( int j = 1; j <= nbCols; j++ ) {
519           if ( aReal->HasValue( myHRow, j ) && aReal->HasValue( myVRow, j ) )
520             nbPoints++;
521         }
522         if ( nbPoints > 0 ) {
523           theHorList = new double[ nbPoints ];
524           theVerList = new double[ nbPoints ];
525           int k = 0;
526           for ( int j = 1; j <= nbCols; j++ ) {
527             if ( aReal->HasValue( myHRow, j ) && aReal->HasValue( myVRow, j ) ) {
528               theHorList[k] = aReal->GetValue( myHRow, j );
529               theVerList[k] = aReal->GetValue( myVRow, j );
530               k++;
531             }
532           }
533         }
534         return nbPoints;
535       }
536     }
537   }
538   return 0;
539 }
540 /*!
541   Creates curve Plot2d presentation object
542 */
543 Plot2d_Curve* VISU::Curve_i::CreatePresentation()
544 {
545   Plot2d_Curve* crv = new Plot2d_Curve();
546   crv->setHorTitle( GetHorTitle().c_str() );
547   string tlt = GetTitle(); 
548   if ( tlt.length() <= 0 )
549     tlt = GetVerTitle();
550   //crv->setVerTitle( strdup( GetVerTitle().c_str() ) );
551   //crv->setVerTitle( strdup( GetName() ) );
552   crv->setVerTitle( tlt.c_str() );
553   crv->setHorUnits( GetHorUnits().c_str() );
554   crv->setVerUnits( GetVerUnits().c_str() );
555   double* xList = 0;
556   double* yList = 0;
557   int     nbPoints = GetData( xList, yList );
558   if ( nbPoints > 0 && xList && yList ) {
559     crv->setData( xList, yList, nbPoints );
560   }
561   //cout << "********** Number of points: " << nbPoints <<endl;
562   //for ( int i =0 ; i < nbPoints; i++ ) {
563   //  cout << i<<"\t"<<xList[i] << "\t"<< yList[i] << endl;
564   //}
565   crv->setLine( (Plot2d_Curve::LineType)GetLine(), GetLineWidth() );
566   crv->setMarker( (Plot2d_Curve::MarkerType)GetMarker() ); 
567   SALOMEDS::Color color = GetColor();
568   crv->setColor( QColor( (int)(color.R*255.), (int)(color.G*255.), (int)(color.B*255.) ) );
569   crv->setAutoAssign( IsAuto() );
570   crv->setIO(new SALOME_InteractiveObject(strdup(GetEntry()),"VISU",strdup(GetName()))); 
571   if ( myTable )
572     crv->setTableIO(new SALOME_InteractiveObject(strdup(myTable->GetEntry()),"VISU",strdup(myTable->GetName()))); 
573   return crv;
574 }
575 /*!
576   Restores curve object from stream
577 */
578 VISU::Storable* VISU::Curve_i::Restore( const Storable::TRestoringMap& theMap )
579      throw( std::logic_error& )
580 {
581   if(MYDEBUG) MESSAGE(GetComment());
582   myName = (const char*)(VISU::Storable::FindValue(theMap,"myName"));
583   myHRow = VISU::Storable::FindValue(theMap,"myHRow").toInt();
584   myVRow = VISU::Storable::FindValue(theMap,"myVRow").toInt();
585   myColor.R = VISU::Storable::FindValue(theMap,"myColor.R").toDouble();
586   myColor.G = VISU::Storable::FindValue(theMap,"myColor.G").toDouble();
587   myColor.B = VISU::Storable::FindValue(theMap,"myColor.B").toDouble();
588   myMarker = ( VISU::Curve::MarkerType )( VISU::Storable::FindValue(theMap,"myMarker").toInt() );
589   myLine = ( VISU::Curve::LineType )( VISU::Storable::FindValue(theMap,"myLine").toInt() );
590   return Build( true );
591 }
592 /*!
593   Flushes curve data into stream
594 */
595 void VISU::Curve_i::ToStream( std::ostringstream& theStr )
596 {
597   Storable::DataToStream( theStr, "TableID",   GetTableID());
598   Storable::DataToStream( theStr, "myName",    myName.c_str() );
599   Storable::DataToStream( theStr, "myHRow",    myHRow );
600   Storable::DataToStream( theStr, "myVRow",    myVRow );
601   Storable::DataToStream( theStr, "myColor.R", myColor.R );
602   Storable::DataToStream( theStr, "myColor.G", myColor.G );
603   Storable::DataToStream( theStr, "myColor.B", myColor.B );
604   Storable::DataToStream( theStr, "myMarker",  myMarker );
605   Storable::DataToStream( theStr, "myLine",    myLine );
606 }
607 /*!
608   Gets reference table's entry
609 */
610 const char* VISU::Curve_i::GetTableID() { 
611   return CORBA::string_dup(myTable->GetEntry());
612 }
613 /*!
614   Called from engine to restore curve from the file
615 */
616 VISU::Storable* VISU::Curve_i::Restore(SALOMEDS::SObject_ptr theSObject, 
617                                        const string& thePrefix, const Storable::TRestoringMap& theMap)
618   throw(std::logic_error&)
619 {
620   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
621   VISU::Table_i* pTable = GetTable( aStudy, theMap );
622   if( pTable != NULL ) {
623     VISU::Curve_i* pResent = new VISU::Curve_i( aStudy, pTable, 0, 0 );
624     return pResent->Restore( theMap );
625   }
626   return NULL;
627 }
628
629 //----------------------------------------------------------------
630 //                      Container Object
631 //----------------------------------------------------------------
632 int VISU::Container_i::myNbPresent = 0;
633 const string VISU::Container_i::myComment  = "CONTAINER";
634 /*! 
635   Generate unique name
636 */
637 const char* VISU::Container_i::GenerateName() 
638
639   return VISU::GenerateName( "Container", ++myNbPresent ); 
640 }
641 /*!
642   Gets comment string
643 */
644 const char* VISU::Container_i::GetComment() const 
645
646   return myComment.c_str(); 
647 }
648 /*!
649   Constructor
650 */
651 VISU::Container_i::Container_i( SALOMEDS::Study_ptr theStudy )
652      : PrsObject_i( theStudy )
653 {
654 }
655 /*!
656   Destructor
657 */
658 VISU::Container_i::~Container_i()
659 {
660   myCurves.clear();
661 }
662 /*!
663   Inserts curve into the container
664 */
665 void VISU::Container_i::AddCurve( Curve_ptr theCurve )
666 {
667   if ( myStudy->_is_nil() )
668     return;
669   SALOMEDS::SObject_var mySO = myStudy->FindObjectID( GetEntry() );
670   if ( mySO->_is_nil() )
671     return;
672   PortableServer::POA_ptr aPOA = GetPOA();
673   Curve_i* pCurve = dynamic_cast<Curve_i*>( aPOA->reference_to_servant( theCurve ) );
674   if( pCurve ) {
675     QString entry = pCurve->GetEntry();
676     SALOMEDS::SObject_var SO = myStudy->FindObjectID( entry.latin1() );
677     if ( !SO->_is_nil() && myCurves.find( entry ) == myCurves.end() ) {
678       myCurves.append( entry );
679       SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
680       SALOMEDS::SObject_var newSO = Builder->NewObject( mySO );
681       Builder->Addreference( newSO, SO );
682     }
683   }
684 }
685 /*!
686   Removes curve from the container
687 */
688 void VISU::Container_i::RemoveCurve( Curve_ptr theCurve )
689 {
690   if ( myStudy->_is_nil() )
691     return;
692   SALOMEDS::SObject_var mySO = myStudy->FindObjectID( GetEntry() );
693   if ( mySO->_is_nil() )
694     return;
695   PortableServer::POA_ptr aPOA = GetPOA();
696   Curve_i* pCurve = dynamic_cast<Curve_i*>( aPOA->reference_to_servant( theCurve ) );
697   if( pCurve ) {
698     QString entry = pCurve->GetEntry();
699     if ( myCurves.find( entry ) != myCurves.end() ) {
700       // found !!!
701       myCurves.remove( entry );
702       SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
703       SALOMEDS::ChildIterator_var CI = myStudy->NewChildIterator( mySO );
704       for ( ; CI->More(); CI->Next() ) {
705         SALOMEDS::SObject_var childSO = CI->Value();
706         SALOMEDS::SObject_var refSO;
707         if ( childSO->ReferencedObject( refSO ) && !refSO->_is_nil() && entry == QString( refSO->GetID() ) ) {
708           Builder->RemoveObject( childSO );
709         }
710       }
711     }
712   }
713 }
714 /*!
715   Gets number of curves in the container
716 */
717 CORBA::Long VISU::Container_i::GetNbCurves()
718 {
719   return myCurves.count();
720 }
721 /*!
722   Clears container
723 */
724 void VISU::Container_i::Clear()
725 {
726   if ( myStudy->_is_nil() )
727     return;
728   SALOMEDS::SObject_var mySO = myStudy->FindObjectID( GetEntry() );
729   if ( mySO->_is_nil() )
730     return;
731   QStringList toDelete;
732   SALOMEDS::ChildIterator_var CI = myStudy->NewChildIterator( mySO );
733   for ( ; CI->More(); CI->Next() ) {
734     toDelete.append( CI->Value()->GetID() );
735   }
736   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
737   for ( int i = 0; i < toDelete.count(); i++ ) {
738     SALOMEDS::SObject_var SO = myStudy->FindObjectID( toDelete[i].latin1() );
739     Builder->RemoveObject( SO );
740   }
741   myCurves.clear();
742 }
743 /*!
744   Creates container object
745 */
746 VISU::Storable* VISU::Container_i::Create()
747 {
748   // generate name ... 
749   myName = GenerateName();
750   // ... and build the object
751   return Build( false );
752 }
753 /*!
754   Builds presentation of container
755 */
756 VISU::Storable* VISU::Container_i::Build( int theRestoring ) 
757 {
758   if ( !theRestoring ) {
759     // looking for component
760     SALOMEDS::SComponent_var SComponent = VISU::FindOrCreateVisuComponent( myStudy );
761     // create SObject and set attributes
762     QString aComment;
763     aComment.sprintf("myComment=%s;myType=%d",GetComment(),VISU::TCONTAINER);
764     string anEntry = CreateAttributes( myStudy, 
765                                        SComponent->GetID(),
766                                        "",
767                                        GetID(),
768                                        GetName(),
769                                        "",
770                                        aComment.latin1(),
771                                        true );
772   }
773   return this;
774 }
775 /*!
776   Updates presentation of container
777 */
778 void VISU::Container_i::Update()
779 {
780   if ( myStudy->_is_nil() )
781     return;
782   SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
783   SALOMEDS::SObject_var mySO = myStudy->FindObjectID( GetEntry() );
784   SALOMEDS::GenericAttribute_var anAttr;
785   if ( !mySO->_is_nil() ) {
786     QStringList toDelete;
787     int i;
788     for ( i = 0; i < myCurves.count(); i++ ) {
789       SALOMEDS::SObject_var SO = myStudy->FindObjectID( myCurves[i].latin1() );
790       if ( !SO->_is_nil() && Builder->FindAttribute( SO, anAttr, "AttributeIOR" ) ) {
791         // if real Curve Object still exists 
792         SALOMEDS::ChildIterator_var CI = myStudy->NewChildIterator( mySO );
793         bool bFound = false;
794         for ( ; CI->More(); CI->Next() ) {
795           SALOMEDS::SObject_var childSO = CI->Value();
796           SALOMEDS::SObject_var refSO;
797           if ( childSO->ReferencedObject( refSO ) && !refSO->_is_nil() && myCurves[i] == QString( refSO->GetID() ) ) {
798             bFound = true; break;
799           }
800         }
801         if (! bFound ) {
802           // create SObject referenced to real curve object if is not yet added
803           SALOMEDS::SObject_var newSO = Builder->NewObject( mySO );
804           Builder->Addreference( newSO, SO );
805         }
806       }
807       else {
808         // real Curve Object doesn't exist (might be removed)
809         toDelete.append( myCurves[i] );
810       }
811     }
812     for ( i = 0; i < toDelete.count(); i++ ) { 
813       myCurves.remove( toDelete[i] );
814     }
815     toDelete.clear();
816     SALOMEDS::ChildIterator_var CI = myStudy->NewChildIterator( mySO );
817     for ( ; CI->More(); CI->Next() ) {
818       SALOMEDS::SObject_var childSO = CI->Value();
819       SALOMEDS::SObject_var refSO;
820       if ( childSO->ReferencedObject( refSO ) && ( refSO->_is_nil() || !Builder->FindAttribute( refSO, anAttr, "AttributeIOR" ) ||
821                                                    myCurves.find( refSO->GetID() ) == myCurves.end() ) ) {
822         toDelete.append( childSO->GetID() );
823       }
824     }
825     for ( i = 0; i < toDelete.count(); i++ ) { 
826       SALOMEDS::ChildIterator_var CI = myStudy->NewChildIterator( mySO );
827       for ( ; CI->More(); CI->Next() ) {
828         SALOMEDS::SObject_var childSO = CI->Value();
829         if ( toDelete[i] == CI->Value()->GetID() ) {
830           Builder->RemoveObject( childSO );
831         }
832       }
833     }
834   }
835 }
836 /*!
837   Gets curve from container by index
838   NB : curves are numbered from 1
839 */
840 VISU::Curve_i* VISU::Container_i::GetCurve( CORBA::Long theIndex )
841 {
842   if ( theIndex > 0 && theIndex <= myCurves.count()  ) {
843     SALOMEDS::StudyBuilder_var Builder = myStudy->NewBuilder();
844     SALOMEDS::GenericAttribute_var anAttr;
845     SALOMEDS::SObject_var SO = myStudy->FindObjectID( myCurves[  theIndex-1 ].latin1() );
846     CORBA::Object_var anObject = VISU::SObjectToObject( SO );
847     if( !CORBA::is_nil( anObject ) ) {
848       // if real Curve Object exists 
849       CORBA::Object_ptr aCurve = VISU::Curve::_narrow( anObject );
850       if( !CORBA::is_nil( aCurve ) )
851       return dynamic_cast<VISU::Curve_i*>(VISU::GetServant( aCurve ) );
852     }
853   }
854   return NULL;
855 }
856 /*!
857   Restores container data from the stream
858 */
859 VISU::Storable* VISU::Container_i::Restore( const Storable::TRestoringMap& theMap )
860      throw( std::logic_error& )
861 {
862   if(MYDEBUG) MESSAGE(GetComment());
863   myName = (const char*)(VISU::Storable::FindValue( theMap, "myName" )); 
864   QString val = VISU::Storable::FindValue( theMap, "myCurves" );
865   myCurves = QStringList::split( QString( "*" ), val, false );
866   return Build( true );
867 }
868 /*!
869   Flushes container data into the stream
870 */
871 void VISU::Container_i::ToStream( std::ostringstream& theStr )
872 {
873   Storable::DataToStream( theStr, "myName",   myName.c_str() );
874   Storable::DataToStream( theStr, "myCurves", myCurves.join( QString( "*" ) ) );
875 //  theStr<<" myName "<<myName;
876 //  theStr<<" myCurves "<<myCurves.join( QString( "*" ) ).latin1()<<"* ";
877 }
878 /*!
879   Called from engine to restore container from the file
880 */
881 VISU::Storable* VISU::Container_i::Restore(SALOMEDS::SObject_ptr theSObject, 
882                                            const string& thePrefix, const Storable::TRestoringMap& theMap)
883   throw(std::logic_error&)
884 {
885   SALOMEDS::Study_var aStudy = theSObject->GetStudy();
886   VISU::Container_i* pResent = new VISU::Container_i( aStudy );
887   return pResent->Restore( theMap );
888 }
889
890 //-------------------------------------------------------------
891 //             Implementation of reading from file
892 //-------------------------------------------------------------
893 typedef double TValue;
894 typedef vector<TValue> TValues;
895
896 struct TRow{
897   string myTitle;
898   string myUnit;
899   TValues myValues;
900 };
901
902 typedef vector<TRow> TRows;
903
904 struct TTable2D{
905   string myTitle;
906   vector<string> myColumnUnits;
907   vector<string> myColumnTitles;
908   TRows myRows;
909   int Check(){
910     if(myRows.empty()) return 0;
911     int iEnd = myRows[0].myValues.size();
912     if(iEnd == 0) return 0;
913     if(myColumnTitles.size() != iEnd) myColumnTitles.resize(iEnd);
914     if(myColumnUnits.size() != iEnd) myColumnUnits.resize(iEnd);
915     int jEnd = myRows.size();
916     for(int j = 0; j < jEnd; j++)
917       if(myRows[j].myValues.size() != iEnd) 
918         return 0;
919     return 1;
920   }
921   void getColumns(TTable2D& theTable2D) const {
922     TRows& aRows = theTable2D.myRows;
923     aRows.clear();
924     if(myRows.empty()) return;
925     int jEnd = myRows.size();
926     //Define Titles & Units
927     theTable2D.myColumnTitles.resize(jEnd);
928     theTable2D.myColumnUnits.resize(jEnd);
929     for(int j = 0; j < jEnd; j++){
930       theTable2D.myColumnTitles[j] = myRows[j].myTitle;
931       theTable2D.myColumnUnits[j] = myRows[j].myUnit;
932     }
933     //Define Rows
934     int iEnd = myRows[0].myValues.size();
935     for(int i = 0; i < iEnd; i++){
936       TRow aNewRow;
937       aNewRow.myTitle = myColumnTitles[i];
938       aNewRow.myUnit = myColumnUnits[i];
939       aNewRow.myValues.resize(jEnd);
940       for(int j = 0; j < jEnd; j++){
941         aNewRow.myValues[j] = myRows[j].myValues[i];
942       }
943       aRows.push_back(aNewRow);
944     }
945   }
946 };
947
948 typedef vector<TTable2D> TTableCont;
949
950 int getLine(ifstream& theStmIn, QString& theString){
951   char tmp;
952   ostrstream aStrOut;
953   while(theStmIn.get(tmp)){
954     aStrOut<<tmp;
955     if(tmp == '\n') break;
956   }
957   aStrOut<<ends;
958   theString = aStrOut.str();
959   return !theStmIn.eof();
960 }
961
962 void ImportTables(const char* theFileName, TTableCont& theTableCont){
963   static int STRPRECISION = 12;
964   ifstream aStmIn;
965   QFileInfo aFileInfo(theFileName);
966   if(!aFileInfo.isFile() || !aFileInfo.isReadable() || !aFileInfo.size()) return;
967   aStmIn.open(theFileName);
968   QString aTmp;
969   do{
970     //Find beginning of Table
971     while(getLine(aStmIn,aTmp) && aTmp == "\n");
972     if(MYDEBUG) cout<<"\n There is new Table2D with Title = ";
973     TTable2D aTable2D;
974     while(!aStmIn.eof() && aTmp != "\n"){
975       if(aTmp.find("#TITLE:") == 0){
976         int aLen = aTmp.find(":") + 1;
977         aTmp.remove(0,aLen);
978         QString aTitle = aTmp.stripWhiteSpace();
979         aTable2D.myTitle = aTitle.latin1();
980         if(MYDEBUG) cout<<aTitle<<endl;
981       }else if(aTmp.find("#COLUMN_TITLES:") == 0){
982         int aLen = aTmp.find(":") + 1;
983         aTmp.remove(0,aLen);
984         QStringList aStrList = QStringList::split("|",aTmp);
985         if(MYDEBUG) cout<<"Its Column Titles : ";
986         for(int i = 0; i < aStrList.count(); i++){
987           aTmp = aStrList[i].stripWhiteSpace();
988           aTable2D.myColumnTitles.push_back(aTmp.latin1());
989           if(MYDEBUG) cout<<"\t"<<aTmp;
990         }
991         if(MYDEBUG) cout<<endl;
992       }else if(aTmp.find("#COLUMN_UNITS:") == 0){
993         int aLen = aTmp.find(":") + 1;
994         aTmp.remove(0,aLen);
995         QStringList aStrList = QStringList::split(" ",aTmp);
996         if(MYDEBUG) cout<<"Its Column Units : ";
997         for(int i = 0; i < aStrList.count(); i++){
998           aTmp = aStrList[i].stripWhiteSpace();
999           aTable2D.myColumnUnits.push_back(aTmp.latin1());
1000           if(MYDEBUG) cout<<"\t"<<aTmp;
1001         }
1002         if(MYDEBUG) cout<<endl;
1003       }else if(aTmp.find("#") == 0){
1004         //It is a comment
1005       }else if(aTmp.find("#TITLE:") > 0){
1006         QStringList aStrList = QStringList::split("#TITLE:",aTmp);
1007         QString aTitle = aStrList[1].stripWhiteSpace();
1008         TRow aRow; 
1009         aRow.myTitle = aTitle.latin1();
1010         if(MYDEBUG) cout<<aTitle<<" : ";
1011         QStringList aValList = QStringList::split(" ",aStrList[0]);
1012         for(int i = 0; i < aValList.count(); i++){
1013           float aVal = aValList[i].toFloat();
1014           aRow.myValues.push_back(aVal);
1015           if(MYDEBUG) cout<<"\t"<<aVal;
1016         }
1017         aTable2D.myRows.push_back(aRow);
1018         if(MYDEBUG) cout<<endl;
1019       }else{
1020         TRow aRow;
1021         TValue aVal;
1022         istrstream aStream(aTmp);
1023         aStream.precision(STRPRECISION);
1024         while(aStream>>aVal){
1025           aRow.myValues.push_back(aVal);
1026           if(MYDEBUG) cout<<"\t"<<aVal;
1027         }
1028         if(aRow.myValues.size() > 0)
1029           aTable2D.myRows.push_back(aRow);
1030         if(MYDEBUG) cout<<endl;
1031       }
1032       getLine(aStmIn,aTmp);
1033     }
1034     if(aTable2D.Check()){
1035       if(MYDEBUG) cout<<"aTable2D checked "<<aTable2D.myTitle<<endl;
1036       theTableCont.push_back(aTable2D);
1037     }
1038   }while(!aStmIn.eof());
1039   aStmIn.close();
1040   if(MYDEBUG) cout<<"After close"<<endl;
1041 }
1042
1043 SALOMEDS::SObject_var VISU::ImportTables(const char* theFileName, SALOMEDS::Study_ptr theStudy){
1044   TTableCont aTableCont;
1045   ImportTables(theFileName,aTableCont);
1046   if(aTableCont.empty()) return SALOMEDS::SObject::_nil();
1047   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1048   SALOMEDS::SComponent_var theSComponent = VISU::FindOrCreateVisuComponent(theStudy);
1049   SALOMEDS::SObject_var aFileObject = aStudyBuilder->NewObject(theSComponent);
1050   SALOMEDS::GenericAttribute_var anAttr = 
1051     aStudyBuilder->FindOrCreateAttribute(aFileObject, "AttributeName");
1052   SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
1053   QFileInfo aFileInfo(theFileName);
1054   aName->SetValue(aFileInfo.fileName().latin1());
1055   int iEnd = aTableCont.size();
1056   for(int i = 0, iEnd = aTableCont.size(); i < iEnd; i++){
1057     const TTable2D& aTable2D = aTableCont[i];
1058     SALOMEDS::SObject_var aRealObject = aStudyBuilder->NewObject(aFileObject);
1059     anAttr = aStudyBuilder->FindOrCreateAttribute(aRealObject, "AttributeName");
1060     aName = SALOMEDS::AttributeName::_narrow(anAttr);
1061     if(MYDEBUG) cout<<"aTable2D.myTitle = "<<aTable2D.myTitle<<endl;
1062     if(aTable2D.myTitle != "")
1063       aName->SetValue(aTable2D.myTitle.c_str());
1064     else{
1065       QString aNewName;
1066       aNewName.sprintf("Table:%d",i);
1067       aName->SetValue(aNewName.latin1());
1068     }
1069     anAttr = aStudyBuilder->FindOrCreateAttribute(aRealObject, "AttributeTableOfReal");
1070     SALOMEDS::AttributeTableOfReal_var aTableOfReal = SALOMEDS::AttributeTableOfReal::_narrow(anAttr);
1071     aTableOfReal->SetTitle(aTable2D.myTitle.c_str());
1072     TTable2D aNewTable2D;
1073     aTable2D.getColumns(aNewTable2D);
1074     int kEnd = aNewTable2D.myRows[0].myValues.size();
1075     aTableOfReal->SetNbColumns(kEnd);
1076     for(int j = 0, jEnd = aNewTable2D.myRows.size(); j < jEnd; j++){
1077       if(MYDEBUG) cout<<"j = "<<j<<endl;
1078       SALOMEDS::DoubleSeq_var aDoubleSeq = new SALOMEDS::DoubleSeq();
1079       aDoubleSeq->length(kEnd);
1080       if(MYDEBUG) cout<<"kEnd = "<<kEnd<<endl;
1081       for(int k = 0; k < kEnd; k++) aDoubleSeq[k] = aNewTable2D.myRows[j].myValues[k];
1082       aTableOfReal->AddRow(aDoubleSeq.in());
1083       aTableOfReal->SetRowTitle(j+1,aNewTable2D.myRows[j].myTitle.c_str());
1084       aTableOfReal->SetRowUnit(j+1,aNewTable2D.myRows[j].myUnit.c_str());
1085     }
1086     for(int k = 0; k < kEnd; k++)
1087       aTableOfReal->SetColumnTitle(k+1,aNewTable2D.myColumnTitles[k].c_str());
1088   }
1089   return aFileObject;
1090 }