From 871973d02a86c71479e5db2229352b5640218eed Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 6 Aug 2025 15:49:29 +0200 Subject: [PATCH] Adds support for std::optional PdmFields --- .../cafPdmFieldScriptingCapability.h | 53 +++++++++++++ .../cafPdmScripting/cafPdmPythonGenerator.cpp | 16 ++-- .../cafMockObjects.cpp | 2 + .../cafMockObjects.h | 5 +- .../cafPdmFieldSerializationTest.cpp | 57 +++++++++++++ .../cafInternalPdmFieldTypeSpecializations.h | 79 ++++++++++++++----- .../cafPdmUiFieldSpecialization.h | 16 ++-- .../cafPdmXml/cafInternalPdmStreamOperators.h | 40 ++++++++++ .../AggregatedTypesInField.cpp | 16 +++- .../cafTestApplication/CMakeLists.txt | 2 + .../cafTestApplication/MainWindow.cpp | 2 + .../cafTestApplication/OptionalFields.cpp | 25 ++++++ .../cafTestApplication/OptionalFields.h | 17 ++++ 13 files changed, 289 insertions(+), 41 deletions(-) create mode 100644 Fwk/AppFwk/cafTests/cafTestApplication/OptionalFields.cpp create mode 100644 Fwk/AppFwk/cafTests/cafTestApplication/OptionalFields.h diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmFieldScriptingCapability.h b/Fwk/AppFwk/cafPdmScripting/cafPdmFieldScriptingCapability.h index 90679f98bb..888258a3a3 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmFieldScriptingCapability.h +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmFieldScriptingCapability.h @@ -317,6 +317,59 @@ struct PdmFieldScriptingCapabilityIOHandler> } }; +template +struct PdmFieldScriptingCapabilityIOHandler> +{ + static void writeToField( std::optional& fieldValue, + QTextStream& inputStream, + PdmScriptIOMessages* errorMessageContainer, + bool stringsAreQuoted = true ) + { + QString textValue; + + PdmFieldScriptingCapabilityIOHandler::writeToField( textValue, + inputStream, + errorMessageContainer, + stringsAreQuoted ); + textValue.remove( '"' ); + if ( !textValue.isEmpty() ) + { + QTextStream singleValueStream( &textValue ); + T singleValue; + bool noStringQuotes = false; + PdmFieldScriptingCapabilityIOHandler::writeToField( singleValue, + singleValueStream, + errorMessageContainer, + noStringQuotes ); + fieldValue = singleValue; + } + else + { + fieldValue.reset(); + } + } + + static void readFromField( const std::optional& fieldValue, + QTextStream& outputStream, + bool quoteStrings = true, + bool quoteNonBuiltins = false ) + { + QString textValue; + + if ( fieldValue.has_value() ) + { + QTextStream singleValueStream( &textValue ); + singleValueStream << fieldValue.value(); + } + else + { + textValue = ""; + } + + PdmFieldScriptingCapabilityIOHandler::readFromField( textValue, outputStream, quoteStrings, quoteNonBuiltins ); + } +}; + template struct PdmFieldScriptingCapabilityIOHandler> { diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp index 2d662051c5..e5aa85c2c0 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp @@ -192,15 +192,14 @@ QString caf::PdmPythonGenerator::generate( PdmObjectFactory* factory, std::vecto } else { - QString valueString = getDefaultValue( field ); - - if ( valueString == "None" ) + QString defaultValue = getDefaultValue( field ); + if ( !dataType.contains( "Optional" ) && defaultValue == "None" ) { dataType = QString( "Optional[%1]" ).arg( dataType ); } QString fieldCode = - QString( " self.%1: %2 = %3\n" ).arg( snake_field_name ).arg( dataType ).arg( valueString ); + QString( " self.%1: %2 = %3\n" ).arg( snake_field_name ).arg( dataType ).arg( defaultValue ); QString fullComment; { @@ -312,7 +311,7 @@ QString caf::PdmPythonGenerator::generate( PdmObjectFactory* factory, std::vecto if ( isList ) dataType = QString( "List[%1]" ).arg( dataType ); QString defaultValue = getDefaultValue( field ); - if ( defaultValue == "None" ) + if ( !dataType.contains( "Optional" ) && defaultValue == "None" ) { dataType = QString( "Optional[%1]" ).arg( dataType ); } @@ -508,7 +507,7 @@ QString PdmPythonGenerator::getDefaultValue( PdmFieldHandle* field ) scriptability->readFromField( valueStream, true, true ); } - if ( valueString.isEmpty() ) + if ( valueString == "\"\"" || valueString.isEmpty() ) { valueString = defaultValue; } @@ -556,6 +555,11 @@ QString PdmPythonGenerator::dataTypeString( const PdmFieldHandle* field, bool us { QString::fromStdString( typeid( QString ).name() ), "str" }, { QString::fromStdString( typeid( caf::FilePath ).name() ), "str" }, { QString::fromStdString( typeid( std::vector ).name() ), "List[float]" }, + { QString::fromStdString( typeid( std::optional ).name() ), "Optional[double]" }, + { QString::fromStdString( typeid( std::optional ).name() ), "Optional[float]" }, + { QString::fromStdString( typeid( std::optional ).name() ), "Optional[int]" }, + { QString::fromStdString( typeid( std::optional ).name() ), "Optional[bool]" }, + { QString::fromStdString( typeid( std::optional ).name() ), "Optional[str]" }, }; #ifndef CAF_EXCLUDE_CVF diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafMockObjects.cpp b/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafMockObjects.cpp index 654fc6916b..436b538843 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafMockObjects.cpp +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafMockObjects.cpp @@ -130,6 +130,8 @@ InheritedDemoObj::InheritedDemoObj() CAF_PDM_InitScriptableFieldNoDefault( &m_texts, "Texts", "Some words" ); CAF_PDM_InitScriptableFieldNoDefault( &m_numbers, "Numbers", "Some words" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_optionalNumber, "OptionalNumber", "Optional Number" ); + CAF_PDM_InitFieldNoDefault( &m_testEnumField, "TestEnumValue", "An Enum" ); CAF_PDM_InitFieldNoDefault( &m_simpleObjectsField, "SimpleObjects", diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafMockObjects.h b/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafMockObjects.h index b5e5d9f306..bdf615441f 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafMockObjects.h +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafMockObjects.h @@ -81,8 +81,9 @@ public: InheritedDemoObj(); - caf::PdmField> m_texts; - caf::PdmField> m_numbers; + caf::PdmField> m_texts; + caf::PdmField> m_numbers; + caf::PdmField> m_optionalNumber; caf::PdmField> m_testEnumField; caf::PdmChildArrayField m_simpleObjectsField; diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafPdmFieldSerializationTest.cpp b/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafPdmFieldSerializationTest.cpp index e772c21afb..42bf527648 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafPdmFieldSerializationTest.cpp +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmScripting_UnitTests/cafPdmFieldSerializationTest.cpp @@ -126,3 +126,60 @@ TEST( PdmFieldSerialization, ValueList ) EXPECT_FLOAT_EQ( floatValues[i], result[i] ); } } + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +TEST( PdmFieldSerialization, OptionalValues ) +{ + { + std::optional optionalString = std::nullopt; + QString text; + QTextStream stream( &text ); + + caf::PdmScriptIOMessages messages; + bool stringsAreQuoted = true; + + caf::PdmFieldScriptingCapabilityIOHandler>::readFromField( optionalString, + stream, + &messages, + stringsAreQuoted ); + + const QString expected = "\"\""; + EXPECT_STREQ( expected.toStdString().c_str(), text.toStdString().c_str() ); + + std::optional result; + caf::PdmFieldScriptingCapabilityIOHandler>::writeToField( result, + stream, + &messages, + stringsAreQuoted ); + + EXPECT_FALSE( result.has_value() ); + } + + { + QString sourceText = "Test string with spaces"; + std::optional optionalString = sourceText; + + QString text; + QTextStream stream( &text ); + + caf::PdmScriptIOMessages messages; + bool stringsAreQuoted = true; + + caf::PdmFieldScriptingCapabilityIOHandler>::readFromField( optionalString, + stream, + &messages, + stringsAreQuoted ); + + const QString expected = "\"Test string with spaces\""; + EXPECT_STREQ( expected.toStdString().c_str(), text.toStdString().c_str() ); + + std::optional result; + caf::PdmFieldScriptingCapabilityIOHandler>::writeToField( result, + stream, + &messages, + stringsAreQuoted ); + + EXPECT_STREQ( sourceText.toStdString().c_str(), result.value().toStdString().c_str() ); + } +} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmFieldTypeSpecializations.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmFieldTypeSpecializations.h index 99375ea01e..8b1ff17289 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmFieldTypeSpecializations.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmFieldTypeSpecializations.h @@ -56,7 +56,6 @@ template class PdmUiFieldSpecialization> { public: - /// Convert the field value into a QVariant static QVariant convert( const std::list& value ) { QList returnList; @@ -68,7 +67,6 @@ public: return returnList; } - /// Set the field value from a QVariant static void setFromVariant( const QVariant& variantValue, std::list& value ) { if ( variantValue.canConvert>() ) @@ -83,19 +81,16 @@ public: } } - /// Operates on scalar content T value of the std::list static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 ) { return PdmValueFieldSpecialization::isEqual( variantValue, variantValue2 ); } - /// Methods to get a list of options for a field, specialized for AppEnum static QList valueOptions( QString keyword, const std::list& ) { return QList(); } - /// Methods to retrieve the possible PdmObject pointed to by a field static void childObjects( const PdmDataValueField>&, std::vector* ) {} }; @@ -107,31 +102,26 @@ template class PdmUiFieldSpecialization> { public: - /// Convert the field value into a QVariant static QVariant convert( const std::vector& value ) { return PdmValueFieldSpecialization>::convert( value ); } - /// Set the field value from a QVariant static void setFromVariant( const QVariant& variantValue, std::vector& value ) { return PdmValueFieldSpecialization>::setFromVariant( variantValue, value ); } - /// Operates on scalar content T value of the std::vector static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 ) { return PdmValueFieldSpecialization::isEqual( variantValue, variantValue2 ); } - /// Methods to get a list of options for a field, specialized for AppEnum static QList valueOptions( QString keyword, const std::vector& ) { return QList(); } - /// Methods to retrieve the possible PdmObject pointed to by a field static void childObjects( const PdmDataValueField>& field, std::vector* objects ) { } @@ -140,20 +130,18 @@ public: //================================================================================================== /// Partial specialization for PdmField< caf::AppEnum > //================================================================================================== - template class PdmUiFieldSpecialization> { public: - /// Convert the field value into a QVariant static QVariant convert( const caf::AppEnum& value ) { T enumVal = value; + // Explicit cast to an int for storage in a QVariant. This allows the use of enum class instead of enum return QVariant( static_cast( enumVal ) ); } - /// Set the field value from a QVariant static void setFromVariant( const QVariant& variantValue, caf::AppEnum& value ) { value = static_cast( variantValue.toInt() ); @@ -164,7 +152,6 @@ public: return variantValue == variantValue2; } - /// Methods to get a list of options for a field, specialized for AppEnum static QList valueOptions( QString keyword, const caf::AppEnum& appEnum ) { QList optionList; @@ -187,23 +174,23 @@ public: return optionList; } - /// Methods to retrieve the possible PdmObject pointed to by a field static void childObjects( const PdmDataValueField>& field, std::vector* objects ) { } }; +//================================================================================================== +/// Partial specialization for PdmField>> +//================================================================================================== template class PdmUiFieldSpecialization> { public: - /// Convert the field value into a QVariant static QVariant convert( const std::pair& value ) { return PdmValueFieldSpecialization>::convert( value ); } - /// Set the field value from a QVariant static void setFromVariant( const QVariant& variantValue, std::pair& value ) { PdmValueFieldSpecialization>::setFromVariant( variantValue, value ); @@ -214,7 +201,6 @@ public: return variantValue == variantValue2; } - /// Methods to get a list of options for a field, specialized for AppEnum static QList valueOptions( QString keyword, const std::pair& ) { QList optionList; @@ -222,8 +208,61 @@ public: return optionList; } + static void childObjects( const PdmDataValueField>& field, std::vector* objects ) + { + } +}; + +//================================================================================================== +/// Partial specialization for PdmField>> +//================================================================================================== +template +class PdmUiFieldSpecialization> +{ +public: + /// Convert the field value into a QVariant + static QVariant convert( const std::optional& value ) + { + if ( value.has_value() ) + { + return PdmValueFieldSpecialization::convert( value.value() ); + } + + return QVariant(); + } + + /// Set the field value from a QVariant + static void setFromVariant( const QVariant& variantValue, std::optional& value ) + { + // An empty QVariant means no value, and we should set the optional to std::nullopt + auto stringText = variantValue.toString(); + stringText.remove( '"' ); + if ( stringText.isEmpty() ) + { + value.reset(); + return; + } + + T valueOfType; + PdmValueFieldSpecialization::setFromVariant( variantValue, valueOfType ); + value = valueOfType; + } + + static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 ) + { + return variantValue == variantValue2; + } + + /// Methods to get a list of options for a field, specialized for std::optional + static QList valueOptions( QString keyword, const std::optional& ) + { + QList optionList; + + return optionList; + } + /// Methods to retrieve the possible PdmObject pointed to by a field - static void childObjects( const PdmDataValueField>& field, std::vector* objects ) + static void childObjects( const PdmDataValueField>& field, std::vector* objects ) { } }; @@ -253,7 +292,7 @@ public: return PdmValueFieldSpecialization::isEqual( variantValue, variantValue2 ); } - /// Methods to get a list of options for a field, specialized for AppEnum + /// Methods to get a list of options for a field, specialized for caf::FilePath static QList valueOptions( QString keyword, const caf::FilePath& ) { return QList(); diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldSpecialization.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldSpecialization.h index 99743acd1a..a4453d7f08 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldSpecialization.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldSpecialization.h @@ -27,17 +27,11 @@ template class PdmUiFieldSpecialization { public: - static QVariant convert( const T& value ) - { - /// Convert the field value into a QVariant - return QVariant::fromValue( value ); - } + /// Convert the field value into a QVariant + static QVariant convert( const T& value ) { return QVariant::fromValue( value ); } - static void setFromVariant( const QVariant& variantValue, T& value ) - { - /// Set the field value from a QVariant - value = variantValue.value(); - } + /// Set the field value from a QVariant + static void setFromVariant( const QVariant& variantValue, T& value ) { value = variantValue.value(); } /// Check equality between QVariants that carries a Field Value. /// The == operator will normally work, but does not support custom types in the QVariant @@ -55,7 +49,7 @@ public: } } - /// Methods to get a list of options for a field, specialized for AppEnum + /// Methods to get a list of options for a field static QList valueOptions( QString keyword, const T& ) { return QList(); } /// Methods to retrieve the possible PdmObject pointed to by a field diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmStreamOperators.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmStreamOperators.h index cc7a04201c..e2fec61ca1 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmStreamOperators.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmStreamOperators.h @@ -127,3 +127,43 @@ QTextStream& operator>>( QTextStream& str, std::pair& sobj ) return str; } + +//================================================================================================== +/// QTextStream Stream operator overloading for std::optional +//================================================================================================== + +template +QTextStream& operator<<( QTextStream& str, const std::optional& sobj ) +{ + if ( sobj.has_value() ) + { + str << sobj.value(); + } + + return str; +} + +template +QTextStream& operator>>( QTextStream& str, std::optional& sobj ) +{ + QString stringValue; + str >> stringValue; + + stringValue.remove( '"' ); + + if ( !stringValue.isEmpty() ) + { + // Use the QTextStream to parse the string value into the type T + QTextStream singleValueStream( &stringValue ); + T singleValue; + singleValueStream >> singleValue; + sobj = singleValue; + } + else + { + // An empty string means no value, so reset the optional + sobj.reset(); + } + + return str; +} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafProjectDataModel_UnitTests/AggregatedTypesInField.cpp b/Fwk/AppFwk/cafProjectDataModel/cafProjectDataModel_UnitTests/AggregatedTypesInField.cpp index 4d00b3067c..3df21d99c7 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafProjectDataModel_UnitTests/AggregatedTypesInField.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafProjectDataModel_UnitTests/AggregatedTypesInField.cpp @@ -55,12 +55,16 @@ public: auto strPair = std::make_pair( false, QString( "msj" ) ); CAF_PDM_InitField( &m_checkableString, "CheckableString", strPair, "label text" ); + + CAF_PDM_InitFieldNoDefault( &m_optionalDouble, "OptionalDouble", "Optional Double" ); } ~AggregatedTypes() {} caf::PdmField> m_checkableDouble; caf::PdmField> m_checkableString; + + caf::PdmField> m_optionalDouble; }; CAF_PDM_SOURCE_INIT( AggregatedTypes, "AggregatedTypes" ); @@ -72,6 +76,7 @@ TEST( AggregatedTypes, AggregatedTypes ) AggregatedTypes obj; EXPECT_EQ( obj.m_checkableDouble().first, false ); EXPECT_EQ( obj.m_checkableDouble().second, 12.0 ); + EXPECT_EQ( obj.m_optionalDouble(), std::nullopt ); } //-------------------------------------------------------------------------------------------------- @@ -83,8 +88,9 @@ TEST( AggregatedTypeTest, MyTest ) QXmlStreamWriter xmlStream( &xml ); xmlStream.setAutoFormatting( true ); - const double testValue = 0.0012; - const QString testString = "string with spaces"; + const double testValue = 0.0012; + const QString testString = "string with spaces"; + const double testOptionalValue = 123.0012; { AggregatedTypes myObj; @@ -95,6 +101,8 @@ TEST( AggregatedTypeTest, MyTest ) auto testStrPair = std::make_pair( true, testString ); myObj.m_checkableString = testStrPair; + myObj.m_optionalDouble = testOptionalValue; + xml = myObj.writeObjectToXmlString(); } @@ -109,5 +117,9 @@ TEST( AggregatedTypeTest, MyTest ) auto fieldStrValue = myObj.m_checkableString(); ASSERT_STREQ( testString.toStdString().data(), fieldStrValue.second.toStdString().data() ); + + auto fieldOptionalValue = myObj.m_optionalDouble(); + ASSERT_TRUE( fieldOptionalValue.has_value() ); + ASSERT_DOUBLE_EQ( testOptionalValue, fieldOptionalValue.value() ); } } diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/CMakeLists.txt b/Fwk/AppFwk/cafTests/cafTestApplication/CMakeLists.txt index f7168bf4f1..c99a8f4e0d 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/CMakeLists.txt +++ b/Fwk/AppFwk/cafTests/cafTestApplication/CMakeLists.txt @@ -44,6 +44,8 @@ set(PROJECT_FILES LineEditAndPushButtons.cpp ApplicationEnum.h ApplicationEnum.cpp + OptionalFields.h + OptionalFields.cpp ) qt_add_executable( diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp b/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp index 9d92f3652d..c11a102330 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp +++ b/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp @@ -8,6 +8,7 @@ #include "LineEditAndPushButtons.h" #include "ManyGroups.h" #include "MenuItemProducer.h" +#include "OptionalFields.h" #include "TamComboBox.h" #include "WidgetLayoutTest.h" @@ -1310,6 +1311,7 @@ void MainWindow::buildTestModel() m_testRoot->objects.push_back( singleEditorObj ); m_testRoot->objects.push_back( new LineEditAndPushButtons ); + m_testRoot->objects.push_back( new OptionalFields ); auto tamComboBox = new TamComboBox; m_testRoot->objects.push_back( tamComboBox ); diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/OptionalFields.cpp b/Fwk/AppFwk/cafTests/cafTestApplication/OptionalFields.cpp new file mode 100644 index 0000000000..05fe4b2832 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestApplication/OptionalFields.cpp @@ -0,0 +1,25 @@ + +#include "OptionalFields.h" + +#include "cafPdmUiLineEditor.h" + +#include + +CAF_PDM_SOURCE_INIT( OptionalFields, "OptionalFields" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +OptionalFields::OptionalFields() +{ + CAF_PDM_InitObject( "Optional Fields", "", "", "" ); + + CAF_PDM_InitFieldNoDefault( &m_optionalStringField, "OptionalStringField", "Optional String Value" ); + m_optionalStringField.uiCapability()->setUiEditorTypeName( caf::PdmUiLineEditor::uiEditorTypeName() ); + + CAF_PDM_InitFieldNoDefault( &m_optionalDoubleField, "OptionalDoubleField", "Optional Double Value" ); + m_optionalDoubleField.uiCapability()->setUiEditorTypeName( caf::PdmUiLineEditor::uiEditorTypeName() ); + + CAF_PDM_InitFieldNoDefault( &m_optionalIntField, "OptionalIntField", "Optional Integer Value" ); + m_optionalIntField.uiCapability()->setUiEditorTypeName( caf::PdmUiLineEditor::uiEditorTypeName() ); +} diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/OptionalFields.h b/Fwk/AppFwk/cafTests/cafTestApplication/OptionalFields.h new file mode 100644 index 0000000000..d1ca5e89d4 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestApplication/OptionalFields.h @@ -0,0 +1,17 @@ +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" + +class OptionalFields : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + OptionalFields(); + +private: + caf::PdmField> m_optionalStringField; + caf::PdmField> m_optionalDoubleField; + caf::PdmField> m_optionalIntField; +};