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. * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -27,6 +27,7 @@
#include <wx/choice.h> #include <wx/choice.h>
#include <wx/notebook.h> #include <wx/notebook.h>
#include <wx/radiobox.h> #include <wx/radiobox.h>
#include <wx/radiobut.h>
#include <wx/textctrl.h> #include <wx/textctrl.h>
#include <widgets/unit_binder.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 ) void WIDGET_SAVE_RESTORE::Add( wxCheckBox& ctrl, bool& dest )
{ {
m_ctrls.emplace_back( WIDGET_CTRL_TYPE_T::CHECKBOX, ctrl, 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(); *ctrl.m_dest.m_bool = ctrl.m_control.m_checkbox->GetValue();
break; 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: case WIDGET_CTRL_TYPE_T::TEXT:
*ctrl.m_dest.m_str = ctrl.m_control.m_textctrl->GetValue(); *ctrl.m_dest.m_str = ctrl.m_control.m_textctrl->GetValue();
break; break;
@ -137,6 +148,10 @@ void WIDGET_SAVE_RESTORE::RestoreConfigToControls()
ctrl.m_control.m_checkbox->SetValue( *ctrl.m_dest.m_bool ); ctrl.m_control.m_checkbox->SetValue( *ctrl.m_dest.m_bool );
break; 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: case WIDGET_CTRL_TYPE_T::TEXT:
ctrl.m_control.m_textctrl->SetValue( *ctrl.m_dest.m_str ); ctrl.m_control.m_textctrl->SetValue( *ctrl.m_dest.m_str );
break; break;

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -92,6 +92,20 @@ public:
m_shouldNumber = aShouldNumber; 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 * @return is the numbering is enabled and should start at a point
* specified in these options or is it implicit according to the calling * 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 /// True if this array numbers the new items
bool m_shouldNumber; 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 /// True if this array's number starts from the preset point
/// False if the array numbering starts from some externally provided point /// False if the array numbering starts from some externally provided point
bool m_numberingStartIsSpecified; bool m_numberingStartIsSpecified;

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -30,6 +30,7 @@ class wxCheckBox;
class wxChoice; class wxChoice;
class wxNotebook; class wxNotebook;
class wxRadioBox; class wxRadioBox;
class wxRadioButton;
class wxString; class wxString;
class wxTextCtrl; class wxTextCtrl;
@ -48,6 +49,11 @@ public:
*/ */
void Add( wxRadioBox& ctrl, long& dest ); 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 * Bind a check box to a binary choice
*/ */
@ -111,6 +117,7 @@ private:
TEXT_DOUBLE, TEXT_DOUBLE,
UNIT_BINDER, UNIT_BINDER,
CHECKBOX, CHECKBOX,
RADIOBUTTON,
RADIOBOX, RADIOBOX,
CHOICE, CHOICE,
TAB TAB
@ -122,6 +129,11 @@ private:
{ {
} }
CONTROL( wxRadioButton* aCtrl ) :
m_radiobutton( aCtrl )
{
}
CONTROL( wxChoice* aCtrl ) : CONTROL( wxChoice* aCtrl ) :
m_choice( aCtrl ) m_choice( aCtrl )
{ {
@ -147,12 +159,13 @@ private:
{ {
} }
wxCheckBox* m_checkbox; wxCheckBox* m_checkbox;
wxChoice* m_choice; wxChoice* m_choice;
wxNotebook* m_notebook; wxNotebook* m_notebook;
wxRadioBox* m_radiobox; wxRadioBox* m_radiobox;
wxTextCtrl* m_textctrl; wxRadioButton* m_radiobutton;
UNIT_BINDER* m_unit_binder; wxTextCtrl* m_textctrl;
UNIT_BINDER* m_unit_binder;
}; };
union DATA { union DATA {

View File

@ -29,6 +29,9 @@
#include <pcb_group.h> #include <pcb_group.h>
#include <pad.h> #include <pad.h>
#include <dialogs/dialog_create_array.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. * 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 ); 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 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( m_selection[ i ] );
item = static_cast<FOOTPRINT*>( item )->GetParent();
} 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; BOARD_ITEM* this_item = nullptr;
if( ptN == 0 ) if( ptN == 0 )
@ -127,18 +134,13 @@ void ARRAY_CREATOR::Invoke()
break; 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 // @TODO: we should merge zones. This is a bit tricky, because
// the undo command needs saving old area, if it is merged. // 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 ) if( this_item )
{ {
// Because aItem is/can be created from a selected item, and inherits from // 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" ) ); commit.Push( _( "Create an array" ) );
} }

View File

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

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -70,7 +70,9 @@ struct CREATE_ARRAY_DIALOG_ENTRIES
m_CircNumberingOffset( "1" ), m_CircNumberingOffset( "1" ),
m_CircNumberingStep( 1 ), m_CircNumberingStep( 1 ),
m_CircRotatationStep( false ), 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; long m_CircNumberingStep;
bool m_CircRotatationStep; bool m_CircRotatationStep;
long m_ArrayTypeTab; long m_ArrayTypeTab;
bool m_FootprintKeepAnnotations;
bool m_FootprintReannotate;
}; };
// Persistent options settings // 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, DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent,
std::unique_ptr<ARRAY_OPTIONS>& aSettings, std::unique_ptr<ARRAY_OPTIONS>& aSettings,
bool enableNumbering, const wxPoint& aOrigPos ) : bool aIsFootprintEditor, const wxPoint& aOrigPos ) :
DIALOG_CREATE_ARRAY_BASE( aParent ), DIALOG_CREATE_ARRAY_BASE( aParent ),
m_settings( aSettings ), m_settings( aSettings ),
m_originalItemPosition( aOrigPos ), m_originalItemPosition( aOrigPos ),
m_numberingEnabled( enableNumbering ), m_isFootprintEditor( aIsFootprintEditor ),
m_hSpacing( aParent, m_labelDx, m_entryDx, m_unitLabelDx ), m_hSpacing( aParent, m_labelDx, m_entryDx, m_unitLabelDx ),
m_vSpacing( aParent, m_labelDy, m_entryDy, m_unitLabelDy ), m_vSpacing( aParent, m_labelDy, m_entryDy, m_unitLabelDy ),
m_hOffset( aParent, m_labelOffsetX, m_entryOffsetX, m_unitLabelOffsetX ), 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_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(); m_cfg_persister.RestoreConfigToControls();
// Run the callbacks once to process the dialog contents // 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_horizontalThenVertical = m_radioBoxGridNumberingAxis->GetSelection() == 0;
newGrid->m_reverseNumberingAlternate = m_checkBoxGridReverseNumbering->GetValue(); 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 ); 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); ok = ok && validateLongEntry(*m_entryCircCount, newCirc->m_nPts, _("point count"), errors);
newCirc->m_rotateItems = m_entryRotateItemsCb->GetValue(); 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 ); newCirc->SetNumberingStartIsSpecified( m_rbCircStartNumberingOpt->GetSelection() == 1 );
@ -424,6 +431,8 @@ bool DIALOG_CREATE_ARRAY::TransferDataFromWindow()
// assign pointer and ownership here // assign pointer and ownership here
m_settings = std::move( newSettings ); m_settings = std::move( newSettings );
m_settings->SetSShouldReannotateFootprints( m_radioBtnUniqueRefs->GetValue() );
// persist the control state for next time // persist the control state for next time
m_cfg_persister.ReadConfigFromControls(); m_cfg_persister.ReadConfigFromControls();
@ -446,8 +455,13 @@ bool DIALOG_CREATE_ARRAY::TransferDataFromWindow()
void DIALOG_CREATE_ARRAY::setControlEnablement() 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, // If we set the start number, we can set the other options,
// otherwise it's a hardcoded linear array // otherwise it's a hardcoded linear array
const bool use_set_start_grid = m_rbGridStartNumberingOpt->GetSelection() == 1; const bool use_set_start_grid = m_rbGridStartNumberingOpt->GetSelection() == 1;
@ -488,9 +502,15 @@ void DIALOG_CREATE_ARRAY::setControlEnablement()
m_entryGridPriNumberingOffset->Enable( false ); m_entryGridPriNumberingOffset->Enable( false );
m_entryGridSecNumberingOffset->Enable( false ); m_entryGridSecNumberingOffset->Enable( false );
m_gridPadNumberingPanel->Show( false );
// circular // circular
m_rbCircStartNumberingOpt->Enable( false ); m_rbCircStartNumberingOpt->Enable( false );
m_entryCircNumberingStart->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; const wxPoint m_originalItemPosition;
// some uses of arrays might not allow component renumbering // Decide whether to display pad numbering options or not
bool m_numberingEnabled; bool m_isFootprintEditor;
UNIT_BINDER m_hSpacing, m_vSpacing; UNIT_BINDER m_hSpacing, m_vSpacing;
UNIT_BINDER m_hOffset, m_vOffset; 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/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // PLEASE DO *NOT* EDIT THIS FILE!
@ -18,6 +18,9 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
wxBoxSizer* bMainSizer; wxBoxSizer* bMainSizer;
bMainSizer = new wxBoxSizer( wxVERTICAL ); bMainSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizer7;
bSizer7 = new wxBoxSizer( wxHORIZONTAL );
m_gridTypeNotebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); m_gridTypeNotebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_gridPanel = new wxPanel( m_gridTypeNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); m_gridPanel = new wxPanel( m_gridTypeNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer2; 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 ); 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 ); m_gridPadNumberingSizer = new wxBoxSizer( wxVERTICAL );
wxString m_radioBoxGridNumberingAxisChoices[] = { _("Horizontal, then vertical"), _("Vertical, then horizontal") }; wxString m_radioBoxGridNumberingAxisChoices[] = { _("Horizontal, then vertical"), _("Vertical, then horizontal") };
int m_radioBoxGridNumberingAxisNChoices = sizeof( m_radioBoxGridNumberingAxisChoices ) / sizeof( wxString ); 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_radioBoxGridNumberingAxis->SetSelection( 0 );
m_gridPadNumberingSizer->Add( m_radioBoxGridNumberingAxis, 0, wxALL|wxEXPAND, 5 ); 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 ); m_gridPadNumberingSizer->Add( m_checkBoxGridReverseNumbering, 0, wxALL, 5 );
wxString m_rbGridStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") }; wxString m_rbGridStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") };
int m_rbGridStartNumberingOptNChoices = sizeof( m_rbGridStartNumberingOptChoices ) / sizeof( wxString ); 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_rbGridStartNumberingOpt->SetSelection( 1 );
m_gridPadNumberingSizer->Add( m_rbGridStartNumberingOpt, 0, wxALL|wxEXPAND, 5 ); m_gridPadNumberingSizer->Add( m_rbGridStartNumberingOpt, 0, wxALL|wxEXPAND, 5 );
wxString m_radioBoxGridNumberingSchemeChoices[] = { _("Continuous (1, 2, 3...)"), _("Coordinate (A1, A2, ... B1, ...)") }; wxString m_radioBoxGridNumberingSchemeChoices[] = { _("Continuous (1, 2, 3...)"), _("Coordinate (A1, A2, ... B1, ...)") };
int m_radioBoxGridNumberingSchemeNChoices = sizeof( m_radioBoxGridNumberingSchemeChoices ) / sizeof( wxString ); 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_radioBoxGridNumberingScheme->SetSelection( 1 );
m_gridPadNumberingSizer->Add( m_radioBoxGridNumberingScheme, 0, wxALL|wxEXPAND, 5 ); 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_labelPriAxisNumbering->Wrap( -1 );
m_gridPadNumberingSizer->Add( m_labelPriAxisNumbering, 0, wxLEFT|wxRIGHT|wxTOP, 5 ); m_gridPadNumberingSizer->Add( m_labelPriAxisNumbering, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
wxArrayString m_choicePriAxisNumberingChoices; 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_choicePriAxisNumbering->SetSelection( 0 );
m_gridPadNumberingSizer->Add( m_choicePriAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); 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->Wrap( -1 );
m_labelSecAxisNumbering->Enable( false ); m_labelSecAxisNumbering->Enable( false );
m_gridPadNumberingSizer->Add( m_labelSecAxisNumbering, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); m_gridPadNumberingSizer->Add( m_labelSecAxisNumbering, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
wxArrayString m_choiceSecAxisNumberingChoices; 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->SetSelection( 0 );
m_choiceSecAxisNumbering->Enable( false ); m_choiceSecAxisNumbering->Enable( false );
@ -156,30 +162,30 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
fgSizer1->SetFlexibleDirection( wxBOTH ); fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); 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 ); m_labelGridNumberingOffset->Wrap( -1 );
fgSizer1->Add( m_labelGridNumberingOffset, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); 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 ) ); m_entryGridPriNumberingOffset->SetMinSize( wxSize( 72,-1 ) );
fgSizer1->Add( m_entryGridPriNumberingOffset, 0, wxALL, 5 ); 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 ) ); m_entryGridSecNumberingOffset->SetMinSize( wxSize( 72,-1 ) );
fgSizer1->Add( m_entryGridSecNumberingOffset, 0, wxALL, 5 ); 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 ); m_labelGridNumberingStep->Wrap( -1 );
fgSizer1->Add( m_labelGridNumberingStep, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); 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 ) ); m_entryGridPriNumberingStep->SetMinSize( wxSize( 72,-1 ) );
fgSizer1->Add( m_entryGridPriNumberingStep, 0, wxALL, 5 ); 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 ) ); m_entryGridSecNumberingStep->SetMinSize( wxSize( 72,-1 ) );
fgSizer1->Add( m_entryGridSecNumberingStep, 0, wxALL, 5 ); 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 ); 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->SetSizer( bSizer2 );
m_gridPanel->Layout(); m_gridPanel->Layout();
bSizer2->Fit( m_gridPanel ); 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 ); m_circularPanel = new wxPanel( m_gridTypeNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer4; wxBoxSizer* bSizer4;
bSizer4 = new wxBoxSizer( wxHORIZONTAL ); 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 ); 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") }; wxString m_rbCircStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") };
int m_rbCircStartNumberingOptNChoices = sizeof( m_rbCircStartNumberingOptChoices ) / sizeof( wxString ); 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 ); 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->SetSizer( bSizer4 );
m_circularPanel->Layout(); m_circularPanel->Layout();
bSizer4->Fit( m_circularPanel ); 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_stdButtons = new wxStdDialogButtonSizer();
m_stdButtonsOK = new wxButton( this, wxID_OK ); 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/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // PLEASE DO *NOT* EDIT THIS FILE!
@ -31,6 +31,7 @@ class TEXT_CTRL_EVAL;
#include <wx/icon.h> #include <wx/icon.h>
#include <wx/statbox.h> #include <wx/statbox.h>
#include <wx/notebook.h> #include <wx/notebook.h>
#include <wx/radiobut.h>
#include <wx/button.h> #include <wx/button.h>
#include <wx/dialog.h> #include <wx/dialog.h>
@ -67,6 +68,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
wxStaticText* m_labelStagger; wxStaticText* m_labelStagger;
TEXT_CTRL_EVAL* m_entryStagger; TEXT_CTRL_EVAL* m_entryStagger;
wxRadioBox* m_radioBoxGridStaggerType; wxRadioBox* m_radioBoxGridStaggerType;
wxPanel* m_gridPadNumberingPanel;
wxBoxSizer* m_gridPadNumberingSizer; wxBoxSizer* m_gridPadNumberingSizer;
wxRadioBox* m_radioBoxGridNumberingAxis; wxRadioBox* m_radioBoxGridNumberingAxis;
wxCheckBox* m_checkBoxGridReverseNumbering; wxCheckBox* m_checkBoxGridReverseNumbering;
@ -99,6 +101,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
TEXT_CTRL_EVAL* m_entryCircCount; TEXT_CTRL_EVAL* m_entryCircCount;
wxStaticText* m_labelCircRotate; wxStaticText* m_labelCircRotate;
wxCheckBox* m_entryRotateItemsCb; wxCheckBox* m_entryRotateItemsCb;
wxPanel* m_circularPadNumberingPanel;
wxStaticBoxSizer* m_circPadNumberingSizer; wxStaticBoxSizer* m_circPadNumberingSizer;
wxRadioBox* m_rbCircStartNumberingOpt; wxRadioBox* m_rbCircStartNumberingOpt;
wxStaticText* m_labelCircNumbering; wxStaticText* m_labelCircNumbering;
@ -107,11 +110,14 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
wxTextCtrl* m_entryCircNumberingStart; wxTextCtrl* m_entryCircNumberingStart;
wxStaticText* m_labelCircNumStep; wxStaticText* m_labelCircNumStep;
wxTextCtrl* m_entryCircNumberingStep; wxTextCtrl* m_entryCircNumberingStep;
wxPanel* m_footprintReannotatePanel;
wxRadioButton* m_radioBtnKeepRefs;
wxRadioButton* m_radioBtnUniqueRefs;
wxStdDialogButtonSizer* m_stdButtons; wxStdDialogButtonSizer* m_stdButtons;
wxButton* m_stdButtonsOK; wxButton* m_stdButtonsOK;
wxButton* m_stdButtonsCancel; 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 OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnParameterChanged( wxCommandEvent& event ) { event.Skip(); } virtual void OnParameterChanged( wxCommandEvent& event ) { event.Skip(); }
@ -119,6 +125,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
public: 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( 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(); ~DIALOG_CREATE_ARRAY_BASE();
}; };

View File

@ -68,17 +68,32 @@ int BOARD_REANNOTATE_TOOL::ReannotateDuplicatesInSelection()
if( selection.Empty() ) if( selection.Empty() )
return 0; 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(); FOOTPRINTS fpOnBoard = m_frame->GetBoard()->Footprints();
std::multimap<wxString, KIID> usedDesignatorsMap; 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 ) for( FOOTPRINT* fp : fpOnBoard )
usedDesignatorsMap.insert( { fp->GetReference(), fp->m_Uuid } ); usedDesignatorsMap.insert( { fp->GetReference(), fp->m_Uuid } );
// 2. Get a sorted list of footprints from the selection // 2. Get a sorted list of footprints from the selection
FOOTPRINTS fpInSelection; FOOTPRINTS fpInSelection;
for( EDA_ITEM* item : selection ) for( EDA_ITEM* item : aSelectionToReannotate )
{ {
if( item->Type() == PCB_FOOTPRINT_T ) if( item->Type() == PCB_FOOTPRINT_T )
fpInSelection.push_back( static_cast<FOOTPRINT*>( item ) ); fpInSelection.push_back( static_cast<FOOTPRINT*>( item ) );
@ -90,7 +105,20 @@ int BOARD_REANNOTATE_TOOL::ReannotateDuplicatesInSelection()
int ii = StrNumCmp( aA->GetReference(), aB->GetReference(), true ); int ii = StrNumCmp( aA->GetReference(), aB->GetReference(), true );
if( ii == 0 ) 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; return ii < 0;
} ); } );

View File

@ -40,8 +40,12 @@ public:
bool Init() override; bool Init() override;
void Reset( RESET_REASON aReason ) override; void Reset( RESET_REASON aReason ) override;
int ShowReannotateDialog( const TOOL_EVENT& aEvent ); int ShowReannotateDialog( const TOOL_EVENT& aEvent );
int ReannotateDuplicatesInSelection(); int ReannotateDuplicatesInSelection();
int ReannotateDuplicates( const PCB_SELECTION& aSelectionToReannotate,
const std::vector<EDA_ITEM*>& aAdditionalFootprints );
private: private:
void setTransitions() override; //> Bind handlers to corresponding TOOL_ACTIONs 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 // we have a selection to work on now, so start the tool process
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>(); 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(); array_creator.Invoke();
return 0; return 0;