Move pad locking from footprint to pads.

Fixes https://gitlab.com/kicad/code/kicad/issues/6997
This commit is contained in:
Jeff Young 2021-01-08 16:32:28 +00:00
parent ce8039c327
commit 3467e643e5
13 changed files with 162 additions and 56 deletions

View File

@ -638,7 +638,7 @@ XNODE* NETLIST_EXPORTER_XML::makeListOfNets( unsigned aCtl )
for( SCH_PIN* pin : symbol->GetPins( &sheet ) )
{
if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC && !pin->Connection( &sheet ) )
{
ncNets.push_back( new NET_RECORD( NC_PREFIX, std::vector<MEMBER_RECORD>() ) );
ncNets.back()->second.emplace_back( pin, sheet );

View File

@ -252,6 +252,18 @@ void DIALOG_FOOTPRINT_PROPERTIES::OnOtherOrientation( wxCommandEvent& aEvent )
}
bool allPadsLocked( FOOTPRINT* aFootprint )
{
for( PAD* pad : aFootprint->Pads() )
{
if( !pad->IsLocked() )
return false;
}
return true;
}
bool DIALOG_FOOTPRINT_PROPERTIES::TransferDataToWindow()
{
if( !wxDialog::TransferDataToWindow() )
@ -304,18 +316,21 @@ bool DIALOG_FOOTPRINT_PROPERTIES::TransferDataToWindow()
if( m_footprint->IsLocked() )
m_AutoPlaceCtrl->SetSelection( 2 );
else if( m_footprint->PadsLocked() )
else if( allPadsLocked( m_footprint ) )
m_AutoPlaceCtrl->SetSelection( 1 );
else
m_AutoPlaceCtrl->SetSelection( 0 );
m_AutoPlaceCtrl->SetItemToolTip( 0, _( "Footprint can be freely moved and auto placed. User "
"can arbitrarily select and edit footprint's pads." ) );
m_AutoPlaceCtrl->SetItemToolTip( 1, _( "Footprint can be freely moved and auto placed, but "
"its pads cannot be edited." ) );
m_AutoPlaceCtrl->SetItemToolTip( 2, _( "Footprint is locked: it cannot be freely moved or "
"auto placed, and can only be selected when the "
"'Locked items' checkbox is enabled in the "
m_AutoPlaceCtrl->SetItemToolTip( 0, _( "Footprint can be freely moved and oriented on the "
"canvas. At least some of the footprint's pads are "
"unlocked and can be moved with respect to the"
"footprint." ) );
m_AutoPlaceCtrl->SetItemToolTip( 1, _( "Footprint can be freely moved and oriented on the "
"canvas, but all of its pads are locked with respect "
"to their position within in the footprint." ) );
m_AutoPlaceCtrl->SetItemToolTip( 2, _( "Footprint is locked: it cannot be freely moved and"
"oriented on the canvas and can only be selected when "
"the 'Locked items' checkbox is enabled in the "
"selection filter." ) );
m_CostRot90Ctrl->SetValue( m_footprint->GetPlacementCost90() );
@ -702,7 +717,12 @@ bool DIALOG_FOOTPRINT_PROPERTIES::TransferDataFromWindow()
wxPoint pos( m_posX.GetValue(), m_posY.GetValue() );
m_footprint->SetPosition( pos );
m_footprint->SetLocked( m_AutoPlaceCtrl->GetSelection() == 2 );
m_footprint->SetPadsLocked( m_AutoPlaceCtrl->GetSelection() == 1 );
if( m_AutoPlaceCtrl->GetSelection() == 1 )
{
for( PAD* pad : m_footprint->Pads() )
pad->SetLocked( true );
}
int attributes = 0;

View File

@ -458,17 +458,20 @@ void DIALOG_PAD_PROPERTIES::initValues()
m_PadLayerECO2->SetLabel( m_board->GetLayerName( Eco2_User ) );
m_PadLayerDraft->SetLabel( m_board->GetLayerName( Dwgs_User ) );
m_isFlipped = false;
if( m_currentPad )
{
m_locked->SetValue( m_currentPad->IsLocked() );
m_isFlipped = m_currentPad->IsFlipped();
// Diplay parent footprint info
FOOTPRINT* footprint = m_currentPad->GetParent();
if( footprint )
{
angle = m_dummyPad->GetOrientation();
angle -= footprint->GetOrientation();
m_dummyPad->SetOrientation( angle );
// Diplay parent footprint info
msg.Printf( _("Footprint %s (%s), %s, rotated %g deg"),
footprint->Reference().GetShownText(),
footprint->Value().GetShownText(),
@ -479,17 +482,10 @@ void DIALOG_PAD_PROPERTIES::initValues()
m_parentInfo->SetLabel( msg );
}
if( m_currentPad )
else
{
FOOTPRINT* footprint = m_currentPad->GetParent();
if( footprint )
{
angle = m_dummyPad->GetOrientation();
angle -= footprint->GetOrientation();
m_dummyPad->SetOrientation( angle );
}
m_locked->Hide();
m_isFlipped = false;
}
if( m_isFlipped )
@ -994,6 +990,10 @@ void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event )
void DIALOG_PAD_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
{
// Enable/disable position
m_posX.Enable( !m_locked->GetValue() );
m_posY.Enable( !m_locked->GetValue() );
bool hasHole = true;
bool hasConnection = true;
@ -1556,9 +1556,13 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow()
// Update values
m_currentPad->SetShape( m_padMaster->GetShape() );
m_currentPad->SetAttribute( m_padMaster->GetAttribute() );
m_currentPad->SetPosition( m_padMaster->GetPosition() );
m_currentPad->SetOrientation( m_padMaster->GetOrientation() );
m_currentPad->SetLocked( m_locked->GetValue() );
if( !m_locked->GetValue() )
m_currentPad->SetPosition( m_padMaster->GetPosition() );
wxSize size;
FOOTPRINT* footprint = m_currentPad->GetParent();

View File

@ -79,6 +79,11 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
m_posYUnits->Wrap( -1 );
gbSizerCommon->Add( m_posYUnits, wxGBPosition( 3, 5 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_locked = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Locked"), wxDefaultPosition, wxDefaultSize, 0 );
m_locked->SetToolTip( _("Do not allow position of pad relative to parent footprint to be changed") );
gbSizerCommon->Add( m_locked, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxBOTTOM|wxRIGHT|wxLEFT, 5 );
gbSizerCommon->AddGrowableCol( 1 );
gbSizerCommon->AddGrowableCol( 4 );

View File

@ -993,6 +993,73 @@
<property name="wrap">-1</property>
</object>
</object>
<object class="gbsizeritem" expanded="1">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">0</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="row">4</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">Locked</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_locked</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">Do not allow position of pad relative to parent footprint to be changed</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="0">

View File

@ -23,11 +23,11 @@ class WX_GRID;
#include <wx/choice.h>
#include <wx/textctrl.h>
#include <widgets/net_selector.h>
#include <wx/checkbox.h>
#include <wx/gbsizer.h>
#include <wx/statline.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/checkbox.h>
#include <wx/simplebook.h>
#include <wx/combobox.h>
#include <wx/bitmap.h>
@ -75,6 +75,7 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
wxStaticText* m_posYLabel;
wxTextCtrl* m_posYCtrl;
wxStaticText* m_posYUnits;
wxCheckBox* m_locked;
wxStaticLine* m_staticline5;
wxStaticText* m_shapeLabel;
wxChoice* m_PadShapeSelector;

View File

@ -331,8 +331,9 @@ public:
m_fpStatus &= ~FP_to_PLACE;
}
bool PadsLocked() const { return m_fpStatus & FP_PADS_are_LOCKED; }
bool LegacyPadsLocked() const { return m_fpStatus & FP_PADS_are_LOCKED; }
/*
void SetPadsLocked( bool aPadsLocked )
{
if( aPadsLocked )
@ -340,6 +341,7 @@ public:
else
m_fpStatus &= ~FP_PADS_are_LOCKED;
}
*/
void SetLastEditTime( timestamp_t aTime ) { m_lastEditTime = aTime; }
void SetLastEditTime() { m_lastEditTime = time( NULL ); }

View File

@ -452,9 +452,6 @@ void FOOTPRINT_EDIT_FRAME::AddFootprintToBoard( FOOTPRINT* aFootprint )
m_footprintNameWhenLoaded = aFootprint->GetFPID().GetLibItemName();
// Pads are always editable in Footprint Editor
aFootprint->SetPadsLocked( false );
PCB_BASE_EDIT_FRAME::AddFootprintToBoard( aFootprint );
if( IsCurrentFPFromBoard() )

View File

@ -133,13 +133,10 @@ PAD& PAD::operator=( const PAD &aOther )
bool PAD::IsLocked() const
{
if( GetParent() )
{
FOOTPRINT* fp = static_cast<FOOTPRINT*>( GetParent() );
return fp->IsLocked() || fp->PadsLocked();
}
if( GetParent() && static_cast<FOOTPRINT*>( GetParent() )->IsLocked() )
return true;
return false;
return BOARD_ITEM::IsLocked();
};

View File

@ -1318,6 +1318,10 @@ void PCB_IO::format( PAD* aPad, int aNestLevel ) const
m_out->Print( 0, " %s", FormatAngle( aPad->GetOrientation() ).c_str() );
m_out->Print( 0, ")" );
if( aPad->IsLocked() )
m_out->Print( 0, " (locked)" );
m_out->Print( 0, " (size %s)", FormatInternalUnits( aPad->GetSize() ).c_str() );
if( (aPad->GetDelta().GetWidth()) != 0 || (aPad->GetDelta().GetHeight() != 0 ) )

View File

@ -92,7 +92,8 @@ class PCB_TEXT;
//#define SEXPR_BOARD_FILE_VERSION 20201114 // Add first-class support for filled shapes.
//#define SEXPR_BOARD_FILE_VERSION 20201115 // module -> footprint and change fill syntax.
//#define SEXPR_BOARD_FILE_VERSION 20201116 // Write version and generator string in footprint files.
#define SEXPR_BOARD_FILE_VERSION 20201220 // Add free via token
//#define SEXPR_BOARD_FILE_VERSION 20201220 // Add free via token
#define SEXPR_BOARD_FILE_VERSION 20210108 // Pad locking moved from footprint to pads
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag

View File

@ -3141,13 +3141,12 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
break;
default:
Expecting(
"locked, placed, tedit, tstamp, at, descr, tags, path, "
"autoplace_cost90, autoplace_cost180, solder_mask_margin, "
"solder_paste_margin, solder_paste_ratio, clearance, "
"zone_connect, thermal_width, thermal_gap, attr, fp_text, "
"fp_arc, fp_circle, fp_curve, fp_line, fp_poly, fp_rect, pad, "
"zone, group, generator, version or model" );
Expecting( "locked, placed, tedit, tstamp, at, descr, tags, path, "
"autoplace_cost90, autoplace_cost180, solder_mask_margin, "
"solder_paste_margin, solder_paste_ratio, clearance, "
"zone_connect, thermal_width, thermal_gap, attr, fp_text, "
"fp_arc, fp_circle, fp_curve, fp_line, fp_poly, fp_rect, pad, "
"zone, group, generator, version or model" );
}
}
@ -3159,15 +3158,22 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
if( m_requiredVersion < 20200826 && attributes == 0 )
attributes |= FP_THROUGH_HOLE;
// Legacy files controlled pad locking at the footprint level.
if( m_requiredVersion < 20210108 )
{
for( PAD* pad : footprint->Pads() )
pad->SetLocked( footprint->IsLocked() || footprint->LegacyPadsLocked() );
}
footprint->SetAttributes( attributes );
footprint->SetFPID( fpid );
footprint->SetProperties( properties );
// We want to calculate the bounding box in most cases except
// if the advanced config is set and its a general footprint load
// This improves debugging greatly under MSVC where full std iterator debugging
// is present and loading a massive amount of footprints can lead to 2 minute load times
// We want to calculate the bounding box in most cases except if the advanced config is set
// and its a general footprint load. This improves debugging greatly under MSVC where full
// STL iterator debugging is present and loading a massive amount of footprints can lead to
// 2 minute load times.
if( !ADVANCED_CFG::GetCfg().m_SkipBoundingBoxOnFpLoad || m_board != nullptr
|| reader->GetSource().Contains( "clipboard" ) )
{
@ -3986,6 +3992,11 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent )
NeedRIGHT();
break;
case T_locked:
pad->SetLocked( true );
NeedRIGHT();
break;
case T_tstamp:
NextTok();
const_cast<KIID&>( pad->m_Uuid ) = CurStrToKIID();
@ -3993,9 +4004,10 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent )
break;
default:
Expecting( "at, drill, layers, net, die_length, solder_mask_margin, roundrect_rratio,\n"
"solder_paste_margin, solder_paste_margin_ratio, clearance, tstamp,\n"
"zone_connect, fp_poly, primitives, thermal_width, or thermal_gap" );
Expecting( "at, locked, drill, layers, net, die_length, roundrect_rratio, "
"solder_mask_margin, solder_paste_margin, solder_paste_margin_ratio, "
"clearance, tstamp, primitives, remove_unused_layers, keep_end_layers, "
"zone_connect, thermal_width, or thermal_gap" );
}
}

View File

@ -232,14 +232,10 @@ std::shared_ptr<EDIT_POINTS> POINT_EDITOR::makePoints( EDA_ITEM* aItem )
case PCB_PAD_T:
{
const PAD* pad = static_cast<const PAD*>( aItem );
FOOTPRINT* parent = pad->GetParent();
wxPoint shapePos = pad->ShapePos();
wxPoint halfSize( pad->GetSize().x / 2, pad->GetSize().y / 2 );
if( !m_isFootprintEditor )
break;
if( parent && ( parent->IsLocked() || parent->PadsLocked() ) )
if( !m_isFootprintEditor || pad->IsLocked() )
break;
switch( pad->GetShape() )
@ -1622,7 +1618,7 @@ void POINT_EDITOR::updatePoints()
case PCB_PAD_T:
{
const PAD* pad = static_cast<const PAD*>( item );
bool locked = pad->GetParent() && pad->GetParent()->PadsLocked();
bool locked = pad->GetParent() && pad->IsLocked();
wxPoint shapePos = pad->ShapePos();
wxPoint halfSize( pad->GetSize().x / 2, pad->GetSize().y / 2 );