From ab55684f0b7ee6078cdcf8225ff5347cc1709aec Mon Sep 17 00:00:00 2001 From: John Beard Date: Sun, 16 Jul 2023 15:37:12 +0100 Subject: [PATCH] ADDED: Add step parameter to footprint pad renumbering Also includes persisting settings for next dialog invocation and use the TransferDataFromWindow function rather than per-field accessor methods. Fixes: https://gitlab.com/kicad/code/kicad/-/issues/10651 --- pcbnew/dialogs/dialog_enum_pads.cpp | 28 ++++-- pcbnew/dialogs/dialog_enum_pads.h | 40 +++++++- pcbnew/dialogs/dialog_enum_pads_base.cpp | 9 +- pcbnew/dialogs/dialog_enum_pads_base.fbp | 123 +++++++++++++++++++++++ pcbnew/dialogs/dialog_enum_pads_base.h | 4 +- pcbnew/tools/pad_tool.cpp | 65 +++++++++--- 6 files changed, 238 insertions(+), 31 deletions(-) diff --git a/pcbnew/dialogs/dialog_enum_pads.cpp b/pcbnew/dialogs/dialog_enum_pads.cpp index d7e86bb483..0323f0c25d 100644 --- a/pcbnew/dialogs/dialog_enum_pads.cpp +++ b/pcbnew/dialogs/dialog_enum_pads.cpp @@ -3,6 +3,7 @@ * * Copyright (C) 2014 CERN * @author Maciej Suminski + * Copyright (C) 2014-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -24,22 +25,27 @@ #include "dialog_enum_pads.h" -DIALOG_ENUM_PADS::DIALOG_ENUM_PADS( wxWindow* aParent ) : - DIALOG_ENUM_PADS_BASE( aParent ) +DIALOG_ENUM_PADS::DIALOG_ENUM_PADS( wxWindow* aParent, + SEQUENTIAL_PAD_ENUMERATION_PARAMS& aParams ) : + DIALOG_ENUM_PADS_BASE( aParent ), + m_params( aParams ) { + // Transfer data from the params to the dialog + m_padStartNum->SetValue( m_params.m_start_number ); + m_padNumStep->SetValue( m_params.m_step ); + m_padPrefix->SetValue( m_params.m_prefix.value_or( "" ) ); // Now all widgets have the size fixed, call FinishDialogSettings finishDialogSettings(); } - -int DIALOG_ENUM_PADS::GetStartNumber() const +bool DIALOG_ENUM_PADS::TransferDataFromWindow() { - return m_padStartNum->GetValue(); -} + // Transfer data from the dialog to the params + m_params.m_start_number = m_padStartNum->GetValue(); + m_params.m_step = m_padNumStep->GetValue(); + m_params.m_prefix = m_padPrefix->GetValue(); - -wxString DIALOG_ENUM_PADS::GetPrefix() const -{ - return m_padPrefix->GetValue(); -} + // No other validation implemented + return true; +} \ No newline at end of file diff --git a/pcbnew/dialogs/dialog_enum_pads.h b/pcbnew/dialogs/dialog_enum_pads.h index 9c4fc36584..702c71c2ff 100644 --- a/pcbnew/dialogs/dialog_enum_pads.h +++ b/pcbnew/dialogs/dialog_enum_pads.h @@ -33,16 +33,46 @@ #include "dialog_enum_pads_base.h" +#include + +/** + * @brief Parameters for sequential pad numbering + * + * This is used by, say, the pad enumeration dialog to pass parameters to the + * pad enumeration tool for the sequential numbering mode. + */ +struct SEQUENTIAL_PAD_ENUMERATION_PARAMS +{ + SEQUENTIAL_PAD_ENUMERATION_PARAMS() : m_start_number( 1 ), m_step( 1 ) {} + + /// @brief Starting number for pad names + int m_start_number; + + /// @brief Step between pad numbers + int m_step; + + /// @brief Optional prefix for pad names + std::optional m_prefix; +}; + + +/** + * @brief Dialog for enumerating pads + * + * This dialog allows the user to set parameters for the sequential + * pad re-numbering tool. + */ class DIALOG_ENUM_PADS : public DIALOG_ENUM_PADS_BASE { public: - DIALOG_ENUM_PADS( wxWindow* parent ); + DIALOG_ENUM_PADS( wxWindow* aParent, SEQUENTIAL_PAD_ENUMERATION_PARAMS& aParams ); - ///< Return the starting number that is going to be used for the first enumerated pad. - int GetStartNumber() const; +private: + /// @brief Transfer data from the dialog to the params + bool TransferDataFromWindow() override; - ///< Return common prefix for all enumerated pads. - wxString GetPrefix() const; + /// @brief The parameters that will be updated when the dialog is closed with OK + SEQUENTIAL_PAD_ENUMERATION_PARAMS& m_params; }; #endif // __dialog_enum_pads__ diff --git a/pcbnew/dialogs/dialog_enum_pads_base.cpp b/pcbnew/dialogs/dialog_enum_pads_base.cpp index 02bcf6242b..77b42f8ce4 100644 --- a/pcbnew/dialogs/dialog_enum_pads_base.cpp +++ b/pcbnew/dialogs/dialog_enum_pads_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -51,6 +51,13 @@ DIALOG_ENUM_PADS_BASE::DIALOG_ENUM_PADS_BASE( wxWindow* parent, wxWindowID id, c m_padStartNum = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 999, 1 ); fgSizer->Add( m_padStartNum, 0, wxALL|wxEXPAND, 5 ); + m_lblPadNumStep = new wxStaticText( this, wxID_ANY, _("Numbering step:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_lblPadNumStep->Wrap( -1 ); + fgSizer->Add( m_lblPadNumStep, 0, wxALL, 5 ); + + m_padNumStep = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 999, 1 ); + fgSizer->Add( m_padNumStep, 0, wxALL|wxEXPAND, 5 ); + bMainSizer->Add( fgSizer, 1, wxEXPAND|wxALL, 5 ); diff --git a/pcbnew/dialogs/dialog_enum_pads_base.fbp b/pcbnew/dialogs/dialog_enum_pads_base.fbp index 92f9303b44..8e5b9a3560 100644 --- a/pcbnew/dialogs/dialog_enum_pads_base.fbp +++ b/pcbnew/dialogs/dialog_enum_pads_base.fbp @@ -396,6 +396,129 @@ + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Numbering step: + 0 + + 0 + + + 0 + + 1 + m_lblPadNumStep + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + 1 + 999 + + 0 + + 0 + + 0 + + 1 + m_padNumStep + 1 + + + protected + 1 + + Resizable + 1 + + wxSP_ARROW_KEYS + + 0 + + + + + + + diff --git a/pcbnew/dialogs/dialog_enum_pads_base.h b/pcbnew/dialogs/dialog_enum_pads_base.h index 7ec867b6a8..d2cf41b943 100644 --- a/pcbnew/dialogs/dialog_enum_pads_base.h +++ b/pcbnew/dialogs/dialog_enum_pads_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -39,6 +39,8 @@ class DIALOG_ENUM_PADS_BASE : public DIALOG_SHIM wxTextCtrl* m_padPrefix; wxStaticText* m_lblPadStartNum; wxSpinCtrl* m_padStartNum; + wxStaticText* m_lblPadNumStep; + wxSpinCtrl* m_padNumStep; wxStdDialogButtonSizer* m_stdButtons; wxButton* m_stdButtonsOK; wxButton* m_stdButtonsCancel; diff --git a/pcbnew/tools/pad_tool.cpp b/pcbnew/tools/pad_tool.cpp index 21466c948d..3d915bda45 100644 --- a/pcbnew/tools/pad_tool.cpp +++ b/pcbnew/tools/pad_tool.cpp @@ -274,6 +274,27 @@ int PAD_TOOL::pushPadSettings( const TOOL_EVENT& aEvent ) } +/** + * @brief Prompts the user for parameters for sequential pad numbering + * + * @param aFrame The parent window for the dialog + * @return The parameters, or nullopt if no parameters, e.g. user cancelled the dialog +*/ +static std::optional +GetSequentialPadNumberingParams( wxWindow* aFrame ) +{ + // Persistent settings for the pad enumeration dialog. + static SEQUENTIAL_PAD_ENUMERATION_PARAMS s_lastUsedParams; + + DIALOG_ENUM_PADS settingsDlg( aFrame, s_lastUsedParams ); + + if( settingsDlg.ShowModal() != wxID_OK ) + return std::nullopt; + + return s_lastUsedParams; +} + + int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent ) { if( !m_isFootprintEditor ) @@ -290,14 +311,16 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent ) guide.SetIgnoreModulesVals( true ); guide.SetIgnoreModulesRefs( true ); - DIALOG_ENUM_PADS settingsDlg( frame() ); + const std::optional params = + GetSequentialPadNumberingParams( frame() ); - if( settingsDlg.ShowModal() != wxID_OK ) + // Cancelled or otherwise failed to get any useful parameters + if( !params ) return 0; - int seqPadNum = settingsDlg.GetStartNumber(); - wxString padPrefix = settingsDlg.GetPrefix(); - std::deque storedPadNumbers; + int seqPadNum = params->m_start_number; + + std::deque storedPadNumbers; std::map> oldNumbers; m_toolMgr->RunAction( PCB_ACTIONS::selectionClear ); @@ -333,8 +356,22 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent ) setCursor(); STATUS_TEXT_POPUP statusPopup( frame() ); - wxString msg = _( "Click on pad %s%d\nPress to cancel all; double-click to finish" ); - statusPopup.SetText( wxString::Format( msg, padPrefix, seqPadNum ) ); + + // Callable lambda to construct the pad number string for the given value + const auto constructPadNumber = [&]( int aValue ) + { + return wxString::Format( wxT( "%s%d" ), params->m_prefix.value_or( "" ), aValue ); + }; + + // Callable lambda to set the popup text for the given pad value + const auto setPopupTextForValue = [&]( int aValue ) + { + const wxString msg = + _( "Click on pad %s\nPress to cancel all; double-click to finish" ); + statusPopup.SetText( wxString::Format( msg, constructPadNumber( aValue ) ) ); + }; + + setPopupTextForValue( seqPadNum ); statusPopup.Popup(); statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) ); canvas()->SetStatusPopup( statusPopup.GetPanel() ); @@ -409,9 +446,12 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent ) storedPadNumbers.pop_front(); } else - newval = seqPadNum++; + { + newval = seqPadNum; + seqPadNum += params->m_step; + } - wxString newNumber = wxString::Format( wxT( "%s%d" ), padPrefix, newval ); + const wxString newNumber = constructPadNumber( newval ); oldNumbers[newNumber] = { newval, pad->GetNumber() }; pad->SetNumber( newNumber ); SetLastPadNumber( newNumber ); @@ -424,7 +464,7 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent ) else newval = seqPadNum; - statusPopup.SetText( wxString::Format( msg, padPrefix, newval ) ); + setPopupTextForValue( newval ); } // ... or restore the old name if it was enumerated and clicked again @@ -440,9 +480,8 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent ) SetLastPadNumber( it->second.second ); oldNumbers.erase( it ); - int newval = storedPadNumbers.front(); - - statusPopup.SetText( wxString::Format( msg, padPrefix, newval ) ); + const int newval = storedPadNumbers.front(); + setPopupTextForValue( newval ); } pad->ClearSelected();