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