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