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
This commit is contained in:
John Beard 2023-07-16 15:37:12 +01:00
parent a16033f624
commit ab55684f0b
6 changed files with 238 additions and 31 deletions

View File

@ -3,6 +3,7 @@
*
* Copyright (C) 2014 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
* 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;
}

View File

@ -33,16 +33,46 @@
#include "dialog_enum_pads_base.h"
#include <optional>
/**
* @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<wxString> 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__

View File

@ -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 );

View File

@ -396,6 +396,129 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticText" 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="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">Numbering step:</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_lblPadNumStep</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"></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="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxSpinCtrl" 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="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="initial">1</property>
<property name="max">999</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min">0</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_padNumStep</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">wxSP_ARROW_KEYS</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="value"></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="1">

View File

@ -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;

View File

@ -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<SEQUENTIAL_PAD_ENUMERATION_PARAMS>
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<SEQUENTIAL_PAD_ENUMERATION_PARAMS> 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<int> storedPadNumbers;
int seqPadNum = params->m_start_number;
std::deque<int> storedPadNumbers;
std::map<wxString, std::pair<int, wxString>> 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 <esc> 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 <esc> 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();