Salome HOME
Unicode support: correct handling of unicode on GUI level
[modules/gui.git] / src / SalomeApp / SalomeApp_DataObject.cxx
1 // Copyright (C) 2007-2016  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, or (at your option) any later version.
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 // File   : SalomeApp_DataObject.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
24
25 #include "SalomeApp_DataObject.h"
26 #include "SalomeApp_Study.h"
27 #include "SalomeApp_Application.h"
28
29 #include <CAM_DataObject.h>
30
31 #include <SUIT_Session.h>
32 #include <SUIT_Application.h>
33 #include <SUIT_ResourceMgr.h>
34
35 #include <SALOME_LifeCycleCORBA.hxx>
36 #include <Basics_Utils.hxx>
37
38 #include <QObject>
39 #include <QVariant>
40
41 //VSR: uncomment below macro to support unicode text properly in SALOME
42 //     current commented out due to regressions
43 //#define PAL22528_UNICODE
44
45 namespace
46 {
47   QString fromUtf8( const char* txt )
48   {
49 #ifdef PAL22528_UNICODE
50     return QString::fromUtf8( txt );
51 #else
52     return QString( txt );
53 #endif
54   }
55
56   QString fromUtf8( const std::string& txt )
57   {
58     return fromUtf8( txt.c_str() );
59   }
60 }
61
62 /*!
63   \class SalomeApp_DataObject
64   \brief Implementation of the data object for use in CORBA-based
65   SALOME modules.
66 */
67
68 /*!
69   \brief Constructor. 
70   \param parent parent data object
71 */
72 SalomeApp_DataObject::SalomeApp_DataObject( SUIT_DataObject* parent )
73 : CAM_DataObject( parent ),
74   LightApp_DataObject( parent )
75 {
76 }
77
78 /*!
79   \brief Constructor. 
80   \param sobj SALOMEDS object
81   \param parent parent data object
82 */
83 SalomeApp_DataObject::SalomeApp_DataObject( const _PTR(SObject)& sobj, 
84                                             SUIT_DataObject* parent )
85 : CAM_DataObject( parent ),
86   LightApp_DataObject( parent )
87 {
88   myObject = sobj;
89 }
90
91 /*!
92   \brief Destructor.
93 */
94 SalomeApp_DataObject::~SalomeApp_DataObject()
95 {
96 }
97
98 /*!
99   \brief Get data object name.
100   \return object name
101 */
102 QString SalomeApp_DataObject::name() const
103 {
104   QString str;
105   if ( myObject )
106     str = fromUtf8( myObject->GetName() );
107   
108   if ( str.isEmpty() ) {
109     _PTR(SObject) refObj = referencedObject();
110     if ( refObj )
111       str = fromUtf8( refObj->GetName() );
112   }
113   
114   if ( isReference() ) {
115     if ( !(QString(referencedObject()->GetName().c_str()).isEmpty()) )
116       str = QString( "* " ) + str;
117     else
118       str = QString( "<Invalid Reference>" );
119   }
120   return str;
121 }
122
123 /*!
124   \brief Get object string identifier.
125   \return object ID
126 */
127 QString SalomeApp_DataObject::entry() const
128 {
129   return entry( myObject );
130 }
131
132 /*!
133   \brief Get object text data for the specified column.
134
135   This method returns the data according to the specufied column \a id:
136   - NameId     : object name (by calling name() method)
137   - EntryId    : object entry (by calling entry() method)
138   - ValueId    : object value
139   - IORId      : object IOR
140   - RefEntryId : object reference entry
141
142   \param id column id
143   \return object text data
144 */
145 QString SalomeApp_DataObject::text( const int id ) const
146 {
147   QString txt;
148
149   // Text for "Value" and "IOR" columns
150   switch ( id )
151   {
152   case ValueId:
153 #ifndef WIN32
154     if ( componentObject() != this )
155 #else
156     if ( componentObject() != (SUIT_DataObject*)this )
157 #endif
158       txt = value( object() );
159       if ( txt.isEmpty() )
160         txt = value( referencedObject() );
161     break;
162   case IORId:
163     txt = ior( referencedObject() );
164     break;
165   default:
166     // Issue 21379: LightApp_DataObject::text() treats "Entry"
167     // and "Reference Entry" columns
168     txt = LightApp_DataObject::text( id );
169     break;
170   }
171   return txt;
172 }
173
174 /*!
175   \brief Get data object icon for the specified column.
176   \param id column id
177   \return object icon for the specified column
178 */
179 QPixmap SalomeApp_DataObject::icon( const int id ) const
180 {
181   // we display icon only for the first (NameId ) column
182   if ( id == NameId ) {
183     _PTR(GenericAttribute) anAttr;
184     if ( myObject && myObject->FindAttribute( anAttr, "AttributePixMap" ) ){
185       _PTR(AttributePixMap) aPixAttr ( anAttr );
186       if ( aPixAttr->HasPixMap() ) {
187         QString componentType = componentDataType();
188         QString pixmapID      = fromUtf8( aPixAttr->GetPixMap() );
189         // select a plugin within a component
190         QStringList plugin_pixmap = pixmapID.split( "::", QString::KeepEmptyParts );
191         if ( plugin_pixmap.size() == 2 ) {
192           componentType = plugin_pixmap.front();
193           pixmapID      = plugin_pixmap.back();
194         }
195         QString pixmapName = QObject::tr( pixmapID.toLatin1().constData() );
196         LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root() );
197         if ( aRoot && aRoot->study() ) {
198           SUIT_ResourceMgr* mgr = aRoot->study()->application()->resourceMgr();
199           return mgr->loadPixmap( componentType, pixmapName, false ); 
200         }
201       }
202     }
203   }
204   return LightApp_DataObject::icon( id );
205 }
206
207 /*!
208   \brief Get data object color for the specified column.
209   \param role color role
210   \param id column id (not used)
211   \return object color for the specified column
212 */
213 QColor SalomeApp_DataObject::color( const ColorRole role, const int id ) const
214 {
215   // we ignore parameter <id> in order to use the same colors for 
216   // all columns
217   QColor c;
218   switch ( role )
219   {
220   case Text:
221   case Foreground:
222     // text color (not selected item)
223     if ( isReference() ) {
224       if ( QString(referencedObject()->GetName().c_str()).isEmpty() )
225         c = QColor( 200, 200, 200 );  // invalid reference (grayed)
226     }
227     else if ( myObject ) {
228       // get color atrtribute value
229       _PTR(GenericAttribute) anAttr;
230       if ( myObject->FindAttribute( anAttr, "AttributeTextColor" ) ) {
231         _PTR(AttributeTextColor) aColAttr = anAttr;
232         c = QColor( (int)aColAttr->TextColor().R, (int)aColAttr->TextColor().G, (int)aColAttr->TextColor().B );
233       }
234     }
235     break;
236
237   case Highlight:
238     // background color for the highlighted item
239     if ( isReference() ) {
240       if ( QString(referencedObject()->GetName().c_str()).isEmpty() )
241         c = QColor( 200, 200, 200 );  // invalid reference (grayed)
242     }
243     else if ( myObject ) {
244       // get color atrtribute value
245       _PTR(GenericAttribute) anAttr;
246       if( myObject->FindAttribute ( anAttr, "AttributeTextHighlightColor") ) {
247         _PTR(AttributeTextHighlightColor) aHighColAttr = anAttr;
248         c = QColor( (int)(aHighColAttr->TextHighlightColor().R), 
249                     (int)(aHighColAttr->TextHighlightColor().G), 
250                     (int)(aHighColAttr->TextHighlightColor().B));
251       }
252     }
253     break;
254   default:
255     break;
256   }
257
258   // Issue 21379: LightApp_DataObject::color() defines colors for valid references
259   if ( !c.isValid() )
260     c = LightApp_DataObject::color( role, id );
261
262   return c;
263 }
264
265 /*!
266   \brief Get data object tooltip for the specified column.
267   \param id column id (not used)
268   \return object tooltip for the specified column
269 */
270 QString SalomeApp_DataObject::toolTip( const int /*id*/ ) const
271 {
272   // we ignore parameter <id> in order to use the same tooltip for 
273   // all columns
274   
275   // Get customized tooltip in case of it exists
276   const SalomeApp_DataObject* compObj = dynamic_cast<SalomeApp_DataObject*>( componentObject() );
277   // Check if the component has been loaded.
278   // In order to avoid loading the component only for getting a custom tooltip.
279   if ( compObj && compObj != this && !ior(compObj->object()).isEmpty() ) {
280     SalomeApp_Application* app = 
281       dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
282     if ( app ) {
283       // --- try to find (and not load) the component instance, like GEOM instance,
284       //     registered in naming service under Containers/<hostname>/...
285       //     with any container name, on every machine available
286       Engines::ContainerParameters params;
287       app->lcc()->preSet(params); // --- any container name, anywhere
288       Engines::EngineComponent_var aComponent =
289         app->lcc()->FindComponent(params, componentDataType().toLatin1().constData() );
290       
291       if ( !CORBA::is_nil(aComponent) && aComponent->hasObjectInfo() ) {
292         LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root() );
293         if ( aRoot && aRoot->study() ) {
294           CORBA::String_var data = aComponent->getObjectInfo( entry().toUtf8().constData());
295           QString objInfo = data.in();
296           QStringList l;
297           l << name();
298           if ( !objInfo.isEmpty() )
299             l << objInfo;
300           return l.join("\n");
301         }
302       }
303     }
304   }
305   
306   return QString( "Object \'%1\', module \'%2\', ID=%3" ).arg( name() ).arg( componentDataType() ).arg( entry() );
307 }
308
309 /*!
310   \brief Get font to be used for data object rendering in the item views
311   \param id column id
312   \return font to be used for the item rendering
313 */
314 QFont SalomeApp_DataObject::font( const int id ) const
315 {
316   QFont f = LightApp_DataObject::font( id );
317   if ( id == NameId ) {
318     if ( !expandable() && hasChildren() ) {
319       // set bold font to highlight the item which is non-expandable but has children
320       f.setBold( true );
321     }
322   }
323   return f;
324 }
325
326 /*!
327   \brief Get component type.
328   \return component type
329 */
330 QString SalomeApp_DataObject::componentDataType() const
331 {
332   //  if ( myCompDataType.isEmpty() ) {
333     const SalomeApp_DataObject* compObj = dynamic_cast<SalomeApp_DataObject*>( componentObject() );
334     if ( compObj && compObj->object() )
335     {
336       _PTR(SComponent) aComp( compObj->object() );
337       if ( aComp ) {
338         SalomeApp_DataObject* that = (SalomeApp_DataObject*)this;
339         that->myCompDataType = aComp->ComponentDataType().c_str();
340       }
341     }
342     //  }
343   return myCompDataType;
344 }
345
346 /*!
347   \brief Get SALOMEDS object.
348   \return SALOMEDS object
349 */
350 _PTR(SObject) SalomeApp_DataObject::object() const
351 {
352   return myObject;
353 }
354
355 /*!
356   \brief Returns the string identifier of the data objects referenced by this one.
357
358   Re-implemented from LightApp_DataObject using SALOMEDS API.
359
360   \return ID string of the referenced SObject
361 */
362 QString SalomeApp_DataObject::refEntry() const
363 {
364   return entry( referencedObject() );
365 }
366
367 /*!
368   \brief Check if the data object is a reference.
369
370   Re-implemented from LightApp_DataObject using SALOMEDS API.
371
372   \return \c true if this data object actually refers to another one
373 */
374 bool SalomeApp_DataObject::isReference() const
375 {
376   bool isRef = false;
377   if ( myObject )
378   {
379     _PTR(SObject) refObj;
380     isRef = myObject->ReferencedObject( refObj );
381   }
382   return isRef;
383 }
384
385 /*!
386   \brief Get the object referenced by this one.
387   \return referenced object
388 */
389 _PTR(SObject) SalomeApp_DataObject::referencedObject() const
390 {
391   _PTR(SObject) refObj;
392   _PTR(SObject) obj = myObject;
393   while ( obj && obj->ReferencedObject( refObj ) )
394     obj = refObj;
395
396   return obj;
397 }
398
399 /*!
400   \brief Check if object has children
401   \return \c true if object has at least one child sub-object and \c false otherwise
402 */
403 bool SalomeApp_DataObject::hasChildren() const
404 {
405   bool ok = false;
406
407   // tmp??
408   _PTR(UseCaseBuilder) aUseCaseBuilder = SalomeApp_Application::getStudy()->GetUseCaseBuilder();
409   if (aUseCaseBuilder->IsUseCaseNode(myObject)) {
410     ok = aUseCaseBuilder->HasChildren(myObject);
411     // TODO: check name as below?
412   }
413   else {
414     _PTR(ChildIterator) it ( SalomeApp_Application::getStudy()->NewChildIterator( myObject ) );
415     for ( ; it->More() && !ok; it->Next() ) {
416       _PTR(SObject) obj = it->Value();
417       if ( obj ) {
418         _PTR(SObject) refObj;
419         //if ( obj->ReferencedObject( refObj ) ) continue; // omit references
420         if ( obj->GetName() != "" ) ok = true;
421       }
422     }
423   }
424   return ok;
425 }
426
427 /*!
428   \brief Check if the object is expandable (e.g. in the data tree view)
429   \return \c true if object is expandable and \c false otherwise
430 */
431 bool SalomeApp_DataObject::expandable() const
432 {
433   bool exp = true;
434   _PTR(GenericAttribute) anAttr;
435   if ( myObject && myObject->FindAttribute( anAttr, "AttributeExpandable" ) ) {
436     _PTR(AttributeExpandable) aAttrExp = anAttr;
437     exp = aAttrExp->IsExpandable();
438   }
439   return exp;
440 }
441
442 /*!
443   \brief Check if the object is visible.
444   \return \c true if this object is displayable or \c false otherwise
445 */
446 bool SalomeApp_DataObject::isVisible() const
447 {
448   bool isDraw = true;
449   _PTR(GenericAttribute) anAttr;
450   if ( myObject && myObject->FindAttribute(anAttr, "AttributeDrawable") ) 
451   {
452     _PTR(AttributeDrawable) aAttrDraw = anAttr;
453     isDraw = aAttrDraw->IsDrawable(); 
454   }
455   return isDraw && LightApp_DataObject::isVisible() && ( !name().isEmpty() || isReference() );
456 }
457
458 /*!
459   \brief Check if the specified column supports custom sorting.
460   \param id column id
461   \return \c true if column sorting should be customized
462   \sa compare()
463 */
464 bool SalomeApp_DataObject::customSorting( const int id ) const
465 {
466   // perform custom sorting for the "Entry" and "Reference Entry" columns
467   return id == EntryId  || id == RefEntryId  ? true 
468     : LightApp_DataObject::customSorting( id );
469 }
470
471 /*!
472   \brief Compares data from two items for sorting purposes.
473
474   This method is called only for those columns for which customSorting()
475   method returns \c true.
476
477   \param left first data to compare
478   \param right second data to compare
479   \param id column id
480   \return result of the comparison
481   \sa customSorting()
482 */
483 bool SalomeApp_DataObject::compare( const QVariant& left, const QVariant& right, const int id ) const
484 {
485   // use the same custom sorting for the "Reference Entry" column as for the
486   // "Entry" column (call base implementation)
487   return LightApp_DataObject::compare( left, right, id == RefEntryId ? EntryId : id );
488 }
489
490 /*!
491   \brief Get data object IOR.
492   \param obj data object
493   \return data object IOR or null string if IOR is empty
494 */
495 QString SalomeApp_DataObject::ior( const _PTR(SObject)& obj ) const
496 {
497   QString txt;
498   if ( obj )
499   {
500     _PTR(GenericAttribute) attr;
501     if ( obj->FindAttribute( attr, "AttributeIOR" ) )
502     {
503       _PTR(AttributeIOR) iorAttr = attr;
504       if ( iorAttr )
505       {
506         std::string str = iorAttr->Value();
507         txt = QString( str.c_str() );
508       }
509     }
510   }
511   return txt;
512 }
513
514 /*!
515   \brief Get data object entry identifier.
516   \param obj data object
517   \return data object entry identifier or empty object does not have entry
518 */
519 QString SalomeApp_DataObject::entry( const _PTR(SObject)& obj ) const
520 {
521   QString txt;
522   if ( obj )
523   {
524     std::string str = obj->GetID();
525     txt = QString( str.c_str() );
526   }
527   return txt;
528 }
529
530 /*!
531   \brief Get data object value.
532   \param obj data object
533   \return data object value or empty string if there is no 
534   value associated to the object
535 */
536 QString SalomeApp_DataObject::value( const _PTR(SObject)& obj ) const
537 {
538   if ( !obj )
539     return QString();
540
541   QString val;
542   _PTR(GenericAttribute) attr;
543
544   if ( obj->FindAttribute( attr, "AttributeString" ) )
545   {
546     _PTR(AttributeString) strAttr = attr;
547     std::string str = strAttr->Value();
548     QString aStrings = fromUtf8( str );
549     
550     //Special case to show NoteBook variables in the "Value" column of the OB 
551     bool ok = false;
552     QStringList aSectionList = aStrings.split( "|" );
553     if ( !aSectionList.isEmpty() )
554     {
555       QString aLastSection = aSectionList.last();
556       QStringList aStringList = aLastSection.split( ":" );
557       if ( !aStringList.isEmpty() )
558       {
559         ok = true;
560         for ( int i = 0, n = aStringList.size(); i < n; i++ )
561         {
562           QString aStr = aStringList[i];
563           if ( SalomeApp_Application::getStudy()->IsVariable( aStr.toStdString() ) )
564             val.append( aStr + ", " );
565         }
566
567         if ( !val.isEmpty() )
568           val.remove( val.length() - 2, 2 );
569       }
570     }
571     if( !ok )
572       val = aStrings;
573   }
574   else if ( obj->FindAttribute( attr, "AttributeInteger" ) )
575   {
576     _PTR(AttributeInteger) intAttr = attr;
577     if ( intAttr )
578       val = QString::number( intAttr->Value() );
579   }
580   else if ( obj->FindAttribute( attr, "AttributeReal" ) )
581   {
582     _PTR(AttributeReal) realAttr = attr;
583     if ( realAttr )
584       val = QString::number( realAttr->Value() );
585   }
586   else if ( obj->FindAttribute( attr, "AttributeTableOfInteger" ) )
587   {
588     _PTR(AttributeTableOfInteger) tableAttr = attr;
589     std::string title = tableAttr->GetTitle();
590     val = QString( title.c_str() );
591     if ( !val.isEmpty() )
592       val += QString( " " );
593     val += QString( "[%1,%2]" ).arg( tableAttr->GetNbRows() ).arg( tableAttr->GetNbColumns() );
594   }
595   else if ( obj->FindAttribute( attr, "AttributeTableOfReal" ) )
596   {
597     _PTR(AttributeTableOfReal) tableAttr = attr;
598     std::string title = tableAttr->GetTitle();
599     val = QString( title.c_str() );
600     if ( !val.isEmpty() )
601       val += QString( " " );
602     val += QString( "[%1,%2]" ).arg( tableAttr->GetNbRows() ).arg( tableAttr->GetNbColumns() );
603   }
604   else if ( obj->FindAttribute( attr, "AttributeComment" ) )
605   {
606     _PTR(AttributeComment) comm = attr;
607     std::string str = comm->Value();
608     val = fromUtf8( str );
609   }
610
611   return val;
612 }
613
614 void SalomeApp_DataObject::insertChildAtTag( SalomeApp_DataObject* obj, int tag )
615 {
616   int pos = 0;
617   int npos = qMin( tag-1,childCount() );
618   for ( int i = npos; i > 0; i-- )
619   {
620     if ( (dynamic_cast<SalomeApp_DataObject*>( childObject( i-1 ) ) )->object()->Tag() < tag )
621     {
622       pos = i;
623       break;
624     }
625   }
626   insertChildAtPos( obj, pos );
627 }
628
629 void SalomeApp_DataObject::updateItem()
630 {
631   if ( modified() ) return;
632   setModified( true );
633 }
634
635 /*!
636   \class SalomeApp_ModuleObject
637   \brief This class is used for optimized access to the SALOMEDS-based 
638   data model from SalomeApp_DataObject class instances.
639   \sa CAM_ModuleObject class
640 */
641
642 /*!
643   \brief Constructor.
644   \param parent parent data object
645 */
646 SalomeApp_ModuleObject::SalomeApp_ModuleObject( SUIT_DataObject* parent )
647 : CAM_DataObject( parent ),
648   LightApp_DataObject( parent ),
649   SalomeApp_DataObject( parent ),
650   CAM_ModuleObject( parent )
651 {
652 }
653
654 /*!
655   \brief Constructor.
656   \param sobj SALOMEDS object
657   \param parent parent data object
658 */
659 SalomeApp_ModuleObject::SalomeApp_ModuleObject( const _PTR(SObject)& sobj, 
660                                                 SUIT_DataObject* parent )
661 : CAM_DataObject( parent ),
662   LightApp_DataObject( parent ),
663   SalomeApp_DataObject( sobj, parent ),
664   CAM_ModuleObject( parent )
665 {
666 }
667
668 /*!
669   \brief Constructor.
670   \param dm data model
671   \param sobj SALOMEDS object
672   \param parent parent data object
673 */
674 SalomeApp_ModuleObject::SalomeApp_ModuleObject( CAM_DataModel* dm, 
675                                                 const _PTR(SObject)& sobj, 
676                                                 SUIT_DataObject* parent )
677 : CAM_DataObject( parent ),
678   LightApp_DataObject( parent ),
679   SalomeApp_DataObject( sobj, parent ),
680   CAM_ModuleObject( dm, parent )
681 {
682 }
683
684 /*!
685   \brief Destructor.
686 */
687 SalomeApp_ModuleObject::~SalomeApp_ModuleObject()
688 {
689 }
690
691 /*!
692   \brief Get module name.
693   \return module name
694 */
695 QString SalomeApp_ModuleObject::name() const
696 {
697   return SalomeApp_DataObject::name();
698 }
699
700 /*!
701   \brief Get data object icon for the specified column.
702   \param id column id
703   \return object icon for the specified column
704   \sa CAM_ModuleObject class
705 */
706 QPixmap SalomeApp_ModuleObject::icon( const int id ) const
707 {
708   QPixmap p = SalomeApp_DataObject::icon( id );
709   // The module might not provide a separate small icon
710   // for Obj. Browser representation -> always try to scale it
711   // See CAM_ModuleObject::icon()
712   if ( !p.isNull() )
713     p = Qtx::scaleIcon( p, 16 );
714   return p;
715 }
716
717 /*!
718   \brief Get data object tooltip for the specified column.
719   \param id column id
720   \return object tooltip for the specified column
721 */
722 QString SalomeApp_ModuleObject::toolTip( const int id ) const
723 {
724   return SalomeApp_DataObject::toolTip( id );
725 }
726
727 /*!
728   \class SalomeApp_RootObject
729   \brief Root data object for the CORBA-based SALOME application.
730
731   This class is to be instanciated by only one object - the root object
732   of the SalomeApp data object tree. This object is not shown in the object browser.
733   The goal of this class is to provide a unified access to SalomeApp_Study
734   object from SalomeApp_DataObject instances.
735 */
736
737 /*!
738   \brief Constructor.
739   \param study pointer to the study
740 */
741 SalomeApp_RootObject::SalomeApp_RootObject( LightApp_Study* study )
742 : CAM_DataObject( 0 ),
743   LightApp_DataObject( 0 ),
744   SalomeApp_DataObject( 0 ),
745   LightApp_RootObject( study ),
746   _toSynchronize(true)
747 {
748 }
749
750 /*!
751   \brief Destructor.
752 */
753 SalomeApp_RootObject::~SalomeApp_RootObject()
754 {
755 }
756
757 /*!
758   \brief Get data object name.
759   \return object name
760 */
761 QString SalomeApp_RootObject::name() const
762 {
763   return LightApp_RootObject::name();
764 }
765  
766 /*!
767   \brief Get object string identifier.
768   \return object ID
769 */
770 QString SalomeApp_RootObject::entry() const
771 {
772   return LightApp_RootObject::entry();
773 }
774
775 /*!
776   \brief Get object text data for the specified column.
777   \param id column id
778   \return object text data
779 */
780 QString SalomeApp_RootObject::text( const int id ) const
781 {
782   return LightApp_RootObject::text( id );
783 }
784
785 /*!
786   \brief Get data object icon for the specified column.
787   \param id column id
788   \return object icon for the specified column
789 */
790 QPixmap SalomeApp_RootObject::icon( const int id ) const
791 {
792   return LightApp_RootObject::icon( id );
793 }
794
795 /*!
796   \brief Get data object color for the specified column.
797   \param role color role
798   \param id column id (not used)
799   \return object color for the specified column
800 */
801 QColor SalomeApp_RootObject::color( const ColorRole role, const int id ) const
802 {
803   return LightApp_RootObject::color( role, id );
804 }
805
806 /*!
807   \brief Get data object tooltip for the specified column.
808   \param id column id (not used)
809   \return object tooltip for the specified column
810 */
811 QString SalomeApp_RootObject::toolTip( const int id ) const
812 {
813   return LightApp_RootObject::toolTip( id );
814 }
815
816 /*!
817   \class SalomeApp_SavePointObject
818   \brief Represents persistent visual_state object.
819
820   Save point objects are stored in the data model, but NOT in SObjects
821   structure, so they are handled separately using this special class
822 */
823
824 /*!
825   \brief Constructor.
826   \param parent parent data object
827   \param id save point ID
828   \param study study
829 */
830 SalomeApp_SavePointObject::SalomeApp_SavePointObject( SUIT_DataObject* parent, 
831                                                       const int id, 
832                                                       SalomeApp_Study* study )
833 : LightApp_DataObject( parent ), 
834   CAM_DataObject( parent ),
835   myId( id ),
836   myStudy( study )
837 {
838 }
839
840 /*!
841   \brief Destructor.
842 */
843 SalomeApp_SavePointObject::~SalomeApp_SavePointObject()
844 {
845 }
846
847 /*!
848   \brief Get save point unique identifier.
849   \return save point ID
850 */
851 int SalomeApp_SavePointObject::getId() const
852 {
853   return myId;
854 }
855
856 /*!
857   \brief Get object string identifier.
858   \return object ID
859 */
860 QString SalomeApp_SavePointObject::entry() const
861 {
862   return QObject::tr( "SAVE_POINT_DEF_NAME" ) + QString::number( myId );
863 }
864
865 /*!
866   \brief Get data object name.
867   \return object name
868 */
869 QString SalomeApp_SavePointObject::name() const
870 {
871   return myStudy->getNameOfSavePoint( myId );
872 }
873
874 /*!
875   \brief Get data object icon for the specified column.
876   \param id column id
877   \return object icon for the specified column
878 */
879 QPixmap SalomeApp_SavePointObject::icon( const int /*id*/ ) const
880 {
881   return QPixmap();
882 }
883
884 /*!
885   \brief Get data object tooltip for the specified column.
886   \param id column id (not used)
887   \return object tooltip for the specified column
888 */
889 QString SalomeApp_SavePointObject::toolTip( const int /*id*/ ) const
890 {
891   return QObject::tr( "SAVE_POINT_OBJECT_TOOLTIP" ).arg( name() );
892 }
893
894 /*!
895   \class SalomeApp_SavePointRootObject
896   \brief Represents parent object for visual_state objects.
897 */
898
899 /*!
900   \brief Constructor.
901   \param parent parent object
902 */
903 SalomeApp_SavePointRootObject::SalomeApp_SavePointRootObject( SUIT_DataObject* parent )
904 : SUIT_DataObject( parent )
905 {
906 }
907
908 /*!
909   \brief Get data object name.
910   \return object name
911 */
912 QString SalomeApp_SavePointRootObject::name() const
913 {
914   return QObject::tr( "SAVE_POINT_ROOT_NAME" ); 
915 }
916
917 /*!
918   \brief Get data object tooltip for the specified column.
919   \param id column id (not used)
920   \return object tooltip for the specified column
921 */
922 QString SalomeApp_SavePointRootObject::toolTip( const int /*id*/ ) const
923 {
924   return QObject::tr( "SAVE_POINT_ROOT_TOOLTIP" ); 
925 }