From 18f07d8efb66328a147c500a10644d2fa9050de7 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 9 Mar 2016 09:15:42 -0500 Subject: [PATCH] Pcbnew: create array dialog fixes. (fixes lp:1549231) * No initial copied object changed (this was a serious bug to modify these objects. Previous version modified references and other texts using a broken algorithm). * Only new pads are numbered (therefore renumbering is used only in footprint editor) * Remove not working feature in circular array: now only use number for pads (other options using alphabetical letters are removed: did not work correctly). * A more clear option is used to choose if the pads are numbered from a chosen value or from the first available value. * Adding a warning message if a parameter is incorrect. --- pcbnew/class_module.cpp | 3 + pcbnew/dialogs/dialog_create_array.cpp | 94 +++---- pcbnew/dialogs/dialog_create_array.h | 10 +- pcbnew/dialogs/dialog_create_array_base.cpp | 56 ++--- pcbnew/dialogs/dialog_create_array_base.fbp | 261 ++++---------------- pcbnew/dialogs/dialog_create_array_base.h | 11 +- pcbnew/edit.cpp | 82 ++---- pcbnew/onrightclick.cpp | 5 - pcbnew/tools/edit_tool.cpp | 141 ++++------- 9 files changed, 190 insertions(+), 473 deletions(-) diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index b44f8d1481..a9e402ed67 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -1175,6 +1175,7 @@ BOARD_ITEM* MODULE::DuplicateAndAddItem( const BOARD_ITEM* aItem, new_item = new_pad; break; } + case PCB_MODULE_TEXT_T: { const TEXTE_MODULE* old_text = static_cast( aItem ); @@ -1190,6 +1191,7 @@ BOARD_ITEM* MODULE::DuplicateAndAddItem( const BOARD_ITEM* aItem, } break; } + case PCB_MODULE_EDGE_T: { EDGE_MODULE* new_edge = new EDGE_MODULE( @@ -1199,6 +1201,7 @@ BOARD_ITEM* MODULE::DuplicateAndAddItem( const BOARD_ITEM* aItem, new_item = new_edge; break; } + case PCB_MODULE_T: // Ignore the module itself break; diff --git a/pcbnew/dialogs/dialog_create_array.cpp b/pcbnew/dialogs/dialog_create_array.cpp index 45389a732e..ccb30bd805 100644 --- a/pcbnew/dialogs/dialog_create_array.cpp +++ b/pcbnew/dialogs/dialog_create_array.cpp @@ -57,11 +57,9 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrig }; m_choicePriAxisNumbering->Set( DIM( charSetDescriptions ), charSetDescriptions ); m_choiceSecAxisNumbering->Set( DIM( charSetDescriptions ), charSetDescriptions ); - m_choiceCircNumberingType->Set( DIM( charSetDescriptions ), charSetDescriptions );; m_choicePriAxisNumbering->SetSelection( 0 ); m_choiceSecAxisNumbering->SetSelection( 0 ); - m_choiceCircNumberingType->SetSelection( 0 ); Add( m_entryNx, m_options.m_gridNx ); Add( m_entryNy, m_options.m_gridNy ); @@ -93,6 +91,9 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrig Add( m_entryGridPriNumberingOffset, m_options.m_gridPriNumberingOffset ); Add( m_entryGridSecNumberingOffset, m_options.m_gridSecNumberingOffset ); + Add( m_rbGridStartNumberingOpt, m_options.m_gridNumberingScheme ); + Add( m_rbCircStartNumberingOpt, m_options.m_circNumberingScheme ); + RestoreConfigToControls(); // Load units into labels @@ -119,19 +120,8 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrig void DIALOG_CREATE_ARRAY::OnParameterChanged( wxCommandEvent& event ) { - const wxObject* evObj = event.GetEventObject(); - - // some controls result in a change of enablement - if( evObj == m_radioBoxGridNumberingScheme - || evObj == m_checkBoxGridRestartNumbering ) - { - setControlEnablement(); - } - - if( evObj == m_entryCentreX || evObj == m_entryCentreY ) - { - calculateCircularArrayProperties(); - } + setControlEnablement(); + calculateCircularArrayProperties(); } @@ -142,12 +132,12 @@ static const std::string& alphabetFromNumberingScheme( static const std::string alphaHex = "0123456789ABCDEF"; static const std::string alphaFull = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static const std::string alphaNoIOSQXZ = "ABCDEFGHJKLMNPRTUVWY"; - static const std::string alphaEmpty = ""; switch( type ) { + default: case DIALOG_CREATE_ARRAY::NUMBERING_NUMERIC: - return alphaNumeric; + break; case DIALOG_CREATE_ARRAY::NUMBERING_HEX: return alphaHex; @@ -157,12 +147,9 @@ static const std::string& alphabetFromNumberingScheme( case DIALOG_CREATE_ARRAY::NUMBERING_ALPHA_FULL: return alphaFull; - - default: - wxASSERT_MSG( false, wxString( "Un-handled numbering scheme: " ) << type ); } - return alphaEmpty; + return alphaNumeric; } @@ -183,9 +170,6 @@ static bool getNumberingOffset( const std::string& str, { const std::string alphabet = alphabetFromNumberingScheme( type ); - wxASSERT_MSG( !alphabet.empty(), wxString( - "Unable to determine alphabet for numbering scheme: " ) << type ); - int offset = 0; const int radix = alphabet.length(); @@ -242,8 +226,8 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event ) newGrid->m_2dArrayNumbering = m_radioBoxGridNumberingScheme->GetSelection() != 0; // this is only correct if you set the choice up according to the enum size and order - ok = ok && m_choicePriAxisNumbering->GetSelection() < NUMBERING_TYPE_Max - && m_choiceSecAxisNumbering->GetSelection() < NUMBERING_TYPE_Max; + ok = ok && m_choicePriAxisNumbering->GetSelection() <= NUMBERING_TYPE_MAX + && m_choiceSecAxisNumbering->GetSelection() <= NUMBERING_TYPE_MAX; // mind undefined casts to enums (should not be able to happen) if( ok ) @@ -264,7 +248,7 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event ) m_entryGridSecNumberingOffset->GetValue().ToStdString(), newGrid->m_secAxisNumType, newGrid->m_numberingOffsetY ); - newGrid->m_shouldRenumber = m_checkBoxGridRestartNumbering->GetValue(); + newGrid->m_shouldRenumber = m_rbGridStartNumberingOpt->GetSelection() == 1; // Only use settings if all values are good if( ok ) @@ -284,16 +268,8 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event ) ok = ok && m_entryCircCount->GetValue().ToLong( &newCirc->m_nPts ); newCirc->m_rotateItems = m_entryRotateItemsCb->GetValue(); - - newCirc->m_shouldRenumber = m_checkBoxCircRestartNumbering->GetValue(); - - // This is only correct if you set the choice up according to the enum size and order - ok = ok && m_choiceCircNumberingType->GetSelection() < NUMBERING_TYPE_Max; - - // Mind undefined casts to enums (should not be able to happen) - if( ok ) - newCirc->m_numberingType = - (ARRAY_NUMBERING_TYPE_T) m_choiceCircNumberingType->GetSelection(); + newCirc->m_shouldRenumber = m_rbCircStartNumberingOpt->GetSelection() == 1; + newCirc->m_numberingType = NUMBERING_NUMERIC; ok = ok && m_entryCircNumberingStart->GetValue().ToLong( &newCirc->m_numberingOffset ); @@ -311,17 +287,19 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event ) // assign pointer and ownership here *m_settings = newSettings; - ReadConfigFromControls(); EndModal( wxID_OK ); } + + else + wxMessageBox( _(" Bad parameters" ) ); } void DIALOG_CREATE_ARRAY::setControlEnablement() { - const bool renumber = m_checkBoxGridRestartNumbering->GetValue(); + const bool renumber = m_rbGridStartNumberingOpt->GetSelection() == 1; // If we're not renumbering, we can't set the numbering scheme // or axis numbering types @@ -341,10 +319,7 @@ void DIALOG_CREATE_ARRAY::setControlEnablement() m_entryGridPriNumberingOffset->Enable( renumber ); m_entryGridSecNumberingOffset->Enable( renumber && num2d ); - - // Circular array options - const bool circRenumber = m_checkBoxCircRestartNumbering->GetValue(); - m_choiceCircNumberingType->Enable( circRenumber ); + m_entryCircNumberingStart->Enable( m_rbCircStartNumberingOpt->GetSelection() == 1 ); } @@ -371,25 +346,22 @@ std::string DIALOG_CREATE_ARRAY::ARRAY_OPTIONS::getCoordinateNumber( int n, std::string itemNum; const std::string& alphabet = alphabetFromNumberingScheme( type ); - if( !alphabet.empty() ) - { - const bool nonUnitColsStartAt0 = schemeNonUnitColsStartAt0( type ); + const bool nonUnitColsStartAt0 = schemeNonUnitColsStartAt0( type ); - bool firstRound = true; - int radix = alphabet.length(); + bool firstRound = true; + int radix = alphabet.length(); - do { - int modN = n % radix; + do { + int modN = n % radix; - if( nonUnitColsStartAt0 && !firstRound ) - modN--; // Start the "tens/hundreds/etc column" at "Ax", not "Bx" + if( nonUnitColsStartAt0 && !firstRound ) + modN--; // Start the "tens/hundreds/etc column" at "Ax", not "Bx" - itemNum.insert( 0, 1, alphabet[modN] ); + itemNum.insert( 0, 1, alphabet[modN] ); - n /= radix; - firstRound = false; - } while( n ); - } + n /= radix; + firstRound = false; + } while( n ); return itemNum; } @@ -493,7 +465,7 @@ void DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::TransformItem( int n, BOARD_IT if( m_angle == 0 ) // angle is zero, divide evenly into m_nPts - angle = 3600.0 * n / float(m_nPts); + angle = 3600.0 * n / double( m_nPts ); else // n'th step angle = m_angle * n; @@ -508,5 +480,9 @@ void DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::TransformItem( int n, BOARD_IT wxString DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::GetItemNumber( int aN ) const { - return getCoordinateNumber( aN + m_numberingOffset, m_numberingType ); + // The first new pad has aN number == 1, not 0 + if( m_shouldRenumber ) // numbering pad from initial user value + return getCoordinateNumber( aN - 1 + m_numberingOffset, m_numberingType ); + else // numbering pad from inital pad number + return getCoordinateNumber( aN + m_numberingOffset, m_numberingType ); } diff --git a/pcbnew/dialogs/dialog_create_array.h b/pcbnew/dialogs/dialog_create_array.h index e244dd2e36..11aa83f7f1 100644 --- a/pcbnew/dialogs/dialog_create_array.h +++ b/pcbnew/dialogs/dialog_create_array.h @@ -190,9 +190,10 @@ public: * for pin numbering on BGAs, etc */ NUMBERING_ALPHA_FULL, ///< Full 26-character alphabet - NUMBERING_TYPE_Max ///< Invalid maximum value, insert above here }; + #define NUMBERING_TYPE_MAX NUMBERING_ALPHA_FULL + /** * Persistent dialog options */ @@ -217,11 +218,11 @@ public: */ virtual void TransformItem( int n, BOARD_ITEM* item, const wxPoint& rotPoint ) const = 0; - virtual int GetArraySize() const = 0; + virtual int GetArraySize() const = 0; virtual wxString GetItemNumber( int n ) const = 0; virtual wxString InterpolateNumberIntoString( int n, const wxString& pattern ) const; - bool ShouldRenumberItems() const + bool ShouldRenumberItems() const { return m_shouldRenumber; } @@ -342,8 +343,9 @@ private: std::string m_circCentreX, m_circCentreY, m_circAngle, m_circCount, m_circNumberingOffset; bool m_circRotate; - int m_arrayTypeTab; + int m_gridNumberingScheme; + int m_circNumberingScheme; }; static CREATE_ARRAY_DIALOG_ENTRIES m_options; diff --git a/pcbnew/dialogs/dialog_create_array_base.cpp b/pcbnew/dialogs/dialog_create_array_base.cpp index 22744258df..f9e7b43e54 100644 --- a/pcbnew/dialogs/dialog_create_array_base.cpp +++ b/pcbnew/dialogs/dialog_create_array_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jun 17 2015) +// C++ code generated with wxFormBuilder (version Jan 1 2016) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -105,20 +105,22 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID 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_gridPanel, wxID_ANY, _("Pad Numbering Direction"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingAxisNChoices, m_radioBoxGridNumberingAxisChoices, 1, wxRA_SPECIFY_COLS ); m_radioBoxGridNumberingAxis->SetSelection( 0 ); bSizer3->Add( m_radioBoxGridNumberingAxis, 0, wxALL|wxEXPAND, 5 ); - m_checkBoxGridReverseNumbering = new wxCheckBox( m_gridPanel, wxID_ANY, _("Reverse numbering on alternate rows or columns"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxGridReverseNumbering = new wxCheckBox( m_gridPanel, wxID_ANY, _("Reverse pad numbering on alternate rows or columns"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer3->Add( m_checkBoxGridReverseNumbering, 0, wxALL, 5 ); - m_checkBoxGridRestartNumbering = new wxCheckBox( m_gridPanel, wxID_ANY, _("Restart numbering"), wxDefaultPosition, wxDefaultSize, 0 ); - m_checkBoxGridRestartNumbering->SetValue(true); - bSizer3->Add( m_checkBoxGridRestartNumbering, 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->SetSelection( 1 ); + bSizer3->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, _("Numbering Scheme"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingSchemeNChoices, m_radioBoxGridNumberingSchemeChoices, 1, wxRA_SPECIFY_COLS ); + m_radioBoxGridNumberingScheme = new wxRadioBox( m_gridPanel, wxID_ANY, _("Pad Numbering Scheme"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingSchemeNChoices, m_radioBoxGridNumberingSchemeChoices, 1, wxRA_SPECIFY_COLS ); m_radioBoxGridNumberingScheme->SetSelection( 1 ); bSizer3->Add( m_radioBoxGridNumberingScheme, 0, wxALL|wxEXPAND, 5 ); @@ -147,7 +149,7 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID wxBoxSizer* bSizer5; bSizer5 = new wxBoxSizer( wxHORIZONTAL ); - m_labelGridNumberingOffset = new wxStaticText( m_gridPanel, wxID_ANY, _("Numbering start:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_labelGridNumberingOffset = new wxStaticText( m_gridPanel, wxID_ANY, _("Pad numbering start:"), wxDefaultPosition, wxDefaultSize, 0 ); m_labelGridNumberingOffset->Wrap( -1 ); bSizer5->Add( m_labelGridNumberingOffset, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); @@ -242,37 +244,30 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID bSizer4->Add( gbSizer2, 0, wxALL|wxEXPAND, 5 ); - wxBoxSizer* bSizer6; - bSizer6 = new wxBoxSizer( wxVERTICAL ); + wxStaticBoxSizer* sbcircPadNumberingSizer; + sbcircPadNumberingSizer = new wxStaticBoxSizer( new wxStaticBox( m_circularPanel, wxID_ANY, _("Pad Numbering Options") ), wxVERTICAL ); - m_checkBoxCircRestartNumbering = new wxCheckBox( m_circularPanel, wxID_ANY, _("Restart numbering"), wxDefaultPosition, wxDefaultSize, 0 ); - m_checkBoxCircRestartNumbering->SetValue(true); - bSizer6->Add( m_checkBoxCircRestartNumbering, 0, wxALL, 5 ); - - m_labelCircNumbering = new wxStaticText( m_circularPanel, wxID_ANY, _("Numbering type:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_labelCircNumbering->Wrap( -1 ); - bSizer6->Add( m_labelCircNumbering, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - wxArrayString m_choiceCircNumberingTypeChoices; - m_choiceCircNumberingType = new wxChoice( m_circularPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceCircNumberingTypeChoices, 0 ); - m_choiceCircNumberingType->SetSelection( 0 ); - bSizer6->Add( m_choiceCircNumberingType, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + wxString m_rbCircStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") }; + int m_rbCircStartNumberingOptNChoices = sizeof( m_rbCircStartNumberingOptChoices ) / sizeof( wxString ); + m_rbCircStartNumberingOpt = new wxRadioBox( sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Initial pad number"), wxDefaultPosition, wxDefaultSize, m_rbCircStartNumberingOptNChoices, m_rbCircStartNumberingOptChoices, 1, wxRA_SPECIFY_COLS ); + m_rbCircStartNumberingOpt->SetSelection( 0 ); + sbcircPadNumberingSizer->Add( m_rbCircStartNumberingOpt, 0, wxALL|wxEXPAND, 5 ); wxBoxSizer* bSizer7; bSizer7 = new wxBoxSizer( wxHORIZONTAL ); - m_labelCircNumStart = new wxStaticText( m_circularPanel, wxID_ANY, _("Numbering start:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_labelCircNumStart = new wxStaticText( sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Pad numbering start value:"), wxDefaultPosition, wxDefaultSize, 0 ); m_labelCircNumStart->Wrap( -1 ); bSizer7->Add( m_labelCircNumStart, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - m_entryCircNumberingStart = new wxTextCtrl( m_circularPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer7->Add( m_entryCircNumberingStart, 0, wxALL, 5 ); + m_entryCircNumberingStart = new wxTextCtrl( sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer7->Add( m_entryCircNumberingStart, 1, wxALL, 5 ); - bSizer6->Add( bSizer7, 0, wxEXPAND, 5 ); + sbcircPadNumberingSizer->Add( bSizer7, 0, wxEXPAND, 5 ); - bSizer4->Add( bSizer6, 1, wxALL|wxEXPAND, 5 ); + bSizer4->Add( sbcircPadNumberingSizer, 1, wxEXPAND|wxALL, 5 ); m_circularPanel->SetSizer( bSizer4 ); @@ -294,7 +289,6 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID this->SetSizer( bMainSizer ); this->Layout(); - bMainSizer->Fit( this ); // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_CREATE_ARRAY_BASE::OnClose ) ); @@ -305,12 +299,13 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID m_entryOffsetX->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_entryOffsetY->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_entryStagger->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); - m_checkBoxGridRestartNumbering->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); + m_rbGridStartNumberingOpt->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_radioBoxGridNumberingScheme->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_entryCentreX->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_entryCentreY->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_entryCircAngle->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_entryCircCount->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); + m_rbCircStartNumberingOpt->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnOkClick ), NULL, this ); } @@ -325,12 +320,13 @@ DIALOG_CREATE_ARRAY_BASE::~DIALOG_CREATE_ARRAY_BASE() m_entryOffsetX->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_entryOffsetY->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_entryStagger->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); - m_checkBoxGridRestartNumbering->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); + m_rbGridStartNumberingOpt->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_radioBoxGridNumberingScheme->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_entryCentreX->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_entryCentreY->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_entryCircAngle->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_entryCircCount->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); + m_rbCircStartNumberingOpt->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this ); m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnOkClick ), NULL, this ); } diff --git a/pcbnew/dialogs/dialog_create_array_base.fbp b/pcbnew/dialogs/dialog_create_array_base.fbp index 9f060cc381..f6eb1cc67e 100644 --- a/pcbnew/dialogs/dialog_create_array_base.fbp +++ b/pcbnew/dialogs/dialog_create_array_base.fbp @@ -44,7 +44,7 @@ -1,-1 DIALOG_CREATE_ARRAY_BASE - -1,-1 + 652,473 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h Create Array @@ -258,11 +258,11 @@ bSizer2 wxHORIZONTAL none - + 5 wxEXPAND 1 - + wxBOTH @@ -397,7 +397,7 @@ 0 - + 0 0 @@ -577,7 +577,7 @@ 0 - + 0 0 @@ -757,7 +757,7 @@ 0 - + 0 0 @@ -1023,7 +1023,7 @@ 0 - + 0 0 @@ -1289,7 +1289,7 @@ 0 - + 0 0 @@ -1555,7 +1555,7 @@ 0 - + 0 0 @@ -1821,7 +1821,7 @@ 0 - + 0 0 @@ -2014,7 +2014,7 @@ 0 0 wxID_ANY - Numbering Direction + Pad Numbering Direction 1 0 @@ -2104,7 +2104,7 @@ 0 0 wxID_ANY - Reverse numbering on alternate rows or columns + Reverse pad numbering on alternate rows or columns 0 @@ -2159,11 +2159,11 @@ - + 5 - wxALL + wxALL|wxEXPAND 0 - + 1 1 1 @@ -2177,7 +2177,7 @@ 1 0 - 1 + "Use first free number" "From start value" 1 1 @@ -2192,7 +2192,8 @@ 0 0 wxID_ANY - Restart numbering + Initial pad number + 1 0 @@ -2200,7 +2201,7 @@ 0 1 - m_checkBoxGridRestartNumbering + m_rbGridStartNumberingOpt 1 @@ -2208,9 +2209,10 @@ 1 Resizable + 1 1 - + wxRA_SPECIFY_COLS 0 @@ -2222,7 +2224,6 @@ - OnParameterChanged @@ -2239,6 +2240,7 @@ + OnParameterChanged @@ -2280,7 +2282,7 @@ 0 0 wxID_ANY - Numbering Scheme + Pad Numbering Scheme 1 0 @@ -2720,7 +2722,7 @@ 0 0 wxID_ANY - Numbering start: + Pad numbering start: 0 @@ -2806,7 +2808,7 @@ 0 - + 0 0 @@ -2897,7 +2899,7 @@ 0 - + 0 0 @@ -3182,7 +3184,7 @@ 0 - + 0 0 @@ -3448,7 +3450,7 @@ 0 - + 0 0 @@ -3886,7 +3888,7 @@ 0 - + 0 0 @@ -4152,7 +4154,7 @@ 0 - + 0 0 @@ -4389,18 +4391,22 @@ 5 - wxALL|wxEXPAND + wxEXPAND|wxALL 1 - + + wxID_ANY + Pad Numbering Options - bSizer6 + sbcircPadNumberingSizer wxVERTICAL + 1 none - + + 5 - wxALL + wxALL|wxEXPAND 0 - + 1 1 1 @@ -4414,7 +4420,7 @@ 1 0 - 1 + "Use first free number" "From start value" 1 1 @@ -4429,7 +4435,8 @@ 0 0 wxID_ANY - Restart numbering + Initial pad number + 1 0 @@ -4437,177 +4444,7 @@ 0 1 - m_checkBoxCircRestartNumbering - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Numbering type: - - 0 - - - 0 - - 1 - m_labelCircNumbering - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_choiceCircNumberingType + m_rbCircStartNumberingOpt 1 @@ -4618,7 +4455,7 @@ 0 1 - + wxRA_SPECIFY_COLS 0 @@ -4630,7 +4467,6 @@ - @@ -4647,6 +4483,7 @@ + OnParameterChanged @@ -4696,7 +4533,7 @@ 0 0 wxID_ANY - Numbering start: + Pad numbering start value: 0 @@ -4750,7 +4587,7 @@ 5 wxALL - 0 + 1 1 1 @@ -4782,7 +4619,7 @@ 0 - + 0 0 diff --git a/pcbnew/dialogs/dialog_create_array_base.h b/pcbnew/dialogs/dialog_create_array_base.h index 3e4f79895d..df1f9903bc 100644 --- a/pcbnew/dialogs/dialog_create_array_base.h +++ b/pcbnew/dialogs/dialog_create_array_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jun 17 2015) +// C++ code generated with wxFormBuilder (version Jan 1 2016) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -30,6 +30,7 @@ class DIALOG_SHIM; #include #include #include +#include #include #include #include @@ -69,7 +70,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM wxRadioBox* m_radioBoxGridStaggerType; wxRadioBox* m_radioBoxGridNumberingAxis; wxCheckBox* m_checkBoxGridReverseNumbering; - wxCheckBox* m_checkBoxGridRestartNumbering; + wxRadioBox* m_rbGridStartNumberingOpt; wxRadioBox* m_radioBoxGridNumberingScheme; wxStaticText* m_labelPriAxisNumbering; wxChoice* m_choicePriAxisNumbering; @@ -94,9 +95,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM wxTextCtrl* m_entryCircCount; wxStaticText* m_labelCircRotate; wxCheckBox* m_entryRotateItemsCb; - wxCheckBox* m_checkBoxCircRestartNumbering; - wxStaticText* m_labelCircNumbering; - wxChoice* m_choiceCircNumberingType; + wxRadioBox* m_rbCircStartNumberingOpt; wxStaticText* m_labelCircNumStart; wxTextCtrl* m_entryCircNumberingStart; wxStdDialogButtonSizer* m_stdButtons; @@ -111,7 +110,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( wxWindow* parent, wxWindowID id = wxID_DIALOG_CREATE_ARRAY, const wxString& title = _("Create Array"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 652,473 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_CREATE_ARRAY_BASE(); }; diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index aa8001d899..804bbeaf04 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -1,10 +1,10 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck * Copyright (C) 2015 Wayne Stambaugh - * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2016 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 @@ -1605,10 +1605,14 @@ void PCB_BASE_EDIT_FRAME::createArray() if( !item ) return; + // Note: original item is no more modified. + bool editingModule = NULL != dynamic_cast( this ); BOARD* board = GetBoard(); - // Remember it is valid only in the module editor + + // Remember this is valid and used only in the module editor. + // in board editor, the parent of items is usually the board. MODULE* module = static_cast( item->GetParent() ); DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* array_opts = NULL; @@ -1633,77 +1637,35 @@ void PCB_BASE_EDIT_FRAME::createArray() // modedit saves everything upfront SaveCopyInUndoList( board->m_Modules, UR_MODEDIT ); } - else - { - // We may also change the original item - SaveCopyInUndoList( item, UR_CHANGED ); - } - wxString cachedString; + #define INCREMENT_REF false + #define INCREMENT_PADNUMBER true - if( item->Type() == PCB_MODULE_T ) + // The first item in list is the original item. We do not modify it + for( int ptN = 1; ptN < array_opts->GetArraySize(); ptN++ ) { - cachedString = static_cast( item )->GetReferencePrefix(); - } - else if( EDA_TEXT* text = dynamic_cast( item ) ) - { - // Copy the text (not just take a reference - cachedString = text->GetText(); - } + BOARD_ITEM* new_item; - for( int ptN = 0; ptN < array_opts->GetArraySize(); ptN++ ) - { - BOARD_ITEM* new_item = NULL; - - if( ptN == 0 ) - { - new_item = item; - } + if( editingModule ) + new_item = module->DuplicateAndAddItem( item, INCREMENT_PADNUMBER ); else - { - if( editingModule ) - new_item = module->DuplicateAndAddItem( item, true ); - else - new_item = board->DuplicateAndAddItem( item, true ); + new_item = board->DuplicateAndAddItem( item, INCREMENT_REF ); - if( new_item ) - { - array_opts->TransformItem( ptN, new_item, rotPoint ); - newItemsList.PushItem( new_item ); - } + if( new_item ) + { + array_opts->TransformItem( ptN, new_item, rotPoint ); + newItemsList.PushItem( new_item ); // For undo list } if( !new_item || !array_opts->ShouldRenumberItems() ) continue; - // Renumber items - switch( new_item->Type() ) - { - case PCB_MODULE_TEXT_T: - case PCB_TEXT_T: - { - EDA_TEXT* text = dynamic_cast( new_item ); - if( text ) - text->SetText( array_opts->InterpolateNumberIntoString( ptN, cachedString ) ); - - break; - } - case PCB_MODULE_T: - { - const wxString padName = array_opts->GetItemNumber( ptN ); - static_cast( new_item )->SetReference( cachedString + padName ); - - break; - } - case PCB_PAD_T: + // Renumber pads. Only new pad number renumbering has meaning, + // in the footprint editor. + if( new_item->Type() == PCB_PAD_T ) { const wxString padName = array_opts->GetItemNumber( ptN ); static_cast( new_item )->SetPadName( padName ); - - break; - } - default: - break; } } diff --git a/pcbnew/onrightclick.cpp b/pcbnew/onrightclick.cpp index 603355e22c..68c83a369f 100644 --- a/pcbnew/onrightclick.cpp +++ b/pcbnew/onrightclick.cpp @@ -308,11 +308,6 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) AddMenuItem( aPopMenu, ID_POPUP_PCB_DUPLICATE_ITEM, msg, KiBitmap( duplicate_target_xpm ) ); - msg = AddHotkeyName( _("Create Target Array" ), g_Board_Editor_Hokeys_Descr, - HK_CREATE_ARRAY ); - AddMenuItem( aPopMenu, ID_POPUP_PCB_CREATE_ARRAY, - msg, KiBitmap( array_target_xpm ) ); - msg = AddHotkeyName( _( "Edit Target" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_MIRE, msg, KiBitmap( edit_xpm ) ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index bb4093c39b..6d9e872a14 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -702,6 +702,8 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent ) int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) { + // Note: original items are no more modified. + bool increment = aEvent.IsAction( &COMMON_ACTIONS::duplicateIncrement ); // first, check if we have a selection, or try to get one @@ -803,8 +805,6 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) if( !hoverSelection( selection ) ) return 0; - bool originalItemsModified = false; - // we have a selection to work on now, so start the tool process PCB_BASE_FRAME* editFrame = getEditFrame(); @@ -815,11 +815,6 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) // Module editors do their undo point upfront for the whole module editFrame->SaveCopyInUndoList( editFrame->GetBoard()->m_Modules, UR_MODEDIT ); } - else - { - // We may also change the original item - editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); - } DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* array_opts = NULL; @@ -840,106 +835,66 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) if( !item ) continue; - wxString cachedString; - - if( item->Type() == PCB_MODULE_T ) - { - cachedString = static_cast( item )->GetReferencePrefix(); - } - else if( EDA_TEXT* text = dynamic_cast( item ) ) - { - // Copy the text (not just take a reference - cachedString = text->GetText(); - } - // iterate across the array, laying out the item at the // correct position const unsigned nPoints = array_opts->GetArraySize(); - for( unsigned ptN = 0; ptN < nPoints; ++ptN ) + // The first item in list is the original item. We do not modify it + for( unsigned ptN = 1; ptN < nPoints; ++ptN ) { BOARD_ITEM* newItem = NULL; - if( ptN == 0 ) - newItem = item; + // Some items cannot be duplicated + // i.e. the ref and value fields of a footprint or zones + // therefore newItem can be null + + #define INCREMENT_REF false + #define INCREMENT_PADNUMBER true + + if( m_editModules ) + newItem = editFrame->GetBoard()->m_Modules->DuplicateAndAddItem( + item, INCREMENT_PADNUMBER ); else { - // if renumbering, no need to increment - const bool increment = !array_opts->ShouldRenumberItems(); - - // Some items cannot be duplicated - // i.e. the ref and value fields of a footprint or zones - // therefore newItem can be null - - if( m_editModules ) - newItem = editFrame->GetBoard()->m_Modules->DuplicateAndAddItem( item, increment ); - else - { #if 0 - // @TODO: see if we allow zone duplication here - // Duplicate zones is especially tricky (overlaping zones must be merged) - // so zones are not duplicated - if( item->Type() == PCB_ZONE_AREA_T ) - newItem = NULL; - else + // @TODO: see if we allow zone duplication here + // Duplicate zones is especially tricky (overlaping zones must be merged) + // so zones are not duplicated + if( item->Type() == PCB_ZONE_AREA_T ) + newItem = NULL; + else #endif - newItem = editFrame->GetBoard()->DuplicateAndAddItem( item, increment ); - } - - if( newItem ) - { - array_opts->TransformItem( ptN, newItem, rotPoint ); - - m_toolMgr->RunAction( COMMON_ACTIONS::unselectItem, true, newItem ); - - newItemList.PushItem( newItem ); - - if( newItem->Type() == PCB_MODULE_T) - { - static_cast( newItem )->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, - getView(), _1 ) ); - } - - editFrame->GetGalCanvas()->GetView()->Add( newItem ); - getModel()->GetRatsnest()->Update( newItem ); - } + newItem = editFrame->GetBoard()->DuplicateAndAddItem( + item, INCREMENT_REF ); + // @TODO: we should merge zones. This is a bit tricky, because + // the undo command needs saving old area, if it is merged. } - // set the number if needed: + if( newItem ) + { + array_opts->TransformItem( ptN, newItem, rotPoint ); + + m_toolMgr->RunAction( COMMON_ACTIONS::unselectItem, true, newItem ); + + newItemList.PushItem( newItem ); + + if( newItem->Type() == PCB_MODULE_T) + { + static_cast( newItem )->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, + getView(), _1 ) ); + } + + editFrame->GetGalCanvas()->GetView()->Add( newItem ); + getModel()->GetRatsnest()->Update( newItem ); + } + + // Only renumbering pads has meaning: if( newItem && array_opts->ShouldRenumberItems() ) { - switch( newItem->Type() ) - { - case PCB_PAD_T: + if( newItem->Type() == PCB_PAD_T ) { const wxString padName = array_opts->GetItemNumber( ptN ); static_cast( newItem )->SetPadName( padName ); - - originalItemsModified = true; - break; - } - case PCB_MODULE_T: - { - const wxString moduleName = array_opts->GetItemNumber( ptN ); - MODULE* module = static_cast( newItem ); - module->SetReference( cachedString + moduleName ); - - originalItemsModified = true; - break; - } - case PCB_MODULE_TEXT_T: - case PCB_TEXT_T: - { - EDA_TEXT* text = dynamic_cast( newItem ); - if( text ) - text->SetText( array_opts->InterpolateNumberIntoString( ptN, cachedString ) ); - - originalItemsModified = true; - break; - } - default: - // no renumbering of other items - break; } } } @@ -947,15 +902,7 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) if( !m_editModules ) { - if( originalItemsModified ) - { - // Update the appearance of the original items - selection.group->ItemsViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - // Add all items as a single undo point for PCB editors - // TODO: Can this be merged into the previous undo point (where - // we saved the original items) editFrame->SaveCopyInUndoList( newItemList, UR_NEW ); } }