mirror of
https://github.com/OPM/ResInsight.git
synced 2026-08-27 05:37:21 -05:00
Refactors PdmUiFieldSpecialization implementation
* Simplifies PdmUiFieldSpecialization implementation. Refactors the PdmUiFieldSpecialization implementation to reduce code duplication. Introduces a base class `PdmUiFieldSpecializationForValueSpec` that delegates to `PdmValueFieldSpecialization`, avoiding boilerplate code for common types. The primary template now inherits from the new base class, providing default behavior for types with custom `PdmValueFieldSpecialization`. * Improve AppEnum subset handling to avoid key collisions Refactored AppEnum to use a unique key combining owner class name and field keyword for enum subset storage, preventing collisions when different object types use the same field keyword. Updated setEnumSubset and enumSubset to accept PdmFieldHandle pointers. Added tests to verify correct and independent subset behavior across object types and handle edge cases. * Refactor PdmValueFieldSpecialization with base helpers Introduce base classes for default isEqual and QVariant conversion. Update specializations to inherit from these helpers, removing redundant code and centralizing default behaviors.
This commit is contained in:
@@ -38,44 +38,7 @@
|
||||
|
||||
#include "cafPdmCoreMat3d.h"
|
||||
|
||||
#include "cafInternalPdmValueFieldSpecializations.h"
|
||||
#include "cafPdmUiFieldSpecialization.h"
|
||||
#include "cafPdmUiItem.h"
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfMatrix3.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
class PdmUiFieldSpecialization<cvf::Mat3d>
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert( const cvf::Mat3d& value )
|
||||
{
|
||||
return PdmValueFieldSpecialization<cvf::Mat3d>::convert( value );
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant( const QVariant& variantValue, cvf::Mat3d& value )
|
||||
{
|
||||
PdmValueFieldSpecialization<cvf::Mat3d>::setFromVariant( variantValue, value );
|
||||
}
|
||||
|
||||
static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return PdmValueFieldSpecialization<cvf::Mat3d>::isEqual( variantValue, variantValue2 );
|
||||
}
|
||||
|
||||
/// Methods to get a list of options for a field, specialized for AppEnum
|
||||
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const cvf::Mat3d& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects( const PdmDataValueField<cvf::Mat3d>&, std::vector<PdmObjectHandle*>* ) {}
|
||||
};
|
||||
|
||||
} // end namespace caf
|
||||
|
||||
@@ -39,47 +39,10 @@
|
||||
#include "cvfBase.h"
|
||||
#include "cvfColor3.h"
|
||||
|
||||
#include "cafInternalPdmValueFieldSpecializations.h"
|
||||
#include "cafPdmUiFieldSpecialization.h"
|
||||
#include "cafPdmUiItem.h"
|
||||
|
||||
#include "cafPdmCoreColor3f.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
class PdmUiFieldSpecialization<cvf::Color3f>
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert( const cvf::Color3f& value )
|
||||
{
|
||||
return PdmValueFieldSpecialization<cvf::Color3f>::convert( value );
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant( const QVariant& variantValue, cvf::Color3f& value )
|
||||
{
|
||||
PdmValueFieldSpecialization<cvf::Color3f>::setFromVariant( variantValue, value );
|
||||
}
|
||||
|
||||
static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return PdmValueFieldSpecialization<cvf::Color3f>::isEqual( variantValue, variantValue2 );
|
||||
}
|
||||
|
||||
/// Methods to get a list of options for a field, specialized for AppEnum
|
||||
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const cvf::Color3f& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects( const PdmDataValueField<cvf::Color3f>&, std::vector<PdmObjectHandle*>* ) {}
|
||||
};
|
||||
|
||||
} // end namespace caf
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// If the macro for registering the editor is put as the single statement
|
||||
// in a cpp file, a dummy static class must be used to make sure the compile unit
|
||||
|
||||
@@ -38,44 +38,7 @@
|
||||
|
||||
#include "cafPdmCoreMat4d.h"
|
||||
|
||||
#include "cafInternalPdmValueFieldSpecializations.h"
|
||||
#include "cafPdmUiFieldSpecialization.h"
|
||||
#include "cafPdmUiItem.h"
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfMatrix4.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
class PdmUiFieldSpecialization<cvf::Mat4d>
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert( const cvf::Mat4d& value )
|
||||
{
|
||||
return PdmValueFieldSpecialization<cvf::Mat4d>::convert( value );
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant( const QVariant& variantValue, cvf::Mat4d& value )
|
||||
{
|
||||
PdmValueFieldSpecialization<cvf::Mat4d>::setFromVariant( variantValue, value );
|
||||
}
|
||||
|
||||
static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return PdmValueFieldSpecialization<cvf::Mat4d>::isEqual( variantValue, variantValue2 );
|
||||
}
|
||||
|
||||
/// Methods to get a list of options for a field, specialized for AppEnum
|
||||
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const cvf::Mat4d& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects( const PdmDataValueField<cvf::Mat4d>&, std::vector<PdmObjectHandle*>* ) {}
|
||||
};
|
||||
|
||||
} // end namespace caf
|
||||
|
||||
@@ -38,48 +38,11 @@
|
||||
|
||||
#include "cafPdmCoreVec3d.h"
|
||||
|
||||
#include "cafInternalPdmValueFieldSpecializations.h"
|
||||
#include "cafPdmUiFieldSpecialization.h"
|
||||
#include "cafPdmUiItem.h"
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
class PdmUiFieldSpecialization<cvf::Vec3d>
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert( const cvf::Vec3d& value )
|
||||
{
|
||||
return PdmValueFieldSpecialization<cvf::Vec3d>::convert( value );
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant( const QVariant& variantValue, cvf::Vec3d& value )
|
||||
{
|
||||
PdmValueFieldSpecialization<cvf::Vec3d>::setFromVariant( variantValue, value );
|
||||
}
|
||||
|
||||
static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return PdmValueFieldSpecialization<cvf::Vec3d>::isEqual( variantValue, variantValue2 );
|
||||
}
|
||||
|
||||
/// Methods to get a list of options for a field, specialized for AppEnum
|
||||
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const cvf::Vec3d& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects( const PdmDataValueField<cvf::Vec3d>&, std::vector<PdmObjectHandle*>* ) {}
|
||||
};
|
||||
|
||||
} // end namespace caf
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// If the macro for registering the editor is put as the single statement
|
||||
// in a cpp file, a dummy static class must be used to make sure the compile unit
|
||||
|
||||
@@ -129,19 +129,34 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
static void setEnumSubset( caf::PdmFieldHandle* fieldKeyword, std::vector<T> subset )
|
||||
static void setEnumSubset( caf::PdmFieldHandle* fieldHandle, std::vector<T> subset )
|
||||
{
|
||||
if ( !fieldKeyword ) return;
|
||||
m_enumSubset[fieldKeyword->keyword()] = subset;
|
||||
if ( !fieldHandle ) return;
|
||||
QString key = createEnumSubsetKey( fieldHandle );
|
||||
m_enumSubset[key] = subset;
|
||||
}
|
||||
static std::vector<T> enumSubset( QString fieldKeyword )
|
||||
static std::vector<T> enumSubset( caf::PdmFieldHandle* fieldHandle )
|
||||
{
|
||||
auto it = m_enumSubset.find( fieldKeyword );
|
||||
if ( !fieldHandle ) return {};
|
||||
QString key = createEnumSubsetKey( fieldHandle );
|
||||
auto it = m_enumSubset.find( key );
|
||||
if ( it != m_enumSubset.end() ) return it->second;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
static QString createEnumSubsetKey( caf::PdmFieldHandle* fieldHandle )
|
||||
{
|
||||
if ( !fieldHandle ) return QString();
|
||||
|
||||
// Create a unique key by combining the owner class name with the field keyword
|
||||
// This prevents collisions when different object types use the same field keyword
|
||||
QString ownerClass = fieldHandle->ownerClass();
|
||||
return ownerClass + "::" + fieldHandle->keyword();
|
||||
}
|
||||
|
||||
public:
|
||||
operator T() const { return m_value; }
|
||||
|
||||
T value() const { return m_value; }
|
||||
@@ -201,7 +216,7 @@ private:
|
||||
|
||||
T m_value;
|
||||
|
||||
static std::map<QString, std::vector<T>> m_enumSubset;
|
||||
static std::map<QString, std::vector<T>> m_enumSubset; // Key format: "ownerClass::fieldKeyword"
|
||||
|
||||
//==================================================================================================
|
||||
/// A private class to handle the instance of the mapping vector.
|
||||
|
||||
+27
-28
@@ -12,6 +12,28 @@
|
||||
|
||||
namespace caf
|
||||
{
|
||||
//==================================================================================================
|
||||
/// Base class providing default implementations for PdmValueFieldSpecialization methods.
|
||||
//==================================================================================================
|
||||
struct PdmValueFieldSpecializationDefaults
|
||||
{
|
||||
static bool isEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Helper base class providing standard QVariant conversion for simple types.
|
||||
/// Useful for types that only need custom isEqual (like float/double with epsilon comparison).
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
struct PdmValueFieldSpecializationStdConversion
|
||||
{
|
||||
static QVariant convert( const T& value ) { return QVariant::fromValue( value ); }
|
||||
static void setFromVariant( const QVariant& variantValue, T& value ) { value = variantValue.value<T>(); }
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// A proxy class that implements the generic QVariant interface for a field
|
||||
///
|
||||
@@ -47,7 +69,7 @@ public:
|
||||
/// Partial specialization for caf::AppEnum
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
class PdmValueFieldSpecialization<caf::AppEnum<T>>
|
||||
class PdmValueFieldSpecialization<caf::AppEnum<T>> : public PdmValueFieldSpecializationDefaults
|
||||
{
|
||||
public:
|
||||
static QVariant convert( const caf::AppEnum<T>& value )
|
||||
@@ -61,11 +83,6 @@ public:
|
||||
{
|
||||
value = static_cast<T>( variantValue.toInt() );
|
||||
}
|
||||
|
||||
static bool isEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
@@ -97,7 +114,7 @@ public:
|
||||
/// Partial specialization for std::vector
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
class PdmValueFieldSpecialization<std::vector<T>>
|
||||
class PdmValueFieldSpecialization<std::vector<T>> : public PdmValueFieldSpecializationDefaults
|
||||
{
|
||||
public:
|
||||
static QVariant convert( const std::vector<T>& value )
|
||||
@@ -127,18 +144,13 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool isEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for std::pair
|
||||
//==================================================================================================
|
||||
template <typename T, typename U>
|
||||
class PdmValueFieldSpecialization<std::pair<T, U>>
|
||||
class PdmValueFieldSpecialization<std::pair<T, U>> : public PdmValueFieldSpecializationDefaults
|
||||
{
|
||||
public:
|
||||
static QVariant convert( const std::pair<T, U>& value )
|
||||
@@ -168,11 +180,6 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool isEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
@@ -199,13 +206,9 @@ public:
|
||||
/// Partial specialization for float
|
||||
//==================================================================================================
|
||||
template <>
|
||||
class PdmValueFieldSpecialization<float>
|
||||
class PdmValueFieldSpecialization<float> : public PdmValueFieldSpecializationStdConversion<float>
|
||||
{
|
||||
public:
|
||||
static QVariant convert( const float& value ) { return QVariant::fromValue( value ); }
|
||||
|
||||
static void setFromVariant( const QVariant& variantValue, float& value ) { value = variantValue.value<float>(); }
|
||||
|
||||
static bool isEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
// See PdmFieldWriter::writeFieldData for the precision used when writing float values
|
||||
@@ -220,13 +223,9 @@ public:
|
||||
/// Partial specialization for double
|
||||
//==================================================================================================
|
||||
template <>
|
||||
class PdmValueFieldSpecialization<double>
|
||||
class PdmValueFieldSpecialization<double> : public PdmValueFieldSpecializationStdConversion<double>
|
||||
{
|
||||
public:
|
||||
static QVariant convert( const double& value ) { return QVariant::fromValue( value ); }
|
||||
|
||||
static void setFromVariant( const QVariant& variantValue, double& value ) { value = variantValue.value<double>(); }
|
||||
|
||||
static bool isEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
// See PdmFieldWriter::writeFieldData for the precision used when writing double values
|
||||
|
||||
@@ -27,6 +27,7 @@ set(PROJECT_FILES
|
||||
cafPdmChildArrayFieldHandleTest.cpp
|
||||
cafSignalTest.cpp
|
||||
cafPdmLoggingTest.cpp
|
||||
cafAppEnumTest.cpp
|
||||
Child.cpp
|
||||
Child.h
|
||||
Parent.cpp
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmDataValueField.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
|
||||
// Define a test enum
|
||||
enum class TestEnumType
|
||||
{
|
||||
VALUE_A,
|
||||
VALUE_B,
|
||||
VALUE_C,
|
||||
VALUE_D,
|
||||
VALUE_E
|
||||
};
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
void AppEnum<TestEnumType>::setUp()
|
||||
{
|
||||
addItem( TestEnumType::VALUE_A, "VALUE_A", "Value A" );
|
||||
addItem( TestEnumType::VALUE_B, "VALUE_B", "Value B" );
|
||||
addItem( TestEnumType::VALUE_C, "VALUE_C", "Value C" );
|
||||
addItem( TestEnumType::VALUE_D, "VALUE_D", "Value D" );
|
||||
addItem( TestEnumType::VALUE_E, "VALUE_E", "Value E" );
|
||||
setDefault( TestEnumType::VALUE_A );
|
||||
}
|
||||
} // namespace caf
|
||||
|
||||
// First test object with an enum field
|
||||
class TestObject1 : public caf::PdmObjectHandle
|
||||
{
|
||||
public:
|
||||
TestObject1()
|
||||
{
|
||||
this->addField( &m_enumField, "EnumField" );
|
||||
m_enumField.setOwnerClass( "TestObject1" );
|
||||
m_enumField = TestEnumType::VALUE_A;
|
||||
}
|
||||
|
||||
caf::PdmDataValueField<caf::AppEnum<TestEnumType>> m_enumField;
|
||||
};
|
||||
|
||||
// Second test object with an enum field using the same keyword
|
||||
class TestObject2 : public caf::PdmObjectHandle
|
||||
{
|
||||
public:
|
||||
TestObject2()
|
||||
{
|
||||
this->addField( &m_enumField, "EnumField" );
|
||||
m_enumField.setOwnerClass( "TestObject2" );
|
||||
m_enumField = TestEnumType::VALUE_B;
|
||||
}
|
||||
|
||||
caf::PdmDataValueField<caf::AppEnum<TestEnumType>> m_enumField;
|
||||
};
|
||||
|
||||
// Third test object to test uninitialized subset
|
||||
class TestObject3 : public caf::PdmObjectHandle
|
||||
{
|
||||
public:
|
||||
TestObject3()
|
||||
{
|
||||
this->addField( &m_enumField, "UniqueEnumField" );
|
||||
m_enumField.setOwnerClass( "TestObject3" );
|
||||
m_enumField = TestEnumType::VALUE_C;
|
||||
}
|
||||
|
||||
caf::PdmDataValueField<caf::AppEnum<TestEnumType>> m_enumField;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Test that two different objects can have the same field keyword with different enum subsets
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( AppEnumTest, EnumSubsetNoCollision )
|
||||
{
|
||||
TestObject1 obj1;
|
||||
TestObject2 obj2;
|
||||
|
||||
// Set different subsets for the same field keyword in different objects
|
||||
std::vector<TestEnumType> subset1 = { TestEnumType::VALUE_A, TestEnumType::VALUE_B };
|
||||
std::vector<TestEnumType> subset2 = { TestEnumType::VALUE_C, TestEnumType::VALUE_D, TestEnumType::VALUE_E };
|
||||
|
||||
caf::AppEnum<TestEnumType>::setEnumSubset( &obj1.m_enumField, subset1 );
|
||||
caf::AppEnum<TestEnumType>::setEnumSubset( &obj2.m_enumField, subset2 );
|
||||
|
||||
// Retrieve the subsets
|
||||
auto retrievedSubset1 = caf::AppEnum<TestEnumType>::enumSubset( &obj1.m_enumField );
|
||||
auto retrievedSubset2 = caf::AppEnum<TestEnumType>::enumSubset( &obj2.m_enumField );
|
||||
|
||||
// Verify that the subsets are correct and independent
|
||||
ASSERT_EQ( 2, retrievedSubset1.size() );
|
||||
EXPECT_EQ( TestEnumType::VALUE_A, retrievedSubset1[0] );
|
||||
EXPECT_EQ( TestEnumType::VALUE_B, retrievedSubset1[1] );
|
||||
|
||||
ASSERT_EQ( 3, retrievedSubset2.size() );
|
||||
EXPECT_EQ( TestEnumType::VALUE_C, retrievedSubset2[0] );
|
||||
EXPECT_EQ( TestEnumType::VALUE_D, retrievedSubset2[1] );
|
||||
EXPECT_EQ( TestEnumType::VALUE_E, retrievedSubset2[2] );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Test that multiple instances of the same class share the same subset
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( AppEnumTest, EnumSubsetSameClass )
|
||||
{
|
||||
TestObject1 obj1a;
|
||||
TestObject1 obj1b;
|
||||
|
||||
// Set subset for first instance
|
||||
std::vector<TestEnumType> subset = { TestEnumType::VALUE_A, TestEnumType::VALUE_C };
|
||||
caf::AppEnum<TestEnumType>::setEnumSubset( &obj1a.m_enumField, subset );
|
||||
|
||||
// Both instances should have the same subset since they have the same class name and field keyword
|
||||
auto retrievedSubset1 = caf::AppEnum<TestEnumType>::enumSubset( &obj1a.m_enumField );
|
||||
auto retrievedSubset2 = caf::AppEnum<TestEnumType>::enumSubset( &obj1b.m_enumField );
|
||||
|
||||
ASSERT_EQ( 2, retrievedSubset1.size() );
|
||||
ASSERT_EQ( 2, retrievedSubset2.size() );
|
||||
EXPECT_EQ( TestEnumType::VALUE_A, retrievedSubset1[0] );
|
||||
EXPECT_EQ( TestEnumType::VALUE_C, retrievedSubset1[1] );
|
||||
EXPECT_EQ( TestEnumType::VALUE_A, retrievedSubset2[0] );
|
||||
EXPECT_EQ( TestEnumType::VALUE_C, retrievedSubset2[1] );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Test that null field handle returns empty subset
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( AppEnumTest, EnumSubsetNullHandle )
|
||||
{
|
||||
auto retrievedSubset = caf::AppEnum<TestEnumType>::enumSubset( nullptr );
|
||||
EXPECT_TRUE( retrievedSubset.empty() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Test that requesting a subset that hasn't been set returns empty vector
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( AppEnumTest, EnumSubsetNotSet )
|
||||
{
|
||||
TestObject3 obj;
|
||||
auto retrievedSubset = caf::AppEnum<TestEnumType>::enumSubset( &obj.m_enumField );
|
||||
EXPECT_TRUE( retrievedSubset.empty() );
|
||||
}
|
||||
+37
-107
@@ -13,6 +13,35 @@ class PdmPointer;
|
||||
template <typename T>
|
||||
class AppEnum;
|
||||
|
||||
//==================================================================================================
|
||||
/// Helper base class for types that delegate all operations to PdmValueFieldSpecialization.
|
||||
/// Inherit from this to avoid repeating the delegation boilerplate.
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
struct PdmUiFieldSpecializationForValueSpec : public PdmUiFieldSpecializationDefaults
|
||||
{
|
||||
static QVariant convert( const T& value ) { return PdmValueFieldSpecialization<T>::convert( value ); }
|
||||
|
||||
static void setFromVariant( const QVariant& variantValue, T& value )
|
||||
{
|
||||
PdmValueFieldSpecialization<T>::setFromVariant( variantValue, value );
|
||||
}
|
||||
|
||||
static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return PdmValueFieldSpecialization<T>::isEqual( variantValue, variantValue2 );
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Primary template - delegates to PdmValueFieldSpecialization<T>.
|
||||
/// Types with custom PdmValueFieldSpecialization will automatically get correct behavior.
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
class PdmUiFieldSpecialization : public PdmUiFieldSpecializationForValueSpec<T>
|
||||
{
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for PdmField< PdmPointer<T> >
|
||||
///
|
||||
@@ -24,7 +53,7 @@ class AppEnum;
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
class PdmUiFieldSpecialization<PdmPointer<T>>
|
||||
class PdmUiFieldSpecialization<PdmPointer<T>> : public PdmUiFieldSpecializationDefaults
|
||||
{
|
||||
public:
|
||||
static QVariant convert( const PdmPointer<T>& value )
|
||||
@@ -41,11 +70,6 @@ public:
|
||||
{
|
||||
return variantValue.value<PdmPointer<PdmObjectHandle>>() == variantValue2.value<PdmPointer<PdmObjectHandle>>();
|
||||
}
|
||||
|
||||
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const PdmPointer<T>& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
@@ -53,7 +77,7 @@ public:
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
class PdmUiFieldSpecialization<std::list<T>>
|
||||
class PdmUiFieldSpecialization<std::list<T>> : public PdmUiFieldSpecializationDefaults
|
||||
{
|
||||
public:
|
||||
static QVariant convert( const std::list<T>& value )
|
||||
@@ -85,13 +109,6 @@ public:
|
||||
{
|
||||
return PdmValueFieldSpecialization<T>::isEqual( variantValue, variantValue2 );
|
||||
}
|
||||
|
||||
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const std::list<T>& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
static void childObjects( const PdmDataValueField<std::list<T>>&, std::vector<PdmObjectHandle*>* ) {}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
@@ -99,7 +116,7 @@ public:
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
class PdmUiFieldSpecialization<std::vector<T>>
|
||||
class PdmUiFieldSpecialization<std::vector<T>> : public PdmUiFieldSpecializationDefaults
|
||||
{
|
||||
public:
|
||||
static QVariant convert( const std::vector<T>& value )
|
||||
@@ -116,22 +133,13 @@ public:
|
||||
{
|
||||
return PdmValueFieldSpecialization<T>::isEqual( variantValue, variantValue2 );
|
||||
}
|
||||
|
||||
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const std::vector<T>& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
static void childObjects( const PdmDataValueField<std::vector<T>>& field, std::vector<PdmObjectHandle*>* objects )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for PdmField< caf::AppEnum<T> >
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
class PdmUiFieldSpecialization<caf::AppEnum<T>>
|
||||
class PdmUiFieldSpecialization<caf::AppEnum<T>> : public PdmUiFieldSpecializationDefaults
|
||||
{
|
||||
public:
|
||||
static QVariant convert( const caf::AppEnum<T>& value )
|
||||
@@ -147,17 +155,12 @@ public:
|
||||
value = static_cast<T>( variantValue.toInt() );
|
||||
}
|
||||
|
||||
static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
|
||||
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const caf::AppEnum<T>& appEnum )
|
||||
static QList<PdmOptionItemInfo> valueOptions( PdmFieldHandle* fieldHandle, const caf::AppEnum<T>& appEnum )
|
||||
{
|
||||
QList<PdmOptionItemInfo> optionList;
|
||||
|
||||
// If a subset of the enum is defined, use that subset
|
||||
auto enumValues = caf::AppEnum<T>::enumSubset( keyword );
|
||||
auto enumValues = caf::AppEnum<T>::enumSubset( fieldHandle );
|
||||
if ( enumValues.empty() )
|
||||
{
|
||||
// If no subset is defined, use all values
|
||||
@@ -173,17 +176,13 @@ public:
|
||||
|
||||
return optionList;
|
||||
}
|
||||
|
||||
static void childObjects( const PdmDataValueField<caf::AppEnum<T>>& field, std::vector<PdmObjectHandle*>* objects )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for PdmField<std::pair<T, U>>>
|
||||
//==================================================================================================
|
||||
template <typename T, typename U>
|
||||
class PdmUiFieldSpecialization<std::pair<T, U>>
|
||||
class PdmUiFieldSpecialization<std::pair<T, U>> : public PdmUiFieldSpecializationDefaults
|
||||
{
|
||||
public:
|
||||
static QVariant convert( const std::pair<T, U>& value )
|
||||
@@ -195,29 +194,13 @@ public:
|
||||
{
|
||||
PdmValueFieldSpecialization<std::pair<T, U>>::setFromVariant( variantValue, value );
|
||||
}
|
||||
|
||||
static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
|
||||
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const std::pair<T, U>& )
|
||||
{
|
||||
QList<PdmOptionItemInfo> optionList;
|
||||
|
||||
return optionList;
|
||||
}
|
||||
|
||||
static void childObjects( const PdmDataValueField<std::pair<T, U>>& field, std::vector<PdmObjectHandle*>* objects )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for PdmField<std::optional<T>>>
|
||||
//==================================================================================================
|
||||
template <typename T>
|
||||
class PdmUiFieldSpecialization<std::optional<T>>
|
||||
class PdmUiFieldSpecialization<std::optional<T>> : public PdmUiFieldSpecializationDefaults
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
@@ -247,59 +230,6 @@ public:
|
||||
PdmValueFieldSpecialization<T>::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<T>
|
||||
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const std::optional<T>& )
|
||||
{
|
||||
QList<PdmOptionItemInfo> optionList;
|
||||
|
||||
return optionList;
|
||||
}
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects( const PdmDataValueField<std::optional<T>>& field, std::vector<PdmObjectHandle*>* objects )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for FilePath
|
||||
//==================================================================================================
|
||||
|
||||
template <>
|
||||
class PdmUiFieldSpecialization<caf::FilePath>
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert( const caf::FilePath& value )
|
||||
{
|
||||
return PdmValueFieldSpecialization<caf::FilePath>::convert( value );
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant( const QVariant& variantValue, caf::FilePath& value )
|
||||
{
|
||||
return PdmValueFieldSpecialization<caf::FilePath>::setFromVariant( variantValue, value );
|
||||
}
|
||||
|
||||
static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return PdmValueFieldSpecialization<caf::FilePath>::isEqual( variantValue, variantValue2 );
|
||||
}
|
||||
|
||||
/// Methods to get a list of options for a field, specialized for caf::FilePath
|
||||
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const caf::FilePath& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects( const PdmDataValueField<caf::FilePath>& field, std::vector<PdmObjectHandle*>* objects ) {}
|
||||
};
|
||||
|
||||
} // End namespace caf
|
||||
|
||||
@@ -198,9 +198,8 @@ QList<PdmOptionItemInfo> PdmFieldUiCap<FieldType>::valueOptions() const
|
||||
|
||||
if ( m_optionEntryCache.empty() )
|
||||
{
|
||||
auto keyword = m_field->keyword();
|
||||
m_optionEntryCache =
|
||||
PdmUiFieldSpecialization<typename FieldType::FieldDataType>::valueOptions( keyword, m_field->value() );
|
||||
PdmUiFieldSpecialization<typename FieldType::FieldDataType>::valueOptions( m_field, m_field->value() );
|
||||
}
|
||||
|
||||
if ( !m_optionEntryCache.empty() && isAutoAddingOptionFromValue() )
|
||||
|
||||
@@ -11,6 +11,30 @@ template <typename T>
|
||||
class PdmDataValueField;
|
||||
class PdmOptionItemInfo;
|
||||
class PdmObjectHandle;
|
||||
class PdmFieldHandle;
|
||||
|
||||
//==================================================================================================
|
||||
/// Base class providing default implementations for PdmUiFieldSpecialization methods.
|
||||
/// Specializations can inherit from this to avoid repeating empty/simple implementations.
|
||||
//==================================================================================================
|
||||
struct PdmUiFieldSpecializationDefaults
|
||||
{
|
||||
static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static QList<PdmOptionItemInfo> valueOptions( PdmFieldHandle*, const T& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void childObjects( const PdmDataValueField<T>&, std::vector<PdmObjectHandle*>* )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// A proxy class that implements the Gui interface of fields
|
||||
@@ -21,40 +45,14 @@ class PdmObjectHandle;
|
||||
///
|
||||
/// When introducing a new type in a PdmField, you might need to implement a (partial)specialization
|
||||
/// of this class.
|
||||
///
|
||||
/// The primary template delegates to PdmValueFieldSpecialization<T>, so types with custom
|
||||
/// PdmValueFieldSpecialization will automatically get the correct behavior without needing
|
||||
/// an explicit PdmUiFieldSpecialization.
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
class PdmUiFieldSpecialization
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert( const T& value ) { return QVariant::fromValue( value ); }
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant( const QVariant& variantValue, T& value ) { value = variantValue.value<T>(); }
|
||||
|
||||
/// Check equality between QVariants that carries a Field Value.
|
||||
/// The == operator will normally work, but does not support custom types in the QVariant
|
||||
/// See http://qt-project.org/doc/qt-4.8/qvariant.html#operator-eq-eq-64
|
||||
/// This is needed for the lookup regarding OptionValues
|
||||
static bool isDataElementEqual( const QVariant& variantValue, const QVariant& variantValue2 )
|
||||
{
|
||||
if ( variantValue.typeId() > QMetaType::User )
|
||||
{
|
||||
return ( variantValue.value<T>() == variantValue2.value<T>() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods to get a list of options for a field
|
||||
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const T& ) { return QList<PdmOptionItemInfo>(); }
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects( const PdmDataValueField<T>&, std::vector<PdmObjectHandle*>* ) {}
|
||||
};
|
||||
class PdmUiFieldSpecialization; // Forward declaration, defined in cafInternalPdmFieldTypeSpecializations.h
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafInternalPdmFieldTypeSpecializations.h"
|
||||
|
||||
Reference in New Issue
Block a user