Make scriptability a CAF-feature

This commit is contained in:
Gaute Lindkvist 2020-03-03 10:43:07 +01:00
parent 5473fa64d5
commit b2f55a3101
55 changed files with 974 additions and 489 deletions

View File

@ -95,6 +95,8 @@
#include "RiuViewer.h"
#include "RiuViewerCommands.h"
#include "cafPdmCodeGenerator.h"
#include "cafPdmDataValueField.h"
#include "cafPdmDefaultObjectFactory.h"
#include "cafPdmSettings.h"
#include "cafPdmUiModelChangeDetector.h"
@ -1700,232 +1702,26 @@ void RiaApplication::resetProject()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication::generatePythonClasses( const QString& fileName )
bool RiaApplication::generateCode( const QString& fileName, QString* errMsg )
{
auto factory = caf::PdmDefaultObjectFactory::instance();
CAF_ASSERT( errMsg );
QFile pythonFile( fileName );
if ( !pythonFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
QFile outputFile( fileName );
if ( !outputFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
{
return;
*errMsg = QString( "Could not open file %1 for writing" ).arg( fileName );
return false;
}
QTextStream out( &pythonFile );
std::vector<QString> classKeywords = factory->classKeywords();
QTextStream out( &outputFile );
std::vector<std::shared_ptr<const caf::PdmObject>> dummyObjects;
for ( QString classKeyword : classKeywords )
std::string fileExt = QFileInfo( fileName ).suffix().toStdString();
std::unique_ptr<caf::PdmCodeGenerator> generator( caf::PdmCodeGeneratorFactory::instance()->create( fileExt ) );
if ( !generator )
{
auto objectHandle = factory->create( classKeyword );
const caf::PdmObject* object = dynamic_cast<const caf::PdmObject*>( objectHandle );
CAF_ASSERT( object );
std::shared_ptr<const caf::PdmObject> sharedObject( object );
if ( RicfObjectCapability::isScriptable( sharedObject.get() ) )
{
dummyObjects.push_back( sharedObject );
}
*errMsg = QString( "No code generator matches the provided file extension" );
return false;
}
// Sort to make sure super classes get created before sub classes
std::sort( dummyObjects.begin(),
dummyObjects.end(),
[]( std::shared_ptr<const caf::PdmObject> lhs, std::shared_ptr<const caf::PdmObject> rhs ) {
if ( lhs->inheritsClassWithKeyword( rhs->classKeyword() ) )
{
return false;
}
return lhs->classKeyword() < rhs->classKeyword();
} );
std::map<QString, std::map<QString, std::pair<QString, QString>>> classAttributesGenerated;
std::map<QString, std::map<QString, QString>> classMethodsGenerated;
std::map<QString, QString> classCommentsGenerated;
// First generate all attributes and comments to go into each object
for ( std::shared_ptr<const caf::PdmObject> object : dummyObjects )
{
const std::list<QString>& classInheritanceStack = object->classInheritanceStack();
for ( auto it = classInheritanceStack.begin(); it != classInheritanceStack.end(); ++it )
{
const QString& classKeyword = *it;
QString scriptClassComment = RicfObjectCapability::scriptClassComment( classKeyword );
std::map<QString, QString> attributesGenerated;
if ( !scriptClassComment.isEmpty() ) classCommentsGenerated[classKeyword] = scriptClassComment;
if ( classKeyword == object->classKeyword() )
{
std::vector<caf::PdmFieldHandle*> fields;
object->fields( fields );
for ( auto field : fields )
{
auto pdmValueField = dynamic_cast<const caf::PdmValueField*>( field );
if ( pdmValueField )
{
QString keyword = pdmValueField->keyword();
auto ricfHandle = field->template capability<RicfFieldHandle>();
if ( ricfHandle != nullptr )
{
bool shouldBeMethod = false;
auto proxyField = dynamic_cast<const caf::PdmProxyFieldHandle*>( field );
if ( proxyField && proxyField->isStreamingField() ) shouldBeMethod = true;
QString snake_field_name = RiaTextStringTools::camelToSnakeCase( ricfHandle->fieldName() );
if ( classAttributesGenerated[field->ownerClass()].count( snake_field_name ) ) continue;
if ( classMethodsGenerated[field->ownerClass()].count( snake_field_name ) ) continue;
QString comment;
{
QStringList commentComponents;
commentComponents << pdmValueField->capability<caf::PdmUiFieldHandle>()->uiName();
commentComponents << pdmValueField->capability<caf::PdmUiFieldHandle>()->uiWhatsThis();
commentComponents.removeAll( QString( "" ) );
comment = commentComponents.join( ". " );
}
QVariant valueVariant = pdmValueField->toQVariant();
QString dataTypeString = valueVariant.typeName();
if ( shouldBeMethod )
{
if ( proxyField->hasGetter() )
{
QString fullComment =
QString( " \"\"\"%1\n Returns:\n %2\n \"\"\"" )
.arg( comment )
.arg( dataTypeString );
QString fieldCode = QString( " def %1(self):\n%2\n return "
"self._call_get_method(\"%3\")\n" )
.arg( snake_field_name )
.arg( fullComment )
.arg( ricfHandle->fieldName() );
classMethodsGenerated[field->ownerClass()][snake_field_name] = fieldCode;
}
if ( proxyField->hasSetter() )
{
QString fullComment = QString( " \"\"\"Set %1\n Attributes:\n"
" values (%2): data\n \"\"\"" )
.arg( comment )
.arg( dataTypeString );
QString fieldCode = QString( " def set_%1(self, values):\n%2\n "
"self._call_set_method(\"%3\", values)\n" )
.arg( snake_field_name )
.arg( fullComment )
.arg( ricfHandle->fieldName() );
classMethodsGenerated[field->ownerClass()][QString( "set_%1" ).arg( snake_field_name )] =
fieldCode;
}
}
else
{
QString fieldCode = QString( " self.%1 = None\n" ).arg( snake_field_name );
QString fullComment =
QString( "%1 (%2): %3\n" ).arg( snake_field_name ).arg( dataTypeString ).arg( comment );
classAttributesGenerated[field->ownerClass()][snake_field_name].first = fieldCode;
classAttributesGenerated[field->ownerClass()][snake_field_name].second = fullComment;
}
}
}
}
}
}
}
// Write out classes
std::set<QString> classesWritten;
for ( std::shared_ptr<const caf::PdmObject> object : dummyObjects )
{
const std::list<QString>& classInheritanceStack = object->classInheritanceStack();
std::list<QString> scriptSuperClassNames;
for ( auto it = classInheritanceStack.begin(); it != classInheritanceStack.end(); ++it )
{
const QString& classKeyword = *it;
QString scriptClassName = RicfObjectCapability::scriptClassNameFromClassKeyword( classKeyword );
if ( scriptClassName.isEmpty() ) scriptClassName = classKeyword;
if ( !classesWritten.count( scriptClassName ) )
{
QString classCode;
if ( scriptSuperClassNames.empty() )
{
classCode = QString( "class %1:\n" ).arg( scriptClassName );
}
else
{
classCode = QString( "class %1(%2):\n" ).arg( scriptClassName ).arg( scriptSuperClassNames.back() );
}
if ( !classCommentsGenerated[classKeyword].isEmpty() || !classAttributesGenerated[classKeyword].empty() )
{
classCode += " \"\"\"\n";
if ( !classCommentsGenerated[classKeyword].isEmpty() )
{
if ( !classCommentsGenerated[classKeyword].isEmpty() )
{
classCode += QString( " %1\n\n" ).arg( classCommentsGenerated[classKeyword] );
}
}
if ( !classAttributesGenerated[classKeyword].empty() )
{
classCode += " Attributes\n";
for ( auto keyWordValuePair : classAttributesGenerated[classKeyword] )
{
classCode += " " + keyWordValuePair.second.second;
}
}
classCode += " \"\"\"\n";
}
classCode +=
QString( " __custom_init__ = None #: Assign a custom init routine to be run at __init__\n\n" );
classCode += QString( " def __init__(self, pb2_object=None, channel=None):\n" );
classCode += QString( " self.class_keyword = \"%1\"\n" ).arg( scriptClassName );
if ( !scriptSuperClassNames.empty() )
{
// Own attributes. This initializes a lot of attributes to None.
// This means it has to be done before we set any values.
for ( auto keyWordValuePair : classAttributesGenerated[classKeyword] )
{
classCode += keyWordValuePair.second.first;
}
// Parent constructor
classCode +=
QString( " %1.__init__(self, pb2_object, channel)\n" ).arg( scriptSuperClassNames.back() );
}
classCode += QString( " if %1.__custom_init__ is not None:\n" ).arg( scriptClassName );
classCode += QString( " %1.__custom_init__(self, pb2_object=pb2_object, channel=channel)\n" )
.arg( scriptClassName );
for ( auto keyWordValuePair : classMethodsGenerated[classKeyword] )
{
classCode += "\n";
classCode += keyWordValuePair.second;
classCode += "\n";
}
out << classCode << "\n";
classesWritten.insert( scriptClassName );
}
scriptSuperClassNames.push_back( scriptClassName );
}
}
out << "def class_dict():\n";
out << " classes = {}\n";
for ( QString classKeyword : classesWritten )
{
out << QString( " classes['%1'] = %1\n" ).arg( classKeyword );
}
out << " return classes\n\n";
out << "def class_from_keyword(class_keyword):\n";
out << " all_classes = class_dict()\n";
out << " if class_keyword in all_classes.keys():\n";
out << " return all_classes[class_keyword]\n";
out << " return None\n";
out << generator->generate( caf::PdmDefaultObjectFactory::instance() );
return true;
}

View File

@ -226,7 +226,7 @@ protected:
friend class RiaRegressionTestRunner;
void resetProject();
void generatePythonClasses( const QString& outputPath );
bool generateCode( const QString& outputPath, QString* errMsg );
protected:
cvf::ref<cvf::Font> m_defaultSceneFont;

View File

@ -137,7 +137,12 @@ RiaApplication::ApplicationStatus RiaConsoleApplication::handleArguments( cvf::P
CVF_ASSERT( o.valueCount() == 1 );
QString outputFile = cvfqt::Utils::toQString( o.value( 0 ) );
RiaApplication::generatePythonClasses( outputFile );
QString errMsg;
if ( !RiaApplication::generateCode( outputFile, &errMsg ) )
{
RiaLogging::error( QString( "Error: %1" ).arg( errMsg ) );
return RiaApplication::EXIT_WITH_ERROR;
}
return RiaApplication::EXIT_COMPLETED;
}

View File

@ -457,7 +457,12 @@ RiaApplication::ApplicationStatus RiaGuiApplication::handleArguments( cvf::Progr
CVF_ASSERT( o.valueCount() == 1 );
QString outputFile = cvfqt::Utils::toQString( o.value( 0 ) );
RiaApplication::generatePythonClasses( outputFile );
QString errMsg;
if ( !RiaApplication::generateCode( outputFile, &errMsg ) )
{
RiaLogging::error( QString( "Error: %1" ).arg( errMsg ) );
return RiaApplication::EXIT_WITH_ERROR;
}
return RiaApplication::EXIT_COMPLETED;
}

View File

@ -55,17 +55,3 @@ QString RiaTextStringTools::trimAndRemoveDoubleSpaces( const QString& s )
return trimmed;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaTextStringTools::camelToSnakeCase( const QString& camelString )
{
static QRegularExpression re1( "(.)([A-Z][a-z]+)" );
static QRegularExpression re2( "([a-z0-9])([A-Z])" );
QString snake_case = camelString;
snake_case.replace( re1, "\\1_\\2" );
snake_case.replace( re2, "\\1_\\2" );
return snake_case.toLower();
}

View File

@ -27,5 +27,4 @@ namespace RiaTextStringTools
{
bool compare( const QString& expected, const QString& actual );
QString trimAndRemoveDoubleSpaces( const QString& s );
QString camelToSnakeCase( const QString& camelString );
} // namespace RiaTextStringTools

View File

@ -18,7 +18,7 @@
#include "RicfCommandObject.h"
#include "RiaTextStringTools.h"
#include "cafPdmPythonGenerator.h"
//--------------------------------------------------------------------------------------------------
///
@ -40,7 +40,7 @@ RicfCommandObject::~RicfCommandObject()
//--------------------------------------------------------------------------------------------------
QString RicfCommandObject::pythonHelpString( const QString& existingTooltip, const QString& keyword )
{
QString snake_case = RiaTextStringTools::camelToSnakeCase( keyword );
QString snake_case = caf::PdmPythonGenerator::camelToSnakeCase( keyword );
QString helpString = QString( "Available through python/rips as the attribute '%1'" ).arg( snake_case );

View File

@ -20,8 +20,10 @@
#include "RicfCommandResponse.h"
#include "RicfFieldCapability.h"
#include "RicfObjectCapability.h"
#include "cafCmdFeature.h"
#include "cafPdmObject.h"
#include "cafPdmObjectScriptabilityRegister.h"
//==================================================================================================
//
@ -77,14 +79,6 @@ public:
whatsThis ); \
AddRicfCapabilityToField( field, scriptKeyword )
#define RICF_InitObject( uiName, iconResourceName, toolTip, whatsThis ) \
CAF_PDM_InitObject( uiName, iconResourceName, toolTip, whatsThis ); \
RicfObjectCapability::addCapabilityToObject( this, classKeyword(), whatsThis );
#define RICF_InitObjectWithScriptNameAndComment( uiName, iconResourceName, toolTip, whatsThis, scriptClassName, scriptComment ) \
CAF_PDM_InitObject( uiName, iconResourceName, toolTip, whatsThis ); \
RicfObjectCapability::addCapabilityToObject( this, scriptClassName, scriptComment );
#define RICF_HEADER_INIT \
CAF_CMD_HEADER_INIT; \
CAF_PDM_HEADER_INIT

View File

@ -22,12 +22,9 @@
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicfFieldHandle::RicfFieldHandle( caf::PdmFieldHandle* owner, const QString& fieldName, bool giveOwnership )
RicfFieldHandle::RicfFieldHandle( caf::PdmFieldHandle* owner, const QString& scriptFieldName, bool giveOwnership )
: caf::PdmFieldScriptability( owner, scriptFieldName, giveOwnership )
{
m_IOWriteable = true;
m_owner = owner;
m_fieldName = fieldName;
owner->addCapability( this, giveOwnership );
}
//--------------------------------------------------------------------------------------------------
@ -36,11 +33,3 @@ RicfFieldHandle::RicfFieldHandle( caf::PdmFieldHandle* owner, const QString& fie
RicfFieldHandle::~RicfFieldHandle()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QString& RicfFieldHandle::fieldName() const
{
return m_fieldName;
}

View File

@ -17,7 +17,7 @@
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmFieldCapability.h"
#include "cafPdmFieldScriptability.h"
#include <QString>
@ -36,18 +36,12 @@ class QTextStream;
//
//
//==================================================================================================
class RicfFieldHandle : public caf::PdmFieldCapability
class RicfFieldHandle : public caf::PdmFieldScriptability
{
public:
RicfFieldHandle( caf::PdmFieldHandle* owner, const QString& fieldName, bool giveOwnership );
RicfFieldHandle( caf::PdmFieldHandle* owner, const QString& scriptFieldName, bool giveOwnership );
~RicfFieldHandle() override;
const QString& fieldName() const;
bool isIOWriteable() const { return m_IOWriteable; }
void setIOWriteable( bool writeable ) { m_IOWriteable = writeable; }
virtual void readFieldData( QTextStream& inputStream,
caf::PdmObjectFactory* objectFactory,
RicfMessages* errorMessageContainer,

View File

@ -26,10 +26,6 @@
#include <QTextStream>
std::map<QString, QString> RicfObjectCapability::s_classKeywordToScriptClassName;
std::map<QString, QString> RicfObjectCapability::s_scriptClassNameToClassKeyword;
std::map<QString, QString> RicfObjectCapability::s_scriptClassComments;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -223,76 +219,3 @@ void RicfObjectCapability::writeFields( QTextStream& outputStream ) const
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicfObjectCapability::registerScriptClassNameAndComment( const QString& classKeyword,
const QString& scriptClassName,
const QString& scriptClassComment )
{
s_classKeywordToScriptClassName[classKeyword] = scriptClassName;
s_scriptClassNameToClassKeyword[scriptClassName] = classKeyword;
s_scriptClassComments[classKeyword] = scriptClassComment;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicfObjectCapability::scriptClassNameFromClassKeyword( const QString& classKeyword )
{
auto it = s_classKeywordToScriptClassName.find( classKeyword );
if ( it != s_classKeywordToScriptClassName.end() )
{
return it->second;
}
return classKeyword;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicfObjectCapability::classKeywordFromScriptClassName( const QString& scriptClassName )
{
auto it = s_scriptClassNameToClassKeyword.find( scriptClassName );
if ( it != s_scriptClassNameToClassKeyword.end() )
{
return it->second;
}
return scriptClassName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicfObjectCapability::scriptClassComment( const QString& classKeyword )
{
auto it = s_scriptClassComments.find( classKeyword );
if ( it != s_scriptClassComments.end() )
{
return it->second;
}
return "";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicfObjectCapability::isScriptable( const caf::PdmObject* object )
{
return s_classKeywordToScriptClassName.find( object->classKeyword() ) != s_classKeywordToScriptClassName.end();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicfObjectCapability::addCapabilityToObject( caf::PdmObject* object,
const QString& scriptClassName,
const QString& scriptClassComment )
{
if ( !object->capability<RicfObjectCapability>() )
{
new RicfObjectCapability( object, true );
}
RicfObjectCapability::registerScriptClassNameAndComment( object->classKeyword(), scriptClassName, scriptClassComment );
}

View File

@ -48,21 +48,6 @@ public:
void readFields( QTextStream& inputStream, caf::PdmObjectFactory* objectFactory, RicfMessages* errorMessageContainer );
void writeFields( QTextStream& outputStream ) const;
static void registerScriptClassNameAndComment( const QString& classKeyword,
const QString& scriptClassName,
const QString& scriptClassComment );
static QString scriptClassNameFromClassKeyword( const QString& classKeyword );
static QString classKeywordFromScriptClassName( const QString& scriptClassName );
static QString scriptClassComment( const QString& classKeyword );
static bool isScriptable( const caf::PdmObject* object );
static void
addCapabilityToObject( caf::PdmObject* object, const QString& scriptClassName, const QString& scriptClassComment );
private:
caf::PdmObjectHandle* m_owner;
static std::map<QString, QString> s_classKeywordToScriptClassName;
static std::map<QString, QString> s_scriptClassNameToClassKeyword;
static std::map<QString, QString> s_scriptClassComments;
};

View File

@ -0,0 +1,28 @@
# Load ResInsight Processing Server Client Library
import rips
# Connect to ResInsight instance
resinsight = rips.Instance.find()
# Get the project
project = resinsight.project
# Find all the well bore stability plots in the project
wbsplots = project.descendants(rips.WellBoreStabilityPlot)
# Chose a sensible output folder
dirname = "C:/temp"
# Loop through all Well Bore Stability plots
for wbsplot in wbsplots:
# Set depth type a parameter and export snapshot
wbsplot.depth_type = "TRUE_VERTICAL_DEPTH_RKB"
# Example of setting parameters for existing plots
params = wbsplot.parameters()
params.user_poisson_ratio = 0.654321
params.update()
wbsplot.update()
wbsplot.export_snapshot(export_folder=dirname)

View File

@ -6,60 +6,33 @@ import rips
# Connect to ResInsight instance
resInsight = rips.Instance.find()
cases = resInsight.project.cases()
well_paths = resInsight.project.import_well_paths(well_path_folder='D:/Projects/ResInsight-regression-test/ModelData/Norne_WellPaths')
well_log_files = resInsight.project.import_well_log_files(well_log_folder='D:/Projects/ResInsight-regression-test/ModelData/Norne_PLT_LAS')
# Get all GeoMech cases
cases = resInsight.project.descendants(rips.GeoMechCase)
# Get all well paths
well_paths = resInsight.project.well_paths()
# Ensure there's at least one well path
if len(well_paths) < 1:
print("No well paths in project")
exit(1)
well_paths = well_paths[0:4]
print(well_paths)
# Example of creating parameters for new plots
wbs_parameters = rips.WbsParameters()
wbs_parameters.user_poisson_ratio = 0.412347
wbs_parameters.pore_pressure_outside_reservoir_source = "USER_DEFINED"
wbs_parameters.user_pp_outside_reservoir = 1.1
wbs_parameters.fg_shale_source = "PROPORTIONAL_TO_SH"
wbs_parameters.user_fg_shale = 1.13
# Loop through all cases
for case in cases:
if case.type == "GeoMechCase":
min_res_depth, max_res_depth = case.reservoir_depth_range()
print (case.id)
case_path = case.file_path
folder_name = os.path.dirname(case_path)
case.import_formation_names(formation_files=['D:/Projects/ResInsight-regression-test/ModelData/norne/Norne_ATW2013.lyr'])
assert(isinstance(case, rips.GeoMechCase))
min_res_depth, max_res_depth = case.reservoir_depth_range()
# create a folder to hold the snapshots
dirname = os.path.join(folder_name, 'snapshots')
print("Exporting to: " + dirname)
# Find a good output path
case_path = case.file_path
folder_name = os.path.dirname(case_path)
for well_path in well_paths:
try:
# Create plot with parameters
wbsplot = case.create_well_bore_stability_plot(well_path=well_path.name, time_step=0, wbs_parameters=wbs_parameters)
# Example of setting parameters for existing plots
replace_params = wbsplot.parameters()
replace_params.user_poisson_ratio = 0.654321
replace_params.user_fg_shale = 1.0321
wbsplot.set_parameters(replace_params)
# Demonstrate altering general well log plot settings
min_depth = max(wbsplot.minimum_depth, min_res_depth)
max_depth = min(wbsplot.maximum_depth, max_res_depth)
wbsplot.minimum_depth = min_depth
wbsplot.maximum_depth = max_depth
wbsplot.update()
#wbsplot.depth_type = "TRUE_VERTICAL_DEPTH_RKB"
wbsplot.export_snapshot(export_folder=dirname)
# Import formation names
case.import_formation_names(formation_files=['D:/Projects/ResInsight-regression-test/ModelData/norne/Norne_ATW2013.lyr'])
except grpc.RpcError as e:
print("Error: ", e.details())
# create a folder to hold the snapshots
dirname = os.path.join(folder_name, 'snapshots')
print("Exporting to: " + dirname)
for well_path in well_paths[0:4]: # Loop through the first five well paths
# Create plot with parameters
wbsplot = case.create_well_bore_stability_plot(well_path=well_path.name, time_step=0)

View File

@ -25,6 +25,7 @@
#include "RimProject.h"
#include "cafPdmObject.h"
#include "cafPdmObjectScriptabilityRegister.h"
using namespace rips;
@ -336,7 +337,7 @@ grpc::Status RiaGrpcPdmObjectService::GetAncestorPdmObject( grpc::ServerContext*
std::vector<caf::PdmObject*> objectsOfCurrentClass;
QString scriptClassName = QString::fromStdString( request->object().class_keyword() );
QString classKeyword = RicfObjectCapability::classKeywordFromScriptClassName( scriptClassName );
QString classKeyword = caf::PdmObjectScriptabilityRegister::classKeywordFromScriptClassName( scriptClassName );
project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass );
@ -353,7 +354,8 @@ grpc::Status RiaGrpcPdmObjectService::GetAncestorPdmObject( grpc::ServerContext*
{
caf::PdmObject* parentObject = nullptr;
QString ancestorScriptName = QString::fromStdString( request->parent_keyword() );
QString ancestorClassKeyword = RicfObjectCapability::classKeywordFromScriptClassName( ancestorScriptName );
QString ancestorClassKeyword =
caf::PdmObjectScriptabilityRegister::classKeywordFromScriptClassName( ancestorScriptName );
matchingObject->firstAncestorOrThisFromClassKeyword( ancestorClassKeyword, parentObject );
if ( parentObject )
{
@ -376,8 +378,8 @@ grpc::Status RiaGrpcPdmObjectService::GetDescendantPdmObjects( grpc::ServerConte
if ( matchingObject )
{
std::vector<caf::PdmObject*> childObjects;
QString childClassKeyword =
RicfObjectCapability::classKeywordFromScriptClassName( QString::fromStdString( request->child_keyword() ) );
QString childClassKeyword = caf::PdmObjectScriptabilityRegister::classKeywordFromScriptClassName(
QString::fromStdString( request->child_keyword() ) );
matchingObject->descendantsIncludingThisFromClassKeyword( childClassKeyword, childObjects );
for ( auto pdmChild : childObjects )
{
@ -549,7 +551,7 @@ caf::PdmObject* RiaGrpcPdmObjectService::findCafObjectFromRipsObject( const rips
std::vector<caf::PdmObject*> objectsOfCurrentClass;
QString scriptClassName = QString::fromStdString( ripsObject.class_keyword() );
QString classKeyword = RicfObjectCapability::classKeywordFromScriptClassName( scriptClassName );
QString classKeyword = caf::PdmObjectScriptabilityRegister::classKeywordFromScriptClassName( scriptClassName );
project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass );

View File

@ -29,6 +29,7 @@
#include "cafPdmChildField.h"
#include "cafPdmDataValueField.h"
#include "cafPdmObject.h"
#include "cafPdmObjectScriptabilityRegister.h"
#include "cafPdmProxyValueField.h"
#include "cafPdmXmlFieldHandle.h"
@ -72,7 +73,7 @@ void RiaGrpcServiceInterface::copyPdmObjectFromCafToRips( const caf::PdmObjectHa
CAF_ASSERT( source && destination && source->xmlCapability() );
QString classKeyword = source->xmlCapability()->classKeyword();
QString scriptName = RicfObjectCapability::scriptClassNameFromClassKeyword( classKeyword );
QString scriptName = caf::PdmObjectScriptabilityRegister::scriptClassNameFromClassKeyword( classKeyword );
destination->set_class_keyword( scriptName.toStdString() );
destination->set_address( reinterpret_cast<uint64_t>( source ) );
@ -107,7 +108,7 @@ void RiaGrpcServiceInterface::copyPdmObjectFromCafToRips( const caf::PdmObjectHa
QString text;
QTextStream outStream( &text );
ricfHandle->writeFieldData( outStream, false );
( *parametersMap )[ricfHandle->fieldName().toStdString()] = text.toStdString();
( *parametersMap )[ricfHandle->scriptFieldName().toStdString()] = text.toStdString();
}
}
}
@ -146,7 +147,7 @@ void RiaGrpcServiceInterface::copyPdmObjectFromRipsToCaf( const rips::PdmObject*
auto ricfHandle = pdmValueField->template capability<RicfFieldHandle>();
if ( ricfHandle )
{
QString keyword = ricfHandle->fieldName();
QString keyword = ricfHandle->scriptFieldName();
QString value = QString::fromStdString( parametersMap[keyword.toStdString()] );
QVariant oldValue, newValue;

View File

@ -43,7 +43,7 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimCase, "Case", "RimCase" );
RimCase::RimCase()
: m_isInActiveDestruction( false )
{
RICF_InitObjectWithScriptNameAndComment( "Case", ":/Case48x48.png", "", "", "Case", "The ResInsight base class for Cases" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "Case", ":/Case48x48.png", "", "", "Case", "The ResInsight base class for Cases" );
RICF_InitField( &caseUserDescription, "Name", QString(), "Case Name", "", "", "" );
caseUserDescription.registerKeywordAlias( "CaseUserDescription" );

View File

@ -78,12 +78,12 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimEclipseCase, "RimReservoir" );
//--------------------------------------------------------------------------------------------------
RimEclipseCase::RimEclipseCase()
{
RICF_InitObjectWithScriptNameAndComment( "EclipseCase",
":/Case48x48.png",
"",
"",
"Reservoir",
"Abtract base class for Eclipse Cases" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "EclipseCase",
":/Case48x48.png",
"",
"",
"Reservoir",
"Abtract base class for Eclipse Cases" );
CAF_PDM_InitFieldNoDefault( &reservoirViews, "ReservoirViews", "", "", "", "" );
reservoirViews.uiCapability()->setUiHidden( true );

View File

@ -51,7 +51,12 @@ CAF_PDM_SOURCE_INIT( RimEclipseCellColors, "ResultSlot" );
//--------------------------------------------------------------------------------------------------
RimEclipseCellColors::RimEclipseCellColors()
{
RICF_InitObjectWithScriptNameAndComment( "Cell Result", ":/CellResult.png", "", "", "CellColors", "Eclipse Cell Colors class" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "Cell Result",
":/CellResult.png",
"",
"",
"CellColors",
"Eclipse Cell Colors class" );
CAF_PDM_InitFieldNoDefault( &obsoleteField_legendConfig, "LegendDefinition", "Color Legend", "", "", "" );
this->obsoleteField_legendConfig.xmlCapability()->setIOWritable( false );

View File

@ -53,12 +53,12 @@ const cvf::Mat4d RimEclipseContourMapView::sm_defaultViewMatrix =
RimEclipseContourMapView::RimEclipseContourMapView()
: m_cameraPositionLastUpdate( cvf::Vec3d::UNDEFINED )
{
RICF_InitObjectWithScriptNameAndComment( "Contour Map View",
":/2DMap16x16.png",
"",
"",
"EclipseContourMap",
"A contour map for Eclipse cases" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "Contour Map View",
":/2DMap16x16.png",
"",
"",
"EclipseContourMap",
"A contour map for Eclipse cases" );
CAF_PDM_InitFieldNoDefault( &m_contourMapProjection, "ContourMapProjection", "Contour Map Projection", "", "", "" );
m_contourMapProjection = new RimEclipseContourMapProjection();

View File

@ -70,7 +70,7 @@ CAF_PDM_SOURCE_INIT( RimEclipseResultCase, "EclipseCase" );
RimEclipseResultCase::RimEclipseResultCase()
: RimEclipseCase()
{
RICF_InitObject( "Eclipse Case", ":/Case48x48.png", "", "The Regular Eclipse Results Case" );
CAF_PDM_InitScriptableObject( "Eclipse Case", ":/Case48x48.png", "", "The Regular Eclipse Results Case" );
CAF_PDM_InitFieldNoDefault( &m_unitSystem, "UnitSystem", "Unit System", "", "", "" );
m_unitSystem.registerGetMethod( RiaApplication::instance()->project(), &RimProject::commonUnitSystemForAllCases );

View File

@ -95,7 +95,7 @@ RimEclipseResultDefinition::RimEclipseResultDefinition( caf::PdmUiItemInfo::Labe
, m_labelPosition( labelPosition )
, m_ternaryEnabled( true )
{
RICF_InitObjectWithScriptNameAndComment( "Result Definition", "", "", "", "EclipseResult", "An eclipse result definition" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "Result Definition", "", "", "", "EclipseResult", "An eclipse result definition" );
RICF_InitFieldNoDefault( &m_resultType, "ResultType", "Type", "", "", "" );
m_resultType.uiCapability()->setUiHidden( true );

View File

@ -121,12 +121,12 @@ RimEclipseView::RimEclipseView()
RiaPreferences* preferences = app->preferences();
CVF_ASSERT( preferences );
RICF_InitObjectWithScriptNameAndComment( "Reservoir View",
":/3DView16x16.png",
"",
"The Eclipse 3d Reservoir View",
"EclipseView",
"The Eclipse 3d Reservoir View" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "Reservoir View",
":/3DView16x16.png",
"",
"The Eclipse 3d Reservoir View",
"EclipseView",
"The Eclipse 3d Reservoir View" );
CAF_PDM_InitFieldNoDefault( &m_cellResult, "GridCellResult", "Cell Result", ":/CellResult.png", "", "" );
m_cellResult = new RimEclipseCellColors();

View File

@ -15,7 +15,12 @@ CAF_PDM_SOURCE_INIT( RimFileWellPath, "WellPath" );
//--------------------------------------------------------------------------------------------------
RimFileWellPath::RimFileWellPath()
{
RICF_InitObjectWithScriptNameAndComment( "File Well Path", ":/Well.png", "", "", "FileWellPath", "Well Paths Loaded From File" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "File Well Path",
":/Well.png",
"",
"",
"FileWellPath",
"Well Paths Loaded From File" );
CAF_PDM_InitFieldNoDefault( &id, "WellPathId", "Id", "", "", "" );
id.uiCapability()->setUiReadOnly( true );

View File

@ -69,12 +69,12 @@ CAF_PDM_SOURCE_INIT( RimGeoMechCase, "ResInsightGeoMechCase" );
RimGeoMechCase::RimGeoMechCase( void )
: m_applyTimeFilter( false )
{
RICF_InitObjectWithScriptNameAndComment( "GeoMechanical Case",
":/GeoMechCase48x48.png",
"",
"The GeoMechanical Results Case",
"GeoMechCase",
"The Abaqus Based GeoMech Case" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "GeoMechanical Case",
":/GeoMechCase48x48.png",
"",
"The GeoMechanical Results Case",
"GeoMechCase",
"The Abaqus Based GeoMech Case" );
CAF_PDM_InitFieldNoDefault( &geoMechViews, "GeoMechViews", "", "", "", "" );
geoMechViews.uiCapability()->setUiHidden( true );

View File

@ -51,12 +51,12 @@ const cvf::Mat4d RimGeoMechContourMapView::sm_defaultViewMatrix =
RimGeoMechContourMapView::RimGeoMechContourMapView()
: m_cameraPositionLastUpdate( cvf::Vec3d::UNDEFINED )
{
RICF_InitObjectWithScriptNameAndComment( "GeoMech Contour Map View",
":/2DMap16x16.png",
"",
"",
"GeoMechContourMap",
"A contour map for GeoMech cases" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "GeoMech Contour Map View",
":/2DMap16x16.png",
"",
"",
"GeoMechContourMap",
"A contour map for GeoMech cases" );
CAF_PDM_InitFieldNoDefault( &m_contourMapProjection, "ContourMapProjection", "Contour Map Projection", "", "", "" );
m_contourMapProjection = new RimGeoMechContourMapProjection();

View File

@ -85,7 +85,7 @@ CAF_PDM_SOURCE_INIT( RimGeoMechView, "GeoMechView" );
//--------------------------------------------------------------------------------------------------
RimGeoMechView::RimGeoMechView( void )
{
RICF_InitObject( "Geomechanical View", ":/3DViewGeoMech16x16.png", "", "The Geomechanical 3d View" );
CAF_PDM_InitScriptableObject( "Geomechanical View", ":/3DViewGeoMech16x16.png", "", "The Geomechanical 3d View" );
CAF_PDM_InitFieldNoDefault( &cellResult, "GridCellResult", "Color Result", ":/CellResult.png", "", "" );
cellResult = new RimGeoMechCellColors();

View File

@ -55,12 +55,12 @@ CAF_PDM_SOURCE_INIT( RimIdenticalGridCaseGroup, "RimIdenticalGridCaseGroup" );
//--------------------------------------------------------------------------------------------------
RimIdenticalGridCaseGroup::RimIdenticalGridCaseGroup()
{
RICF_InitObjectWithScriptNameAndComment( "Grid Case Group",
":/GridCaseGroup16x16.png",
"",
"",
"GridCaseGroup",
"A statistics case group" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "Grid Case Group",
":/GridCaseGroup16x16.png",
"",
"",
"GridCaseGroup",
"A statistics case group" );
RICF_InitField( &name, "UserDescription", QString( "Grid Case Group" ), "Name", "", "", "" );

View File

@ -40,7 +40,10 @@ CAF_PDM_SOURCE_INIT( RimModeledWellPath, "ModeledWellPath" );
//--------------------------------------------------------------------------------------------------
RimModeledWellPath::RimModeledWellPath()
{
RICF_InitObject( "Modeled WellPath", ":/EditableWell.png", "", "A Well Path created interactively in ResInsight" );
CAF_PDM_InitScriptableObject( "Modeled WellPath",
":/EditableWell.png",
"",
"A Well Path created interactively in ResInsight" );
CAF_PDM_InitFieldNoDefault( &m_geometryDefinition, "WellPathGeometryDef", "Trajectory", "", "", "" );
m_geometryDefinition = new RimWellPathGeometryDef;

View File

@ -33,7 +33,7 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimPlot, "RimPlot" ); // Do not use. Abstract
//--------------------------------------------------------------------------------------------------
RimPlot::RimPlot()
{
RICF_InitObjectWithScriptNameAndComment( "Plot", "", "", "", "Plot", "The Abstract Base Class for all Plot Objects" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "Plot", "", "", "", "Plot", "The Abstract Base Class for all Plot Objects" );
CAF_PDM_InitFieldNoDefault( &m_rowSpan, "RowSpan", "Row Span", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_colSpan, "ColSpan", "Col Span", "", "", "" );

View File

@ -37,12 +37,12 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimPlotWindow, "RimPlotWindow" ); // Do not us
//--------------------------------------------------------------------------------------------------
RimPlotWindow::RimPlotWindow()
{
RICF_InitObjectWithScriptNameAndComment( "PlotWindow",
"",
"",
"",
"PlotWindow",
"The Abstract base class for all MDI Windows in the Plot Window" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "PlotWindow",
"",
"",
"",
"PlotWindow",
"The Abstract base class for all MDI Windows in the Plot Window" );
RICF_InitField( &m_id, "Id", -1, "View ID", "", "", "" );
m_id.registerKeywordAlias( "ViewId" );

View File

@ -113,7 +113,7 @@ RimProject::RimProject( void )
, m_nextValidPlotId( 1 )
, m_nextValidCalculationId( 1 )
{
RICF_InitObjectWithScriptNameAndComment( "Project", "", "", "", "Project", "The ResInsight Project" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "Project", "", "", "", "Project", "The ResInsight Project" );
CAF_PDM_InitField( &m_projectFileVersionString, "ProjectFileVersionString", QString( STRPRODUCTVER ), "", "", "", "" );
m_projectFileVersionString.uiCapability()->setUiHidden( true );

View File

@ -62,7 +62,12 @@ CAF_PDM_SOURCE_INIT( RimSimWellInView, "Well" );
//--------------------------------------------------------------------------------------------------
RimSimWellInView::RimSimWellInView()
{
RICF_InitObjectWithScriptNameAndComment( "Simulation Well", ":/Well.png", "", "", "SimulationWell", "An Eclipse Simulation Well" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "Simulation Well",
":/Well.png",
"",
"",
"SimulationWell",
"An Eclipse Simulation Well" );
RICF_InitFieldNoDefault( &name, "Name", "Name", "", "", "" );
name.registerKeywordAlias( "WellName" );

View File

@ -43,12 +43,12 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimViewWindow, "ViewWindow" ); // Do not use.
//--------------------------------------------------------------------------------------------------
RimViewWindow::RimViewWindow( void )
{
RICF_InitObjectWithScriptNameAndComment( "View window",
"",
"",
"",
"ViewWindow",
"The Base Class for all Views and Plots in ResInsight" );
CAF_PDM_InitScriptableObjectWithNameAndComment( "View window",
"",
"",
"",
"ViewWindow",
"The Base Class for all Views and Plots in ResInsight" );
CAF_PDM_InitFieldNoDefault( &m_windowController, "WindowController", "", "", "", "" );
m_windowController.uiCapability()->setUiHidden( true );

View File

@ -33,7 +33,7 @@ CAF_PDM_SOURCE_INIT( RimWbsParameters, "WbsParameters" );
//--------------------------------------------------------------------------------------------------
RimWbsParameters::RimWbsParameters()
{
RICF_InitObject( "Well Bore Stability Parameters", ":/WellLogPlot16x16.png", "", "" );
CAF_PDM_InitScriptableObject( "Well Bore Stability Parameters", ":/WellLogPlot16x16.png", "", "" );
RICF_InitFieldNoDefault( &m_porePressureSource,
"PorePressureReservoirSource",

View File

@ -42,7 +42,10 @@ CAF_PDM_SOURCE_INIT( RimWellBoreStabilityPlot, "WellBoreStabilityPlot" );
//--------------------------------------------------------------------------------------------------
RimWellBoreStabilityPlot::RimWellBoreStabilityPlot()
{
RICF_InitObject( "Well Bore Stability Plot", ":/WellBoreStability16x16.png", "", "A GeoMechanical Well Bore Stabilit Plot" );
CAF_PDM_InitScriptableObject( "Well Bore Stability Plot",
":/WellBoreStability16x16.png",
"",
"A GeoMechanical Well Bore Stabilit Plot" );
CAF_PDM_InitFieldNoDefault( &m_wbsParameters, "WbsParameters", "Well Bore Stability Parameters", "", "", "" );
m_wbsParameters = new RimWbsParameters;

View File

@ -71,10 +71,10 @@ CAF_PDM_SOURCE_INIT( RimWellLogPlot, "WellLogPlot" );
//--------------------------------------------------------------------------------------------------
RimWellLogPlot::RimWellLogPlot()
{
RICF_InitObject( "Well Log Plot",
":/WellLogPlot16x16.png",
"",
"A Well Log Plot With a shared Depth Axis and Multiple Tracks" );
CAF_PDM_InitScriptableObject( "Well Log Plot",
":/WellLogPlot16x16.png",
"",
"A Well Log Plot With a shared Depth Axis and Multiple Tracks" );
CAF_PDM_InitFieldNoDefault( &m_commonDataSource,
"CommonDataSource",

View File

@ -73,7 +73,7 @@ const char RimWellPath::SIM_WELL_NONE_UI_TEXT[] = "None";
//--------------------------------------------------------------------------------------------------
RimWellPath::RimWellPath()
{
RICF_InitObject( "WellPath", ":/Well.png", "", "The Base class for Well Paths" );
CAF_PDM_InitScriptableObject( "WellPath", ":/Well.png", "", "The Base class for Well Paths" );
RICF_InitFieldNoDefault( &m_name, "Name", "Name", "", "", "" );
m_name.registerKeywordAlias( "WellPathName" );

View File

@ -42,7 +42,7 @@ CAF_PDM_SOURCE_INIT( RimFileSummaryCase, "FileSummaryCase" );
//--------------------------------------------------------------------------------------------------
RimFileSummaryCase::RimFileSummaryCase()
{
RICF_InitObject( "File Summary Case ", "", "", "A Summary Case based on SMSPEC files" );
CAF_PDM_InitScriptableObject( "File Summary Case ", "", "", "A Summary Case based on SMSPEC files" );
CAF_PDM_InitField( &m_includeRestartFiles, "IncludeRestartFiles", false, "Include Restart Files", "", "", "" );
m_includeRestartFiles.uiCapability()->setUiHidden( true );

View File

@ -40,7 +40,7 @@ CAF_PDM_SOURCE_INIT( RimGridSummaryCase, "GridSummaryCase" );
//--------------------------------------------------------------------------------------------------
RimGridSummaryCase::RimGridSummaryCase()
{
RICF_InitObject( "Grid Summary Case ", "", "", "A Summary Case based on extracting grid data." );
CAF_PDM_InitScriptableObject( "Grid Summary Case ", "", "", "A Summary Case based on extracting grid data." );
CAF_PDM_InitFieldNoDefault( &m_eclipseCase, "Associated3DCase", "Eclipse Case", "", "", "" );
m_eclipseCase.uiCapability()->setUiHidden( true );

View File

@ -44,7 +44,7 @@ const QString RimSummaryCase::DEFAULT_DISPLAY_NAME = "Display Name";
//--------------------------------------------------------------------------------------------------
RimSummaryCase::RimSummaryCase()
{
RICF_InitObject( "Summary Case", ":/SummaryCase16x16.png", "", "The Base Class for all Summary Cases" );
CAF_PDM_InitScriptableObject( "Summary Case", ":/SummaryCase16x16.png", "", "The Base Class for all Summary Cases" );
RICF_InitField( &m_shortName, "ShortName", QString( "Display Name" ), DEFAULT_DISPLAY_NAME, "", "", "" );
RICF_InitField( &m_useAutoShortName, "AutoShortyName", false, "Use Auto Display Name", "", "", "" );

View File

@ -143,7 +143,7 @@ CurvesData concatCurvesData( const std::vector<CurvesData>& curvesData );
RimSummaryPlot::RimSummaryPlot()
: RimPlot()
{
RICF_InitObject( "Summary Plot", ":/SummaryPlotLight16x16.png", "", "A Summary Plot" );
CAF_PDM_InitScriptableObject( "Summary Plot", ":/SummaryPlotLight16x16.png", "", "A Summary Plot" );
RICF_InitField( &m_showPlotTitle, "ShowPlotTitle", true, "Plot Title", "", "", "" );
m_showPlotTitle.xmlCapability()->setIOWritable( false );

View File

@ -382,10 +382,13 @@ add_subdirectory(Fwk/AppFwk/cafUserInterface)
add_subdirectory(Fwk/AppFwk/cafPdmCvf)
add_subdirectory(Fwk/AppFwk/CommonCode)
add_subdirectory(Fwk/AppFwk/cafVizExtensions)
add_subdirectory(Fwk/AppFwk/cafPdmScripting)
set_property(TARGET cafPdmScripting PROPERTY FOLDER "AppFwk")
add_subdirectory(Fwk/AppFwk/cafCommandFeatures)
set_property(TARGET cafCommandFeatures PROPERTY FOLDER "AppFwk")
#add_subdirectory(Fwk/AppFwk/cafTests/cafTestCvfApplication)
add_subdirectory(Fwk/AppFwk/cafTensor)
@ -403,9 +406,10 @@ list(APPEND APP_FWK_LIBRARIES
cafCommand
cafPdmCvf
cafTensor
cafTensor
CommonCode
cafVizExtensions
cafPdmScripting
)
set_property(TARGET

View File

@ -47,6 +47,7 @@ add_subdirectory(cafProjectDataModel)
add_subdirectory(cafCommand)
add_subdirectory(cafCommandFeatures)
add_subdirectory(cafUserInterface)
add_subdirectory(cafPdmScripting)
#executables
add_subdirectory(cafTests/cafTestApplication)
@ -59,6 +60,7 @@ add_subdirectory (cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests)
add_subdirectory (cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests)
add_subdirectory (cafProjectDataModel/cafProjectDataModel_UnitTests)
add_subdirectory (cafUserInterface/cafUserInterface_UnitTests)
#add_subdirectory(cafPdmScripting/cafPdmScripting_UnitTests)
# Organize sub-projects into folders on Visual Studio
# Turn on using solution folders

View File

@ -0,0 +1,32 @@
cmake_minimum_required (VERSION 2.8.12)
project (cafPdmScripting)
set( PROJECT_FILES
cafPdmCodeGenerator.h
cafPdmFieldScriptability.h
cafPdmFieldScriptability.cpp
cafPdmObjectScriptabilityRegister.h
cafPdmObjectScriptabilityRegister.cpp
cafPdmPythonGenerator.h
cafPdmPythonGenerator.cpp
)
add_library( ${PROJECT_NAME}
${PROJECT_FILES}
)
target_include_directories(${PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
target_link_libraries( ${PROJECT_NAME} cafProjectDataModel ${QT_LIBRARIES} )
source_group("" FILES ${PROJECT_FILES})
# cotire
if (COMMAND caf_apply_cotire)
caf_apply_cotire("${PROJECT_NAME}")
endif()

View File

@ -0,0 +1,67 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions 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.
//
//##################################################################################################
#pragma once
#include "cafFactory.h"
#include <QString>
#define CAF_PDM_CODE_GENERATOR_HEADER_INIT \
public: \
static const std::string& fileExtension();
#define CAF_PDM_CODE_GENERATOR_SOURCE_INIT(ClassName, FileExtension)\
const std::string& ClassName::fileExtension() { static std::string ext = FileExtension; return ext;} \
CAF_FACTORY_REGISTER(caf::PdmCodeGenerator, ClassName, std::string, ClassName::fileExtension())
namespace caf {
class PdmObjectFactory;
//==================================================================================================
/// Abstract skeleton code generator for the Project Data Model
//==================================================================================================
class PdmCodeGenerator
{
public:
virtual QString generate(PdmObjectFactory* factory) const = 0;
};
typedef Factory<PdmCodeGenerator, std::string> PdmCodeGeneratorFactory;
}

View File

@ -0,0 +1,84 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions 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 "cafPdmFieldScriptability.h"
#include "cafPdmFieldHandle.h"
using namespace caf;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmFieldScriptability::PdmFieldScriptability(caf::PdmFieldHandle* owner, const QString& scriptFieldName, bool giveOwnership)
{
m_IOWriteable = true;
m_owner = owner;
m_scriptFieldName = scriptFieldName;
owner->addCapability(this, giveOwnership);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmFieldScriptability::~PdmFieldScriptability()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QString PdmFieldScriptability::scriptFieldName() const
{
return m_scriptFieldName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool PdmFieldScriptability::isIOWriteable() const
{
return m_IOWriteable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptability::setIOWriteable(bool writeable)
{
m_IOWriteable = writeable;
}

View File

@ -0,0 +1,63 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions 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.
//
//##################################################################################################
#pragma once
#include <QString>
#include "cafPdmFieldCapability.h"
namespace caf {
class PdmFieldHandle;
class PdmFieldScriptability : public PdmFieldCapability
{
public:
PdmFieldScriptability(caf::PdmFieldHandle* owner, const QString& scriptFieldName, bool giveOwnership);
virtual ~PdmFieldScriptability();
const QString scriptFieldName() const;
bool isIOWriteable() const;
void setIOWriteable(bool writeable);
private:
caf::PdmFieldHandle* m_owner;
QString m_scriptFieldName;
bool m_IOWriteable;
};
}

View File

@ -0,0 +1,103 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions 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 "cafPdmObjectScriptabilityRegister.h"
#include "cafPdmObject.h"
using namespace caf;
std::map<QString, QString> PdmObjectScriptabilityRegister::s_classKeywordToScriptClassName;
std::map<QString, QString> PdmObjectScriptabilityRegister::s_scriptClassNameToClassKeyword;
std::map<QString, QString> PdmObjectScriptabilityRegister::s_scriptClassComments;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmObjectScriptabilityRegister::registerScriptClassNameAndComment(const QString& classKeyword,
const QString& scriptClassName,
const QString& scriptClassComment)
{
s_classKeywordToScriptClassName[classKeyword] = scriptClassName;
s_scriptClassNameToClassKeyword[scriptClassName] = classKeyword;
s_scriptClassComments[classKeyword] = scriptClassComment;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmObjectScriptabilityRegister::scriptClassNameFromClassKeyword(const QString& classKeyword)
{
auto it = s_classKeywordToScriptClassName.find(classKeyword);
if (it != s_classKeywordToScriptClassName.end())
{
return it->second;
}
return classKeyword;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmObjectScriptabilityRegister::classKeywordFromScriptClassName(const QString& scriptClassName)
{
auto it = s_scriptClassNameToClassKeyword.find(scriptClassName);
if (it != s_scriptClassNameToClassKeyword.end())
{
return it->second;
}
return scriptClassName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmObjectScriptabilityRegister::scriptClassComment(const QString& classKeyword)
{
auto it = s_scriptClassComments.find(classKeyword);
if (it != s_scriptClassComments.end())
{
return it->second;
}
return "";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool PdmObjectScriptabilityRegister::isScriptable(const caf::PdmObject* object)
{
return s_classKeywordToScriptClassName.find(object->classKeyword()) != s_classKeywordToScriptClassName.end();
}

View File

@ -0,0 +1,75 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions 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.
//
//##################################################################################################
#pragma once
#include <QString>
#include <map>
#define CAF_PDM_InitScriptableObject( uiName, iconResourceName, toolTip, whatsThis ) \
CAF_PDM_InitObject( uiName, iconResourceName, toolTip, whatsThis ); \
caf::PdmObjectScriptabilityRegister::registerScriptClassNameAndComment( classKeyword(), classKeyword(), whatsThis );
#define CAF_PDM_InitScriptableObjectWithNameAndComment( uiName, iconResourceName, toolTip, whatsThis, scriptClassName, scriptComment ) \
CAF_PDM_InitObject( uiName, iconResourceName, toolTip, whatsThis ); \
caf::PdmObjectScriptabilityRegister::registerScriptClassNameAndComment( classKeyword(), scriptClassName, scriptComment );
namespace caf {
class PdmObject;
//==================================================================================================
/// Static register for object scriptability.
//==================================================================================================
class PdmObjectScriptabilityRegister
{
public:
static void registerScriptClassNameAndComment(const QString& classKeyword,
const QString& scriptClassName,
const QString& scriptClassComment);
static QString scriptClassNameFromClassKeyword(const QString& classKeyword);
static QString classKeywordFromScriptClassName(const QString& scriptClassName);
static QString scriptClassComment(const QString& classKeyword);
static bool isScriptable(const caf::PdmObject* object);
private:
static std::map<QString, QString> s_classKeywordToScriptClassName;
static std::map<QString, QString> s_scriptClassNameToClassKeyword;
static std::map<QString, QString> s_scriptClassComments;
};
}

View File

@ -0,0 +1,298 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions 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 "cafPdmPythonGenerator.h"
#include "cafPdmFieldScriptability.h"
#include "cafPdmObject.h"
#include "cafPdmObjectFactory.h"
#include "cafPdmObjectScriptabilityRegister.h"
#include "cafPdmProxyValueField.h"
#include <QRegularExpression>
#include <QTextStream>
#include <list>
#include <memory>
#include <set>
using namespace caf;
CAF_PDM_CODE_GENERATOR_SOURCE_INIT(PdmPythonGenerator, "py");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const
{
QString generatedCode;
QTextStream out(&generatedCode);
std::vector<QString> classKeywords = factory->classKeywords();
std::vector<std::shared_ptr<const PdmObject>> dummyObjects;
for (QString classKeyword : classKeywords)
{
auto objectHandle = factory->create(classKeyword);
const PdmObject* object = dynamic_cast<const PdmObject*>(objectHandle);
CAF_ASSERT(object);
std::shared_ptr<const PdmObject> sharedObject(object);
if (PdmObjectScriptabilityRegister::isScriptable(sharedObject.get()))
{
dummyObjects.push_back(sharedObject);
}
}
// Sort to make sure super classes get created before sub classes
std::sort(dummyObjects.begin(),
dummyObjects.end(),
[](std::shared_ptr<const PdmObject> lhs, std::shared_ptr<const PdmObject> rhs) {
if (lhs->inheritsClassWithKeyword(rhs->classKeyword()))
{
return false;
}
return lhs->classKeyword() < rhs->classKeyword();
});
std::map<QString, std::map<QString, std::pair<QString, QString>>> classAttributesGenerated;
std::map<QString, std::map<QString, QString>> classMethodsGenerated;
std::map<QString, QString> classCommentsGenerated;
// First generate all attributes and comments to go into each object
for (std::shared_ptr<const PdmObject> object : dummyObjects)
{
const std::list<QString>& classInheritanceStack = object->classInheritanceStack();
for (auto it = classInheritanceStack.begin(); it != classInheritanceStack.end(); ++it)
{
const QString& classKeyword = *it;
QString scriptClassComment = PdmObjectScriptabilityRegister::scriptClassComment(classKeyword);
std::map<QString, QString> attributesGenerated;
if (!scriptClassComment.isEmpty()) classCommentsGenerated[classKeyword] = scriptClassComment;
if (classKeyword == object->classKeyword())
{
std::vector<PdmFieldHandle*> fields;
object->fields(fields);
for (auto field : fields)
{
auto pdmValueField = dynamic_cast<const PdmValueField*>(field);
if (pdmValueField)
{
QString keyword = pdmValueField->keyword();
auto scriptability = field->template capability<PdmFieldScriptability>();
if (scriptability != nullptr)
{
bool shouldBeMethod = false;
auto proxyField = dynamic_cast<const PdmProxyFieldHandle*>(field);
if (proxyField && proxyField->isStreamingField()) shouldBeMethod = true;
QString snake_field_name = camelToSnakeCase(scriptability->scriptFieldName());
if (classAttributesGenerated[field->ownerClass()].count(snake_field_name)) continue;
if (classMethodsGenerated[field->ownerClass()].count(snake_field_name)) continue;
QString comment;
{
QStringList commentComponents;
commentComponents << pdmValueField->capability<PdmUiFieldHandle>()->uiName();
commentComponents << pdmValueField->capability<PdmUiFieldHandle>()->uiWhatsThis();
commentComponents.removeAll(QString(""));
comment = commentComponents.join(". ");
}
QVariant valueVariant = pdmValueField->toQVariant();
QString dataTypeString = valueVariant.typeName();
if (shouldBeMethod)
{
if (proxyField->hasGetter())
{
QString fullComment =
QString(" \"\"\"%1\n Returns:\n %2\n \"\"\"")
.arg(comment)
.arg(dataTypeString);
QString fieldCode = QString(" def %1(self):\n%2\n return "
"self._call_get_method(\"%3\")\n")
.arg(snake_field_name)
.arg(fullComment)
.arg(scriptability->scriptFieldName());
classMethodsGenerated[field->ownerClass()][snake_field_name] = fieldCode;
}
if (proxyField->hasSetter())
{
QString fullComment = QString(" \"\"\"Set %1\n Attributes:\n"
" values (%2): data\n \"\"\"")
.arg(comment)
.arg(dataTypeString);
QString fieldCode = QString(" def set_%1(self, values):\n%2\n "
"self._call_set_method(\"%3\", values)\n")
.arg(snake_field_name)
.arg(fullComment)
.arg(scriptability->scriptFieldName());
classMethodsGenerated[field->ownerClass()][QString("set_%1").arg(snake_field_name)] =
fieldCode;
}
}
else
{
QString fieldCode = QString(" self.%1 = None\n").arg(snake_field_name);
QString fullComment =
QString("%1 (%2): %3\n").arg(snake_field_name).arg(dataTypeString).arg(comment);
classAttributesGenerated[field->ownerClass()][snake_field_name].first = fieldCode;
classAttributesGenerated[field->ownerClass()][snake_field_name].second = fullComment;
}
}
}
}
}
}
}
// Write out classes
std::set<QString> classesWritten;
for (std::shared_ptr<const PdmObject> object : dummyObjects)
{
const std::list<QString>& classInheritanceStack = object->classInheritanceStack();
std::list<QString> scriptSuperClassNames;
for (auto it = classInheritanceStack.begin(); it != classInheritanceStack.end(); ++it)
{
const QString& classKeyword = *it;
QString scriptClassName = PdmObjectScriptabilityRegister::scriptClassNameFromClassKeyword(classKeyword);
if (scriptClassName.isEmpty()) scriptClassName = classKeyword;
if (!classesWritten.count(scriptClassName))
{
QString classCode;
if (scriptSuperClassNames.empty())
{
classCode = QString("class %1:\n").arg(scriptClassName);
}
else
{
classCode = QString("class %1(%2):\n").arg(scriptClassName).arg(scriptSuperClassNames.back());
}
if (!classCommentsGenerated[classKeyword].isEmpty() || !classAttributesGenerated[classKeyword].empty())
{
classCode += " \"\"\"\n";
if (!classCommentsGenerated[classKeyword].isEmpty())
{
if (!classCommentsGenerated[classKeyword].isEmpty())
{
classCode += QString(" %1\n\n").arg(classCommentsGenerated[classKeyword]);
}
}
if (!classAttributesGenerated[classKeyword].empty())
{
classCode += " Attributes\n";
for (auto keyWordValuePair : classAttributesGenerated[classKeyword])
{
classCode += " " + keyWordValuePair.second.second;
}
}
classCode += " \"\"\"\n";
}
classCode +=
QString(" __custom_init__ = None #: Assign a custom init routine to be run at __init__\n\n");
classCode += QString(" def __init__(self, pb2_object=None, channel=None):\n");
classCode += QString(" self.class_keyword = \"%1\"\n").arg(scriptClassName);
if (!scriptSuperClassNames.empty())
{
// Own attributes. This initializes a lot of attributes to None.
// This means it has to be done before we set any values.
for (auto keyWordValuePair : classAttributesGenerated[classKeyword])
{
classCode += keyWordValuePair.second.first;
}
// Parent constructor
classCode +=
QString(" %1.__init__(self, pb2_object, channel)\n").arg(scriptSuperClassNames.back());
}
classCode += QString(" if %1.__custom_init__ is not None:\n").arg(scriptClassName);
classCode += QString(" %1.__custom_init__(self, pb2_object=pb2_object, channel=channel)\n")
.arg(scriptClassName);
for (auto keyWordValuePair : classMethodsGenerated[classKeyword])
{
classCode += "\n";
classCode += keyWordValuePair.second;
classCode += "\n";
}
out << classCode << "\n";
classesWritten.insert(scriptClassName);
}
scriptSuperClassNames.push_back(scriptClassName);
}
}
out << "def class_dict():\n";
out << " classes = {}\n";
for (QString classKeyword : classesWritten)
{
out << QString(" classes['%1'] = %1\n").arg(classKeyword);
}
out << " return classes\n\n";
out << "def class_from_keyword(class_keyword):\n";
out << " all_classes = class_dict()\n";
out << " if class_keyword in all_classes.keys():\n";
out << " return all_classes[class_keyword]\n";
out << " return None\n";
return generatedCode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmPythonGenerator::camelToSnakeCase(const QString& camelString)
{
static QRegularExpression re1("(.)([A-Z][a-z]+)");
static QRegularExpression re2("([a-z0-9])([A-Z])");
QString snake_case = camelString;
snake_case.replace(re1, "\\1_\\2");
snake_case.replace(re2, "\\1_\\2");
return snake_case.toLower();
}

View File

@ -0,0 +1,53 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions 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.
//
//##################################################################################################
#pragma once
#include "cafPdmCodeGenerator.h"
namespace caf {
//==================================================================================================
/// Python skeleton generator from Project Data Model
//==================================================================================================
class PdmPythonGenerator : public PdmCodeGenerator
{
CAF_PDM_CODE_GENERATOR_HEADER_INIT;
public:
QString generate(PdmObjectFactory* factory) const override;
static QString camelToSnakeCase(const QString& camelString);
};
}

View File

@ -87,7 +87,7 @@ public:
return true;
}
std::vector<QString> classKeywords() const;
std::vector<QString> classKeywords() const override;
private:
PdmDefaultObjectFactory() {}

View File

@ -37,6 +37,8 @@
#pragma once
#include <vector>
class QString;
namespace caf
@ -56,7 +58,7 @@ class PdmObjectFactory
public:
virtual PdmObjectHandle* create(const QString& classNameKeyword) = 0;
virtual std::vector<QString> classKeywords() const = 0;
protected:
PdmObjectFactory() {}
virtual ~PdmObjectFactory() {}

View File

@ -19,6 +19,7 @@ add_subdirectory(AppFwk/cafProjectDataModel/cafPdmXml)
add_subdirectory(AppFwk/cafProjectDataModel)
add_subdirectory(AppFwk/cafCommand)
add_subdirectory(AppFwk/cafUserInterface)
add_subdirectory(AppFwk/cafPdmScripting)
# Unit Tests
add_subdirectory(AppFwk/cafProjectDataModel/cafProjectDataModel_UnitTests)