kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #23878
Re: Array tool patches
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 <john.j.beard@xxxxxxxxx>
> 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 <john.j.beard@xxxxxxxxx>
> 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 <john.j.beard@xxxxxxxxx>
> 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 <john.j.beard@xxxxxxxxx>
> 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 : kicad-developers@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~kicad-developers
> More help : https://help.launchpad.net/ListHelp
References