1 // Copyright (C) 2007-2016 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 CORBA::String_var data = aComponent->getObjectInfo( aRoot->study()->id(), entry().toLatin1().constData());
295 QString objInfo = data.in();
298 if ( !objInfo.isEmpty() )
306 return QString( "Object \'%1\', module \'%2\', ID=%3" ).arg( name() ).arg( componentDataType() ).arg( entry() );
310 \brief Get font to be used for data object rendering in the item views
312 \return font to be used for the item rendering
314 QFont SalomeApp_DataObject::font( const int id ) const
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
327 \brief Get component type.
328 \return component type
330 QString SalomeApp_DataObject::componentDataType() const
332 // if ( myCompDataType.isEmpty() ) {
333 const SalomeApp_DataObject* compObj = dynamic_cast<SalomeApp_DataObject*>( componentObject() );
334 if ( compObj && compObj->object() )
336 _PTR(SComponent) aComp( compObj->object() );
338 SalomeApp_DataObject* that = (SalomeApp_DataObject*)this;
339 that->myCompDataType = aComp->ComponentDataType().c_str();
343 return myCompDataType;
347 \brief Get SALOMEDS object.
348 \return SALOMEDS object
350 _PTR(SObject) SalomeApp_DataObject::object() const
356 \brief Returns the string identifier of the data objects referenced by this one.
358 Re-implemented from LightApp_DataObject using SALOMEDS API.
360 \return ID string of the referenced SObject
362 QString SalomeApp_DataObject::refEntry() const
364 return entry( referencedObject() );
368 \brief Check if the data object is a reference.
370 Re-implemented from LightApp_DataObject using SALOMEDS API.
372 \return \c true if this data object actually refers to another one
374 bool SalomeApp_DataObject::isReference() const
379 _PTR(SObject) refObj;
380 isRef = myObject->ReferencedObject( refObj );
386 \brief Get the object referenced by this one.
387 \return referenced object
389 _PTR(SObject) SalomeApp_DataObject::referencedObject() const
391 _PTR(SObject) refObj;
392 _PTR(SObject) obj = myObject;
393 while ( obj && obj->ReferencedObject( refObj ) )
400 \brief Check if object has children
401 \return \c true if object has at least one child sub-object and \c false otherwise
403 bool SalomeApp_DataObject::hasChildren() const
408 _PTR(UseCaseBuilder) aUseCaseBuilder = myObject->GetStudy()->GetUseCaseBuilder();
409 if (aUseCaseBuilder->IsUseCaseNode(myObject)) {
410 ok = aUseCaseBuilder->HasChildren(myObject);
411 // TODO: check name as below?
414 _PTR(ChildIterator) it ( myObject->GetStudy()->NewChildIterator( myObject ) );
415 for ( ; it->More() && !ok; it->Next() ) {
416 _PTR(SObject) obj = it->Value();
418 _PTR(SObject) refObj;
419 //if ( obj->ReferencedObject( refObj ) ) continue; // omit references
420 if ( obj->GetName() != "" ) ok = true;
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
431 bool SalomeApp_DataObject::expandable() const
434 _PTR(GenericAttribute) anAttr;
435 if ( myObject && myObject->FindAttribute( anAttr, "AttributeExpandable" ) ) {
436 _PTR(AttributeExpandable) aAttrExp = anAttr;
437 exp = aAttrExp->IsExpandable();
443 \brief Check if the object is visible.
444 \return \c true if this object is displayable or \c false otherwise
446 bool SalomeApp_DataObject::isVisible() const
449 _PTR(GenericAttribute) anAttr;
450 if ( myObject && myObject->FindAttribute(anAttr, "AttributeDrawable") )
452 _PTR(AttributeDrawable) aAttrDraw = anAttr;
453 isDraw = aAttrDraw->IsDrawable();
455 return isDraw && LightApp_DataObject::isVisible() && ( !name().isEmpty() || isReference() );
459 \brief Check if the specified column supports custom sorting.
461 \return \c true if column sorting should be customized
464 bool SalomeApp_DataObject::customSorting( const int id ) const
466 // perform custom sorting for the "Entry" and "Reference Entry" columns
467 return id == EntryId || id == RefEntryId ? true
468 : LightApp_DataObject::customSorting( id );
472 \brief Compares data from two items for sorting purposes.
474 This method is called only for those columns for which customSorting()
475 method returns \c true.
477 \param left first data to compare
478 \param right second data to compare
480 \return result of the comparison
483 bool SalomeApp_DataObject::compare( const QVariant& left, const QVariant& right, const int id ) const
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 );
491 \brief Get data object IOR.
492 \param obj data object
493 \return data object IOR or null string if IOR is empty
495 QString SalomeApp_DataObject::ior( const _PTR(SObject)& obj ) const
500 _PTR(GenericAttribute) attr;
501 if ( obj->FindAttribute( attr, "AttributeIOR" ) )
503 _PTR(AttributeIOR) iorAttr = attr;
506 std::string str = iorAttr->Value();
507 txt = QString( str.c_str() );
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
519 QString SalomeApp_DataObject::entry( const _PTR(SObject)& obj ) const
524 std::string str = obj->GetID();
525 txt = QString( str.c_str() );
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
536 QString SalomeApp_DataObject::value( const _PTR(SObject)& obj ) const
542 _PTR(GenericAttribute) attr;
544 if ( obj->FindAttribute( attr, "AttributeString" ) )
546 _PTR(AttributeString) strAttr = attr;
547 std::string str = strAttr->Value();
548 QString aStrings = fromUtf8( str );
550 //Special case to show NoteBook variables in the "Value" column of the OB
551 if ( LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root() ) )
553 if ( SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( aRoot->study() ) )
555 _PTR(Study) studyDS( aStudy->studyDS() );
558 QStringList aSectionList = aStrings.split( "|" );
559 if ( !aSectionList.isEmpty() )
561 QString aLastSection = aSectionList.last();
562 QStringList aStringList = aLastSection.split( ":" );
563 if ( !aStringList.isEmpty() )
566 for ( int i = 0, n = aStringList.size(); i < n; i++ )
568 QString aStr = aStringList[i];
569 if ( studyDS->IsVariable( aStr.toStdString() ) )
570 val.append( aStr + ", " );
573 if ( !val.isEmpty() )
574 val.remove( val.length() - 2, 2 );
582 else if ( obj->FindAttribute( attr, "AttributeInteger" ) )
584 _PTR(AttributeInteger) intAttr = attr;
586 val = QString::number( intAttr->Value() );
588 else if ( obj->FindAttribute( attr, "AttributeReal" ) )
590 _PTR(AttributeReal) realAttr = attr;
592 val = QString::number( realAttr->Value() );
594 else if ( obj->FindAttribute( attr, "AttributeTableOfInteger" ) )
596 _PTR(AttributeTableOfInteger) tableAttr = attr;
597 std::string title = tableAttr->GetTitle();
598 val = QString( title.c_str() );
599 if ( !val.isEmpty() )
600 val += QString( " " );
601 val += QString( "[%1,%2]" ).arg( tableAttr->GetNbRows() ).arg( tableAttr->GetNbColumns() );
603 else if ( obj->FindAttribute( attr, "AttributeTableOfReal" ) )
605 _PTR(AttributeTableOfReal) tableAttr = attr;
606 std::string title = tableAttr->GetTitle();
607 val = QString( title.c_str() );
608 if ( !val.isEmpty() )
609 val += QString( " " );
610 val += QString( "[%1,%2]" ).arg( tableAttr->GetNbRows() ).arg( tableAttr->GetNbColumns() );
612 else if ( obj->FindAttribute( attr, "AttributeComment" ) )
614 _PTR(AttributeComment) comm = attr;
615 std::string str = comm->Value();
616 val = fromUtf8( str );
622 void SalomeApp_DataObject::insertChildAtTag( SalomeApp_DataObject* obj, int tag )
625 int npos = qMin( tag-1,childCount() );
626 for ( int i = npos; i > 0; i-- )
628 if ( (dynamic_cast<SalomeApp_DataObject*>( childObject( i-1 ) ) )->object()->Tag() < tag )
634 insertChildAtPos( obj, pos );
637 void SalomeApp_DataObject::updateItem()
639 if ( modified() ) return;
644 \class SalomeApp_ModuleObject
645 \brief This class is used for optimized access to the SALOMEDS-based
646 data model from SalomeApp_DataObject class instances.
647 \sa CAM_ModuleObject class
652 \param parent parent data object
654 SalomeApp_ModuleObject::SalomeApp_ModuleObject( SUIT_DataObject* parent )
655 : CAM_DataObject( parent ),
656 LightApp_DataObject( parent ),
657 SalomeApp_DataObject( parent ),
658 CAM_ModuleObject( parent )
664 \param sobj SALOMEDS object
665 \param parent parent data object
667 SalomeApp_ModuleObject::SalomeApp_ModuleObject( const _PTR(SObject)& sobj,
668 SUIT_DataObject* parent )
669 : CAM_DataObject( parent ),
670 LightApp_DataObject( parent ),
671 SalomeApp_DataObject( sobj, parent ),
672 CAM_ModuleObject( parent )
679 \param sobj SALOMEDS object
680 \param parent parent data object
682 SalomeApp_ModuleObject::SalomeApp_ModuleObject( CAM_DataModel* dm,
683 const _PTR(SObject)& sobj,
684 SUIT_DataObject* parent )
685 : CAM_DataObject( parent ),
686 LightApp_DataObject( parent ),
687 SalomeApp_DataObject( sobj, parent ),
688 CAM_ModuleObject( dm, parent )
695 SalomeApp_ModuleObject::~SalomeApp_ModuleObject()
700 \brief Get module name.
703 QString SalomeApp_ModuleObject::name() const
705 return SalomeApp_DataObject::name();
709 \brief Get data object icon for the specified column.
711 \return object icon for the specified column
712 \sa CAM_ModuleObject class
714 QPixmap SalomeApp_ModuleObject::icon( const int id ) const
716 QPixmap p = SalomeApp_DataObject::icon( id );
717 // The module might not provide a separate small icon
718 // for Obj. Browser representation -> always try to scale it
719 // See CAM_ModuleObject::icon()
721 p = Qtx::scaleIcon( p, 16 );
726 \brief Get data object tooltip for the specified column.
728 \return object tooltip for the specified column
730 QString SalomeApp_ModuleObject::toolTip( const int id ) const
732 return SalomeApp_DataObject::toolTip( id );
736 \class SalomeApp_RootObject
737 \brief Root data object for the CORBA-based SALOME application.
739 This class is to be instanciated by only one object - the root object
740 of the SalomeApp data object tree. This object is not shown in the object browser.
741 The goal of this class is to provide a unified access to SalomeApp_Study
742 object from SalomeApp_DataObject instances.
747 \param study pointer to the study
749 SalomeApp_RootObject::SalomeApp_RootObject( LightApp_Study* study )
750 : CAM_DataObject( 0 ),
751 LightApp_DataObject( 0 ),
752 SalomeApp_DataObject( 0 ),
753 LightApp_RootObject( study ),
761 SalomeApp_RootObject::~SalomeApp_RootObject()
766 \brief Get data object name.
769 QString SalomeApp_RootObject::name() const
771 return LightApp_RootObject::name();
775 \brief Get object string identifier.
778 QString SalomeApp_RootObject::entry() const
780 return LightApp_RootObject::entry();
784 \brief Get object text data for the specified column.
786 \return object text data
788 QString SalomeApp_RootObject::text( const int id ) const
790 return LightApp_RootObject::text( id );
794 \brief Get data object icon for the specified column.
796 \return object icon for the specified column
798 QPixmap SalomeApp_RootObject::icon( const int id ) const
800 return LightApp_RootObject::icon( id );
804 \brief Get data object color for the specified column.
805 \param role color role
806 \param id column id (not used)
807 \return object color for the specified column
809 QColor SalomeApp_RootObject::color( const ColorRole role, const int id ) const
811 return LightApp_RootObject::color( role, id );
815 \brief Get data object tooltip for the specified column.
816 \param id column id (not used)
817 \return object tooltip for the specified column
819 QString SalomeApp_RootObject::toolTip( const int id ) const
821 return LightApp_RootObject::toolTip( id );
825 \class SalomeApp_SavePointObject
826 \brief Represents persistent visual_state object.
828 Save point objects are stored in the data model, but NOT in SObjects
829 structure, so they are handled separately using this special class
834 \param parent parent data object
835 \param id save point ID
838 SalomeApp_SavePointObject::SalomeApp_SavePointObject( SUIT_DataObject* parent,
840 SalomeApp_Study* study )
841 : LightApp_DataObject( parent ),
842 CAM_DataObject( parent ),
851 SalomeApp_SavePointObject::~SalomeApp_SavePointObject()
856 \brief Get save point unique identifier.
857 \return save point ID
859 int SalomeApp_SavePointObject::getId() const
865 \brief Get object string identifier.
868 QString SalomeApp_SavePointObject::entry() const
870 return QObject::tr( "SAVE_POINT_DEF_NAME" ) + QString::number( myId );
874 \brief Get data object name.
877 QString SalomeApp_SavePointObject::name() const
879 return myStudy->getNameOfSavePoint( myId );
883 \brief Get data object icon for the specified column.
885 \return object icon for the specified column
887 QPixmap SalomeApp_SavePointObject::icon( const int /*id*/ ) const
893 \brief Get data object tooltip for the specified column.
894 \param id column id (not used)
895 \return object tooltip for the specified column
897 QString SalomeApp_SavePointObject::toolTip( const int /*id*/ ) const
899 return QObject::tr( "SAVE_POINT_OBJECT_TOOLTIP" ).arg( name() );
903 \class SalomeApp_SavePointRootObject
904 \brief Represents parent object for visual_state objects.
909 \param parent parent object
911 SalomeApp_SavePointRootObject::SalomeApp_SavePointRootObject( SUIT_DataObject* parent )
912 : SUIT_DataObject( parent )
917 \brief Get data object name.
920 QString SalomeApp_SavePointRootObject::name() const
922 return QObject::tr( "SAVE_POINT_ROOT_NAME" );
926 \brief Get data object tooltip for the specified column.
927 \param id column id (not used)
928 \return object tooltip for the specified column
930 QString SalomeApp_SavePointRootObject::toolTip( const int /*id*/ ) const
932 return QObject::tr( "SAVE_POINT_ROOT_TOOLTIP" );