Eeschema: add support for default schematic symbol instance data.

Prior to fixing the schematic file change churn do to instance data
changing to the last selected sheet instance, the symbol instance data
was set rather than empty.  This change allows for users to set the
default instance data which is used for every new instance of the
schematic.

ADDED: Default schematic symbol instance data (unit and reference, value,
       and footprint fields) can be set to be used as the default settings
       for all new instances of the schematic.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/11113
This commit is contained in:
Wayne Stambaugh 2022-04-08 12:05:27 -04:00
parent 8f63aea0c3
commit 239f0214ac
13 changed files with 281 additions and 44 deletions

View File

@ -372,14 +372,27 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow()
m_sheet->SetBorderColor( m_borderSwatch->GetSwatchColor() ); m_sheet->SetBorderColor( m_borderSwatch->GetSwatchColor() );
m_sheet->SetBackgroundColor( m_backgroundSwatch->GetSwatchColor() ); m_sheet->SetBackgroundColor( m_backgroundSwatch->GetSwatchColor() );
SCH_SHEET_LIST hierarchy = m_frame->Schematic().GetFullHierarchy();
SCH_SHEET_PATH instance = m_frame->GetCurrentSheet(); SCH_SHEET_PATH instance = m_frame->GetCurrentSheet();
instance.push_back( m_sheet ); instance.push_back( m_sheet );
if( m_sheet->IsNew() ) if( m_sheet->IsNew() )
{
m_sheet->AddInstance( instance ); m_sheet->AddInstance( instance );
if( filename_changed )
{
// Set the symbol instance data to the default for all new sheets and sub-sheets.
SCH_SHEET_LIST newInstances( m_sheet );
for( SCH_SHEET_PATH& newInstance : newInstances )
{
instance = m_frame->GetCurrentSheet() + newInstance;
instance.SetSymbolInstancesToDefault();
}
}
}
m_sheet->SetPageNumber( instance, m_pageNumberTextCtrl->GetValue() ); m_sheet->SetPageNumber( instance, m_pageNumberTextCtrl->GetValue() );
m_frame->TestDanglingEnds(); m_frame->TestDanglingEnds();
@ -448,7 +461,6 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
bool renameFile = false; bool renameFile = false;
bool loadFromFile = false; bool loadFromFile = false;
bool clearAnnotation = false; bool clearAnnotation = false;
bool restoreSheet = false;
bool isExistingSheet = false; bool isExistingSheet = false;
SCH_SCREEN* useScreen = nullptr; SCH_SCREEN* useScreen = nullptr;
SCH_SCREEN* oldScreen = nullptr; SCH_SCREEN* oldScreen = nullptr;
@ -533,7 +545,8 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
{ {
if( m_sheet->GetScreenCount() > 1 ) if( m_sheet->GetScreenCount() > 1 )
{ {
if( !IsOK( this, wxString::Format( _( "Create new file '%s' with contents of '%s'?" ), if( !IsOK( this, wxString::Format( _( "Create new file '%s' with contents "
"of '%s'?" ),
sheetFileName.GetFullName(), sheetFileName.GetFullName(),
m_sheet->GetFileName() ) m_sheet->GetFileName() )
+ wxT( "\n\n" ) + wxT( "\n\n" )
@ -604,18 +617,16 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
// No need to check for valid library IDs if we are using an existing screen. // No need to check for valid library IDs if we are using an existing screen.
if( m_frame->CheckSheetForRecursion( tmpSheet.get(), &currentSheet ) ) if( m_frame->CheckSheetForRecursion( tmpSheet.get(), &currentSheet ) )
{
if( restoreSheet )
currentSheet.LastScreen()->Append( m_sheet );
return false; return false;
}
// It's safe to set the sheet screen now. // It's safe to set the sheet screen now.
m_sheet->SetScreen( useScreen ); m_sheet->SetScreen( useScreen );
// currentSheet.LastScreen()->Append( m_sheet );
} }
else if( loadFromFile ) else if( loadFromFile )
{ {
bool restoreSheet = false;
if( isExistingSheet ) if( isExistingSheet )
{ {
// Temporarily remove the sheet from the current schematic page so that recursion // Temporarily remove the sheet from the current schematic page so that recursion
@ -642,8 +653,7 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
if( restoreSheet ) if( restoreSheet )
currentSheet.LastScreen()->Append( m_sheet ); currentSheet.LastScreen()->Append( m_sheet );
// The full hiearchy needs to be reloaded because any sub-sheet that occurred on // The full hierarchy needs to be reloaded because due to the addition of a new sheet.
// file load will have new SCH_SHEET object pointers.
fullHierarchy = m_frame->Schematic().GetFullHierarchy(); fullHierarchy = m_frame->Schematic().GetFullHierarchy();
fullHierarchy.UpdateSheetInstances( sheetInstances ); fullHierarchy.UpdateSheetInstances( sheetInstances );
} }

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -794,6 +794,18 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataFromWindow()
} }
} }
if( m_cbMakeDefaultInstance->IsChecked() )
{
SYMBOL_INSTANCE_REFERENCE defaultInstance;
defaultInstance.m_Unit = unit_selection;
defaultInstance.m_Reference = m_fields->at( REFERENCE_FIELD ).GetText();
defaultInstance.m_Value = m_fields->at( VALUE_FIELD ).GetText();
defaultInstance.m_Footprint = m_fields->at( FOOTPRINT_FIELD ).GetText();
m_symbol->SetDefaultInstance( defaultInstance );
}
currentScreen->Append( m_symbol ); currentScreen->Append( m_symbol );
GetParent()->TestDanglingEnds(); GetParent()->TestDanglingEnds();
GetParent()->UpdateItem( m_symbol, false, true ); GetParent()->UpdateItem( m_symbol, false, true );
@ -1017,7 +1029,8 @@ void DIALOG_SYMBOL_PROPERTIES::OnPinTableCellEdited( wxGridEvent& aEvent )
{ {
int row = aEvent.GetRow(); int row = aEvent.GetRow();
if( m_pinGrid->GetCellValue( row, COL_ALT_NAME ) == m_dataModel->GetValue( row, COL_BASE_NAME ) ) if( m_pinGrid->GetCellValue( row, COL_ALT_NAME ) ==
m_dataModel->GetValue( row, COL_BASE_NAME ) )
m_dataModel->SetValue( row, COL_ALT_NAME, wxEmptyString ); m_dataModel->SetValue( row, COL_ALT_NAME, wxEmptyString );
// These are just to get the cells refreshed // These are just to get the cells refreshed

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.0) // C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // PLEASE DO *NOT* EDIT THIS FILE!
@ -137,7 +137,12 @@ DIALOG_SYMBOL_PROPERTIES_BASE::DIALOG_SYMBOL_PROPERTIES_BASE( wxWindow* parent,
m_cbAlternateSymbol = new wxCheckBox( sbGeneralProps->GetStaticBox(), wxID_ANY, _("Alternate symbol (De Morgan)"), wxDefaultPosition, wxDefaultSize, 0 ); m_cbAlternateSymbol = new wxCheckBox( sbGeneralProps->GetStaticBox(), wxID_ANY, _("Alternate symbol (De Morgan)"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbAlternateSymbol->SetToolTip( _("Use the alternate shape of this symbol.\nFor gates, this is the \"De Morgan\" conversion") ); m_cbAlternateSymbol->SetToolTip( _("Use the alternate shape of this symbol.\nFor gates, this is the \"De Morgan\" conversion") );
gbSizer1->Add( m_cbAlternateSymbol, wxGBPosition( 1, 0 ), wxGBSpan( 1, 2 ), wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 ); gbSizer1->Add( m_cbAlternateSymbol, wxGBPosition( 1, 0 ), wxGBSpan( 1, 2 ), wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
m_cbMakeDefaultInstance = new wxCheckBox( sbGeneralProps->GetStaticBox(), wxID_ANY, _("Default for all sheet instances"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbMakeDefaultInstance->SetToolTip( _("Check to make the unit and reference, value, and\nfootprint fields the default for all sheet instances\nof this symbol") );
gbSizer1->Add( m_cbMakeDefaultInstance, wxGBPosition( 2, 0 ), wxGBSpan( 1, 2 ), wxBOTTOM|wxLEFT|wxRIGHT, 5 );
m_orientationLabel = new wxStaticText( sbGeneralProps->GetStaticBox(), wxID_ANY, _("Angle:"), wxDefaultPosition, wxDefaultSize, 0 ); m_orientationLabel = new wxStaticText( sbGeneralProps->GetStaticBox(), wxID_ANY, _("Angle:"), wxDefaultPosition, wxDefaultSize, 0 );
m_orientationLabel->Wrap( -1 ); m_orientationLabel->Wrap( -1 );

View File

@ -784,7 +784,7 @@
<property name="border">5</property> <property name="border">5</property>
<property name="colspan">2</property> <property name="colspan">2</property>
<property name="column">0</property> <property name="column">0</property>
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property> <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
<property name="row">1</property> <property name="row">1</property>
<property name="rowspan">1</property> <property name="rowspan">1</property>
<object class="wxCheckBox" expanded="0"> <object class="wxCheckBox" expanded="0">
@ -848,6 +848,73 @@
<event name="OnCheckBox">OnCheckBox</event> <event name="OnCheckBox">OnCheckBox</event>
</object> </object>
</object> </object>
<object class="gbsizeritem" expanded="1">
<property name="border">5</property>
<property name="colspan">2</property>
<property name="column">0</property>
<property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
<property name="row">2</property>
<property name="rowspan">1</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></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="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">Default for all sheet instances</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_cbMakeDefaultInstance</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">Check to make the unit and reference, value, and&#x0A;footprint fields the default for all sheet instances&#x0A;of this symbol</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 class="gbsizeritem" expanded="1"> <object class="gbsizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="colspan">1</property> <property name="colspan">1</property>

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.0) // C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // PLEASE DO *NOT* EDIT THIS FILE!
@ -56,6 +56,7 @@ class DIALOG_SYMBOL_PROPERTIES_BASE : public DIALOG_SHIM
wxStaticText* m_unitLabel; wxStaticText* m_unitLabel;
wxChoice* m_unitChoice; wxChoice* m_unitChoice;
wxCheckBox* m_cbAlternateSymbol; wxCheckBox* m_cbAlternateSymbol;
wxCheckBox* m_cbMakeDefaultInstance;
wxStaticText* m_orientationLabel; wxStaticText* m_orientationLabel;
wxChoice* m_orientationCtrl; wxChoice* m_orientationCtrl;
wxStaticText* m_mirrorLabel; wxStaticText* m_mirrorLabel;

View File

@ -79,4 +79,5 @@
//#define SEXPR_SCHEMATIC_FILE_VERSION 20220124 // netclass_flag -> directive_label //#define SEXPR_SCHEMATIC_FILE_VERSION 20220124 // netclass_flag -> directive_label
//#define SEXPR_SCHEMATIC_FILE_VERSION 20220126 // Text boxes //#define SEXPR_SCHEMATIC_FILE_VERSION 20220126 // Text boxes
//#define SEXPR_SCHEMATIC_FILE_VERSION 20220328 // Text box start/end -> at/size //#define SEXPR_SCHEMATIC_FILE_VERSION 20220328 // Text box start/end -> at/size
#define SEXPR_SCHEMATIC_FILE_VERSION 20220331 // Text colors //#define SEXPR_SCHEMATIC_FILE_VERSION 20220331 // Text colors
#define SEXPR_SCHEMATIC_FILE_VERSION 20220404 // Default schematic symbol instance data.

View File

@ -2541,6 +2541,51 @@ SCH_SYMBOL* SCH_SEXPR_PARSER::parseSchematicSymbol()
NeedRIGHT(); NeedRIGHT();
break; break;
case T_default_instance:
{
SYMBOL_INSTANCE_REFERENCE defaultInstance;
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
switch( token )
{
case T_reference:
NeedSYMBOL();
defaultInstance.m_Reference = FromUTF8();
NeedRIGHT();
break;
case T_unit:
defaultInstance.m_Unit = parseInt( "symbol unit" );
NeedRIGHT();
break;
case T_value:
NeedSYMBOL();
defaultInstance.m_Value = FromUTF8();
NeedRIGHT();
break;
case T_footprint:
NeedSYMBOL();
defaultInstance.m_Footprint = FromUTF8();
NeedRIGHT();
break;
default:
Expecting( "path, unit, value or footprint" );
}
}
symbol->SetDefaultInstance( defaultInstance );
break;
}
case T_property: case T_property:
// The field parent symbol must be set and its orientation must be set before // The field parent symbol must be set and its orientation must be set before
// the field positions are set. // the field positions are set.

View File

@ -685,9 +685,9 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPa
m_out->Print( 0, ")" ); m_out->Print( 0, ")" );
} }
int unit = ( aSymbol->GetInstanceReferences().size() == 0 ) ? // The symbol unit is always set to the default instance regardless of the sheet instance
aSymbol->GetUnit() : // to prevent file churn.
aSymbol->GetInstanceReferences()[0].m_Unit; int unit = aSymbol->GetDefaultInstance().m_Unit;
m_out->Print( 0, " (unit %d)", unit ); m_out->Print( 0, " (unit %d)", unit );
@ -706,6 +706,13 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPa
m_out->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aSymbol->m_Uuid.AsString() ) ); m_out->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aSymbol->m_Uuid.AsString() ) );
m_out->Print( aNestLevel + 1,
"(default_instance (reference %s) (unit %d) (value %s) (footprint %s))\n",
m_out->Quotew( aSymbol->GetDefaultInstance().m_Reference ).c_str(),
aSymbol->GetDefaultInstance().m_Unit,
m_out->Quotew( aSymbol->GetDefaultInstance().m_Value ).c_str(),
m_out->Quotew( aSymbol->GetDefaultInstance().m_Footprint ).c_str() );
m_nextFreeFieldId = MANDATORY_FIELDS; m_nextFreeFieldId = MANDATORY_FIELDS;
for( SCH_FIELD& field : aSymbol->GetFields() ) for( SCH_FIELD& field : aSymbol->GetFields() )
@ -713,26 +720,19 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPa
int id = field.GetId(); int id = field.GetId();
wxString value = field.GetText(); wxString value = field.GetText();
// The instance fields are always set to the first sheet instance of the project to // The instance fields are always set to the default instance regardless of the
// schematic file changes when switching sheet instances with the current project // sheet instance to prevent file churn.
// schematic. It does not solve the problem for schematics shared between projects.
if( id == REFERENCE_FIELD ) if( id == REFERENCE_FIELD )
{ {
field.SetText( ( aSymbol->GetInstanceReferences().size() == 0 ) ? field.SetText( aSymbol->GetDefaultInstance().m_Reference );
value :
aSymbol->GetInstanceReferences()[0].m_Reference );
} }
else if( id == VALUE_FIELD ) else if( id == VALUE_FIELD )
{ {
field.SetText( ( aSymbol->GetInstanceReferences().size() == 0 ) ? field.SetText( aSymbol->GetDefaultInstance().m_Value );
value :
aSymbol->GetInstanceReferences()[0].m_Value );
} }
else if( id == FOOTPRINT_FIELD ) else if( id == FOOTPRINT_FIELD )
{ {
field.SetText( ( aSymbol->GetInstanceReferences().size() == 0 ) ? field.SetText( aSymbol->GetDefaultInstance().m_Footprint );
value :
aSymbol->GetInstanceReferences()[0].m_Footprint );
} }
try try

View File

@ -115,6 +115,19 @@ SCH_SHEET_PATH& SCH_SHEET_PATH::operator=( const SCH_SHEET_PATH& aOther )
} }
SCH_SHEET_PATH SCH_SHEET_PATH::operator+( const SCH_SHEET_PATH& aOther )
{
SCH_SHEET_PATH retv = *this;
size_t size = aOther.size();
for( size_t i = 0; i < size; i++ )
retv.push_back( aOther.at( i ) );
return retv;
}
void SCH_SHEET_PATH::initFromOther( const SCH_SHEET_PATH& aOther ) void SCH_SHEET_PATH::initFromOther( const SCH_SHEET_PATH& aOther )
{ {
m_sheets = aOther.m_sheets; m_sheets = aOther.m_sheets;
@ -193,9 +206,17 @@ bool SCH_SHEET_PATH::IsContainedWithin( const SCH_SHEET_PATH& aSheetPathToTest )
for( size_t i = 0; i < aSheetPathToTest.size(); ++i ) for( size_t i = 0; i < aSheetPathToTest.size(); ++i )
{ {
if( at( i )->m_Uuid != aSheetPathToTest.at( i )->m_Uuid ) if( at( i )->m_Uuid != aSheetPathToTest.at( i )->m_Uuid )
{
wxLogTrace( traceSchSheetPaths, "Sheet path '%s' is not within path '%s'.",
aSheetPathToTest.Path().AsString(), Path().AsString() );
return false; return false;
}
} }
wxLogTrace( traceSchSheetPaths, "Sheet path '%s' is within path '%s'.",
aSheetPathToTest.Path().AsString(), Path().AsString() );
return true; return true;
} }
@ -374,6 +395,19 @@ void SCH_SHEET_PATH::AppendMultiUnitSymbol( SCH_MULTI_UNIT_REFERENCE_MAP& aRefLi
} }
void SCH_SHEET_PATH::SetSymbolInstancesToDefault()
{
for( SCH_ITEM* item : LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
{
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
wxCHECK2( symbol, continue );
symbol->SetInstanceToDefault( *this );
}
}
bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 ) const bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 ) const
{ {
return m_current_hash == d1.GetCurrentHash(); return m_current_hash == d1.GetCurrentHash();

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -134,6 +134,8 @@ public:
SCH_SHEET_PATH& operator=( const SCH_SHEET_PATH& aOther ); SCH_SHEET_PATH& operator=( const SCH_SHEET_PATH& aOther );
SCH_SHEET_PATH operator+( const SCH_SHEET_PATH& aOther );
~SCH_SHEET_PATH() = default; ~SCH_SHEET_PATH() = default;
/// Forwarded method from std::vector /// Forwarded method from std::vector
@ -215,8 +217,8 @@ public:
int Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const; int Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const;
/** /**
* Compare sheets by their page number. If the actual page number is equal, use virtual page numbers * Compare sheets by their page number. If the actual page number is equal, use virtual page
* to compare. * numbers to compare.
* *
* @return -1 if aSheetPathToTest is greater than this (should appear later in the sort order) * @return -1 if aSheetPathToTest is greater than this (should appear later in the sort order)
* 0 if aSheetPathToTest is equal to this * 0 if aSheetPathToTest is equal to this
@ -336,6 +338,11 @@ public:
void GetMultiUnitSymbols( SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, void GetMultiUnitSymbols( SCH_MULTI_UNIT_REFERENCE_MAP &aRefList,
bool aIncludePowerSymbols = true ) const; bool aIncludePowerSymbols = true ) const;
/**
* Set all of the symbol instances in this sheet instance to the default symbol instance data.
*/
void SetSymbolInstancesToDefault();
/** /**
* Test the SCH_SHEET_PATH file names to check adding the sheet stored in the file * Test the SCH_SHEET_PATH file names to check adding the sheet stored in the file
* \a aSrcFileName to the sheet stored in file \a aDestFileName will cause a sheet * \a aSrcFileName to the sheet stored in file \a aDestFileName will cause a sheet

View File

@ -52,6 +52,7 @@ std::string toUTFTildaText( const wxString& txt )
if( (unsigned char) *it <= ' ' ) if( (unsigned char) *it <= ' ' )
*it = '~'; *it = '~';
} }
return ret; return ret;
} }
@ -103,13 +104,14 @@ SCH_SYMBOL::SCH_SYMBOL() :
SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const LIB_ID& aLibId, SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const LIB_ID& aLibId,
const SCH_SHEET_PATH* aSheet, int unit, int convert, const VECTOR2I& pos ) : const SCH_SHEET_PATH* aSheet, int aUnit, int aConvert,
const VECTOR2I& aPosition ) :
SCH_ITEM( nullptr, SCH_SYMBOL_T ) SCH_ITEM( nullptr, SCH_SYMBOL_T )
{ {
Init( pos ); Init( aPosition );
m_unit = unit; m_unit = aUnit;
m_convert = convert; m_convert = aConvert;
m_lib_id = aLibId; m_lib_id = aLibId;
std::unique_ptr< LIB_SYMBOL > part; std::unique_ptr< LIB_SYMBOL > part;
@ -128,6 +130,12 @@ SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const LIB_ID& aLibId,
m_prefix = UTIL::GetRefDesPrefix( m_part->GetReferenceField().GetText() ); m_prefix = UTIL::GetRefDesPrefix( m_part->GetReferenceField().GetText() );
// Set initial default symbol instance data from library symbol and initial unit.
m_defaultInstance.m_Reference = m_prefix;
m_defaultInstance.m_Unit = aUnit;
m_defaultInstance.m_Value = m_part->GetValueField().GetText();
m_defaultInstance.m_Footprint = m_part->GetFootprintField().GetText();
if( aSheet ) if( aSheet )
{ {
SetRef( aSheet, UTIL::GetRefDesUnannotated( m_prefix ) ); SetRef( aSheet, UTIL::GetRefDesUnannotated( m_prefix ) );
@ -146,8 +154,8 @@ SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const LIB_ID& aLibId,
SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const SCH_SHEET_PATH* aSheet, SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const SCH_SHEET_PATH* aSheet,
const PICKED_SYMBOL& aSel, const VECTOR2I& pos ) : const PICKED_SYMBOL& aSel, const VECTOR2I& aPosition ) :
SCH_SYMBOL( aSymbol, aSel.LibId, aSheet, aSel.Unit, aSel.Convert, pos ) SCH_SYMBOL( aSymbol, aSel.LibId, aSheet, aSel.Unit, aSel.Convert, aPosition )
{ {
// Set any fields that were modified as part of the symbol selection // Set any fields that were modified as part of the symbol selection
for( const std::pair<int, wxString>& i : aSel.Fields ) for( const std::pair<int, wxString>& i : aSel.Fields )
@ -188,6 +196,7 @@ SCH_SYMBOL::SCH_SYMBOL( const SCH_SYMBOL& aSymbol ) :
m_fieldsAutoplaced = aSymbol.m_fieldsAutoplaced; m_fieldsAutoplaced = aSymbol.m_fieldsAutoplaced;
m_schLibSymbolName = aSymbol.m_schLibSymbolName; m_schLibSymbolName = aSymbol.m_schLibSymbolName;
m_defaultInstance = aSymbol.m_defaultInstance;
} }
@ -215,6 +224,7 @@ void SCH_SYMBOL::Init( const VECTOR2I& pos )
} }
m_prefix = wxString( wxT( "U" ) ); m_prefix = wxString( wxT( "U" ) );
m_defaultInstance.m_Reference = m_prefix;
m_isInNetlist = true; m_isInNetlist = true;
m_inBom = true; m_inBom = true;
m_onBoard = true; m_onBoard = true;
@ -935,6 +945,7 @@ void SCH_SYMBOL::SwapData( SCH_ITEM* aItem )
std::swap( m_instanceReferences, symbol->m_instanceReferences ); std::swap( m_instanceReferences, symbol->m_instanceReferences );
std::swap( m_schLibSymbolName, symbol->m_schLibSymbolName ); std::swap( m_schLibSymbolName, symbol->m_schLibSymbolName );
std::swap( m_defaultInstance, symbol->m_defaultInstance );
} }
@ -1108,8 +1119,8 @@ bool SCH_SYMBOL::ReplaceInstanceSheetPath( const KIID_PATH& aOldSheetPath,
} }
wxLogTrace( traceSchSheetPaths, wxLogTrace( traceSchSheetPaths,
"Could not find sheet path %s\n to replace with sheet path %s\n for symbol %s.", "Could not find sheet path %s\n to replace with sheet path %s\n for symbol %s.",
aOldSheetPath.AsString(), aNewSheetPath.AsString(), m_Uuid.AsString() ); aOldSheetPath.AsString(), aNewSheetPath.AsString(), m_Uuid.AsString() );
return false; return false;
} }
@ -1780,6 +1791,7 @@ SCH_SYMBOL& SCH_SYMBOL::operator=( const SCH_ITEM& aItem )
m_transform = c->m_transform; m_transform = c->m_transform;
m_instanceReferences = c->m_instanceReferences; m_instanceReferences = c->m_instanceReferences;
m_defaultInstance = c->m_defaultInstance;
m_fields = c->m_fields; // std::vector's assignment operator m_fields = c->m_fields; // std::vector's assignment operator
@ -1923,3 +1935,25 @@ bool SCH_SYMBOL::IsPointClickableAnchor( const VECTOR2I& aPos ) const
return false; return false;
} }
void SCH_SYMBOL::SetInstanceToDefault( const SCH_SHEET_PATH& aInstance )
{
KIID_PATH path = aInstance.Path();
for( SYMBOL_INSTANCE_REFERENCE& instance: m_instanceReferences )
{
if( instance.m_Path == path )
{
instance.m_Reference = m_defaultInstance.m_Reference;
instance.m_Unit = m_defaultInstance.m_Unit;
instance.m_Value = m_defaultInstance.m_Value;
instance.m_Footprint = m_defaultInstance.m_Footprint;
return;
}
}
// It's a new instance so add it.
AddHierarchicalReference( path, m_defaultInstance.m_Reference, m_defaultInstance.m_Unit,
m_defaultInstance.m_Value, m_defaultInstance.m_Footprint );
}

View File

@ -4,7 +4,7 @@
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com * Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com
* Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -125,6 +125,15 @@ public:
return m_instanceReferences; return m_instanceReferences;
} }
void SetDefaultInstance( const SYMBOL_INSTANCE_REFERENCE& aInstance )
{
m_defaultInstance = aInstance;
}
const SYMBOL_INSTANCE_REFERENCE& GetDefaultInstance() const { return m_defaultInstance; }
void SetInstanceToDefault( const SCH_SHEET_PATH& aInstance );
void ViewGetLayers( int aLayers[], int& aCount ) const override; void ViewGetLayers( int aLayers[], int& aCount ) const override;
/** /**
@ -710,6 +719,16 @@ private:
// Defines the hierarchical path and reference of the symbol. This allows support // Defines the hierarchical path and reference of the symbol. This allows support
// for multiple references to a single sub-sheet. // for multiple references to a single sub-sheet.
std::vector<SYMBOL_INSTANCE_REFERENCE> m_instanceReferences; std::vector<SYMBOL_INSTANCE_REFERENCE> m_instanceReferences;
/**
* The default instance data for this symbol.
*
* This allows for setting the default data across all instances of this symbol. This
* means that any reuse of the symbol in the current schematic will initially use the
* default instance data. @see SYMBOL_INSTANCE_REFERENCE definition for the allowable
* instance settings.
*/
SYMBOL_INSTANCE_REFERENCE m_defaultInstance;
}; };
#endif /* __SYMBOL_H__ */ #endif /* __SYMBOL_H__ */

View File

@ -24,6 +24,7 @@ convert
data data
date date
default default
default_instance
diameter diameter
diamond diamond
directive_label directive_label