1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SalomeApp_DataObject.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "SalomeApp_DataObject.h"
26 #include "SalomeApp_Study.h"
27 #include "SalomeApp_Application.h"
29 #include <CAM_DataObject.h>
31 #include <SUIT_Session.h>
32 #include <SUIT_Application.h>
33 #include <SUIT_ResourceMgr.h>
35 #include <SALOME_LifeCycleCORBA.hxx>
36 #include <Basics_Utils.hxx>
41 //VSR: uncomment below macro to support unicode text properly in SALOME
42 // current commented out due to regressions
43 //#define PAL22528_UNICODE
47 QString fromUtf8( const char* txt )
49 #ifdef PAL22528_UNICODE
50 return QString::fromUtf8( txt );
52 return QString( txt );
56 QString fromUtf8( const std::string& txt )
58 return fromUtf8( txt.c_str() );
63 \class SalomeApp_DataObject
64 \brief Implementation of the data object for use in CORBA-based
70 \param parent parent data object
72 SalomeApp_DataObject::SalomeApp_DataObject( SUIT_DataObject* parent )
73 : CAM_DataObject( parent ),
74 LightApp_DataObject( parent )
80 \param sobj SALOMEDS object
81 \param parent parent data object
83 SalomeApp_DataObject::SalomeApp_DataObject( const _PTR(SObject)& sobj,
84 SUIT_DataObject* parent )
85 : CAM_DataObject( parent ),
86 LightApp_DataObject( parent )
94 SalomeApp_DataObject::~SalomeApp_DataObject()
99 \brief Get data object name.
102 QString SalomeApp_DataObject::name() const
106 str = fromUtf8( myObject->GetName() );
108 if ( str.isEmpty() ) {
109 _PTR(SObject) refObj = referencedObject();
111 str = fromUtf8( refObj->GetName() );
114 if ( isReference() ) {
115 if ( !(QString(referencedObject()->GetName().c_str()).isEmpty()) )
116 str = QString( "* " ) + str;
118 str = QString( "<Invalid Reference>" );
124 \brief Get object string identifier.
127 QString SalomeApp_DataObject::entry() const
129 return entry( myObject );
133 \brief Get object text data for the specified column.
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
140 - RefEntryId : object reference entry
143 \return object text data
145 QString SalomeApp_DataObject::text( const int id ) const
149 // Text for "Value" and "IOR" columns
154 if ( componentObject() != this )
156 if ( componentObject() != (SUIT_DataObject*)this )
158 txt = value( object() );
160 txt = value( referencedObject() );
163 txt = ior( referencedObject() );
166 // Issue 21379: LightApp_DataObject::text() treats "Entry"
167 // and "Reference Entry" columns
168 txt = LightApp_DataObject::text( id );
175 \brief Get data object icon for the specified column.
177 \return object icon for the specified column
179 QPixmap SalomeApp_DataObject::icon( const int id ) const
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();
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 );
204 return LightApp_DataObject::icon( id );
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
213 QColor SalomeApp_DataObject::color( const ColorRole role, const int id ) const
215 // we ignore parameter <id> in order to use the same colors for
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)
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 );
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)
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));
258 // Issue 21379: LightApp_DataObject::color() defines colors for valid references
260 c = LightApp_DataObject::color( role, id );
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
270 QString SalomeApp_DataObject::toolTip( const int /*id*/ ) const
272 // we ignore parameter <id> in order to use the same tooltip for
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() );
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() );
291 if ( !CORBA::is_nil(aComponent) && aComponent->hasObjectInfo() ) {
292 LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root() );
293 if ( aRoot && aRoot->study() )
294 return QString( (CORBA::String_var)aComponent->getObjectInfo( aRoot->study()->id(), entry().toLatin1().constData()) );
299 return QString( "Object \'%1\', module \'%2\', ID=%3" ).arg( name() ).arg( componentDataType() ).arg( entry() );
303 \brief Get font to be used for data object rendering in the item views
305 \return font to be used for the item rendering
307 QFont SalomeApp_DataObject::font( const int id ) const
309 QFont f = LightApp_DataObject::font( id );
310 if ( id == NameId ) {
311 if ( !expandable() && hasChildren() ) {
312 // set bold font to highlight the item which is non-expandable but has children
320 \brief Get component type.
321 \return component type
323 QString SalomeApp_DataObject::componentDataType() const
325 // if ( myCompDataType.isEmpty() ) {
326 const SalomeApp_DataObject* compObj = dynamic_cast<SalomeApp_DataObject*>( componentObject() );
327 if ( compObj && compObj->object() )
329 _PTR(SComponent) aComp( compObj->object() );
331 SalomeApp_DataObject* that = (SalomeApp_DataObject*)this;
332 that->myCompDataType = aComp->ComponentDataType().c_str();
336 return myCompDataType;
340 \brief Get SALOMEDS object.
341 \return SALOMEDS object
343 _PTR(SObject) SalomeApp_DataObject::object() const
349 \brief Returns the string identifier of the data objects referenced by this one.
351 Re-implemented from LightApp_DataObject using SALOMEDS API.
353 \return ID string of the referenced SObject
355 QString SalomeApp_DataObject::refEntry() const
357 return entry( referencedObject() );
361 \brief Check if the data object is a reference.
363 Re-implemented from LightApp_DataObject using SALOMEDS API.
365 \return \c true if this data object actually refers to another one
367 bool SalomeApp_DataObject::isReference() const
372 _PTR(SObject) refObj;
373 isRef = myObject->ReferencedObject( refObj );
379 \brief Get the object referenced by this one.
380 \return referenced object
382 _PTR(SObject) SalomeApp_DataObject::referencedObject() const
384 _PTR(SObject) refObj;
385 _PTR(SObject) obj = myObject;
386 while ( obj && obj->ReferencedObject( refObj ) )
393 \brief Check if object has children
394 \return \c true if object has at least one child sub-object and \c false otherwise
396 bool SalomeApp_DataObject::hasChildren() const
401 _PTR(UseCaseBuilder) aUseCaseBuilder = myObject->GetStudy()->GetUseCaseBuilder();
402 if (aUseCaseBuilder->IsUseCaseNode(myObject)) {
403 ok = aUseCaseBuilder->HasChildren(myObject);
404 // TODO: check name as below?
407 _PTR(ChildIterator) it ( myObject->GetStudy()->NewChildIterator( myObject ) );
408 for ( ; it->More() && !ok; it->Next() ) {
409 _PTR(SObject) obj = it->Value();
411 _PTR(SObject) refObj;
412 //if ( obj->ReferencedObject( refObj ) ) continue; // omit references
413 if ( obj->GetName() != "" ) ok = true;
421 \brief Check if the object is expandable (e.g. in the data tree view)
422 \return \c true if object is expandable and \c false otherwise
424 bool SalomeApp_DataObject::expandable() const
427 _PTR(GenericAttribute) anAttr;
428 if ( myObject && myObject->FindAttribute( anAttr, "AttributeExpandable" ) ) {
429 _PTR(AttributeExpandable) aAttrExp = anAttr;
430 exp = aAttrExp->IsExpandable();
436 \brief Check if the object is visible.
437 \return \c true if this object is displayable or \c false otherwise
439 bool SalomeApp_DataObject::isVisible() const
442 _PTR(GenericAttribute) anAttr;
443 if ( myObject && myObject->FindAttribute(anAttr, "AttributeDrawable") )
445 _PTR(AttributeDrawable) aAttrDraw = anAttr;
446 isDraw = aAttrDraw->IsDrawable();
448 return isDraw && LightApp_DataObject::isVisible() && ( !name().isEmpty() || isReference() );
452 \brief Check if the specified column supports custom sorting.
454 \return \c true if column sorting should be customized
457 bool SalomeApp_DataObject::customSorting( const int id ) const
459 // perform custom sorting for the "Entry" and "Reference Entry" columns
460 return id == EntryId || id == RefEntryId ? true
461 : LightApp_DataObject::customSorting( id );
465 \brief Compares data from two items for sorting purposes.
467 This method is called only for those columns for which customSorting()
468 method returns \c true.
470 \param left first data to compare
471 \param right second data to compare
473 \return result of the comparison
476 bool SalomeApp_DataObject::compare( const QVariant& left, const QVariant& right, const int id ) const
478 // use the same custom sorting for the "Reference Entry" column as for the
479 // "Entry" column (call base implementation)
480 return LightApp_DataObject::compare( left, right, id == RefEntryId ? EntryId : id );
484 \brief Get data object IOR.
485 \param obj data object
486 \return data object IOR or null string if IOR is empty
488 QString SalomeApp_DataObject::ior( const _PTR(SObject)& obj ) const
493 _PTR(GenericAttribute) attr;
494 if ( obj->FindAttribute( attr, "AttributeIOR" ) )
496 _PTR(AttributeIOR) iorAttr = attr;
499 std::string str = iorAttr->Value();
500 txt = QString( str.c_str() );
508 \brief Get data object entry identifier.
509 \param obj data object
510 \return data object entry identifier or empty object does not have entry
512 QString SalomeApp_DataObject::entry( const _PTR(SObject)& obj ) const
517 std::string str = obj->GetID();
518 txt = QString( str.c_str() );
524 \brief Get data object value.
525 \param obj data object
526 \return data object value or empty string if there is no
527 value associated to the object
529 QString SalomeApp_DataObject::value( const _PTR(SObject)& obj ) const
535 _PTR(GenericAttribute) attr;
537 if ( obj->FindAttribute( attr, "AttributeString" ) )
539 _PTR(AttributeString) strAttr = attr;
540 std::string str = strAttr->Value();
541 QString aStrings = fromUtf8( str );
543 //Special case to show NoteBook variables in the "Value" column of the OB
544 if ( LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root() ) )
546 if ( SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( aRoot->study() ) )
548 _PTR(Study) studyDS( aStudy->studyDS() );
551 QStringList aSectionList = aStrings.split( "|" );
552 if ( !aSectionList.isEmpty() )
554 QString aLastSection = aSectionList.last();
555 QStringList aStringList = aLastSection.split( ":" );
556 if ( !aStringList.isEmpty() )
559 for ( int i = 0, n = aStringList.size(); i < n; i++ )
561 QString aStr = aStringList[i];
562 if ( studyDS->IsVariable( aStr.toStdString() ) )
563 val.append( aStr + ", " );
566 if ( !val.isEmpty() )
567 val.remove( val.length() - 2, 2 );
575 else if ( obj->FindAttribute( attr, "AttributeInteger" ) )
577 _PTR(AttributeInteger) intAttr = attr;
579 val = QString::number( intAttr->Value() );
581 else if ( obj->FindAttribute( attr, "AttributeReal" ) )
583 _PTR(AttributeReal) realAttr = attr;
585 val = QString::number( realAttr->Value() );
587 else if ( obj->FindAttribute( attr, "AttributeTableOfInteger" ) )
589 _PTR(AttributeTableOfInteger) tableAttr = attr;
590 std::string title = tableAttr->GetTitle();
591 val = QString( title.c_str() );
592 if ( !val.isEmpty() )
593 val += QString( " " );
594 val += QString( "[%1,%2]" ).arg( tableAttr->GetNbRows() ).arg( tableAttr->GetNbColumns() );
596 else if ( obj->FindAttribute( attr, "AttributeTableOfReal" ) )
598 _PTR(AttributeTableOfReal) tableAttr = attr;
599 std::string title = tableAttr->GetTitle();
600 val = QString( title.c_str() );
601 if ( !val.isEmpty() )
602 val += QString( " " );
603 val += QString( "[%1,%2]" ).arg( tableAttr->GetNbRows() ).arg( tableAttr->GetNbColumns() );
605 else if ( obj->FindAttribute( attr, "AttributeComment" ) )
607 _PTR(AttributeComment) comm = attr;
608 std::string str = comm->Value();
609 val = QString::fromUtf8( str.c_str() );
615 void SalomeApp_DataObject::insertChildAtTag( SalomeApp_DataObject* obj, int tag )
618 int npos = qMin( tag-1,childCount() );
619 for ( int i = npos; i > 0; i-- )
621 if ( (dynamic_cast<SalomeApp_DataObject*>( childObject( i-1 ) ) )->object()->Tag() < tag )
627 insertChildAtPos( obj, pos );
630 void SalomeApp_DataObject::updateItem()
632 if ( modified() ) return;
637 \class SalomeApp_ModuleObject
638 \brief This class is used for optimized access to the SALOMEDS-based
639 data model from SalomeApp_DataObject class instances.
640 \sa CAM_ModuleObject class
645 \param parent parent data object
647 SalomeApp_ModuleObject::SalomeApp_ModuleObject( SUIT_DataObject* parent )
648 : CAM_DataObject( parent ),
649 LightApp_DataObject( parent ),
650 SalomeApp_DataObject( parent ),
651 CAM_ModuleObject( parent )
657 \param sobj SALOMEDS object
658 \param parent parent data object
660 SalomeApp_ModuleObject::SalomeApp_ModuleObject( const _PTR(SObject)& sobj,
661 SUIT_DataObject* parent )
662 : CAM_DataObject( parent ),
663 LightApp_DataObject( parent ),
664 SalomeApp_DataObject( sobj, parent ),
665 CAM_ModuleObject( parent )
672 \param sobj SALOMEDS object
673 \param parent parent data object
675 SalomeApp_ModuleObject::SalomeApp_ModuleObject( CAM_DataModel* dm,
676 const _PTR(SObject)& sobj,
677 SUIT_DataObject* parent )
678 : CAM_DataObject( parent ),
679 LightApp_DataObject( parent ),
680 SalomeApp_DataObject( sobj, parent ),
681 CAM_ModuleObject( dm, parent )
688 SalomeApp_ModuleObject::~SalomeApp_ModuleObject()
693 \brief Get module name.
696 QString SalomeApp_ModuleObject::name() const
698 return SalomeApp_DataObject::name();
702 \brief Get data object icon for the specified column.
704 \return object icon for the specified column
705 \sa CAM_ModuleObject class
707 QPixmap SalomeApp_ModuleObject::icon( const int id ) const
709 QPixmap p = SalomeApp_DataObject::icon( id );
710 // The module might not provide a separate small icon
711 // for Obj. Browser representation -> always try to scale it
712 // See CAM_ModuleObject::icon()
714 p = Qtx::scaleIcon( p, 16 );
719 \brief Get data object tooltip for the specified column.
721 \return object tooltip for the specified column
723 QString SalomeApp_ModuleObject::toolTip( const int id ) const
725 return SalomeApp_DataObject::toolTip( id );
729 \class SalomeApp_RootObject
730 \brief Root data object for the CORBA-based SALOME application.
732 This class is to be instanciated by only one object - the root object
733 of the SalomeApp data object tree. This object is not shown in the object browser.
734 The goal of this class is to provide a unified access to SalomeApp_Study
735 object from SalomeApp_DataObject instances.
740 \param study pointer to the study
742 SalomeApp_RootObject::SalomeApp_RootObject( LightApp_Study* study )
743 : CAM_DataObject( 0 ),
744 LightApp_DataObject( 0 ),
745 SalomeApp_DataObject( 0 ),
746 LightApp_RootObject( study ),
754 SalomeApp_RootObject::~SalomeApp_RootObject()
759 \brief Get data object name.
762 QString SalomeApp_RootObject::name() const
764 return LightApp_RootObject::name();
768 \brief Get object string identifier.
771 QString SalomeApp_RootObject::entry() const
773 return LightApp_RootObject::entry();
777 \brief Get object text data for the specified column.
779 \return object text data
781 QString SalomeApp_RootObject::text( const int id ) const
783 return LightApp_RootObject::text( id );
787 \brief Get data object icon for the specified column.
789 \return object icon for the specified column
791 QPixmap SalomeApp_RootObject::icon( const int id ) const
793 return LightApp_RootObject::icon( id );
797 \brief Get data object color for the specified column.
798 \param role color role
799 \param id column id (not used)
800 \return object color for the specified column
802 QColor SalomeApp_RootObject::color( const ColorRole role, const int id ) const
804 return LightApp_RootObject::color( role, id );
808 \brief Get data object tooltip for the specified column.
809 \param id column id (not used)
810 \return object tooltip for the specified column
812 QString SalomeApp_RootObject::toolTip( const int id ) const
814 return LightApp_RootObject::toolTip( id );
818 \class SalomeApp_SavePointObject
819 \brief Represents persistent visual_state object.
821 Save point objects are stored in the data model, but NOT in SObjects
822 structure, so they are handled separately using this special class
827 \param parent parent data object
828 \param id save point ID
831 SalomeApp_SavePointObject::SalomeApp_SavePointObject( SUIT_DataObject* parent,
833 SalomeApp_Study* study )
834 : LightApp_DataObject( parent ),
835 CAM_DataObject( parent ),
844 SalomeApp_SavePointObject::~SalomeApp_SavePointObject()
849 \brief Get save point unique identifier.
850 \return save point ID
852 int SalomeApp_SavePointObject::getId() const
858 \brief Get object string identifier.
861 QString SalomeApp_SavePointObject::entry() const
863 return QObject::tr( "SAVE_POINT_DEF_NAME" ) + QString::number( myId );
867 \brief Get data object name.
870 QString SalomeApp_SavePointObject::name() const
872 return myStudy->getNameOfSavePoint( myId );
876 \brief Get data object icon for the specified column.
878 \return object icon for the specified column
880 QPixmap SalomeApp_SavePointObject::icon( const int /*id*/ ) const
886 \brief Get data object tooltip for the specified column.
887 \param id column id (not used)
888 \return object tooltip for the specified column
890 QString SalomeApp_SavePointObject::toolTip( const int /*id*/ ) const
892 return QObject::tr( "SAVE_POINT_OBJECT_TOOLTIP" ).arg( name() );
896 \class SalomeApp_SavePointRootObject
897 \brief Represents parent object for visual_state objects.
902 \param parent parent object
904 SalomeApp_SavePointRootObject::SalomeApp_SavePointRootObject( SUIT_DataObject* parent )
905 : SUIT_DataObject( parent )
910 \brief Get data object name.
913 QString SalomeApp_SavePointRootObject::name() const
915 return QObject::tr( "SAVE_POINT_ROOT_NAME" );
919 \brief Get data object tooltip for the specified column.
920 \param id column id (not used)
921 \return object tooltip for the specified column
923 QString SalomeApp_SavePointRootObject::toolTip( const int /*id*/ ) const
925 return QObject::tr( "SAVE_POINT_ROOT_TOOLTIP" );