From 7f00efe6cf202463f6aec261607e232b2c976878 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Sun, 29 Mar 2020 21:14:10 +0200 Subject: [PATCH] Properties: Fixed conditional properties using enum values in the conditions When wxAny holds an enum, it cannot be compared with an integer due to a missing conversion function. In such case, conditional properties compare a raw value rather than wxAny. --- common/eda_shape.cpp | 2 +- common/widgets/properties_panel.cpp | 50 ++++++++++++--------------- pcbnew/pad.h | 8 ++--- qa/unittests/common/test_property.cpp | 10 +++--- 4 files changed, 34 insertions(+), 36 deletions(-) diff --git a/common/eda_shape.cpp b/common/eda_shape.cpp index eb8f4bd7fb..781f09b470 100644 --- a/common/eda_shape.cpp +++ b/common/eda_shape.cpp @@ -1666,7 +1666,7 @@ static struct EDA_SHAPE_DESC angle->SetAvailableFunc( [=]( INSPECTABLE* aItem ) -> bool { - return aItem->Get( shape ).As() == SHAPE_T::ARC; + return aItem->Get( shape ) == SHAPE_T::ARC; } ); propMgr.AddProperty( angle ); } diff --git a/common/widgets/properties_panel.cpp b/common/widgets/properties_panel.cpp index 3eb1954406..97a5803283 100644 --- a/common/widgets/properties_panel.cpp +++ b/common/widgets/properties_panel.cpp @@ -89,48 +89,44 @@ void PROPERTIES_PANEL::update( const SELECTION& aSelection ) if( !property->Available( aSelection.Front() ) ) continue; - // Either determine the common value for a property or "<...>" to mark multiple values - bool first = true; + // Either determine the common value for a property or "<...>" to indicate multiple values bool available = true; wxVariant commonVal, itemVal; for( EDA_ITEM* item : aSelection ) { - wxVariant& value = first ? commonVal : itemVal; + if( !property->Available( item ) ) + break; // there is an item that does not have this property, so do not display it - if( !first && !property->Available( item ) ) + wxVariant& value = commonVal.IsNull() ? commonVal : itemVal; + const wxAny& any = item->Get( property ); + bool converted = false; + + if( property->HasChoices() ) { - // there is an item that does not have this property + // handle enums as ints, since there are no default conversion functions for wxAny + int tmp; + converted = any.GetAs( &tmp ); + + if( converted ) + value = wxVariant( tmp ); + } + + if( !converted ) // all other types + converted = any.GetAs( &value ); + + if( !converted ) + { + wxFAIL_MSG( "Could not convert wxAny to wxVariant" ); available = false; break; } - const wxAny& any = static_cast( item )->Get( property ); - - if( !any.GetAs( &value ) ) - { - int tmp; - - if( any.GetAs( &tmp ) ) // needed to handle enums - { - value = wxVariant( tmp ); - } - else - { - wxFAIL_MSG( "Could not convert wxAny to wxVariant" ); - // if it is an enum, be sure that there is a corresponding ENUM_TO_WXANY - available = false; - break; - } - } - - if( !first && value != commonVal ) + if( !commonVal.IsNull() && value != commonVal ) { commonVal.MakeNull(); // items have different values for this property break; } - - first = false; } if( available ) diff --git a/pcbnew/pad.h b/pcbnew/pad.h index e3f83a88da..2baf33ff83 100644 --- a/pcbnew/pad.h +++ b/pcbnew/pad.h @@ -239,9 +239,9 @@ public: void SetSize( const VECTOR2I& aSize ) { m_size = aSize; SetDirty(); } const VECTOR2I& GetSize() const { return m_size; } void SetSizeX( const int aX ) { m_size.x = aX; SetDirty(); } - const int GetSizeX() const { return m_size.x; } + int GetSizeX() const { return m_size.x; } void SetSizeY( const int aY ) { m_size.y = aY; SetDirty(); } - const int GetSizeY() const { return m_size.y; } + int GetSizeY() const { return m_size.y; } void SetDelta( const VECTOR2I& aSize ) { m_deltaSize = aSize; SetDirty(); } const VECTOR2I& GetDelta() const { return m_deltaSize; } @@ -249,9 +249,9 @@ public: void SetDrillSize( const VECTOR2I& aSize ) { m_drill = aSize; SetDirty(); } const VECTOR2I& GetDrillSize() const { return m_drill; } void SetDrillSizeX( const int aX ) { m_drill.x = aX; SetDirty(); } - const int GetDrillSizeX() const { return m_drill.x; } + int GetDrillSizeX() const { return m_drill.x; } void SetDrillSizeY( const int aY ) { m_drill.y = aY; SetDirty(); } - const int GetDrillSizeY() const { return m_drill.y; } + int GetDrillSizeY() const { return m_drill.y; } void SetOffset( const VECTOR2I& aOffset ) { m_offset = aOffset; SetDirty(); } const VECTOR2I& GetOffset() const { return m_offset; } diff --git a/qa/unittests/common/test_property.cpp b/qa/unittests/common/test_property.cpp index 5a17639470..7e3077c475 100644 --- a/qa/unittests/common/test_property.cpp +++ b/qa/unittests/common/test_property.cpp @@ -177,7 +177,9 @@ static struct CLASS_D_DESC propMgr.InheritsAfter( TYPE_HASH( D ), TYPE_HASH( C ) ); auto cond = new PROPERTY( "cond", &D::setCond, &D::getCond ); - cond->SetAvailableFunc( [=](INSPECTABLE* aItem)->bool { return *aItem->Get( "A" ) > 50; } ); + cond->SetAvailableFunc( [=](INSPECTABLE* aItem)->bool { + return *aItem->Get( "enumGlob" ) == enum_glob::TEST1; + } ); propMgr.AddProperty( cond ); } } _CLASS_D_DESC; @@ -356,11 +358,11 @@ BOOST_AUTO_TEST_CASE( Availability ) PROPERTY_BASE* propCond = propMgr.GetProperty( TYPE_HASH( D ), "cond" ); ptr = &d; - // "cond" property is available only when "a" field is greater than 50 - d.setA( 0 ); + // "cond" property is available only when "a" field is greater than 50 //TODO fix desc + d.setGlobEnum( enum_glob::TEST3 ); BOOST_CHECK( !propCond->Available( ptr ) ); - d.setA( 100 ); + d.setGlobEnum( enum_glob::TEST1 ); BOOST_CHECK( propCond->Available( ptr ) ); }