Comboboxes for units and body styles.

Also for pin-types in pad properties.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19904

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19905
This commit is contained in:
Jeff Young 2025-07-23 14:33:29 +01:00
parent c63e2edfff
commit ec155c00f3
35 changed files with 472 additions and 447 deletions

View File

@ -134,29 +134,12 @@ LIB_TREE_NODE::LIB_TREE_NODE()
LIB_TREE_NODE_UNIT::LIB_TREE_NODE_UNIT( LIB_TREE_NODE* aParent, LIB_TREE_ITEM* aItem, int aUnit ) LIB_TREE_NODE_UNIT::LIB_TREE_NODE_UNIT( LIB_TREE_NODE* aParent, LIB_TREE_ITEM* aItem, int aUnit )
{ {
static void* locale = nullptr;
static wxString namePrefix;
// Fetching translations can take a surprising amount of time when loading libraries,
// so only do it when necessary.
if( Pgm().GetLocale() != locale )
{
namePrefix = _( "Unit" );
locale = Pgm().GetLocale();
}
m_Parent = aParent; m_Parent = aParent;
m_Type = TYPE::UNIT; m_Type = TYPE::UNIT;
m_Unit = aUnit; m_Unit = aUnit;
m_LibId = aParent->m_LibId; m_LibId = aParent->m_LibId;
m_Name = aItem->GetUnitName( aUnit );
m_Name = namePrefix + " " + aItem->GetUnitReference( aUnit );
if( aItem->HasUnitDisplayName( aUnit ) )
m_Desc = aItem->GetUnitDisplayName( aUnit );
else
m_Desc = wxEmptyString;
m_IntrinsicRank = -aUnit; m_IntrinsicRank = -aUnit;
} }

View File

@ -55,6 +55,31 @@ enum class ELECTRICAL_PINTYPE
#define ELECTRICAL_PINTYPES_TOTAL ( static_cast<int>( ELECTRICAL_PINTYPE::PT_LAST_OPTION ) + 1 ) #define ELECTRICAL_PINTYPES_TOTAL ( static_cast<int>( ELECTRICAL_PINTYPE::PT_LAST_OPTION ) + 1 )
inline wxString GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE aType )
{
// These strings are the canonical name of the electrictal type
// Not translated, no space in name, only ASCII chars.
// to use when the string name must be known and well defined
// must have same order than enum ELECTRICAL_PINTYPE (see sch_pin.h)
static const wxChar* msgPinElectricType[] =
{
wxT( "input" ),
wxT( "output" ),
wxT( "bidirectional" ),
wxT( "tri_state" ),
wxT( "passive" ),
wxT( "free" ),
wxT( "unspecified" ),
wxT( "power_in" ),
wxT( "power_out" ),
wxT( "open_collector" ),
wxT( "open_emitter" ),
wxT( "no_connect" )
};
return msgPinElectricType[static_cast<int>( aType )];
}
enum class GRAPHIC_PINSHAPE enum class GRAPHIC_PINSHAPE
{ {
LINE, LINE,

View File

@ -25,10 +25,15 @@
#include <properties/property.h> #include <properties/property.h>
#include <algorithm> #include <algorithm>
#include <ranges>
#include <utility> #include <utility>
#include <wx/wx.h> #include <wx/wx.h>
static wxString EMPTY_STRING( wxEmptyString );
// Global to prevent simultaneous multi-threaded static initialization
static const std::vector<PROPERTY_BASE*> EMPTY_PROP_LIST;
static const std::map<PROPERTY_BASE*, int> EMPTY_PROP_DISPLAY_ORDER;
std::vector<wxString> EMPTY_GROUP_DISPLAY_ORDER;
void PROPERTY_MANAGER::RegisterType( TYPE_ID aType, const wxString& aName ) void PROPERTY_MANAGER::RegisterType( TYPE_ID aType, const wxString& aName )
@ -38,13 +43,6 @@ void PROPERTY_MANAGER::RegisterType( TYPE_ID aType, const wxString& aName )
} }
const wxString& PROPERTY_MANAGER::ResolveType( TYPE_ID aType ) const
{
auto it = m_classNames.find( aType );
return it != m_classNames.end() ? it->second : EMPTY_STRING;
}
PROPERTY_BASE* PROPERTY_MANAGER::GetProperty( TYPE_ID aType, const wxString& aProperty ) const PROPERTY_BASE* PROPERTY_MANAGER::GetProperty( TYPE_ID aType, const wxString& aProperty ) const
{ {
if( m_dirty ) if( m_dirty )
@ -67,31 +65,29 @@ PROPERTY_BASE* PROPERTY_MANAGER::GetProperty( TYPE_ID aType, const wxString& aPr
} }
const PROPERTY_LIST& PROPERTY_MANAGER::GetProperties( TYPE_ID aType ) const const std::vector<PROPERTY_BASE*>& PROPERTY_MANAGER::GetProperties( TYPE_ID aType ) const
{ {
if( m_dirty ) if( m_dirty )
const_cast<PROPERTY_MANAGER*>( this )->Rebuild(); const_cast<PROPERTY_MANAGER*>( this )->Rebuild();
static const PROPERTY_LIST empty;
auto it = m_classes.find( aType ); auto it = m_classes.find( aType );
if( it == m_classes.end() ) if( it == m_classes.end() )
return empty; return EMPTY_PROP_LIST;
return it->second.m_allProperties; return it->second.m_allProperties;
} }
const PROPERTY_DISPLAY_ORDER& PROPERTY_MANAGER::GetDisplayOrder( TYPE_ID aType ) const const std::map<PROPERTY_BASE*, int>& PROPERTY_MANAGER::GetDisplayOrder( TYPE_ID aType ) const
{ {
if( m_dirty ) if( m_dirty )
const_cast<PROPERTY_MANAGER*>( this )->Rebuild(); const_cast<PROPERTY_MANAGER*>( this )->Rebuild();
static const PROPERTY_DISPLAY_ORDER empty;
auto it = m_classes.find( aType ); auto it = m_classes.find( aType );
if( it == m_classes.end() ) if( it == m_classes.end() )
return empty; return EMPTY_PROP_DISPLAY_ORDER;
return it->second.m_displayOrder; return it->second.m_displayOrder;
} }
@ -102,11 +98,10 @@ const std::vector<wxString>& PROPERTY_MANAGER::GetGroupDisplayOrder( TYPE_ID aTy
if( m_dirty ) if( m_dirty )
const_cast<PROPERTY_MANAGER*>( this )->Rebuild(); const_cast<PROPERTY_MANAGER*>( this )->Rebuild();
static const std::vector<wxString> empty;
auto it = m_classes.find( aType ); auto it = m_classes.find( aType );
if( it == m_classes.end() ) if( it == m_classes.end() )
return empty; return EMPTY_GROUP_DISPLAY_ORDER;
return it->second.m_groupDisplayOrder; return it->second.m_groupDisplayOrder;
} }
@ -122,7 +117,7 @@ const void* PROPERTY_MANAGER::TypeCast( const void* aSource, TYPE_ID aBase, TYPE
if( classDesc == m_classes.end() ) if( classDesc == m_classes.end() )
return aSource; return aSource;
auto& converters = classDesc->second.m_typeCasts; const std::map<TYPE_ID, std::unique_ptr<TYPE_CAST_BASE>>& converters = classDesc->second.m_typeCasts;
auto converter = converters.find( aTarget ); auto converter = converters.find( aTarget );
if( converter == converters.end() ) // explicit type cast not found if( converter == converters.end() ) // explicit type cast not found
@ -137,6 +132,7 @@ PROPERTY_BASE& PROPERTY_MANAGER::AddProperty( PROPERTY_BASE* aProperty, const wx
const wxString& name = aProperty->Name(); const wxString& name = aProperty->Name();
TYPE_ID hash = aProperty->OwnerHash(); TYPE_ID hash = aProperty->OwnerHash();
CLASS_DESC& classDesc = getClass( hash ); CLASS_DESC& classDesc = getClass( hash );
classDesc.m_ownProperties.emplace( name, aProperty ); classDesc.m_ownProperties.emplace( name, aProperty );
classDesc.m_ownDisplayOrder.emplace_back( aProperty ); classDesc.m_ownDisplayOrder.emplace_back( aProperty );
@ -153,8 +149,8 @@ PROPERTY_BASE& PROPERTY_MANAGER::AddProperty( PROPERTY_BASE* aProperty, const wx
} }
PROPERTY_BASE& PROPERTY_MANAGER::ReplaceProperty( size_t aBase, const wxString& aName, PROPERTY_BASE& PROPERTY_MANAGER::ReplaceProperty( size_t aBase, const wxString& aName, PROPERTY_BASE* aNew,
PROPERTY_BASE* aNew, const wxString& aGroup ) const wxString& aGroup )
{ {
CLASS_DESC& classDesc = getClass( aNew->OwnerHash() ); CLASS_DESC& classDesc = getClass( aNew->OwnerHash() );
classDesc.m_replaced.insert( std::make_pair( aBase, aName ) ); classDesc.m_replaced.insert( std::make_pair( aBase, aName ) );
@ -166,29 +162,28 @@ void PROPERTY_MANAGER::AddTypeCast( TYPE_CAST_BASE* aCast )
{ {
TYPE_ID derivedHash = aCast->DerivedHash(); TYPE_ID derivedHash = aCast->DerivedHash();
CLASS_DESC& classDesc = getClass( aCast->BaseHash() ); CLASS_DESC& classDesc = getClass( aCast->BaseHash() );
auto& typeCasts = classDesc.m_typeCasts;
wxASSERT_MSG( typeCasts.count( derivedHash ) == 0, "Such converter already exists" ); wxASSERT_MSG( classDesc.m_typeCasts.count( derivedHash ) == 0, wxT( "Such converter already exists" ) );
typeCasts.emplace( derivedHash, aCast ); classDesc.m_typeCasts.emplace( derivedHash, aCast );
} }
void PROPERTY_MANAGER::InheritsAfter( TYPE_ID aDerived, TYPE_ID aBase ) void PROPERTY_MANAGER::InheritsAfter( TYPE_ID aDerived, TYPE_ID aBase )
{ {
wxASSERT_MSG( aDerived != aBase, "Class cannot inherit from itself" ); wxASSERT_MSG( aDerived != aBase, wxT( "Class cannot inherit from itself" ) );
CLASS_DESC& derived = getClass( aDerived ); CLASS_DESC& derived = getClass( aDerived );
CLASS_DESC& base = getClass( aBase ); derived.m_bases.push_back( getClass( aBase ) );
derived.m_bases.push_back( base );
m_dirty = true; m_dirty = true;
wxASSERT_MSG( derived.m_bases.size() == 1 || derived.m_typeCasts.count( aBase ) == 1, wxASSERT_MSG( derived.m_bases.size() == 1 || derived.m_typeCasts.count( aBase ) == 1,
"You need to add a TYPE_CAST for classes inheriting from multiple bases" ); wxT( "You need to add a TYPE_CAST for classes inheriting from multiple bases" ) );
} }
void PROPERTY_MANAGER::Mask( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName ) void PROPERTY_MANAGER::Mask( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName )
{ {
wxASSERT_MSG( aDerived != aBase, "Class cannot mask from itself" ); wxASSERT_MSG( aDerived != aBase, wxT( "Class cannot mask from itself" ) );
CLASS_DESC& derived = getClass( aDerived ); CLASS_DESC& derived = getClass( aDerived );
derived.m_maskedBaseProperties.insert( std::make_pair( aBase, aName ) ); derived.m_maskedBaseProperties.insert( std::make_pair( aBase, aName ) );
@ -196,11 +191,10 @@ void PROPERTY_MANAGER::Mask( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aN
} }
void PROPERTY_MANAGER::OverrideAvailability( TYPE_ID aDerived, TYPE_ID aBase, void PROPERTY_MANAGER::OverrideAvailability( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName,
const wxString& aName,
std::function<bool( INSPECTABLE* )> aFunc ) std::function<bool( INSPECTABLE* )> aFunc )
{ {
wxASSERT_MSG( aDerived != aBase, "Class cannot override from itself" ); wxASSERT_MSG( aDerived != aBase, wxT( "Class cannot override from itself" ) );
CLASS_DESC& derived = getClass( aDerived ); CLASS_DESC& derived = getClass( aDerived );
derived.m_availabilityOverrides[std::make_pair( aBase, aName )] = std::move( aFunc ); derived.m_availabilityOverrides[std::make_pair( aBase, aName )] = std::move( aFunc );
@ -208,11 +202,10 @@ void PROPERTY_MANAGER::OverrideAvailability( TYPE_ID aDerived, TYPE_ID aBase,
} }
void PROPERTY_MANAGER::OverrideWriteability( TYPE_ID aDerived, TYPE_ID aBase, void PROPERTY_MANAGER::OverrideWriteability( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName,
const wxString& aName,
std::function<bool( INSPECTABLE* )> aFunc ) std::function<bool( INSPECTABLE* )> aFunc )
{ {
wxASSERT_MSG( aDerived != aBase, "Class cannot override from itself" ); wxASSERT_MSG( aDerived != aBase, wxT( "Class cannot override from itself" ) );
CLASS_DESC& derived = getClass( aDerived ); CLASS_DESC& derived = getClass( aDerived );
derived.m_writeabilityOverrides[std::make_pair( aBase, aName )] = std::move( aFunc ); derived.m_writeabilityOverrides[std::make_pair( aBase, aName )] = std::move( aFunc );
@ -220,16 +213,14 @@ void PROPERTY_MANAGER::OverrideWriteability( TYPE_ID aDerived, TYPE_ID aBase,
} }
bool PROPERTY_MANAGER::IsAvailableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp, bool PROPERTY_MANAGER::IsAvailableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp, INSPECTABLE* aItem )
INSPECTABLE* aItem )
{ {
if( !aProp->Available( aItem ) ) if( !aProp->Available( aItem ) )
return false; return false;
CLASS_DESC& derived = getClass( aItemClass ); CLASS_DESC& derived = getClass( aItemClass );
auto it = derived.m_availabilityOverrides.find( std::make_pair( aProp->BaseHash(), auto it = derived.m_availabilityOverrides.find( std::make_pair( aProp->BaseHash(), aProp->Name() ) );
aProp->Name() ) );
if( it != derived.m_availabilityOverrides.end() ) if( it != derived.m_availabilityOverrides.end() )
return it->second( aItem ); return it->second( aItem );
@ -238,16 +229,14 @@ bool PROPERTY_MANAGER::IsAvailableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp,
} }
bool PROPERTY_MANAGER::IsWriteableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp, bool PROPERTY_MANAGER::IsWriteableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp, INSPECTABLE* aItem )
INSPECTABLE* aItem )
{ {
if( !aProp->Writeable( aItem ) ) if( !aProp->Writeable( aItem ) )
return false; return false;
CLASS_DESC& derived = getClass( aItemClass ); CLASS_DESC& derived = getClass( aItemClass );
auto it = derived.m_writeabilityOverrides.find( std::make_pair( aProp->BaseHash(), auto it = derived.m_writeabilityOverrides.find( std::make_pair( aProp->BaseHash(), aProp->Name() ) );
aProp->Name() ) );
if( it != derived.m_writeabilityOverrides.end() ) if( it != derived.m_writeabilityOverrides.end() )
return it->second( aItem ); return it->second( aItem );
@ -265,7 +254,7 @@ bool PROPERTY_MANAGER::IsOfType( TYPE_ID aDerived, TYPE_ID aBase ) const
wxCHECK( derived != m_classes.end(), false ); // missing class description wxCHECK( derived != m_classes.end(), false ); // missing class description
// traverse the hierarchy seeking for the base class // traverse the hierarchy seeking for the base class
for( auto& base : derived->second.m_bases ) for( const std::reference_wrapper<CLASS_DESC>& base : derived->second.m_bases )
{ {
if( IsOfType( base.get().m_id, aBase ) ) if( IsOfType( base.get().m_id, aBase ) )
return true; return true;
@ -297,8 +286,8 @@ PROPERTY_MANAGER::CLASS_DESC& PROPERTY_MANAGER::getClass( TYPE_ID aTypeId )
void PROPERTY_MANAGER::CLASS_DESC::rebuild() void PROPERTY_MANAGER::CLASS_DESC::rebuild()
{ {
PROPERTY_SET replaced; std::set<std::pair<size_t, wxString>> replaced;
PROPERTY_SET masked; std::set<std::pair<size_t, wxString>> masked;
m_allProperties.clear(); m_allProperties.clear();
collectPropsRecur( m_allProperties, replaced, m_displayOrder, masked ); collectPropsRecur( m_allProperties, replaced, m_displayOrder, masked );
@ -338,10 +327,10 @@ void PROPERTY_MANAGER::CLASS_DESC::rebuild()
} }
void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( PROPERTY_LIST& aResult, void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( std::vector<PROPERTY_BASE*>& aResult,
PROPERTY_SET& aReplaced, std::set<std::pair<size_t, wxString>>& aReplaced,
PROPERTY_DISPLAY_ORDER& aDisplayOrder, std::map<PROPERTY_BASE*, int>& aDisplayOrder,
PROPERTY_SET& aMasked ) const std::set<std::pair<size_t, wxString>>& aMasked ) const
{ {
for( const std::pair<size_t, wxString>& replacedEntry : m_replaced ) for( const std::pair<size_t, wxString>& replacedEntry : m_replaced )
aReplaced.emplace( replacedEntry ); aReplaced.emplace( replacedEntry );
@ -371,7 +360,7 @@ void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( PROPERTY_LIST& aResult,
for( PROPERTY_BASE* property : m_ownDisplayOrder ) for( PROPERTY_BASE* property : m_ownDisplayOrder )
{ {
PROPERTY_SET::key_type propertyKey = std::make_pair( property->OwnerHash(), std::set<std::pair<size_t, wxString>>::key_type propertyKey = std::make_pair( property->OwnerHash(),
property->Name() ); property->Name() );
// Do not store replaced properties // Do not store replaced properties
if( aReplaced.count( propertyKey ) ) if( aReplaced.count( propertyKey ) )
@ -386,28 +375,8 @@ void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( PROPERTY_LIST& aResult,
} }
// Iterate backwards so that replaced properties appear before base properties // Iterate backwards so that replaced properties appear before base properties
for( auto it = m_bases.rbegin(); it != m_bases.rend(); ++it ) for( std::reference_wrapper<CLASS_DESC> base : std::ranges::reverse_view( m_bases ) )
it->get().collectPropsRecur( aResult, aReplaced, aDisplayOrder, aMasked ); base.get().collectPropsRecur( aResult, aReplaced, aDisplayOrder, aMasked );
}
std::vector<TYPE_ID> PROPERTY_MANAGER::GetMatchingClasses( PROPERTY_BASE* aProperty )
{
std::vector<TYPE_ID> ids;
/*
for( auto& cls : m_classes )
{
CLASS_INFO info;
for( auto prop : cls.second.m_allProperties )
info.properties.push_back(prop);
}
*/
return ids;
} }
@ -458,7 +427,7 @@ void PROPERTY_MANAGER::PropertyChanged( INSPECTABLE* aObject, PROPERTY_BASE* aPr
PROPERTY_COMMIT_HANDLER::PROPERTY_COMMIT_HANDLER( COMMIT* aCommit ) PROPERTY_COMMIT_HANDLER::PROPERTY_COMMIT_HANDLER( COMMIT* aCommit )
{ {
wxCHECK2_MSG( PROPERTY_MANAGER::Instance().m_managedCommit == nullptr, wxCHECK2_MSG( PROPERTY_MANAGER::Instance().m_managedCommit == nullptr,
return, "Can't have more than one managed commit at a time!" ); return, wxT( "Can't have more than one managed commit at a time!" ) );
PROPERTY_MANAGER::Instance().m_managedCommit = aCommit; PROPERTY_MANAGER::Instance().m_managedCommit = aCommit;
} }
@ -467,7 +436,7 @@ PROPERTY_COMMIT_HANDLER::PROPERTY_COMMIT_HANDLER( COMMIT* aCommit )
PROPERTY_COMMIT_HANDLER::~PROPERTY_COMMIT_HANDLER() PROPERTY_COMMIT_HANDLER::~PROPERTY_COMMIT_HANDLER()
{ {
wxASSERT_MSG( PROPERTY_MANAGER::Instance().m_managedCommit != nullptr, wxASSERT_MSG( PROPERTY_MANAGER::Instance().m_managedCommit != nullptr,
"Something went wrong: m_managedCommit already null!" ); wxT( "Something went wrong: m_managedCommit already null!" ) );
PROPERTY_MANAGER::Instance().m_managedCommit = nullptr; PROPERTY_MANAGER::Instance().m_managedCommit = nullptr;
} }

View File

@ -122,17 +122,14 @@ PROPERTIES_PANEL::PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame )
m_grid->CenterSplitter(); m_grid->CenterSplitter();
Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( PROPERTIES_PANEL::onCharHook ), nullptr, this ); Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( PROPERTIES_PANEL::onCharHook ), nullptr, this );
Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanged ), Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanged ), nullptr, this );
nullptr, this ); Connect( wxEVT_PG_CHANGING, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanging ), nullptr, this );
Connect( wxEVT_PG_CHANGING, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanging ),
nullptr, this );
Connect( wxEVT_SHOW, wxShowEventHandler( PROPERTIES_PANEL::onShow ), nullptr, this ); Connect( wxEVT_SHOW, wxShowEventHandler( PROPERTIES_PANEL::onShow ), nullptr, this );
Bind( wxEVT_PG_COL_END_DRAG, Bind( wxEVT_PG_COL_END_DRAG,
[&]( wxPropertyGridEvent& ) [&]( wxPropertyGridEvent& )
{ {
m_splitter_key_proportion = m_splitter_key_proportion = static_cast<float>( m_grid->GetSplitterPosition() ) / m_grid->GetSize().x;
static_cast<float>( m_grid->GetSplitterPosition() ) / m_grid->GetSize().x;
} ); } );
Bind( wxEVT_SIZE, Bind( wxEVT_SIZE,
@ -227,13 +224,11 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
std::set<PROPERTY_BASE*> commonProps; std::set<PROPERTY_BASE*> commonProps;
const PROPERTY_LIST& allProperties = propMgr.GetProperties( *types.begin() ); const std::vector<PROPERTY_BASE*>& allProperties = propMgr.GetProperties( *types.begin() );
copy( allProperties.begin(), allProperties.end(), copy( allProperties.begin(), allProperties.end(), inserter( commonProps, commonProps.begin() ) );
inserter( commonProps, commonProps.begin() ) );
PROPERTY_DISPLAY_ORDER displayOrder = propMgr.GetDisplayOrder( *types.begin() );
std::map<PROPERTY_BASE*, int> displayOrder = propMgr.GetDisplayOrder( *types.begin() );
std::vector<wxString> groupDisplayOrder = propMgr.GetGroupDisplayOrder( *types.begin() ); std::vector<wxString> groupDisplayOrder = propMgr.GetGroupDisplayOrder( *types.begin() );
std::set<wxString> groups( groupDisplayOrder.begin(), groupDisplayOrder.end() ); std::set<wxString> groups( groupDisplayOrder.begin(), groupDisplayOrder.end() );
@ -242,16 +237,12 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
// Get all possible properties // Get all possible properties
for( const TYPE_ID& type : types ) for( const TYPE_ID& type : types )
{ {
const PROPERTY_LIST& itemProps = propMgr.GetProperties( type ); const std::vector<PROPERTY_BASE*>& itemProps = propMgr.GetProperties( type );
const std::map<PROPERTY_BASE*, int>& itemDisplayOrder = propMgr.GetDisplayOrder( type );
const PROPERTY_DISPLAY_ORDER& itemDisplayOrder = propMgr.GetDisplayOrder( type ); copy( itemDisplayOrder.begin(), itemDisplayOrder.end(), inserter( displayOrder, displayOrder.begin() ) );
copy( itemDisplayOrder.begin(), itemDisplayOrder.end(), for( const wxString& group : propMgr.GetGroupDisplayOrder( type ) )
inserter( displayOrder, displayOrder.begin() ) );
const std::vector<wxString>& itemGroups = propMgr.GetGroupDisplayOrder( type );
for( const wxString& group : itemGroups )
{ {
if( !groups.count( group ) ) if( !groups.count( group ) )
{ {
@ -306,8 +297,9 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
continue; continue;
wxVariant commonVal; wxVariant commonVal;
wxPGChoices choices;
extractValueAndWritability( aSelection, property, commonVal, writeable ); extractValueAndWritability( aSelection, property, commonVal, writeable, choices );
pgProp->SetValue( commonVal ); pgProp->SetValue( commonVal );
pgProp->Enable( writeable ); pgProp->Enable( writeable );
@ -327,12 +319,16 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
{ {
wxPGProperty* pgProp = createPGProperty( property ); wxPGProperty* pgProp = createPGProperty( property );
wxVariant commonVal; wxVariant commonVal;
wxPGChoices choices;
if( !extractValueAndWritability( aSelection, property, commonVal, writeable ) ) if( !extractValueAndWritability( aSelection, property, commonVal, writeable, choices ) )
continue; continue;
if( pgProp ) if( pgProp )
{ {
if( choices.GetCount() )
pgProp->SetChoices( choices );
pgProp->SetValue( commonVal ); pgProp->SetValue( commonVal );
pgProp->Enable( writeable ); pgProp->Enable( writeable );
m_displayed.push_back( property ); m_displayed.push_back( property );
@ -403,13 +399,12 @@ bool PROPERTIES_PANEL::getItemValue( EDA_ITEM* aItem, PROPERTY_BASE* aProperty,
} }
bool PROPERTIES_PANEL::extractValueAndWritability( const SELECTION& aSelection, bool PROPERTIES_PANEL::extractValueAndWritability( const SELECTION& aSelection, PROPERTY_BASE* aProperty,
PROPERTY_BASE* aProperty, wxVariant& aValue, bool& aWritable, wxPGChoices& aChoices )
wxVariant& aValue, bool& aWritable )
{ {
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
bool different = false; bool different = false;
wxVariant commonVal; bool first = true;
aWritable = true; aWritable = true;
@ -421,6 +416,22 @@ bool PROPERTIES_PANEL::extractValueAndWritability( const SELECTION& aSelection,
if( aProperty->IsHiddenFromPropertiesManager() ) if( aProperty->IsHiddenFromPropertiesManager() )
return false; return false;
wxPGChoices choices = aProperty->GetChoices( item );
if( first )
{
aChoices = choices;
first = false;
}
else
{
wxArrayString labels = choices.GetLabels();
wxArrayInt values = choices.GetValuesForStrings( labels );
if( labels != aChoices.GetLabels() || values != aChoices.GetValuesForStrings( labels ) )
return false;
}
// If read-only for any of the selection, read-only for the whole selection. // If read-only for any of the selection, read-only for the whole selection.
if( !propMgr.IsWriteableFor( TYPE_HASH( *item ), aProperty, item ) ) if( !propMgr.IsWriteableFor( TYPE_HASH( *item ), aProperty, item ) )
aWritable = false; aWritable = false;

View File

@ -102,7 +102,7 @@ protected:
* @return true if the property is available for all the items in the selection * @return true if the property is available for all the items in the selection
*/ */
bool extractValueAndWritability( const SELECTION& aSelection, PROPERTY_BASE* aProperty, bool extractValueAndWritability( const SELECTION& aSelection, PROPERTY_BASE* aProperty,
wxVariant& aValue, bool& aWritable ); wxVariant& aValue, bool& aWritable, wxPGChoices& aChoices );
public: public:
int m_SuppressGridChangeEvents; int m_SuppressGridChangeEvents;

View File

@ -445,12 +445,7 @@ bool DIALOG_FIELD_PROPERTIES::TransferDataToWindow()
const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( parent ); const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( parent );
for( int ii = 1; ii <= symbol->GetUnitCount(); ii++ ) for( int ii = 1; ii <= symbol->GetUnitCount(); ii++ )
{ m_unitChoice->Append( symbol->GetUnitDisplayName( ii, false ) );
if( symbol->HasUnitDisplayName( ii ) )
m_unitChoice->Append( symbol->GetUnitDisplayName( ii ) );
else
m_unitChoice->Append( symbol->SubReference( ii, false ) );
}
if( symbol->GetUnit() <= (int) m_unitChoice->GetCount() ) if( symbol->GetUnit() <= (int) m_unitChoice->GetCount() )
m_unitChoice->SetSelection( symbol->GetUnit() - 1 ); m_unitChoice->SetSelection( symbol->GetUnit() - 1 );

View File

@ -1143,7 +1143,7 @@ DIALOG_LIB_EDIT_PIN_TABLE::DIALOG_LIB_EDIT_PIN_TABLE( SYMBOL_EDIT_FRAME* parent,
m_unitFilter->Append( wxGetTranslation( UNITS_ALL ) ); m_unitFilter->Append( wxGetTranslation( UNITS_ALL ) );
for( int ii = 0; ii < aSymbol->GetUnitCount(); ++ii ) for( int ii = 0; ii < aSymbol->GetUnitCount(); ++ii )
m_unitFilter->Append( aSymbol->GetUnitReference( ii + 1 ) ); m_unitFilter->Append( LIB_SYMBOL::LetterSubReference( ii + 1, 'A' ) );
m_unitFilter->SetSelection( -1 ); m_unitFilter->SetSelection( -1 );
} }

View File

@ -483,12 +483,7 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataToWindow()
m_symbol->SetUnit( m_symbol->GetUnitSelection( &GetParent()->GetCurrentSheet() ) ); m_symbol->SetUnit( m_symbol->GetUnitSelection( &GetParent()->GetCurrentSheet() ) );
for( int ii = 1; ii <= m_symbol->GetUnitCount(); ii++ ) for( int ii = 1; ii <= m_symbol->GetUnitCount(); ii++ )
{ m_unitChoice->Append( m_symbol->GetUnitDisplayName( ii, false ) );
if( m_symbol->HasUnitDisplayName( ii ) )
m_unitChoice->Append( m_symbol->GetUnitDisplayName( ii ) );
else
m_unitChoice->Append( m_symbol->SubReference( ii, false ) );
}
if( m_symbol->GetUnit() <= ( int )m_unitChoice->GetCount() ) if( m_symbol->GetUnit() <= ( int )m_unitChoice->GetCount() )
m_unitChoice->SetSelection( m_symbol->GetUnit() - 1 ); m_unitChoice->SetSelection( m_symbol->GetUnit() - 1 );

View File

@ -575,11 +575,11 @@ int ERC_TESTER::TestMissingUnits()
{ {
if( ii++ == 3 ) if( ii++ == 3 )
{ {
missing_pin_units += wxS( "....." ); missing_pin_units += wxS( "..." );
break; break;
} }
missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit ) + ", " ; missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit, false ) + ", " ;
} }
missing_pin_units.Truncate( missing_pin_units.length() - 2 ); missing_pin_units.Truncate( missing_pin_units.length() - 2 );

View File

@ -286,24 +286,31 @@ LIB_SYMBOL_SPTR LIB_SYMBOL::GetRootSymbol() const
} }
wxString LIB_SYMBOL::GetUnitReference( int aUnit ) bool LIB_SYMBOL::HasUnitDisplayName( int aUnit ) const
{
return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
}
bool LIB_SYMBOL::HasUnitDisplayName( int aUnit )
{ {
return ( m_unitDisplayNames.count( aUnit ) == 1 ); return ( m_unitDisplayNames.count( aUnit ) == 1 );
} }
wxString LIB_SYMBOL::GetUnitDisplayName( int aUnit ) wxString LIB_SYMBOL::GetUnitDisplayName( int aUnit, bool aLabel ) const
{ {
if( HasUnitDisplayName( aUnit ) ) if( m_unitDisplayNames.contains( aUnit ) )
return m_unitDisplayNames[aUnit]; return m_unitDisplayNames.at( aUnit );
else if( aLabel )
return wxString::Format( _( "Unit %s" ), LIB_SYMBOL::LetterSubReference( aUnit, 'A' ) );
else else
return wxString::Format( _( "Unit %s" ), GetUnitReference( aUnit ) ); return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
}
wxString LIB_SYMBOL::GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const
{
if( aBodyStyle == BODY_STYLE::DEMORGAN )
return aLabel ? _( "Alternate" ) : _HKI( "Alternate" );
else if( aBodyStyle == BODY_STYLE::BASE )
return aLabel ? _( "Standard" ) : _HKI( "Standard" );
else
return wxT( "?" );
} }
@ -515,7 +522,7 @@ void LIB_SYMBOL::SetNormal()
} }
wxString LIB_SYMBOL::LetterSubReference( int aUnit, int aFirstId ) wxString LIB_SYMBOL::LetterSubReference( int aUnit, wxChar aInitialLetter )
{ {
// use letters as notation. To allow more than 26 units, the sub ref // use letters as notation. To allow more than 26 units, the sub ref
// use one letter if letter = A .. Z or a ... z, and 2 letters otherwise // use one letter if letter = A .. Z or a ... z, and 2 letters otherwise
@ -526,7 +533,7 @@ wxString LIB_SYMBOL::LetterSubReference( int aUnit, int aFirstId )
do do
{ {
u = ( aUnit - 1 ) % 26; u = ( aUnit - 1 ) % 26;
suffix = wxChar( aFirstId + u ) + suffix; suffix = wxChar( aInitialLetter + u ) + suffix;
aUnit = ( aUnit - u ) / 26; aUnit = ( aUnit - u ) / 26;
} while( aUnit > 0 ); } while( aUnit > 0 );

View File

@ -542,20 +542,22 @@ public:
void SetUnitCount( int aCount, bool aDuplicateDrawItems = true ); void SetUnitCount( int aCount, bool aDuplicateDrawItems = true );
int GetUnitCount() const override; int GetUnitCount() const override;
/**
* Return an identifier for \a aUnit for symbols with units.
*/
wxString GetUnitReference( int aUnit ) override;
/** /**
* Return true if the given unit \a aUnit has a display name defined * Return true if the given unit \a aUnit has a display name defined
*/ */
bool HasUnitDisplayName( int aUnit ) override; bool HasUnitDisplayName( int aUnit ) const;
wxString GetUnitName( int aUnit ) const override
{
return GetUnitDisplayName( aUnit, true );
}
/** /**
* Return the user-defined display name for \a aUnit for symbols with units. * Return the user-defined display name for \a aUnit for symbols with units.
*/ */
wxString GetUnitDisplayName( int aUnit ) override; wxString GetUnitDisplayName( int aUnit, bool aLabel ) const override;
wxString GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const override;
/** /**
* Copy all unit display names into the given map \a aTarget * Copy all unit display names into the given map \a aTarget
@ -586,7 +588,7 @@ public:
*/ */
bool IsMulti() const override { return m_unitCount > 1; } bool IsMulti() const override { return m_unitCount > 1; }
static wxString LetterSubReference( int aUnit, int aFirstId ); static wxString LetterSubReference( int aUnit, wxChar aInitialLetter );
/** /**
* Set or clear the alternate body style (DeMorgan) for the symbol. * Set or clear the alternate body style (DeMorgan) for the symbol.

View File

@ -119,8 +119,8 @@ void SCH_EDIT_FRAME::SelectUnit( SCH_SYMBOL* aSymbol, int aUnit )
if( otherSymbolRef ) if( otherSymbolRef )
{ {
const wxString targetUnitName = symbol->GetUnitDisplayName( aUnit ); const wxString targetUnitName = symbol->GetUnitDisplayName( aUnit, false );
const wxString currUnitName = symbol->GetUnitDisplayName( currentUnit ); const wxString currUnitName = symbol->GetUnitDisplayName( currentUnit, false );
wxString otherSheetName = otherSymbolRef->GetSheetPath().PathHumanReadable( true, true ); wxString otherSheetName = otherSymbolRef->GetSheetPath().PathHumanReadable( true, true );
if( otherSheetName.IsEmpty() ) if( otherSheetName.IsEmpty() )

View File

@ -260,7 +260,7 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMAT
// if the unit has a display name, write that // if the unit has a display name, write that
if( aSymbol->HasUnitDisplayName( unit.m_unit ) ) if( aSymbol->HasUnitDisplayName( unit.m_unit ) )
{ {
name = aSymbol->GetUnitDisplayName( unit.m_unit ); name = aSymbol->GetUnitDisplayName( unit.m_unit, false );
aFormatter.Print( "(unit_name %s)", aFormatter.Quotes( name ).c_str() ); aFormatter.Print( "(unit_name %s)", aFormatter.Quotes( name ).c_str() );
} }

View File

@ -45,28 +45,6 @@
#define BITMAP_FONT_SIZE_THRESHOLD 3 #define BITMAP_FONT_SIZE_THRESHOLD 3
wxString SCH_ITEM::GetUnitDescription( int aUnit )
{
if( aUnit == 0 )
return _( "All" );
else
return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
}
wxString SCH_ITEM::GetBodyStyleDescription( int aBodyStyle )
{
if( aBodyStyle == 0 )
return _( "All" );
else if( aBodyStyle == BODY_STYLE::DEMORGAN )
return _( "Alternate" );
else if( aBodyStyle == BODY_STYLE::BASE )
return _( "Standard" );
else
return wxT( "?" );
}
/* Constructor and destructor for SCH_ITEM */ /* Constructor and destructor for SCH_ITEM */
/* They are not inline because this creates problems with gcc at linking time in debug mode */ /* They are not inline because this creates problems with gcc at linking time in debug mode */
@ -187,25 +165,81 @@ SCH_ITEM* SCH_ITEM::Duplicate( bool addToParentGroup, SCH_COMMIT* aCommit, bool
} }
void SCH_ITEM::SetUnitProp( int aUnit ) void SCH_ITEM::SetUnitProp( const wxString& aUnit )
{ {
if( GetParentSymbol() ) if( aUnit == _HKI( "All units" ) )
aUnit = std::min( aUnit, GetParentSymbol()->GetUnitCount() ); {
m_unit = 0;
return;
}
aUnit = std::max( aUnit, 0 ); if( SYMBOL* symbol = GetParentSymbol() )
{
m_unit = aUnit; for( int unit = 1; unit <= symbol->GetUnitCount(); unit++ )
{
if( symbol->GetUnitDisplayName( unit, false ) == aUnit )
{
m_unit = unit;
return;
}
}
}
} }
void SCH_ITEM::SetBodyStyleProp( int aBodyStyle ) wxString SCH_ITEM::GetUnitDisplayName( int aUnit, bool aLabel ) const
{ {
if( GetParentSymbol() && GetParentSymbol()->HasAlternateBodyStyle() ) if( aUnit == 0 )
aBodyStyle = std::min( aBodyStyle, (int) BODY_STYLE::DEMORGAN ); return aLabel ? _( "All units" ) : _HKI( "All units" );
else if( const SYMBOL* symbol = GetParentSymbol() )
return symbol->GetUnitDisplayName( aUnit, aLabel );
aBodyStyle = std::max( aBodyStyle, 0 ); return wxEmptyString;
}
m_bodyStyle = aBodyStyle;
wxString SCH_ITEM::GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const
{
if( aBodyStyle == 0 )
return aLabel ? _( "All body styles" ) : _HKI( "All body styles" );
else if( const SYMBOL* symbol = GetParentSymbol() )
return symbol->GetBodyStyleDescription( aBodyStyle, aLabel );
return wxEmptyString;
}
wxString SCH_ITEM::GetUnitProp() const
{
return GetUnitDisplayName( m_unit, false );
}
void SCH_ITEM::SetBodyStyleProp( const wxString& aBodyStyle )
{
if( aBodyStyle == _HKI( "All body styles" ) )
{
m_bodyStyle = 0;
return;
}
if( SYMBOL* symbol = GetParentSymbol() )
{
for( int bodyStyle : { BODY_STYLE::BASE, BODY_STYLE::DEMORGAN } )
{
if( symbol->GetBodyStyleDescription( bodyStyle, false ) == aBodyStyle )
{
m_bodyStyle = bodyStyle;
return;
}
}
}
}
wxString SCH_ITEM::GetBodyStyleProp() const
{
return GetBodyStyleDescription( m_bodyStyle, false );
} }
@ -625,21 +659,18 @@ bool SCH_ITEM::RenderAsBitmap( double aWorldScale ) const
} }
void SCH_ITEM::getSymbolEditorMsgPanelInfo( EDA_DRAW_FRAME* aFrame, void SCH_ITEM::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
std::vector<MSG_PANEL_ITEM>& aList )
{ {
aList.emplace_back( _( "Type" ), GetFriendlyName() ); wxString msg;
SYMBOL* symbol = GetParentSymbol();
if( const SYMBOL* parent = GetParentSymbol() ) if( symbol->GetUnitCount() )
{ aList.emplace_back( _( "Unit" ), GetUnitDisplayName( GetUnit(), false ) );
if( parent->GetUnitCount() )
aList.emplace_back( _( "Unit" ), GetUnitDescription( m_unit ) );
if( parent->HasAlternateBodyStyle() ) if( symbol->HasAlternateBodyStyle() )
aList.emplace_back( _( "Body Style" ), GetBodyStyleDescription( m_bodyStyle ) ); aList.emplace_back( _( "Body Style" ), GetBodyStyleDescription( GetBodyStyle(), true ) );
}
if( IsPrivate() ) if( dynamic_cast<LIB_SYMBOL*>( symbol ) && IsPrivate() )
aList.emplace_back( _( "Private" ), wxEmptyString ); aList.emplace_back( _( "Private" ), wxEmptyString );
} }
@ -682,15 +713,48 @@ static struct SCH_ITEM_DESC
return false; return false;
}; };
propMgr.AddProperty( new PROPERTY<SCH_ITEM, int>( _HKI( "Unit" ), propMgr.AddProperty( new PROPERTY<SCH_ITEM, wxString>( _HKI( "Unit" ),
&SCH_ITEM::SetUnitProp, &SCH_ITEM::GetUnit ) ) &SCH_ITEM::SetUnitProp, &SCH_ITEM::GetUnitProp ) )
.SetAvailableFunc( multiUnit ) .SetAvailableFunc( multiUnit )
.SetIsHiddenFromDesignEditors(); .SetIsHiddenFromDesignEditors()
.SetChoicesFunc( []( INSPECTABLE* aItem )
{
wxPGChoices choices;
choices.Add( _HKI( "All units" ) );
propMgr.AddProperty( new PROPERTY<SCH_ITEM, int>( _HKI( "Body Style" ), if( SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aItem ) )
&SCH_ITEM::SetBodyStyle, &SCH_ITEM::GetBodyStyle ) ) {
if( SYMBOL* symbol = item->GetParentSymbol() )
{
for( int ii = 1; ii <= symbol->GetUnitCount(); ii++ )
choices.Add( symbol->GetUnitDisplayName( ii, false ) );
}
}
return choices;
} );
propMgr.AddProperty( new PROPERTY<SCH_ITEM, wxString>( _HKI( "Body Style" ),
&SCH_ITEM::SetBodyStyleProp, &SCH_ITEM::GetBodyStyleProp ) )
.SetAvailableFunc( multiBodyStyle ) .SetAvailableFunc( multiBodyStyle )
.SetIsHiddenFromDesignEditors(); .SetIsHiddenFromDesignEditors()
.SetChoicesFunc( []( INSPECTABLE* aItem )
{
wxPGChoices choices;
choices.Add( _HKI( "All body styles" ) );
if( SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aItem ) )
{
if( SYMBOL* symbol = item->GetParentSymbol() )
{
for( int ii : { BODY_STYLE::BASE, BODY_STYLE::DEMORGAN } )
choices.Add( symbol->GetBodyStyleDescription( ii, false ) );
}
}
return choices;
} );
propMgr.AddProperty( new PROPERTY<SCH_ITEM, bool>( _HKI( "Private" ), propMgr.AddProperty( new PROPERTY<SCH_ITEM, bool>( _HKI( "Private" ),
&SCH_ITEM::SetPrivate, &SCH_ITEM::IsPrivate ) ) &SCH_ITEM::SetPrivate, &SCH_ITEM::IsPrivate ) )

View File

@ -235,16 +235,20 @@ public:
*/ */
SCH_ITEM* Duplicate( bool addToParentGroup, SCH_COMMIT* aCommit = nullptr, bool doClone = false ) const; SCH_ITEM* Duplicate( bool addToParentGroup, SCH_COMMIT* aCommit = nullptr, bool doClone = false ) const;
static wxString GetUnitDescription( int aUnit );
static wxString GetBodyStyleDescription( int aBodyStyle );
virtual void SetUnit( int aUnit ) { m_unit = aUnit; } virtual void SetUnit( int aUnit ) { m_unit = aUnit; }
int GetUnit() const { return m_unit; } int GetUnit() const { return m_unit; }
void SetUnitProp( int aUnit );
virtual wxString GetUnitDisplayName( int aUnit, bool aLabel ) const;
virtual wxString GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const;
virtual void SetUnitProp( const wxString& aUnit );
virtual wxString GetUnitProp() const;
virtual void SetBodyStyle( int aBodyStyle ) { m_bodyStyle = aBodyStyle; } virtual void SetBodyStyle( int aBodyStyle ) { m_bodyStyle = aBodyStyle; }
int GetBodyStyle() const { return m_bodyStyle; } int GetBodyStyle() const { return m_bodyStyle; }
void SetBodyStyleProp( int aBodyStyle );
virtual void SetBodyStyleProp( const wxString& aBodyStyle );
virtual wxString GetBodyStyleProp() const;
void SetPrivate( bool aPrivate ) { m_private = aPrivate; } void SetPrivate( bool aPrivate ) { m_private = aPrivate; }
bool IsPrivate() const { return m_private; } bool IsPrivate() const { return m_private; }
@ -612,6 +616,8 @@ public:
virtual void SetStroke( const STROKE_PARAMS& aStroke ) { wxCHECK( false, /* void */ ); } virtual void SetStroke( const STROKE_PARAMS& aStroke ) { wxCHECK( false, /* void */ ); }
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
/** /**
* Plot the item to \a aPlotter. * Plot the item to \a aPlotter.
* *
@ -692,8 +698,6 @@ protected:
bool operator()( const SCH_ITEM* aFirst, const SCH_ITEM* aSecond ) const; bool operator()( const SCH_ITEM* aFirst, const SCH_ITEM* aSecond ) const;
}; };
void getSymbolEditorMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList );
/** /**
* Provide the draw object specific comparison called by the == and < operators. * Provide the draw object specific comparison called by the == and < operators.
* *

View File

@ -43,32 +43,6 @@
// small margin in internal units between the pin text and the pin line // small margin in internal units between the pin text and the pin line
#define PIN_TEXT_MARGIN 4 #define PIN_TEXT_MARGIN 4
wxString SCH_PIN::GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE aType )
{
// These strings are the canonical name of the electrictal type
// Not translated, no space in name, only ASCII chars.
// to use when the string name must be known and well defined
// must have same order than enum ELECTRICAL_PINTYPE (see sch_pin.h)
static const wxChar* msgPinElectricType[] =
{
wxT( "input" ),
wxT( "output" ),
wxT( "bidirectional" ),
wxT( "tri_state" ),
wxT( "passive" ),
wxT( "free" ),
wxT( "unspecified" ),
wxT( "power_in" ),
wxT( "power_out" ),
wxT( "open_collector" ),
wxT( "open_emitter" ),
wxT( "no_connect" )
};
return msgPinElectricType[static_cast<int>( aType )];
}
/// Utility for getting the size of the 'internal' pin decorators (as a radius) /// Utility for getting the size of the 'internal' pin decorators (as a radius)
/// i.e. the clock symbols (falling clock is actually external but is of /// i.e. the clock symbols (falling clock is actually external but is of
/// the same kind) /// the same kind)
@ -324,29 +298,25 @@ void SCH_PIN::SetType( ELECTRICAL_PINTYPE aType )
wxString SCH_PIN::GetCanonicalElectricalTypeName() const wxString SCH_PIN::GetCanonicalElectricalTypeName() const
{ {
if( m_type == ELECTRICAL_PINTYPE::PT_INHERIT ) if( m_type != ELECTRICAL_PINTYPE::PT_INHERIT )
{ return ::GetCanonicalElectricalTypeName( m_type );
if( !m_libPin ) if( !m_libPin )
return GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE::PT_UNSPECIFIED ); return ::GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
return m_libPin->GetCanonicalElectricalTypeName(); return m_libPin->GetCanonicalElectricalTypeName();
}
return GetCanonicalElectricalTypeName( m_type );
} }
wxString SCH_PIN::GetElectricalTypeName() const wxString SCH_PIN::GetElectricalTypeName() const
{ {
if( m_type == ELECTRICAL_PINTYPE::PT_INHERIT ) if( m_type != ELECTRICAL_PINTYPE::PT_INHERIT )
{ return ElectricalPinTypeGetText( m_type );
if( !m_libPin ) if( !m_libPin )
return ElectricalPinTypeGetText( ELECTRICAL_PINTYPE::PT_UNSPECIFIED ); return ElectricalPinTypeGetText( ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
return m_libPin->GetElectricalTypeName(); return m_libPin->GetElectricalTypeName();
}
return ElectricalPinTypeGetText( m_type );
} }
@ -1156,28 +1126,9 @@ void SCH_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITE
wxString msg; wxString msg;
SYMBOL* symbol = GetParentSymbol(); SYMBOL* symbol = GetParentSymbol();
if( dynamic_cast<LIB_SYMBOL*>( symbol ) )
{
getSymbolEditorMsgPanelInfo( aFrame, aList );
}
else
{
aList.emplace_back( _( "Type" ), _( "Pin" ) ); aList.emplace_back( _( "Type" ), _( "Pin" ) );
if( symbol->GetUnitCount() ) SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
{
msg = m_libPin ? GetUnitDescription( m_libPin->GetUnit() ) :
wxString( "Undefined library pin." );
aList.emplace_back( _( "Unit" ), msg );
}
if( symbol->HasAlternateBodyStyle() )
{
msg = m_libPin ? GetBodyStyleDescription( m_libPin->GetBodyStyle() ) :
wxString( "Undefined library pin." );
aList.emplace_back( _( "Body Style" ), msg );
}
}
aList.emplace_back( _( "Name" ), UnescapeString( GetShownName() ) ); aList.emplace_back( _( "Name" ), UnescapeString( GetShownName() ) );
aList.emplace_back( _( "Number" ), GetShownNumber() ); aList.emplace_back( _( "Number" ), GetShownNumber() );

View File

@ -317,9 +317,6 @@ const BOX2I SCH_SHAPE::GetBoundingBox() const
void SCH_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) void SCH_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
{ {
if( m_layer == LAYER_DEVICE )
getSymbolEditorMsgPanelInfo( aFrame, aList );
else
SCH_ITEM::GetMsgPanelInfo( aFrame, aList ); SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
ShapeGetMsgPanelInfo( aFrame, aList ); ShapeGetMsgPanelInfo( aFrame, aList );

View File

@ -441,24 +441,32 @@ int SCH_SYMBOL::GetUnitCount() const
} }
wxString SCH_SYMBOL::GetUnitDisplayName( int aUnit ) const wxString SCH_SYMBOL::GetUnitDisplayName( int aUnit, bool aLabel ) const
{ {
wxCHECK( m_part, ( wxString::Format( _( "Unit %s" ), SubReference( aUnit ) ) ) ); if( m_part )
return m_part->GetUnitDisplayName( aUnit, aLabel );
return m_part->GetUnitDisplayName( aUnit ); else if( aLabel )
return wxString::Format( _( "Unit %s" ), SubReference( aUnit ) );
else
return SubReference( aUnit );
} }
bool SCH_SYMBOL::HasUnitDisplayName( int aUnit ) const wxString SCH_SYMBOL::GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const
{ {
wxCHECK( m_part, false ); if( m_part )
return m_part->GetBodyStyleDescription( aBodyStyle, aLabel );
return m_part->HasUnitDisplayName( aUnit ); else if( aBodyStyle == BODY_STYLE::DEMORGAN )
return aLabel ? _( "Alternate" ) : _HKI( "Alternate" );
else if( aBodyStyle == BODY_STYLE::BASE )
return aLabel ? _( "Standard" ) : _HKI( "Standard" );
else
return wxT( "?" );
} }
bool SCH_SYMBOL::GetInstance( SCH_SYMBOL_INSTANCE& aInstance, bool SCH_SYMBOL::GetInstance( SCH_SYMBOL_INSTANCE& aInstance, const KIID_PATH& aSheetPath,
const KIID_PATH& aSheetPath, bool aTestFromEnd ) const bool aTestFromEnd ) const
{ {
for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences ) for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
{ {
@ -2918,11 +2926,35 @@ static struct SCH_SYMBOL_DESC
propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Unit" ), propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Unit" ),
&SCH_SYMBOL::SetUnitProp, &SCH_SYMBOL::GetUnitProp ) ) &SCH_SYMBOL::SetUnitProp, &SCH_SYMBOL::GetUnitProp ) )
.SetAvailableFunc( multiUnit ); .SetAvailableFunc( multiUnit )
.SetChoicesFunc( []( INSPECTABLE* aItem )
{
wxPGChoices choices;
propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, int>( _HKI( "Body Style" ), if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
{
for( int ii = 1; ii <= symbol->GetUnitCount(); ii++ )
choices.Add( symbol->GetUnitDisplayName( ii, false ) );
}
return choices;
} );
propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Body Style" ),
&SCH_SYMBOL::SetBodyStyleProp, &SCH_SYMBOL::GetBodyStyleProp ) ) &SCH_SYMBOL::SetBodyStyleProp, &SCH_SYMBOL::GetBodyStyleProp ) )
.SetAvailableFunc( multiBodyStyle ); .SetAvailableFunc( multiBodyStyle )
.SetChoicesFunc( []( INSPECTABLE* aItem )
{
wxPGChoices choices;
if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
{
for( int ii : { BODY_STYLE::BASE, BODY_STYLE::DEMORGAN } )
choices.Add( symbol->GetBodyStyleDescription( ii, false ) );
}
return choices;
} );
const wxString groupAttributes = _HKI( "Attributes" ); const wxString groupAttributes = _HKI( "Attributes" );

View File

@ -221,19 +221,14 @@ public:
*/ */
void UpdatePins(); void UpdatePins();
/**
* Return true if the given unit \a aUnit has a display name set.
*
* @return true if the display name of a unit is set, otherwise false.
*/
bool HasUnitDisplayName( int aUnit ) const;
/** /**
* Return the display name for a given unit \a aUnit. * Return the display name for a given unit \a aUnit.
* *
* @return the display name of a unit if set, or the ordinal name of the unit otherwise. * @return the display name of a unit if set, or the ordinal name of the unit otherwise.
*/ */
wxString GetUnitDisplayName( int aUnit ) const; wxString GetUnitDisplayName( int aUnit, bool aLabel ) const override;
wxString GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const override;
void SetBodyStyle( int aBodyStyle ) override; void SetBodyStyle( int aBodyStyle ) override;
@ -489,6 +484,7 @@ public:
} }
void SetRefProp( const wxString& aRef ); void SetRefProp( const wxString& aRef );
wxString GetValueProp() const wxString GetValueProp() const
{ {
return GetValue( false, &Schematic()->CurrentSheet(), false ); return GetValue( false, &Schematic()->CurrentSheet(), false );
@ -499,31 +495,18 @@ public:
SetValueFieldText( aRef ); SetValueFieldText( aRef );
} }
wxString GetUnitProp() const wxString GetUnitProp() const override
{ {
int unit = GetUnitSelection( &Schematic()->CurrentSheet() ); int unit = GetUnitSelection( &Schematic()->CurrentSheet() );
if( HasUnitDisplayName( unit ) ) return GetUnitDisplayName( unit, false );
return GetUnitDisplayName( unit );
else
return SubReference( unit, false );
} }
void SetUnitProp( const wxString& aUnit ) void SetUnitProp( const wxString& aUnit ) override
{ {
for( int unit = 1; unit <= GetUnitCount(); unit++ ) for( int unit = 1; unit <= GetUnitCount(); unit++ )
{ {
if( HasUnitDisplayName( unit ) && GetUnitDisplayName( unit ) == aUnit ) if( GetUnitDisplayName( unit, false ) == aUnit )
{
SetUnitSelection( &Schematic()->CurrentSheet(), unit );
SetUnit( unit );
return;
}
}
for( int unit = 1; unit <= GetUnitCount(); unit++ )
{
if( SubReference( unit, false ) == aUnit )
{ {
SetUnitSelection( &Schematic()->CurrentSheet(), unit ); SetUnitSelection( &Schematic()->CurrentSheet(), unit );
SetUnit( unit ); SetUnit( unit );
@ -532,14 +515,21 @@ public:
} }
} }
int GetBodyStyleProp() const wxString GetBodyStyleProp() const override
{ {
return GetBodyStyle(); return GetBodyStyleDescription( GetBodyStyle(), false );
} }
void SetBodyStyleProp( int aBodyStyle ) void SetBodyStyleProp( const wxString& aBodyStyle ) override
{ {
SetBodyStyle( aBodyStyle ); for( int bodyStyle : { BODY_STYLE::BASE, BODY_STYLE::DEMORGAN } )
{
if( GetBodyStyleDescription( bodyStyle, false ) == aBodyStyle )
{
SetBodyStyle( bodyStyle );
return;
}
}
} }
/** /**

View File

@ -447,6 +447,8 @@ void SCH_TABLE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_I
{ {
// Don't use GetShownText() here; we want to show the user the variable references // Don't use GetShownText() here; we want to show the user the variable references
aList.emplace_back( _( "Table" ), wxString::Format( _( "%d Columns" ), m_colCount ) ); aList.emplace_back( _( "Table" ), wxString::Format( _( "%d Columns" ), m_colCount ) );
SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
} }

View File

@ -544,6 +544,8 @@ void SCH_TEXT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_IT
// Don't use GetShownText() here; we want to show the user the variable references // Don't use GetShownText() here; we want to show the user the variable references
aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) ); aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
if( m_excludedFromSim ) if( m_excludedFromSim )
aList.emplace_back( _( "Exclude from" ), _( "Simulation" ) ); aList.emplace_back( _( "Exclude from" ), _( "Simulation" ) );

View File

@ -455,6 +455,8 @@ void SCH_TEXTBOX::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL
// Don't use GetShownText() here; we want to show the user the variable references // Don't use GetShownText() here; we want to show the user the variable references
aList.emplace_back( _( "Text Box" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) ); aList.emplace_back( _( "Text Box" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
if( m_excludedFromSim ) if( m_excludedFromSim )
aList.emplace_back( _( "Exclude from" ), _( "Simulation" ) ); aList.emplace_back( _( "Exclude from" ), _( "Simulation" ) );

View File

@ -86,7 +86,7 @@ void CheckDuplicatePins( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
pin->GetName(), pin->GetName(),
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ), aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ), aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
SCH_ITEM::GetBodyStyleDescription( pin->GetBodyStyle() ).Lower() ); aSymbol->GetBodyStyleDescription( pin->GetBodyStyle(), true ).Lower() );
} }
else else
{ {
@ -101,9 +101,9 @@ void CheckDuplicatePins( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
pinName, pinName,
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ), aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ), aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
aSymbol->GetUnitReference( next->GetUnit() ), aSymbol->GetUnitDisplayName( next->GetUnit(), false ),
aSymbol->GetUnitReference( pin->GetUnit() ), aSymbol->GetUnitDisplayName( pin->GetUnit(), false ),
SCH_ITEM::GetBodyStyleDescription( pin->GetBodyStyle() ).Lower() ); aSymbol->GetBodyStyleDescription( pin->GetBodyStyle(), true ).Lower() );
} }
} }
else else
@ -134,8 +134,8 @@ void CheckDuplicatePins( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
pinName, pinName,
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ), aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ), aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
aSymbol->GetUnitReference( next->GetUnit() ), aSymbol->GetUnitDisplayName( next->GetUnit(), false ),
aSymbol->GetUnitReference( pin->GetUnit() ) ); aSymbol->GetUnitDisplayName( pin->GetUnit(), false ) );
} }
} }
@ -264,7 +264,7 @@ void CheckLibSymbol( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
pinName, pinName,
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ), aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ), aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
SCH_ITEM::GetBodyStyleDescription( pin->GetBodyStyle() ).Lower() ); aSymbol->GetBodyStyleDescription( pin->GetBodyStyle(), true ).Lower() );
} }
else else
{ {
@ -275,7 +275,7 @@ void CheckLibSymbol( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ), aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ), aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
'A' + pin->GetUnit() - 1, 'A' + pin->GetUnit() - 1,
SCH_ITEM::GetBodyStyleDescription( pin->GetBodyStyle() ).Lower() ); aSymbol->GetBodyStyleDescription( pin->GetBodyStyle(), true ).Lower() );
} }
} }
else else
@ -323,7 +323,7 @@ void CheckLibSymbol( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
pinName, pinName,
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ), aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ), aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
SCH_ITEM::GetBodyStyleDescription( pin->GetBodyStyle() ).Lower() ); aSymbol->GetBodyStyleDescription( pin->GetBodyStyle(), true ).Lower() );
} }
else else
{ {
@ -334,7 +334,7 @@ void CheckLibSymbol( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ), aUnitsProvider->MessageTextFromValue( pin->GetPosition().x ),
aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ), aUnitsProvider->MessageTextFromValue( -pin->GetPosition().y ),
'A' + pin->GetUnit() - 1, 'A' + pin->GetUnit() - 1,
SCH_ITEM::GetBodyStyleDescription( pin->GetBodyStyle() ).Lower() ); aSymbol->GetBodyStyleDescription( pin->GetBodyStyle(), true ).Lower() );
} }
} }
else else

View File

@ -715,7 +715,7 @@ void SYMBOL_EDIT_FRAME::RebuildSymbolUnitsList()
{ {
for( int i = 0; i < m_symbol->GetUnitCount(); i++ ) for( int i = 0; i < m_symbol->GetUnitCount(); i++ )
{ {
wxString unitDisplayName = m_symbol->GetUnitDisplayName( i + 1 ); wxString unitDisplayName = m_symbol->GetUnitDisplayName( i + 1, true );
m_unitSelectBox->Append( unitDisplayName ); m_unitSelectBox->Append( unitDisplayName );
} }
} }

View File

@ -1736,20 +1736,6 @@ void SYMBOL_EDIT_FRAME::UpdateSymbolMsgPanelInfo()
AppendMsgPanel( _( "Parent" ), UnescapeString( msg ), 8 ); AppendMsgPanel( _( "Parent" ), UnescapeString( msg ), 8 );
} }
static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
msg = UnitLetter[m_unit];
AppendMsgPanel( _( "Unit" ), msg, 8 );
if( m_bodyStyle == BODY_STYLE::DEMORGAN )
msg = _( "Alternate" );
else if( m_bodyStyle == BODY_STYLE::BASE )
msg = _( "Standard" );
else
msg = wxT( "?" );
AppendMsgPanel( _( "Body" ), msg, 8 );
if( m_symbol->IsGlobalPower() ) if( m_symbol->IsGlobalPower() )
msg = _( "Power Symbol" ); msg = _( "Power Symbol" );
else if( m_symbol->IsLocalPower() ) else if( m_symbol->IsLocalPower() )

View File

@ -504,7 +504,7 @@ void SYMBOL_VIEWER_FRAME::onUpdateUnitChoice( wxUpdateUIEvent& aEvent )
for( int ii = 0; ii < unit_count; ii++ ) for( int ii = 0; ii < unit_count; ii++ )
{ {
wxString unit = symbol->GetUnitDisplayName( ii + 1 ); wxString unit = symbol->GetUnitDisplayName( ii + 1, true );
m_unitChoice->Append( unit ); m_unitChoice->Append( unit );
} }

View File

@ -102,12 +102,7 @@ private:
for( int ii = 0; ii < nUnits; ii++ ) for( int ii = 0; ii < nUnits; ii++ )
{ {
wxString unit_text; wxString unit_text = symbol->GetUnitDisplayName( ii + 1, false );
if( symbol->GetLibSymbolRef()->HasUnitDisplayName( ii + 1 ) )
unit_text = symbol->GetLibSymbolRef()->GetUnitDisplayName( ii + 1 );
else
unit_text.Printf( _( "Unit %s" ), symbol->SubReference( ii + 1, false ) );
if( missingUnits.count( ii + 1 ) == 0 ) if( missingUnits.count( ii + 1 ) == 0 )
unit_text += _( " (already placed)" ); unit_text += _( " (already placed)" );

View File

@ -841,13 +841,11 @@ int SYMBOL_EDITOR_EDIT_TOOL::SetUnitDisplayName( const TOOL_EVENT& aEvent )
} }
wxString promptText = wxString::Format( _( "Enter display name for unit %s" ), wxString promptText = wxString::Format( _( "Enter display name for unit %s" ),
symbol->GetUnitReference( unitid ) ); LIB_SYMBOL::LetterSubReference( unitid, 'A' ) );
wxString currentvalue; wxString currentvalue;
if( symbol->HasUnitDisplayName( unitid ) ) if( symbol->HasUnitDisplayName( unitid ) )
{ currentvalue = symbol->GetUnitDisplayName( unitid, false );
currentvalue = symbol->GetUnitDisplayName( unitid );
}
wxTextEntryDialog dlg( m_frame, promptText, _( "Set Unit Display Name" ), currentvalue ); wxTextEntryDialog dlg( m_frame, promptText, _( "Set Unit Display Name" ), currentvalue );

View File

@ -261,8 +261,7 @@ void SCH_PROPERTIES_PANEL::updateFontList()
// Regnerate font names // Regnerate font names
std::vector<std::string> fontNames; std::vector<std::string> fontNames;
Fontconfig()->ListFonts( fontNames, std::string( Pgm().GetLanguageTag().utf8_str() ), Fontconfig()->ListFonts( fontNames, std::string( Pgm().GetLanguageTag().utf8_str() ), fontFiles );
fontFiles );
fonts.Add( _( "Default Font" ), -1 ); fonts.Add( _( "Default Font" ), -1 );
fonts.Add( KICAD_FONT_NAME, -2 ); fonts.Add( KICAD_FONT_NAME, -2 );

View File

@ -73,6 +73,27 @@ public:
return object != nullptr; return object != nullptr;
} }
bool Set( PROPERTY_BASE* aProperty, wxVariant aValue, bool aNotify = true )
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
void* object = propMgr.TypeCast( this, TYPE_HASH( *this ), aProperty->OwnerHash() );
if( object )
{
wxPGChoices choices = aProperty->GetChoices( this );
if( choices.GetCount() )
aProperty->set<wxString>( object, choices.GetLabel( aValue.GetInteger() ) );
else
aProperty->set<wxVariant>( object, aValue );
if( aNotify )
propMgr.PropertyChanged( this, aProperty );
}
return object != nullptr;
}
template<typename T> template<typename T>
bool Set( const wxString& aProperty, T aValue, bool aNotify = true ) bool Set( const wxString& aProperty, T aValue, bool aNotify = true )
{ {

View File

@ -81,17 +81,7 @@ public:
/** /**
* For items with units, return an identifier for unit x. * For items with units, return an identifier for unit x.
*/ */
virtual wxString GetUnitReference( int aUnit ) { return wxEmptyString; } virtual wxString GetUnitName( int aUnit ) const { return wxEmptyString; }
/**
* For items with units, return a display name for unit x.
*/
virtual wxString GetUnitDisplayName( int aUnit ) { return wxEmptyString; }
/**
* For items with units, return true if a display name is set for x.
*/
virtual bool HasUnitDisplayName( int aUnit ) { return false; }
}; };
#endif //LIB_TREE_ITEM_H #endif //LIB_TREE_ITEM_H

View File

@ -241,7 +241,7 @@ public:
*/ */
virtual bool HasChoices() const virtual bool HasChoices() const
{ {
return false; return m_choicesFunc != nullptr;
} }
/** /**
@ -261,6 +261,20 @@ public:
return *this; return *this;
} }
wxPGChoices GetChoices( INSPECTABLE* aObject ) const
{
if( m_choicesFunc )
return m_choicesFunc( aObject );
return {};
}
PROPERTY_BASE& SetChoicesFunc( std::function<wxPGChoices(INSPECTABLE*)> aFunc )
{
m_choicesFunc = std::move( aFunc );
return *this;
}
virtual bool Writeable( INSPECTABLE* aObject ) const virtual bool Writeable( INSPECTABLE* aObject ) const
{ {
return m_writeableFunc( aObject ); return m_writeableFunc( aObject );
@ -434,6 +448,8 @@ private:
std::function<bool(INSPECTABLE*)> m_writeableFunc; ///< Eval to determine if prop is read-only std::function<bool(INSPECTABLE*)> m_writeableFunc; ///< Eval to determine if prop is read-only
std::function<wxPGChoices(INSPECTABLE*)> m_choicesFunc;
PROPERTY_VALIDATOR_FN m_validator; PROPERTY_VALIDATOR_FN m_validator;
friend class INSPECTABLE; friend class INSPECTABLE;

View File

@ -46,17 +46,6 @@ class COMMIT;
///< Unique type identifier ///< Unique type identifier
using TYPE_ID = size_t; using TYPE_ID = size_t;
using PROPERTY_LIST = std::vector<PROPERTY_BASE*>;
using PROPERTY_SET = std::set<std::pair<size_t, wxString>>;
template<typename ValueType>
using PROPERTY_MAP = std::map<std::pair<size_t, wxString>, ValueType>;
using PROPERTY_FUNCTOR_MAP = PROPERTY_MAP<std::function<bool( INSPECTABLE* )>>;
using PROPERTY_DISPLAY_ORDER = std::map<PROPERTY_BASE*, int>;
using PROPERTY_LISTENER = std::function<void( INSPECTABLE*, PROPERTY_BASE*, COMMIT* )>; using PROPERTY_LISTENER = std::function<void( INSPECTABLE*, PROPERTY_BASE*, COMMIT* )>;
class PROPERTY_COMMIT_HANDLER class PROPERTY_COMMIT_HANDLER
@ -100,14 +89,6 @@ public:
*/ */
void RegisterType( TYPE_ID aType, const wxString& aName ); void RegisterType( TYPE_ID aType, const wxString& aName );
/**
* Return name of a type.
*
* @param aType is the type identifier (obtained using TYPE_HASH()).
* @return Name of the type or empty string, if not available.
*/
const wxString& ResolveType( TYPE_ID aType ) const;
/** /**
* Return a property for a specific type. * Return a property for a specific type.
* *
@ -123,9 +104,9 @@ public:
* @param aType is the type identifier (obtained using TYPE_HASH()). * @param aType is the type identifier (obtained using TYPE_HASH()).
* @return Vector storing all properties of the requested type. * @return Vector storing all properties of the requested type.
*/ */
const PROPERTY_LIST& GetProperties( TYPE_ID aType ) const; const std::vector<PROPERTY_BASE*>& GetProperties( TYPE_ID aType ) const;
const PROPERTY_DISPLAY_ORDER& GetDisplayOrder( TYPE_ID aType ) const; const std::map<PROPERTY_BASE*, int>& GetDisplayOrder( TYPE_ID aType ) const;
const std::vector<wxString>& GetGroupDisplayOrder( TYPE_ID aType ) const; const std::vector<wxString>& GetGroupDisplayOrder( TYPE_ID aType ) const;
@ -258,8 +239,6 @@ public:
CLASSES_INFO GetAllClasses(); CLASSES_INFO GetAllClasses();
std::vector<TYPE_ID> GetMatchingClasses( PROPERTY_BASE* aProperty );
/** /**
* Callback to alert the notification system that a property has changed * Callback to alert the notification system that a property has changed
* @param aObject is the object whose property just changed * @param aObject is the object whose property just changed
@ -314,19 +293,19 @@ private:
std::map<TYPE_ID, std::unique_ptr<TYPE_CAST_BASE>> m_typeCasts; std::map<TYPE_ID, std::unique_ptr<TYPE_CAST_BASE>> m_typeCasts;
///< Properties from bases that should be masked (hidden) on this subclass ///< Properties from bases that should be masked (hidden) on this subclass
PROPERTY_SET m_maskedBaseProperties; std::set<std::pair<size_t, wxString>> m_maskedBaseProperties;
///< Overrides for base class property availabilities ///< Overrides for base class property availabilities
PROPERTY_FUNCTOR_MAP m_availabilityOverrides; std::map<std::pair<size_t, wxString>, std::function<bool( INSPECTABLE* )>> m_availabilityOverrides;
///< Overrides for base class property writeable status ///< Overrides for base class property writeable status
PROPERTY_FUNCTOR_MAP m_writeabilityOverrides; std::map<std::pair<size_t, wxString>, std::function<bool( INSPECTABLE* )>> m_writeabilityOverrides;
///< All properties (both unique to the type and inherited) ///< All properties (both unique to the type and inherited)
std::vector<PROPERTY_BASE*> m_allProperties; std::vector<PROPERTY_BASE*> m_allProperties;
///< Compiled display order for all properties ///< Compiled display order for all properties
PROPERTY_DISPLAY_ORDER m_displayOrder; std::map<PROPERTY_BASE*, int> m_displayOrder;
///< List of property groups provided by this class in display order ///< List of property groups provided by this class in display order
std::vector<wxString> m_groupDisplayOrder; std::vector<wxString> m_groupDisplayOrder;
@ -338,16 +317,17 @@ private:
std::set<wxString> m_groups; std::set<wxString> m_groups;
///< Replaced properties (TYPE_ID / name) ///< Replaced properties (TYPE_ID / name)
PROPERTY_SET m_replaced; std::set<std::pair<size_t, wxString>> m_replaced;
///< Recreates the list of properties ///< Recreates the list of properties
void rebuild(); void rebuild();
///< Traverses the class inheritance hierarchy bottom-to-top, gathering ///< Traverses the class inheritance hierarchy bottom-to-top, gathering
///< all properties available to a type ///< all properties available to a type
void collectPropsRecur( PROPERTY_LIST& aResult, PROPERTY_SET& aReplaced, void collectPropsRecur( std::vector<PROPERTY_BASE*>& aResult,
PROPERTY_DISPLAY_ORDER& aDisplayOrder, std::set<std::pair<size_t, wxString>>& aReplaced,
PROPERTY_SET& aMasked ) const; std::map<PROPERTY_BASE*, int>& aDisplayOrder,
std::set<std::pair<size_t, wxString>>& aMasked ) const;
}; };
///< Returns metadata for a specific type ///< Returns metadata for a specific type

View File

@ -538,7 +538,7 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
for( const PROPERTY_MANAGER::CLASS_INFO& cls : propMgr.GetAllClasses() ) for( const PROPERTY_MANAGER::CLASS_INFO& cls : propMgr.GetAllClasses() )
{ {
const PROPERTY_LIST& props = propMgr.GetProperties( cls.type ); const std::vector<PROPERTY_BASE*>& props = propMgr.GetProperties( cls.type );
for( PROPERTY_BASE* prop : props ) for( PROPERTY_BASE* prop : props )
{ {

View File

@ -66,6 +66,7 @@
#include <pcb_group.h> #include <pcb_group.h>
#include <gal/graphics_abstraction_layer.h> #include <gal/graphics_abstraction_layer.h>
#include <pin_type.h>
using KIGFX::PCB_PAINTER; using KIGFX::PCB_PAINTER;
using KIGFX::PCB_RENDER_SETTINGS; using KIGFX::PCB_RENDER_SETTINGS;
@ -2803,15 +2804,23 @@ static struct PAD_DESC
.SetIsHiddenFromLibraryEditors(); .SetIsHiddenFromLibraryEditors();
propMgr.AddProperty( new PROPERTY<PAD, wxString>( _HKI( "Pin Type" ), propMgr.AddProperty( new PROPERTY<PAD, wxString>( _HKI( "Pin Type" ),
&PAD::SetPinType, &PAD::GetPinType ), groupPad ) &PAD::SetPinType, &PAD::GetPinType ), groupPad )
.SetIsHiddenFromLibraryEditors(); .SetIsHiddenFromLibraryEditors()
.SetChoicesFunc( []( INSPECTABLE* aItem )
{
wxPGChoices choices;
for( int ii = 0; ii < ELECTRICAL_PINTYPES_TOTAL; ii++ )
choices.Add( GetCanonicalElectricalTypeName( (ELECTRICAL_PINTYPE) ii ) );
return choices;
} );
propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Size X" ), propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Size X" ),
&PAD::SetSizeX, &PAD::GetSizeX, PROPERTY_DISPLAY::PT_SIZE ), groupPad ) &PAD::SetSizeX, &PAD::GetSizeX, PROPERTY_DISPLAY::PT_SIZE ), groupPad )
.SetAvailableFunc( hasNormalPadstack ); .SetAvailableFunc( hasNormalPadstack );
propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Size Y" ), propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Size Y" ),
&PAD::SetSizeY, &PAD::GetSizeY, PROPERTY_DISPLAY::PT_SIZE ), groupPad ) &PAD::SetSizeY, &PAD::GetSizeY, PROPERTY_DISPLAY::PT_SIZE ), groupPad )
.SetAvailableFunc( .SetAvailableFunc( []( INSPECTABLE* aItem ) -> bool
[=]( INSPECTABLE* aItem ) -> bool
{ {
if( PAD* pad = dynamic_cast<PAD*>( aItem ) ) if( PAD* pad = dynamic_cast<PAD*>( aItem ) )
{ {
@ -2826,7 +2835,8 @@ static struct PAD_DESC
return true; return true;
} ); } );
const auto hasRoundRadius = [=]( INSPECTABLE* aItem ) -> bool const auto hasRoundRadius =
[]( INSPECTABLE* aItem ) -> bool
{ {
if( PAD* pad = dynamic_cast<PAD*>( aItem ) ) if( PAD* pad = dynamic_cast<PAD*>( aItem ) )
{ {
@ -2862,8 +2872,7 @@ static struct PAD_DESC
&PAD::SetDrillSizeY, &PAD::GetDrillSizeY, PROPERTY_DISPLAY::PT_SIZE ), groupPad ) &PAD::SetDrillSizeY, &PAD::GetDrillSizeY, PROPERTY_DISPLAY::PT_SIZE ), groupPad )
.SetWriteableFunc( padCanHaveHole ) .SetWriteableFunc( padCanHaveHole )
.SetValidator( PROPERTY_VALIDATORS::PositiveIntValidator ) .SetValidator( PROPERTY_VALIDATORS::PositiveIntValidator )
.SetAvailableFunc( .SetAvailableFunc( []( INSPECTABLE* aItem ) -> bool
[=]( INSPECTABLE* aItem ) -> bool
{ {
// Circle holes have no usable y-size // Circle holes have no usable y-size
if( PAD* pad = dynamic_cast<PAD*>( aItem ) ) if( PAD* pad = dynamic_cast<PAD*>( aItem ) )