← Back to team overview

kicad-developers team mailing list archive

Array tool patches

 

Hi,

Please find attached a patchset for the array tool.

These patches add a couple of new features:

  * You can specify a "step" between array items (so you can do U1, U3,
U5, etc)
  * You can specify a circular array's centre as relative to the first
item, as opposed to only absolutely.

The third patch refactors some of the array code to make reuse easier
for any future array tools and adds a few general tidy-ups.

Thank you,

John


>From 61e09b33ec7d1edcd14a49eed45655c264b98952 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Thu, 9 Jul 2015 23:36:12 +0100
Subject: [PATCH 1/3] Add a numbering step to grids

---
 pcbnew/dialogs/dialog_create_array.cpp      |  38 ++-
 pcbnew/dialogs/dialog_create_array.h        |  32 +-
 pcbnew/dialogs/dialog_create_array_base.cpp |  47 ++-
 pcbnew/dialogs/dialog_create_array_base.fbp | 473 +++++++++++++++++++++++++++-
 pcbnew/dialogs/dialog_create_array_base.h   |   8 +-
 5 files changed, 564 insertions(+), 34 deletions(-)

diff --git a/pcbnew/dialogs/dialog_create_array.cpp b/pcbnew/dialogs/dialog_create_array.cpp
index 45389a7..d42134f 100644
--- a/pcbnew/dialogs/dialog_create_array.cpp
+++ b/pcbnew/dialogs/dialog_create_array.cpp
@@ -83,6 +83,7 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrig
     Add( m_entryCircCount, m_options.m_circCount );
     Add( m_entryRotateItemsCb, m_options.m_circRotate );
     Add( m_entryCircNumberingStart, m_options.m_circNumberingOffset );
+    Add( m_spinCtrlCircNumberingStep, m_options.m_circNumberingStep );
 
     Add( m_gridTypeNotebook, m_options.m_arrayTypeTab );
 
@@ -92,6 +93,8 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrig
 
     Add( m_entryGridPriNumberingOffset, m_options.m_gridPriNumberingOffset );
     Add( m_entryGridSecNumberingOffset, m_options.m_gridSecNumberingOffset );
+    Add( m_spinCtrlGridPriAxisNumberingStep, m_options.m_gridPriAxisNumberingStep );
+    Add( m_spinCtrlGridSecAxisNumberingStep, m_options.m_gridSecAxisNumberingStep );
 
     RestoreConfigToControls();
 
@@ -123,7 +126,8 @@ void DIALOG_CREATE_ARRAY::OnParameterChanged( wxCommandEvent& event )
 
     // some controls result in a change of enablement
     if( evObj == m_radioBoxGridNumberingScheme
-        || evObj == m_checkBoxGridRestartNumbering )
+        || evObj == m_checkBoxGridRestartNumbering
+        || evObj == m_checkBoxCircRestartNumbering )
     {
         setControlEnablement();
     }
@@ -259,10 +263,15 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
                 m_entryGridPriNumberingOffset->GetValue().ToStdString(),
                 newGrid->m_priAxisNumType, newGrid->m_numberingOffsetX );
 
+        newGrid->m_priAxisNumStep = m_spinCtrlGridPriAxisNumberingStep->GetValue();
+
         if( newGrid->m_2dArrayNumbering )
+        {
             ok = ok && getNumberingOffset(
                     m_entryGridSecNumberingOffset->GetValue().ToStdString(),
                     newGrid->m_secAxisNumType, newGrid->m_numberingOffsetY );
+            newGrid->m_secAxisNumStep = m_spinCtrlGridSecAxisNumberingStep->GetValue();
+        }
 
         newGrid->m_shouldRenumber = m_checkBoxGridRestartNumbering->GetValue();
 
@@ -295,6 +304,8 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
             newCirc->m_numberingType =
                 (ARRAY_NUMBERING_TYPE_T) m_choiceCircNumberingType->GetSelection();
 
+        newCirc->m_numberingStep = m_spinCtrlCircNumberingStep->GetValue();
+
         ok = ok && m_entryCircNumberingStart->GetValue().ToLong( &newCirc->m_numberingOffset );
 
         // Only use settings if all values are good
@@ -318,7 +329,6 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
     }
 }
 
-
 void DIALOG_CREATE_ARRAY::setControlEnablement()
 {
     const bool renumber = m_checkBoxGridRestartNumbering->GetValue();
@@ -341,9 +351,14 @@ void DIALOG_CREATE_ARRAY::setControlEnablement()
     m_entryGridPriNumberingOffset->Enable( renumber );
     m_entryGridSecNumberingOffset->Enable( renumber && num2d );
 
+    // We can always set the step on one axis, the other needs a 2d grid
+    m_spinCtrlGridSecAxisNumberingStep->Enable( renumber && num2d );
+
 
     // Circular array options
     const bool circRenumber = m_checkBoxCircRestartNumbering->GetValue();
+    m_labelCircNumStart->Enable( circRenumber );
+    m_labelCircNumbering->Enable( circRenumber );
     m_choiceCircNumberingType->Enable( circRenumber );
 }
 
@@ -468,12 +483,22 @@ wxString DIALOG_CREATE_ARRAY::ARRAY_GRID_OPTIONS::GetItemNumber( int n ) const
     {
         wxPoint coords = getGridCoords( n );
 
-        itemNum += getCoordinateNumber( coords.x + m_numberingOffsetX, m_priAxisNumType );
-        itemNum += getCoordinateNumber( coords.y + m_numberingOffsetY, m_secAxisNumType );
+        itemNum += getCoordinateNumber(
+                coords.x * m_priAxisNumStep + m_numberingOffsetX,
+                m_priAxisNumType
+        );
+
+        itemNum += getCoordinateNumber(
+                coords.y * m_secAxisNumStep + m_numberingOffsetY,
+                m_secAxisNumType
+        );
     }
     else
     {
-        itemNum += getCoordinateNumber( n + m_numberingOffsetX, m_priAxisNumType );
+        itemNum += getCoordinateNumber(
+                n * m_priAxisNumStep + m_numberingOffsetX,
+                m_priAxisNumType
+        );
     }
 
     return itemNum;
@@ -508,5 +533,6 @@ void DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::TransformItem( int n, BOARD_IT
 
 wxString DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::GetItemNumber( int aN ) const
 {
-    return getCoordinateNumber( aN + m_numberingOffset, m_numberingType );
+    return getCoordinateNumber( aN * m_numberingStep + m_numberingOffset,
+            m_numberingType );
 }
diff --git a/pcbnew/dialogs/dialog_create_array.h b/pcbnew/dialogs/dialog_create_array.h
index e244dd2..c130c55 100644
--- a/pcbnew/dialogs/dialog_create_array.h
+++ b/pcbnew/dialogs/dialog_create_array.h
@@ -40,7 +40,8 @@ private:
         CFG_CTRL_CHECKBOX,
         CFG_CTRL_RADIOBOX,
         CFG_CTRL_CHOICE,
-        CFG_CTRL_TAB
+        CFG_CTRL_TAB,
+        CFG_CTRL_SPINBOX,
     };
 
     struct CONFIG_CTRL_T
@@ -93,6 +94,13 @@ protected:
         ctrls.push_back( ctrlInfo );
     }
 
+    void Add( wxSpinCtrl* ctrl, int& dest )
+    {
+        CONFIG_CTRL_T ctrlInfo = { ctrl, CFG_CTRL_SPINBOX, (void*) &dest };
+
+        ctrls.push_back( ctrlInfo );
+    }
+
     void ReadConfigFromControls()
     {
         for( std::vector<CONFIG_CTRL_T>::const_iterator iter = ctrls.begin(), iend = ctrls.end();
@@ -120,6 +128,10 @@ protected:
                 *(int*) iter->dest = static_cast<wxNotebook*>( iter->control )->GetSelection();
                 break;
 
+            case CFG_CTRL_SPINBOX:
+                *(int*) iter->dest = static_cast<wxSpinCtrl*>( iter->control )->GetValue();
+                break;
+
             default:
                 wxASSERT_MSG( false, wxString(
                                 "Unhandled control type for config store: " ) << iter->type );
@@ -159,6 +171,10 @@ protected:
                 static_cast<wxNotebook*>( iter->control )->SetSelection( *(int*) iter->dest );
                 break;
 
+            case CFG_CTRL_SPINBOX:
+                static_cast<wxSpinCtrl*>( iter->control )->SetValue( *(int*) iter->dest );
+                break;
+
             default:
                 wxASSERT_MSG( false, wxString(
                                 "Unhandled control type for config restore: " ) << iter->type );
@@ -243,7 +259,9 @@ protected:
             m_numberingOffsetX( 0 ),
             m_numberingOffsetY( 0 ),
             m_priAxisNumType( NUMBERING_NUMERIC ),
-            m_secAxisNumType( NUMBERING_NUMERIC )
+            m_secAxisNumType( NUMBERING_NUMERIC ),
+            m_priAxisNumStep( 1 ),
+            m_secAxisNumStep( 1 )
         {}
 
         long    m_nx, m_ny;
@@ -255,6 +273,7 @@ protected:
         bool    m_2dArrayNumbering;
         int     m_numberingOffsetX, m_numberingOffsetY;
         ARRAY_NUMBERING_TYPE_T m_priAxisNumType, m_secAxisNumType;
+        long    m_priAxisNumStep, m_secAxisNumStep;
 
         void        TransformItem( int n, BOARD_ITEM* item, const wxPoint& rotPoint ) const;    // override virtual
         int         GetArraySize() const;                                                       // override virtual
@@ -272,7 +291,8 @@ private:
             m_angle( 0.0f ),
             m_rotateItems( false ),
             m_numberingType( NUMBERING_NUMERIC ),
-            m_numberingOffset( 0 )
+            m_numberingOffset( 0 ),
+            m_numberingStep( 1 )
         {}
 
         long m_nPts;
@@ -281,6 +301,7 @@ private:
         bool m_rotateItems;
         ARRAY_NUMBERING_TYPE_T m_numberingType;
         long m_numberingOffset;
+        int m_numberingStep;
 
         void        TransformItem( int n, BOARD_ITEM* item, const wxPoint& rotPoint ) const;    // override virtual
         int         GetArraySize() const;                                                       // override virtual
@@ -322,7 +343,10 @@ private:
             m_grid2dArrayNumbering( 0 ),
             m_gridPriAxisNumScheme( 0 ),
             m_gridSecAxisNumScheme( 0 ),
+            m_gridPriAxisNumberingStep( 1 ),
+            m_gridSecAxisNumberingStep( 1 ),
             m_circRotate( false ),
+            m_circNumberingStep( 1 ),
             m_arrayTypeTab( 0 )
         {}
 
@@ -338,10 +362,12 @@ private:
         int     m_grid2dArrayNumbering;
         int     m_gridPriAxisNumScheme, m_gridSecAxisNumScheme;
         std::string m_gridPriNumberingOffset, m_gridSecNumberingOffset;
+        int     m_gridPriAxisNumberingStep, m_gridSecAxisNumberingStep;
 
         std::string m_circCentreX, m_circCentreY,
                     m_circAngle, m_circCount, m_circNumberingOffset;
         bool m_circRotate;
+        int m_circNumberingStep;
 
         int m_arrayTypeTab;
     };
diff --git a/pcbnew/dialogs/dialog_create_array_base.cpp b/pcbnew/dialogs/dialog_create_array_base.cpp
index 821376e..2379f79 100644
--- a/pcbnew/dialogs/dialog_create_array_base.cpp
+++ b/pcbnew/dialogs/dialog_create_array_base.cpp
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jun  5 2014)
+// C++ code generated with wxFormBuilder (version Jun  6 2014)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -144,18 +144,34 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
 	
 	bSizer3->Add( m_choiceSecAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
 	
-	wxBoxSizer* bSizer5;
-	bSizer5 = new wxBoxSizer( wxHORIZONTAL );
+	wxGridSizer* gSizer1;
+	gSizer1 = new wxGridSizer( 0, 3, 0, 0 );
 	
 	m_labelGridNumberingOffset = new wxStaticText( m_gridPanel, wxID_ANY, _("Numbering start:"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_labelGridNumberingOffset->Wrap( -1 );
-	bSizer5->Add( m_labelGridNumberingOffset, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+	gSizer1->Add( m_labelGridNumberingOffset, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
 	
 	m_entryGridPriNumberingOffset = new wxTextCtrl( m_gridPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
-	bSizer5->Add( m_entryGridPriNumberingOffset, 0, wxALL, 5 );
+	gSizer1->Add( m_entryGridPriNumberingOffset, 0, wxALL|wxEXPAND, 5 );
 	
 	m_entryGridSecNumberingOffset = new wxTextCtrl( m_gridPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
-	bSizer5->Add( m_entryGridSecNumberingOffset, 0, wxALL, 5 );
+	gSizer1->Add( m_entryGridSecNumberingOffset, 0, wxALL|wxEXPAND, 5 );
+	
+	m_labelGridNumberingStep = new wxStaticText( m_gridPanel, wxID_ANY, _("Numbering step:"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_labelGridNumberingStep->Wrap( -1 );
+	gSizer1->Add( m_labelGridNumberingStep, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+	
+	m_spinCtrlGridPriAxisNumberingStep = new wxSpinCtrl( m_gridPanel, wxID_ANY, wxT("1"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 1000, 0 );
+	gSizer1->Add( m_spinCtrlGridPriAxisNumberingStep, 0, wxALL|wxEXPAND, 5 );
+	
+	m_spinCtrlGridSecAxisNumberingStep = new wxSpinCtrl( m_gridPanel, wxID_ANY, wxT("1"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 1000, 0 );
+	gSizer1->Add( m_spinCtrlGridSecAxisNumberingStep, 0, wxALL|wxEXPAND, 5 );
+	
+	
+	bSizer3->Add( gSizer1, 0, 0, 5 );
+	
+	wxBoxSizer* bSizer5;
+	bSizer5 = new wxBoxSizer( wxHORIZONTAL );
 	
 	
 	bSizer3->Add( bSizer5, 0, wxEXPAND, 5 );
@@ -258,18 +274,25 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
 	m_choiceCircNumberingType->SetSelection( 0 );
 	bSizer6->Add( m_choiceCircNumberingType, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
 	
-	wxBoxSizer* bSizer7;
-	bSizer7 = new wxBoxSizer( wxHORIZONTAL );
+	wxGridSizer* gSizer2;
+	gSizer2 = new wxGridSizer( 0, 2, 0, 0 );
 	
 	m_labelCircNumStart = new wxStaticText( m_circularPanel, wxID_ANY, _("Numbering start:"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_labelCircNumStart->Wrap( -1 );
-	bSizer7->Add( m_labelCircNumStart, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+	gSizer2->Add( m_labelCircNumStart, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
 	
 	m_entryCircNumberingStart = new wxTextCtrl( m_circularPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
-	bSizer7->Add( m_entryCircNumberingStart, 0, wxALL, 5 );
+	gSizer2->Add( m_entryCircNumberingStart, 0, wxALL|wxEXPAND, 5 );
+	
+	m_labelCircNumberingStep = new wxStaticText( m_circularPanel, wxID_ANY, _("Numbering step:"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_labelCircNumberingStep->Wrap( -1 );
+	gSizer2->Add( m_labelCircNumberingStep, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+	
+	m_spinCtrlCircNumberingStep = new wxSpinCtrl( m_circularPanel, wxID_ANY, wxT("1"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 1000, 0 );
+	gSizer2->Add( m_spinCtrlCircNumberingStep, 0, wxALL|wxEXPAND, 5 );
 	
 	
-	bSizer6->Add( bSizer7, 0, wxEXPAND, 5 );
+	bSizer6->Add( gSizer2, 0, wxEXPAND, 5 );
 	
 	
 	bSizer4->Add( bSizer6, 1, wxALL|wxEXPAND, 5 );
@@ -311,6 +334,7 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
 	m_entryCentreY->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_entryCircAngle->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_entryCircCount->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+	m_checkBoxCircRestartNumbering->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnOkClick ), NULL, this );
 }
 
@@ -331,6 +355,7 @@ DIALOG_CREATE_ARRAY_BASE::~DIALOG_CREATE_ARRAY_BASE()
 	m_entryCentreY->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_entryCircAngle->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_entryCircCount->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+	m_checkBoxCircRestartNumbering->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnOkClick ), NULL, this );
 	
 }
diff --git a/pcbnew/dialogs/dialog_create_array_base.fbp b/pcbnew/dialogs/dialog_create_array_base.fbp
index eb976c4..4d10147 100644
--- a/pcbnew/dialogs/dialog_create_array_base.fbp
+++ b/pcbnew/dialogs/dialog_create_array_base.fbp
@@ -2679,18 +2679,21 @@
                                                     <event name="OnUpdateUI"></event>
                                                 </object>
                                             </object>
-                                            <object class="sizeritem" expanded="0">
+                                            <object class="sizeritem" expanded="1">
                                                 <property name="border">5</property>
-                                                <property name="flag">wxEXPAND</property>
+                                                <property name="flag"></property>
                                                 <property name="proportion">0</property>
-                                                <object class="wxBoxSizer" expanded="0">
+                                                <object class="wxGridSizer" expanded="1">
+                                                    <property name="cols">3</property>
+                                                    <property name="hgap">0</property>
                                                     <property name="minimum_size"></property>
-                                                    <property name="name">bSizer5</property>
-                                                    <property name="orient">wxHORIZONTAL</property>
+                                                    <property name="name">gSizer1</property>
                                                     <property name="permission">none</property>
+                                                    <property name="rows">0</property>
+                                                    <property name="vgap">0</property>
                                                     <object class="sizeritem" expanded="0">
                                                         <property name="border">5</property>
-                                                        <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+                                                        <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
                                                         <property name="proportion">0</property>
                                                         <object class="wxStaticText" expanded="0">
                                                             <property name="BottomDockable">1</property>
@@ -2773,7 +2776,7 @@
                                                     </object>
                                                     <object class="sizeritem" expanded="0">
                                                         <property name="border">5</property>
-                                                        <property name="flag">wxALL</property>
+                                                        <property name="flag">wxALL|wxEXPAND</property>
                                                         <property name="proportion">0</property>
                                                         <object class="wxTextCtrl" expanded="0">
                                                             <property name="BottomDockable">1</property>
@@ -2864,7 +2867,7 @@
                                                     </object>
                                                     <object class="sizeritem" expanded="0">
                                                         <property name="border">5</property>
-                                                        <property name="flag">wxALL</property>
+                                                        <property name="flag">wxALL|wxEXPAND</property>
                                                         <property name="proportion">0</property>
                                                         <object class="wxTextCtrl" expanded="0">
                                                             <property name="BottomDockable">1</property>
@@ -2953,6 +2956,276 @@
                                                             <event name="OnUpdateUI"></event>
                                                         </object>
                                                     </object>
+                                                    <object class="sizeritem" expanded="1">
+                                                        <property name="border">5</property>
+                                                        <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+                                                        <property name="proportion">0</property>
+                                                        <object class="wxStaticText" expanded="1">
+                                                            <property name="BottomDockable">1</property>
+                                                            <property name="LeftDockable">1</property>
+                                                            <property name="RightDockable">1</property>
+                                                            <property name="TopDockable">1</property>
+                                                            <property name="aui_layer"></property>
+                                                            <property name="aui_name"></property>
+                                                            <property name="aui_position"></property>
+                                                            <property name="aui_row"></property>
+                                                            <property name="best_size"></property>
+                                                            <property name="bg"></property>
+                                                            <property name="caption"></property>
+                                                            <property name="caption_visible">1</property>
+                                                            <property name="center_pane">0</property>
+                                                            <property name="close_button">1</property>
+                                                            <property name="context_help"></property>
+                                                            <property name="context_menu">1</property>
+                                                            <property name="default_pane">0</property>
+                                                            <property name="dock">Dock</property>
+                                                            <property name="dock_fixed">0</property>
+                                                            <property name="docking">Left</property>
+                                                            <property name="enabled">1</property>
+                                                            <property name="fg"></property>
+                                                            <property name="floatable">1</property>
+                                                            <property name="font"></property>
+                                                            <property name="gripper">0</property>
+                                                            <property name="hidden">0</property>
+                                                            <property name="id">wxID_ANY</property>
+                                                            <property name="label">Numbering step:</property>
+                                                            <property name="max_size"></property>
+                                                            <property name="maximize_button">0</property>
+                                                            <property name="maximum_size"></property>
+                                                            <property name="min_size"></property>
+                                                            <property name="minimize_button">0</property>
+                                                            <property name="minimum_size"></property>
+                                                            <property name="moveable">1</property>
+                                                            <property name="name">m_labelGridNumberingStep</property>
+                                                            <property name="pane_border">1</property>
+                                                            <property name="pane_position"></property>
+                                                            <property name="pane_size"></property>
+                                                            <property name="permission">protected</property>
+                                                            <property name="pin_button">1</property>
+                                                            <property name="pos"></property>
+                                                            <property name="resize">Resizable</property>
+                                                            <property name="show">1</property>
+                                                            <property name="size"></property>
+                                                            <property name="style"></property>
+                                                            <property name="subclass"></property>
+                                                            <property name="toolbar_pane">0</property>
+                                                            <property name="tooltip"></property>
+                                                            <property name="window_extra_style"></property>
+                                                            <property name="window_name"></property>
+                                                            <property name="window_style"></property>
+                                                            <property name="wrap">-1</property>
+                                                            <event name="OnChar"></event>
+                                                            <event name="OnEnterWindow"></event>
+                                                            <event name="OnEraseBackground"></event>
+                                                            <event name="OnKeyDown"></event>
+                                                            <event name="OnKeyUp"></event>
+                                                            <event name="OnKillFocus"></event>
+                                                            <event name="OnLeaveWindow"></event>
+                                                            <event name="OnLeftDClick"></event>
+                                                            <event name="OnLeftDown"></event>
+                                                            <event name="OnLeftUp"></event>
+                                                            <event name="OnMiddleDClick"></event>
+                                                            <event name="OnMiddleDown"></event>
+                                                            <event name="OnMiddleUp"></event>
+                                                            <event name="OnMotion"></event>
+                                                            <event name="OnMouseEvents"></event>
+                                                            <event name="OnMouseWheel"></event>
+                                                            <event name="OnPaint"></event>
+                                                            <event name="OnRightDClick"></event>
+                                                            <event name="OnRightDown"></event>
+                                                            <event name="OnRightUp"></event>
+                                                            <event name="OnSetFocus"></event>
+                                                            <event name="OnSize"></event>
+                                                            <event name="OnUpdateUI"></event>
+                                                        </object>
+                                                    </object>
+                                                    <object class="sizeritem" expanded="1">
+                                                        <property name="border">5</property>
+                                                        <property name="flag">wxALL|wxEXPAND</property>
+                                                        <property name="proportion">0</property>
+                                                        <object class="wxSpinCtrl" expanded="1">
+                                                            <property name="BottomDockable">1</property>
+                                                            <property name="LeftDockable">1</property>
+                                                            <property name="RightDockable">1</property>
+                                                            <property name="TopDockable">1</property>
+                                                            <property name="aui_layer"></property>
+                                                            <property name="aui_name"></property>
+                                                            <property name="aui_position"></property>
+                                                            <property name="aui_row"></property>
+                                                            <property name="best_size"></property>
+                                                            <property name="bg"></property>
+                                                            <property name="caption"></property>
+                                                            <property name="caption_visible">1</property>
+                                                            <property name="center_pane">0</property>
+                                                            <property name="close_button">1</property>
+                                                            <property name="context_help"></property>
+                                                            <property name="context_menu">1</property>
+                                                            <property name="default_pane">0</property>
+                                                            <property name="dock">Dock</property>
+                                                            <property name="dock_fixed">0</property>
+                                                            <property name="docking">Left</property>
+                                                            <property name="enabled">1</property>
+                                                            <property name="fg"></property>
+                                                            <property name="floatable">1</property>
+                                                            <property name="font"></property>
+                                                            <property name="gripper">0</property>
+                                                            <property name="hidden">0</property>
+                                                            <property name="id">wxID_ANY</property>
+                                                            <property name="initial">0</property>
+                                                            <property name="max">1000</property>
+                                                            <property name="max_size"></property>
+                                                            <property name="maximize_button">0</property>
+                                                            <property name="maximum_size">-1,-1</property>
+                                                            <property name="min">0</property>
+                                                            <property name="min_size"></property>
+                                                            <property name="minimize_button">0</property>
+                                                            <property name="minimum_size"></property>
+                                                            <property name="moveable">1</property>
+                                                            <property name="name">m_spinCtrlGridPriAxisNumberingStep</property>
+                                                            <property name="pane_border">1</property>
+                                                            <property name="pane_position"></property>
+                                                            <property name="pane_size"></property>
+                                                            <property name="permission">protected</property>
+                                                            <property name="pin_button">1</property>
+                                                            <property name="pos"></property>
+                                                            <property name="resize">Resizable</property>
+                                                            <property name="show">1</property>
+                                                            <property name="size"></property>
+                                                            <property name="style">wxSP_ARROW_KEYS</property>
+                                                            <property name="subclass"></property>
+                                                            <property name="toolbar_pane">0</property>
+                                                            <property name="tooltip"></property>
+                                                            <property name="value">1</property>
+                                                            <property name="window_extra_style"></property>
+                                                            <property name="window_name"></property>
+                                                            <property name="window_style"></property>
+                                                            <event name="OnChar"></event>
+                                                            <event name="OnEnterWindow"></event>
+                                                            <event name="OnEraseBackground"></event>
+                                                            <event name="OnKeyDown"></event>
+                                                            <event name="OnKeyUp"></event>
+                                                            <event name="OnKillFocus"></event>
+                                                            <event name="OnLeaveWindow"></event>
+                                                            <event name="OnLeftDClick"></event>
+                                                            <event name="OnLeftDown"></event>
+                                                            <event name="OnLeftUp"></event>
+                                                            <event name="OnMiddleDClick"></event>
+                                                            <event name="OnMiddleDown"></event>
+                                                            <event name="OnMiddleUp"></event>
+                                                            <event name="OnMotion"></event>
+                                                            <event name="OnMouseEvents"></event>
+                                                            <event name="OnMouseWheel"></event>
+                                                            <event name="OnPaint"></event>
+                                                            <event name="OnRightDClick"></event>
+                                                            <event name="OnRightDown"></event>
+                                                            <event name="OnRightUp"></event>
+                                                            <event name="OnSetFocus"></event>
+                                                            <event name="OnSize"></event>
+                                                            <event name="OnSpinCtrl"></event>
+                                                            <event name="OnSpinCtrlText"></event>
+                                                            <event name="OnTextEnter"></event>
+                                                            <event name="OnUpdateUI"></event>
+                                                        </object>
+                                                    </object>
+                                                    <object class="sizeritem" expanded="1">
+                                                        <property name="border">5</property>
+                                                        <property name="flag">wxALL|wxEXPAND</property>
+                                                        <property name="proportion">0</property>
+                                                        <object class="wxSpinCtrl" expanded="1">
+                                                            <property name="BottomDockable">1</property>
+                                                            <property name="LeftDockable">1</property>
+                                                            <property name="RightDockable">1</property>
+                                                            <property name="TopDockable">1</property>
+                                                            <property name="aui_layer"></property>
+                                                            <property name="aui_name"></property>
+                                                            <property name="aui_position"></property>
+                                                            <property name="aui_row"></property>
+                                                            <property name="best_size"></property>
+                                                            <property name="bg"></property>
+                                                            <property name="caption"></property>
+                                                            <property name="caption_visible">1</property>
+                                                            <property name="center_pane">0</property>
+                                                            <property name="close_button">1</property>
+                                                            <property name="context_help"></property>
+                                                            <property name="context_menu">1</property>
+                                                            <property name="default_pane">0</property>
+                                                            <property name="dock">Dock</property>
+                                                            <property name="dock_fixed">0</property>
+                                                            <property name="docking">Left</property>
+                                                            <property name="enabled">1</property>
+                                                            <property name="fg"></property>
+                                                            <property name="floatable">1</property>
+                                                            <property name="font"></property>
+                                                            <property name="gripper">0</property>
+                                                            <property name="hidden">0</property>
+                                                            <property name="id">wxID_ANY</property>
+                                                            <property name="initial">0</property>
+                                                            <property name="max">1000</property>
+                                                            <property name="max_size"></property>
+                                                            <property name="maximize_button">0</property>
+                                                            <property name="maximum_size"></property>
+                                                            <property name="min">0</property>
+                                                            <property name="min_size"></property>
+                                                            <property name="minimize_button">0</property>
+                                                            <property name="minimum_size"></property>
+                                                            <property name="moveable">1</property>
+                                                            <property name="name">m_spinCtrlGridSecAxisNumberingStep</property>
+                                                            <property name="pane_border">1</property>
+                                                            <property name="pane_position"></property>
+                                                            <property name="pane_size"></property>
+                                                            <property name="permission">protected</property>
+                                                            <property name="pin_button">1</property>
+                                                            <property name="pos"></property>
+                                                            <property name="resize">Resizable</property>
+                                                            <property name="show">1</property>
+                                                            <property name="size"></property>
+                                                            <property name="style">wxSP_ARROW_KEYS</property>
+                                                            <property name="subclass"></property>
+                                                            <property name="toolbar_pane">0</property>
+                                                            <property name="tooltip"></property>
+                                                            <property name="value">1</property>
+                                                            <property name="window_extra_style"></property>
+                                                            <property name="window_name"></property>
+                                                            <property name="window_style"></property>
+                                                            <event name="OnChar"></event>
+                                                            <event name="OnEnterWindow"></event>
+                                                            <event name="OnEraseBackground"></event>
+                                                            <event name="OnKeyDown"></event>
+                                                            <event name="OnKeyUp"></event>
+                                                            <event name="OnKillFocus"></event>
+                                                            <event name="OnLeaveWindow"></event>
+                                                            <event name="OnLeftDClick"></event>
+                                                            <event name="OnLeftDown"></event>
+                                                            <event name="OnLeftUp"></event>
+                                                            <event name="OnMiddleDClick"></event>
+                                                            <event name="OnMiddleDown"></event>
+                                                            <event name="OnMiddleUp"></event>
+                                                            <event name="OnMotion"></event>
+                                                            <event name="OnMouseEvents"></event>
+                                                            <event name="OnMouseWheel"></event>
+                                                            <event name="OnPaint"></event>
+                                                            <event name="OnRightDClick"></event>
+                                                            <event name="OnRightDown"></event>
+                                                            <event name="OnRightUp"></event>
+                                                            <event name="OnSetFocus"></event>
+                                                            <event name="OnSize"></event>
+                                                            <event name="OnSpinCtrl"></event>
+                                                            <event name="OnSpinCtrlText"></event>
+                                                            <event name="OnTextEnter"></event>
+                                                            <event name="OnUpdateUI"></event>
+                                                        </object>
+                                                    </object>
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem" expanded="1">
+                                                <property name="border">5</property>
+                                                <property name="flag">wxEXPAND</property>
+                                                <property name="proportion">0</property>
+                                                <object class="wxBoxSizer" expanded="1">
+                                                    <property name="minimum_size"></property>
+                                                    <property name="name">bSizer5</property>
+                                                    <property name="orient">wxHORIZONTAL</property>
+                                                    <property name="permission">none</property>
                                                 </object>
                                             </object>
                                         </object>
@@ -4459,7 +4732,7 @@
                                                     <property name="window_name"></property>
                                                     <property name="window_style"></property>
                                                     <event name="OnChar"></event>
-                                                    <event name="OnCheckBox"></event>
+                                                    <event name="OnCheckBox">OnParameterChanged</event>
                                                     <event name="OnEnterWindow"></event>
                                                     <event name="OnEraseBackground"></event>
                                                     <event name="OnKeyDown"></event>
@@ -4659,11 +4932,14 @@
                                                 <property name="border">5</property>
                                                 <property name="flag">wxEXPAND</property>
                                                 <property name="proportion">0</property>
-                                                <object class="wxBoxSizer" expanded="0">
+                                                <object class="wxGridSizer" expanded="0">
+                                                    <property name="cols">2</property>
+                                                    <property name="hgap">0</property>
                                                     <property name="minimum_size"></property>
-                                                    <property name="name">bSizer7</property>
-                                                    <property name="orient">wxHORIZONTAL</property>
+                                                    <property name="name">gSizer2</property>
                                                     <property name="permission">none</property>
+                                                    <property name="rows">0</property>
+                                                    <property name="vgap">0</property>
                                                     <object class="sizeritem" expanded="0">
                                                         <property name="border">5</property>
                                                         <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
@@ -4749,7 +5025,7 @@
                                                     </object>
                                                     <object class="sizeritem" expanded="0">
                                                         <property name="border">5</property>
-                                                        <property name="flag">wxALL</property>
+                                                        <property name="flag">wxALL|wxEXPAND</property>
                                                         <property name="proportion">0</property>
                                                         <object class="wxTextCtrl" expanded="0">
                                                             <property name="BottomDockable">1</property>
@@ -4838,6 +5114,177 @@
                                                             <event name="OnUpdateUI"></event>
                                                         </object>
                                                     </object>
+                                                    <object class="sizeritem" expanded="1">
+                                                        <property name="border">5</property>
+                                                        <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+                                                        <property name="proportion">0</property>
+                                                        <object class="wxStaticText" expanded="1">
+                                                            <property name="BottomDockable">1</property>
+                                                            <property name="LeftDockable">1</property>
+                                                            <property name="RightDockable">1</property>
+                                                            <property name="TopDockable">1</property>
+                                                            <property name="aui_layer"></property>
+                                                            <property name="aui_name"></property>
+                                                            <property name="aui_position"></property>
+                                                            <property name="aui_row"></property>
+                                                            <property name="best_size"></property>
+                                                            <property name="bg"></property>
+                                                            <property name="caption"></property>
+                                                            <property name="caption_visible">1</property>
+                                                            <property name="center_pane">0</property>
+                                                            <property name="close_button">1</property>
+                                                            <property name="context_help"></property>
+                                                            <property name="context_menu">1</property>
+                                                            <property name="default_pane">0</property>
+                                                            <property name="dock">Dock</property>
+                                                            <property name="dock_fixed">0</property>
+                                                            <property name="docking">Left</property>
+                                                            <property name="enabled">1</property>
+                                                            <property name="fg"></property>
+                                                            <property name="floatable">1</property>
+                                                            <property name="font"></property>
+                                                            <property name="gripper">0</property>
+                                                            <property name="hidden">0</property>
+                                                            <property name="id">wxID_ANY</property>
+                                                            <property name="label">Numbering step:</property>
+                                                            <property name="max_size"></property>
+                                                            <property name="maximize_button">0</property>
+                                                            <property name="maximum_size"></property>
+                                                            <property name="min_size"></property>
+                                                            <property name="minimize_button">0</property>
+                                                            <property name="minimum_size"></property>
+                                                            <property name="moveable">1</property>
+                                                            <property name="name">m_labelCircNumberingStep</property>
+                                                            <property name="pane_border">1</property>
+                                                            <property name="pane_position"></property>
+                                                            <property name="pane_size"></property>
+                                                            <property name="permission">protected</property>
+                                                            <property name="pin_button">1</property>
+                                                            <property name="pos"></property>
+                                                            <property name="resize">Resizable</property>
+                                                            <property name="show">1</property>
+                                                            <property name="size"></property>
+                                                            <property name="style"></property>
+                                                            <property name="subclass"></property>
+                                                            <property name="toolbar_pane">0</property>
+                                                            <property name="tooltip"></property>
+                                                            <property name="window_extra_style"></property>
+                                                            <property name="window_name"></property>
+                                                            <property name="window_style"></property>
+                                                            <property name="wrap">-1</property>
+                                                            <event name="OnChar"></event>
+                                                            <event name="OnEnterWindow"></event>
+                                                            <event name="OnEraseBackground"></event>
+                                                            <event name="OnKeyDown"></event>
+                                                            <event name="OnKeyUp"></event>
+                                                            <event name="OnKillFocus"></event>
+                                                            <event name="OnLeaveWindow"></event>
+                                                            <event name="OnLeftDClick"></event>
+                                                            <event name="OnLeftDown"></event>
+                                                            <event name="OnLeftUp"></event>
+                                                            <event name="OnMiddleDClick"></event>
+                                                            <event name="OnMiddleDown"></event>
+                                                            <event name="OnMiddleUp"></event>
+                                                            <event name="OnMotion"></event>
+                                                            <event name="OnMouseEvents"></event>
+                                                            <event name="OnMouseWheel"></event>
+                                                            <event name="OnPaint"></event>
+                                                            <event name="OnRightDClick"></event>
+                                                            <event name="OnRightDown"></event>
+                                                            <event name="OnRightUp"></event>
+                                                            <event name="OnSetFocus"></event>
+                                                            <event name="OnSize"></event>
+                                                            <event name="OnUpdateUI"></event>
+                                                        </object>
+                                                    </object>
+                                                    <object class="sizeritem" expanded="1">
+                                                        <property name="border">5</property>
+                                                        <property name="flag">wxALL|wxEXPAND</property>
+                                                        <property name="proportion">0</property>
+                                                        <object class="wxSpinCtrl" expanded="1">
+                                                            <property name="BottomDockable">1</property>
+                                                            <property name="LeftDockable">1</property>
+                                                            <property name="RightDockable">1</property>
+                                                            <property name="TopDockable">1</property>
+                                                            <property name="aui_layer"></property>
+                                                            <property name="aui_name"></property>
+                                                            <property name="aui_position"></property>
+                                                            <property name="aui_row"></property>
+                                                            <property name="best_size"></property>
+                                                            <property name="bg"></property>
+                                                            <property name="caption"></property>
+                                                            <property name="caption_visible">1</property>
+                                                            <property name="center_pane">0</property>
+                                                            <property name="close_button">1</property>
+                                                            <property name="context_help"></property>
+                                                            <property name="context_menu">1</property>
+                                                            <property name="default_pane">0</property>
+                                                            <property name="dock">Dock</property>
+                                                            <property name="dock_fixed">0</property>
+                                                            <property name="docking">Left</property>
+                                                            <property name="enabled">1</property>
+                                                            <property name="fg"></property>
+                                                            <property name="floatable">1</property>
+                                                            <property name="font"></property>
+                                                            <property name="gripper">0</property>
+                                                            <property name="hidden">0</property>
+                                                            <property name="id">wxID_ANY</property>
+                                                            <property name="initial">0</property>
+                                                            <property name="max">1000</property>
+                                                            <property name="max_size"></property>
+                                                            <property name="maximize_button">0</property>
+                                                            <property name="maximum_size"></property>
+                                                            <property name="min">0</property>
+                                                            <property name="min_size"></property>
+                                                            <property name="minimize_button">0</property>
+                                                            <property name="minimum_size"></property>
+                                                            <property name="moveable">1</property>
+                                                            <property name="name">m_spinCtrlCircNumberingStep</property>
+                                                            <property name="pane_border">1</property>
+                                                            <property name="pane_position"></property>
+                                                            <property name="pane_size"></property>
+                                                            <property name="permission">protected</property>
+                                                            <property name="pin_button">1</property>
+                                                            <property name="pos"></property>
+                                                            <property name="resize">Resizable</property>
+                                                            <property name="show">1</property>
+                                                            <property name="size"></property>
+                                                            <property name="style">wxSP_ARROW_KEYS</property>
+                                                            <property name="subclass"></property>
+                                                            <property name="toolbar_pane">0</property>
+                                                            <property name="tooltip"></property>
+                                                            <property name="value">1</property>
+                                                            <property name="window_extra_style"></property>
+                                                            <property name="window_name"></property>
+                                                            <property name="window_style"></property>
+                                                            <event name="OnChar"></event>
+                                                            <event name="OnEnterWindow"></event>
+                                                            <event name="OnEraseBackground"></event>
+                                                            <event name="OnKeyDown"></event>
+                                                            <event name="OnKeyUp"></event>
+                                                            <event name="OnKillFocus"></event>
+                                                            <event name="OnLeaveWindow"></event>
+                                                            <event name="OnLeftDClick"></event>
+                                                            <event name="OnLeftDown"></event>
+                                                            <event name="OnLeftUp"></event>
+                                                            <event name="OnMiddleDClick"></event>
+                                                            <event name="OnMiddleDown"></event>
+                                                            <event name="OnMiddleUp"></event>
+                                                            <event name="OnMotion"></event>
+                                                            <event name="OnMouseEvents"></event>
+                                                            <event name="OnMouseWheel"></event>
+                                                            <event name="OnPaint"></event>
+                                                            <event name="OnRightDClick"></event>
+                                                            <event name="OnRightDown"></event>
+                                                            <event name="OnRightUp"></event>
+                                                            <event name="OnSetFocus"></event>
+                                                            <event name="OnSize"></event>
+                                                            <event name="OnSpinCtrl"></event>
+                                                            <event name="OnSpinCtrlText"></event>
+                                                            <event name="OnTextEnter"></event>
+                                                            <event name="OnUpdateUI"></event>
+                                                        </object>
+                                                    </object>
                                                 </object>
                                             </object>
                                         </object>
diff --git a/pcbnew/dialogs/dialog_create_array_base.h b/pcbnew/dialogs/dialog_create_array_base.h
index bfedc27..e8a0b9f 100644
--- a/pcbnew/dialogs/dialog_create_array_base.h
+++ b/pcbnew/dialogs/dialog_create_array_base.h
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jun  5 2014)
+// C++ code generated with wxFormBuilder (version Jun  6 2014)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -25,6 +25,7 @@ class DIALOG_SHIM;
 #include <wx/gbsizer.h>
 #include <wx/checkbox.h>
 #include <wx/choice.h>
+#include <wx/spinctrl.h>
 #include <wx/sizer.h>
 #include <wx/panel.h>
 #include <wx/bitmap.h>
@@ -78,6 +79,9 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
 		wxStaticText* m_labelGridNumberingOffset;
 		wxTextCtrl* m_entryGridPriNumberingOffset;
 		wxTextCtrl* m_entryGridSecNumberingOffset;
+		wxStaticText* m_labelGridNumberingStep;
+		wxSpinCtrl* m_spinCtrlGridPriAxisNumberingStep;
+		wxSpinCtrl* m_spinCtrlGridSecAxisNumberingStep;
 		wxPanel* m_circularPanel;
 		wxStaticText* m_labelCentreX;
 		wxTextCtrl* m_entryCentreX;
@@ -99,6 +103,8 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
 		wxChoice* m_choiceCircNumberingType;
 		wxStaticText* m_labelCircNumStart;
 		wxTextCtrl* m_entryCircNumberingStart;
+		wxStaticText* m_labelCircNumberingStep;
+		wxSpinCtrl* m_spinCtrlCircNumberingStep;
 		wxStdDialogButtonSizer* m_stdButtons;
 		wxButton* m_stdButtonsOK;
 		wxButton* m_stdButtonsCancel;
-- 
1.9.1

>From 11b4c43d43a1d2741a878f82bdac3047a6a9a717 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Fri, 10 Jul 2015 00:36:39 +0100
Subject: [PATCH 2/3] Allow circular grids to be specified relative to items as
 well as absolutely

---
 pcbnew/dialogs/dialog_create_array.cpp      |  20 ++-
 pcbnew/dialogs/dialog_create_array.h        |   5 +-
 pcbnew/dialogs/dialog_create_array_base.cpp |  27 ++--
 pcbnew/dialogs/dialog_create_array_base.fbp | 193 ++++++++++++++++++++++++++--
 pcbnew/dialogs/dialog_create_array_base.h   |   2 +
 5 files changed, 226 insertions(+), 21 deletions(-)

diff --git a/pcbnew/dialogs/dialog_create_array.cpp b/pcbnew/dialogs/dialog_create_array.cpp
index d42134f..a33a524 100644
--- a/pcbnew/dialogs/dialog_create_array.cpp
+++ b/pcbnew/dialogs/dialog_create_array.cpp
@@ -79,6 +79,7 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrig
 
     Add( m_entryCentreX, m_options.m_circCentreX );
     Add( m_entryCentreY, m_options.m_circCentreY );
+    Add( m_entryCircRelativeCentreCb, m_options.m_circRelativeCentre );
     Add( m_entryCircAngle, m_options.m_circAngle );
     Add( m_entryCircCount, m_options.m_circCount );
     Add( m_entryRotateItemsCb, m_options.m_circRotate );
@@ -132,7 +133,8 @@ void DIALOG_CREATE_ARRAY::OnParameterChanged( wxCommandEvent& event )
         setControlEnablement();
     }
 
-    if( evObj == m_entryCentreX || evObj == m_entryCentreY )
+    if( evObj == m_entryCentreX || evObj == m_entryCentreY
+        || evObj == m_entryCircRelativeCentreCb )
     {
         calculateCircularArrayProperties();
     }
@@ -289,6 +291,8 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
         newCirc->m_centre.x = DoubleValueFromString( g_UserUnit, m_entryCentreX->GetValue() );
         newCirc->m_centre.y = DoubleValueFromString( g_UserUnit, m_entryCentreY->GetValue() );
 
+        newCirc->m_relativeCentre = m_entryCircRelativeCentreCb->GetValue();
+
         newCirc->m_angle = DoubleValueFromString( DEGREES, m_entryCircAngle->GetValue() );
         ok = ok && m_entryCircCount->GetValue().ToLong( &newCirc->m_nPts );
 
@@ -371,7 +375,12 @@ void DIALOG_CREATE_ARRAY::calculateCircularArrayProperties()
     centre.y = DoubleValueFromString( g_UserUnit, m_entryCentreY->GetValue() );
 
     // Find the radius, etc of the circle
-    centre -= m_originalItemPosition;
+
+    // If the centre is not relative, the radius is between the original item
+    // and the given point, otherwise we don't need to consider the original
+    // location - the radius is just the length of the vector
+    if ( !m_entryCircRelativeCentreCb->GetValue() )
+        centre -= m_originalItemPosition;
 
     const double radius = VECTOR2I(centre.x, centre.y).EuclideanNorm();
     m_labelCircRadiusValue->SetLabelText( StringFromValue( g_UserUnit, int(radius), true ) );
@@ -523,7 +532,12 @@ void DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::TransformItem( int n, BOARD_IT
         // n'th step
         angle = m_angle * n;
 
-    item->Rotate( m_centre, angle );
+    wxPoint centre = m_centre;
+
+    if ( m_relativeCentre )
+        centre += item->GetCenter();
+
+    item->Rotate( centre, angle );
 
     // take off the rotation (but not the translation) if needed
     if( !m_rotateItems )
diff --git a/pcbnew/dialogs/dialog_create_array.h b/pcbnew/dialogs/dialog_create_array.h
index c130c55..6c06d03 100644
--- a/pcbnew/dialogs/dialog_create_array.h
+++ b/pcbnew/dialogs/dialog_create_array.h
@@ -289,6 +289,7 @@ private:
             ARRAY_OPTIONS( ARRAY_CIRCULAR ),
             m_nPts( 0 ),
             m_angle( 0.0f ),
+            m_relativeCentre( false ),
             m_rotateItems( false ),
             m_numberingType( NUMBERING_NUMERIC ),
             m_numberingOffset( 0 ),
@@ -298,6 +299,7 @@ private:
         long m_nPts;
         double m_angle;
         wxPoint m_centre;
+        bool m_relativeCentre;
         bool m_rotateItems;
         ARRAY_NUMBERING_TYPE_T m_numberingType;
         long m_numberingOffset;
@@ -346,6 +348,7 @@ private:
             m_gridPriAxisNumberingStep( 1 ),
             m_gridSecAxisNumberingStep( 1 ),
             m_circRotate( false ),
+            m_circRelativeCentre( false ),
             m_circNumberingStep( 1 ),
             m_arrayTypeTab( 0 )
         {}
@@ -366,7 +369,7 @@ private:
 
         std::string m_circCentreX, m_circCentreY,
                     m_circAngle, m_circCount, m_circNumberingOffset;
-        bool m_circRotate;
+        bool m_circRotate, m_circRelativeCentre;
         int m_circNumberingStep;
 
         int m_arrayTypeTab;
diff --git a/pcbnew/dialogs/dialog_create_array_base.cpp b/pcbnew/dialogs/dialog_create_array_base.cpp
index 2379f79..c5940f2 100644
--- a/pcbnew/dialogs/dialog_create_array_base.cpp
+++ b/pcbnew/dialogs/dialog_create_array_base.cpp
@@ -215,45 +215,52 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
 	m_unitLabelCentreY->Wrap( -1 );
 	gbSizer2->Add( m_unitLabelCentreY, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL, 5 );
 	
+	m_labelCircRelativeCentre = new wxStaticText( m_circularPanel, wxID_ANY, _("Relative:"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_labelCircRelativeCentre->Wrap( -1 );
+	gbSizer2->Add( m_labelCircRelativeCentre, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+	
+	m_entryCircRelativeCentreCb = new wxCheckBox( m_circularPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+	gbSizer2->Add( m_entryCircRelativeCentreCb, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+	
 	m_labelCircRadius = new wxStaticText( m_circularPanel, wxID_ANY, _("Radius:"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_labelCircRadius->Wrap( -1 );
-	gbSizer2->Add( m_labelCircRadius, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+	gbSizer2->Add( m_labelCircRadius, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
 	
 	m_labelCircRadiusValue = new wxStaticText( m_circularPanel, wxID_ANY, _("0 mm"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_labelCircRadiusValue->Wrap( -1 );
-	gbSizer2->Add( m_labelCircRadiusValue, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+	gbSizer2->Add( m_labelCircRadiusValue, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
 	
 	m_labelCircAngle = new wxStaticText( m_circularPanel, wxID_ANY, _("Angle:"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_labelCircAngle->Wrap( -1 );
-	gbSizer2->Add( m_labelCircAngle, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+	gbSizer2->Add( m_labelCircAngle, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
 	
 	m_entryCircAngle = new wxTextCtrl( m_circularPanel, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_entryCircAngle->SetToolTip( _("Positive angles represent an anti-clockwise rotation. An angle of 0 will produce a full circle divided evenly into \"Count\" portions.") );
 	
-	gbSizer2->Add( m_entryCircAngle, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+	gbSizer2->Add( m_entryCircAngle, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
 	
 	m_unitLabelCircAngle = new wxStaticText( m_circularPanel, wxID_ANY, _("deg"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_unitLabelCircAngle->Wrap( -1 );
-	gbSizer2->Add( m_unitLabelCircAngle, wxGBPosition( 3, 2 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+	gbSizer2->Add( m_unitLabelCircAngle, wxGBPosition( 4, 2 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL, 5 );
 	
 	m_labelCircCount = new wxStaticText( m_circularPanel, wxID_ANY, _("Count:"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_labelCircCount->Wrap( -1 );
-	gbSizer2->Add( m_labelCircCount, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+	gbSizer2->Add( m_labelCircCount, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
 	
 	m_entryCircCount = new wxTextCtrl( m_circularPanel, wxID_ANY, _("4"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_entryCircCount->SetToolTip( _("How many items in the array.") );
 	
-	gbSizer2->Add( m_entryCircCount, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+	gbSizer2->Add( m_entryCircCount, wxGBPosition( 5, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
 	
 	m_labelCircRotate = new wxStaticText( m_circularPanel, wxID_ANY, _("Rotate:"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_labelCircRotate->Wrap( -1 );
-	gbSizer2->Add( m_labelCircRotate, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+	gbSizer2->Add( m_labelCircRotate, wxGBPosition( 6, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
 	
 	m_entryRotateItemsCb = new wxCheckBox( m_circularPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
 	m_entryRotateItemsCb->SetValue(true); 
 	m_entryRotateItemsCb->SetToolTip( _("Rotate the item as well as move it - multi-selections will be rotated together") );
 	
-	gbSizer2->Add( m_entryRotateItemsCb, wxGBPosition( 5, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+	gbSizer2->Add( m_entryRotateItemsCb, wxGBPosition( 6, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
 	
 	
 	bSizer4->Add( gbSizer2, 0, wxALL|wxEXPAND, 5 );
@@ -332,6 +339,7 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
 	m_radioBoxGridNumberingScheme->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_entryCentreX->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_entryCentreY->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+	m_entryCircRelativeCentreCb->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_entryCircAngle->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_entryCircCount->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_checkBoxCircRestartNumbering->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
@@ -353,6 +361,7 @@ DIALOG_CREATE_ARRAY_BASE::~DIALOG_CREATE_ARRAY_BASE()
 	m_radioBoxGridNumberingScheme->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_entryCentreX->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_entryCentreY->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+	m_entryCircRelativeCentreCb->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_entryCircAngle->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_entryCircCount->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
 	m_checkBoxCircRestartNumbering->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
diff --git a/pcbnew/dialogs/dialog_create_array_base.fbp b/pcbnew/dialogs/dialog_create_array_base.fbp
index 4d10147..21d47c2 100644
--- a/pcbnew/dialogs/dialog_create_array_base.fbp
+++ b/pcbnew/dialogs/dialog_create_array_base.fbp
@@ -3898,6 +3898,183 @@
                                                     <property name="gripper">0</property>
                                                     <property name="hidden">0</property>
                                                     <property name="id">wxID_ANY</property>
+                                                    <property name="label">Relative:</property>
+                                                    <property name="max_size"></property>
+                                                    <property name="maximize_button">0</property>
+                                                    <property name="maximum_size"></property>
+                                                    <property name="min_size"></property>
+                                                    <property name="minimize_button">0</property>
+                                                    <property name="minimum_size"></property>
+                                                    <property name="moveable">1</property>
+                                                    <property name="name">m_labelCircRelativeCentre</property>
+                                                    <property name="pane_border">1</property>
+                                                    <property name="pane_position"></property>
+                                                    <property name="pane_size"></property>
+                                                    <property name="permission">protected</property>
+                                                    <property name="pin_button">1</property>
+                                                    <property name="pos"></property>
+                                                    <property name="resize">Resizable</property>
+                                                    <property name="show">1</property>
+                                                    <property name="size"></property>
+                                                    <property name="style"></property>
+                                                    <property name="subclass"></property>
+                                                    <property name="toolbar_pane">0</property>
+                                                    <property name="tooltip"></property>
+                                                    <property name="window_extra_style"></property>
+                                                    <property name="window_name"></property>
+                                                    <property name="window_style"></property>
+                                                    <property name="wrap">-1</property>
+                                                    <event name="OnChar"></event>
+                                                    <event name="OnEnterWindow"></event>
+                                                    <event name="OnEraseBackground"></event>
+                                                    <event name="OnKeyDown"></event>
+                                                    <event name="OnKeyUp"></event>
+                                                    <event name="OnKillFocus"></event>
+                                                    <event name="OnLeaveWindow"></event>
+                                                    <event name="OnLeftDClick"></event>
+                                                    <event name="OnLeftDown"></event>
+                                                    <event name="OnLeftUp"></event>
+                                                    <event name="OnMiddleDClick"></event>
+                                                    <event name="OnMiddleDown"></event>
+                                                    <event name="OnMiddleUp"></event>
+                                                    <event name="OnMotion"></event>
+                                                    <event name="OnMouseEvents"></event>
+                                                    <event name="OnMouseWheel"></event>
+                                                    <event name="OnPaint"></event>
+                                                    <event name="OnRightDClick"></event>
+                                                    <event name="OnRightDown"></event>
+                                                    <event name="OnRightUp"></event>
+                                                    <event name="OnSetFocus"></event>
+                                                    <event name="OnSize"></event>
+                                                    <event name="OnUpdateUI"></event>
+                                                </object>
+                                            </object>
+                                            <object class="gbsizeritem" expanded="1">
+                                                <property name="border">5</property>
+                                                <property name="colspan">1</property>
+                                                <property name="column">1</property>
+                                                <property name="flag">wxALL</property>
+                                                <property name="row">2</property>
+                                                <property name="rowspan">1</property>
+                                                <object class="wxCheckBox" expanded="1">
+                                                    <property name="BottomDockable">1</property>
+                                                    <property name="LeftDockable">1</property>
+                                                    <property name="RightDockable">1</property>
+                                                    <property name="TopDockable">1</property>
+                                                    <property name="aui_layer"></property>
+                                                    <property name="aui_name"></property>
+                                                    <property name="aui_position"></property>
+                                                    <property name="aui_row"></property>
+                                                    <property name="best_size"></property>
+                                                    <property name="bg"></property>
+                                                    <property name="caption"></property>
+                                                    <property name="caption_visible">1</property>
+                                                    <property name="center_pane">0</property>
+                                                    <property name="checked">0</property>
+                                                    <property name="close_button">1</property>
+                                                    <property name="context_help"></property>
+                                                    <property name="context_menu">1</property>
+                                                    <property name="default_pane">0</property>
+                                                    <property name="dock">Dock</property>
+                                                    <property name="dock_fixed">0</property>
+                                                    <property name="docking">Left</property>
+                                                    <property name="enabled">1</property>
+                                                    <property name="fg"></property>
+                                                    <property name="floatable">1</property>
+                                                    <property name="font"></property>
+                                                    <property name="gripper">0</property>
+                                                    <property name="hidden">0</property>
+                                                    <property name="id">wxID_ANY</property>
+                                                    <property name="label"></property>
+                                                    <property name="max_size"></property>
+                                                    <property name="maximize_button">0</property>
+                                                    <property name="maximum_size"></property>
+                                                    <property name="min_size"></property>
+                                                    <property name="minimize_button">0</property>
+                                                    <property name="minimum_size"></property>
+                                                    <property name="moveable">1</property>
+                                                    <property name="name">m_entryCircRelativeCentreCb</property>
+                                                    <property name="pane_border">1</property>
+                                                    <property name="pane_position"></property>
+                                                    <property name="pane_size"></property>
+                                                    <property name="permission">protected</property>
+                                                    <property name="pin_button">1</property>
+                                                    <property name="pos"></property>
+                                                    <property name="resize">Resizable</property>
+                                                    <property name="show">1</property>
+                                                    <property name="size"></property>
+                                                    <property name="style"></property>
+                                                    <property name="subclass"></property>
+                                                    <property name="toolbar_pane">0</property>
+                                                    <property name="tooltip"></property>
+                                                    <property name="validator_data_type"></property>
+                                                    <property name="validator_style">wxFILTER_NONE</property>
+                                                    <property name="validator_type">wxDefaultValidator</property>
+                                                    <property name="validator_variable"></property>
+                                                    <property name="window_extra_style"></property>
+                                                    <property name="window_name"></property>
+                                                    <property name="window_style"></property>
+                                                    <event name="OnChar"></event>
+                                                    <event name="OnCheckBox">OnParameterChanged</event>
+                                                    <event name="OnEnterWindow"></event>
+                                                    <event name="OnEraseBackground"></event>
+                                                    <event name="OnKeyDown"></event>
+                                                    <event name="OnKeyUp"></event>
+                                                    <event name="OnKillFocus"></event>
+                                                    <event name="OnLeaveWindow"></event>
+                                                    <event name="OnLeftDClick"></event>
+                                                    <event name="OnLeftDown"></event>
+                                                    <event name="OnLeftUp"></event>
+                                                    <event name="OnMiddleDClick"></event>
+                                                    <event name="OnMiddleDown"></event>
+                                                    <event name="OnMiddleUp"></event>
+                                                    <event name="OnMotion"></event>
+                                                    <event name="OnMouseEvents"></event>
+                                                    <event name="OnMouseWheel"></event>
+                                                    <event name="OnPaint"></event>
+                                                    <event name="OnRightDClick"></event>
+                                                    <event name="OnRightDown"></event>
+                                                    <event name="OnRightUp"></event>
+                                                    <event name="OnSetFocus"></event>
+                                                    <event name="OnSize"></event>
+                                                    <event name="OnUpdateUI"></event>
+                                                </object>
+                                            </object>
+                                            <object class="gbsizeritem" expanded="1">
+                                                <property name="border">5</property>
+                                                <property name="colspan">1</property>
+                                                <property name="column">0</property>
+                                                <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+                                                <property name="row">3</property>
+                                                <property name="rowspan">1</property>
+                                                <object class="wxStaticText" expanded="1">
+                                                    <property name="BottomDockable">1</property>
+                                                    <property name="LeftDockable">1</property>
+                                                    <property name="RightDockable">1</property>
+                                                    <property name="TopDockable">1</property>
+                                                    <property name="aui_layer"></property>
+                                                    <property name="aui_name"></property>
+                                                    <property name="aui_position"></property>
+                                                    <property name="aui_row"></property>
+                                                    <property name="best_size"></property>
+                                                    <property name="bg"></property>
+                                                    <property name="caption"></property>
+                                                    <property name="caption_visible">1</property>
+                                                    <property name="center_pane">0</property>
+                                                    <property name="close_button">1</property>
+                                                    <property name="context_help"></property>
+                                                    <property name="context_menu">1</property>
+                                                    <property name="default_pane">0</property>
+                                                    <property name="dock">Dock</property>
+                                                    <property name="dock_fixed">0</property>
+                                                    <property name="docking">Left</property>
+                                                    <property name="enabled">1</property>
+                                                    <property name="fg"></property>
+                                                    <property name="floatable">1</property>
+                                                    <property name="font"></property>
+                                                    <property name="gripper">0</property>
+                                                    <property name="hidden">0</property>
+                                                    <property name="id">wxID_ANY</property>
                                                     <property name="label">Radius:</property>
                                                     <property name="max_size"></property>
                                                     <property name="maximize_button">0</property>
@@ -3954,7 +4131,7 @@
                                                 <property name="colspan">1</property>
                                                 <property name="column">1</property>
                                                 <property name="flag">wxALL</property>
-                                                <property name="row">2</property>
+                                                <property name="row">3</property>
                                                 <property name="rowspan">1</property>
                                                 <object class="wxStaticText" expanded="0">
                                                     <property name="BottomDockable">1</property>
@@ -4040,7 +4217,7 @@
                                                 <property name="colspan">1</property>
                                                 <property name="column">0</property>
                                                 <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
-                                                <property name="row">3</property>
+                                                <property name="row">4</property>
                                                 <property name="rowspan">1</property>
                                                 <object class="wxStaticText" expanded="0">
                                                     <property name="BottomDockable">1</property>
@@ -4126,7 +4303,7 @@
                                                 <property name="colspan">1</property>
                                                 <property name="column">1</property>
                                                 <property name="flag">wxALL</property>
-                                                <property name="row">3</property>
+                                                <property name="row">4</property>
                                                 <property name="rowspan">1</property>
                                                 <object class="wxTextCtrl" expanded="0">
                                                     <property name="BottomDockable">1</property>
@@ -4220,7 +4397,7 @@
                                                 <property name="colspan">1</property>
                                                 <property name="column">2</property>
                                                 <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
-                                                <property name="row">3</property>
+                                                <property name="row">4</property>
                                                 <property name="rowspan">1</property>
                                                 <object class="wxStaticText" expanded="0">
                                                     <property name="BottomDockable">1</property>
@@ -4306,7 +4483,7 @@
                                                 <property name="colspan">1</property>
                                                 <property name="column">0</property>
                                                 <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
-                                                <property name="row">4</property>
+                                                <property name="row">5</property>
                                                 <property name="rowspan">1</property>
                                                 <object class="wxStaticText" expanded="0">
                                                     <property name="BottomDockable">1</property>
@@ -4392,7 +4569,7 @@
                                                 <property name="colspan">1</property>
                                                 <property name="column">1</property>
                                                 <property name="flag">wxALL</property>
-                                                <property name="row">4</property>
+                                                <property name="row">5</property>
                                                 <property name="rowspan">1</property>
                                                 <object class="wxTextCtrl" expanded="0">
                                                     <property name="BottomDockable">1</property>
@@ -4486,7 +4663,7 @@
                                                 <property name="colspan">1</property>
                                                 <property name="column">0</property>
                                                 <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
-                                                <property name="row">5</property>
+                                                <property name="row">6</property>
                                                 <property name="rowspan">1</property>
                                                 <object class="wxStaticText" expanded="0">
                                                     <property name="BottomDockable">1</property>
@@ -4572,7 +4749,7 @@
                                                 <property name="colspan">1</property>
                                                 <property name="column">1</property>
                                                 <property name="flag">wxALL</property>
-                                                <property name="row">5</property>
+                                                <property name="row">6</property>
                                                 <property name="rowspan">1</property>
                                                 <object class="wxCheckBox" expanded="0">
                                                     <property name="BottomDockable">1</property>
diff --git a/pcbnew/dialogs/dialog_create_array_base.h b/pcbnew/dialogs/dialog_create_array_base.h
index e8a0b9f..223f21d 100644
--- a/pcbnew/dialogs/dialog_create_array_base.h
+++ b/pcbnew/dialogs/dialog_create_array_base.h
@@ -89,6 +89,8 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
 		wxStaticText* m_labelCentreY;
 		wxTextCtrl* m_entryCentreY;
 		wxStaticText* m_unitLabelCentreY;
+		wxStaticText* m_labelCircRelativeCentre;
+		wxCheckBox* m_entryCircRelativeCentreCb;
 		wxStaticText* m_labelCircRadius;
 		wxStaticText* m_labelCircRadiusValue;
 		wxStaticText* m_labelCircAngle;
-- 
1.9.1

>From 397614b955b720157eb4d7c215a57e98189df304 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Tue, 14 Jul 2015 23:43:26 +0100
Subject: [PATCH 3/3] Refactor some aspects of the Create Array tool

  * Use a re-usable "axis" definition for the array types, so that it
    it is easier and more repeatable to parse axis options for new
    array types
  * Abstract the validity of the save/restore config struct into a
    reusable struct
  * Use wxStrings more
  * Some general tidy-up and commentary
---
 pcbnew/dialogs/dialog_create_array.cpp | 121 +++++++++++------------
 pcbnew/dialogs/dialog_create_array.h   | 169 +++++++++++++++++++++++----------
 2 files changed, 177 insertions(+), 113 deletions(-)

diff --git a/pcbnew/dialogs/dialog_create_array.cpp b/pcbnew/dialogs/dialog_create_array.cpp
index a33a524..a3e8bc5 100644
--- a/pcbnew/dialogs/dialog_create_array.cpp
+++ b/pcbnew/dialogs/dialog_create_array.cpp
@@ -40,7 +40,7 @@ DIALOG_CREATE_ARRAY::CREATE_ARRAY_DIALOG_ENTRIES DIALOG_CREATE_ARRAY::m_options;
 DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrigPos,
                                           ARRAY_OPTIONS** aSettings ) :
     DIALOG_CREATE_ARRAY_BASE( aParent ),
-    CONFIG_SAVE_RESTORE_WINDOW( m_options.m_optionsSet ),
+    CONFIG_SAVE_RESTORE_WINDOW( m_options ),
     m_settings( aSettings ),
     m_originalItemPosition( aOrigPos )
 {
@@ -141,14 +141,14 @@ 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 std::string    alphaEmpty      = "";
+    static const wxString    alphaNumeric   = "0123456789";
+    static const wxString    alphaHex       = "0123456789ABCDEF";
+    static const wxString    alphaFull      = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    static const wxString    alphaNoIOSQXZ  = "ABCDEFGHJKLMNPRTUVWY";
+    static const wxString    alphaEmpty     = "";
 
     switch( type )
     {
@@ -183,11 +183,11 @@ 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 );
 
     wxASSERT_MSG( !alphabet.empty(), wxString(
                     "Unable to determine alphabet for numbering scheme: " ) << type );
@@ -217,6 +217,29 @@ static bool getNumberingOffset( const std::string& str,
 }
 
 
+bool DIALOG_CREATE_ARRAY::fillAxisFromControls( ARRAY_OPTIONS::AXIS_T& aAxis,
+        wxChoice* aAlphabetSelector,
+        wxTextCtrl* aOffsetEntry,
+        wxSpinCtrl* aStepEntry )
+{
+    // this is only correct if you set the choice up according to the enum size and order
+    bool ok = aAlphabetSelector->GetSelection() < NUMBERING_TYPE_Max;
+
+    if (ok)
+        aAxis.m_type = static_cast<ARRAY_NUMBERING_TYPE_T>(
+                aAlphabetSelector->GetSelection() );
+
+    ok = ok && getNumberingOffset(
+            aOffsetEntry->GetValue().ToStdString(),
+            aAxis.m_type, aAxis.m_offset );
+
+    if (ok)
+        aAxis.m_step = aStepEntry->GetValue();
+
+    return ok;
+}
+
+
 void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
 {
     ARRAY_OPTIONS* newSettings = NULL;
@@ -247,32 +270,18 @@ 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;
-
-        // 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_entryGridPriNumberingOffset->GetValue().ToStdString(),
-                newGrid->m_priAxisNumType, newGrid->m_numberingOffsetX );
-
-        newGrid->m_priAxisNumStep = m_spinCtrlGridPriAxisNumberingStep->GetValue();
+        ok = ok && fillAxisFromControls( newGrid->m_priAxis,
+                m_choicePriAxisNumbering,
+                m_entryGridPriNumberingOffset,
+                m_spinCtrlGridPriAxisNumberingStep );
 
         if( newGrid->m_2dArrayNumbering )
         {
-            ok = ok && getNumberingOffset(
-                    m_entryGridSecNumberingOffset->GetValue().ToStdString(),
-                    newGrid->m_secAxisNumType, newGrid->m_numberingOffsetY );
-            newGrid->m_secAxisNumStep = m_spinCtrlGridSecAxisNumberingStep->GetValue();
+            ok = ok && fillAxisFromControls( newGrid->m_secAxis,
+                    m_choiceSecAxisNumbering,
+                    m_entryGridSecNumberingOffset,
+                    m_spinCtrlGridSecAxisNumberingStep );
         }
 
         newGrid->m_shouldRenumber = m_checkBoxGridRestartNumbering->GetValue();
@@ -300,17 +309,10 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
 
         newCirc->m_shouldRenumber = m_checkBoxCircRestartNumbering->GetValue();
 
-        // This is only correct if you set the choice up according to the enum size and order
-        ok = ok && m_choiceCircNumberingType->GetSelection() < NUMBERING_TYPE_Max;
-
-        // Mind undefined casts to enums (should not be able to happen)
-        if( ok )
-            newCirc->m_numberingType =
-                (ARRAY_NUMBERING_TYPE_T) m_choiceCircNumberingType->GetSelection();
-
-        newCirc->m_numberingStep = m_spinCtrlCircNumberingStep->GetValue();
-
-        ok = ok && m_entryCircNumberingStart->GetValue().ToLong( &newCirc->m_numberingOffset );
+        ok = ok && fillAxisFromControls( newCirc->m_axis,
+                m_choiceCircNumberingType,
+                m_entryCircNumberingStart,
+                m_spinCtrlCircNumberingStep );
 
         // Only use settings if all values are good
         if( ok )
@@ -333,6 +335,7 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
     }
 }
 
+
 void DIALOG_CREATE_ARRAY::setControlEnablement()
 {
     const bool renumber = m_checkBoxGridRestartNumbering->GetValue();
@@ -389,15 +392,18 @@ void DIALOG_CREATE_ARRAY::calculateCircularArrayProperties()
 
 // ARRAY OPTION implementation functions --------------------------------------
 
-std::string DIALOG_CREATE_ARRAY::ARRAY_OPTIONS::getCoordinateNumber( int n,
-        ARRAY_NUMBERING_TYPE_T type )
+wxString DIALOG_CREATE_ARRAY::ARRAY_OPTIONS::AXIS_T::GetCoordinateNumberForIndex(
+        int aN ) const
 {
-    std::string itemNum;
-    const std::string& alphabet = alphabetFromNumberingScheme( type );
+    // convert index to
+    int n = aN * m_step + m_offset;
+
+    wxString itemNum;
+    const wxString& alphabet = alphabetFromNumberingScheme( m_type );
 
     if( !alphabet.empty() )
     {
-        const bool nonUnitColsStartAt0 = schemeNonUnitColsStartAt0( type );
+        const bool nonUnitColsStartAt0 = schemeNonUnitColsStartAt0( m_type );
 
         bool    firstRound = true;
         int     radix = alphabet.length();
@@ -492,22 +498,12 @@ wxString DIALOG_CREATE_ARRAY::ARRAY_GRID_OPTIONS::GetItemNumber( int n ) const
     {
         wxPoint coords = getGridCoords( n );
 
-        itemNum += getCoordinateNumber(
-                coords.x * m_priAxisNumStep + m_numberingOffsetX,
-                m_priAxisNumType
-        );
-
-        itemNum += getCoordinateNumber(
-                coords.y * m_secAxisNumStep + m_numberingOffsetY,
-                m_secAxisNumType
-        );
+        itemNum += m_priAxis.GetCoordinateNumberForIndex( coords.x );
+        itemNum += m_secAxis.GetCoordinateNumberForIndex( coords.y );
     }
     else
     {
-        itemNum += getCoordinateNumber(
-                n * m_priAxisNumStep + m_numberingOffsetX,
-                m_priAxisNumType
-        );
+        itemNum += m_priAxis.GetCoordinateNumberForIndex(n);
     }
 
     return itemNum;
@@ -527,7 +523,7 @@ void DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::TransformItem( int n, BOARD_IT
 
     if( m_angle == 0 )
         // angle is zero, divide evenly into m_nPts
-        angle = 3600.0 * n / float(m_nPts);
+        angle = ( 3600.0f * n ) / m_nPts;
     else
         // n'th step
         angle = m_angle * n;
@@ -547,6 +543,5 @@ void DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::TransformItem( int n, BOARD_IT
 
 wxString DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::GetItemNumber( int aN ) const
 {
-    return getCoordinateNumber( aN * m_numberingStep + m_numberingOffset,
-            m_numberingType );
+    return m_axis.GetCoordinateNumberForIndex( aN );
 }
diff --git a/pcbnew/dialogs/dialog_create_array.h b/pcbnew/dialogs/dialog_create_array.h
index 6c06d03..0d3a2e5 100644
--- a/pcbnew/dialogs/dialog_create_array.h
+++ b/pcbnew/dialogs/dialog_create_array.h
@@ -32,6 +32,31 @@
 
 class CONFIG_SAVE_RESTORE_WINDOW
 {
+protected:
+    /*!
+     * Struct RECORD_T
+     *
+     * Base class for a save/restore window - this provides the "valid" flag
+     * and any other common methods.
+     */
+    struct RECORD_T
+    {
+        RECORD_T() :
+            m_configValid( false )
+        {}
+
+        void SetValid()
+        {
+            m_configValid = true;
+        }
+
+        bool IsConfigValid() const
+        {
+            return m_configValid;
+        }
+
+        bool m_configValid;
+    };
 private:
 
     enum CONFIG_CTRL_TYPE_T
@@ -52,11 +77,12 @@ private:
     };
 
     std::vector<CONFIG_CTRL_T> ctrls;
-    bool& valid;
+    RECORD_T& m_record;
 
 protected:
-    CONFIG_SAVE_RESTORE_WINDOW( bool& validFlag ) :
-        valid( validFlag )
+
+    CONFIG_SAVE_RESTORE_WINDOW( RECORD_T& aRecord ) :
+        m_record( aRecord )
     {}
 
     void Add( wxRadioBox* ctrl, int& dest )
@@ -73,7 +99,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 };
 
@@ -113,7 +139,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:
@@ -138,12 +164,12 @@ protected:
             }
         }
 
-        valid = true;
+        m_record.SetValid();
     }
 
     void RestoreConfigToControls()
     {
-        if( !valid )
+        if( !m_record.IsConfigValid() )
             return;
 
         for( std::vector<CONFIG_CTRL_T>::const_iterator iter = ctrls.begin(), iend = ctrls.end();
@@ -156,7 +182,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:
@@ -210,7 +236,11 @@ public:
     };
 
     /**
-     * Persistent dialog options
+     * Struct ARRAY_OPTIONS
+     *
+     * This is the base class which describes some grid and provides the
+     * laying out of array items according to some given parameters, which
+     * will mostly depend on the array type, with a few common ones.
      */
     struct ARRAY_OPTIONS
     {
@@ -242,10 +272,42 @@ public:
             return m_shouldRenumber;
         }
 
-protected:
-        static std::string getCoordinateNumber( int n, ARRAY_NUMBERING_TYPE_T type );
+        /*!
+         * Struct AXIS_T
+         * Describes a single axis of an array. Arrays can have one or more
+         * axes (grids have two, circle have one, for example)
+         */
+        struct AXIS_T
+        {
+            ARRAY_NUMBERING_TYPE_T m_type;
+            int m_offset;
+            int m_step;
+
+            AXIS_T() :
+                m_type( NUMBERING_NUMERIC ),
+                m_offset( 0 ),
+                m_step ( 1 )
+            {}
+
+            /*!
+             * Function GetCoordinateNumberForIndex
+             *
+             * Get the coordinate number for a give axis index. This applies
+             * the offset and stepping internally, and returns a string in the
+             * correct alphabet
+             *
+             * @param n the index of the coordinate to get a number for
+             * @return wxString of the coordinate
+             */
+            wxString GetCoordinateNumberForIndex( int n ) const;
+        };
     };
 
+
+    /*!
+     * Struct ARRAY_GRID_OPTIONS
+     * Parameters and layout for 2D grid arrays
+     */
     struct ARRAY_GRID_OPTIONS : public ARRAY_OPTIONS
     {
         ARRAY_GRID_OPTIONS() :
@@ -255,13 +317,7 @@ protected:
             m_reverseNumberingAlternate( false ),
             m_stagger( 0 ),
             m_stagger_rows( true ),
-            m_2dArrayNumbering( false ),
-            m_numberingOffsetX( 0 ),
-            m_numberingOffsetY( 0 ),
-            m_priAxisNumType( NUMBERING_NUMERIC ),
-            m_secAxisNumType( NUMBERING_NUMERIC ),
-            m_priAxisNumStep( 1 ),
-            m_secAxisNumStep( 1 )
+            m_2dArrayNumbering( false )
         {}
 
         long    m_nx, m_ny;
@@ -271,9 +327,7 @@ protected:
         long    m_stagger;
         bool    m_stagger_rows;
         bool    m_2dArrayNumbering;
-        int     m_numberingOffsetX, m_numberingOffsetY;
-        ARRAY_NUMBERING_TYPE_T m_priAxisNumType, m_secAxisNumType;
-        long    m_priAxisNumStep, m_secAxisNumStep;
+        AXIS_T  m_priAxis, m_secAxis;
 
         void        TransformItem( int n, BOARD_ITEM* item, const wxPoint& rotPoint ) const;    // override virtual
         int         GetArraySize() const;                                                       // override virtual
@@ -283,6 +337,11 @@ private:
         wxPoint getGridCoords( int n ) const;
     };
 
+    /*!
+     * Struct ARRAY_CIRCULAR_OPTIONS
+     *
+     * Parameters and layout for circular arrays
+     */
     struct ARRAY_CIRCULAR_OPTIONS : public ARRAY_OPTIONS
     {
         ARRAY_CIRCULAR_OPTIONS() :
@@ -290,10 +349,7 @@ private:
             m_nPts( 0 ),
             m_angle( 0.0f ),
             m_relativeCentre( false ),
-            m_rotateItems( false ),
-            m_numberingType( NUMBERING_NUMERIC ),
-            m_numberingOffset( 0 ),
-            m_numberingStep( 1 )
+            m_rotateItems( false )
         {}
 
         long m_nPts;
@@ -301,9 +357,7 @@ private:
         wxPoint m_centre;
         bool m_relativeCentre;
         bool m_rotateItems;
-        ARRAY_NUMBERING_TYPE_T m_numberingType;
-        long m_numberingOffset;
-        int m_numberingStep;
+        AXIS_T m_axis;
 
         void        TransformItem( int n, BOARD_ITEM* item, const wxPoint& rotPoint ) const;    // override virtual
         int         GetArraySize() const;                                                       // override virtual
@@ -317,12 +371,12 @@ private:
 private:
 
     /**
-     * The settings object returned to the caller.
+     * The settings object returned to the caller by this dialog.
      * We update the caller's object and never have ownership
      */
     ARRAY_OPTIONS** m_settings;
 
-    /*
+    /*!
      * The position of the original item(s), used for finding radius, etc
      */
     const wxPoint m_originalItemPosition;
@@ -333,12 +387,26 @@ private:
 
     // Internal callback handlers
     void setControlEnablement();
+
+    // Calculate derived properties of a circular grid (eg radius)
     void calculateCircularArrayProperties();
 
-    struct CREATE_ARRAY_DIALOG_ENTRIES
+    /*!
+     * Fill an axis description from a set of controls
+     * @return true if the values made sense
+     */
+    bool fillAxisFromControls( ARRAY_OPTIONS::AXIS_T& axis,
+            wxChoice* alphabetSelector,
+            wxTextCtrl* offsetEntry,
+            wxSpinCtrl* stepEntry );
+
+    /*!
+     * Persistent settings for the create array dialog - these are
+     * save on close and reloaded on next dialog open
+     */
+    struct CREATE_ARRAY_DIALOG_ENTRIES: public CONFIG_SAVE_RESTORE_WINDOW::RECORD_T
     {
         CREATE_ARRAY_DIALOG_ENTRIES() :
-            m_optionsSet( false ),
             m_gridStaggerType( 0 ),
             m_gridNumberingAxis( 0 ),
             m_gridNumberingReverseAlternate( false ),
@@ -353,30 +421,31 @@ private:
             m_arrayTypeTab( 0 )
         {}
 
-        bool m_optionsSet;
+        wxString m_gridNx, m_gridNy,
+                 m_gridDx, m_gridDy,
+                 m_gridOffsetX, m_gridOffsetY,
+                 m_gridStagger;
 
-        std::string m_gridNx, m_gridNy,
-                    m_gridDx, m_gridDy,
-                    m_gridOffsetX, m_gridOffsetY,
-                    m_gridStagger;
+        int      m_gridStaggerType, m_gridNumberingAxis;
+        bool     m_gridNumberingReverseAlternate;
+        int      m_grid2dArrayNumbering;
+        int      m_gridPriAxisNumScheme, m_gridSecAxisNumScheme;
+        wxString m_gridPriNumberingOffset, m_gridSecNumberingOffset;
+        int      m_gridPriAxisNumberingStep, m_gridSecAxisNumberingStep;
 
-        int m_gridStaggerType, m_gridNumberingAxis;
-        bool    m_gridNumberingReverseAlternate;
-        int     m_grid2dArrayNumbering;
-        int     m_gridPriAxisNumScheme, m_gridSecAxisNumScheme;
-        std::string m_gridPriNumberingOffset, m_gridSecNumberingOffset;
-        int     m_gridPriAxisNumberingStep, m_gridSecAxisNumberingStep;
+        wxString m_circCentreX, m_circCentreY,
+                 m_circAngle, m_circCount, m_circNumberingOffset;
+        bool     m_circRotate, m_circRelativeCentre;
+        int      m_circNumberingStep;
 
-        std::string m_circCentreX, m_circCentreY,
-                    m_circAngle, m_circCount, m_circNumberingOffset;
-        bool m_circRotate, m_circRelativeCentre;
-        int m_circNumberingStep;
-
-        int m_arrayTypeTab;
+        int      m_arrayTypeTab;
     };
 
+    /*!
+     * The static dialog state, which is used to save and restore the
+     * dialog settings
+     */
     static CREATE_ARRAY_DIALOG_ENTRIES m_options;
-
 };
 
 #endif      // __DIALOG_CREATE_ARRAY__
-- 
1.9.1


Follow ups