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