ADDED: Local power symbol option

Local power symbols work like regular power symbols except that they are
scoped only the the sheet in which they are instantiated

Fixes https://gitlab.com/kicad/code/kicad/-/issues/2075
This commit is contained in:
Seth Hillbrand 2025-02-26 18:13:36 -08:00
parent 699fd2b3ac
commit 49a4699d5a
43 changed files with 739 additions and 148 deletions

View File

@ -42,6 +42,7 @@
#include <sch_sheet_pin.h>
#include <sch_text.h>
#include <schematic.h>
#include <symbol.h>
#include <connection_graph.h>
#include <project/project_file.h>
#include <project/net_settings.h>
@ -151,8 +152,17 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
SCH_PIN* pa = static_cast<SCH_PIN*>( a );
SCH_PIN* pb = static_cast<SCH_PIN*>( b );
bool aPower = pa->GetLibPin()->GetParentSymbol()->IsPower();
bool bPower = pb->GetLibPin()->GetParentSymbol()->IsPower();
bool aPower = pa->GetLibPin()->GetParentSymbol()->IsGlobalPower();
bool bPower = pb->GetLibPin()->GetParentSymbol()->IsGlobalPower();
if( aPower && !bPower )
return true;
else if( bPower && !aPower )
return false;
// Secondary check for local power pin
aPower = pa->GetLibPin()->GetParentSymbol()->IsLocalPower();
bPower = pb->GetLibPin()->GetParentSymbol()->IsLocalPower();
if( aPower && !bPower )
return true;
@ -217,7 +227,7 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
m_strong_driver = true;
// Power pins are 5, global labels are 6
m_local_driver = ( highest_priority < PRIORITY::POWER_PIN );
m_local_driver = ( highest_priority < PRIORITY::GLOBAL_POWER_PIN );
if( !candidates.empty() )
{
@ -422,6 +432,7 @@ const wxString& CONNECTION_SUBGRAPH::GetNameForDriver( SCH_ITEM* aItem ) const
if( aItem->HasCachedDriverName() )
return aItem->GetCachedDriverName();
std::lock_guard lock( m_driver_name_cache_mutex );
auto it = m_driver_name_cache.find( aItem );
if( it != m_driver_name_cache.end() )
@ -575,7 +586,9 @@ CONNECTION_SUBGRAPH::PRIORITY CONNECTION_SUBGRAPH::GetDriverPriority( SCH_ITEM*
const SCH_SYMBOL* sym = static_cast<SCH_SYMBOL*>( sch_pin->GetParentSymbol() );
if( sch_pin->IsGlobalPower() )
return PRIORITY::POWER_PIN;
return PRIORITY::GLOBAL_POWER_PIN;
else if( sch_pin->IsLocalPower() )
return PRIORITY::LOCAL_POWER_PIN;
else if( !sym || sym->GetExcludedFromBoard()
|| sym->GetLibSymbolRef()->GetReferenceField().GetText().StartsWith( '#' ) )
return PRIORITY::NONE;
@ -1569,8 +1582,21 @@ void CONNECTION_GRAPH::collectAllDriverValues()
case SCH_PIN_T:
{
SCH_PIN* pin = static_cast<SCH_PIN*>( driver );
wxASSERT( pin->IsGlobalPower() );
m_global_label_cache[name].push_back( subgraph );
if( pin->IsGlobalPower() )
{
m_global_label_cache[name].push_back( subgraph );
}
else if( pin->IsLocalPower() )
{
m_local_label_cache[std::make_pair( sheet, name )].push_back( subgraph );
}
else
{
UNITS_PROVIDER unitsProvider( schIUScale, EDA_UNITS::MILLIMETRES );
wxLogTrace( ConnTrace, wxS( "Unexpected normal pin %s" ),
driver->GetItemDescription( &unitsProvider, true ) );
}
break;
}
default:
@ -1662,7 +1688,7 @@ void CONNECTION_GRAPH::generateGlobalPowerPinSubGraphs()
SCH_PIN* pin = it.second;
if( !pin->ConnectedItems( sheet ).empty()
&& !pin->GetLibPin()->GetParentSymbol()->IsPower() )
&& !pin->GetLibPin()->GetParentSymbol()->IsGlobalPower() )
{
// ERC will warn about this: user has wired up an invisible pin
continue;
@ -1677,7 +1703,7 @@ void CONNECTION_GRAPH::generateGlobalPowerPinSubGraphs()
// Proper modern power symbols get their net name from the value field
// in the symbol, but we support legacy non-power symbols with global
// power connections based on invisible, power-in, pin's names.
if( pin->GetLibPin()->GetParentSymbol()->IsPower() )
if( pin->GetLibPin()->GetParentSymbol()->IsGlobalPower() )
connection->SetName( pin->GetParentSymbol()->GetValue( true, &sheet, false ) );
else
connection->SetName( pin->GetShownName() );
@ -2000,7 +2026,7 @@ void CONNECTION_GRAPH::processSubGraphs()
{
auto pin = static_cast<SCH_PIN*>( driver );
if( pin->IsGlobalPower()
if( pin->IsPower()
&& pin->GetDefaultNetName( sheet ) == test_name )
{
match = true;
@ -2183,7 +2209,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
continue;
bool secondary_is_global = CONNECTION_SUBGRAPH::GetDriverPriority( driver )
>= CONNECTION_SUBGRAPH::PRIORITY::POWER_PIN;
>= CONNECTION_SUBGRAPH::PRIORITY::GLOBAL_POWER_PIN;
for( CONNECTION_SUBGRAPH* candidate : global_subgraphs )
{
@ -2722,7 +2748,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
// Take whichever name is higher priority
if( CONNECTION_SUBGRAPH::GetDriverPriority( neighbor->m_driver )
>= CONNECTION_SUBGRAPH::PRIORITY::POWER_PIN )
>= CONNECTION_SUBGRAPH::PRIORITY::GLOBAL_POWER_PIN )
{
member->Clone( *neighbor_conn );
stale_bus_members.insert( member );
@ -2788,7 +2814,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
wxString bestName = aSubgraph->m_driver_connection->Name();
// Check if a subsheet has a higher-priority connection to the same net
if( highest < CONNECTION_SUBGRAPH::PRIORITY::POWER_PIN )
if( highest < CONNECTION_SUBGRAPH::PRIORITY::GLOBAL_POWER_PIN )
{
for( CONNECTION_SUBGRAPH* subgraph : visited )
{
@ -2810,7 +2836,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
// d) matches our priority, is a strong driver, and has a shorter path
// e) matches our strength and is at least as short, and is alphabetically lower
if( ( priority >= CONNECTION_SUBGRAPH::PRIORITY::POWER_PIN ) ||
if( ( priority >= CONNECTION_SUBGRAPH::PRIORITY::GLOBAL_POWER_PIN ) ||
( !bestIsStrong && candidateStrong ) ||
( priority > highest && candidateStrong ) ||
( priority == highest && candidateStrong && shorterPath ) ||
@ -2894,7 +2920,7 @@ std::shared_ptr<SCH_CONNECTION> CONNECTION_GRAPH::getDefaultConnection( SCH_ITEM
{
SCH_PIN* pin = static_cast<SCH_PIN*>( aItem );
if( pin->IsGlobalPower() )
if( pin->IsPower() )
c = std::make_shared<SCH_CONNECTION>( aItem, aSubgraph->m_sheet );
break;
@ -3264,7 +3290,7 @@ bool CONNECTION_GRAPH::ercCheckMultipleDrivers( const CONNECTION_SUBGRAPH* aSubg
|| driver->Type() == SCH_HIER_LABEL_T
|| driver->Type() == SCH_LABEL_T
|| ( driver->Type() == SCH_PIN_T
&& static_cast<SCH_PIN*>( driver )->IsGlobalPower() ) )
&& static_cast<SCH_PIN*>( driver )->IsPower() ) )
{
const wxString& primaryName = aSubgraph->GetNameForDriver( aSubgraph->m_driver );
const wxString& secondaryName = aSubgraph->GetNameForDriver( driver );
@ -3501,7 +3527,7 @@ bool CONNECTION_GRAPH::ercCheckBusToBusEntryConflicts( const CONNECTION_SUBGRAPH
// Don't report warnings if this bus member has been overridden by a higher priority power pin
// or global label
if( conflict && CONNECTION_SUBGRAPH::GetDriverPriority( aSubgraph->m_driver )
>= CONNECTION_SUBGRAPH::PRIORITY::POWER_PIN )
>= CONNECTION_SUBGRAPH::PRIORITY::GLOBAL_POWER_PIN )
{
conflict = false;
}
@ -3706,7 +3732,7 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph
// Or else we may fail walking connected components to a power symbol pin since we
// reject starting at a power symbol
if( test_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN
&& !test_pin->IsGlobalPower() )
&& !test_pin->IsPower() )
{
pin = test_pin;
break;
@ -3718,7 +3744,7 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph
// We want to throw unconnected errors for power symbols even if they are connected to other
// net items by name, because usually failing to connect them graphically is a mistake
if( pin && !has_other_connections
&& !pin->IsGlobalPower()
&& !pin->IsPower()
&& !pin->GetLibPin()->GetParentSymbol()->IsPower() )
{
wxString name = pin->Connection( &sheet )->Name();

View File

@ -70,7 +70,8 @@ public:
SHEET_PIN,
HIER_LABEL,
LOCAL_LABEL,
POWER_PIN,
LOCAL_POWER_PIN,
GLOBAL_POWER_PIN,
GLOBAL
};
@ -297,6 +298,7 @@ private:
std::unordered_set<CONNECTION_SUBGRAPH*> m_hier_children;
/// A cache of escaped netnames from schematic items.
mutable std::mutex m_driver_name_cache_mutex;
mutable std::unordered_map<SCH_ITEM*, wxString> m_driver_name_cache;
/// Fully-resolved driver for the subgraph (might not exist in this subgraph).

View File

@ -339,6 +339,24 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataToWindow()
}
}
// Add local power labels from power symbols
if( m_currentLabel->Type() == SCH_LABEL_T )
{
for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_LOCATE_POWER_T ) )
{
const SCH_SYMBOL* power = static_cast<const SCH_SYMBOL*>( item );
// Ensure the symbol has the Power (i.e. equivalent to a local label
// before adding its value in list
if( power->IsSymbolLikePowerLocalLabel() )
{
const SCH_FIELD* valueField = power->GetField( FIELD_T::VALUE );
existingLabels.insert( UnescapeString( valueField->GetText() ) );
}
}
}
// Add bus aliases from the current screen
auto& sheetAliases = screen->GetBusAliases();
busAliases.insert( busAliases.end(), sheetAliases.begin(), sheetAliases.end() );
}

View File

@ -235,9 +235,17 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataToWindow()
m_hasAlternateBodyStyles->SetValue( m_Parent->GetShowDeMorgan() );
m_OptionPower->SetValue( m_libEntry->IsPower() );
m_OptionLocalPower->SetValue( m_libEntry->IsLocalPower() );
if( m_libEntry->IsPower() )
{
m_spiceFieldsButton->Hide();
m_OptionLocalPower->Enable();
}
else
{
m_OptionLocalPower->Enable( false );
}
m_excludeFromSimCheckBox->SetValue( m_libEntry->GetExcludedFromSim() );
m_excludeFromBomCheckBox->SetValue( m_libEntry->GetExcludedFromBOM() );
@ -483,7 +491,11 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
if( m_OptionPower->GetValue() )
{
m_libEntry->SetPower();
if( m_OptionLocalPower->GetValue() )
m_libEntry->SetLocalPower();
else
m_libEntry->SetGlobalPower();
// Power symbols must have value matching name for now
m_libEntry->GetValueField().SetText( newName );
}
@ -979,6 +991,7 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::onPowerCheckBox( wxCommandEvent& aEvent )
m_excludeFromBoardCheckBox->Enable( false );
m_excludeFromSimCheckBox->Enable( false );
m_spiceFieldsButton->Show( false );
m_OptionLocalPower->Enable( true );
}
else
{
@ -986,6 +999,7 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::onPowerCheckBox( wxCommandEvent& aEvent )
m_excludeFromBoardCheckBox->Enable( true );
m_excludeFromSimCheckBox->Enable( true );
m_spiceFieldsButton->Show( true );
m_OptionLocalPower->Enable( false );
}
OnModify();

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -184,22 +184,30 @@ DIALOG_LIB_SYMBOL_PROPERTIES_BASE::DIALOG_LIB_SYMBOL_PROPERTIES_BASE( wxWindow*
sbSizerSymbol->Add( m_OptionPartsInterchangeable, 0, wxALL, 4 );
sbSizerSymbol->Add( 0, 8, 0, wxEXPAND, 5 );
m_hasAlternateBodyStyles = new wxCheckBox( sbSizerSymbol->GetStaticBox(), wxID_ANY, _("Has alternate body style (De Morgan)"), wxDefaultPosition, wxDefaultSize, 0 );
m_hasAlternateBodyStyles->SetToolTip( _("Check this option if the symbol has an alternate body style for a De Morgan logic equivalence.\nFor instance, this should be checked for a NAND gate to provide an alternate representation as an OR gate with inverted inputs.") );
sbSizerSymbol->Add( m_hasAlternateBodyStyles, 0, wxBOTTOM|wxRIGHT|wxLEFT, 4 );
sbSizerSymbol->Add( 0, 7, 0, wxEXPAND, 5 );
m_OptionPower = new wxCheckBox( sbSizerSymbol->GetStaticBox(), wxID_ANY, _("Define as power symbol"), wxDefaultPosition, wxDefaultSize, 0 );
m_OptionPower->SetToolTip( _("Setting this option makes the symbol in question appear in the\n\"add power symbol\" dialog. It will lock the value text to protect it\nfrom editing in the schematic. The symbol will not be included in\nthe BOM and cannot be assigned a footprint.") );
m_OptionPower->SetToolTip( _("Power symbols define a global net with the value as a netname.\nThey will not be included in the BOM and cannot be assigned a footprint.") );
sbSizerSymbol->Add( m_OptionPower, 0, wxBOTTOM|wxRIGHT|wxLEFT, 4 );
wxBoxSizer* bSizer16;
bSizer16 = new wxBoxSizer( wxHORIZONTAL );
bSizer16->Add( 0, 0, 0, wxEXPAND|wxLEFT|wxRIGHT, 10 );
m_OptionLocalPower = new wxCheckBox( sbSizerSymbol->GetStaticBox(), wxID_ANY, _("Define as local power symbol"), wxDefaultPosition, wxDefaultSize, 0 );
m_OptionLocalPower->SetToolTip( _("Local power symbols create labels that are limited to the sheet in which they are used") );
bSizer16->Add( m_OptionLocalPower, 0, wxBOTTOM|wxLEFT|wxRIGHT, 4 );
sbSizerSymbol->Add( bSizer16, 1, wxEXPAND, 5 );
bSizerLeftCol->Add( sbSizerSymbol, 0, wxEXPAND|wxALL, 5 );
@ -292,7 +300,7 @@ DIALOG_LIB_SYMBOL_PROPERTIES_BASE::DIALOG_LIB_SYMBOL_PROPERTIES_BASE( wxWindow*
m_PanelBasic->SetSizer( bSizerBasicPanel );
m_PanelBasic->Layout();
bSizerBasicPanel->Fit( m_PanelBasic );
m_NoteBook->AddPage( m_PanelBasic, _("General"), false );
m_NoteBook->AddPage( m_PanelBasic, _("General"), true );
m_PanelFootprintFilter = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bPanelFpFilterBoxSizer;
bPanelFpFilterBoxSizer = new wxBoxSizer( wxHORIZONTAL );
@ -340,7 +348,7 @@ DIALOG_LIB_SYMBOL_PROPERTIES_BASE::DIALOG_LIB_SYMBOL_PROPERTIES_BASE( wxWindow*
m_PanelFootprintFilter->SetSizer( bPanelFpFilterBoxSizer );
m_PanelFootprintFilter->Layout();
bPanelFpFilterBoxSizer->Fit( m_PanelFootprintFilter );
m_NoteBook->AddPage( m_PanelFootprintFilter, _("Footprint Filters"), true );
m_NoteBook->AddPage( m_PanelFootprintFilter, _("Footprint Filters"), false );
bUpperSizer->Add( m_NoteBook, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 );
@ -394,6 +402,7 @@ DIALOG_LIB_SYMBOL_PROPERTIES_BASE::DIALOG_LIB_SYMBOL_PROPERTIES_BASE( wxWindow*
m_OptionPartsInterchangeable->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::OnCheckBox ), NULL, this );
m_hasAlternateBodyStyles->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::OnCheckBox ), NULL, this );
m_OptionPower->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::onPowerCheckBox ), NULL, this );
m_OptionLocalPower->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::onPowerCheckBox ), NULL, this );
m_ShowPinNumButt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::OnCheckBox ), NULL, this );
m_ShowPinNameButt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::OnCheckBox ), NULL, this );
m_PinsNameInsideButt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::OnCheckBox ), NULL, this );
@ -429,6 +438,7 @@ DIALOG_LIB_SYMBOL_PROPERTIES_BASE::~DIALOG_LIB_SYMBOL_PROPERTIES_BASE()
m_OptionPartsInterchangeable->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::OnCheckBox ), NULL, this );
m_hasAlternateBodyStyles->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::OnCheckBox ), NULL, this );
m_OptionPower->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::onPowerCheckBox ), NULL, this );
m_OptionLocalPower->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::onPowerCheckBox ), NULL, this );
m_ShowPinNumButt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::OnCheckBox ), NULL, this );
m_ShowPinNameButt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::OnCheckBox ), NULL, this );
m_PinsNameInsideButt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES_BASE::OnCheckBox ), NULL, this );

View File

@ -136,7 +136,7 @@
<object class="notebookpage" expanded="true">
<property name="bitmap"></property>
<property name="label">General</property>
<property name="select">0</property>
<property name="select">1</property>
<object class="wxPanel" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
@ -1269,16 +1269,6 @@
<event name="OnCheckBox">OnCheckBox</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="spacer" expanded="true">
<property name="height">8</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">4</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
@ -1345,16 +1335,6 @@
<event name="OnCheckBox">OnCheckBox</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="spacer" expanded="true">
<property name="height">7</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">4</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
@ -1410,7 +1390,7 @@
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Setting this option makes the symbol in question appear in the&#x0A;&quot;add power symbol&quot; dialog. It will lock the value text to protect it&#x0A;from editing in the schematic. The symbol will not be included in&#x0A;the BOM and cannot be assigned a footprint.</property>
<property name="tooltip">Power symbols define a global net with the value as a netname.&#x0A;They will not be included in the BOM and cannot be assigned a footprint.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
@ -1421,6 +1401,93 @@
<event name="OnCheckBox">onPowerCheckBox</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizer16</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">10</property>
<property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
<property name="proportion">0</property>
<object class="spacer" expanded="true">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">4</property>
<property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Define as local power symbol</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_OptionLocalPower</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Local power symbols create labels that are limited to the sheet in which they are used</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnCheckBox">onPowerCheckBox</event>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
@ -2110,7 +2177,7 @@
<object class="notebookpage" expanded="true">
<property name="bitmap"></property>
<property name="label">Footprint Filters</property>
<property name="select">1</property>
<property name="select">0</property>
<object class="wxPanel" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -68,6 +68,7 @@ class DIALOG_LIB_SYMBOL_PROPERTIES_BASE : public DIALOG_SHIM
wxCheckBox* m_OptionPartsInterchangeable;
wxCheckBox* m_hasAlternateBodyStyles;
wxCheckBox* m_OptionPower;
wxCheckBox* m_OptionLocalPower;
wxCheckBox* m_ShowPinNumButt;
wxCheckBox* m_ShowPinNameButt;
wxCheckBox* m_PinsNameInsideButt;

View File

@ -88,6 +88,8 @@ void PANEL_EESCHEMA_EDITING_OPTIONS::loadEEschemaSettings( EESCHEMA_SETTINGS* aC
m_cbAutoStartWires->SetValue( aCfg->m_Drawing.auto_start_wires );
m_escClearsNetHighlight->SetValue( aCfg->m_Input.esc_clears_net_highlight );
m_choicePower->SetSelection( static_cast<int>( aCfg->m_Drawing.new_power_symbols ) );
}
@ -107,6 +109,8 @@ bool PANEL_EESCHEMA_EDITING_OPTIONS::TransferDataFromWindow()
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
EESCHEMA_SETTINGS* cfg = mgr.GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
cfg->m_Drawing.new_power_symbols = static_cast<POWER_SYMBOLS>( m_choicePower->GetSelection() );
cfg->m_Drawing.default_sheet_border_color = m_borderColorSwatch->GetSwatchColor();
cfg->m_Drawing.default_sheet_background_color = m_backgroundColorSwatch->GetSwatchColor();

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -71,26 +71,54 @@ PANEL_EESCHEMA_EDITING_OPTIONS_BASE::PANEL_EESCHEMA_EDITING_OPTIONS_BASE( wxWind
m_staticline4 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bLeftColumn->Add( m_staticline4, 0, wxEXPAND|wxBOTTOM, 5 );
wxBoxSizer* bSizer6;
bSizer6 = new wxBoxSizer( wxHORIZONTAL );
wxGridBagSizer* gbSizer1;
gbSizer1 = new wxGridBagSizer( 0, 0 );
gbSizer1->SetFlexibleDirection( wxBOTH );
gbSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_borderColorLabel = new wxStaticText( this, wxID_ANY, _("Sheet border:"), wxDefaultPosition, wxDefaultSize, 0 );
m_borderColorLabel->Wrap( -1 );
bSizer6->Add( m_borderColorLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
gbSizer1->Add( m_borderColorLabel, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALL, 5 );
m_borderColorSwatch = new COLOR_SWATCH( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_borderColorSwatch->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
bSizer6->Add( m_borderColorSwatch, 1, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
gbSizer1->Add( m_borderColorSwatch, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
m_backgroundColorLabel = new wxStaticText( this, wxID_ANY, _("Sheet background:"), wxDefaultPosition, wxDefaultSize, 0 );
m_backgroundColorLabel->Wrap( -1 );
bSizer6->Add( m_backgroundColorLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
gbSizer1->Add( m_backgroundColorLabel, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALL, 5 );
m_backgroundColorSwatch = new COLOR_SWATCH( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_backgroundColorSwatch->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
bSizer6->Add( m_backgroundColorSwatch, 1, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
gbSizer1->Add( m_backgroundColorSwatch, wxGBPosition( 0, 3 ), wxGBSpan( 1, 1 ), wxALL, 5 );
m_powerSymbolLabel = new wxStaticText( this, wxID_ANY, _("Power Symbols:"), wxDefaultPosition, wxDefaultSize, 0 );
m_powerSymbolLabel->Wrap( -1 );
gbSizer1->Add( m_powerSymbolLabel, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
wxString m_choicePowerChoices[] = { _("Default"), _("Global"), _("Local") };
int m_choicePowerNChoices = sizeof( m_choicePowerChoices ) / sizeof( wxString );
m_choicePower = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choicePowerNChoices, m_choicePowerChoices, 0 );
m_choicePower->SetSelection( 0 );
m_choicePower->SetToolTip( _("Select the assigned type of new power symbol.\nDefault will follow the symbol definition.\nGlobal will convert new power symbols to global power symbols.\nLocal will convert new power symbols to a local power symbols.") );
gbSizer1->Add( m_choicePower, wxGBPosition( 1, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
bLeftColumn->Add( gbSizer1, 0, wxEXPAND|wxLEFT|wxTOP, 10 );
wxFlexGridSizer* fgSizer4;
fgSizer4 = new wxFlexGridSizer( 2, 4, 0, 0 );
fgSizer4->SetFlexibleDirection( wxBOTH );
fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
bLeftColumn->Add( fgSizer4, 1, wxEXPAND, 5 );
wxBoxSizer* bSizer6;
bSizer6 = new wxBoxSizer( wxHORIZONTAL );
bLeftColumn->Add( bSizer6, 0, wxEXPAND|wxTOP|wxLEFT, 10 );

View File

@ -667,17 +667,26 @@
</object>
<object class="sizeritem" expanded="true">
<property name="border">10</property>
<property name="flag">wxEXPAND|wxTOP|wxLEFT</property>
<property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<object class="wxGridBagSizer" expanded="true">
<property name="empty_cell_size"></property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols"></property>
<property name="growablerows"></property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">bSizer6</property>
<property name="orient">wxHORIZONTAL</property>
<property name="name">gbSizer1</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="vgap">0</property>
<object class="gbsizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT</property>
<property name="proportion">0</property>
<property name="colspan">1</property>
<property name="column">0</property>
<property name="flag">wxALL</property>
<property name="row">0</property>
<property name="rowspan">1</property>
<object class="wxStaticText" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
@ -736,10 +745,13 @@
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="true">
<object class="gbsizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">1</property>
<property name="colspan">1</property>
<property name="column">1</property>
<property name="flag">wxALL</property>
<property name="row">0</property>
<property name="rowspan">1</property>
<object class="CustomControl" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
@ -799,10 +811,13 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="true">
<object class="gbsizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<property name="colspan">1</property>
<property name="column">2</property>
<property name="flag">wxALL</property>
<property name="row">0</property>
<property name="rowspan">1</property>
<object class="wxStaticText" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
@ -861,10 +876,13 @@
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="true">
<object class="gbsizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">1</property>
<property name="colspan">1</property>
<property name="column">3</property>
<property name="flag">wxALL</property>
<property name="row">0</property>
<property name="rowspan">1</property>
<object class="CustomControl" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
@ -924,6 +942,168 @@
<property name="window_style"></property>
</object>
</object>
<object class="gbsizeritem" expanded="true">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">0</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="row">1</property>
<property name="rowspan">1</property>
<object class="wxStaticText" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Power Symbols:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_powerSymbolLabel</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="gbsizeritem" expanded="true">
<property name="border">5</property>
<property name="colspan">2</property>
<property name="column">1</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property>
<property name="row">1</property>
<property name="rowspan">1</property>
<object class="wxChoice" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices">&quot;Default&quot; &quot;Global&quot; &quot;Local&quot;</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_choicePower</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">0</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Select the assigned type of new power symbol.&#x0A;Default will follow the symbol definition.&#x0A;Global will convert new power symbols to global power symbols.&#x0A;Local will convert new power symbols to a local power symbols.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxFlexGridSizer" expanded="true">
<property name="cols">4</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols"></property>
<property name="growablerows"></property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">fgSizer4</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property>
<property name="rows">2</property>
<property name="vgap">0</property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">10</property>
<property name="flag">wxEXPAND|wxTOP|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizer6</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
</object>
</object>
<object class="sizeritem" expanded="true">

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -22,6 +22,7 @@
#include <wx/choice.h>
#include <wx/sizer.h>
#include <wx/checkbox.h>
#include <wx/gbsizer.h>
#include <wx/panel.h>
#include <wx/simplebook.h>
#include <wx/textctrl.h>
@ -50,6 +51,8 @@ class PANEL_EESCHEMA_EDITING_OPTIONS_BASE : public RESETTABLE_PANEL
COLOR_SWATCH* m_borderColorSwatch;
wxStaticText* m_backgroundColorLabel;
COLOR_SWATCH* m_backgroundColorSwatch;
wxStaticText* m_powerSymbolLabel;
wxChoice* m_choicePower;
wxSimplebook* m_leftClickCmdsBook;
wxPanel* m_pageWinLin;
wxStaticText* m_leftClickLabel;

View File

@ -371,6 +371,10 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
m_params.emplace_back( new PARAM<COLOR4D>( "drawing.default_sheet_background_color",
&m_Drawing.default_sheet_background_color, COLOR4D::UNSPECIFIED ) );
m_params.emplace_back( new PARAM_ENUM<POWER_SYMBOLS>(
"drawing.new_power_symbols", &m_Drawing.new_power_symbols, POWER_SYMBOLS::DEFAULT,
POWER_SYMBOLS::DEFAULT, POWER_SYMBOLS::LOCAL ) );
m_params.emplace_back( new PARAM_LIST<double>( "drawing.junction_size_mult_list",
&m_Drawing.junction_size_mult_list, { 0.0, 1.7, 4.0, 6.0, 9.0, 12.0 } ) );

View File

@ -49,6 +49,13 @@ enum LINE_MODE
};
enum class POWER_SYMBOLS
{
DEFAULT = 0,
GLOBAL,
LOCAL
};
class EESCHEMA_SETTINGS : public APP_SETTINGS_BASE
{
public:
@ -147,26 +154,27 @@ public:
struct DRAWING
{
int default_bus_thickness;
int default_junction_size;
int default_line_thickness;
int default_repeat_offset_x;
int default_repeat_offset_y;
int default_wire_thickness;
int default_text_size;
int pin_symbol_size;
double text_offset_ratio;
COLOR4D default_sheet_border_color;
COLOR4D default_sheet_background_color;
wxString field_names;
int line_mode;
int repeat_label_increment;
bool intersheets_ref_show;
bool intersheets_ref_own_page;
bool intersheets_ref_short;
wxString intersheets_ref_prefix;
wxString intersheets_ref_suffix;
bool auto_start_wires;
int default_bus_thickness;
int default_junction_size;
int default_line_thickness;
int default_repeat_offset_x;
int default_repeat_offset_y;
int default_wire_thickness;
int default_text_size;
int pin_symbol_size;
double text_offset_ratio;
COLOR4D default_sheet_border_color;
COLOR4D default_sheet_background_color;
POWER_SYMBOLS new_power_symbols;
wxString field_names;
int line_mode;
int repeat_label_increment;
bool intersheets_ref_show;
bool intersheets_ref_own_page;
bool intersheets_ref_short;
wxString intersheets_ref_prefix;
wxString intersheets_ref_suffix;
bool auto_start_wires;
std::vector<double> junction_size_mult_list;
// Pulldown index for user default junction dot size (e.g. smallest = 0, small = 1, etc)

View File

@ -1333,7 +1333,7 @@ int ERC_TESTER::TestSimilarLabels()
{
SCH_PIN* pin = static_cast<SCH_PIN*>( item );
if( !pin->IsGlobalPower() )
if( !pin->IsPower() )
{
continue;
}

View File

@ -411,33 +411,69 @@ const wxString LIB_SYMBOL::GetLibraryName() const
}
bool LIB_SYMBOL::IsPower() const
bool LIB_SYMBOL::IsLocalPower() const
{
std::shared_ptr<LIB_SYMBOL> parent;
if( !m_parent.expired() && ( parent = m_parent.lock() ) )
{
if( parent->IsRoot() )
return parent->m_options == ENTRY_POWER;
return parent->m_options == ENTRY_LOCAL_POWER;
else
return parent->IsPower();
return parent->IsLocalPower();
}
return m_options == ENTRY_POWER;
return m_options == ENTRY_LOCAL_POWER;
}
void LIB_SYMBOL::SetPower()
void LIB_SYMBOL::SetLocalPower()
{
if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
{
if( parent->IsRoot() )
parent->m_options = ENTRY_POWER;
parent->m_options = ENTRY_LOCAL_POWER;
else
parent->SetPower();
parent->SetLocalPower();
}
m_options = ENTRY_POWER;
m_options = ENTRY_LOCAL_POWER;
}
bool LIB_SYMBOL::IsGlobalPower() const
{
std::shared_ptr<LIB_SYMBOL> parent;
if( !m_parent.expired() && ( parent = m_parent.lock() ) )
{
if( parent->IsRoot() )
return parent->m_options == ENTRY_GLOBAL_POWER;
else
return parent->IsGlobalPower();
}
return m_options == ENTRY_GLOBAL_POWER;
}
bool LIB_SYMBOL::IsPower() const
{
return IsLocalPower() || IsGlobalPower();
}
void LIB_SYMBOL::SetGlobalPower()
{
if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
{
if( parent->IsRoot() )
parent->m_options = ENTRY_GLOBAL_POWER;
else
parent->SetGlobalPower();
}
m_options = ENTRY_GLOBAL_POWER;
}

View File

@ -58,8 +58,9 @@ typedef LIB_ITEMS_CONTAINER::ITEM_PTR_VECTOR LIB_ITEMS;
/* values for member .m_options */
enum LIBRENTRYOPTIONS
{
ENTRY_NORMAL, // Libentry is a standard symbol (real or alias)
ENTRY_POWER // Libentry is a power symbol
ENTRY_NORMAL, // Libentry is a standard symbol (real or alias)
ENTRY_GLOBAL_POWER, // Libentry is a power symbol
ENTRY_LOCAL_POWER // Libentry is a local power symbol
};
@ -266,10 +267,13 @@ public:
return GetBodyBoundingBox( m_previewUnit, m_previewBodyStyle, true, false );
}
bool IsGlobalPower() const override;
bool IsLocalPower() const override;
bool IsPower() const override;
bool IsNormal() const override;
void SetPower();
void SetGlobalPower();
void SetLocalPower();
void SetNormal();
/**

View File

@ -336,7 +336,7 @@ bool SCH_CONNECTION::IsDriver() const
if( const SCH_SYMBOL* symbol = dynamic_cast<const SCH_SYMBOL*>( pin->GetParentSymbol() ) )
{
// Only annotated symbols should drive nets.
return pin->IsGlobalPower() || symbol->IsAnnotated( &m_sheet );
return pin->IsPower() || symbol->IsAnnotated( &m_sheet );
}
return true;
@ -399,12 +399,17 @@ void SCH_CONNECTION::recacheName()
switch( m_driver->Type() )
{
case SCH_GLOBAL_LABEL_T:
case SCH_PIN_T:
// Pins are either power connections or belong to a uniquely-annotated
// symbol, so they don't need a path if they are driving the subgraph.
prepend_path = false;
break;
case SCH_PIN_T:
{ // Normal pins and global power pins do not need a path. But local power pins do
SCH_PIN* pin = static_cast<SCH_PIN*>( m_driver );
prepend_path = pin->IsLocalPower();
break;
}
default:
break;
}

View File

@ -115,4 +115,5 @@
//#define SEXPR_SCHEMATIC_FILE_VERSION 20241004 // Use booleans for 'hide' in symbols
//#define SEXPR_SCHEMATIC_FILE_VERSION 20241209 // Private flags for SCH_FIELDs
//#define SEXPR_SCHEMATIC_FILE_VERSION 20250114 // Full paths for text variable cross references
#define SEXPR_SCHEMATIC_FILE_VERSION 20250222 // Hatched fills for shapes
//#define SEXPR_SCHEMATIC_FILE_VERSION 20250222 // Hatched fills for shapes
#define SEXPR_SCHEMATIC_FILE_VERSION 20250227 // Support for local power symbols

View File

@ -3673,7 +3673,7 @@ void SCH_IO_ALTIUM::ParsePowerPort( const std::map<wxString, wxString>& aPropert
else
{
libSymbol = new LIB_SYMBOL( wxEmptyString );
libSymbol->SetPower();
libSymbol->SetGlobalPower();
libSymbol->SetName( elem.text );
libSymbol->GetReferenceField().SetText( "#PWR" );
libSymbol->GetReferenceField().SetVisible( false );

View File

@ -893,7 +893,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadSchematicSymbolInstances()
wxCHECK( templatePart, /*void*/ );
kiPart = new LIB_SYMBOL( *templatePart );
kiPart->SetPower();
kiPart->SetGlobalPower();
kiPart->SetName( libPartName );
kiPart->GetValueField().SetText( symbolInstanceNetName );
kiPart->SetShowPinNames( false );

View File

@ -1999,7 +1999,7 @@ void SCH_IO_EAGLE::loadInstance( const std::unique_ptr<EINSTANCE>& aInstance,
for( const SCH_PIN* pin : symbol->GetLibPins() )
m_connPoints[symbol->GetPinPhysicalPosition( pin )].emplace( pin );
if( part->IsPower() )
if( part->IsGlobalPower() )
m_powerPorts[ reference ] = symbol->GetField( FIELD_T::VALUE )->GetText();
symbol->ClearFlags();
@ -2082,7 +2082,7 @@ EAGLE_LIBRARY* SCH_IO_EAGLE::loadLibrary( const ELIBRARY* aLibrary, EAGLE_LIBRAR
libSymbol->SetUnitCount( gate_count );
if( gate_count == 1 && ispower )
libSymbol->SetPower();
libSymbol->SetGlobalPower();
// Don't set the footprint field if no package is defined in the Eagle schematic.
if( edevice->package )
@ -3346,7 +3346,7 @@ void SCH_IO_EAGLE::addImplicitConnections( SCH_SYMBOL* aSymbol, SCH_SCREEN* aScr
// Normally power parts also have power input pins,
// but they already force net names on the attached wires
if( aSymbol->GetLibSymbolRef()->IsPower() )
if( aSymbol->GetLibSymbolRef()->IsGlobalPower() )
return;
int unit = aSymbol->GetUnit();

View File

@ -990,7 +990,7 @@ std::pair<LIB_SYMBOL*, bool> SCH_EASYEDA_PARSER::MakePowerSymbol( const wxString
LIB_ID libId = EasyEdaToKiCadLibID( wxEmptyString, aNetname );
ksymbol->SetPower();
ksymbol->SetGlobalPower();
ksymbol->SetLibId( libId );
ksymbol->SetName( aNetname );
ksymbol->GetReferenceField().SetText( wxS( "#PWR" ) );

View File

@ -678,7 +678,7 @@ SCH_EASYEDAPRO_PARSER::ParseSymbol( const std::vector<nlohmann::json>& aLines,
if( symInfo.head.symbolType == EASYEDAPRO::SYMBOL_TYPE::POWER_PORT
|| symInfo.head.symbolType == EASYEDAPRO::SYMBOL_TYPE::NETPORT )
{
ksymbol->SetPower();
ksymbol->SetGlobalPower();
ksymbol->GetReferenceField().SetText( wxS( "#PWR" ) );
ksymbol->GetReferenceField().SetVisible( false );
ksymbol->SetKeyWords( wxS( "power-flag" ) );

View File

@ -2135,7 +2135,7 @@ void SCH_IO_KICAD_LEGACY::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
for( LIB_SYMBOL_MAP::const_iterator it = symbols.begin(); it != symbols.end(); ++it )
{
if( !powerSymbolsOnly || it->second->IsPower() )
if( !powerSymbolsOnly || it->second->IsGlobalPower() )
aSymbolNameList.Add( it->first );
}
}
@ -2156,7 +2156,7 @@ void SCH_IO_KICAD_LEGACY::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolL
for( LIB_SYMBOL_MAP::const_iterator it = symbols.begin(); it != symbols.end(); ++it )
{
if( !powerSymbolsOnly || it->second->IsPower() )
if( !powerSymbolsOnly || it->second->IsGlobalPower() )
aSymbolList.push_back( it->second );
}
}

View File

@ -447,7 +447,7 @@ LIB_SYMBOL* SCH_IO_KICAD_LEGACY_LIB_CACHE::LoadPart( LINE_READER& aReader, int a
tmp = tokens.GetNextToken();
if( tmp == "P" )
symbol->SetPower();
symbol->SetGlobalPower();
else if( tmp == "N" )
symbol->SetNormal();
else
@ -1520,7 +1520,7 @@ void SCH_IO_KICAD_LEGACY_LIB_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMA
aSymbol->GetShowPinNumbers() ? 'Y' : 'N',
aSymbol->GetShowPinNames() ? 'Y' : 'N',
aSymbol->GetUnitCount(), aSymbol->UnitsLocked() ? 'L' : 'F',
aSymbol->IsPower() ? 'P' : 'N' );
aSymbol->IsGlobalPower() ? 'P' : 'N' );
timestamp_t dateModified = aSymbol->GetLastModDate();

View File

@ -168,8 +168,10 @@ void SCH_IO_KICAD_SEXPR_LIB_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMAT
{
aFormatter.Print( "(symbol %s", name.c_str() );
if( aSymbol->IsPower() )
aFormatter.Print( "(power)" );
if( aSymbol->IsGlobalPower() )
aFormatter.Print( "(power global)" );
else if( aSymbol->IsLocalPower() )
aFormatter.Print( "(power local)" );
// TODO: add uuid token here.

View File

@ -357,7 +357,17 @@ LIB_SYMBOL* SCH_IO_KICAD_SEXPR_PARSER::parseLibSymbol( LIB_SYMBOL_MAP& aSymbolLi
switch( token )
{
case T_power:
symbol->SetPower();
symbol->SetGlobalPower();
token = NextTok();
if( token == T_RIGHT )
break;
if( token == T_local )
symbol->SetLocalPower();
else if( token != T_global )
Expecting( "global or local" );
NeedRIGHT();
break;

View File

@ -825,7 +825,7 @@ SCH_SYMBOL* SCH_IO_LTSPICE_PARSER::CreatePowerSymbol( const VECTOR2I& aOffset,
LINE_STYLE::SOLID ) );
lib_symbol->AddDrawItem( shape );
lib_symbol->SetPower();
lib_symbol->SetGlobalPower();
SCH_PIN* pin = new SCH_PIN( lib_symbol );

View File

@ -775,6 +775,51 @@ void SCH_PAINTER::drawPinDanglingIndicator( const SCH_PIN& aPin, const COLOR4D&
}
/**
* Draw an local power pin indicator icon.
*/
static void drawLocalPowerIcon( GAL& aGal, const VECTOR2D& aPos, double aSize, bool aRotate,
const COLOR4D& aColor )
{
aGal.Save();
aGal.Translate( aPos );
if( aRotate )
{
aGal.Rotate( ANGLE_270.AsRadians() );
}
aGal.SetIsFill( false );
aGal.SetIsStroke( true );
aGal.SetLineWidth( KiROUND( aSize / 10.0 ) );
aGal.SetStrokeColor( aColor );
double x_right = aSize / 1.6180339887;
double x_middle = x_right / 2.0;
VECTOR2D bottomPt = VECTOR2D{ x_middle, 0 };
VECTOR2D leftPt = VECTOR2D{ 0, 2.0 * -aSize / 3.0 };
VECTOR2D rightPt = VECTOR2D{ x_right, 2.0 * -aSize / 3.0 };
VECTOR2D bottomAnchorPt = VECTOR2D{ x_middle, -aSize / 4.0 };
VECTOR2D leftSideAnchorPt1 = VECTOR2D{ 0, -aSize / 2.5 };
VECTOR2D leftSideAnchorPt2 = VECTOR2D{ 0, -aSize * 1.15 };
VECTOR2D rightSideAnchorPt1 = VECTOR2D{ x_right, -aSize / 2.5 };
VECTOR2D rightSideAnchorPt2 = VECTOR2D{ x_right, -aSize * 1.15 };
aGal.DrawCurve( bottomPt, bottomAnchorPt, leftSideAnchorPt1, leftPt );
aGal.DrawCurve( leftPt, leftSideAnchorPt2, rightSideAnchorPt2, rightPt );
aGal.DrawCurve( rightPt, rightSideAnchorPt1, bottomAnchorPt, bottomPt );
aGal.SetIsFill( true );
aGal.SetFillColor( aColor );
aGal.DrawCircle( ( leftPt + rightPt ) / 2.0, aSize / 15.0 );
aGal.Restore();
};
/**
* Draw an alternate pin mode indicator icon.
*/
@ -2488,6 +2533,30 @@ void SCH_PAINTER::draw( const SCH_FIELD* aField, int aLayer, bool aDimmed )
const_cast<SCH_FIELD*>( aField )->ClearFlags( IS_SHOWN_AS_BITMAP );
}
if( aField->GetParent() && aField->GetParent()->Type() == SCH_SYMBOL_T )
{
SCH_SYMBOL* parent = static_cast<SCH_SYMBOL*>( aField->GetParent() );
bool rotated = !orient.IsHorizontal() && !aField->CanAutoplace();
VECTOR2D pos;
double size = bbox.GetHeight() / 1.5;
if( rotated )
{
pos = VECTOR2D( bbox.GetRight() - bbox.GetWidth() / 6.0,
bbox.GetBottom() + bbox.GetWidth() / 2.0 );
size = bbox.GetWidth() / 1.5;
}
else
{
pos = VECTOR2D( bbox.GetLeft() - bbox.GetHeight() / 2.0,
bbox.GetBottom() - bbox.GetHeight() / 6.0 );
}
if( parent->IsSymbolLikePowerLocalLabel() )
drawLocalPowerIcon( *m_gal, pos, size, rotated, m_gal->GetStrokeColor() );
}
}
// Draw anchor or umbilical line

View File

@ -363,7 +363,20 @@ wxString SCH_PIN::GetElectricalTypeName() const
bool SCH_PIN::IsGlobalPower() const
{
return GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN
&& ( !IsVisible() || GetParentSymbol()->IsPower() );
&& ( !IsVisible() || GetParentSymbol()->IsGlobalPower() );
}
bool SCH_PIN::IsLocalPower() const
{
return GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN
&& GetParentSymbol()->IsLocalPower();
}
bool SCH_PIN::IsPower() const
{
return IsLocalPower() || IsGlobalPower();
}
@ -1220,9 +1233,11 @@ wxString SCH_PIN::GetDefaultNetName( const SCH_SHEET_PATH& aPath, bool aForceNoC
// Need to check for parent as power symbol to make sure we aren't dealing
// with legacy global power pins on non-power symbols
if( IsGlobalPower() )
if( IsGlobalPower() || IsLocalPower() )
{
if( GetLibPin()->GetParentSymbol()->IsPower() )
SYMBOL* parent = GetLibPin()->GetParentSymbol();
if( parent->IsGlobalPower() || parent->IsLocalPower() )
{
return EscapeString( symbol->GetValue( true, &aPath, false ), CTX_NETNAME );
}

View File

@ -193,6 +193,18 @@ public:
*/
bool IsGlobalPower() const;
/**
* Local power pin is the same except that it is sheet-local and it does not support the legacy
* hidden pin mode
*/
bool IsLocalPower() const;
/**
* Check if the pin is _either_ a global or local power pin.
* @see IsGlobalPower() and IsLocalPower()
*/
bool IsPower() const;
int GetPenWidth() const override { return 0; }
void Move( const VECTOR2I& aOffset ) override;

View File

@ -1424,7 +1424,7 @@ void SCH_SCREEN::FixLegacyPowerSymbolMismatches()
// Fix pre-8.0 legacy power symbols with invisible pins
// that have mismatched pin names and value fields
if( symbol->GetLibSymbolRef()
&& symbol->GetLibSymbolRef()->IsPower()
&& symbol->GetLibSymbolRef()->IsGlobalPower()
&& symbol->GetAllLibPins().size() > 0
&& symbol->GetAllLibPins()[0]->IsGlobalPower()
&& !symbol->GetAllLibPins()[0]->IsVisible() )

View File

@ -2277,8 +2277,7 @@ INSPECT_RESULT SCH_SYMBOL::Visit( INSPECTOR aInspector, void* aTestData,
{
for( KICAD_T scanType : aScanTypes )
{
if( scanType == SCH_LOCATE_ANY_T
|| ( scanType == SCH_SYMBOL_T )
if( scanType == SCH_LOCATE_ANY_T || ( scanType == SCH_SYMBOL_T )
|| ( scanType == SCH_SYMBOL_LOCATE_POWER_T && m_part && m_part->IsPower() ) )
{
if( INSPECT_RESULT::QUIT == aInspector( this, aTestData ) )
@ -2726,7 +2725,7 @@ bool SCH_SYMBOL::IsSymbolLikePowerGlobalLabel() const
// It is a Power symbol
// It has only one pin type Power input
if( !GetLibSymbolRef() || !GetLibSymbolRef()->IsPower() )
if( !GetLibSymbolRef() || !GetLibSymbolRef()->IsGlobalPower() )
return false;
std::vector<SCH_PIN*> pin_list = GetAllLibPins();
@ -2738,12 +2737,45 @@ bool SCH_SYMBOL::IsSymbolLikePowerGlobalLabel() const
}
bool SCH_SYMBOL::IsPower() const
bool SCH_SYMBOL::IsSymbolLikePowerLocalLabel() const
{
// return true if the symbol is equivalent to a local label:
// It is a Power symbol
// It has only one pin type Power input
if( !GetLibSymbolRef() || !GetLibSymbolRef()->IsLocalPower() )
return false;
std::vector<SCH_PIN*> pin_list = GetAllLibPins();
if( pin_list.size() != 1 )
return false;
return pin_list[0]->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN;
}
bool SCH_SYMBOL::IsLocalPower() const
{
if( !m_part )
return false;
return m_part->IsPower();
return m_part->IsLocalPower();
}
bool SCH_SYMBOL::IsGlobalPower() const
{
if( !m_part )
return false;
return m_part->IsGlobalPower();
}
bool SCH_SYMBOL::IsPower() const
{
return IsLocalPower() || IsGlobalPower();
}

View File

@ -822,7 +822,10 @@ public:
* It has only one pin type Power input
*/
bool IsSymbolLikePowerGlobalLabel() const;
bool IsSymbolLikePowerLocalLabel() const;
bool IsGlobalPower() const override;
bool IsLocalPower() const override;
bool IsPower() const override;
bool IsNormal() const override;

View File

@ -55,6 +55,7 @@ footprint
free
generator
generator_version
global
global_label
hatch
header
@ -86,6 +87,7 @@ lib_name
lib_symbols
line
line_spacing
local
margins
members
mid

View File

@ -110,6 +110,8 @@ public:
virtual wxString GetDescription() const = 0;
virtual wxString GetKeyWords() const = 0;
virtual bool IsGlobalPower() const = 0;
virtual bool IsLocalPower() const = 0;
virtual bool IsPower() const = 0;
virtual bool IsNormal() const = 0;

View File

@ -249,7 +249,7 @@ void CheckLibSymbol( LIB_SYMBOL* aSymbol, std::vector<wxString>& aMessages,
else
pinName = "'" + pinName + "'";
if( !aSymbol->IsPower()
if( !aSymbol->IsGlobalPower()
&& pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN
&& !pin->IsVisible() )
{

View File

@ -420,7 +420,7 @@ void SYMBOL_EDIT_FRAME::CreateNewSymbol( const wxString& aInheritFrom )
new_symbol.SetPinNameOffset( 0 );
}
( dlg.GetPowerSymbol() ) ? new_symbol.SetPower() : new_symbol.SetNormal();
( dlg.GetPowerSymbol() ) ? new_symbol.SetGlobalPower() : new_symbol.SetNormal();
new_symbol.SetShowPinNumbers( dlg.GetShowPinNumber() );
new_symbol.SetShowPinNames( dlg.GetShowPinName() );
new_symbol.LockUnits( !dlg.GetUnitsInterchangeable() );
@ -1757,8 +1757,10 @@ void SYMBOL_EDIT_FRAME::UpdateSymbolMsgPanelInfo()
AppendMsgPanel( _( "Body" ), msg, 8 );
if( m_symbol->IsPower() )
if( m_symbol->IsGlobalPower() )
msg = _( "Power Symbol" );
else if( m_symbol->IsLocalPower() )
msg = _( "Power Symbol (Local)" );
else
msg = _( "Symbol" );

View File

@ -710,7 +710,7 @@ void BACK_ANNOTATE::processNetNameChange( SCH_COMMIT* aCommit, const wxString& a
SCH_PIN* schPin = static_cast<SCH_PIN*>( driver );
SPIN_STYLE spin = orientLabel( schPin );
if( schPin->IsGlobalPower() )
if( schPin->IsPower() )
{
msg.Printf( _( "Net %s cannot be changed to %s because it is driven by a power pin." ),
EscapeHTML( aOldName ),

View File

@ -392,6 +392,36 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
GRID_HELPER_GRIDS::GRID_CONNECTABLE );
}
EESCHEMA_SETTINGS* cfg = m_frame->eeconfig();
if( !libSymbol->IsLocalPower() && cfg->m_Drawing.new_power_symbols == POWER_SYMBOLS::LOCAL )
{
libSymbol->SetLocalPower();
wxString keywords = libSymbol->GetKeyWords();
// Adjust the KiCad library default fields to match the new power symbol type
if( keywords.Contains( wxT( "global power" ) ) )
{
keywords.Replace( wxT( "global power" ), wxT( "local power" ) );
libSymbol->SetKeyWords( keywords );
}
wxString desc = libSymbol->GetDescription();
if( desc.Contains( wxT( "global label" ) ) )
{
desc.Replace( wxT( "global label" ), wxT( "local label" ) );
libSymbol->SetDescription( desc );
}
}
else if( !libSymbol->IsGlobalPower()
&& cfg->m_Drawing.new_power_symbols == POWER_SYMBOLS::GLOBAL )
{
// We do not currently have local power symbols in the KiCad library, so
// don't update any fields
libSymbol->SetGlobalPower();
}
symbol = new SCH_SYMBOL( *libSymbol, &m_frame->GetCurrentSheet(), sel, cursorPos,
&m_frame->Schematic() );
addSymbol( symbol );

View File

@ -42,7 +42,7 @@ struct LEGACY_POWER_SYMBOLS_TEST_FIXTURE
// Fix pre-8.0 legacy power symbols with invisible pins
// that have mismatched pin names and value fields
if( symbol->GetLibSymbolRef()
&& symbol->GetLibSymbolRef()->IsPower()
&& symbol->GetLibSymbolRef()->IsGlobalPower()
&& symbol->GetAllLibPins().size() > 0
&& symbol->GetAllLibPins()[0]->IsGlobalPower()
&& !symbol->GetAllLibPins()[0]->IsVisible() )

View File

@ -391,10 +391,10 @@ BOOST_AUTO_TEST_CASE( Compare )
m_part_no_data.SetUnitCount( 1 );
// Options flag comparison tests.
testPart.SetPower();
testPart.SetGlobalPower();
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
testPart.SetNormal();
m_part_no_data.SetPower();
m_part_no_data.SetGlobalPower();
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
m_part_no_data.SetNormal();
@ -678,7 +678,7 @@ BOOST_AUTO_TEST_CASE( IsPowerTest )
BOOST_CHECK( !symbol->IsPower() );
BOOST_CHECK( symbol->IsNormal() );
symbol->SetPower();
symbol->SetGlobalPower();
BOOST_CHECK( symbol->IsPower() );
BOOST_CHECK( !symbol->IsNormal() );

View File

@ -91,6 +91,7 @@ BOOST_AUTO_TEST_CASE( DefaultProperties )
BOOST_CHECK( ( m_sch_pin->GetType() == m_lib_pin->GetType() ) );
BOOST_CHECK_EQUAL( m_sch_pin->IsGlobalPower(), m_lib_pin->IsGlobalPower() );
BOOST_CHECK_EQUAL( m_sch_pin->IsLocalPower(), m_lib_pin->IsLocalPower() );
}
/**
@ -162,7 +163,7 @@ BOOST_AUTO_TEST_CASE( PinNumberingPower )
{
// but if we set isPower...
m_lib_pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
m_parent_part->SetPower();
m_parent_part->SetGlobalPower();
BOOST_CHECK_EQUAL( m_lib_pin->IsGlobalPower(), true );
// and update symbol from library...