Personally, I'd rather patch 1 actually _hid_ the pad numbering options rather than just greying them out - I found it a bit confusing at first, I instinctively started trying to figure out how to un-grey them before I realized they were pad-specific options... :P
On Tue, Mar 22, 2016 at 09:01:09AM +0000, John Beard wrote: > Hi all, > > Thank to JP for fixing the bug due to mistaken and misguided handling of > the ratsnest in the array tool in pcbnew! > > These patches tidy up a bit more of that tool: > > * Disable re-numbering (the bit that was broken) controls in pcbnew. > * Centralise code shared between legacy and GAL canvasses (decouples the > array tool from the actual canvas implementation) > * Improved error reporting when bad parameters are detected. > > Thanks, > > John > > From 15d935aa90757b69ab332919358fde1049b06992 Mon Sep 17 00:00:00 2001 > From: John Beard <[email protected]> > Date: Mon, 21 Mar 2016 07:25:34 +0000 > Subject: [PATCH 4/4] Present a list of errors to the user if bad array options > detected > > Also use wxString consistently thoughout the dialog code > --- > pcbnew/dialogs/dialog_create_array.cpp | 164 > +++++++++++++++++++++++++-------- > pcbnew/dialogs/dialog_create_array.h | 26 +++--- > 2 files changed, 137 insertions(+), 53 deletions(-) > > diff --git a/pcbnew/dialogs/dialog_create_array.cpp > b/pcbnew/dialogs/dialog_create_array.cpp > index 7160af7..cf5d7cd 100644 > --- a/pcbnew/dialogs/dialog_create_array.cpp > +++ b/pcbnew/dialogs/dialog_create_array.cpp > @@ -25,6 +25,7 @@ > #include <wxPcbStruct.h> > #include <base_units.h> > #include <macros.h> > +#include <boost/algorithm/string/join.hpp> > > #include <class_drawpanel.h> > #include <class_board.h> > @@ -93,9 +94,6 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* > aParent, > 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 > @@ -134,13 +132,13 @@ void DIALOG_CREATE_ARRAY::OnParameterChanged( > wxCommandEvent& event ) > } > > > -static const std::string& alphabetFromNumberingScheme( > +static const wxString& alphabetFromNumberingScheme( > DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T type ) > { > - static const std::string alphaNumeric = "0123456789"; > - static const std::string alphaHex = "0123456789ABCDEF"; > - static const std::string alphaFull = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; > - static const std::string alphaNoIOSQXZ = "ABCDEFGHJKLMNPRTUVWY"; > + static const wxString alphaNumeric = "0123456789"; > + static const wxString alphaHex = "0123456789ABCDEF"; > + static const wxString alphaFull = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; > + static const wxString alphaNoIOSQXZ = "ABCDEFGHJKLMNPRTUVWY"; > > switch( type ) > { > @@ -173,18 +171,18 @@ static bool schemeNonUnitColsStartAt0( > DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE > } > > > -static bool getNumberingOffset( const std::string& str, > +static bool getNumberingOffset( const wxString& str, > DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T type, > int& offsetToFill ) > { > - const std::string alphabet = alphabetFromNumberingScheme( type ); > + const wxString alphabet = alphabetFromNumberingScheme( type ); > > int offset = 0; > const int radix = alphabet.length(); > > for( unsigned i = 0; i < str.length(); i++ ) > { > - int chIndex = alphabet.find( str[i], 0 ); > + int chIndex = alphabet.Find( str[i], false ); > > if( chIndex == wxNOT_FOUND ) > return false; > @@ -204,10 +202,91 @@ static bool getNumberingOffset( const std::string& str, > } > > > +/** > + * Validates and saves (if valid) the type and offset of an array axis > numbering > + * > + * @param offsetEntry the entry of the offset (text) > + * @param typeEntry the entry of the axis nmbering scheme (choice) > + * @param type the destination of the type if valid > + * @param offset the destination of the offset if valid > + * @param errors error string accumulator > + * @return if all valid > + */ > +static bool validateNumberingTypeAndOffset( const wxTextCtrl& offsetEntry, > + const wxChoice& typeEntry, > + > DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T& type, > + int& offset, > + wxArrayString& errors ) > +{ > + const int typeVal = typeEntry.GetSelection(); > + // mind undefined casts to enums (should not be able to happen) > + bool ok = typeVal <= DIALOG_CREATE_ARRAY::NUMBERING_TYPE_MAX; > + > + if( ok ) > + { > + type = (DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T) typeVal; > + } > + else > + { > + wxString err; > + err.Printf( _("Unrecognised numbering scheme: %d"), typeVal ); > + errors.Add( err ); > + // we can't proceed - we don't know the numbering type > + return false; > + } > + > + const wxString text = offsetEntry.GetValue(); > + ok = getNumberingOffset( text, type, offset ); > + > + if( !ok ) > + { > + const wxString& alphabet = alphabetFromNumberingScheme( type ); > + > + wxString err; > + err.Printf( _( "Could not determine numbering start from \"%s\": " > + "expected value consistent with alphabet \"%s\"" ), > + text, alphabet ); > + errors.Add(err); > + } > + > + return ok; > +} > + > + > +/** > + * Validate and save a long integer entry > + * > + * @param entry the text entry to read from > + * @param dest the value destination > + * @param description description of the field (used if the value is not OK) > + * @param errors a list of errors to add any error to > + * @return valid > + */ > +static bool validateLongEntry( const wxTextEntry& entry, > + long& dest, > + const wxString description, > + wxArrayString& errors ) > +{ > + bool ok = true; > + > + if( !entry.GetValue().ToLong( &dest ) ) > + { > + wxString err; > + err.Printf( _("Bad integral value for %s: %s"), description, > entry.GetValue() ); > + errors.Add( err ); > + ok = false; > + } > + > + return ok; > +} > + > + > void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event ) > { > ARRAY_OPTIONS* newSettings = NULL; > > + wxArrayString errorStrs; > + > const wxWindow* page = m_gridTypeNotebook->GetCurrentPage(); > > if( page == m_gridPanel ) > @@ -216,8 +295,11 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& > event ) > bool ok = true; > > // ints > - ok = ok && m_entryNx->GetValue().ToLong( &newGrid->m_nx ); > - ok = ok && m_entryNy->GetValue().ToLong( &newGrid->m_ny ); > + ok = ok && validateLongEntry(*m_entryNx, newGrid->m_nx, > _("horizontal count"), > + errorStrs); > + ok = ok && validateLongEntry(*m_entryNy, newGrid->m_ny, _("vertical > count"), > + errorStrs); > + > > newGrid->m_delta.x = DoubleValueFromString( g_UserUnit, > m_entryDx->GetValue() ); > newGrid->m_delta.y = DoubleValueFromString( g_UserUnit, > m_entryDy->GetValue() ); > @@ -225,7 +307,8 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& > event ) > newGrid->m_offset.x = DoubleValueFromString( g_UserUnit, > m_entryOffsetX->GetValue() ); > newGrid->m_offset.y = DoubleValueFromString( g_UserUnit, > m_entryOffsetY->GetValue() ); > > - ok = ok && m_entryStagger->GetValue().ToLong( &newGrid->m_stagger ); > + ok = ok && validateLongEntry(*m_entryStagger, newGrid->m_stagger, > _("stagger"), > + errorStrs); > > newGrid->m_stagger_rows = m_radioBoxGridStaggerType->GetSelection() > == 0; > > @@ -238,28 +321,20 @@ 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; > + bool numOk = validateNumberingTypeAndOffset( > + *m_entryGridPriNumberingOffset, > *m_choicePriAxisNumbering, > + newGrid->m_priAxisNumType, newGrid->m_numberingOffsetX, > + errorStrs ); > > - // mind undefined casts to enums (should not be able to happen) > - if( ok ) > + if( newGrid->m_2dArrayNumbering ) > { > - newGrid->m_priAxisNumType = > - (ARRAY_NUMBERING_TYPE_T) > m_choicePriAxisNumbering->GetSelection(); > - newGrid->m_secAxisNumType = > - (ARRAY_NUMBERING_TYPE_T) > m_choiceSecAxisNumbering->GetSelection(); > + numOk = validateNumberingTypeAndOffset( > + *m_entryGridSecNumberingOffset, > *m_choiceSecAxisNumbering, > + newGrid->m_secAxisNumType, > newGrid->m_numberingOffsetY, > + errorStrs ) && numOk; > } > > - // Work out the offsets for the numbering > - ok = ok && getNumberingOffset( > - m_entryGridPriNumberingOffset->GetValue().ToStdString(), > - newGrid->m_priAxisNumType, newGrid->m_numberingOffsetX ); > - > - if( newGrid->m_2dArrayNumbering ) > - ok = ok && getNumberingOffset( > - > m_entryGridSecNumberingOffset->GetValue().ToStdString(), > - newGrid->m_secAxisNumType, > newGrid->m_numberingOffsetY ); > + ok = ok && numOk; > > newGrid->m_numberingStartIsSpecified = > m_rbGridStartNumberingOpt->GetSelection() == 1; > } > @@ -279,7 +354,9 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& > event ) > newCirc->m_centre.y = DoubleValueFromString( g_UserUnit, > m_entryCentreY->GetValue() ); > > newCirc->m_angle = DoubleValueFromString( DEGREES, > m_entryCircAngle->GetValue() ); > - ok = ok && m_entryCircCount->GetValue().ToLong( &newCirc->m_nPts ); > + > + ok = ok && validateLongEntry(*m_entryCircCount, newCirc->m_nPts, > + _("point count"), errorStrs); > > newCirc->m_rotateItems = m_entryRotateItemsCb->GetValue(); > > @@ -290,7 +367,9 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& > event ) > newCirc->m_numberingStartIsSpecified = > m_rbCircStartNumberingOpt->GetSelection() == 1; > newCirc->m_numberingType = NUMBERING_NUMERIC; > > - ok = ok && m_entryCircNumberingStart->GetValue().ToLong( > &newCirc->m_numberingOffset ); > + ok = ok && validateLongEntry(*m_entryCircNumberingStart, > + newCirc->m_numberingOffset, > + _("numbering start"), errorStrs); > } > > // Only use settings if all values are good > @@ -313,7 +392,14 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& > event ) > } > else > { > - wxMessageBox( _("Bad parameters" ) ); > + wxString errorStr; > + > + if( errorStrs.IsEmpty() ) > + errorStr = _("Bad parameters"); > + else > + errorStr = boost::algorithm::join( errorStrs, "\n" ); > + > + wxMessageBox( errorStr ); > } > } > > @@ -380,16 +466,16 @@ void > DIALOG_CREATE_ARRAY::calculateCircularArrayProperties() > > // ARRAY OPTION implementation functions > -------------------------------------- > > -std::string DIALOG_CREATE_ARRAY::ARRAY_OPTIONS::getCoordinateNumber( int n, > +wxString DIALOG_CREATE_ARRAY::ARRAY_OPTIONS::getCoordinateNumber( int n, > ARRAY_NUMBERING_TYPE_T type ) > { > - std::string itemNum; > - const std::string& alphabet = alphabetFromNumberingScheme( type ); > + wxString itemNum; > + const wxString& alphabet = alphabetFromNumberingScheme( type ); > > const bool nonUnitColsStartAt0 = schemeNonUnitColsStartAt0( type ); > > bool firstRound = true; > - int radix = alphabet.length(); > + int radix = alphabet.Length(); > > do { > int modN = n % radix; > diff --git a/pcbnew/dialogs/dialog_create_array.h > b/pcbnew/dialogs/dialog_create_array.h > index f5559d1..4ff2449 100644 > --- a/pcbnew/dialogs/dialog_create_array.h > +++ b/pcbnew/dialogs/dialog_create_array.h > @@ -75,7 +75,7 @@ protected: > ctrls.push_back( ctrlInfo ); > } > > - void Add( wxTextCtrl* ctrl, std::string& dest ) > + void Add( wxTextCtrl* ctrl, wxString& dest ) > { > CONFIG_CTRL_T ctrlInfo = { ctrl, CFG_CTRL_TEXT, (void*) &dest }; > > @@ -108,7 +108,7 @@ protected: > break; > > case CFG_CTRL_TEXT: > - *(std::string*) iter->dest = static_cast<wxTextCtrl*>( > iter->control )->GetValue(); > + *(wxString*) iter->dest = static_cast<wxTextCtrl*>( > iter->control )->GetValue(); > break; > > case CFG_CTRL_CHOICE: > @@ -147,7 +147,7 @@ protected: > break; > > case CFG_CTRL_TEXT: > - static_cast<wxTextCtrl*>( iter->control )->SetValue( > *(std::string*) iter->dest ); > + static_cast<wxTextCtrl*>( iter->control )->SetValue( > *(wxString*) iter->dest ); > break; > > case CFG_CTRL_CHOICE: > @@ -245,7 +245,7 @@ public: > } > > protected: > - static std::string getCoordinateNumber( int n, > ARRAY_NUMBERING_TYPE_T type ); > + static wxString getCoordinateNumber( int n, ARRAY_NUMBERING_TYPE_T > type ); > > // allow the dialog to set directly > friend class DIALOG_CREATE_ARRAY; > @@ -367,23 +367,21 @@ private: > > bool m_optionsSet; > > - std::string m_gridNx, m_gridNy, > - m_gridDx, m_gridDy, > - m_gridOffsetX, m_gridOffsetY, > - m_gridStagger; > + wxString m_gridNx, m_gridNy, > + m_gridDx, m_gridDy, > + m_gridOffsetX, m_gridOffsetY, > + m_gridStagger; > > - int m_gridStaggerType, m_gridNumberingAxis; > + int m_gridStaggerType, m_gridNumberingAxis; > bool m_gridNumberingReverseAlternate; > int m_grid2dArrayNumbering; > int m_gridPriAxisNumScheme, m_gridSecAxisNumScheme; > - std::string m_gridPriNumberingOffset, m_gridSecNumberingOffset; > + wxString m_gridPriNumberingOffset, m_gridSecNumberingOffset; > > - std::string m_circCentreX, m_circCentreY, > - m_circAngle, m_circCount, m_circNumberingOffset; > + wxString m_circCentreX, m_circCentreY, > + m_circAngle, m_circCount, m_circNumberingOffset; > bool m_circRotate; > int m_arrayTypeTab; > - int m_gridNumberingScheme; > - int m_circNumberingScheme; > }; > > // some uses of arrays might not allow component renumbering > -- > 1.9.1 > > From fd1e58bfef63d86c5ee6a409e115976e39bcad9e Mon Sep 17 00:00:00 2001 > From: John Beard <[email protected]> > Date: Mon, 21 Mar 2016 06:59:12 +0000 > Subject: [PATCH 3/4] Improve code reuse for array tools between GAL/legacy > > Array creation is now handles though an ARRAY_CREATOR class, which is a > class template interface that is inherited and implemented by a version > each for the Legacy canvas and the GAL, providing the canvas-specific > functionality. This centralises the core logic for arraying. > --- > pcbnew/CMakeLists.txt | 1 + > pcbnew/array_creator.cpp | 110 ++++++++++++++++++++++ > pcbnew/array_creator.h | 93 ++++++++++++++++++ > pcbnew/dialogs/dialog_create_array.h | 3 + > pcbnew/edit.cpp | 116 ++++++++--------------- > pcbnew/tools/edit_tool.cpp | 176 > ++++++++++++++--------------------- > 6 files changed, 317 insertions(+), 182 deletions(-) > create mode 100644 pcbnew/array_creator.cpp > create mode 100644 pcbnew/array_creator.h > > diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt > index fe75d5d..6fc2c9f 100644 > --- a/pcbnew/CMakeLists.txt > +++ b/pcbnew/CMakeLists.txt > @@ -187,6 +187,7 @@ set( PCBNEW_CLASS_SRCS > pcbframe.cpp > pcb_base_edit_frame.cpp > append_board_to_current.cpp > + array_creator.cpp > attribut.cpp > board_items_to_polygon_shape_transform.cpp > board_undo_redo.cpp > diff --git a/pcbnew/array_creator.cpp b/pcbnew/array_creator.cpp > new file mode 100644 > index 0000000..b4c9d16 > --- /dev/null > +++ b/pcbnew/array_creator.cpp > @@ -0,0 +1,110 @@ > +/* > + * array_creator.cpp > + * > + * Created on: 11 Mar 2016 > + * Author: John Beard > + */ > + > +#include "array_creator.h" > + > +#include <class_undoredo_container.h> > + > +#include <dialogs/dialog_create_array.h> > + > + > +void ARRAY_CREATOR::Invoke() > +{ > + const int numItems = getNumberOfItemsToArray(); > + > + // bail out if no items > + if( numItems == 0 ) > + return; > + > + MODULE* const module = getModule(); > + const bool isModuleEditor = module != NULL; > + > + const bool enableArrayNumbering = isModuleEditor; > + const wxPoint rotPoint = getRotationCentre(); > + > + DIALOG_CREATE_ARRAY dialog( &m_parent, enableArrayNumbering, rotPoint ); > + int ret = dialog.ShowModal(); > + > + DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* const array_opts = > dialog.GetArrayOptions(); > + > + if( ret == wxID_OK && array_opts != NULL ) > + { > + PICKED_ITEMS_LIST newItemsList; > + > + if( isModuleEditor ) > + { > + // modedit saves everything upfront > + m_parent.SaveCopyInUndoList( getBoard()->m_Modules, UR_MODEDIT ); > + } > + > + for ( int i = 0; i < numItems; ++i ) > + { > + BOARD_ITEM* item = getNthItemToArray( i ); > + > + if( item->Type() == PCB_PAD_T && !isModuleEditor ) > + { > + // If it is not the module editor, then duplicate the parent > module instead > + item = static_cast<MODULE*>( item )->GetParent(); > + } > + > + // The first item in list is the original item. We do not modify > it > + for( int ptN = 1; ptN < array_opts->GetArraySize(); ptN++ ) > + { > + BOARD_ITEM* new_item; > + > + if( isModuleEditor ) > + { > + // increment pad numbers if do any renumbering > + // (we will number again later according to the > numbering scheme if set) > + new_item = module->DuplicateAndAddItem( > + item, array_opts->ShouldNumberItems() ); > + } > + else > + { > + // PCB items keep the same numbering > + new_item = getBoard()->DuplicateAndAddItem( item, false > ); > + > + // @TODO: we should merge zones. This is a bit tricky, > because > + // the undo command needs saving old area, if it is > merged. > + } > + > + if( new_item ) > + { > + array_opts->TransformItem( ptN, new_item, rotPoint ); > + > + prePushAction( new_item ); > + > + newItemsList.PushItem( new_item ); // For undo list > + > + postPushAction( new_item ); > + } > + > + // attempt to renumber items if the array parameters define > + // a complete numbering scheme to number by (as opposed to > + // implicit numbering by incrementing the items during > creation > + if( new_item && array_opts->NumberingStartIsSpecified() ) > + { > + // 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<D_PAD*>( new_item )->SetPadName( padName > ); > + } > + } > + } > + } > + > + if( !isModuleEditor ) > + { > + // Add all items as a single undo point for PCB editors > + m_parent.SaveCopyInUndoList( newItemsList, UR_NEW ); > + } > + > + finalise(); > + } > +} > diff --git a/pcbnew/array_creator.h b/pcbnew/array_creator.h > new file mode 100644 > index 0000000..07b0a30 > --- /dev/null > +++ b/pcbnew/array_creator.h > @@ -0,0 +1,93 @@ > +/* > + * array_creator.h > + * > + * Created on: 11 Mar 2016 > + * Author: John Beard > + */ > + > +#ifndef PCBNEW_ARRAY_CREATOR_H_ > +#define PCBNEW_ARRAY_CREATOR_H_ > + > +#include <dialogs/dialog_create_array.h> > + > +#include <class_board.h> > +#include <class_module.h> > +#include <class_board_item.h> > + > +/*! > + * Class that performs array creation by producing a dialog to gather > + * parameters and then creating and laying out the items. > + * > + * This is a template class which needs to be implemented by the relevant > + * edit tooling, since the details of how the document is manipulated > + * varies between edit modes (e.g. legacy or GAL) > + */ > +class ARRAY_CREATOR > +{ > +public: > + ARRAY_CREATOR(PCB_BASE_FRAME& parent): > + m_parent( parent ) > + {} > + > + /*! > + * Open the dialog, gather parameters and create the array > + */ > + void Invoke(); > + > +protected: > + virtual ~ARRAY_CREATOR() {} > + > + PCB_BASE_FRAME& m_parent; > + > +private: > + > + /*! > + * Get the BOARD that is currently being edited. > + */ > + virtual BOARD* getBoard() const = 0; > + > + /*! > + * If editing a footprint, returns the relevant MODULE, else NULL > + */ > + virtual MODULE* getModule() const = 0; > + > + /*! > + * @return number of original items to put into an array (eg size of the > + * selection) > + */ > + virtual int getNumberOfItemsToArray() const = 0; > + > + /*! > + * @return the n'th original item to be arrayed > + */ > + virtual BOARD_ITEM* getNthItemToArray( int n ) const = 0; > + > + /*! > + * @return the rotation centre of all the items to be arrayed, when taken > + * together > + */ > + virtual wxPoint getRotationCentre() const = 0; > + > + /*! > + * Perform any relevant action before pushing a newly created array item > + * to the BOARD > + */ > + virtual void prePushAction( BOARD_ITEM* new_item ) > + {} > + > + /*! > + * Perform any actions needed after pushing an item to the BOARD > + */ > + virtual void postPushAction( BOARD_ITEM* new_item ) > + {} > + > + /*! > + * Actions to perform after the array process is complete > + */ > + virtual void finalise() = 0; > +}; > + > + > + > + > +#endif /* PCBNEW_ARRAY_CREATOR_H_ */ > diff --git a/pcbnew/dialogs/dialog_create_array.h > b/pcbnew/dialogs/dialog_create_array.h > index 848a26c..f5559d1 100644 > --- a/pcbnew/dialogs/dialog_create_array.h > +++ b/pcbnew/dialogs/dialog_create_array.h > @@ -28,6 +28,9 @@ > // Include the wxFormBuider header base: > #include <dialog_create_array_base.h> > > +#include <class_board_item.h> > +#include <wxBasePcbFrame.h> > + > #include <boost/bimap.hpp> > > class CONFIG_SAVE_RESTORE_WINDOW > diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp > index af23428..d78abfa 100644 > --- a/pcbnew/edit.cpp > +++ b/pcbnew/edit.cpp > @@ -53,9 +53,9 @@ > #include <dialog_drc.h> > #include <dialog_global_edit_tracks_and_vias.h> > #include <invoke_pcb_dialog.h> > +#include <array_creator.h> > > #include <dialog_move_exact.h> > -#include <dialog_create_array.h> > > #include <tool/tool_manager.h> > #include <tools/common_actions.h> > @@ -1598,94 +1598,56 @@ void PCB_BASE_EDIT_FRAME::duplicateItem( BOARD_ITEM* > aItem, bool aIncrement ) > } > > > -void PCB_BASE_EDIT_FRAME::createArray() > +class LEGACY_ARRAY_CREATOR: public ARRAY_CREATOR > { > - BOARD_ITEM* item = GetScreen()->GetCurItem(); > - > - if( !item ) > - return; > - > - // Note: original item is no more modified. > +public: > > - bool editingModule = NULL != dynamic_cast<FOOTPRINT_EDIT_FRAME*>( this ); > - > - BOARD* board = GetBoard(); > - > - // 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<MODULE*>( item->GetParent() ); > - > - const wxPoint rotPoint = item->GetCenter(); > - > - const bool enableArrayNumbering = editingModule; > - > - DIALOG_CREATE_ARRAY dialog( this, enableArrayNumbering, rotPoint ); > - int ret = dialog.ShowModal(); > + LEGACY_ARRAY_CREATOR( PCB_BASE_EDIT_FRAME& editFrame ): > + ARRAY_CREATOR( editFrame ), > + m_item( m_parent.GetScreen()->GetCurItem() ) > + {} > > - DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* const array_opts = > dialog.GetArrayOptions(); > +private: > > - if( ret == wxID_OK && array_opts != NULL ) > + int getNumberOfItemsToArray() const //override > { > - PICKED_ITEMS_LIST newItemsList; > + // only handle single items > + return (m_item != NULL) ? 1 : 0; > + } > > - if( item->Type() == PCB_PAD_T && !editingModule ) > - { > - // If it is not the module editor, then duplicate the parent > module instead > - item = static_cast<MODULE*>( item )->GetParent(); > - } > + BOARD_ITEM* getNthItemToArray( int n ) const //override > + { > + wxASSERT_MSG( n == 0, "Legacy array tool can only handle a single > item" ); > + return m_item; > + } > > - if( editingModule ) > - { > - // modedit saves everything upfront > - SaveCopyInUndoList( board->m_Modules, UR_MODEDIT ); > - } > + BOARD* getBoard() const //override > + { > + return m_parent.GetBoard(); > + } > > + MODULE* getModule() const //override > + { > + return dynamic_cast<MODULE*>( m_item->GetParent() ); > + } > > - // The first item in list is the original item. We do not modify it > - for( int ptN = 1; ptN < array_opts->GetArraySize(); ptN++ ) > - { > - BOARD_ITEM* new_item; > + wxPoint getRotationCentre() const //override > + { > + return m_item->GetCenter(); > + } > > - if( editingModule ) > - { > - // increment pad numbers if do any renumbering > - // (we will number again later according to the numbering > scheme if set) > - new_item = module->DuplicateAndAddItem( item, > - > !array_opts->ShouldNumberItems() ); > - } > - else > - { > - // PCB items keep the same numbering > - new_item = board->DuplicateAndAddItem( item, false ); > - } > + void finalise() // override > + { > + m_parent.GetCanvas()->Refresh(); > + } > > - if( new_item ) > - { > - array_opts->TransformItem( ptN, new_item, rotPoint ); > - newItemsList.PushItem( new_item ); // For undo list > - } > + BOARD_ITEM* m_item; // only have the one > +}; > > - // attempt to renumber items if the array parameters define > - // a complete numbering scheme to number by (as opposed to > - // implicit numbering by incrementing the items during creation > - if( new_item && array_opts->NumberingStartIsSpecified() ) > - { > - // 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<D_PAD*>( new_item )->SetPadName( padName ); > - } > - } > - } > > - if( !editingModule ) > - { > - // pcbnew saves the new items like this > - SaveCopyInUndoList( newItemsList, UR_NEW ); > - } > +void PCB_BASE_EDIT_FRAME::createArray() > +{ > + LEGACY_ARRAY_CREATOR array_creator( *this ); > > - m_canvas->Refresh(); > - } > + array_creator.Invoke(); > } > diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp > index c82c065..19f397e 100644 > --- a/pcbnew/tools/edit_tool.cpp > +++ b/pcbnew/tools/edit_tool.cpp > @@ -33,6 +33,7 @@ > #include <kiway.h> > #include <class_draw_panel_gal.h> > #include <module_editor_frame.h> > +#include <array_creator.h> > > #include <tool/tool_manager.h> > #include <view/view_controls.h> > @@ -51,7 +52,6 @@ > > #include <router/router_tool.h> > > -#include <dialogs/dialog_create_array.h> > #include <dialogs/dialog_move_exact.h> > #include <dialogs/dialog_track_via_properties.h> > > @@ -794,136 +794,102 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) > decUndoInhibit(); > > return 0; > -} > +}; > > > -int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) > +class GAL_ARRAY_CREATOR: public ARRAY_CREATOR > { > - // first, check if we have a selection, or try to get one > - SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>(); > - const SELECTION& selection = selTool->GetSelection(); > +public: > > - // Be sure that there is at least one item that we can modify > - if( !hoverSelection( selection ) ) > - return 0; > + GAL_ARRAY_CREATOR( PCB_BASE_FRAME& editFrame, bool editModules, > + RN_DATA* ratsnest, > + const SELECTION& selection ): > + ARRAY_CREATOR( editFrame ), > + m_editModules( editModules ), > + m_ratsnest( ratsnest ), > + m_selection( selection ) > + {} > > - // we have a selection to work on now, so start the tool process > +private: > > - PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>(); > - editFrame->OnModify(); > - > - if( m_editModules ) > + int getNumberOfItemsToArray() const //override > { > - // Module editors do their undo point upfront for the whole module > - editFrame->SaveCopyInUndoList( editFrame->GetBoard()->m_Modules, > UR_MODEDIT ); > + // only handle single items > + return m_selection.Size(); > } > > - VECTOR2I rp = selection.GetCenter(); > - const wxPoint rotPoint( rp.x, rp.y ); > + BOARD_ITEM* getNthItemToArray( int n ) const //override > + { > + return m_selection.Item<BOARD_ITEM>( n ); > + } > > - // only allow renumbering in modedit, since renumbering in pcbnew > - // needs to be done in sync with the netlist > - const bool enableNumbering = m_editModules; > + BOARD* getBoard() const //override > + { > + return m_parent.GetBoard(); > + } > > - DIALOG_CREATE_ARRAY dialog( editFrame, enableNumbering, rotPoint ); > - int ret = dialog.ShowModal(); > - dialog.FitInside(); // since we may or may not have numbering options > + MODULE* getModule() const //override > + { > + // Remember this is valid and used only in the module editor. > + // in board editor, the parent of items is usually the board. > + return m_editModules ? m_parent.GetBoard()->m_Modules.GetFirst() : > NULL; > + } > > - const DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* const array_opts = > dialog.GetArrayOptions(); > + wxPoint getRotationCentre() const //override > + { > + const VECTOR2I rp = m_selection.GetCenter(); > + return wxPoint( rp.x, rp.y ); > + } > > - if( ret == wxID_OK && array_opts != NULL ) > + void prePushAction( BOARD_ITEM* new_item ) // override > { > - PICKED_ITEMS_LIST newItemList; > + m_parent.GetToolManager()->RunAction( COMMON_ACTIONS::unselectItem, > + true, new_item ); > + } > > - for( int i = 0; i < selection.Size(); ++i ) > + void postPushAction( BOARD_ITEM* new_item ) //override > + { > + KIGFX::VIEW* view = m_parent.GetToolManager()->GetView(); > + if( new_item->Type() == PCB_MODULE_T) > { > - BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i ); > - > - if( !item ) > - continue; > - > - // iterate across the array, laying out the item at the > - // correct position > - const unsigned nPoints = array_opts->GetArraySize(); > - > - // 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; > + static_cast<MODULE*>( new_item )->RunOnChildren( > + boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); > + } > > - // Some items cannot be duplicated > - // i.e. the ref and value fields of a footprint or zones > - // therefore newItem can be null > + m_parent.GetGalCanvas()->GetView()->Add( new_item ); > + m_ratsnest->Update( new_item ); > + } > > - if( m_editModules ) > - { > - // renumber if we are numbering at all AND we have a > specific > - // numbering scheme in mind, rather than just > incrementing > - newItem = > editFrame->GetBoard()->m_Modules->DuplicateAndAddItem( > - item, array_opts->ShouldNumberItems()); > - } > - 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 > -#endif > - { > - // PCB items never get numberered, they stay the same > - newItem = editFrame->GetBoard()->DuplicateAndAddItem( > - item, false ); > - } > - // @TODO: we should merge zones. This is a bit tricky, > because > - // the undo command needs saving old area, if it is > merged. > - } > + void finalise() // override > + { > + m_ratsnest->Recalculate(); > + } > > - if( newItem ) > - { > - array_opts->TransformItem( ptN, newItem, rotPoint ); > + bool m_editModules; > + RN_DATA* m_ratsnest; > + const SELECTION& m_selection; > +}; > > - m_toolMgr->RunAction( COMMON_ACTIONS::unselectItem, > true, newItem ); > > - newItemList.PushItem( newItem ); > +int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) > +{ > + // first, check if we have a selection, or try to get one > + SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>(); > + const SELECTION& selection = selTool->GetSelection(); > > - if( newItem->Type() == PCB_MODULE_T) > - { > - static_cast<MODULE*>( newItem )->RunOnChildren( > boost::bind( &KIGFX::VIEW::Add, > - getView(), _1 ) ); > - } > + // pick up items under the cursor if needed > + hoverSelection( selection ); > > - editFrame->GetGalCanvas()->GetView()->Add( newItem ); > - getModel<BOARD>()->GetRatsnest()->Update( newItem ); > - } > + // we have a selection to work on now, so start the tool process > > - // attempt to renumber items if the array parameters define > - // a complete numbering scheme to number by (as opposed to > - // implicit numbering by incrementing the items during > creation > - if( newItem && array_opts->NumberingStartIsSpecified() ) > - { > - // Only renumbering pads has meaning: > - if( newItem->Type() == PCB_PAD_T ) > - { > - const wxString padName = array_opts->GetItemNumber( > ptN ); > - static_cast<D_PAD*>( newItem )->SetPadName( padName > ); > - } > - } > - } > - } > + PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>(); > + editFrame->OnModify(); > > - if( !m_editModules ) > - { > - // Add all items as a single undo point for PCB editors > - editFrame->SaveCopyInUndoList( newItemList, UR_NEW ); > - } > - } > + GAL_ARRAY_CREATOR array_creator( *editFrame, m_editModules, > + getModel<BOARD>()->GetRatsnest(), > + selection ); > > - getModel<BOARD>()->GetRatsnest()->Recalculate(); > + array_creator.Invoke(); > > return 0; > } > -- > 1.9.1 > > From 6fdcdacd81db01e7b525cf8531ab3259a2bb1443 Mon Sep 17 00:00:00 2001 > From: John Beard <[email protected]> > Date: Mon, 21 Mar 2016 06:45:23 +0000 > Subject: [PATCH 2/4] Create Array dialog retains ownership of the options > > --- > pcbnew/dialogs/dialog_create_array.cpp | 19 +++++++++++++------ > pcbnew/dialogs/dialog_create_array.h | 17 +++++++++++++---- > pcbnew/edit.cpp | 6 +++--- > pcbnew/tools/edit_tool.cpp | 7 ++++--- > 4 files changed, 33 insertions(+), 16 deletions(-) > > diff --git a/pcbnew/dialogs/dialog_create_array.cpp > b/pcbnew/dialogs/dialog_create_array.cpp > index 85c2e3f..7160af7 100644 > --- a/pcbnew/dialogs/dialog_create_array.cpp > +++ b/pcbnew/dialogs/dialog_create_array.cpp > @@ -39,11 +39,10 @@ DIALOG_CREATE_ARRAY::CREATE_ARRAY_DIALOG_ENTRIES > DIALOG_CREATE_ARRAY::m_options; > > DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, > bool enableNumbering, > - wxPoint aOrigPos, > - ARRAY_OPTIONS** aSettings ) : > + wxPoint aOrigPos ) : > DIALOG_CREATE_ARRAY_BASE( aParent ), > CONFIG_SAVE_RESTORE_WINDOW( m_options.m_optionsSet ), > - m_settings( aSettings ), > + m_settings( NULL ), > m_originalItemPosition( aOrigPos ), > m_numberingEnabled(enableNumbering) > { > @@ -121,6 +120,13 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( > PCB_BASE_FRAME* aParent, > } > > > +DIALOG_CREATE_ARRAY::~DIALOG_CREATE_ARRAY() > +{ > + if( m_settings != NULL ) > + delete m_settings; > +} > + > + > void DIALOG_CREATE_ARRAY::OnParameterChanged( wxCommandEvent& event ) > { > setControlEnablement(); > @@ -297,17 +303,18 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& > event ) > // If we got good settings, send them out and finish > if( newSettings ) > { > - delete *m_settings; > + delete m_settings; > > // assign pointer and ownership here > - *m_settings = newSettings; > + m_settings = newSettings; > ReadConfigFromControls(); > > EndModal( wxID_OK ); > } > - > else > + { > wxMessageBox( _("Bad parameters" ) ); > + } > } > > > diff --git a/pcbnew/dialogs/dialog_create_array.h > b/pcbnew/dialogs/dialog_create_array.h > index 8a44119..848a26c 100644 > --- a/pcbnew/dialogs/dialog_create_array.h > +++ b/pcbnew/dialogs/dialog_create_array.h > @@ -314,17 +314,26 @@ private: > > // Constructor and destructor > DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, bool enableNumbering, > - wxPoint aOrigPos, ARRAY_OPTIONS** settings ); > + wxPoint aOrigPos ); > > - virtual ~DIALOG_CREATE_ARRAY() {}; > + ~DIALOG_CREATE_ARRAY(); > + > + /*! > + * @return the array options set by this dialogue, or NULL if they were > + * not set, or could not be set > + */ > + ARRAY_OPTIONS* GetArrayOptions() const > + { > + return m_settings; > + } > > private: > > /** > * The settings object returned to the caller. > - * We update the caller's object and never have ownership > + * We retain ownership of this > */ > - ARRAY_OPTIONS** m_settings; > + ARRAY_OPTIONS* m_settings; > > /* > * The position of the original item(s), used for finding radius, etc > diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp > index b6b7e9a..af23428 100644 > --- a/pcbnew/edit.cpp > +++ b/pcbnew/edit.cpp > @@ -1615,15 +1615,15 @@ void PCB_BASE_EDIT_FRAME::createArray() > // in board editor, the parent of items is usually the board. > MODULE* module = static_cast<MODULE*>( item->GetParent() ); > > - DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* array_opts = NULL; > - > const wxPoint rotPoint = item->GetCenter(); > > const bool enableArrayNumbering = editingModule; > > - DIALOG_CREATE_ARRAY dialog( this, enableArrayNumbering, rotPoint, > &array_opts ); > + DIALOG_CREATE_ARRAY dialog( this, enableArrayNumbering, rotPoint ); > int ret = dialog.ShowModal(); > > + DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* const array_opts = > dialog.GetArrayOptions(); > + > if( ret == wxID_OK && array_opts != NULL ) > { > PICKED_ITEMS_LIST newItemsList; > diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp > index 694df16..c82c065 100644 > --- a/pcbnew/tools/edit_tool.cpp > +++ b/pcbnew/tools/edit_tool.cpp > @@ -818,8 +818,6 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) > editFrame->SaveCopyInUndoList( editFrame->GetBoard()->m_Modules, > UR_MODEDIT ); > } > > - DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* array_opts = NULL; > - > VECTOR2I rp = selection.GetCenter(); > const wxPoint rotPoint( rp.x, rp.y ); > > @@ -827,8 +825,11 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) > // needs to be done in sync with the netlist > const bool enableNumbering = m_editModules; > > - DIALOG_CREATE_ARRAY dialog( editFrame, enableNumbering, rotPoint, > &array_opts ); > + DIALOG_CREATE_ARRAY dialog( editFrame, enableNumbering, rotPoint ); > int ret = dialog.ShowModal(); > + dialog.FitInside(); // since we may or may not have numbering options > + > + const DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* const array_opts = > dialog.GetArrayOptions(); > > if( ret == wxID_OK && array_opts != NULL ) > { > -- > 1.9.1 > > From 61abc64662349c50b902f4ad048bfc1bf9174ea1 Mon Sep 17 00:00:00 2001 > From: John Beard <[email protected]> > Date: Mon, 21 Mar 2016 06:34:32 +0000 > Subject: [PATCH 1/4] Hide array numbering when not useful. > > Also makes some adjustments to how the numbering options are presented > to callers (making the distinction between numbering at all, and > numbering in an explicit way set in the dialog as opposed to implicit > numbering according to the available numbers in the document) > --- > pcbnew/dialogs/dialog_create_array.cpp | 125 > +++++++++++++++++----------- > pcbnew/dialogs/dialog_create_array.h | 43 ++++++++-- > pcbnew/dialogs/dialog_create_array_base.cpp | 40 +++++---- > pcbnew/dialogs/dialog_create_array_base.fbp | 9 +- > pcbnew/dialogs/dialog_create_array_base.h | 4 +- > pcbnew/edit.cpp | 37 +++++--- > pcbnew/tools/edit_tool.cpp | 29 +++++-- > 7 files changed, 184 insertions(+), 103 deletions(-) > > diff --git a/pcbnew/dialogs/dialog_create_array.cpp > b/pcbnew/dialogs/dialog_create_array.cpp > index ee63520..85c2e3f 100644 > --- a/pcbnew/dialogs/dialog_create_array.cpp > +++ b/pcbnew/dialogs/dialog_create_array.cpp > @@ -37,12 +37,15 @@ > DIALOG_CREATE_ARRAY::CREATE_ARRAY_DIALOG_ENTRIES > DIALOG_CREATE_ARRAY::m_options; > > > -DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint > aOrigPos, > +DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, > + bool enableNumbering, > + wxPoint aOrigPos, > ARRAY_OPTIONS** aSettings ) : > DIALOG_CREATE_ARRAY_BASE( aParent ), > CONFIG_SAVE_RESTORE_WINDOW( m_options.m_optionsSet ), > m_settings( aSettings ), > - m_originalItemPosition( aOrigPos ) > + m_originalItemPosition( aOrigPos ), > + m_numberingEnabled(enableNumbering) > { > // Set up numbering scheme drop downs > // > @@ -223,32 +226,37 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& > event ) > newGrid->m_horizontalThenVertical = > m_radioBoxGridNumberingAxis->GetSelection() == 0; > newGrid->m_reverseNumberingAlternate = > m_checkBoxGridReverseNumbering->GetValue(); > > - newGrid->m_2dArrayNumbering = > m_radioBoxGridNumberingScheme->GetSelection() != 0; > + newGrid->m_shouldNumber = m_numberingEnabled; > > - // 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; > - > - // mind undefined casts to enums (should not be able to happen) > - if( ok ) > + if ( m_numberingEnabled ) > { > - newGrid->m_priAxisNumType = > - (ARRAY_NUMBERING_TYPE_T) > m_choicePriAxisNumbering->GetSelection(); > - newGrid->m_secAxisNumType = > - (ARRAY_NUMBERING_TYPE_T) > m_choiceSecAxisNumbering->GetSelection(); > - } > - > - // Work out the offsets for the numbering > - ok = ok && getNumberingOffset( > - m_entryGridPriNumberingOffset->GetValue().ToStdString(), > - newGrid->m_priAxisNumType, newGrid->m_numberingOffsetX ); > - > - if( newGrid->m_2dArrayNumbering ) > + 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; > + > + // mind undefined casts to enums (should not be able to happen) > + if( ok ) > + { > + newGrid->m_priAxisNumType = > + (ARRAY_NUMBERING_TYPE_T) > m_choicePriAxisNumbering->GetSelection(); > + newGrid->m_secAxisNumType = > + (ARRAY_NUMBERING_TYPE_T) > m_choiceSecAxisNumbering->GetSelection(); > + } > + > + // Work out the offsets for the numbering > ok = ok && getNumberingOffset( > - m_entryGridSecNumberingOffset->GetValue().ToStdString(), > - newGrid->m_secAxisNumType, newGrid->m_numberingOffsetY ); > + m_entryGridPriNumberingOffset->GetValue().ToStdString(), > + newGrid->m_priAxisNumType, newGrid->m_numberingOffsetX ); > + > + if( newGrid->m_2dArrayNumbering ) > + ok = ok && getNumberingOffset( > + > m_entryGridSecNumberingOffset->GetValue().ToStdString(), > + newGrid->m_secAxisNumType, > newGrid->m_numberingOffsetY ); > > - newGrid->m_shouldRenumber = > m_rbGridStartNumberingOpt->GetSelection() == 1; > + newGrid->m_numberingStartIsSpecified = > m_rbGridStartNumberingOpt->GetSelection() == 1; > + } > > // Only use settings if all values are good > if( ok ) > @@ -268,10 +276,16 @@ 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_rbCircStartNumberingOpt->GetSelection() == 1; > - newCirc->m_numberingType = NUMBERING_NUMERIC; > > - ok = ok && m_entryCircNumberingStart->GetValue().ToLong( > &newCirc->m_numberingOffset ); > + newCirc->m_shouldNumber = m_numberingEnabled; > + > + if ( m_numberingEnabled ) > + { > + newCirc->m_numberingStartIsSpecified = > m_rbCircStartNumberingOpt->GetSelection() == 1; > + newCirc->m_numberingType = NUMBERING_NUMERIC; > + > + ok = ok && m_entryCircNumberingStart->GetValue().ToLong( > &newCirc->m_numberingOffset ); > + } > > // Only use settings if all values are good > if( ok ) > @@ -299,27 +313,46 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& > event ) > > void DIALOG_CREATE_ARRAY::setControlEnablement() > { > - const bool renumber = m_rbGridStartNumberingOpt->GetSelection() == 1; > + if ( m_numberingEnabled ) > + { > + const bool renumber = m_rbGridStartNumberingOpt->GetSelection() == 1; > > - // If we're not renumbering, we can't set the numbering scheme > - // or axis numbering types > - m_radioBoxGridNumberingScheme->Enable( renumber ); > - m_labelPriAxisNumbering->Enable( renumber ); > - m_choicePriAxisNumbering->Enable( renumber ); > + // If we're not renumbering, we can't set the numbering scheme > + // or axis numbering types > + m_radioBoxGridNumberingScheme->Enable( renumber ); > + m_labelPriAxisNumbering->Enable( renumber ); > + m_choicePriAxisNumbering->Enable( renumber ); > > - // Disable the secondary axis numbering option if the > - // numbering scheme doesn't have two axes > - const bool num2d = m_radioBoxGridNumberingScheme->GetSelection() != 0; > + // Disable the secondary axis numbering option if the > + // numbering scheme doesn't have two axes > + const bool num2d = m_radioBoxGridNumberingScheme->GetSelection() != > 0; > > - m_labelSecAxisNumbering->Enable( renumber && num2d ); > - m_choiceSecAxisNumbering->Enable( renumber && num2d ); > + m_labelSecAxisNumbering->Enable( renumber && num2d ); > + m_choiceSecAxisNumbering->Enable( renumber && num2d ); > > - // We can only set an offset if we renumber > - m_labelGridNumberingOffset->Enable( renumber ); > - m_entryGridPriNumberingOffset->Enable( renumber ); > - m_entryGridSecNumberingOffset->Enable( renumber && num2d ); > + // We can only set an offset if we renumber > + m_labelGridNumberingOffset->Enable( renumber ); > + m_entryGridPriNumberingOffset->Enable( renumber ); > + m_entryGridSecNumberingOffset->Enable( renumber && num2d ); > > - m_entryCircNumberingStart->Enable( > m_rbCircStartNumberingOpt->GetSelection() == 1 ); > + m_entryCircNumberingStart->Enable( > m_rbCircStartNumberingOpt->GetSelection() == 1 ); > + } > + else > + { > + // grid > + m_rbGridStartNumberingOpt->Enable( false ); > + m_checkBoxGridReverseNumbering->Enable( false ); > + m_radioBoxGridNumberingAxis->Enable( false ); > + m_radioBoxGridNumberingScheme->Enable( false ); > + m_choiceSecAxisNumbering->Enable( false ); > + m_choicePriAxisNumbering->Enable( false ); > + m_entryGridPriNumberingOffset->Enable( false ); > + m_entryGridSecNumberingOffset->Enable( false ); > + > + // circular > + m_rbCircStartNumberingOpt->Enable( false ); > + m_entryCircNumberingStart->Enable( false ); > + } > } > > > @@ -480,9 +513,5 @@ void > DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::TransformItem( int n, BOARD_IT > > wxString DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::GetItemNumber( int aN > ) const > { > - // 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 > ); > + return getCoordinateNumber( aN + m_numberingOffset, m_numberingType ); > } > diff --git a/pcbnew/dialogs/dialog_create_array.h > b/pcbnew/dialogs/dialog_create_array.h > index 11aa83f..8a44119 100644 > --- a/pcbnew/dialogs/dialog_create_array.h > +++ b/pcbnew/dialogs/dialog_create_array.h > @@ -201,13 +201,13 @@ public: > { > ARRAY_OPTIONS( ARRAY_TYPE_T aType ) : > m_type( aType ), > - m_shouldRenumber( false ) > + m_shouldNumber( false ), > + m_numberingStartIsSpecified( false ) > {} > > virtual ~ARRAY_OPTIONS() {}; > > ARRAY_TYPE_T m_type; > - bool m_shouldRenumber; > > /*! > * Function GetArrayPositions > @@ -222,13 +222,37 @@ public: > virtual wxString GetItemNumber( int n ) const = 0; > virtual wxString InterpolateNumberIntoString( int n, const wxString& > pattern ) const; > > - bool ShouldRenumberItems() const > + /*! > + * @return are the items in this array numberred, or are all the > + * items numbered the same > + */ > + bool ShouldNumberItems() const > { > - return m_shouldRenumber; > + return m_shouldNumber; > } > > -protected: > + /*! > + * @return is the numbering is enabled and should start at a point > + * specified in these options or is it implicit according to the > calling > + * code? > + */ > + bool NumberingStartIsSpecified() const > + { > + return m_shouldNumber && m_numberingStartIsSpecified; > + } > + > + protected: > static std::string getCoordinateNumber( int n, > ARRAY_NUMBERING_TYPE_T type ); > + > + // allow the dialog to set directly > + friend class DIALOG_CREATE_ARRAY; > + > + /// True if this array numbers the new items > + bool m_shouldNumber; > + > + /// 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; > }; > > struct ARRAY_GRID_OPTIONS : public ARRAY_OPTIONS > @@ -289,7 +313,9 @@ private: > }; > > // Constructor and destructor > - DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrigPos, > ARRAY_OPTIONS** settings ); > + DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, bool enableNumbering, > + wxPoint aOrigPos, ARRAY_OPTIONS** settings ); > + > virtual ~DIALOG_CREATE_ARRAY() {}; > > private: > @@ -348,8 +374,11 @@ private: > int m_circNumberingScheme; > }; > > - static CREATE_ARRAY_DIALOG_ENTRIES m_options; > + // some uses of arrays might not allow component renumbering > + bool m_numberingEnabled; > > + // saved array options > + static CREATE_ARRAY_DIALOG_ENTRIES m_options; > }; > > #endif // __DIALOG_CREATE_ARRAY__ > diff --git a/pcbnew/dialogs/dialog_create_array_base.cpp > b/pcbnew/dialogs/dialog_create_array_base.cpp > index f9e7b43..67d5e6e 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 Jan 1 2016) > +// C++ code generated with wxFormBuilder (version Mar 9 2016) > // http://www.wxformbuilder.org/ > // > // PLEASE DO "NOT" EDIT THIS FILE! > @@ -100,51 +100,50 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( > wxWindow* parent, wxWindowID > > bSizer2->Add( gbSizer1, 1, wxEXPAND, 5 ); > > - wxBoxSizer* bSizer3; > - bSizer3 = new wxBoxSizer( wxVERTICAL ); > + 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, > _("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_gridPadNumberingSizer->Add( m_radioBoxGridNumberingAxis, 0, > wxALL|wxEXPAND, 5 ); > > 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_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->SetSelection( 1 ); > - bSizer3->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, ...)") }; > 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->SetSelection( 1 ); > - bSizer3->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->Wrap( -1 ); > - bSizer3->Add( m_labelPriAxisNumbering, 0, wxLEFT|wxRIGHT|wxTOP, 5 ); > + 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->SetSelection( 0 ); > - bSizer3->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->Wrap( -1 ); > m_labelSecAxisNumbering->Enable( false ); > > - bSizer3->Add( m_labelSecAxisNumbering, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); > + 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->SetSelection( 0 ); > m_choiceSecAxisNumbering->Enable( false ); > > - bSizer3->Add( m_choiceSecAxisNumbering, 0, > wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); > + m_gridPadNumberingSizer->Add( m_choiceSecAxisNumbering, 0, > wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); > > wxBoxSizer* bSizer5; > bSizer5 = new wxBoxSizer( wxHORIZONTAL ); > @@ -160,10 +159,10 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( > wxWindow* parent, wxWindowID > bSizer5->Add( m_entryGridSecNumberingOffset, 0, wxALL, 5 ); > > > - bSizer3->Add( bSizer5, 0, wxEXPAND, 5 ); > + m_gridPadNumberingSizer->Add( bSizer5, 0, wxEXPAND, 5 ); > > > - bSizer2->Add( bSizer3, 0, wxALL|wxEXPAND, 5 ); > + bSizer2->Add( m_gridPadNumberingSizer, 0, wxALL|wxEXPAND, 5 ); > > > m_gridPanel->SetSizer( bSizer2 ); > @@ -244,30 +243,29 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( > wxWindow* parent, wxWindowID > > bSizer4->Add( gbSizer2, 0, wxALL|wxEXPAND, 5 ); > > - wxStaticBoxSizer* sbcircPadNumberingSizer; > - sbcircPadNumberingSizer = new wxStaticBoxSizer( new wxStaticBox( > m_circularPanel, wxID_ANY, _("Pad Numbering Options") ), wxVERTICAL ); > + m_circPadNumberingSizer = new wxStaticBoxSizer( new wxStaticBox( > m_circularPanel, wxID_ANY, _("Pad Numbering Options") ), wxVERTICAL ); > > 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 = new wxRadioBox( > m_circPadNumberingSizer->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 ); > + m_circPadNumberingSizer->Add( m_rbCircStartNumberingOpt, 0, > wxALL|wxEXPAND, 5 ); > > wxBoxSizer* bSizer7; > bSizer7 = new wxBoxSizer( wxHORIZONTAL ); > > - m_labelCircNumStart = new wxStaticText( > sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Pad numbering start > value:"), wxDefaultPosition, wxDefaultSize, 0 ); > + m_labelCircNumStart = new wxStaticText( > m_circPadNumberingSizer->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( > sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("1"), wxDefaultPosition, > wxDefaultSize, 0 ); > + m_entryCircNumberingStart = new wxTextCtrl( > m_circPadNumberingSizer->GetStaticBox(), wxID_ANY, _("1"), wxDefaultPosition, > wxDefaultSize, 0 ); > bSizer7->Add( m_entryCircNumberingStart, 1, wxALL, 5 ); > > > - sbcircPadNumberingSizer->Add( bSizer7, 0, wxEXPAND, 5 ); > + m_circPadNumberingSizer->Add( bSizer7, 0, wxEXPAND, 5 ); > > > - bSizer4->Add( sbcircPadNumberingSizer, 1, wxEXPAND|wxALL, 5 ); > + bSizer4->Add( m_circPadNumberingSizer, 1, wxEXPAND|wxALL, 5 ); > > > m_circularPanel->SetSizer( bSizer4 ); > diff --git a/pcbnew/dialogs/dialog_create_array_base.fbp > b/pcbnew/dialogs/dialog_create_array_base.fbp > index f6eb1cc..b4af4d4 100644 > --- a/pcbnew/dialogs/dialog_create_array_base.fbp > +++ b/pcbnew/dialogs/dialog_create_array_base.fbp > @@ -1978,9 +1978,9 @@ > <property > name="proportion">0</property> > <object class="wxBoxSizer" > expanded="0"> > <property > name="minimum_size"></property> > - <property > name="name">bSizer3</property> > + <property > name="name">m_gridPadNumberingSizer</property> > <property > name="orient">wxVERTICAL</property> > - <property > name="permission">none</property> > + <property > name="permission">protected</property> > <object class="sizeritem" > expanded="0"> > <property > name="border">5</property> > <property > name="flag">wxALL|wxEXPAND</property> > @@ -4397,10 +4397,9 @@ > <property > name="id">wxID_ANY</property> > <property name="label">Pad > Numbering Options</property> > <property > name="minimum_size"></property> > - <property > name="name">sbcircPadNumberingSizer</property> > + <property > name="name">m_circPadNumberingSizer</property> > <property > name="orient">wxVERTICAL</property> > - <property > name="parent">1</property> > - <property > name="permission">none</property> > + <property > name="permission">protected</property> > <event name="OnUpdateUI"></event> > <object class="sizeritem" > expanded="1"> > <property > name="border">5</property> > diff --git a/pcbnew/dialogs/dialog_create_array_base.h > b/pcbnew/dialogs/dialog_create_array_base.h > index df1f990..0e11e36 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 Jan 1 2016) > +// C++ code generated with wxFormBuilder (version Mar 9 2016) > // http://www.wxformbuilder.org/ > // > // PLEASE DO "NOT" EDIT THIS FILE! > @@ -68,6 +68,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM > wxStaticText* m_labelStagger; > wxTextCtrl* m_entryStagger; > wxRadioBox* m_radioBoxGridStaggerType; > + wxBoxSizer* m_gridPadNumberingSizer; > wxRadioBox* m_radioBoxGridNumberingAxis; > wxCheckBox* m_checkBoxGridReverseNumbering; > wxRadioBox* m_rbGridStartNumberingOpt; > @@ -95,6 +96,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM > wxTextCtrl* m_entryCircCount; > wxStaticText* m_labelCircRotate; > wxCheckBox* m_entryRotateItemsCb; > + wxStaticBoxSizer* m_circPadNumberingSizer; > wxRadioBox* m_rbCircStartNumberingOpt; > wxStaticText* m_labelCircNumStart; > wxTextCtrl* m_entryCircNumberingStart; > diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp > index 703186b..b6b7e9a 100644 > --- a/pcbnew/edit.cpp > +++ b/pcbnew/edit.cpp > @@ -1619,7 +1619,9 @@ void PCB_BASE_EDIT_FRAME::createArray() > > const wxPoint rotPoint = item->GetCenter(); > > - DIALOG_CREATE_ARRAY dialog( this, rotPoint, &array_opts ); > + const bool enableArrayNumbering = editingModule; > + > + DIALOG_CREATE_ARRAY dialog( this, enableArrayNumbering, rotPoint, > &array_opts ); > int ret = dialog.ShowModal(); > > if( ret == wxID_OK && array_opts != NULL ) > @@ -1638,8 +1640,6 @@ void PCB_BASE_EDIT_FRAME::createArray() > SaveCopyInUndoList( board->m_Modules, UR_MODEDIT ); > } > > - #define INCREMENT_REF false > - #define INCREMENT_PADNUMBER true > > // The first item in list is the original item. We do not modify it > for( int ptN = 1; ptN < array_opts->GetArraySize(); ptN++ ) > @@ -1647,9 +1647,17 @@ void PCB_BASE_EDIT_FRAME::createArray() > BOARD_ITEM* new_item; > > if( editingModule ) > - new_item = module->DuplicateAndAddItem( item, > INCREMENT_PADNUMBER ); > + { > + // increment pad numbers if do any renumbering > + // (we will number again later according to the numbering > scheme if set) > + new_item = module->DuplicateAndAddItem( item, > + > !array_opts->ShouldNumberItems() ); > + } > else > - new_item = board->DuplicateAndAddItem( item, INCREMENT_REF ); > + { > + // PCB items keep the same numbering > + new_item = board->DuplicateAndAddItem( item, false ); > + } > > if( new_item ) > { > @@ -1657,15 +1665,18 @@ void PCB_BASE_EDIT_FRAME::createArray() > newItemsList.PushItem( new_item ); // For undo list > } > > - if( !new_item || !array_opts->ShouldRenumberItems() ) > - continue; > - > - // Renumber pads. Only new pad number renumbering has meaning, > - // in the footprint editor. > - if( new_item->Type() == PCB_PAD_T ) > + // attempt to renumber items if the array parameters define > + // a complete numbering scheme to number by (as opposed to > + // implicit numbering by incrementing the items during creation > + if( new_item && array_opts->NumberingStartIsSpecified() ) > { > - const wxString padName = array_opts->GetItemNumber( ptN ); > - static_cast<D_PAD*>( new_item )->SetPadName( padName ); > + // 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<D_PAD*>( new_item )->SetPadName( padName ); > + } > } > } > > diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp > index 02bbc78..694df16 100644 > --- a/pcbnew/tools/edit_tool.cpp > +++ b/pcbnew/tools/edit_tool.cpp > @@ -823,7 +823,11 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) > VECTOR2I rp = selection.GetCenter(); > const wxPoint rotPoint( rp.x, rp.y ); > > - DIALOG_CREATE_ARRAY dialog( editFrame, rotPoint, &array_opts ); > + // only allow renumbering in modedit, since renumbering in pcbnew > + // needs to be done in sync with the netlist > + const bool enableNumbering = m_editModules; > + > + DIALOG_CREATE_ARRAY dialog( editFrame, enableNumbering, rotPoint, > &array_opts ); > int ret = dialog.ShowModal(); > > if( ret == wxID_OK && array_opts != NULL ) > @@ -850,12 +854,13 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) > // 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 ) > + { > + // renumber if we are numbering at all AND we have a > specific > + // numbering scheme in mind, rather than just > incrementing > newItem = > editFrame->GetBoard()->m_Modules->DuplicateAndAddItem( > - item, > INCREMENT_PADNUMBER ); > + item, array_opts->ShouldNumberItems()); > + } > else > { > #if 0 > @@ -863,11 +868,16 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) > // 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 > + { > + // PCB items never get numberered, they stay the same > newItem = editFrame->GetBoard()->DuplicateAndAddItem( > - item, > INCREMENT_REF ); > + item, false ); > + } > // @TODO: we should merge zones. This is a bit tricky, > because > // the undo command needs saving old area, if it is > merged. > } > @@ -890,9 +900,12 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) > getModel<BOARD>()->GetRatsnest()->Update( newItem ); > } > > - // Only renumbering pads has meaning: > - if( newItem && array_opts->ShouldRenumberItems() ) > + // attempt to renumber items if the array parameters define > + // a complete numbering scheme to number by (as opposed to > + // implicit numbering by incrementing the items during > creation > + if( newItem && array_opts->NumberingStartIsSpecified() ) > { > + // Only renumbering pads has meaning: > if( newItem->Type() == PCB_PAD_T ) > { > const wxString padName = array_opts->GetItemNumber( > ptN ); > -- > 1.9.1 > > _______________________________________________ > Mailing list: https://launchpad.net/~kicad-developers > Post to : [email protected] > Unsubscribe : https://launchpad.net/~kicad-developers > More help : https://help.launchpad.net/ListHelp _______________________________________________ Mailing list: https://launchpad.net/~kicad-developers Post to : [email protected] Unsubscribe : https://launchpad.net/~kicad-developers More help : https://help.launchpad.net/ListHelp

