Array creator tool: Add option to assign unique reference designators

ADDED: Option to assign unique reference designators to footprints
created with the array tool [pcbnew]

CHANGED: Array creator dialog no longer displays pad numbering properties
when in the board editor. [pcbnew]

Fixes https://gitlab.com/kicad/code/kicad/-/issues/2354
This commit is contained in:
Roberto Fernandez Bautista 2021-10-24 20:59:19 +01:00
parent 36d11f745e
commit a79a221257
13 changed files with 3886 additions and 3400 deletions

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 KiCad Developers, see AUTHORS.TXT for contributors.
* Copyright (C) 2019-2021 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
@ -27,6 +27,7 @@
#include <wx/choice.h>
#include <wx/notebook.h>
#include <wx/radiobox.h>
#include <wx/radiobut.h>
#include <wx/textctrl.h>
#include <widgets/unit_binder.h>
@ -38,6 +39,12 @@ void WIDGET_SAVE_RESTORE::Add( wxRadioBox& ctrl, long& dest )
}
void WIDGET_SAVE_RESTORE::Add( wxRadioButton& ctrl, bool& dest )
{
m_ctrls.emplace_back( WIDGET_CTRL_TYPE_T::RADIOBUTTON, ctrl, dest );
}
void WIDGET_SAVE_RESTORE::Add( wxCheckBox& ctrl, bool& dest )
{
m_ctrls.emplace_back( WIDGET_CTRL_TYPE_T::CHECKBOX, ctrl, dest );
@ -90,6 +97,10 @@ void WIDGET_SAVE_RESTORE::ReadConfigFromControls()
*ctrl.m_dest.m_bool = ctrl.m_control.m_checkbox->GetValue();
break;
case WIDGET_CTRL_TYPE_T::RADIOBUTTON:
*ctrl.m_dest.m_bool = ctrl.m_control.m_radiobutton->GetValue();
break;
case WIDGET_CTRL_TYPE_T::TEXT:
*ctrl.m_dest.m_str = ctrl.m_control.m_textctrl->GetValue();
break;
@ -137,6 +148,10 @@ void WIDGET_SAVE_RESTORE::RestoreConfigToControls()
ctrl.m_control.m_checkbox->SetValue( *ctrl.m_dest.m_bool );
break;
case WIDGET_CTRL_TYPE_T::RADIOBUTTON:
ctrl.m_control.m_radiobutton->SetValue( *ctrl.m_dest.m_bool );
break;
case WIDGET_CTRL_TYPE_T::TEXT:
ctrl.m_control.m_textctrl->SetValue( *ctrl.m_dest.m_str );
break;

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2021 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
@ -92,6 +92,20 @@ public:
m_shouldNumber = aShouldNumber;
}
/*!
* @return are the footprints in this array reannotated to be unique (true), or do they
* keep the original annotation (false)?
*/
bool ShouldReannotateFootprints() const
{
return m_reannotateFootprints;
}
void SetSShouldReannotateFootprints( bool aShouldReannotate )
{
m_reannotateFootprints = aShouldReannotate;
}
/*!
* @return is the numbering is enabled and should start at a point
* specified in these options or is it implicit according to the calling
@ -114,6 +128,9 @@ protected:
/// True if this array numbers the new items
bool m_shouldNumber;
/// True if this array will rename any footprints to be unique
bool m_reannotateFootprints;
/// True if this array's number starts from the preset point
/// False if the array numbering starts from some externally provided point
bool m_numberingStartIsSpecified;

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 KiCad Developers, see AUTHORS.TXT for contributors.
* Copyright (C) 2019-2021 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
@ -30,6 +30,7 @@ class wxCheckBox;
class wxChoice;
class wxNotebook;
class wxRadioBox;
class wxRadioButton;
class wxString;
class wxTextCtrl;
@ -48,6 +49,11 @@ public:
*/
void Add( wxRadioBox& ctrl, long& dest );
/**
* Bind a radio button to a binary choice
*/
void Add( wxRadioButton& ctrl, bool& dest );
/**
* Bind a check box to a binary choice
*/
@ -111,6 +117,7 @@ private:
TEXT_DOUBLE,
UNIT_BINDER,
CHECKBOX,
RADIOBUTTON,
RADIOBOX,
CHOICE,
TAB
@ -122,6 +129,11 @@ private:
{
}
CONTROL( wxRadioButton* aCtrl ) :
m_radiobutton( aCtrl )
{
}
CONTROL( wxChoice* aCtrl ) :
m_choice( aCtrl )
{
@ -147,12 +159,13 @@ private:
{
}
wxCheckBox* m_checkbox;
wxChoice* m_choice;
wxNotebook* m_notebook;
wxRadioBox* m_radiobox;
wxTextCtrl* m_textctrl;
UNIT_BINDER* m_unit_binder;
wxCheckBox* m_checkbox;
wxChoice* m_choice;
wxNotebook* m_notebook;
wxRadioBox* m_radiobox;
wxRadioButton* m_radiobutton;
wxTextCtrl* m_textctrl;
UNIT_BINDER* m_unit_binder;
};
union DATA {

View File

@ -29,6 +29,9 @@
#include <pcb_group.h>
#include <pad.h>
#include <dialogs/dialog_create_array.h>
#include <tool/tool_manager.h>
#include <tools/board_reannotate_tool.h>
#include <tools/pcb_selection_tool.h>
/**
* Transform a #BOARD_ITEM from the given #ARRAY_OPTIONS and an index into the array.
@ -70,19 +73,23 @@ void ARRAY_CREATOR::Invoke()
ARRAY_PAD_NUMBER_PROVIDER pad_number_provider( fp, *array_opts );
for ( int i = 0; i < m_selection.Size(); ++i )
std::vector<EDA_ITEM*> all_added_items;
// The first item in list is the original item. We do not modify it
for( int ptN = 0; ptN < array_opts->GetArraySize(); ptN++ )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( m_selection[ i ] );
PCB_SELECTION items_for_this_block;
if( item->Type() == PCB_PAD_T && !m_isFootprintEditor )
for ( int i = 0; i < m_selection.Size(); ++i )
{
// If it is not the footprint editor, then duplicate the parent footprint instead
item = static_cast<FOOTPRINT*>( item )->GetParent();
}
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( m_selection[ i ] );
if( item->Type() == PCB_PAD_T && !m_isFootprintEditor )
{
// If it is not the footprint editor, then duplicate the parent footprint instead
item = static_cast<FOOTPRINT*>( item )->GetParent();
}
// The first item in list is the original item. We do not modify it
for( int ptN = 0; ptN < array_opts->GetArraySize(); ptN++ )
{
BOARD_ITEM* this_item = nullptr;
if( ptN == 0 )
@ -127,18 +134,13 @@ void ARRAY_CREATOR::Invoke()
break;
}
// PCB items keep the same numbering
// @TODO: renumber footprints if asked. This needs UI to enable.
// something like this, but needs a "block offset" to prevent
// multiple selections overlapping.
// if( this_item->Type() == PCB_FOOTPRINT_T )
// static_cast<FOOTPRINT&>( *new_item ).IncrementReference( ptN );
// @TODO: we should merge zones. This is a bit tricky, because
// the undo command needs saving old area, if it is merged.
}
// Add new items to selection (footprints in the selection will be reannotated)
items_for_this_block.Add( this_item );
if( this_item )
{
// Because aItem is/can be created from a selected item, and inherits from
@ -192,7 +194,19 @@ void ARRAY_CREATOR::Invoke()
}
}
}
if( !m_isFootprintEditor && array_opts->ShouldReannotateFootprints() )
{
m_toolMgr->GetTool<BOARD_REANNOTATE_TOOL>()->ReannotateDuplicates( items_for_this_block,
all_added_items );
}
for( EDA_ITEM* item : items_for_this_block )
all_added_items.push_back( item );
}
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &all_added_items );
commit.Push( _( "Create an array" ) );
}

View File

@ -32,6 +32,8 @@
#include <board_item.h>
#include <tools/pcb_selection.h>
class TOOL_MANAGER;
/*!
* Class that performs array creation by producing a dialog to gather parameters and then
* creating and laying out the items.
@ -40,10 +42,11 @@ class ARRAY_CREATOR
{
public:
ARRAY_CREATOR( PCB_BASE_FRAME& aParent, bool aIsFootprintEditor,
const PCB_SELECTION& aSelection ) :
const PCB_SELECTION& aSelection, TOOL_MANAGER* aToolManager ) :
m_parent( aParent ),
m_isFootprintEditor( aIsFootprintEditor ),
m_selection( aSelection )
m_selection( aSelection ),
m_toolMgr( aToolManager )
{}
virtual ~ARRAY_CREATOR() {}
@ -56,7 +59,8 @@ public:
private:
PCB_BASE_FRAME& m_parent;
bool m_isFootprintEditor;
const PCB_SELECTION& m_selection;
const PCB_SELECTION m_selection;
TOOL_MANAGER* m_toolMgr;
};
#endif /* ARRAY_CREATOR_H_ */

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2021 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
@ -70,7 +70,9 @@ struct CREATE_ARRAY_DIALOG_ENTRIES
m_CircNumberingOffset( "1" ),
m_CircNumberingStep( 1 ),
m_CircRotatationStep( false ),
m_ArrayTypeTab( 0 ) // start on grid view
m_ArrayTypeTab( 0 ), // start on grid view
m_FootprintKeepAnnotations( false ),
m_FootprintReannotate( true ) // Assign unique by default
{
}
@ -106,6 +108,8 @@ struct CREATE_ARRAY_DIALOG_ENTRIES
long m_CircNumberingStep;
bool m_CircRotatationStep;
long m_ArrayTypeTab;
bool m_FootprintKeepAnnotations;
bool m_FootprintReannotate;
};
// Persistent options settings
@ -145,11 +149,11 @@ static const std::vector<NUMBERING_LIST_DATA> numberingTypeData {
DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent,
std::unique_ptr<ARRAY_OPTIONS>& aSettings,
bool enableNumbering, const wxPoint& aOrigPos ) :
bool aIsFootprintEditor, const wxPoint& aOrigPos ) :
DIALOG_CREATE_ARRAY_BASE( aParent ),
m_settings( aSettings ),
m_originalItemPosition( aOrigPos ),
m_numberingEnabled( enableNumbering ),
m_isFootprintEditor( aIsFootprintEditor ),
m_hSpacing( aParent, m_labelDx, m_entryDx, m_unitLabelDx ),
m_vSpacing( aParent, m_labelDy, m_entryDy, m_unitLabelDy ),
m_hOffset( aParent, m_labelOffsetX, m_entryOffsetX, m_unitLabelOffsetX ),
@ -224,6 +228,9 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent,
m_cfg_persister.Add( *m_gridTypeNotebook, s_arrayOptions.m_ArrayTypeTab );
m_cfg_persister.Add( *m_radioBtnKeepRefs, s_arrayOptions.m_FootprintKeepAnnotations );
m_cfg_persister.Add( *m_radioBtnUniqueRefs, s_arrayOptions.m_FootprintReannotate );
m_cfg_persister.RestoreConfigToControls();
// Run the callbacks once to process the dialog contents
@ -342,9 +349,9 @@ bool DIALOG_CREATE_ARRAY::TransferDataFromWindow()
newGrid->m_horizontalThenVertical = m_radioBoxGridNumberingAxis->GetSelection() == 0;
newGrid->m_reverseNumberingAlternate = m_checkBoxGridReverseNumbering->GetValue();
newGrid->SetShouldNumber( m_numberingEnabled );
newGrid->SetShouldNumber( m_isFootprintEditor );
if ( m_numberingEnabled )
if( m_isFootprintEditor )
{
newGrid->SetNumberingStartIsSpecified( m_rbGridStartNumberingOpt->GetSelection() == 1 );
@ -393,9 +400,9 @@ bool DIALOG_CREATE_ARRAY::TransferDataFromWindow()
ok = ok && validateLongEntry(*m_entryCircCount, newCirc->m_nPts, _("point count"), errors);
newCirc->m_rotateItems = m_entryRotateItemsCb->GetValue();
newCirc->SetShouldNumber( m_numberingEnabled );
newCirc->SetShouldNumber( m_isFootprintEditor );
if ( m_numberingEnabled )
if( m_isFootprintEditor )
{
newCirc->SetNumberingStartIsSpecified( m_rbCircStartNumberingOpt->GetSelection() == 1 );
@ -424,6 +431,8 @@ bool DIALOG_CREATE_ARRAY::TransferDataFromWindow()
// assign pointer and ownership here
m_settings = std::move( newSettings );
m_settings->SetSShouldReannotateFootprints( m_radioBtnUniqueRefs->GetValue() );
// persist the control state for next time
m_cfg_persister.ReadConfigFromControls();
@ -446,8 +455,13 @@ bool DIALOG_CREATE_ARRAY::TransferDataFromWindow()
void DIALOG_CREATE_ARRAY::setControlEnablement()
{
if ( m_numberingEnabled )
if( m_isFootprintEditor )
{
m_footprintReannotatePanel->Show( false );
m_gridPadNumberingPanel->Show( true );
m_circularPadNumberingPanel->Show( true );
// If we set the start number, we can set the other options,
// otherwise it's a hardcoded linear array
const bool use_set_start_grid = m_rbGridStartNumberingOpt->GetSelection() == 1;
@ -488,9 +502,15 @@ void DIALOG_CREATE_ARRAY::setControlEnablement()
m_entryGridPriNumberingOffset->Enable( false );
m_entryGridSecNumberingOffset->Enable( false );
m_gridPadNumberingPanel->Show( false );
// circular
m_rbCircStartNumberingOpt->Enable( false );
m_entryCircNumberingStart->Enable( false );
m_circularPadNumberingPanel->Show( false );
m_footprintReannotatePanel->Show( true );
}
}

View File

@ -71,8 +71,8 @@ private:
*/
const wxPoint m_originalItemPosition;
// some uses of arrays might not allow component renumbering
bool m_numberingEnabled;
// Decide whether to display pad numbering options or not
bool m_isFootprintEditor;
UNIT_BINDER m_hSpacing, m_vSpacing;
UNIT_BINDER m_hOffset, m_vOffset;

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.9.0 Jun 18 2020)
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -18,6 +18,9 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
wxBoxSizer* bMainSizer;
bMainSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizer7;
bSizer7 = new wxBoxSizer( wxHORIZONTAL );
m_gridTypeNotebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_gridPanel = new wxPanel( m_gridTypeNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer2;
@ -105,46 +108,49 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
bSizer2->Add( 0, 0, 0, wxALL|wxEXPAND, 10 );
m_gridPadNumberingPanel = new wxPanel( m_gridPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_gridPadNumberingPanel->Hide();
m_gridPadNumberingSizer = new wxBoxSizer( wxVERTICAL );
wxString m_radioBoxGridNumberingAxisChoices[] = { _("Horizontal, then vertical"), _("Vertical, then horizontal") };
int m_radioBoxGridNumberingAxisNChoices = sizeof( m_radioBoxGridNumberingAxisChoices ) / sizeof( wxString );
m_radioBoxGridNumberingAxis = new wxRadioBox( m_gridPanel, wxID_ANY, _("Numbering Direction"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingAxisNChoices, m_radioBoxGridNumberingAxisChoices, 1, wxRA_SPECIFY_COLS );
m_radioBoxGridNumberingAxis = new wxRadioBox( m_gridPadNumberingPanel, wxID_ANY, _("Numbering Direction"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingAxisNChoices, m_radioBoxGridNumberingAxisChoices, 1, wxRA_SPECIFY_COLS );
m_radioBoxGridNumberingAxis->SetSelection( 0 );
m_gridPadNumberingSizer->Add( m_radioBoxGridNumberingAxis, 0, wxALL|wxEXPAND, 5 );
m_checkBoxGridReverseNumbering = new wxCheckBox( m_gridPanel, wxID_ANY, _("Reverse numbering on alternate rows/columns"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkBoxGridReverseNumbering = new wxCheckBox( m_gridPadNumberingPanel, wxID_ANY, _("Reverse numbering on alternate rows/columns"), wxDefaultPosition, wxDefaultSize, 0 );
m_gridPadNumberingSizer->Add( m_checkBoxGridReverseNumbering, 0, wxALL, 5 );
wxString m_rbGridStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") };
int m_rbGridStartNumberingOptNChoices = sizeof( m_rbGridStartNumberingOptChoices ) / sizeof( wxString );
m_rbGridStartNumberingOpt = new wxRadioBox( m_gridPanel, wxID_ANY, _("Initial Pad Number"), wxDefaultPosition, wxDefaultSize, m_rbGridStartNumberingOptNChoices, m_rbGridStartNumberingOptChoices, 1, wxRA_SPECIFY_COLS );
m_rbGridStartNumberingOpt = new wxRadioBox( m_gridPadNumberingPanel, wxID_ANY, _("Initial Pad Number"), wxDefaultPosition, wxDefaultSize, m_rbGridStartNumberingOptNChoices, m_rbGridStartNumberingOptChoices, 1, wxRA_SPECIFY_COLS );
m_rbGridStartNumberingOpt->SetSelection( 1 );
m_gridPadNumberingSizer->Add( m_rbGridStartNumberingOpt, 0, wxALL|wxEXPAND, 5 );
wxString m_radioBoxGridNumberingSchemeChoices[] = { _("Continuous (1, 2, 3...)"), _("Coordinate (A1, A2, ... B1, ...)") };
int m_radioBoxGridNumberingSchemeNChoices = sizeof( m_radioBoxGridNumberingSchemeChoices ) / sizeof( wxString );
m_radioBoxGridNumberingScheme = new wxRadioBox( m_gridPanel, wxID_ANY, _("Pad Numbering Scheme"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingSchemeNChoices, m_radioBoxGridNumberingSchemeChoices, 1, wxRA_SPECIFY_COLS );
m_radioBoxGridNumberingScheme = new wxRadioBox( m_gridPadNumberingPanel, wxID_ANY, _("Pad Numbering Scheme"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingSchemeNChoices, m_radioBoxGridNumberingSchemeChoices, 1, wxRA_SPECIFY_COLS );
m_radioBoxGridNumberingScheme->SetSelection( 1 );
m_gridPadNumberingSizer->Add( m_radioBoxGridNumberingScheme, 0, wxALL|wxEXPAND, 5 );
m_labelPriAxisNumbering = new wxStaticText( m_gridPanel, wxID_ANY, _("Primary axis numbering:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelPriAxisNumbering = new wxStaticText( m_gridPadNumberingPanel, wxID_ANY, _("Primary axis numbering:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelPriAxisNumbering->Wrap( -1 );
m_gridPadNumberingSizer->Add( m_labelPriAxisNumbering, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
wxArrayString m_choicePriAxisNumberingChoices;
m_choicePriAxisNumbering = new wxChoice( m_gridPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choicePriAxisNumberingChoices, 0 );
m_choicePriAxisNumbering = new wxChoice( m_gridPadNumberingPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choicePriAxisNumberingChoices, 0 );
m_choicePriAxisNumbering->SetSelection( 0 );
m_gridPadNumberingSizer->Add( m_choicePriAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_labelSecAxisNumbering = new wxStaticText( m_gridPanel, wxID_ANY, _("Secondary axis numbering:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelSecAxisNumbering = new wxStaticText( m_gridPadNumberingPanel, wxID_ANY, _("Secondary axis numbering:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelSecAxisNumbering->Wrap( -1 );
m_labelSecAxisNumbering->Enable( false );
m_gridPadNumberingSizer->Add( m_labelSecAxisNumbering, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
wxArrayString m_choiceSecAxisNumberingChoices;
m_choiceSecAxisNumbering = new wxChoice( m_gridPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceSecAxisNumberingChoices, 0 );
m_choiceSecAxisNumbering = new wxChoice( m_gridPadNumberingPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceSecAxisNumberingChoices, 0 );
m_choiceSecAxisNumbering->SetSelection( 0 );
m_choiceSecAxisNumbering->Enable( false );
@ -156,30 +162,30 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_labelGridNumberingOffset = new wxStaticText( m_gridPanel, wxID_ANY, _("Pad numbering start:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelGridNumberingOffset = new wxStaticText( m_gridPadNumberingPanel, wxID_ANY, _("Pad numbering start:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelGridNumberingOffset->Wrap( -1 );
fgSizer1->Add( m_labelGridNumberingOffset, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_entryGridPriNumberingOffset = new wxTextCtrl( m_gridPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
m_entryGridPriNumberingOffset = new wxTextCtrl( m_gridPadNumberingPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
m_entryGridPriNumberingOffset->SetMinSize( wxSize( 72,-1 ) );
fgSizer1->Add( m_entryGridPriNumberingOffset, 0, wxALL, 5 );
m_entryGridSecNumberingOffset = new wxTextCtrl( m_gridPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
m_entryGridSecNumberingOffset = new wxTextCtrl( m_gridPadNumberingPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
m_entryGridSecNumberingOffset->SetMinSize( wxSize( 72,-1 ) );
fgSizer1->Add( m_entryGridSecNumberingOffset, 0, wxALL, 5 );
m_labelGridNumberingStep = new wxStaticText( m_gridPanel, wxID_ANY, _("Pad numbering skip:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelGridNumberingStep = new wxStaticText( m_gridPadNumberingPanel, wxID_ANY, _("Pad numbering skip:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelGridNumberingStep->Wrap( -1 );
fgSizer1->Add( m_labelGridNumberingStep, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_entryGridPriNumberingStep = new wxTextCtrl( m_gridPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
m_entryGridPriNumberingStep = new wxTextCtrl( m_gridPadNumberingPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
m_entryGridPriNumberingStep->SetMinSize( wxSize( 72,-1 ) );
fgSizer1->Add( m_entryGridPriNumberingStep, 0, wxALL, 5 );
m_entryGridSecNumberingStep = new wxTextCtrl( m_gridPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
m_entryGridSecNumberingStep = new wxTextCtrl( m_gridPadNumberingPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
m_entryGridSecNumberingStep->SetMinSize( wxSize( 72,-1 ) );
fgSizer1->Add( m_entryGridSecNumberingStep, 0, wxALL, 5 );
@ -188,13 +194,16 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
m_gridPadNumberingSizer->Add( fgSizer1, 1, wxEXPAND, 5 );
bSizer2->Add( m_gridPadNumberingSizer, 0, wxALL|wxEXPAND, 5 );
m_gridPadNumberingPanel->SetSizer( m_gridPadNumberingSizer );
m_gridPadNumberingPanel->Layout();
m_gridPadNumberingSizer->Fit( m_gridPadNumberingPanel );
bSizer2->Add( m_gridPadNumberingPanel, 1, wxEXPAND | wxALL, 5 );
m_gridPanel->SetSizer( bSizer2 );
m_gridPanel->Layout();
bSizer2->Fit( m_gridPanel );
m_gridTypeNotebook->AddPage( m_gridPanel, _("Grid Array"), false );
m_gridTypeNotebook->AddPage( m_gridPanel, _("Grid Array"), true );
m_circularPanel = new wxPanel( m_gridTypeNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer4;
bSizer4 = new wxBoxSizer( wxHORIZONTAL );
@ -276,7 +285,10 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
bSizer4->Add( 0, 0, 0, wxALL|wxEXPAND, 10 );
m_circPadNumberingSizer = new wxStaticBoxSizer( new wxStaticBox( m_circularPanel, wxID_ANY, _("Numbering Options") ), wxVERTICAL );
m_circularPadNumberingPanel = new wxPanel( m_circularPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_circularPadNumberingPanel->Hide();
m_circPadNumberingSizer = new wxStaticBoxSizer( new wxStaticBox( m_circularPadNumberingPanel, wxID_ANY, _("Numbering Options") ), wxVERTICAL );
wxString m_rbCircStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") };
int m_rbCircStartNumberingOptNChoices = sizeof( m_rbCircStartNumberingOptChoices ) / sizeof( wxString );
@ -317,15 +329,46 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
m_circPadNumberingSizer->Add( fgSizer2, 1, wxEXPAND, 5 );
bSizer4->Add( m_circPadNumberingSizer, 0, wxEXPAND|wxALL, 5 );
m_circularPadNumberingPanel->SetSizer( m_circPadNumberingSizer );
m_circularPadNumberingPanel->Layout();
m_circPadNumberingSizer->Fit( m_circularPadNumberingPanel );
bSizer4->Add( m_circularPadNumberingPanel, 1, wxEXPAND | wxALL, 5 );
m_circularPanel->SetSizer( bSizer4 );
m_circularPanel->Layout();
bSizer4->Fit( m_circularPanel );
m_gridTypeNotebook->AddPage( m_circularPanel, _("Circular Array"), true );
m_gridTypeNotebook->AddPage( m_circularPanel, _("Circular Array"), false );
bMainSizer->Add( m_gridTypeNotebook, 1, wxEXPAND | wxALL, 5 );
bSizer7->Add( m_gridTypeNotebook, 1, wxEXPAND | wxALL, 5 );
m_footprintReannotatePanel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer8;
bSizer8 = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* sbSizerFootprintAnnotation;
sbSizerFootprintAnnotation = new wxStaticBoxSizer( new wxStaticBox( m_footprintReannotatePanel, wxID_ANY, _("Footprint Annotation") ), wxVERTICAL );
m_radioBtnKeepRefs = new wxRadioButton( sbSizerFootprintAnnotation->GetStaticBox(), wxID_ANY, _("Keep existing reference designators"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerFootprintAnnotation->Add( m_radioBtnKeepRefs, 0, wxALL, 5 );
m_radioBtnUniqueRefs = new wxRadioButton( sbSizerFootprintAnnotation->GetStaticBox(), wxID_ANY, _("Assign unique reference designators"), wxDefaultPosition, wxDefaultSize, 0 );
m_radioBtnUniqueRefs->SetValue( true );
m_radioBtnUniqueRefs->SetToolTip( _("This can conflict with reference designators in the schematic that have not yet been synchronized with the board.") );
sbSizerFootprintAnnotation->Add( m_radioBtnUniqueRefs, 0, wxALL, 5 );
bSizer8->Add( sbSizerFootprintAnnotation, 0, wxEXPAND, 5 );
m_footprintReannotatePanel->SetSizer( bSizer8 );
m_footprintReannotatePanel->Layout();
bSizer8->Fit( m_footprintReannotatePanel );
bSizer7->Add( m_footprintReannotatePanel, 0, wxEXPAND | wxALL, 5 );
bMainSizer->Add( bSizer7, 1, wxEXPAND, 5 );
m_stdButtons = new wxStdDialogButtonSizer();
m_stdButtonsOK = new wxButton( this, wxID_OK );

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.9.0 Jun 18 2020)
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -31,6 +31,7 @@ class TEXT_CTRL_EVAL;
#include <wx/icon.h>
#include <wx/statbox.h>
#include <wx/notebook.h>
#include <wx/radiobut.h>
#include <wx/button.h>
#include <wx/dialog.h>
@ -67,6 +68,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
wxStaticText* m_labelStagger;
TEXT_CTRL_EVAL* m_entryStagger;
wxRadioBox* m_radioBoxGridStaggerType;
wxPanel* m_gridPadNumberingPanel;
wxBoxSizer* m_gridPadNumberingSizer;
wxRadioBox* m_radioBoxGridNumberingAxis;
wxCheckBox* m_checkBoxGridReverseNumbering;
@ -99,6 +101,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
TEXT_CTRL_EVAL* m_entryCircCount;
wxStaticText* m_labelCircRotate;
wxCheckBox* m_entryRotateItemsCb;
wxPanel* m_circularPadNumberingPanel;
wxStaticBoxSizer* m_circPadNumberingSizer;
wxRadioBox* m_rbCircStartNumberingOpt;
wxStaticText* m_labelCircNumbering;
@ -107,11 +110,14 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
wxTextCtrl* m_entryCircNumberingStart;
wxStaticText* m_labelCircNumStep;
wxTextCtrl* m_entryCircNumberingStep;
wxPanel* m_footprintReannotatePanel;
wxRadioButton* m_radioBtnKeepRefs;
wxRadioButton* m_radioBtnUniqueRefs;
wxStdDialogButtonSizer* m_stdButtons;
wxButton* m_stdButtonsOK;
wxButton* m_stdButtonsCancel;
// Virtual event handlers, overide them in your derived class
// Virtual event handlers, override them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnParameterChanged( wxCommandEvent& event ) { event.Skip(); }
@ -119,6 +125,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
public:
DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID id = wxID_DIALOG_CREATE_ARRAY, const wxString& title = _("Create Array"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_CREATE_ARRAY_BASE();
};

View File

@ -68,17 +68,32 @@ int BOARD_REANNOTATE_TOOL::ReannotateDuplicatesInSelection()
if( selection.Empty() )
return 0;
// 1. Build list of designators on the board
return ReannotateDuplicates( selection, std::vector<EDA_ITEM*>() );
}
int BOARD_REANNOTATE_TOOL::ReannotateDuplicates( const PCB_SELECTION& aSelectionToReannotate,
const std::vector<EDA_ITEM*>& aAdditionalFootprints )
{
if( aSelectionToReannotate.Empty() )
return 0;
// 1. Build list of designators on the board & the additional footprints
FOOTPRINTS fpOnBoard = m_frame->GetBoard()->Footprints();
std::multimap<wxString, KIID> usedDesignatorsMap;
for( EDA_ITEM* item : aAdditionalFootprints )
{
if( item->Type() == PCB_FOOTPRINT_T )
fpOnBoard.push_back( static_cast<FOOTPRINT*>( item ) );
}
for( FOOTPRINT* fp : fpOnBoard )
usedDesignatorsMap.insert( { fp->GetReference(), fp->m_Uuid } );
// 2. Get a sorted list of footprints from the selection
FOOTPRINTS fpInSelection;
for( EDA_ITEM* item : selection )
for( EDA_ITEM* item : aSelectionToReannotate )
{
if( item->Type() == PCB_FOOTPRINT_T )
fpInSelection.push_back( static_cast<FOOTPRINT*>( item ) );
@ -90,7 +105,20 @@ int BOARD_REANNOTATE_TOOL::ReannotateDuplicatesInSelection()
int ii = StrNumCmp( aA->GetReference(), aB->GetReference(), true );
if( ii == 0 )
ii = aA->m_Uuid < aB->m_Uuid; // ensure a deterministic sort
{
// Sort by position: x, then y
if( aA->GetPosition().y == aB->GetPosition().y )
{
if( aA->GetPosition().x == aB->GetPosition().x )
return aA->m_Uuid < aB->m_Uuid; // ensure a deterministic sort
else
return aA->GetPosition().x < aB->GetPosition().x;
}
else
{
return aA->GetPosition().y > aB->GetPosition().y;
}
}
return ii < 0;
} );

View File

@ -40,8 +40,12 @@ public:
bool Init() override;
void Reset( RESET_REASON aReason ) override;
int ShowReannotateDialog( const TOOL_EVENT& aEvent );
int ReannotateDuplicatesInSelection();
int ReannotateDuplicates( const PCB_SELECTION& aSelectionToReannotate,
const std::vector<EDA_ITEM*>& aAdditionalFootprints );
private:
void setTransitions() override; //> Bind handlers to corresponding TOOL_ACTIONs

View File

@ -2276,7 +2276,7 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
// we have a selection to work on now, so start the tool process
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
ARRAY_CREATOR array_creator( *editFrame, m_isFootprintEditor, selection );
ARRAY_CREATOR array_creator( *editFrame, m_isFootprintEditor, selection, m_toolMgr );
array_creator.Invoke();
return 0;