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