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