ResInsight/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.cpp

247 lines
10 KiB
C++

#include "cafPdmUiObjectHandle.h"
#include "cafAssert.h"
#include "cafPdmFieldHandle.h"
#include "cafPdmObjectHandle.h"
#include "cafPdmUiFieldHandle.h"
#include "cafPdmUiOrdering.h"
#include "cafPdmUiTreeOrdering.h"
namespace caf
{
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiObjectHandle::PdmUiObjectHandle( PdmObjectHandle* owner, bool giveOwnership )
{
m_owner = owner;
m_owner->addCapability( this, giveOwnership );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiObjectHandle* uiObj( const PdmObjectHandle* obj )
{
if ( !obj ) return nullptr;
return obj->uiCapability();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiObjectHandle::uiOrdering( const QString& uiConfigName, PdmUiOrdering& uiOrdering )
{
// Restore state for includeRemainingFields, as this flag
// can be changed in defineUiOrdering()
bool includeRemaining_originalState = uiOrdering.isIncludingRemainingFields();
this->defineUiOrdering( uiConfigName, uiOrdering );
if ( uiOrdering.isIncludingRemainingFields() )
{
// Add the remaining Fields To UiConfig
std::vector<PdmFieldHandle*> fields = m_owner->fields();
for ( size_t i = 0; i < fields.size(); ++i )
{
PdmUiFieldHandle* field = fields[i]->uiCapability();
if ( !uiOrdering.contains( field ) )
{
uiOrdering.add( field->fieldHandle() );
}
}
}
// Restore incoming value
uiOrdering.skipRemainingFields( !includeRemaining_originalState );
CAF_ASSERT( includeRemaining_originalState == uiOrdering.isIncludingRemainingFields() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiObjectHandle::editorAttribute( const PdmFieldHandle* field,
const QString& uiConfigName,
PdmUiEditorAttribute* attribute )
{
this->defineEditorAttribute( field, uiConfigName, attribute );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiObjectHandle::objectEditorAttribute( const QString& uiConfigName, PdmUiEditorAttribute* attribute )
{
this->defineObjectEditorAttribute( uiConfigName, attribute );
}
//--------------------------------------------------------------------------------------------------
/// This method creates a tree-representation of the object hierarchy starting at this
/// object to be used for a tree view.
/// This method calls the optional virtual user defined method "defineUiTreeOrdering" to customize the
/// order and content of the children directly below each object. If this method does nothing,
/// the default behavior applies: Add all fields that contains objects, and their objects.
///
/// The caller is responsible to delete the returned PdmUiTreeOrdering
//--------------------------------------------------------------------------------------------------
PdmUiTreeOrdering* PdmUiObjectHandle::uiTreeOrdering( const QString& uiConfigName /*= ""*/ ) const
{
CAF_ASSERT( this ); // This method actually is possible to call on a NULL ptr without getting a crash, so we assert
// instead.
PdmUiTreeOrdering* uiTreeOrdering = new PdmUiTreeOrdering( nullptr, m_owner );
if ( !m_owner->uiCapability()->isUiTreeHidden() ) expandUiTree( uiTreeOrdering, uiConfigName );
return uiTreeOrdering;
}
//--------------------------------------------------------------------------------------------------
/// Adds the direct children of this PdmObject to the PdmUiTree according to
/// the default rules. Add all fields that contains objects, and their objects.
/// Takes into account the control variables regarding this:
/// PdmField::isUiHidden
/// PdmField::isUiChildrenHidden
/// And whether the fields and objects are already added by the user.
//--------------------------------------------------------------------------------------------------
void PdmUiObjectHandle::addDefaultUiTreeChildren( PdmUiTreeOrdering* uiTreeOrdering )
{
#if 1
if ( uiTreeOrdering->isIncludingRemainingChildren() )
{
// Add the remaining Fields To UiConfig
std::vector<PdmFieldHandle*> fields = m_owner->fields();
for ( size_t fIdx = 0; fIdx < fields.size(); ++fIdx )
{
if ( fields[fIdx]->hasChildren() && !uiTreeOrdering->containsField( fields[fIdx] ) )
{
if ( fields[fIdx]->uiCapability()->isUiTreeHidden() &&
!fields[fIdx]->uiCapability()->isUiTreeChildrenHidden() )
{
std::vector<PdmObjectHandle*> children = fields[fIdx]->children();
std::set<PdmObjectHandle*> objectsAddedByApplication;
for ( int i = 0; i < uiTreeOrdering->childCount(); i++ )
{
if ( uiTreeOrdering->child( i )->isRepresentingObject() &&
!uiTreeOrdering->child( i )->object()->uiCapability()->isUiTreeHidden() )
{
objectsAddedByApplication.insert( uiTreeOrdering->child( i )->object() );
}
}
for ( size_t cIdx = 0; cIdx < children.size(); cIdx++ )
{
if ( children[cIdx] )
{
bool isAlreadyAdded = false;
std::set<PdmObjectHandle*>::iterator it = objectsAddedByApplication.find( children[cIdx] );
if ( it != objectsAddedByApplication.end() )
{
isAlreadyAdded = true;
break;
}
if ( !isAlreadyAdded && !children[cIdx]->uiCapability()->isUiTreeHidden() )
{
uiTreeOrdering->add( children[cIdx] );
}
}
}
}
else if ( !fields[fIdx]->uiCapability()->isUiTreeHidden() )
{
uiTreeOrdering->add( fields[fIdx] );
}
}
}
}
#endif
}
//--------------------------------------------------------------------------------------------------
/// Builds the sPdmUiTree for all the children of @param root recursively, and stores the result
/// in root
//--------------------------------------------------------------------------------------------------
void PdmUiObjectHandle::expandUiTree( PdmUiTreeOrdering* root, const QString& uiConfigName /*= "" */ )
{
if ( !root || !root->isValid() ) return;
if ( root->childCount() > 0 )
{
for ( int cIdx = 0; cIdx < root->childCount(); ++cIdx )
{
PdmUiTreeOrdering* child = root->child( cIdx );
if ( child->isValid() && !child->ignoreSubTree() && !child->activeItem()->isUiTreeHidden( uiConfigName ) )
{
expandUiTree( child, uiConfigName );
}
}
}
else //( root->childCount() == 0) // This means that no one has tried to expand it.
{
if ( !root->ignoreSubTree() )
{
if ( root->isRepresentingField() && !root->field()->uiCapability()->isUiTreeHidden( uiConfigName ) &&
!root->field()->uiCapability()->isUiTreeChildrenHidden( uiConfigName ) )
{
auto children = root->field()->children();
for ( size_t cIdx = 0; cIdx < children.size(); ++cIdx )
{
PdmObjectHandle* childObject = children[cIdx];
if ( childObject && !childObject->uiCapability()->isUiTreeHidden() )
{
root->appendChild( uiObj( childObject )->uiTreeOrdering( uiConfigName ) );
}
}
}
else if ( root->isRepresentingObject() && !root->object()->uiCapability()->isUiTreeHidden( uiConfigName ) &&
!root->object()->uiCapability()->isUiTreeChildrenHidden( uiConfigName ) )
{
uiObj( root->object() )->defineUiTreeOrdering( *root, uiConfigName );
uiObj( root->object() )->addDefaultUiTreeChildren( root );
if ( root->childCount() )
{
expandUiTree( root, uiConfigName );
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiObjectHandle::updateUiIconFromToggleField()
{
if ( objectToggleField() )
{
PdmUiFieldHandle* uiFieldHandle = objectToggleField()->uiCapability();
if ( uiFieldHandle )
{
bool active = uiFieldHandle->uiValue().toBool();
updateUiIconFromState( active );
}
}
}
//--------------------------------------------------------------------------------------------------
/// Implementation of uiCapability() defined in cafPdmObjectHandle.h
//--------------------------------------------------------------------------------------------------
PdmUiObjectHandle* PdmObjectHandle::uiCapability() const
{
if ( !m_uiCapability )
{
// Cache the ui capability for performance reasons
auto uiField = capability<PdmUiObjectHandle>();
CAF_ASSERT( uiField );
m_uiCapability = uiField;
}
return m_uiCapability;
}
} // End namespace caf