diff --git a/ApplicationLibCode/Application/RiaApplication.cpp b/ApplicationLibCode/Application/RiaApplication.cpp index 493572af43..53619538b0 100644 --- a/ApplicationLibCode/Application/RiaApplication.cpp +++ b/ApplicationLibCode/Application/RiaApplication.cpp @@ -1555,7 +1555,9 @@ bool RiaApplication::generateCode( const QString& fileName, gsl::not_nullgenerate( caf::PdmDefaultObjectFactory::instance() ); + std::vector logMessages; + + out << generator->generate( caf::PdmDefaultObjectFactory::instance(), logMessages ); } { @@ -1613,7 +1615,22 @@ bool RiaApplication::generateCode( const QString& fileName, gsl::not_nullgenerate( caf::PdmDefaultObjectFactory::instance() ); + std::vector logMessages; + + out << generator->generate( caf::PdmDefaultObjectFactory::instance(), logMessages ); + + QString errorText; + for ( const auto& msg : logMessages ) + { + errorText += msg; + errorText += "\n"; + } + + if ( !errorText.isEmpty() ) + { + *errMsg = errorText; + return false; + } } return true; diff --git a/ApplicationLibCode/Application/RiaGuiApplication.cpp b/ApplicationLibCode/Application/RiaGuiApplication.cpp index 287f19f2a2..2df91a9845 100644 --- a/ApplicationLibCode/Application/RiaGuiApplication.cpp +++ b/ApplicationLibCode/Application/RiaGuiApplication.cpp @@ -453,7 +453,7 @@ RiaApplication::ApplicationStatus RiaGuiApplication::handleArguments( gsl::not_n if ( !RiaApplication::generateCode( outputFile, &errMsg ) ) { RiaLogging::error( QString( "Error: %1" ).arg( errMsg ) ); - return RiaApplication::ApplicationStatus::EXIT_WITH_ERROR; + return RiaApplication::ApplicationStatus::KEEP_GOING; } return RiaApplication::ApplicationStatus::EXIT_COMPLETED; diff --git a/ApplicationLibCode/Commands/RicImportFormationNamesFeature.cpp b/ApplicationLibCode/Commands/RicImportFormationNamesFeature.cpp index 6ee33db26b..c4916cb28a 100644 --- a/ApplicationLibCode/Commands/RicImportFormationNamesFeature.cpp +++ b/ApplicationLibCode/Commands/RicImportFormationNamesFeature.cpp @@ -89,7 +89,9 @@ RimFormationNames* RicImportFormationNamesFeature::importFormationFiles( const Q } } - return formationNames.back(); + if ( !formationNames.empty() ) return formationNames.back(); + + return nullptr; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.cpp b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.cpp index 40759a2580..f4b1dd7fad 100644 --- a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.cpp @@ -44,7 +44,7 @@ RimCellFilterCollection::RimCellFilterCollection() CAF_PDM_InitScriptableField( &m_isActive, "Active", true, "Active", "", "", "" ); m_isActive.uiCapability()->setUiHidden( true ); - CAF_PDM_InitScriptableFieldNoDefault( &m_cellFilters, "CellFilters", "Filters", "", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_cellFilters, "CellFilters", "Filters", "", "", "" ); m_cellFilters.uiCapability()->setUiTreeHidden( true ); caf::PdmFieldReorderCapability::addToField( &m_cellFilters ); diff --git a/ApplicationLibCode/ProjectDataModel/RimEnsembleFractureStatisticsPlotCollection.cpp b/ApplicationLibCode/ProjectDataModel/RimEnsembleFractureStatisticsPlotCollection.cpp index df2823f6d3..949ec056f2 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEnsembleFractureStatisticsPlotCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEnsembleFractureStatisticsPlotCollection.cpp @@ -30,9 +30,9 @@ CAF_PDM_SOURCE_INIT( RimEnsembleFractureStatisticsPlotCollection, "EnsembleFract //-------------------------------------------------------------------------------------------------- RimEnsembleFractureStatisticsPlotCollection::RimEnsembleFractureStatisticsPlotCollection() { - CAF_PDM_InitScriptableObject( "Ensemble Fracture Statistics Plots", ":/WellLogPlots16x16.png", "", "" ); + CAF_PDM_InitObject( "Ensemble Fracture Statistics Plots", ":/WellLogPlots16x16.png", "", "" ); - CAF_PDM_InitScriptableFieldNoDefault( &m_ensembleFractureStatisticsPlots, "EnsembleFractureStatisticsPlots", "", "", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_ensembleFractureStatisticsPlots, "EnsembleFractureStatisticsPlots", "", "", "", "" ); m_ensembleFractureStatisticsPlots.uiCapability()->setUiHidden( true ); } diff --git a/ApplicationLibCode/ProjectDataModel/RimGridStatisticsPlotCollection.cpp b/ApplicationLibCode/ProjectDataModel/RimGridStatisticsPlotCollection.cpp index b33f58261d..31e7422bc3 100644 --- a/ApplicationLibCode/ProjectDataModel/RimGridStatisticsPlotCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimGridStatisticsPlotCollection.cpp @@ -30,9 +30,9 @@ CAF_PDM_SOURCE_INIT( RimGridStatisticsPlotCollection, "GridStatisticsPlotCollect //-------------------------------------------------------------------------------------------------- RimGridStatisticsPlotCollection::RimGridStatisticsPlotCollection() { - CAF_PDM_InitScriptableObject( "Grid Statistics Plots", ":/WellLogPlots16x16.png", "", "" ); + CAF_PDM_InitObject( "Grid Statistics Plots", ":/WellLogPlots16x16.png", "", "" ); - CAF_PDM_InitScriptableFieldNoDefault( &m_gridStatisticsPlots, "GridStatisticsPlots", "", "", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_gridStatisticsPlots, "GridStatisticsPlots", "", "", "", "" ); m_gridStatisticsPlots.uiCapability()->setUiHidden( true ); } diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathCollection.cpp b/ApplicationLibCode/ProjectDataModel/RimWellPathCollection.cpp index 8879113ba0..f31df93ae2 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimWellPathCollection.cpp @@ -54,6 +54,8 @@ #include "Riu3DMainWindowTools.h" +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmObjectScriptingCapability.h" #include "cafPdmUiEditorHandle.h" #include "cafPdmUiTreeOrdering.h" #include "cafProgressInfo.h" @@ -83,7 +85,12 @@ CAF_PDM_SOURCE_INIT( RimWellPathCollection, "WellPaths" ); //-------------------------------------------------------------------------------------------------- RimWellPathCollection::RimWellPathCollection() { - CAF_PDM_InitObject( "Wells", ":/WellCollection.png", "", "" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "Wells", + ":/WellCollection.png", + "", + "", + "WellPathCollection", + "Collection of Well Paths" ); CAF_PDM_InitField( &isActive, "Active", true, "Active", "", "", "" ); isActive.uiCapability()->setUiHidden( true ); @@ -109,7 +116,7 @@ RimWellPathCollection::RimWellPathCollection() CAF_PDM_InitField( &wellPathClip, "WellPathClip", true, "Clip Well Paths", "", "", "" ); CAF_PDM_InitField( &wellPathClipZDistance, "WellPathClipZDistance", 100, "Well Path Clipping Depth Distance", "", "", "" ); - CAF_PDM_InitFieldNoDefault( &m_wellPaths, "WellPaths", "Well Paths", "", "", "" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_wellPaths, "WellPaths", "Well Paths", "", "", "" ); m_wellPaths.uiCapability()->setUiHidden( true ); m_wellPaths.uiCapability()->setUiTreeHidden( true ); m_wellPaths.uiCapability()->setUiTreeChildrenHidden( true ); @@ -977,3 +984,14 @@ void RimWellPathCollection::onChildDeleted( caf::PdmChildArrayFieldHandle* scheduleRedrawAffectedViews(); uiCapability()->updateConnectedEditors(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCollection::onChildAdded( caf::PdmFieldHandle* containerForNewObject ) +{ + rebuildWellPathNodes(); + + scheduleRedrawAffectedViews(); + uiCapability()->updateConnectedEditors(); +} diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathCollection.h b/ApplicationLibCode/ProjectDataModel/RimWellPathCollection.h index 97964b3500..2f22495b2d 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathCollection.h +++ b/ApplicationLibCode/ProjectDataModel/RimWellPathCollection.h @@ -127,6 +127,8 @@ public: void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray, std::vector& referringObjects ) override; + void onChildAdded( caf::PdmFieldHandle* containerForNewObject ) override; + protected: void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathGroup.cpp b/ApplicationLibCode/ProjectDataModel/RimWellPathGroup.cpp index 081c47fb2a..f1afeb8997 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathGroup.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimWellPathGroup.cpp @@ -25,8 +25,7 @@ #include "RimWellPathCompletions.h" #include "RimWellPathValve.h" -#include "cafPdmFieldScriptingCapability.h" -#include "cafPdmObjectScriptingCapability.h" +#include "cafPdmObject.h" #include "cafPdmUiTreeOrdering.h" #include @@ -38,23 +37,18 @@ CAF_PDM_SOURCE_INIT( RimWellPathGroup, "WellPathGroup" ); //-------------------------------------------------------------------------------------------------- RimWellPathGroup::RimWellPathGroup() { - CAF_PDM_InitScriptableObjectWithNameAndComment( "Well Path Group", - ":/WellPathGroup.svg", - "", - "", - "WellPathGroup", - "A Group of Well Paths" ); - CAF_PDM_InitScriptableFieldNoDefault( &m_childWellPaths, "ChildWellPaths", "Child Well Paths", "", "", "" ); - CAF_PDM_InitScriptableFieldNoDefault( &m_groupName, "GroupName", "Group Name", "", "", "" ); + CAF_PDM_InitObject( "Well Path Group", ":/WellPathGroup.svg", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_childWellPaths, "ChildWellPaths", "Child Well Paths", "", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_groupName, "GroupName", "Group Name", "", "", "" ); - CAF_PDM_InitScriptableField( &m_addValveAtConnection, - "AddValveAtConnection", - false, - "Add Outlet Valve for Branches", - "", - "Should an outlet valve be added to branches for MSW export?", - "" ); - CAF_PDM_InitScriptableFieldNoDefault( &m_valve, "Valve", "Branch Outlet Valve", "", "", "" ); + CAF_PDM_InitField( &m_addValveAtConnection, + "AddValveAtConnection", + false, + "Add Outlet Valve for Branches", + "", + "Should an outlet valve be added to branches for MSW export?", + "" ); + CAF_PDM_InitFieldNoDefault( &m_valve, "Valve", "Branch Outlet Valve", "", "", "" ); m_valve = new RimWellPathValve; m_groupName.registerGetMethod( this, &RimWellPathGroup::createGroupName ); diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathTarget.cpp b/ApplicationLibCode/ProjectDataModel/RimWellPathTarget.cpp index 652a76ff37..97dfb1c189 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathTarget.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimWellPathTarget.cpp @@ -26,6 +26,9 @@ #include "RimWellPath.h" #include "RimWellPathGeometryDef.h" +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmFieldScriptingCapabilityCvfVec3d.h" +#include "cafPdmObjectScriptingCapability.h" #include "cafPdmUiCheckBoxEditor.h" #include "cafPdmUiLineEditor.h" @@ -54,19 +57,26 @@ RimWellPathTarget::RimWellPathTarget() , m_inclination( 0.0 ) , m_isFullUpdateEnabled( true ) { + CAF_PDM_InitScriptableObjectWithNameAndComment( "Well Target", + "", + "", + "", + "WellPathTarget", + "Class containing the Well Target definition" ); + CAF_PDM_InitField( &m_isEnabled, "IsEnabled", true, "", "", "", "" ); CAF_PDM_InitField( &m_isLocked, "IsLocked", false, "", "", "", "" ); m_isLocked.uiCapability()->setUiHidden( true ); // m_targetType.uiCapability()->setUiHidden(true); - CAF_PDM_InitFieldNoDefault( &m_targetPoint, "TargetPoint", "Point", "", "", "" ); - CAF_PDM_InitField( &m_dogleg1, "Dogleg1", 3.0, "DL in", "", "[deg/30m]", "" ); - CAF_PDM_InitField( &m_dogleg2, "Dogleg2", 3.0, "DL out", "", "[deg/30m]", "" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_targetPoint, "TargetPoint", "Point", "", "", "" ); + CAF_PDM_InitScriptableField( &m_dogleg1, "Dogleg1", 3.0, "DL in", "", "[deg/30m]", "" ); + CAF_PDM_InitScriptableField( &m_dogleg2, "Dogleg2", 3.0, "DL out", "", "[deg/30m]", "" ); CAF_PDM_InitFieldNoDefault( &m_targetType, "TargetType", "Type", "", "", "" ); m_targetType.uiCapability()->setUiHidden( true ); CAF_PDM_InitField( &m_hasTangentConstraintUiField, "HasTangentConstraint", false, "Dir", "", "", "" ); m_hasTangentConstraintUiField.xmlCapability()->disableIO(); - CAF_PDM_InitField( &m_azimuth, "Azimuth", 0.0, "Azi(deg)", "", "", "" ); - CAF_PDM_InitField( &m_inclination, "Inclination", 0.0, "Inc(deg)", "", "", "" ); + CAF_PDM_InitScriptableField( &m_azimuth, "Azimuth", 0.0, "Azi(deg)", "", "", "" ); + CAF_PDM_InitScriptableField( &m_inclination, "Inclination", 0.0, "Inc(deg)", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_parentWellPath, "ParentWellPath", "Parent Well Path", "", "", "" ); diff --git a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimFaciesInitialPressureConfig.cpp b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimFaciesInitialPressureConfig.cpp index 60d48d28e2..b7e01ee320 100644 --- a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimFaciesInitialPressureConfig.cpp +++ b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimFaciesInitialPressureConfig.cpp @@ -18,6 +18,8 @@ #include "RimFaciesInitialPressureConfig.h" +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmObjectScriptingCapability.h" #include "cafPdmUiCheckBoxEditor.h" #include "cafPdmUiLineEditor.h" @@ -29,12 +31,14 @@ CAF_PDM_SOURCE_INIT( RimFaciesInitialPressureConfig, "FaciesInitialPressureConfi RimFaciesInitialPressureConfig::RimFaciesInitialPressureConfig() : changed( this ) { + CAF_PDM_InitScriptableObject( "Facies Initial Pressure Config", "", "", "" ); + m_isChecked.uiCapability()->setUiHidden( false ); - CAF_PDM_InitFieldNoDefault( &m_faciesName, "FaciesName", "Facies", "", "", "" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_faciesName, "FaciesName", "Facies", "", "", "" ); m_faciesName.uiCapability()->setUiReadOnly( true ); - CAF_PDM_InitFieldNoDefault( &m_faciesValue, "FaciesValue", "Value", "", "", "" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_faciesValue, "FaciesValue", "Value", "", "", "" ); m_faciesValue.uiCapability()->setUiHidden( true ); // Use unicode for delta letter @@ -44,7 +48,7 @@ RimFaciesInitialPressureConfig::RimFaciesInitialPressureConfig() QString deltaPressureFractionString = QString::fromUtf8( "\u0394 Pressure Fraction" ); #endif - CAF_PDM_InitField( &m_fraction, "Fraction", 0.0, deltaPressureFractionString, "", "", "" ); + CAF_PDM_InitScriptableField( &m_fraction, "Fraction", 0.0, deltaPressureFractionString, "", "", "" ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimPressureTable.cpp b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimPressureTable.cpp index eebfc6a389..af8a836048 100644 --- a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimPressureTable.cpp +++ b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimPressureTable.cpp @@ -21,6 +21,8 @@ #include "RimPressureTableItem.h" #include "cafCmdFeatureMenuBuilder.h" +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmObjectScriptingCapability.h" #include "cafPdmUiTableViewEditor.h" #include "cafPdmUiTreeOrdering.h" @@ -32,14 +34,14 @@ CAF_PDM_SOURCE_INIT( RimPressureTable, "PressureTable" ); RimPressureTable::RimPressureTable() : changed( this ) { - CAF_PDM_InitObject( "Pressure Table", "", "", "" ); + CAF_PDM_InitScriptableObject( "Pressure Table", "", "", "" ); - CAF_PDM_InitFieldNoDefault( &m_pressureTableItems, "Items", "Pressure Table Items", "", "", "" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_pressureTableItems, "Items", "Pressure Table Items", "", "", "" ); m_pressureTableItems.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() ); m_pressureTableItems.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN ); m_pressureTableItems.uiCapability()->setCustomContextMenuEnabled( true ); - CAF_PDM_InitFieldNoDefault( &m_pressureDate, "PressureDate", "Pressure Date", "", "", "" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_pressureDate, "PressureDate", "Pressure Date", "", "", "" ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimPressureTableItem.cpp b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimPressureTableItem.cpp index 81ac53ee7c..7b7b3ca71b 100644 --- a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimPressureTableItem.cpp +++ b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimPressureTableItem.cpp @@ -18,6 +18,8 @@ #include "RimPressureTableItem.h" +#include "cafPdmFieldScriptingCapability.h" +#include "cafPdmObjectScriptingCapability.h" #include "cafPdmUiCheckBoxEditor.h" #include "cafPdmUiLineEditor.h" @@ -29,9 +31,11 @@ CAF_PDM_SOURCE_INIT( RimPressureTableItem, "PressureTableItem" ); RimPressureTableItem::RimPressureTableItem() : changed( this ) { - CAF_PDM_InitField( &m_depth, "Depth", 0.0, "Depth TVDMSL [m]", "", "", "" ); - CAF_PDM_InitField( &m_initialPressure, "InitialPressure", 0.0, "Initial Pressure [Bar]", "", "", "" ); - CAF_PDM_InitField( &m_pressure, "Pressure", 0.0, "Pressure [Bar]", "", "", "" ); + CAF_PDM_InitScriptableObject( "Pressure Table Item", "", "", "" ); + + CAF_PDM_InitScriptableField( &m_depth, "Depth", 0.0, "Depth TVDMSL [m]", "", "", "" ); + CAF_PDM_InitScriptableField( &m_initialPressure, "InitialPressure", 0.0, "Initial Pressure [Bar]", "", "", "" ); + CAF_PDM_InitScriptableField( &m_pressure, "Pressure", 0.0, "Pressure [Bar]", "", "", "" ); } //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmCodeGenerator.h b/Fwk/AppFwk/cafPdmScripting/cafPdmCodeGenerator.h index b7fb3ccae4..88f01eec37 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmCodeGenerator.h +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmCodeGenerator.h @@ -61,9 +61,9 @@ class PdmObjectFactory; class PdmCodeGenerator { public: - virtual QString generate( PdmObjectFactory* factory ) const = 0; + virtual QString generate( PdmObjectFactory* factory, std::vector& errorMessages ) const = 0; }; typedef Factory PdmCodeGeneratorFactory; -} // namespace caf \ No newline at end of file +} // namespace caf diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmMarkdownGenerator.cpp b/Fwk/AppFwk/cafPdmScripting/cafPdmMarkdownGenerator.cpp index fec56b0988..73fcbbbfc2 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmMarkdownGenerator.cpp +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmMarkdownGenerator.cpp @@ -46,7 +46,7 @@ CAF_PDM_CODE_GENERATOR_SOURCE_INIT( PdmMarkdownGenerator, "md" ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString caf::PdmMarkdownGenerator::generate( PdmObjectFactory* factory ) const +QString caf::PdmMarkdownGenerator::generate( PdmObjectFactory* factory, std::vector& errorMessages ) const { QString generatedCode; QTextStream out( &generatedCode ); diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmMarkdownGenerator.h b/Fwk/AppFwk/cafPdmScripting/cafPdmMarkdownGenerator.h index 5a21651a26..ddffdb8e92 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmMarkdownGenerator.h +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmMarkdownGenerator.h @@ -58,7 +58,7 @@ class PdmMarkdownGenerator : public PdmCodeGenerator }; public: - QString generate( PdmObjectFactory* factory ) const override; + QString generate( PdmObjectFactory* factory, std::vector& errorMessages ) const override; }; } // namespace caf diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp index 9a5c848bb9..8c581ff8e9 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp @@ -59,7 +59,7 @@ CAF_PDM_CODE_GENERATOR_SOURCE_INIT( PdmPythonGenerator, "py" ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString PdmPythonGenerator::generate( PdmObjectFactory* factory ) const +QString caf::PdmPythonGenerator::generate( PdmObjectFactory* factory, std::vector& errorMessages ) const { QString generatedCode; QTextStream out( &generatedCode ); @@ -92,6 +92,7 @@ QString PdmPythonGenerator::generate( PdmObjectFactory* factory ) const std::map>> classAttributesGenerated; std::map> classMethodsGenerated; std::map classCommentsGenerated; + std::set dataTypesInChildFields; // First generate all attributes and comments to go into each object for ( std::shared_ptr object : dummyObjects ) @@ -181,9 +182,14 @@ QString PdmPythonGenerator::generate( PdmObjectFactory* factory ) const } else { - QString valueString; - QTextStream valueStream( &valueString ); - scriptability->readFromField( valueStream, true, true ); + QString valueString; + + // Always make sure the default value for a ptrField is empty string + if ( !field->hasPtrReferencedObjects() ) + { + QTextStream valueStream( &valueString ); + scriptability->readFromField( valueStream, true, true ); + } if ( valueString.isEmpty() ) valueString = QString( "\"\"" ); valueString = pythonifyDataValue( valueString ); @@ -203,6 +209,8 @@ QString PdmPythonGenerator::generate( PdmObjectFactory* factory ) const QString scriptDataType = PdmObjectScriptingCapabilityRegister::scriptClassNameFromClassKeyword( dataType ); + dataTypesInChildFields.insert( scriptDataType ); + QString commentDataType = field->xmlCapability()->isVectorField() ? QString( "List of %1" ).arg( scriptDataType ) : scriptDataType; @@ -385,6 +393,16 @@ QString PdmPythonGenerator::generate( PdmObjectFactory* factory ) const out << " return all_classes[class_keyword]\n"; out << " return None\n"; + // Check if all referenced data types are exported as classes + for ( const auto& scriptDataType : dataTypesInChildFields ) + { + if ( classesWritten.count( scriptDataType ) == 0 ) + { + QString errorText = "No export for data type " + scriptDataType; + errorMessages.push_back( errorText ); + } + } + return generatedCode; } diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.h b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.h index 4587178d66..f4068e84a8 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.h +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.h @@ -49,11 +49,11 @@ class PdmPythonGenerator : public PdmCodeGenerator CAF_PDM_CODE_GENERATOR_HEADER_INIT; public: - QString generate( PdmObjectFactory* factory ) const override; + QString generate( PdmObjectFactory* factory, std::vector& errorMessages ) const override; static QString camelToSnakeCase( const QString& camelString ); static QString dataTypeString( const PdmFieldHandle* field, bool useStrForUnknownDataTypes ); static QString pythonifyDataValue( const QString& dataValue ); }; -} // namespace caf \ No newline at end of file +} // namespace caf diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafPdmScriptingBasicTest.cpp b/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafPdmScriptingBasicTest.cpp index 042fe399da..372b533003 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafPdmScriptingBasicTest.cpp +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafPdmScriptingBasicTest.cpp @@ -250,7 +250,8 @@ TEST( PdmScriptingTest, BasicUse ) std::string fileExt = "py"; std::unique_ptr generator( caf::PdmCodeGeneratorFactory::instance()->create( fileExt ) ); - auto generatedText = generator->generate( caf::PdmDefaultObjectFactory::instance() ); + std::vector logMessages; + auto generatedText = generator->generate( caf::PdmDefaultObjectFactory::instance(), logMessages ); auto string = generatedText.toStdString(); } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.h index f94a78110c..3811191203 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.h @@ -104,6 +104,8 @@ public: virtual void onChildDeleted( PdmChildArrayFieldHandle* childArray, std::vector& referringObjects ); + virtual void onChildAdded( caf::PdmFieldHandle* containerForNewObject ){}; + protected: void addField( PdmFieldHandle* field, const QString& keyword ); diff --git a/GrpcInterface/GrpcProtos/PdmObject.proto b/GrpcInterface/GrpcProtos/PdmObject.proto index e64712c8c4..cff7e5db9b 100644 --- a/GrpcInterface/GrpcProtos/PdmObject.proto +++ b/GrpcInterface/GrpcProtos/PdmObject.proto @@ -32,6 +32,7 @@ message CreatePdmChildObjectRequest { PdmObject object = 1; string child_field = 2; + string class_keyword = 3; } message PdmParentObjectRequest diff --git a/GrpcInterface/Python/rips/pdmobject.py b/GrpcInterface/Python/rips/pdmobject.py index 400492d8e5..e919cd96c1 100644 --- a/GrpcInterface/Python/rips/pdmobject.py +++ b/GrpcInterface/Python/rips/pdmobject.py @@ -284,6 +284,41 @@ class PdmObjectBase: return [] raise e + def add_new_object(self, class_definition, child_field=""): + """Create and add an object to the specified child field + Arguments: + class_definition[class]: Class definition of the object to create + child_field[str]: The keyword for the field to create a new object in. If empty, the first child array field is used. + Returns: + The created PdmObject inside the child_field + """ + from .generated.generated_classes import class_from_keyword + + assert inspect.isclass(class_definition) + + class_keyword = class_definition.__name__ + + request = PdmObject_pb2.CreatePdmChildObjectRequest( + object=self._pb2_object, + child_field=child_field, + class_keyword=class_keyword, + ) + try: + pb2_object = self._pdm_object_stub.CreateChildPdmObject(request) + child_class_definition = class_from_keyword(pb2_object.class_keyword) + + if child_class_definition is None: + child_class_definition = class_keyword + + pdm_object = child_class_definition( + pb2_object=pb2_object, channel=self.channel() + ) + return pdm_object + except grpc.RpcError as e: + if e.code() == grpc.StatusCode.NOT_FOUND: + return None + raise e + def ancestor(self, class_definition): """Find the first ancestor that matches the provided class_keyword Arguments: diff --git a/GrpcInterface/Python/rips/tests/create_well_path.py b/GrpcInterface/Python/rips/tests/create_well_path.py new file mode 100644 index 0000000000..41206b7174 --- /dev/null +++ b/GrpcInterface/Python/rips/tests/create_well_path.py @@ -0,0 +1,35 @@ +from rips.generated.generated_classes import ( + ModeledWellPath, + StimPlanModel, + WellPathGeometry, + WellPathTarget, +) +import sys +import os + +sys.path.insert(1, os.path.join(sys.path[0], "../../")) +import rips + + +def test_well_path_target(rips_instance, initialize_test): + well_path_coll = rips_instance.project.descendants(rips.WellPathCollection)[0] + + my_well_path = well_path_coll.add_new_object(rips.ModeledWellPath) + my_well_path.name = "test" + my_well_path.update() + + geometry = my_well_path.well_path_geometry() + geometry.add_new_object(rips.WellPathTarget) + geometry.add_new_object(rips.WellPathTarget) + geometry.add_new_object(rips.WellPathTarget) + assert len(geometry.well_path_targets()) == 3 + + assert len(well_path_coll.well_paths()) == 1 + my_well_path_duplicate = well_path_coll.well_paths()[0] + assert my_well_path_duplicate.name == "test" + geometry_duplicate = my_well_path_duplicate.well_path_geometry() + assert len(geometry_duplicate.well_path_targets()) == 3 + + # Not allowed to add object of unrelated type + invalid_object = geometry.add_new_object(rips.WellPath) + assert invalid_object is None diff --git a/GrpcInterface/Python/setup.py.cmake b/GrpcInterface/Python/setup.py.cmake index 498fa2194a..9f14dcab76 100644 --- a/GrpcInterface/Python/setup.py.cmake +++ b/GrpcInterface/Python/setup.py.cmake @@ -19,5 +19,5 @@ setup( license=license, packages=['rips'], package_data={'rips': ['*.py', 'generated/*.py', 'PythonExamples/*.py', 'tests/*.py']}, - install_requires=['grpcio>=1.20.0', protobuf, wheel] + install_requires=['grpcio>=1.20.0', 'protobuf', 'wheel'] ) \ No newline at end of file diff --git a/GrpcInterface/RiaGrpcCommandService.cpp b/GrpcInterface/RiaGrpcCommandService.cpp index 7ebad0af0a..a8073357cf 100644 --- a/GrpcInterface/RiaGrpcCommandService.cpp +++ b/GrpcInterface/RiaGrpcCommandService.cpp @@ -269,7 +269,7 @@ void RiaGrpcCommandService::assignPdmObjectValues( caf::PdmObjectHandle* } else if ( childObjects.empty() ) { - childObject = emplaceChildField( pdmChildFieldHandle ); + childObject = emplaceChildField( pdmChildFieldHandle, "" ); } CAF_ASSERT( childObject ); if ( childObject ) diff --git a/GrpcInterface/RiaGrpcPdmObjectService.cpp b/GrpcInterface/RiaGrpcPdmObjectService.cpp index 1847a6b301..c52af25c3d 100644 --- a/GrpcInterface/RiaGrpcPdmObjectService.cpp +++ b/GrpcInterface/RiaGrpcPdmObjectService.cpp @@ -473,11 +473,15 @@ grpc::Status RiaGrpcPdmObjectService::CreateChildPdmObject( grpc::ServerContext* { CAF_ASSERT( request ); - caf::PdmObjectHandle* pdmObject = - emplaceChildField( matchingObject, QString::fromStdString( request->child_field() ) ); - if ( pdmObject ) + QString keywordClassToCreate = QString::fromStdString( request->class_keyword() ); + QString fieldKeyword = QString::fromStdString( request->child_field() ); + + caf::PdmObjectHandle* pdmObjectHandle = emplaceChildField( matchingObject, fieldKeyword, keywordClassToCreate ); + if ( pdmObjectHandle ) { - copyPdmObjectFromCafToRips( pdmObject, reply ); + copyPdmObjectFromCafToRips( pdmObjectHandle, reply ); + matchingObject->uiCapability()->updateConnectedEditors(); + return grpc::Status::OK; } return grpc::Status( grpc::NOT_FOUND, "Could not create PdmObject" ); diff --git a/GrpcInterface/RiaGrpcServiceInterface.cpp b/GrpcInterface/RiaGrpcServiceInterface.cpp index 12107a9b13..a91366ee57 100644 --- a/GrpcInterface/RiaGrpcServiceInterface.cpp +++ b/GrpcInterface/RiaGrpcServiceInterface.cpp @@ -142,6 +142,12 @@ void RiaGrpcServiceInterface::copyPdmObjectFromRipsToCaf( const rips::PdmObject* auto scriptability = field->template capability(); if ( scriptability ) { + if ( !dynamic_cast( field ) ) + { + // Recursive object update is not supported + // https://github.com/OPM/ResInsight/issues/7794 + continue; + } QString keyword = scriptability->scriptFieldName(); QString value = QString::fromStdString( parametersMap[keyword.toStdString()] ); @@ -181,7 +187,9 @@ bool RiaGrpcServiceInterface::assignFieldValue( const QString& stringValue //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmObject* parent, const QString& fieldLabel ) +caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmObject* parent, + const QString& fieldKeyword, + const QString& keywordForClassToCreate ) { std::vector fields; parent->fields( fields ); @@ -190,13 +198,32 @@ caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmObject { auto pdmChildArrayField = dynamic_cast( field ); auto pdmChildField = dynamic_cast( field ); - if ( pdmChildArrayField && pdmChildArrayField->keyword() == fieldLabel ) + if ( pdmChildArrayField ) { - return emplaceChildArrayField( 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() == fieldLabel ) + else if ( pdmChildField && pdmChildField->keyword() == fieldKeyword ) { - return emplaceChildField( pdmChildField ); + return emplaceChildField( pdmChildField, keywordForClassToCreate ); } } return nullptr; @@ -205,12 +232,33 @@ caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmObject //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmChildFieldHandle* childField ) +caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmChildFieldHandle* childField, + const QString& keywordForClassToCreate ) { - QString childClassKeyword = childField->xmlCapability()->dataTypeName(); + 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; } @@ -218,13 +266,34 @@ caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmChildF //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildArrayField( caf::PdmChildArrayFieldHandle* childArrayField ) +caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildArrayField( caf::PdmChildArrayFieldHandle* childArrayField, + const QString& keywordForClassToCreate ) { - QString childClassKeyword = childArrayField->xmlCapability()->dataTypeName(); + QString childClassKeyword; + if ( keywordForClassToCreate.isEmpty() ) + { + childClassKeyword = childArrayField->xmlCapability()->dataTypeName(); + } + else + { + childClassKeyword = keywordForClassToCreate; + } auto pdmObjectHandle = caf::PdmDefaultObjectFactory::instance()->create( childClassKeyword ); - CAF_ASSERT( pdmObjectHandle ); + 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; } diff --git a/GrpcInterface/RiaGrpcServiceInterface.h b/GrpcInterface/RiaGrpcServiceInterface.h index 95c5870a87..997cb0f304 100644 --- a/GrpcInterface/RiaGrpcServiceInterface.h +++ b/GrpcInterface/RiaGrpcServiceInterface.h @@ -60,10 +60,13 @@ public: static bool assignFieldValue( const QString& stringValue, caf::PdmFieldHandle* field, QVariant* oldValue, QVariant* newValue ); - static caf::PdmObjectHandle* emplaceChildField( caf::PdmObject* parent, const QString& fieldLabel ); + static caf::PdmObjectHandle* + emplaceChildField( caf::PdmObject* parent, const QString& fieldKeyword, const QString& keywordForClassToCreate ); - static caf::PdmObjectHandle* emplaceChildField( caf::PdmChildFieldHandle* childField ); - static caf::PdmObjectHandle* emplaceChildArrayField( caf::PdmChildArrayFieldHandle* childArrayField ); + static caf::PdmObjectHandle* emplaceChildField( caf::PdmChildFieldHandle* childField, + const QString& keywordForClassToCreate ); + static caf::PdmObjectHandle* emplaceChildArrayField( caf::PdmChildArrayFieldHandle* childArrayField, + const QString& keywordForClassToCreate ); }; #include "cafFactory.h"