2015-07-29 07:19:43 -05:00
|
|
|
//##################################################################################################
|
|
|
|
//
|
|
|
|
// Custom Visualization Core library
|
|
|
|
// Copyright (C) 2011-2013 Ceetron AS
|
|
|
|
//
|
|
|
|
// This library may be used under the terms of either the GNU General Public License or
|
|
|
|
// the GNU Lesser General Public License as follows:
|
|
|
|
//
|
|
|
|
// GNU General Public License Usage
|
|
|
|
// This library is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
//
|
|
|
|
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
|
|
|
// for more details.
|
|
|
|
//
|
|
|
|
// GNU Lesser General Public License Usage
|
|
|
|
// This library is free software; you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
// the Free Software Foundation; either version 2.1 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
//
|
|
|
|
// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
|
|
|
// for more details.
|
|
|
|
//
|
|
|
|
//##################################################################################################
|
|
|
|
|
|
|
|
#include "cafPdmReferenceHelper.h"
|
|
|
|
|
2017-03-08 01:19:51 -06:00
|
|
|
#include "cafAssert.h"
|
2015-07-29 07:19:43 -05:00
|
|
|
#include "cafPdmFieldHandle.h"
|
|
|
|
|
2024-01-07 06:31:22 -06:00
|
|
|
#include <QRegularExpression>
|
2015-07-29 07:19:43 -05:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
namespace caf
|
|
|
|
{
|
2020-02-14 08:38:19 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
///
|
2020-02-14 08:38:19 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QString rootIdentifierString()
|
|
|
|
{
|
|
|
|
return "$ROOT$";
|
|
|
|
}
|
|
|
|
|
2015-07-29 07:19:43 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
///
|
2015-07-29 07:19:43 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
QString PdmReferenceHelper::referenceFromRootToObject( PdmObjectHandle* root, PdmObjectHandle* obj )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( obj == nullptr || root == nullptr ) return QString();
|
2015-10-06 08:03:55 -05:00
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
QStringList objectNames = referenceFromRootToObjectAsStringList( root, obj );
|
|
|
|
|
|
|
|
QString completeReference = objectNames.join( " " );
|
2015-07-29 07:19:43 -05:00
|
|
|
return completeReference;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
///
|
2015-07-29 07:19:43 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
QString PdmReferenceHelper::referenceFromRootToField( PdmObjectHandle* root, PdmFieldHandle* field )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( field == nullptr || root == nullptr ) return QString();
|
2015-07-29 07:19:43 -05:00
|
|
|
|
|
|
|
PdmObjectHandle* owner = field->ownerObject();
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( !owner ) return QString(); // Should be assert ?
|
2015-07-29 07:19:43 -05:00
|
|
|
|
|
|
|
QStringList refFromRootToField;
|
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
refFromRootToField = referenceFromRootToObjectAsStringList( root, owner );
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
refFromRootToField.push_front( field->keyword() );
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
QString completeReference = refFromRootToField.join( " " );
|
2015-07-29 07:19:43 -05:00
|
|
|
return completeReference;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
///
|
2015-07-29 07:19:43 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
PdmObjectHandle* PdmReferenceHelper::objectFromReference( PdmObjectHandle* root, const QString& reference )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
QStringList decodedReference = reference.split( " " );
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
return objectFromReferenceStringList( root, decodedReference );
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
///
|
2015-07-29 07:19:43 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
QStringList PdmReferenceHelper::referenceFromRootToObjectAsStringList( PdmObjectHandle* root, PdmObjectHandle* obj )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
|
|
|
QStringList objectNames;
|
2020-06-19 00:53:59 -05:00
|
|
|
|
|
|
|
if ( obj != nullptr && root )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( obj == root ) return objectNames;
|
2015-07-29 07:19:43 -05:00
|
|
|
|
|
|
|
PdmObjectHandle* currentObject = obj;
|
|
|
|
|
|
|
|
bool continueParsing = true;
|
2020-06-19 00:53:59 -05:00
|
|
|
while ( continueParsing )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
|
|
|
caf::PdmFieldHandle* parentField = currentObject->parentField();
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( !parentField )
|
2015-10-06 08:03:55 -05:00
|
|
|
{
|
|
|
|
// Could not find a path from obj to root, obj and root are unrelated objects
|
|
|
|
return QStringList();
|
|
|
|
}
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2023-05-12 14:41:34 -05:00
|
|
|
std::vector<PdmObjectHandle*> childObjects = parentField->children();
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2023-05-12 14:41:34 -05:00
|
|
|
if ( !childObjects.empty() )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
|
|
|
int index = -1;
|
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
for ( size_t i = 0; i < childObjects.size(); i++ )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( childObjects[i] == currentObject )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
index = static_cast<int>( i );
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
objectNames.push_front( QString::number( index ) );
|
|
|
|
objectNames.push_front( parentField->keyword() );
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
continueParsing = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
PdmObjectHandle* ownerObject = parentField->ownerObject();
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( !ownerObject )
|
2015-10-06 08:03:55 -05:00
|
|
|
{
|
|
|
|
// Could not find a path from obj to root, obj and root are unrelated objects
|
|
|
|
return QStringList();
|
|
|
|
}
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( ownerObject == root )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
|
|
|
continueParsing = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
currentObject = ownerObject;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return objectNames;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
///
|
2015-07-29 07:19:43 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
PdmFieldHandle* PdmReferenceHelper::fieldFromReference( PdmObjectHandle* root, const QString& reference )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
QStringList decodedReference = reference.split( " " );
|
2023-09-25 06:44:35 -05:00
|
|
|
if ( decodedReference.empty() ) return nullptr;
|
2015-07-29 07:19:43 -05:00
|
|
|
|
|
|
|
QString fieldKeyword = decodedReference[0];
|
|
|
|
decodedReference.pop_front();
|
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
PdmObjectHandle* parentObject = objectFromReferenceStringList( root, decodedReference );
|
2024-10-21 07:08:15 -05:00
|
|
|
if ( !parentObject ) return nullptr;
|
|
|
|
|
|
|
|
return parentObject->findField( fieldKeyword );
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
///
|
2015-07-29 07:19:43 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
PdmObjectHandle* PdmReferenceHelper::objectFromReferenceStringList( PdmObjectHandle* root, const QStringList& reference )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( !root ) return nullptr;
|
2015-10-06 08:03:55 -05:00
|
|
|
|
2015-07-29 07:19:43 -05:00
|
|
|
PdmObjectHandle* currentObject = root;
|
|
|
|
|
|
|
|
int i = 0;
|
2020-06-19 00:53:59 -05:00
|
|
|
while ( i < reference.size() )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2024-10-21 07:08:15 -05:00
|
|
|
if ( !currentObject ) return nullptr;
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2024-10-21 07:08:15 -05:00
|
|
|
QString fieldKeyword = reference.at( i++ );
|
|
|
|
auto fieldHandle = currentObject->findField( fieldKeyword );
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( !fieldHandle )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2018-02-18 11:05:08 -06:00
|
|
|
return nullptr;
|
2015-10-06 08:03:55 -05:00
|
|
|
}
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2023-05-12 14:41:34 -05:00
|
|
|
std::vector<PdmObjectHandle*> childObjects = fieldHandle->children();
|
|
|
|
if ( childObjects.empty() )
|
2015-10-06 08:03:55 -05:00
|
|
|
{
|
2018-02-18 11:05:08 -06:00
|
|
|
return nullptr;
|
2015-10-06 08:03:55 -05:00
|
|
|
}
|
2015-09-18 11:49:27 -05:00
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
QString fieldIndex = reference.at( i++ );
|
|
|
|
bool conversionOk = true;
|
|
|
|
int index = fieldIndex.toInt( &conversionOk );
|
|
|
|
if ( !conversionOk )
|
2015-10-06 08:03:55 -05:00
|
|
|
{
|
2018-02-18 11:05:08 -06:00
|
|
|
return nullptr;
|
2015-10-06 08:03:55 -05:00
|
|
|
}
|
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( index < 0 || index > ( (int)childObjects.size() ) - 1 )
|
2015-10-06 08:03:55 -05:00
|
|
|
{
|
2018-02-18 11:05:08 -06:00
|
|
|
return nullptr;
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
2015-10-06 08:03:55 -05:00
|
|
|
|
|
|
|
currentObject = childObjects[index];
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return currentObject;
|
|
|
|
}
|
|
|
|
|
2015-10-06 08:03:55 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
///
|
2015-10-06 08:03:55 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
std::vector<PdmObjectHandle*> findPathToObjectFromRoot( PdmObjectHandle* obj )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
|
|
|
std::vector<PdmObjectHandle*> objPath;
|
2020-06-19 00:53:59 -05:00
|
|
|
PdmObjectHandle* currentObj = obj;
|
|
|
|
while ( currentObj )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
objPath.push_back( currentObj );
|
|
|
|
if ( currentObj->parentField() )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
|
|
|
currentObj = currentObj->parentField()->ownerObject();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-18 11:05:08 -06:00
|
|
|
currentObj = nullptr;
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
std::reverse( objPath.begin(), objPath.end() );
|
2015-07-29 07:19:43 -05:00
|
|
|
|
|
|
|
return objPath;
|
|
|
|
}
|
|
|
|
|
2015-10-06 08:03:55 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
///
|
2015-10-06 08:03:55 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
QString PdmReferenceHelper::referenceFromFieldToObject( PdmFieldHandle* fromField, PdmObjectHandle* toObj )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( !fromField || !toObj ) return "";
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
PdmObjectHandle* fromObj = fromField->ownerObject();
|
|
|
|
if ( !fromObj ) return "";
|
2015-10-06 08:03:55 -05:00
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
std::vector<PdmObjectHandle*> fromObjPath = findPathToObjectFromRoot( fromObj );
|
|
|
|
std::vector<PdmObjectHandle*> toObjPath = findPathToObjectFromRoot( toObj );
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
// Make sure the objects actually have at least one common ancestor
|
|
|
|
if ( fromObjPath.front() != toObjPath.front() ) return nullptr;
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
bool anchestorIsEqual = true;
|
|
|
|
size_t idxToLastCommonAnchestor = 0;
|
|
|
|
while ( anchestorIsEqual )
|
|
|
|
{
|
2015-07-29 07:19:43 -05:00
|
|
|
++idxToLastCommonAnchestor;
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( idxToLastCommonAnchestor >= fromObjPath.size() || idxToLastCommonAnchestor >= toObjPath.size() ||
|
|
|
|
fromObjPath[idxToLastCommonAnchestor] != toObjPath[idxToLastCommonAnchestor] )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
|
|
|
anchestorIsEqual = false;
|
|
|
|
idxToLastCommonAnchestor -= 1;
|
|
|
|
}
|
2020-06-19 00:53:59 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t levelCountToCommonAnchestor = ( fromObjPath.size() - 1 ) - idxToLastCommonAnchestor;
|
|
|
|
|
|
|
|
PdmObjectHandle* lastCommonAnchestor = fromObjPath[idxToLastCommonAnchestor];
|
|
|
|
|
|
|
|
QStringList referenceList = referenceFromRootToObjectAsStringList( lastCommonAnchestor, toObj );
|
|
|
|
|
|
|
|
if ( idxToLastCommonAnchestor == 0 )
|
|
|
|
{
|
|
|
|
referenceList.push_front( rootIdentifierString() );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for ( size_t i = 0; i < levelCountToCommonAnchestor; ++i )
|
|
|
|
{
|
|
|
|
referenceList.push_front( ".." );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QString completeReference = referenceList.join( " " );
|
|
|
|
|
|
|
|
return completeReference;
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
|
|
|
|
2015-10-06 08:03:55 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
///
|
2015-10-06 08:03:55 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
PdmObjectHandle* PdmReferenceHelper::objectFromFieldReference( PdmFieldHandle* fromField, const QString& reference )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( !fromField ) return nullptr;
|
|
|
|
if ( reference.isEmpty() ) return nullptr;
|
|
|
|
if ( reference.trimmed().isEmpty() ) return nullptr;
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2024-10-28 07:09:18 -05:00
|
|
|
QStringList decodedReference = reference.split( QRegularExpression( "\\s+" ), Qt::SkipEmptyParts );
|
2015-07-29 07:19:43 -05:00
|
|
|
PdmObjectHandle* lastCommonAnchestor = fromField->ownerObject();
|
2020-06-19 00:53:59 -05:00
|
|
|
CAF_ASSERT( lastCommonAnchestor );
|
|
|
|
|
|
|
|
if ( !decodedReference.empty() && decodedReference.front() == rootIdentifierString() )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
lastCommonAnchestor = findRoot( lastCommonAnchestor );
|
2020-02-14 08:38:19 -06:00
|
|
|
decodedReference.pop_front();
|
|
|
|
}
|
|
|
|
else
|
2020-06-19 00:53:59 -05:00
|
|
|
{
|
|
|
|
while ( !decodedReference.empty() && decodedReference.front() == ".." )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-02-14 08:38:19 -06:00
|
|
|
PdmFieldHandle* parentField = lastCommonAnchestor->parentField();
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( !parentField )
|
2020-02-14 08:38:19 -06:00
|
|
|
{
|
|
|
|
// Error: Relative object reference has an invalid number of parent levels
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2020-02-14 08:38:19 -06:00
|
|
|
lastCommonAnchestor = parentField->ownerObject();
|
2020-06-19 00:53:59 -05:00
|
|
|
CAF_ASSERT( lastCommonAnchestor );
|
2020-02-14 08:38:19 -06:00
|
|
|
decodedReference.pop_front();
|
|
|
|
}
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
|
|
|
|
2020-06-19 00:53:59 -05:00
|
|
|
return objectFromReferenceStringList( lastCommonAnchestor, decodedReference );
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
///
|
2015-07-29 07:19:43 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
PdmObjectHandle* PdmReferenceHelper::findRoot( PdmObjectHandle* obj )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
std::vector<PdmObjectHandle*> path = findPathToObjectFromRoot( obj );
|
2015-07-29 07:19:43 -05:00
|
|
|
|
2023-09-25 06:44:35 -05:00
|
|
|
if ( !path.empty() )
|
2020-06-19 00:53:59 -05:00
|
|
|
return path[0];
|
|
|
|
else
|
|
|
|
return nullptr;
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
///
|
2015-07-29 07:19:43 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-06-19 00:53:59 -05:00
|
|
|
PdmObjectHandle* PdmReferenceHelper::findRoot( PdmFieldHandle* field )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
2020-06-19 00:53:59 -05:00
|
|
|
if ( field )
|
2015-07-29 07:19:43 -05:00
|
|
|
{
|
|
|
|
PdmObjectHandle* ownerObject = field->ownerObject();
|
2020-06-19 00:53:59 -05:00
|
|
|
return findRoot( ownerObject );
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
2020-06-19 00:53:59 -05:00
|
|
|
|
2018-02-18 11:05:08 -06:00
|
|
|
return nullptr;
|
2015-07-29 07:19:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
} // end namespace caf
|