#14401 Introduce initAfterInsert() to combine resolveReferencesRecursively() and initAfterReadRecursively()

This commit is contained in:
Magne Sjaastad committed 2026-08-03 15:34:10 +02:00
1 parent e001c8fefa
commit 9ccca3e20a
19 files changed
+80 -64

No files matched your search

@@ -165,9 +165,7 @@ void RicAdvancedSnapshotExportFeature::exportMultipleSnapshots( const QString& f
copyOfGeoMechView->setGeoMechCase( geomCase );
// Resolve references after reservoir view has been inserted into Rim structures
copyOfGeoMechView->resolveReferencesRecursively();
copyOfGeoMechView->initAfterReadRecursively();
copyOfGeoMechView->initAfterInsert();
copyOfGeoMechView->loadDataAndUpdate();
@@ -61,8 +61,7 @@ void RicPasteGridCrossPlotDataSetFeature::onActionTriggered( bool isChecked )
{
auto newDataSet = dataSet->copyObject<RimGridCrossPlotDataSet>();
crossPlot->addDataSet( newDataSet );
newDataSet->resolveReferencesRecursively();
newDataSet->initAfterReadRecursively();
newDataSet->initAfterInsert();
objectToSelect = newDataSet;
}
@@ -112,10 +112,8 @@ void RicPasteEclipseViewsFeature::onActionTriggered( bool isChecked )
rimReservoirView->setEclipseCase( eclipseCase );
// Resolve references after reservoir view has been inserted into Rim structures
// Intersections referencing a well path/ simulation well requires this
rimReservoirView->resolveReferencesRecursively();
rimReservoirView->initAfterReadRecursively();
// Intersections referencing a well path/ simulation well requires resolving after insert
rimReservoirView->initAfterInsert();
eclipseCase->intersectionViewCollection()->syncFromExistingIntersections( false );
rimReservoirView->loadDataAndUpdate();
@@ -88,10 +88,8 @@ void RicPasteGeoMechViewsFeature::onActionTriggered( bool isChecked )
rimReservoirView->setGeoMechCase( geomCase );
// Resolve references after reservoir view has been inserted into Rim structures
// Intersections referencing a well path requires this
rimReservoirView->resolveReferencesRecursively();
rimReservoirView->initAfterReadRecursively();
// Intersections referencing a well path requires resolving after insert
rimReservoirView->initAfterInsert();
caf::PdmDocument::updateUiIconStateRecursively( rimReservoirView );
@@ -88,8 +88,7 @@ void RicDeleteItemExec::undo()
listField->insertAt( m_commandData.m_indexToObject, obj );
obj->xmlCapability()->initAfterReadRecursively();
obj->xmlCapability()->resolveReferencesRecursively();
obj->xmlCapability()->initAfterInsert();
listField->uiCapability()->updateConnectedEditors();
listField->ownerObject()->uiCapability()->updateConnectedEditors();
@@ -225,9 +225,7 @@ RimEclipseContourMapView*
contourMap->setName( QString( "Contour Map %1" ).arg( i + 1 ) );
eclipseCase->contourMapCollection()->addView( contourMap );
// Resolve references after contour map has been inserted into Rim structures
contourMap->resolveReferencesRecursively();
contourMap->initAfterReadRecursively();
contourMap->initAfterInsert();
return contourMap;
}
@@ -269,9 +267,7 @@ RimEclipseContourMapView* RicNewContourMapViewFeature::createEclipseContourMapFr
contourMap->synchronizeLocalAnnotationsFromGlobal();
// Resolve references after contour map has been inserted into Rim structures
contourMap->resolveReferencesRecursively();
contourMap->initAfterReadRecursively();
contourMap->initAfterInsert();
eclipseCase->contourMapCollection()->updateConnectedEditors();
@@ -330,9 +326,7 @@ RimEclipseContourMapView* RicNewContourMapViewFeature::createEclipseContourMap(
auto col = RiuGuiTheme::getColorByVariableName( "backgroundColor2" );
contourMap->setBackgroundColor( RiaColorTools::fromQColorTo3f( col ) ); // Ignore original view background
// Resolve references after contour map has been inserted into Rim structures
contourMap->resolveReferencesRecursively();
contourMap->initAfterReadRecursively();
contourMap->initAfterInsert();
return contourMap;
}
@@ -358,9 +352,7 @@ RimGeoMechContourMapView*
contourMap->setName( QString( "Contour Map %1" ).arg( i + 1 ) );
geoMechCase->contourMapCollection()->addView( contourMap );
// Resolve references after contour map has been inserted into Rim structures
contourMap->resolveReferencesRecursively();
contourMap->initAfterReadRecursively();
contourMap->initAfterInsert();
return contourMap;
}
@@ -390,9 +382,7 @@ RimGeoMechContourMapView* RicNewContourMapViewFeature::createGeoMechContourMapFr
geoMechCase->contourMapCollection()->addView( contourMap );
// Resolve references after contour map has been inserted into Rim structures
contourMap->resolveReferencesRecursively();
contourMap->initAfterReadRecursively();
contourMap->initAfterInsert();
return contourMap;
}
@@ -415,9 +405,7 @@ RimGeoMechContourMapView* RicNewContourMapViewFeature::createGeoMechContourMap(
auto col = RiuGuiTheme::getColorByVariableName( "backgroundColor2" );
contourMap->setBackgroundColor( RiaColorTools::fromQColorTo3f( col ) ); // Ignore original view background
// Resolve references after contour map has been inserted into Rim structures
contourMap->resolveReferencesRecursively();
contourMap->initAfterReadRecursively();
contourMap->initAfterInsert();
return contourMap;
}
@@ -69,9 +69,7 @@ void RicDuplicateSummaryTableFeature::copyTableAndAddToCollection( RimSummaryTab
// Add table to collection
summaryTableColl->addTable( newSummaryTable );
// Resolve references after object has been inserted into the data model
newSummaryTable->resolveReferencesRecursively();
newSummaryTable->initAfterReadRecursively();
newSummaryTable->initAfterInsert();
// Update name
QString nameOfCopy = QString( "Copy of " ) + sourceTable->description();
@@ -69,15 +69,12 @@ void RicPasteAsciiDataCurveFeature::onActionTriggered( bool isChecked )
summaryPlot->addAsciiDataCruve( newObject );
// Resolve references after object has been inserted into the project data model
newObject->resolveReferencesRecursively();
newObject->initAfterInsert();
// If source curve is part of a curve filter, resolve of references to the summary case does not
// work when pasting the new curve into a plot. Must set summary case manually.
// newObject->setSummaryCase(sourceObjects[i]->summaryCase());
newObject->initAfterReadRecursively();
newObject->loadDataAndUpdate( true );
newObject->updateConnectedEditors();
@@ -50,9 +50,7 @@ RimEnsembleCurveSet* RicPasteEnsembleCurveSetFeature::copyCurveSetAndAddToCollec
curveSetCollection->addCurveSet( newCurveSet );
// Resolve references after object has been inserted into the project data model
newCurveSet->resolveReferencesRecursively();
newCurveSet->initAfterReadRecursively();
newCurveSet->initAfterInsert();
newCurveSet->loadDataAndUpdate( false );
newCurveSet->updateConnectedEditors();
@@ -77,15 +77,12 @@ void RicPasteTimeHistoryCurveFeature::onActionTriggered( bool isChecked )
summaryPlot->addGridTimeHistoryCurve( newObject );
// Resolve references after object has been inserted into the project data model
newObject->resolveReferencesRecursively();
newObject->initAfterInsert();
// If source curve is part of a curve filter, resolve of references to the summary case does not
// work when pasting the new curve into a plot. Must set summary case manually.
// newObject->setSummaryCase(sourceObjects[i]->summaryCase());
newObject->initAfterReadRecursively();
newObject->loadDataAndUpdate( true );
newObject->updateConnectedEditors();
@@ -110,9 +110,7 @@ void RicPasteWellLogCurveFeature::onActionTriggered( bool isChecked )
wellLogTrack->addCurve( newObject );
// Resolve references after object has been inserted into the project data model
newObject->resolveReferencesRecursively();
newObject->initAfterReadRecursively();
newObject->initAfterInsert();
newObject->loadDataAndUpdate( true );
@@ -78,9 +78,7 @@ void RicPasteWellLogPlotFeature::onActionTriggered( bool isChecked )
newObject->resetDockWindowId();
wellLogPlotCollection->addWellLogPlot( newObject );
// Resolve references after object has been inserted into the project data model
newObject->resolveReferencesRecursively();
newObject->initAfterReadRecursively();
newObject->initAfterInsert();
QString customName = "Copy of " + newObject->nameConfig()->customName();
newObject->nameConfig()->setCustomName( customName );
@@ -80,9 +80,7 @@ void RicPasteWellLogTrackFeature::onActionTriggered( bool isChecked )
newObject->setDescription( QString( "Track %1" ).arg( wellLogPlot->plotCount() ) );
// Resolve references after object has been inserted into the project data model
newObject->resolveReferencesRecursively();
newObject->initAfterReadRecursively();
newObject->initAfterInsert();
newObject->loadDataAndUpdate();
@@ -251,9 +251,7 @@ RimGeoMechView* RimGeoMechCase::createCopyAndAddView( const RimGeoMechView* sour
geoMechViews.push_back( rimGeoMechView );
// Resolve references after reservoir view has been inserted into Rim structures
rimGeoMechView->resolveReferencesRecursively();
rimGeoMechView->initAfterReadRecursively();
rimGeoMechView->initAfterInsert();
return rimGeoMechView;
}
@@ -410,9 +410,7 @@ RimEclipseView* RimEclipseCase::createCopyAndAddView( const RimEclipseView* sour
viewColl->addView( rimEclipseView );
// Resolve references after reservoir view has been inserted into Rim structures
rimEclipseView->resolveReferencesRecursively();
rimEclipseView->initAfterReadRecursively();
rimEclipseView->initAfterInsert();
return rimEclipseView;
}
@@ -210,8 +210,7 @@ RimSummaryMultiPlot* RimSummaryMultiPlotCollection::duplicatePlot( RimSummaryMul
plotCopy->resetDockWindowId();
addSummaryMultiPlot( plotCopy );
plotCopy->resolveReferencesRecursively();
plotCopy->initAfterReadRecursively();
plotCopy->initAfterInsert();
plotCopy->updateAllRequiredEditors();
plotCopy->loadDataAndUpdate();
@@ -501,6 +501,20 @@ void PdmXmlObjectHandle::resolveReferencesRecursively(
}
}
//--------------------------------------------------------------------------------------------------
/// Call after the object has been inserted into the document tree, typically after a copy by XML
/// serialization. Resolves pointer references (which requires the object to be reachable from the
/// document root) and then re-runs initAfterRead() so overrides can use the resolved pointers.
//--------------------------------------------------------------------------------------------------
void PdmXmlObjectHandle::initAfterInsert()
{
// The object must be inserted into the document tree before references can be resolved
CAF_ASSERT( m_owner && m_owner->parentField() );
resolveReferencesRecursively();
initAfterReadRecursively();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -62,6 +62,11 @@ public:
// resolving might fail. The object needs to be fully inserted into the document before resolving references.
void resolveReferencesRecursively( std::vector<PdmFieldHandle*>* fieldWithFailingResolve = nullptr );
// Call after the object has been inserted into the document tree, typically after a copy by XML serialization.
// Resolves pointer references (which requires the object to be reachable from the document root) and then
// re-runs initAfterRead() so overrides can use the resolved pointers.
void initAfterInsert();
bool inheritsClassWithKeyword( const QString& testClassKeyword ) const;
const std::list<QString>& classInheritanceStack() const;
@@ -110,6 +110,9 @@ public:
return m_doubleMember;
}
double m_doubleMember;
void initAfterRead() override { m_initAfterReadCount++; }
int m_initAfterReadCount = 0;
};
CAF_PDM_XML_SOURCE_INIT( DemoPdmObjectA, "DemoPdmObjectA" );
@@ -268,3 +271,38 @@ TEST( AdvancedObjectTest, CopyOfObjects )
}
}
}
//--------------------------------------------------------------------------------------------------
/// initAfterInsert() resolves references and re-runs initAfterRead() after the object has been
/// inserted into the document tree
//--------------------------------------------------------------------------------------------------
TEST( AdvancedObjectTest, InitAfterInsert )
{
ContainerPdmObject* root = new ContainerPdmObject;
ContainerPdmObject* container = new ContainerPdmObject;
ContainerPdmObject* sibling = new ContainerPdmObject;
root->m_containers.push_back( container );
root->m_containers.push_back( sibling );
ItemPdmObject* item = new ItemPdmObject();
item->m_name = "Obj A";
container->m_items.push_back( item );
DemoPdmObjectA* a = new DemoPdmObjectA;
sibling->m_demoObjs.push_back( a );
a->m_pointerToItem = item;
auto* objCopy = dynamic_cast<DemoPdmObjectA*>(
a->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) );
ASSERT_TRUE( objCopy != nullptr );
// The pointer field is not resolvable until the copy is inserted into the document tree
objCopy->m_pointerToItem = nullptr;
sibling->m_demoObjs.push_back( objCopy );
const int initCountBeforeInsert = objCopy->m_initAfterReadCount;
objCopy->xmlCapability()->initAfterInsert();
ASSERT_TRUE( objCopy->m_pointerToItem() == item );
ASSERT_EQ( initCountBeforeInsert + 1, objCopy->m_initAfterReadCount );
}