1 // Copyright (C) 2007-2020 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
153 if ( componentObject() != (SUIT_DataObject*)this )
154 txt = value( object() );
156 txt = value( referencedObject() );
159 txt = ior( referencedObject() );
162 // Issue 21379: LightApp_DataObject::text() treats "Entry"
163 // and "Reference Entry" columns
164 txt = LightApp_DataObject::text( id );
171 \brief Get data object icon for the specified column.
173 \return object icon for the specified column
175 QPixmap SalomeApp_DataObject::icon( const int id ) const
177 // we display icon only for the first (NameId ) column
178 if ( id == NameId ) {
179 _PTR(GenericAttribute) anAttr;
180 if ( myObject && myObject->FindAttribute( anAttr, "AttributePixMap" ) ){
181 _PTR(AttributePixMap) aPixAttr ( anAttr );
182 if ( aPixAttr->HasPixMap() ) {
183 QString componentType = componentDataType();
184 QString pixmapID = fromUtf8( aPixAttr->GetPixMap() );
185 // select a plugin within a component
186 QStringList plugin_pixmap = pixmapID.split( "::", QString::KeepEmptyParts );
187 if ( plugin_pixmap.size() == 2 ) {
188 componentType = plugin_pixmap.front();
189 pixmapID = plugin_pixmap.back();
191 QString pixmapName = QObject::tr( pixmapID.toLatin1().constData() );
192 LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root() );
193 if ( aRoot && aRoot->study() ) {
194 SUIT_ResourceMgr* mgr = aRoot->study()->application()->resourceMgr();
195 return mgr->loadPixmap( componentType, pixmapName, false );
200 return LightApp_DataObject::icon( id );
204 \brief Get data object color for the specified column.
205 \param role color role
206 \param id column id (not used)
207 \return object color for the specified column
209 QColor SalomeApp_DataObject::color( const ColorRole role, const int id ) const
211 // we ignore parameter <id> in order to use the same colors for
218 // text color (not selected item)
219 if ( isReference() ) {
220 if ( QString(referencedObject()->GetName().c_str()).isEmpty() )
221 c = QColor( 200, 200, 200 ); // invalid reference (grayed)
223 else if ( myObject ) {
224 // get color atrtribute value
225 _PTR(GenericAttribute) anAttr;
226 if ( myObject->FindAttribute( anAttr, "AttributeTextColor" ) ) {
227 _PTR(AttributeTextColor) aColAttr = anAttr;
228 c = QColor( (int)aColAttr->TextColor().R, (int)aColAttr->TextColor().G, (int)aColAttr->TextColor().B );
234 // background color for the highlighted item
235 if ( isReference() ) {
236 if ( QString(referencedObject()->GetName().c_str()).isEmpty() )
237 c = QColor( 200, 200, 200 ); // invalid reference (grayed)
239 else if ( myObject ) {
240 // get color atrtribute value
241 _PTR(GenericAttribute) anAttr;
242 if( myObject->FindAttribute ( anAttr, "AttributeTextHighlightColor") ) {
243 _PTR(AttributeTextHighlightColor) aHighColAttr = anAttr;
244 c = QColor( (int)(aHighColAttr->TextHighlightColor().R),
245 (int)(aHighColAttr->TextHighlightColor().G),
246 (int)(aHighColAttr->TextHighlightColor().B));
254 // Issue 21379: LightApp_DataObject::color() defines colors for valid references
256 c = LightApp_DataObject::color( role, id );
262 \brief Get data object tooltip for the specified column.
263 \param id column id (not used)
264 \return object tooltip for the specified column
266 QString SalomeApp_DataObject::toolTip( const int /*id*/ ) const
268 // we ignore parameter <id> in order to use the same tooltip for
271 // Get customized tooltip in case of it exists
272 const SalomeApp_DataObject* compObj = dynamic_cast<SalomeApp_DataObject*>( componentObject() );
273 // Check if the component has been loaded.
274 // In order to avoid loading the component only for getting a custom tooltip.
275 if ( compObj && compObj != this && !ior(compObj->object()).isEmpty() ) {
276 SalomeApp_Application* app =
277 dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
279 // --- try to find (and not load) the component instance, like GEOM instance,
280 // registered in naming service under Containers/<hostname>/...
281 // with any container name, on every machine available
282 Engines::ContainerParameters params;
283 app->lcc()->preSet(params); // --- any container name, anywhere
284 Engines::EngineComponent_var aComponent =
285 app->lcc()->FindComponent(params, componentDataType().toLatin1().constData() );
287 if ( !CORBA::is_nil(aComponent) && aComponent->hasObjectInfo() ) {
288 LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root() );
289 if ( aRoot && aRoot->study() ) {
290 CORBA::String_var data = aComponent->getObjectInfo( entry().toUtf8().constData());
291 QString objInfo = data.in();
294 if ( !objInfo.isEmpty() )
302 return QString( "Object \'%1\', module \'%2\', ID=%3" ).arg( name() ).arg( componentDataType() ).arg( entry() );
306 \brief Get font to be used for data object rendering in the item views
308 \return font to be used for the item rendering
310 QFont SalomeApp_DataObject::font( const int id ) const
312 QFont f = LightApp_DataObject::font( id );
313 if ( id == NameId ) {
314 if ( !expandable() && hasChildren() ) {
315 // set bold font to highlight the item which is non-expandable but has children
323 \brief Get component type.
324 \return component type
326 QString SalomeApp_DataObject::componentDataType() const
328 // if ( myCompDataType.isEmpty() ) {
329 const SalomeApp_DataObject* compObj = dynamic_cast<SalomeApp_DataObject*>( componentObject() );
330 if ( compObj && compObj->object() )
332 _PTR(SComponent) aComp( compObj->object() );
334 SalomeApp_DataObject* that = (SalomeApp_DataObject*)this;
335 that->myCompDataType = aComp->ComponentDataType().c_str();
339 return myCompDataType;
343 \brief Get SALOMEDS object.
344 \return SALOMEDS object
346 _PTR(SObject) SalomeApp_DataObject::object() const
352 \brief Returns the string identifier of the data objects referenced by this one.
354 Re-implemented from LightApp_DataObject using SALOMEDS API.
356 \return ID string of the referenced SObject
358 QString SalomeApp_DataObject::refEntry() const
360 return entry( referencedObject() );
364 \brief Check if the data object is a reference.
366 Re-implemented from LightApp_DataObject using SALOMEDS API.
368 \return \c true if this data object actually refers to another one
370 bool SalomeApp_DataObject::isReference() const
375 _PTR(SObject) refObj;
376 isRef = myObject->ReferencedObject( refObj );
382 \brief Get the object referenced by this one.
383 \return referenced object
385 _PTR(SObject) SalomeApp_DataObject::referencedObject() const
387 _PTR(SObject) refObj;
388 _PTR(SObject) obj = myObject;
389 while ( obj && obj->ReferencedObject( refObj ) )
396 \brief Check if object has children
397 \return \c true if object has at least one child sub-object and \c false otherwise
399 bool SalomeApp_DataObject::hasChildren() const
404 _PTR(UseCaseBuilder) aUseCaseBuilder = SalomeApp_Application::getStudy()->GetUseCaseBuilder();
405 if (aUseCaseBuilder->IsUseCaseNode(myObject)) {
406 ok = aUseCaseBuilder->HasChildren(myObject);
407 // TODO: check name as below?
410 _PTR(ChildIterator) it ( SalomeApp_Application::getStudy()->NewChildIterator( myObject ) );
411 for ( ; it->More() && !ok; it->Next() ) {
412 _PTR(SObject) obj = it->Value();
414 _PTR(SObject) refObj;
415 //if ( obj->ReferencedObject( refObj ) ) continue; // omit references
416 if ( obj->GetName() != "" ) ok = true;
424 \brief Check if the object is expandable (e.g. in the data tree view)
425 \return \c true if object is expandable and \c false otherwise
427 bool SalomeApp_DataObject::expandable() const
430 _PTR(GenericAttribute) anAttr;
431 if ( myObject && myObject->FindAttribute( anAttr, "AttributeExpandable" ) ) {
432 _PTR(AttributeExpandable) aAttrExp = anAttr;
433 exp = aAttrExp->IsExpandable();
439 \brief Check if the object is visible.
440 \return \c true if this object is displayable or \c false otherwise
442 bool SalomeApp_DataObject::isVisible() const
445 _PTR(GenericAttribute) anAttr;
446 if ( myObject && myObject->FindAttribute(anAttr, "AttributeDrawable") )
448 _PTR(AttributeDrawable) aAttrDraw = anAttr;
449 isDraw = aAttrDraw->IsDrawable();
451 return isDraw && LightApp_DataObject::isVisible() && ( !name().isEmpty() || isReference() );
455 \brief Check if the specified column supports custom sorting.
457 \return \c true if column sorting should be customized
460 bool SalomeApp_DataObject::customSorting( const int id ) const
462 // perform custom sorting for the "Entry" and "Reference Entry" columns
463 return id == EntryId || id == RefEntryId ? true
464 : LightApp_DataObject::customSorting( id );
468 \brief Compares data from two items for sorting purposes.
470 This method is called only for those columns for which customSorting()
471 method returns \c true.
473 \param left first data to compare
474 \param right second data to compare
476 \return result of the comparison
479 bool SalomeApp_DataObject::compare( const QVariant& left, const QVariant& right, const int id ) const
481 // use the same custom sorting for the "Reference Entry" column as for the
482 // "Entry" column (call base implementation)
483 return LightApp_DataObject::compare( left, right, id == RefEntryId ? EntryId : id );
487 \brief Get data object IOR.
488 \param obj data object
489 \return data object IOR or null string if IOR is empty
491 QString SalomeApp_DataObject::ior( const _PTR(SObject)& obj ) const
496 _PTR(GenericAttribute) attr;
497 if ( obj->FindAttribute( attr, "AttributeIOR" ) )
499 _PTR(AttributeIOR) iorAttr = attr;
502 std::string str = iorAttr->Value();
503 txt = QString( str.c_str() );
511 \brief Get data object entry identifier.
512 \param obj data object
513 \return data object entry identifier or empty object does not have entry
515 QString SalomeApp_DataObject::entry( const _PTR(SObject)& obj ) const
520 std::string str = obj->GetID();
521 txt = QString( str.c_str() );
527 \brief Get data object value.
528 \param obj data object
529 \return data object value or empty string if there is no
530 value associated to the object
532 QString SalomeApp_DataObject::value( const _PTR(SObject)& obj ) const
538 _PTR(GenericAttribute) attr;
540 if ( obj->FindAttribute( attr, "AttributeString" ) )
542 _PTR(AttributeString) strAttr = attr;
543 std::string str = strAttr->Value();
544 QString aStrings = fromUtf8( str );
546 //Special case to show NoteBook variables in the "Value" column of the OB
548 QStringList aSectionList = aStrings.split( "|" );
549 if ( !aSectionList.isEmpty() )
551 QString aLastSection = aSectionList.last();
552 QStringList aStringList = aLastSection.split( ":" );
553 if ( !aStringList.isEmpty() )
556 for ( int i = 0, n = aStringList.size(); i < n; i++ )
558 QString aStr = aStringList[i];
559 if ( SalomeApp_Application::getStudy()->IsVariable( aStr.toStdString() ) )
560 val.append( aStr + ", " );
563 if ( !val.isEmpty() )
564 val.remove( val.length() - 2, 2 );
570 else if ( obj->FindAttribute( attr, "AttributeInteger" ) )
572 _PTR(AttributeInteger) intAttr = attr;
574 val = QString::number( intAttr->Value() );
576 else if ( obj->FindAttribute( attr, "AttributeReal" ) )
578 _PTR(AttributeReal) realAttr = attr;
580 val = QString::number( realAttr->Value() );
582 else if ( obj->FindAttribute( attr, "AttributeTableOfInteger" ) )
584 _PTR(AttributeTableOfInteger) tableAttr = attr;
585 std::string title = tableAttr->GetTitle();
586 val = QString( title.c_str() );
587 if ( !val.isEmpty() )
588 val += QString( " " );
589 val += QString( "[%1,%2]" ).arg( tableAttr->GetNbRows() ).arg( tableAttr->GetNbColumns() );
591 else if ( obj->FindAttribute( attr, "AttributeTableOfReal" ) )
593 _PTR(AttributeTableOfReal) tableAttr = attr;
594 std::string title = tableAttr->GetTitle();
595 val = QString( title.c_str() );
596 if ( !val.isEmpty() )
597 val += QString( " " );
598 val += QString( "[%1,%2]" ).arg( tableAttr->GetNbRows() ).arg( tableAttr->GetNbColumns() );
600 else if ( obj->FindAttribute( attr, "AttributeComment" ) )
602 _PTR(AttributeComment) comm = attr;
603 std::string str = comm->Value();
604 val = fromUtf8( str );
610 void SalomeApp_DataObject::insertChildAtTag( SalomeApp_DataObject* obj, int tag )
613 int npos = qMin( tag-1,childCount() );
614 for ( int i = npos; i > 0; i-- )
616 if ( (dynamic_cast<SalomeApp_DataObject*>( childObject( i-1 ) ) )->object()->Tag() < tag )
622 insertChildAtPos( obj, pos );
625 void SalomeApp_DataObject::updateItem()
627 if ( modified() ) return;
632 \class SalomeApp_ModuleObject
633 \brief This class is used for optimized access to the SALOMEDS-based
634 data model from SalomeApp_DataObject class instances.
635 \sa CAM_ModuleObject class
640 \param parent parent data object
642 SalomeApp_ModuleObject::SalomeApp_ModuleObject( SUIT_DataObject* parent )
643 : CAM_DataObject( parent ),
644 LightApp_DataObject( parent ),
645 SalomeApp_DataObject( parent ),
646 CAM_ModuleObject( parent )
652 \param sobj SALOMEDS object
653 \param parent parent data object
655 SalomeApp_ModuleObject::SalomeApp_ModuleObject( const _PTR(SObject)& sobj,
656 SUIT_DataObject* parent )
657 : CAM_DataObject( parent ),
658 LightApp_DataObject( parent ),
659 SalomeApp_DataObject( sobj, parent ),
660 CAM_ModuleObject( parent )
667 \param sobj SALOMEDS object
668 \param parent parent data object
670 SalomeApp_ModuleObject::SalomeApp_ModuleObject( CAM_DataModel* dm,
671 const _PTR(SObject)& sobj,
672 SUIT_DataObject* parent )
673 : CAM_DataObject( parent ),
674 LightApp_DataObject( parent ),
675 SalomeApp_DataObject( sobj, parent ),
676 CAM_ModuleObject( dm, parent )
683 SalomeApp_ModuleObject::~SalomeApp_ModuleObject()
688 \brief Get module name.
691 QString SalomeApp_ModuleObject::name() const
693 return SalomeApp_DataObject::name();
697 \brief Get data object icon for the specified column.
699 \return object icon for the specified column
700 \sa CAM_ModuleObject class
702 QPixmap SalomeApp_ModuleObject::icon( const int id ) const
704 QPixmap p = SalomeApp_DataObject::icon( id );
705 // The module might not provide a separate small icon
706 // for Obj. Browser representation -> always try to scale it
707 // See CAM_ModuleObject::icon()
709 p = Qtx::scaleIcon( p, 16 );
714 \brief Get data object tooltip for the specified column.
716 \return object tooltip for the specified column
718 QString SalomeApp_ModuleObject::toolTip( const int id ) const
720 return SalomeApp_DataObject::toolTip( id );
724 \class SalomeApp_RootObject
725 \brief Root data object for the CORBA-based SALOME application.
727 This class is to be instanciated by only one object - the root object
728 of the SalomeApp data object tree. This object is not shown in the object browser.
729 The goal of this class is to provide a unified access to SalomeApp_Study
730 object from SalomeApp_DataObject instances.
735 \param study pointer to the study
737 SalomeApp_RootObject::SalomeApp_RootObject( LightApp_Study* study )
738 : CAM_DataObject( 0 ),
739 LightApp_DataObject( 0 ),
740 SalomeApp_DataObject( 0 ),
741 LightApp_RootObject( study ),
749 SalomeApp_RootObject::~SalomeApp_RootObject()
754 \brief Get data object name.
757 QString SalomeApp_RootObject::name() const
759 return LightApp_RootObject::name();
763 \brief Get object string identifier.
766 QString SalomeApp_RootObject::entry() const
768 return LightApp_RootObject::entry();
772 \brief Get object text data for the specified column.
774 \return object text data
776 QString SalomeApp_RootObject::text( const int id ) const
778 return LightApp_RootObject::text( id );
782 \brief Get data object icon for the specified column.
784 \return object icon for the specified column
786 QPixmap SalomeApp_RootObject::icon( const int id ) const
788 return LightApp_RootObject::icon( id );
792 \brief Get data object color for the specified column.
793 \param role color role
794 \param id column id (not used)
795 \return object color for the specified column
797 QColor SalomeApp_RootObject::color( const ColorRole role, const int id ) const
799 return LightApp_RootObject::color( role, id );
803 \brief Get data object tooltip for the specified column.
804 \param id column id (not used)
805 \return object tooltip for the specified column
807 QString SalomeApp_RootObject::toolTip( const int id ) const
809 return LightApp_RootObject::toolTip( id );
813 \class SalomeApp_SavePointObject
814 \brief Represents persistent visual_state object.
816 Save point objects are stored in the data model, but NOT in SObjects
817 structure, so they are handled separately using this special class
822 \param parent parent data object
823 \param id save point ID
826 SalomeApp_SavePointObject::SalomeApp_SavePointObject( SUIT_DataObject* parent,
828 SalomeApp_Study* study )
829 : CAM_DataObject( parent ),
830 LightApp_DataObject( parent ),
839 SalomeApp_SavePointObject::~SalomeApp_SavePointObject()
844 \brief Get save point unique identifier.
845 \return save point ID
847 int SalomeApp_SavePointObject::getId() const
853 \brief Get object string identifier.
856 QString SalomeApp_SavePointObject::entry() const
858 return QObject::tr( "SAVE_POINT_DEF_NAME" ) + QString::number( myId );
862 \brief Get data object name.
865 QString SalomeApp_SavePointObject::name() const
867 return myStudy->getNameOfSavePoint( myId );
871 \brief Get data object icon for the specified column.
873 \return object icon for the specified column
875 QPixmap SalomeApp_SavePointObject::icon( const int /*id*/ ) const
881 \brief Get data object tooltip for the specified column.
882 \param id column id (not used)
883 \return object tooltip for the specified column
885 QString SalomeApp_SavePointObject::toolTip( const int /*id*/ ) const
887 return QObject::tr( "SAVE_POINT_OBJECT_TOOLTIP" ).arg( name() );
891 \class SalomeApp_SavePointRootObject
892 \brief Represents parent object for visual_state objects.
897 \param parent parent object
899 SalomeApp_SavePointRootObject::SalomeApp_SavePointRootObject( SUIT_DataObject* parent )
900 : SUIT_DataObject( parent )
905 \brief Get data object name.
908 QString SalomeApp_SavePointRootObject::name() const
910 return QObject::tr( "SAVE_POINT_ROOT_NAME" );
914 \brief Get data object tooltip for the specified column.
915 \param id column id (not used)
916 \return object tooltip for the specified column
918 QString SalomeApp_SavePointRootObject::toolTip( const int /*id*/ ) const
920 return QObject::tr( "SAVE_POINT_ROOT_TOOLTIP" );