///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2019- Equinor ASA // // ResInsight 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. // // ResInsight 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 // for more details. // ////////////////////////////////////////////////////////////////////////////////// #include "RiaGrpcServiceInterface.h" #include "RiaLogging.h" #include "RimProject.h" #include "cafPdmAbstractFieldScriptingCapability.h" #include "cafPdmChildArrayField.h" #include "cafPdmChildField.h" #include "cafPdmDataValueField.h" #include "cafPdmObject.h" #include "cafPdmObjectScriptingCapability.h" #include "cafPdmObjectScriptingCapabilityRegister.h" #include "cafPdmProxyValueField.h" #include "cafPdmScriptIOMessages.h" #include "cafPdmXmlFieldHandle.h" #include #include #include #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiaGrpcServiceInterface::copyPdmObjectFromCafToRips( const caf::PdmObjectHandle* source, rips::PdmObject* destination ) { CAF_ASSERT( source && destination && source->xmlCapability() ); QString classKeyword = source->xmlCapability()->classKeyword(); QString scriptClassName; // Find first scriptable object in inheritance stack { auto pdmObject = dynamic_cast( source ); auto classKeywordStack = pdmObject->classInheritanceStack(); // Reverse to get leaf node first classKeywordStack.reverse(); for ( const auto& candidateClassKeyword : classKeywordStack ) { if ( caf::PdmObjectScriptingCapabilityRegister::isScriptable( candidateClassKeyword ) ) { scriptClassName = caf::PdmObjectScriptingCapabilityRegister::scriptClassNameFromClassKeyword( candidateClassKeyword ); break; } } // Fallback to source object class name if ( scriptClassName.isEmpty() ) scriptClassName = classKeyword; } destination->set_class_keyword( scriptClassName.toStdString() ); destination->set_address( reinterpret_cast( source ) ); bool visible = true; if ( source->uiCapability() && source->uiCapability()->objectToggleField() ) { const auto* boolField = dynamic_cast*>( source->uiCapability()->objectToggleField() ); if ( boolField ) { visible = boolField->value(); } } destination->set_visible( visible ); std::vector fields = source->fields(); auto parametersMap = destination->mutable_parameters(); for ( auto field : fields ) { auto pdmValueField = dynamic_cast( field ); if ( pdmValueField ) { QString keyword = pdmValueField->keyword(); auto ricfHandle = field->template capability(); if ( ricfHandle != nullptr ) { auto pdmProxyField = dynamic_cast( field ); if ( !( pdmProxyField && pdmProxyField->isStreamingField() ) ) { QString text; QTextStream outStream( &text ); ricfHandle->readFromField( outStream, false ); ( *parametersMap )[ricfHandle->scriptFieldName().toStdString()] = text.toStdString(); } } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiaGrpcServiceInterface::copyPdmObjectFromRipsToCaf( const rips::PdmObject* source, caf::PdmObjectHandle* destination ) { CAF_ASSERT( source && destination && destination->xmlCapability() ); if ( destination->uiCapability() && destination->uiCapability()->objectToggleField() ) { auto* boolField = dynamic_cast*>( destination->uiCapability()->objectToggleField() ); if ( boolField ) { QVariant oldValue = boolField->toQVariant(); boolField->setValue( source->visible() ); QVariant newValue = boolField->toQVariant(); destination->uiCapability()->fieldChangedByUi( boolField, oldValue, newValue ); } } std::vector fields = destination->fields(); auto parametersMap = source->parameters(); bool printContent = false; // Flag to control debug output to debugger if ( printContent ) { for ( const auto& p : parametersMap ) { qDebug() << QString::fromStdString( p.first ) << " : " << QString::fromStdString( p.second ); } } caf::PdmScriptIOMessages messages; for ( auto field : fields ) { auto scriptability = field->template capability(); if ( scriptability ) { bool isPdmPtrArrayField = ( dynamic_cast( field ) && !dynamic_cast( field ) ); if ( !isPdmPtrArrayField && !dynamic_cast( field ) ) { // Update of child objects and child object arrays are not supported // Update of PdmPtrArrayField is supported, used by RimcSummaryPlotCollection_newSummaryPlot // https://github.com/OPM/ResInsight/issues/7794 continue; } QString keyword = scriptability->scriptFieldName(); QString value = QString::fromStdString( parametersMap[keyword.toStdString()] ); QVariant oldValue, newValue; messages.currentCommand = "Assign value to field " + keyword; messages.currentArgument = value; if ( assignFieldValue( value, field, &oldValue, &newValue, &messages ) ) { destination->uiCapability()->fieldChangedByUi( field, oldValue, newValue ); } } } for ( const auto message : messages.m_messages ) { RiaLogging::error( message.second ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RiaGrpcServiceInterface::assignFieldValue( const QString& stringValue, caf::PdmFieldHandle* field, QVariant* oldValue, QVariant* newValue, caf::PdmScriptIOMessages* messages ) { CAF_ASSERT( oldValue && newValue ); auto scriptability = field->template capability(); if ( field && scriptability != nullptr && scriptability->isIOWriteable() ) { auto* valueField = dynamic_cast( field ); QTextStream stream( stringValue.toLatin1() ); if ( valueField ) *oldValue = valueField->toQVariant(); scriptability->writeToField( stream, nullptr, messages, false, RimProject::current() ); if ( valueField ) *newValue = valueField->toQVariant(); return true; } return false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmObject* parent, const QString& fieldKeyword, const QString& keywordForClassToCreate ) { std::vector fields = parent->fields(); for ( auto field : fields ) { auto pdmChildArrayField = dynamic_cast( field ); auto pdmChildField = dynamic_cast( field ); if ( pdmChildArrayField ) { bool isMatching = false; if ( fieldKeyword.isEmpty() ) { // Use first child array field if no fieldKeyword is specified isMatching = true; } else { isMatching = ( pdmChildArrayField->keyword() == fieldKeyword ); } if ( isMatching ) { auto objectCreated = emplaceChildArrayField( pdmChildArrayField, keywordForClassToCreate ); // Notify parent object that a new object has been created if ( objectCreated ) parent->onChildAdded( pdmChildArrayField ); return objectCreated; } } else if ( pdmChildField && pdmChildField->keyword() == fieldKeyword ) { return emplaceChildField( pdmChildField, keywordForClassToCreate ); } } return nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmChildFieldHandle* childField, const QString& keywordForClassToCreate ) { QString childClassKeyword; if ( keywordForClassToCreate.isEmpty() ) { childClassKeyword = childField->xmlCapability()->dataTypeName(); } else { childClassKeyword = keywordForClassToCreate; } auto pdmObjectHandle = caf::PdmDefaultObjectFactory::instance()->create( childClassKeyword ); CAF_ASSERT( pdmObjectHandle ); { auto childDataTypeName = childField->xmlCapability()->dataTypeName(); auto isInheritanceValid = pdmObjectHandle->xmlCapability()->inheritsClassWithKeyword( childDataTypeName ); if ( !isInheritanceValid ) { delete pdmObjectHandle; return nullptr; } } childField->setChildObject( pdmObjectHandle ); return pdmObjectHandle; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildArrayField( caf::PdmChildArrayFieldHandle* childArrayField, const QString& keywordForClassToCreate ) { QString childClassKeyword; if ( keywordForClassToCreate.isEmpty() ) { childClassKeyword = childArrayField->xmlCapability()->dataTypeName(); } else { childClassKeyword = keywordForClassToCreate; } auto pdmObjectHandle = caf::PdmDefaultObjectFactory::instance()->create( childClassKeyword ); if ( !pdmObjectHandle ) return nullptr; { auto childDataTypeName = childArrayField->xmlCapability()->dataTypeName(); auto isInheritanceValid = pdmObjectHandle->xmlCapability()->inheritsClassWithKeyword( childDataTypeName ); if ( !isInheritanceValid ) { delete pdmObjectHandle; return nullptr; } } childArrayField->insertAt( -1, pdmObjectHandle ); return pdmObjectHandle; }