diff --git a/pcbnew/footprint.cpp b/pcbnew/footprint.cpp index 456d6260c0..0725e1f343 100644 --- a/pcbnew/footprint.cpp +++ b/pcbnew/footprint.cpp @@ -650,6 +650,48 @@ double FOOTPRINT::GetArea( int aPadding ) const } +int FOOTPRINT::GetLikelyAttribute() const +{ + int smd_count = 0; + int tht_count = 0; + + for( PAD* pad : m_pads ) + { + switch( pad->GetAttribute() ) + { + case PAD_ATTRIB::PTH: + tht_count++; + break; + case PAD_ATTRIB::SMD: + smd_count++; + break; + default: + break; + } + } + + if( tht_count > 0 ) + return FP_THROUGH_HOLE; + + if( smd_count > 0 ) + return FP_SMD; + + return 0; +} + + +wxString FOOTPRINT::GetTypeName() const +{ + if( ( m_attributes & FP_SMD ) == FP_SMD ) + return _( "SMD" ); + + if( ( m_attributes & FP_THROUGH_HOLE ) == FP_THROUGH_HOLE ) + return _( "Through hole" ); + + return _( "Other" ); +} + + EDA_RECT FOOTPRINT::GetFpPadsLocalBbox() const { EDA_RECT area; diff --git a/pcbnew/footprint.h b/pcbnew/footprint.h index 8ce689943d..5292f538fe 100644 --- a/pcbnew/footprint.h +++ b/pcbnew/footprint.h @@ -245,6 +245,13 @@ public: return GetKeywords().StartsWith( wxT( "net tie" ) ); } + /** + * Returns the most likely attribute based on pads + * Either FP_THROUGH_HOLE/FP_SMD/OTHER(0) + * @return 0/FP_SMD/FP_THROUGH_HOLE + */ + int GetLikelyAttribute() const; + void Move( const wxPoint& aMoveVector ) override; void Rotate( const wxPoint& aRotCentre, double aAngle ) override; @@ -531,6 +538,12 @@ public: */ wxString GetNextPadNumber( const wxString& aLastPadName ) const; + /** + * Get the type of footprint + * @return "SMD"/"Through hole"/"Other" based on attributes + */ + wxString GetTypeName() const; + double GetArea( int aPadding = 0 ) const; KIID GetLink() const { return m_link; } diff --git a/pcbnew/footprint_libraries_utils.cpp b/pcbnew/footprint_libraries_utils.cpp index 121622c924..3ff96c8580 100644 --- a/pcbnew/footprint_libraries_utils.cpp +++ b/pcbnew/footprint_libraries_utils.cpp @@ -784,6 +784,38 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprint( FOOTPRINT* aFootprint ) wxString libraryName = aFootprint->GetFPID().GetLibNickname(); wxString footprintName = aFootprint->GetFPID().GetLibItemName(); bool nameChanged = m_footprintNameWhenLoaded != footprintName; + int likelyAttr = aFootprint->GetLikelyAttribute(); + int setAttr = ( aFootprint->GetAttributes() & ( FP_SMD | FP_THROUGH_HOLE ) ); + + // This is only valid if the footprint doesn't have FP_SMD and FP_THROUGH_HOLE set + // Which is, unfortunately, possible in theory but not in the UI (I think) + if( likelyAttr != setAttr ) + { + wxString msg; + + if( likelyAttr == FP_THROUGH_HOLE ) + { + msg.Printf( _( "Your footprint has plated through hole pads but " + "its type is set to \"%s\"" ), aFootprint->GetTypeName() ); + } + else if( likelyAttr == FP_SMD ) + { + msg.Printf( _( "Your footprint has SMD pads but " + "its type is set to \"%s\"" ), aFootprint->GetTypeName() ); + } + else + { + msg.Printf( _( "Your footprint has no SMD or plated through hole pads but " + "its type is set to \"%s\"" ), aFootprint->GetTypeName() ); + } + + KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING ); + errorDlg.SetOKLabel( _( "Continue" ) ); + errorDlg.DoNotShowCheckbox( __FILE__, __LINE__ ); + + if( errorDlg.ShowModal() == wxID_CANCEL ) + return false; + } if( aFootprint->GetLink() != niluuid ) {