AppFwk: make PdmUiTreeOrdering::add null-tolerant and clean up containsField

The add() overloads aborted via CAF_ASSERT when passed a null field or
object, forcing every call site that adds an optional child to pre-guard.
Adding an optional node is inherently an "add it if it exists" operation,
so make both overloads a no-op on null instead: the field overload returns,
and the object overload returns nullptr. This removes a class of latent
release crashes and the need for repetitive null checks at call sites.

Also remove a redundant dynamic_cast (and its "// What ???" comment) in
containsField, since child() already returns PdmUiTreeOrdering*.
This commit is contained in:
Magne Sjaastad committed 2026-06-04 16:07:12 +02:00
1 parent 85f5848bde
commit 99fdcc9a9a
1 file changed
+3 -3
@@ -51,7 +51,7 @@ namespace caf
//--------------------------------------------------------------------------------------------------
void PdmUiTreeOrdering::add( PdmFieldHandle* field, QString uiConfigName )
{
CAF_ASSERT( field );
if ( !field ) return;
if ( field->uiCapability()->isUiTreeHidden( uiConfigName ) )
{
@@ -75,7 +75,7 @@ void PdmUiTreeOrdering::add( PdmFieldHandle* field, QString uiConfigName )
//--------------------------------------------------------------------------------------------------
PdmUiTreeOrdering* PdmUiTreeOrdering::add( PdmObjectHandle* object )
{
CAF_ASSERT( object );
if ( !object ) return nullptr;
auto node = new PdmUiTreeOrdering( this, object );
@@ -102,7 +102,7 @@ bool PdmUiTreeOrdering::containsField( const PdmFieldHandle* field )
CAF_ASSERT( field );
for ( int cIdx = 0; cIdx < this->childCount(); ++cIdx )
{
PdmUiTreeOrdering* child = dynamic_cast<PdmUiTreeOrdering*>( this->child( cIdx ) ); // What ???
PdmUiTreeOrdering* child = this->child( cIdx );
if ( child->m_field == field )
{