Enhancements in Create array tool (bad parameters detection and disable parms when not applicable)
This commit is contained in:
parent
76d099b337
commit
b8a91c7a98
|
@ -187,6 +187,7 @@ set( PCBNEW_CLASS_SRCS
|
||||||
pcbframe.cpp
|
pcbframe.cpp
|
||||||
pcb_base_edit_frame.cpp
|
pcb_base_edit_frame.cpp
|
||||||
append_board_to_current.cpp
|
append_board_to_current.cpp
|
||||||
|
array_creator.cpp
|
||||||
attribut.cpp
|
attribut.cpp
|
||||||
board_items_to_polygon_shape_transform.cpp
|
board_items_to_polygon_shape_transform.cpp
|
||||||
board_undo_redo.cpp
|
board_undo_redo.cpp
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Created on: 11 Mar 2016, author John Beard
|
||||||
|
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file array_creator.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "array_creator.h"
|
||||||
|
|
||||||
|
#include <class_undoredo_container.h>
|
||||||
|
|
||||||
|
#include <dialogs/dialog_create_array.h>
|
||||||
|
|
||||||
|
|
||||||
|
void ARRAY_CREATOR::Invoke()
|
||||||
|
{
|
||||||
|
const int numItems = getNumberOfItemsToArray();
|
||||||
|
|
||||||
|
// bail out if no items
|
||||||
|
if( numItems == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
MODULE* const module = getModule();
|
||||||
|
const bool isModuleEditor = module != NULL;
|
||||||
|
|
||||||
|
const bool enableArrayNumbering = isModuleEditor;
|
||||||
|
const wxPoint rotPoint = getRotationCentre();
|
||||||
|
|
||||||
|
DIALOG_CREATE_ARRAY dialog( &m_parent, enableArrayNumbering, rotPoint );
|
||||||
|
int ret = dialog.ShowModal();
|
||||||
|
|
||||||
|
DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* const array_opts = dialog.GetArrayOptions();
|
||||||
|
|
||||||
|
if( ret == wxID_OK && array_opts != NULL )
|
||||||
|
{
|
||||||
|
PICKED_ITEMS_LIST newItemsList;
|
||||||
|
|
||||||
|
if( isModuleEditor )
|
||||||
|
{
|
||||||
|
// modedit saves everything upfront
|
||||||
|
m_parent.SaveCopyInUndoList( getBoard()->m_Modules, UR_MODEDIT );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int i = 0; i < numItems; ++i )
|
||||||
|
{
|
||||||
|
BOARD_ITEM* item = getNthItemToArray( i );
|
||||||
|
|
||||||
|
if( item->Type() == PCB_PAD_T && !isModuleEditor )
|
||||||
|
{
|
||||||
|
// If it is not the module editor, then duplicate the parent module instead
|
||||||
|
item = static_cast<MODULE*>( item )->GetParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first item in list is the original item. We do not modify it
|
||||||
|
for( int ptN = 1; ptN < array_opts->GetArraySize(); ptN++ )
|
||||||
|
{
|
||||||
|
BOARD_ITEM* new_item;
|
||||||
|
|
||||||
|
if( isModuleEditor )
|
||||||
|
{
|
||||||
|
// increment pad numbers if do any renumbering
|
||||||
|
// (we will number again later according to the numbering scheme if set)
|
||||||
|
new_item = module->DuplicateAndAddItem(
|
||||||
|
item, array_opts->ShouldNumberItems() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// PCB items keep the same numbering
|
||||||
|
new_item = getBoard()->DuplicateAndAddItem( item, false );
|
||||||
|
|
||||||
|
// @TODO: we should merge zones. This is a bit tricky, because
|
||||||
|
// the undo command needs saving old area, if it is merged.
|
||||||
|
}
|
||||||
|
|
||||||
|
if( new_item )
|
||||||
|
{
|
||||||
|
array_opts->TransformItem( ptN, new_item, rotPoint );
|
||||||
|
|
||||||
|
prePushAction( new_item );
|
||||||
|
|
||||||
|
newItemsList.PushItem( new_item ); // For undo list
|
||||||
|
|
||||||
|
postPushAction( new_item );
|
||||||
|
}
|
||||||
|
|
||||||
|
// attempt to renumber items if the array parameters define
|
||||||
|
// a complete numbering scheme to number by (as opposed to
|
||||||
|
// implicit numbering by incrementing the items during creation
|
||||||
|
if( new_item && array_opts->NumberingStartIsSpecified() )
|
||||||
|
{
|
||||||
|
// Renumber pads. Only new pad number renumbering has meaning,
|
||||||
|
// in the footprint editor.
|
||||||
|
if( new_item->Type() == PCB_PAD_T )
|
||||||
|
{
|
||||||
|
const wxString padName = array_opts->GetItemNumber( ptN );
|
||||||
|
static_cast<D_PAD*>( new_item )->SetPadName( padName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !isModuleEditor )
|
||||||
|
{
|
||||||
|
// Add all items as a single undo point for PCB editors
|
||||||
|
m_parent.SaveCopyInUndoList( newItemsList, UR_NEW );
|
||||||
|
}
|
||||||
|
|
||||||
|
finalise();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Created on: 11 Mar 2016, author John Beard
|
||||||
|
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file array_creator.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PCBNEW_ARRAY_CREATOR_H_
|
||||||
|
#define PCBNEW_ARRAY_CREATOR_H_
|
||||||
|
|
||||||
|
#include <dialogs/dialog_create_array.h>
|
||||||
|
|
||||||
|
#include <class_board.h>
|
||||||
|
#include <class_module.h>
|
||||||
|
#include <class_board_item.h>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Class that performs array creation by producing a dialog to gather
|
||||||
|
* parameters and then creating and laying out the items.
|
||||||
|
*
|
||||||
|
* This is a template class which needs to be implemented by the relevant
|
||||||
|
* edit tooling, since the details of how the document is manipulated
|
||||||
|
* varies between edit modes (e.g. legacy or GAL)
|
||||||
|
*/
|
||||||
|
class ARRAY_CREATOR
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ARRAY_CREATOR(PCB_BASE_FRAME& parent):
|
||||||
|
m_parent( parent )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Open the dialog, gather parameters and create the array
|
||||||
|
*/
|
||||||
|
void Invoke();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~ARRAY_CREATOR() {}
|
||||||
|
|
||||||
|
PCB_BASE_FRAME& m_parent;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Get the BOARD that is currently being edited.
|
||||||
|
*/
|
||||||
|
virtual BOARD* getBoard() const = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* If editing a footprint, returns the relevant MODULE, else NULL
|
||||||
|
*/
|
||||||
|
virtual MODULE* getModule() const = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @return number of original items to put into an array (eg size of the
|
||||||
|
* selection)
|
||||||
|
*/
|
||||||
|
virtual int getNumberOfItemsToArray() const = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @return the n'th original item to be arrayed
|
||||||
|
*/
|
||||||
|
virtual BOARD_ITEM* getNthItemToArray( int n ) const = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @return the rotation centre of all the items to be arrayed, when taken
|
||||||
|
* together
|
||||||
|
*/
|
||||||
|
virtual wxPoint getRotationCentre() const = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Perform any relevant action before pushing a newly created array item
|
||||||
|
* to the BOARD
|
||||||
|
*/
|
||||||
|
virtual void prePushAction( BOARD_ITEM* new_item )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Perform any actions needed after pushing an item to the BOARD
|
||||||
|
*/
|
||||||
|
virtual void postPushAction( BOARD_ITEM* new_item )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Actions to perform after the array process is complete
|
||||||
|
*/
|
||||||
|
virtual void finalise() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* PCBNEW_ARRAY_CREATOR_H_ */
|
|
@ -25,6 +25,7 @@
|
||||||
#include <wxPcbStruct.h>
|
#include <wxPcbStruct.h>
|
||||||
#include <base_units.h>
|
#include <base_units.h>
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
|
#include <boost/algorithm/string/join.hpp>
|
||||||
|
|
||||||
#include <class_drawpanel.h>
|
#include <class_drawpanel.h>
|
||||||
#include <class_board.h>
|
#include <class_board.h>
|
||||||
|
@ -37,12 +38,14 @@
|
||||||
DIALOG_CREATE_ARRAY::CREATE_ARRAY_DIALOG_ENTRIES DIALOG_CREATE_ARRAY::m_options;
|
DIALOG_CREATE_ARRAY::CREATE_ARRAY_DIALOG_ENTRIES DIALOG_CREATE_ARRAY::m_options;
|
||||||
|
|
||||||
|
|
||||||
DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrigPos,
|
DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent,
|
||||||
ARRAY_OPTIONS** aSettings ) :
|
bool enableNumbering,
|
||||||
|
wxPoint aOrigPos ) :
|
||||||
DIALOG_CREATE_ARRAY_BASE( aParent ),
|
DIALOG_CREATE_ARRAY_BASE( aParent ),
|
||||||
CONFIG_SAVE_RESTORE_WINDOW( m_options.m_optionsSet ),
|
CONFIG_SAVE_RESTORE_WINDOW( m_options.m_optionsSet ),
|
||||||
m_settings( aSettings ),
|
m_settings( NULL ),
|
||||||
m_originalItemPosition( aOrigPos )
|
m_originalItemPosition( aOrigPos ),
|
||||||
|
m_numberingEnabled(enableNumbering)
|
||||||
{
|
{
|
||||||
// Set up numbering scheme drop downs
|
// Set up numbering scheme drop downs
|
||||||
//
|
//
|
||||||
|
@ -91,9 +94,6 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrig
|
||||||
Add( m_entryGridPriNumberingOffset, m_options.m_gridPriNumberingOffset );
|
Add( m_entryGridPriNumberingOffset, m_options.m_gridPriNumberingOffset );
|
||||||
Add( m_entryGridSecNumberingOffset, m_options.m_gridSecNumberingOffset );
|
Add( m_entryGridSecNumberingOffset, m_options.m_gridSecNumberingOffset );
|
||||||
|
|
||||||
Add( m_rbGridStartNumberingOpt, m_options.m_gridNumberingScheme );
|
|
||||||
Add( m_rbCircStartNumberingOpt, m_options.m_circNumberingScheme );
|
|
||||||
|
|
||||||
RestoreConfigToControls();
|
RestoreConfigToControls();
|
||||||
|
|
||||||
// Load units into labels
|
// Load units into labels
|
||||||
|
@ -118,6 +118,13 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DIALOG_CREATE_ARRAY::~DIALOG_CREATE_ARRAY()
|
||||||
|
{
|
||||||
|
if( m_settings != NULL )
|
||||||
|
delete m_settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DIALOG_CREATE_ARRAY::OnParameterChanged( wxCommandEvent& event )
|
void DIALOG_CREATE_ARRAY::OnParameterChanged( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
setControlEnablement();
|
setControlEnablement();
|
||||||
|
@ -125,13 +132,13 @@ void DIALOG_CREATE_ARRAY::OnParameterChanged( wxCommandEvent& event )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const std::string& alphabetFromNumberingScheme(
|
static const wxString& alphabetFromNumberingScheme(
|
||||||
DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T type )
|
DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T type )
|
||||||
{
|
{
|
||||||
static const std::string alphaNumeric = "0123456789";
|
static const wxString alphaNumeric = "0123456789";
|
||||||
static const std::string alphaHex = "0123456789ABCDEF";
|
static const wxString alphaHex = "0123456789ABCDEF";
|
||||||
static const std::string alphaFull = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
static const wxString alphaFull = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
static const std::string alphaNoIOSQXZ = "ABCDEFGHJKLMNPRTUVWY";
|
static const wxString alphaNoIOSQXZ = "ABCDEFGHJKLMNPRTUVWY";
|
||||||
|
|
||||||
switch( type )
|
switch( type )
|
||||||
{
|
{
|
||||||
|
@ -164,18 +171,18 @@ static bool schemeNonUnitColsStartAt0( DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool getNumberingOffset( const std::string& str,
|
static bool getNumberingOffset( const wxString& str,
|
||||||
DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T type,
|
DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T type,
|
||||||
int& offsetToFill )
|
int& offsetToFill )
|
||||||
{
|
{
|
||||||
const std::string alphabet = alphabetFromNumberingScheme( type );
|
const wxString alphabet = alphabetFromNumberingScheme( type );
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
const int radix = alphabet.length();
|
const int radix = alphabet.length();
|
||||||
|
|
||||||
for( unsigned i = 0; i < str.length(); i++ )
|
for( unsigned i = 0; i < str.length(); i++ )
|
||||||
{
|
{
|
||||||
int chIndex = alphabet.find( str[i], 0 );
|
int chIndex = alphabet.Find( str[i], false );
|
||||||
|
|
||||||
if( chIndex == wxNOT_FOUND )
|
if( chIndex == wxNOT_FOUND )
|
||||||
return false;
|
return false;
|
||||||
|
@ -195,10 +202,91 @@ static bool getNumberingOffset( const std::string& str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates and saves (if valid) the type and offset of an array axis numbering
|
||||||
|
*
|
||||||
|
* @param offsetEntry the entry of the offset (text)
|
||||||
|
* @param typeEntry the entry of the axis nmbering scheme (choice)
|
||||||
|
* @param type the destination of the type if valid
|
||||||
|
* @param offset the destination of the offset if valid
|
||||||
|
* @param errors error string accumulator
|
||||||
|
* @return if all valid
|
||||||
|
*/
|
||||||
|
static bool validateNumberingTypeAndOffset( const wxTextCtrl& offsetEntry,
|
||||||
|
const wxChoice& typeEntry,
|
||||||
|
DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T& type,
|
||||||
|
int& offset,
|
||||||
|
wxArrayString& errors )
|
||||||
|
{
|
||||||
|
const int typeVal = typeEntry.GetSelection();
|
||||||
|
// mind undefined casts to enums (should not be able to happen)
|
||||||
|
bool ok = typeVal <= DIALOG_CREATE_ARRAY::NUMBERING_TYPE_MAX;
|
||||||
|
|
||||||
|
if( ok )
|
||||||
|
{
|
||||||
|
type = (DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T) typeVal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxString err;
|
||||||
|
err.Printf( _("Unrecognised numbering scheme: %d"), typeVal );
|
||||||
|
errors.Add( err );
|
||||||
|
// we can't proceed - we don't know the numbering type
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxString text = offsetEntry.GetValue();
|
||||||
|
ok = getNumberingOffset( text, type, offset );
|
||||||
|
|
||||||
|
if( !ok )
|
||||||
|
{
|
||||||
|
const wxString& alphabet = alphabetFromNumberingScheme( type );
|
||||||
|
|
||||||
|
wxString err;
|
||||||
|
err.Printf( _( "Could not determine numbering start from \"%s\": "
|
||||||
|
"expected value consistent with alphabet \"%s\"" ),
|
||||||
|
text, alphabet );
|
||||||
|
errors.Add(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate and save a long integer entry
|
||||||
|
*
|
||||||
|
* @param entry the text entry to read from
|
||||||
|
* @param dest the value destination
|
||||||
|
* @param description description of the field (used if the value is not OK)
|
||||||
|
* @param errors a list of errors to add any error to
|
||||||
|
* @return valid
|
||||||
|
*/
|
||||||
|
static bool validateLongEntry( const wxTextEntry& entry,
|
||||||
|
long& dest,
|
||||||
|
const wxString description,
|
||||||
|
wxArrayString& errors )
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
|
||||||
|
if( !entry.GetValue().ToLong( &dest ) )
|
||||||
|
{
|
||||||
|
wxString err;
|
||||||
|
err.Printf( _("Bad integral value for %s: %s"), description, entry.GetValue() );
|
||||||
|
errors.Add( err );
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
|
void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
ARRAY_OPTIONS* newSettings = NULL;
|
ARRAY_OPTIONS* newSettings = NULL;
|
||||||
|
|
||||||
|
wxArrayString errorStrs;
|
||||||
|
|
||||||
const wxWindow* page = m_gridTypeNotebook->GetCurrentPage();
|
const wxWindow* page = m_gridTypeNotebook->GetCurrentPage();
|
||||||
|
|
||||||
if( page == m_gridPanel )
|
if( page == m_gridPanel )
|
||||||
|
@ -207,8 +295,11 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
// ints
|
// ints
|
||||||
ok = ok && m_entryNx->GetValue().ToLong( &newGrid->m_nx );
|
ok = ok && validateLongEntry(*m_entryNx, newGrid->m_nx, _("horizontal count"),
|
||||||
ok = ok && m_entryNy->GetValue().ToLong( &newGrid->m_ny );
|
errorStrs);
|
||||||
|
ok = ok && validateLongEntry(*m_entryNy, newGrid->m_ny, _("vertical count"),
|
||||||
|
errorStrs);
|
||||||
|
|
||||||
|
|
||||||
newGrid->m_delta.x = DoubleValueFromString( g_UserUnit, m_entryDx->GetValue() );
|
newGrid->m_delta.x = DoubleValueFromString( g_UserUnit, m_entryDx->GetValue() );
|
||||||
newGrid->m_delta.y = DoubleValueFromString( g_UserUnit, m_entryDy->GetValue() );
|
newGrid->m_delta.y = DoubleValueFromString( g_UserUnit, m_entryDy->GetValue() );
|
||||||
|
@ -216,40 +307,38 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
|
||||||
newGrid->m_offset.x = DoubleValueFromString( g_UserUnit, m_entryOffsetX->GetValue() );
|
newGrid->m_offset.x = DoubleValueFromString( g_UserUnit, m_entryOffsetX->GetValue() );
|
||||||
newGrid->m_offset.y = DoubleValueFromString( g_UserUnit, m_entryOffsetY->GetValue() );
|
newGrid->m_offset.y = DoubleValueFromString( g_UserUnit, m_entryOffsetY->GetValue() );
|
||||||
|
|
||||||
ok = ok && m_entryStagger->GetValue().ToLong( &newGrid->m_stagger );
|
ok = ok && validateLongEntry(*m_entryStagger, newGrid->m_stagger, _("stagger"),
|
||||||
|
errorStrs);
|
||||||
|
|
||||||
newGrid->m_stagger_rows = m_radioBoxGridStaggerType->GetSelection() == 0;
|
newGrid->m_stagger_rows = m_radioBoxGridStaggerType->GetSelection() == 0;
|
||||||
|
|
||||||
newGrid->m_horizontalThenVertical = m_radioBoxGridNumberingAxis->GetSelection() == 0;
|
newGrid->m_horizontalThenVertical = m_radioBoxGridNumberingAxis->GetSelection() == 0;
|
||||||
newGrid->m_reverseNumberingAlternate = m_checkBoxGridReverseNumbering->GetValue();
|
newGrid->m_reverseNumberingAlternate = m_checkBoxGridReverseNumbering->GetValue();
|
||||||
|
|
||||||
newGrid->m_2dArrayNumbering = m_radioBoxGridNumberingScheme->GetSelection() != 0;
|
newGrid->m_shouldNumber = m_numberingEnabled;
|
||||||
|
|
||||||
// this is only correct if you set the choice up according to the enum size and order
|
if ( m_numberingEnabled )
|
||||||
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 =
|
newGrid->m_2dArrayNumbering = m_radioBoxGridNumberingScheme->GetSelection() != 0;
|
||||||
(ARRAY_NUMBERING_TYPE_T) m_choicePriAxisNumbering->GetSelection();
|
|
||||||
newGrid->m_secAxisNumType =
|
bool numOk = validateNumberingTypeAndOffset(
|
||||||
(ARRAY_NUMBERING_TYPE_T) m_choiceSecAxisNumbering->GetSelection();
|
*m_entryGridPriNumberingOffset, *m_choicePriAxisNumbering,
|
||||||
|
newGrid->m_priAxisNumType, newGrid->m_numberingOffsetX,
|
||||||
|
errorStrs );
|
||||||
|
|
||||||
|
if( newGrid->m_2dArrayNumbering )
|
||||||
|
{
|
||||||
|
numOk = validateNumberingTypeAndOffset(
|
||||||
|
*m_entryGridSecNumberingOffset, *m_choiceSecAxisNumbering,
|
||||||
|
newGrid->m_secAxisNumType, newGrid->m_numberingOffsetY,
|
||||||
|
errorStrs ) && numOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = ok && numOk;
|
||||||
|
|
||||||
|
newGrid->m_numberingStartIsSpecified = m_rbGridStartNumberingOpt->GetSelection() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Work out the offsets for the numbering
|
|
||||||
ok = ok && getNumberingOffset(
|
|
||||||
m_entryGridPriNumberingOffset->GetValue().ToStdString(),
|
|
||||||
newGrid->m_priAxisNumType, newGrid->m_numberingOffsetX );
|
|
||||||
|
|
||||||
if( newGrid->m_2dArrayNumbering )
|
|
||||||
ok = ok && getNumberingOffset(
|
|
||||||
m_entryGridSecNumberingOffset->GetValue().ToStdString(),
|
|
||||||
newGrid->m_secAxisNumType, newGrid->m_numberingOffsetY );
|
|
||||||
|
|
||||||
newGrid->m_shouldRenumber = m_rbGridStartNumberingOpt->GetSelection() == 1;
|
|
||||||
|
|
||||||
// Only use settings if all values are good
|
// Only use settings if all values are good
|
||||||
if( ok )
|
if( ok )
|
||||||
newSettings = newGrid;
|
newSettings = newGrid;
|
||||||
|
@ -265,13 +354,23 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
|
||||||
newCirc->m_centre.y = DoubleValueFromString( g_UserUnit, m_entryCentreY->GetValue() );
|
newCirc->m_centre.y = DoubleValueFromString( g_UserUnit, m_entryCentreY->GetValue() );
|
||||||
|
|
||||||
newCirc->m_angle = DoubleValueFromString( DEGREES, m_entryCircAngle->GetValue() );
|
newCirc->m_angle = DoubleValueFromString( DEGREES, m_entryCircAngle->GetValue() );
|
||||||
ok = ok && m_entryCircCount->GetValue().ToLong( &newCirc->m_nPts );
|
|
||||||
|
ok = ok && validateLongEntry(*m_entryCircCount, newCirc->m_nPts,
|
||||||
|
_("point count"), errorStrs);
|
||||||
|
|
||||||
newCirc->m_rotateItems = m_entryRotateItemsCb->GetValue();
|
newCirc->m_rotateItems = m_entryRotateItemsCb->GetValue();
|
||||||
newCirc->m_shouldRenumber = m_rbCircStartNumberingOpt->GetSelection() == 1;
|
|
||||||
newCirc->m_numberingType = NUMBERING_NUMERIC;
|
|
||||||
|
|
||||||
ok = ok && m_entryCircNumberingStart->GetValue().ToLong( &newCirc->m_numberingOffset );
|
newCirc->m_shouldNumber = m_numberingEnabled;
|
||||||
|
|
||||||
|
if ( m_numberingEnabled )
|
||||||
|
{
|
||||||
|
newCirc->m_numberingStartIsSpecified = m_rbCircStartNumberingOpt->GetSelection() == 1;
|
||||||
|
newCirc->m_numberingType = NUMBERING_NUMERIC;
|
||||||
|
|
||||||
|
ok = ok && validateLongEntry(*m_entryCircNumberingStart,
|
||||||
|
newCirc->m_numberingOffset,
|
||||||
|
_("numbering start"), errorStrs);
|
||||||
|
}
|
||||||
|
|
||||||
// Only use settings if all values are good
|
// Only use settings if all values are good
|
||||||
if( ok )
|
if( ok )
|
||||||
|
@ -283,43 +382,70 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
|
||||||
// If we got good settings, send them out and finish
|
// If we got good settings, send them out and finish
|
||||||
if( newSettings )
|
if( newSettings )
|
||||||
{
|
{
|
||||||
delete *m_settings;
|
delete m_settings;
|
||||||
|
|
||||||
// assign pointer and ownership here
|
// assign pointer and ownership here
|
||||||
*m_settings = newSettings;
|
m_settings = newSettings;
|
||||||
ReadConfigFromControls();
|
ReadConfigFromControls();
|
||||||
|
|
||||||
EndModal( wxID_OK );
|
EndModal( wxID_OK );
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
wxMessageBox( _("Bad parameters" ) );
|
{
|
||||||
|
wxString errorStr;
|
||||||
|
|
||||||
|
if( errorStrs.IsEmpty() )
|
||||||
|
errorStr = _("Bad parameters");
|
||||||
|
else
|
||||||
|
errorStr = boost::algorithm::join( errorStrs, "\n" );
|
||||||
|
|
||||||
|
wxMessageBox( errorStr );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DIALOG_CREATE_ARRAY::setControlEnablement()
|
void DIALOG_CREATE_ARRAY::setControlEnablement()
|
||||||
{
|
{
|
||||||
const bool renumber = m_rbGridStartNumberingOpt->GetSelection() == 1;
|
if ( m_numberingEnabled )
|
||||||
|
{
|
||||||
|
const bool renumber = m_rbGridStartNumberingOpt->GetSelection() == 1;
|
||||||
|
|
||||||
// If we're not renumbering, we can't set the numbering scheme
|
// If we're not renumbering, we can't set the numbering scheme
|
||||||
// or axis numbering types
|
// or axis numbering types
|
||||||
m_radioBoxGridNumberingScheme->Enable( renumber );
|
m_radioBoxGridNumberingScheme->Enable( renumber );
|
||||||
m_labelPriAxisNumbering->Enable( renumber );
|
m_labelPriAxisNumbering->Enable( renumber );
|
||||||
m_choicePriAxisNumbering->Enable( renumber );
|
m_choicePriAxisNumbering->Enable( renumber );
|
||||||
|
|
||||||
// Disable the secondary axis numbering option if the
|
// Disable the secondary axis numbering option if the
|
||||||
// numbering scheme doesn't have two axes
|
// numbering scheme doesn't have two axes
|
||||||
const bool num2d = m_radioBoxGridNumberingScheme->GetSelection() != 0;
|
const bool num2d = m_radioBoxGridNumberingScheme->GetSelection() != 0;
|
||||||
|
|
||||||
m_labelSecAxisNumbering->Enable( renumber && num2d );
|
m_labelSecAxisNumbering->Enable( renumber && num2d );
|
||||||
m_choiceSecAxisNumbering->Enable( renumber && num2d );
|
m_choiceSecAxisNumbering->Enable( renumber && num2d );
|
||||||
|
|
||||||
// We can only set an offset if we renumber
|
// We can only set an offset if we renumber
|
||||||
m_labelGridNumberingOffset->Enable( renumber );
|
m_labelGridNumberingOffset->Enable( renumber );
|
||||||
m_entryGridPriNumberingOffset->Enable( renumber );
|
m_entryGridPriNumberingOffset->Enable( renumber );
|
||||||
m_entryGridSecNumberingOffset->Enable( renumber && num2d );
|
m_entryGridSecNumberingOffset->Enable( renumber && num2d );
|
||||||
|
|
||||||
m_entryCircNumberingStart->Enable( m_rbCircStartNumberingOpt->GetSelection() == 1 );
|
m_entryCircNumberingStart->Enable( m_rbCircStartNumberingOpt->GetSelection() == 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// grid
|
||||||
|
m_rbGridStartNumberingOpt->Enable( false );
|
||||||
|
m_checkBoxGridReverseNumbering->Enable( false );
|
||||||
|
m_radioBoxGridNumberingAxis->Enable( false );
|
||||||
|
m_radioBoxGridNumberingScheme->Enable( false );
|
||||||
|
m_choiceSecAxisNumbering->Enable( false );
|
||||||
|
m_choicePriAxisNumbering->Enable( false );
|
||||||
|
m_entryGridPriNumberingOffset->Enable( false );
|
||||||
|
m_entryGridSecNumberingOffset->Enable( false );
|
||||||
|
|
||||||
|
// circular
|
||||||
|
m_rbCircStartNumberingOpt->Enable( false );
|
||||||
|
m_entryCircNumberingStart->Enable( false );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -340,16 +466,16 @@ void DIALOG_CREATE_ARRAY::calculateCircularArrayProperties()
|
||||||
|
|
||||||
// ARRAY OPTION implementation functions --------------------------------------
|
// ARRAY OPTION implementation functions --------------------------------------
|
||||||
|
|
||||||
std::string DIALOG_CREATE_ARRAY::ARRAY_OPTIONS::getCoordinateNumber( int n,
|
wxString DIALOG_CREATE_ARRAY::ARRAY_OPTIONS::getCoordinateNumber( int n,
|
||||||
ARRAY_NUMBERING_TYPE_T type )
|
ARRAY_NUMBERING_TYPE_T type )
|
||||||
{
|
{
|
||||||
std::string itemNum;
|
wxString itemNum;
|
||||||
const std::string& alphabet = alphabetFromNumberingScheme( type );
|
const wxString& alphabet = alphabetFromNumberingScheme( type );
|
||||||
|
|
||||||
const bool nonUnitColsStartAt0 = schemeNonUnitColsStartAt0( type );
|
const bool nonUnitColsStartAt0 = schemeNonUnitColsStartAt0( type );
|
||||||
|
|
||||||
bool firstRound = true;
|
bool firstRound = true;
|
||||||
int radix = alphabet.length();
|
int radix = alphabet.Length();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
int modN = n % radix;
|
int modN = n % radix;
|
||||||
|
@ -480,9 +606,5 @@ void DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::TransformItem( int n, BOARD_IT
|
||||||
|
|
||||||
wxString DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::GetItemNumber( int aN ) const
|
wxString DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::GetItemNumber( int aN ) const
|
||||||
{
|
{
|
||||||
// The first new pad has aN number == 1, not 0
|
return getCoordinateNumber( aN + m_numberingOffset, m_numberingType );
|
||||||
if( m_shouldRenumber ) // numbering pad from initial user value
|
|
||||||
return getCoordinateNumber( aN - 1 + m_numberingOffset, m_numberingType );
|
|
||||||
else // numbering pad from inital pad number
|
|
||||||
return getCoordinateNumber( aN + m_numberingOffset, m_numberingType );
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
// Include the wxFormBuider header base:
|
// Include the wxFormBuider header base:
|
||||||
#include <dialog_create_array_base.h>
|
#include <dialog_create_array_base.h>
|
||||||
|
|
||||||
|
#include <class_board_item.h>
|
||||||
|
#include <wxBasePcbFrame.h>
|
||||||
|
|
||||||
#include <boost/bimap.hpp>
|
#include <boost/bimap.hpp>
|
||||||
|
|
||||||
class CONFIG_SAVE_RESTORE_WINDOW
|
class CONFIG_SAVE_RESTORE_WINDOW
|
||||||
|
@ -72,7 +75,7 @@ protected:
|
||||||
ctrls.push_back( ctrlInfo );
|
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 };
|
CONFIG_CTRL_T ctrlInfo = { ctrl, CFG_CTRL_TEXT, (void*) &dest };
|
||||||
|
|
||||||
|
@ -105,7 +108,7 @@ protected:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CFG_CTRL_TEXT:
|
case CFG_CTRL_TEXT:
|
||||||
*(std::string*) iter->dest = static_cast<wxTextCtrl*>( iter->control )->GetValue();
|
*(wxString*) iter->dest = static_cast<wxTextCtrl*>( iter->control )->GetValue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CFG_CTRL_CHOICE:
|
case CFG_CTRL_CHOICE:
|
||||||
|
@ -144,7 +147,7 @@ protected:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CFG_CTRL_TEXT:
|
case CFG_CTRL_TEXT:
|
||||||
static_cast<wxTextCtrl*>( iter->control )->SetValue( *(std::string*) iter->dest );
|
static_cast<wxTextCtrl*>( iter->control )->SetValue( *(wxString*) iter->dest );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CFG_CTRL_CHOICE:
|
case CFG_CTRL_CHOICE:
|
||||||
|
@ -201,13 +204,13 @@ public:
|
||||||
{
|
{
|
||||||
ARRAY_OPTIONS( ARRAY_TYPE_T aType ) :
|
ARRAY_OPTIONS( ARRAY_TYPE_T aType ) :
|
||||||
m_type( aType ),
|
m_type( aType ),
|
||||||
m_shouldRenumber( false )
|
m_shouldNumber( false ),
|
||||||
|
m_numberingStartIsSpecified( false )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~ARRAY_OPTIONS() {};
|
virtual ~ARRAY_OPTIONS() {};
|
||||||
|
|
||||||
ARRAY_TYPE_T m_type;
|
ARRAY_TYPE_T m_type;
|
||||||
bool m_shouldRenumber;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Function GetArrayPositions
|
* Function GetArrayPositions
|
||||||
|
@ -222,13 +225,37 @@ public:
|
||||||
virtual wxString GetItemNumber( int n ) const = 0;
|
virtual wxString GetItemNumber( int n ) const = 0;
|
||||||
virtual wxString InterpolateNumberIntoString( int n, const wxString& pattern ) const;
|
virtual wxString InterpolateNumberIntoString( int n, const wxString& pattern ) const;
|
||||||
|
|
||||||
bool ShouldRenumberItems() const
|
/*!
|
||||||
|
* @return are the items in this array numberred, or are all the
|
||||||
|
* items numbered the same
|
||||||
|
*/
|
||||||
|
bool ShouldNumberItems() const
|
||||||
{
|
{
|
||||||
return m_shouldRenumber;
|
return m_shouldNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
/*!
|
||||||
static std::string getCoordinateNumber( int n, ARRAY_NUMBERING_TYPE_T type );
|
* @return is the numbering is enabled and should start at a point
|
||||||
|
* specified in these options or is it implicit according to the calling
|
||||||
|
* code?
|
||||||
|
*/
|
||||||
|
bool NumberingStartIsSpecified() const
|
||||||
|
{
|
||||||
|
return m_shouldNumber && m_numberingStartIsSpecified;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static wxString getCoordinateNumber( int n, ARRAY_NUMBERING_TYPE_T type );
|
||||||
|
|
||||||
|
// allow the dialog to set directly
|
||||||
|
friend class DIALOG_CREATE_ARRAY;
|
||||||
|
|
||||||
|
/// True if this array numbers the new items
|
||||||
|
bool m_shouldNumber;
|
||||||
|
|
||||||
|
/// True if this array's number starts from the preset point
|
||||||
|
/// False if the array numbering starts from some externally provided point
|
||||||
|
bool m_numberingStartIsSpecified;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ARRAY_GRID_OPTIONS : public ARRAY_OPTIONS
|
struct ARRAY_GRID_OPTIONS : public ARRAY_OPTIONS
|
||||||
|
@ -289,16 +316,27 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Constructor and destructor
|
// Constructor and destructor
|
||||||
DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrigPos, ARRAY_OPTIONS** settings );
|
DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, bool enableNumbering,
|
||||||
virtual ~DIALOG_CREATE_ARRAY() {};
|
wxPoint aOrigPos );
|
||||||
|
|
||||||
|
~DIALOG_CREATE_ARRAY();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @return the array options set by this dialogue, or NULL if they were
|
||||||
|
* not set, or could not be set
|
||||||
|
*/
|
||||||
|
ARRAY_OPTIONS* GetArrayOptions() const
|
||||||
|
{
|
||||||
|
return m_settings;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The settings object returned to the caller.
|
* The settings object returned to the caller.
|
||||||
* We update the caller's object and never have ownership
|
* We retain ownership of this
|
||||||
*/
|
*/
|
||||||
ARRAY_OPTIONS** m_settings;
|
ARRAY_OPTIONS* m_settings;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The position of the original item(s), used for finding radius, etc
|
* The position of the original item(s), used for finding radius, etc
|
||||||
|
@ -329,27 +367,28 @@ private:
|
||||||
|
|
||||||
bool m_optionsSet;
|
bool m_optionsSet;
|
||||||
|
|
||||||
std::string m_gridNx, m_gridNy,
|
wxString m_gridNx, m_gridNy,
|
||||||
m_gridDx, m_gridDy,
|
m_gridDx, m_gridDy,
|
||||||
m_gridOffsetX, m_gridOffsetY,
|
m_gridOffsetX, m_gridOffsetY,
|
||||||
m_gridStagger;
|
m_gridStagger;
|
||||||
|
|
||||||
int m_gridStaggerType, m_gridNumberingAxis;
|
int m_gridStaggerType, m_gridNumberingAxis;
|
||||||
bool m_gridNumberingReverseAlternate;
|
bool m_gridNumberingReverseAlternate;
|
||||||
int m_grid2dArrayNumbering;
|
int m_grid2dArrayNumbering;
|
||||||
int m_gridPriAxisNumScheme, m_gridSecAxisNumScheme;
|
int m_gridPriAxisNumScheme, m_gridSecAxisNumScheme;
|
||||||
std::string m_gridPriNumberingOffset, m_gridSecNumberingOffset;
|
wxString m_gridPriNumberingOffset, m_gridSecNumberingOffset;
|
||||||
|
|
||||||
std::string m_circCentreX, m_circCentreY,
|
wxString m_circCentreX, m_circCentreY,
|
||||||
m_circAngle, m_circCount, m_circNumberingOffset;
|
m_circAngle, m_circCount, m_circNumberingOffset;
|
||||||
bool m_circRotate;
|
bool m_circRotate;
|
||||||
int m_arrayTypeTab;
|
int m_arrayTypeTab;
|
||||||
int m_gridNumberingScheme;
|
|
||||||
int m_circNumberingScheme;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static CREATE_ARRAY_DIALOG_ENTRIES m_options;
|
// some uses of arrays might not allow component renumbering
|
||||||
|
bool m_numberingEnabled;
|
||||||
|
|
||||||
|
// saved array options
|
||||||
|
static CREATE_ARRAY_DIALOG_ENTRIES m_options;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __DIALOG_CREATE_ARRAY__
|
#endif // __DIALOG_CREATE_ARRAY__
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// C++ code generated with wxFormBuilder (version Jan 1 2016)
|
// C++ code generated with wxFormBuilder (version Mar 9 2016)
|
||||||
// http://www.wxformbuilder.org/
|
// http://www.wxformbuilder.org/
|
||||||
//
|
//
|
||||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
|
@ -100,51 +100,50 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
|
||||||
|
|
||||||
bSizer2->Add( gbSizer1, 1, wxEXPAND, 5 );
|
bSizer2->Add( gbSizer1, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
wxBoxSizer* bSizer3;
|
m_gridPadNumberingSizer = new wxBoxSizer( wxVERTICAL );
|
||||||
bSizer3 = new wxBoxSizer( wxVERTICAL );
|
|
||||||
|
|
||||||
wxString m_radioBoxGridNumberingAxisChoices[] = { _("Horizontal, then vertical"), _("Vertical, then horizontal") };
|
wxString m_radioBoxGridNumberingAxisChoices[] = { _("Horizontal, then vertical"), _("Vertical, then horizontal") };
|
||||||
int m_radioBoxGridNumberingAxisNChoices = sizeof( m_radioBoxGridNumberingAxisChoices ) / sizeof( wxString );
|
int m_radioBoxGridNumberingAxisNChoices = sizeof( m_radioBoxGridNumberingAxisChoices ) / sizeof( wxString );
|
||||||
m_radioBoxGridNumberingAxis = new wxRadioBox( m_gridPanel, wxID_ANY, _("Pad Numbering Direction"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingAxisNChoices, m_radioBoxGridNumberingAxisChoices, 1, wxRA_SPECIFY_COLS );
|
m_radioBoxGridNumberingAxis = new wxRadioBox( m_gridPanel, wxID_ANY, _("Pad Numbering Direction"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingAxisNChoices, m_radioBoxGridNumberingAxisChoices, 1, wxRA_SPECIFY_COLS );
|
||||||
m_radioBoxGridNumberingAxis->SetSelection( 0 );
|
m_radioBoxGridNumberingAxis->SetSelection( 0 );
|
||||||
bSizer3->Add( m_radioBoxGridNumberingAxis, 0, wxALL|wxEXPAND, 5 );
|
m_gridPadNumberingSizer->Add( m_radioBoxGridNumberingAxis, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
m_checkBoxGridReverseNumbering = new wxCheckBox( m_gridPanel, wxID_ANY, _("Reverse pad numbering on alternate rows or columns"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_checkBoxGridReverseNumbering = new wxCheckBox( m_gridPanel, wxID_ANY, _("Reverse pad numbering on alternate rows or columns"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
bSizer3->Add( m_checkBoxGridReverseNumbering, 0, wxALL, 5 );
|
m_gridPadNumberingSizer->Add( m_checkBoxGridReverseNumbering, 0, wxALL, 5 );
|
||||||
|
|
||||||
wxString m_rbGridStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") };
|
wxString m_rbGridStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") };
|
||||||
int m_rbGridStartNumberingOptNChoices = sizeof( m_rbGridStartNumberingOptChoices ) / sizeof( wxString );
|
int m_rbGridStartNumberingOptNChoices = sizeof( m_rbGridStartNumberingOptChoices ) / sizeof( wxString );
|
||||||
m_rbGridStartNumberingOpt = new wxRadioBox( m_gridPanel, wxID_ANY, _("Initial pad number"), wxDefaultPosition, wxDefaultSize, m_rbGridStartNumberingOptNChoices, m_rbGridStartNumberingOptChoices, 1, wxRA_SPECIFY_COLS );
|
m_rbGridStartNumberingOpt = new wxRadioBox( m_gridPanel, wxID_ANY, _("Initial pad number"), wxDefaultPosition, wxDefaultSize, m_rbGridStartNumberingOptNChoices, m_rbGridStartNumberingOptChoices, 1, wxRA_SPECIFY_COLS );
|
||||||
m_rbGridStartNumberingOpt->SetSelection( 1 );
|
m_rbGridStartNumberingOpt->SetSelection( 1 );
|
||||||
bSizer3->Add( m_rbGridStartNumberingOpt, 0, wxALL|wxEXPAND, 5 );
|
m_gridPadNumberingSizer->Add( m_rbGridStartNumberingOpt, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
wxString m_radioBoxGridNumberingSchemeChoices[] = { _("Continuous (1, 2, 3...)"), _("Coordinate (A1, A2, ... B1, ...)") };
|
wxString m_radioBoxGridNumberingSchemeChoices[] = { _("Continuous (1, 2, 3...)"), _("Coordinate (A1, A2, ... B1, ...)") };
|
||||||
int m_radioBoxGridNumberingSchemeNChoices = sizeof( m_radioBoxGridNumberingSchemeChoices ) / sizeof( wxString );
|
int m_radioBoxGridNumberingSchemeNChoices = sizeof( m_radioBoxGridNumberingSchemeChoices ) / sizeof( wxString );
|
||||||
m_radioBoxGridNumberingScheme = new wxRadioBox( m_gridPanel, wxID_ANY, _("Pad Numbering Scheme"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingSchemeNChoices, m_radioBoxGridNumberingSchemeChoices, 1, wxRA_SPECIFY_COLS );
|
m_radioBoxGridNumberingScheme = new wxRadioBox( m_gridPanel, wxID_ANY, _("Pad Numbering Scheme"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingSchemeNChoices, m_radioBoxGridNumberingSchemeChoices, 1, wxRA_SPECIFY_COLS );
|
||||||
m_radioBoxGridNumberingScheme->SetSelection( 1 );
|
m_radioBoxGridNumberingScheme->SetSelection( 1 );
|
||||||
bSizer3->Add( m_radioBoxGridNumberingScheme, 0, wxALL|wxEXPAND, 5 );
|
m_gridPadNumberingSizer->Add( m_radioBoxGridNumberingScheme, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
m_labelPriAxisNumbering = new wxStaticText( m_gridPanel, wxID_ANY, _("Primary axis numbering:"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_labelPriAxisNumbering = new wxStaticText( m_gridPanel, wxID_ANY, _("Primary axis numbering:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
m_labelPriAxisNumbering->Wrap( -1 );
|
m_labelPriAxisNumbering->Wrap( -1 );
|
||||||
bSizer3->Add( m_labelPriAxisNumbering, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
|
m_gridPadNumberingSizer->Add( m_labelPriAxisNumbering, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
|
||||||
|
|
||||||
wxArrayString m_choicePriAxisNumberingChoices;
|
wxArrayString m_choicePriAxisNumberingChoices;
|
||||||
m_choicePriAxisNumbering = new wxChoice( m_gridPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choicePriAxisNumberingChoices, 0 );
|
m_choicePriAxisNumbering = new wxChoice( m_gridPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choicePriAxisNumberingChoices, 0 );
|
||||||
m_choicePriAxisNumbering->SetSelection( 0 );
|
m_choicePriAxisNumbering->SetSelection( 0 );
|
||||||
bSizer3->Add( m_choicePriAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
m_gridPadNumberingSizer->Add( m_choicePriAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||||
|
|
||||||
m_labelSecAxisNumbering = new wxStaticText( m_gridPanel, wxID_ANY, _("Secondary axis numbering:"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_labelSecAxisNumbering = new wxStaticText( m_gridPanel, wxID_ANY, _("Secondary axis numbering:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
m_labelSecAxisNumbering->Wrap( -1 );
|
m_labelSecAxisNumbering->Wrap( -1 );
|
||||||
m_labelSecAxisNumbering->Enable( false );
|
m_labelSecAxisNumbering->Enable( false );
|
||||||
|
|
||||||
bSizer3->Add( m_labelSecAxisNumbering, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
m_gridPadNumberingSizer->Add( m_labelSecAxisNumbering, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||||
|
|
||||||
wxArrayString m_choiceSecAxisNumberingChoices;
|
wxArrayString m_choiceSecAxisNumberingChoices;
|
||||||
m_choiceSecAxisNumbering = new wxChoice( m_gridPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceSecAxisNumberingChoices, 0 );
|
m_choiceSecAxisNumbering = new wxChoice( m_gridPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceSecAxisNumberingChoices, 0 );
|
||||||
m_choiceSecAxisNumbering->SetSelection( 0 );
|
m_choiceSecAxisNumbering->SetSelection( 0 );
|
||||||
m_choiceSecAxisNumbering->Enable( false );
|
m_choiceSecAxisNumbering->Enable( false );
|
||||||
|
|
||||||
bSizer3->Add( m_choiceSecAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
m_gridPadNumberingSizer->Add( m_choiceSecAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||||
|
|
||||||
wxBoxSizer* bSizer5;
|
wxBoxSizer* bSizer5;
|
||||||
bSizer5 = new wxBoxSizer( wxHORIZONTAL );
|
bSizer5 = new wxBoxSizer( wxHORIZONTAL );
|
||||||
|
@ -160,10 +159,10 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
|
||||||
bSizer5->Add( m_entryGridSecNumberingOffset, 0, wxALL, 5 );
|
bSizer5->Add( m_entryGridSecNumberingOffset, 0, wxALL, 5 );
|
||||||
|
|
||||||
|
|
||||||
bSizer3->Add( bSizer5, 0, wxEXPAND, 5 );
|
m_gridPadNumberingSizer->Add( bSizer5, 0, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
bSizer2->Add( bSizer3, 0, wxALL|wxEXPAND, 5 );
|
bSizer2->Add( m_gridPadNumberingSizer, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
m_gridPanel->SetSizer( bSizer2 );
|
m_gridPanel->SetSizer( bSizer2 );
|
||||||
|
@ -244,30 +243,29 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
|
||||||
|
|
||||||
bSizer4->Add( gbSizer2, 0, wxALL|wxEXPAND, 5 );
|
bSizer4->Add( gbSizer2, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
wxStaticBoxSizer* sbcircPadNumberingSizer;
|
m_circPadNumberingSizer = new wxStaticBoxSizer( new wxStaticBox( m_circularPanel, wxID_ANY, _("Pad Numbering Options") ), wxVERTICAL );
|
||||||
sbcircPadNumberingSizer = new wxStaticBoxSizer( new wxStaticBox( m_circularPanel, wxID_ANY, _("Pad Numbering Options") ), wxVERTICAL );
|
|
||||||
|
|
||||||
wxString m_rbCircStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") };
|
wxString m_rbCircStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") };
|
||||||
int m_rbCircStartNumberingOptNChoices = sizeof( m_rbCircStartNumberingOptChoices ) / sizeof( wxString );
|
int m_rbCircStartNumberingOptNChoices = sizeof( m_rbCircStartNumberingOptChoices ) / sizeof( wxString );
|
||||||
m_rbCircStartNumberingOpt = new wxRadioBox( sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Initial pad number"), wxDefaultPosition, wxDefaultSize, m_rbCircStartNumberingOptNChoices, m_rbCircStartNumberingOptChoices, 1, wxRA_SPECIFY_COLS );
|
m_rbCircStartNumberingOpt = new wxRadioBox( m_circPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Initial pad number"), wxDefaultPosition, wxDefaultSize, m_rbCircStartNumberingOptNChoices, m_rbCircStartNumberingOptChoices, 1, wxRA_SPECIFY_COLS );
|
||||||
m_rbCircStartNumberingOpt->SetSelection( 0 );
|
m_rbCircStartNumberingOpt->SetSelection( 0 );
|
||||||
sbcircPadNumberingSizer->Add( m_rbCircStartNumberingOpt, 0, wxALL|wxEXPAND, 5 );
|
m_circPadNumberingSizer->Add( m_rbCircStartNumberingOpt, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
wxBoxSizer* bSizer7;
|
wxBoxSizer* bSizer7;
|
||||||
bSizer7 = new wxBoxSizer( wxHORIZONTAL );
|
bSizer7 = new wxBoxSizer( wxHORIZONTAL );
|
||||||
|
|
||||||
m_labelCircNumStart = new wxStaticText( sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Pad numbering start value:"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_labelCircNumStart = new wxStaticText( m_circPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Pad numbering start value:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
m_labelCircNumStart->Wrap( -1 );
|
m_labelCircNumStart->Wrap( -1 );
|
||||||
bSizer7->Add( m_labelCircNumStart, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
bSizer7->Add( m_labelCircNumStart, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
m_entryCircNumberingStart = new wxTextCtrl( sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_entryCircNumberingStart = new wxTextCtrl( m_circPadNumberingSizer->GetStaticBox(), wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
bSizer7->Add( m_entryCircNumberingStart, 1, wxALL, 5 );
|
bSizer7->Add( m_entryCircNumberingStart, 1, wxALL, 5 );
|
||||||
|
|
||||||
|
|
||||||
sbcircPadNumberingSizer->Add( bSizer7, 0, wxEXPAND, 5 );
|
m_circPadNumberingSizer->Add( bSizer7, 0, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
bSizer4->Add( sbcircPadNumberingSizer, 1, wxEXPAND|wxALL, 5 );
|
bSizer4->Add( m_circPadNumberingSizer, 1, wxEXPAND|wxALL, 5 );
|
||||||
|
|
||||||
|
|
||||||
m_circularPanel->SetSizer( bSizer4 );
|
m_circularPanel->SetSizer( bSizer4 );
|
||||||
|
|
|
@ -1978,9 +1978,9 @@
|
||||||
<property name="proportion">0</property>
|
<property name="proportion">0</property>
|
||||||
<object class="wxBoxSizer" expanded="0">
|
<object class="wxBoxSizer" expanded="0">
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="name">bSizer3</property>
|
<property name="name">m_gridPadNumberingSizer</property>
|
||||||
<property name="orient">wxVERTICAL</property>
|
<property name="orient">wxVERTICAL</property>
|
||||||
<property name="permission">none</property>
|
<property name="permission">protected</property>
|
||||||
<object class="sizeritem" expanded="0">
|
<object class="sizeritem" expanded="0">
|
||||||
<property name="border">5</property>
|
<property name="border">5</property>
|
||||||
<property name="flag">wxALL|wxEXPAND</property>
|
<property name="flag">wxALL|wxEXPAND</property>
|
||||||
|
@ -4397,10 +4397,9 @@
|
||||||
<property name="id">wxID_ANY</property>
|
<property name="id">wxID_ANY</property>
|
||||||
<property name="label">Pad Numbering Options</property>
|
<property name="label">Pad Numbering Options</property>
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="name">sbcircPadNumberingSizer</property>
|
<property name="name">m_circPadNumberingSizer</property>
|
||||||
<property name="orient">wxVERTICAL</property>
|
<property name="orient">wxVERTICAL</property>
|
||||||
<property name="parent">1</property>
|
<property name="permission">protected</property>
|
||||||
<property name="permission">none</property>
|
|
||||||
<event name="OnUpdateUI"></event>
|
<event name="OnUpdateUI"></event>
|
||||||
<object class="sizeritem" expanded="1">
|
<object class="sizeritem" expanded="1">
|
||||||
<property name="border">5</property>
|
<property name="border">5</property>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// C++ code generated with wxFormBuilder (version Jan 1 2016)
|
// C++ code generated with wxFormBuilder (version Mar 9 2016)
|
||||||
// http://www.wxformbuilder.org/
|
// http://www.wxformbuilder.org/
|
||||||
//
|
//
|
||||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
|
@ -68,6 +68,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
|
||||||
wxStaticText* m_labelStagger;
|
wxStaticText* m_labelStagger;
|
||||||
wxTextCtrl* m_entryStagger;
|
wxTextCtrl* m_entryStagger;
|
||||||
wxRadioBox* m_radioBoxGridStaggerType;
|
wxRadioBox* m_radioBoxGridStaggerType;
|
||||||
|
wxBoxSizer* m_gridPadNumberingSizer;
|
||||||
wxRadioBox* m_radioBoxGridNumberingAxis;
|
wxRadioBox* m_radioBoxGridNumberingAxis;
|
||||||
wxCheckBox* m_checkBoxGridReverseNumbering;
|
wxCheckBox* m_checkBoxGridReverseNumbering;
|
||||||
wxRadioBox* m_rbGridStartNumberingOpt;
|
wxRadioBox* m_rbGridStartNumberingOpt;
|
||||||
|
@ -95,6 +96,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
|
||||||
wxTextCtrl* m_entryCircCount;
|
wxTextCtrl* m_entryCircCount;
|
||||||
wxStaticText* m_labelCircRotate;
|
wxStaticText* m_labelCircRotate;
|
||||||
wxCheckBox* m_entryRotateItemsCb;
|
wxCheckBox* m_entryRotateItemsCb;
|
||||||
|
wxStaticBoxSizer* m_circPadNumberingSizer;
|
||||||
wxRadioBox* m_rbCircStartNumberingOpt;
|
wxRadioBox* m_rbCircStartNumberingOpt;
|
||||||
wxStaticText* m_labelCircNumStart;
|
wxStaticText* m_labelCircNumStart;
|
||||||
wxTextCtrl* m_entryCircNumberingStart;
|
wxTextCtrl* m_entryCircNumberingStart;
|
||||||
|
|
127
pcbnew/edit.cpp
127
pcbnew/edit.cpp
|
@ -53,9 +53,9 @@
|
||||||
#include <dialog_drc.h>
|
#include <dialog_drc.h>
|
||||||
#include <dialog_global_edit_tracks_and_vias.h>
|
#include <dialog_global_edit_tracks_and_vias.h>
|
||||||
#include <invoke_pcb_dialog.h>
|
#include <invoke_pcb_dialog.h>
|
||||||
|
#include <array_creator.h>
|
||||||
|
|
||||||
#include <dialog_move_exact.h>
|
#include <dialog_move_exact.h>
|
||||||
#include <dialog_create_array.h>
|
|
||||||
|
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <tools/common_actions.h>
|
#include <tools/common_actions.h>
|
||||||
|
@ -1599,83 +1599,56 @@ void PCB_BASE_EDIT_FRAME::duplicateItem( BOARD_ITEM* aItem, bool aIncrement )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class LEGACY_ARRAY_CREATOR: public ARRAY_CREATOR
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
LEGACY_ARRAY_CREATOR( PCB_BASE_EDIT_FRAME& editFrame ):
|
||||||
|
ARRAY_CREATOR( editFrame ),
|
||||||
|
m_item( m_parent.GetScreen()->GetCurItem() )
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int getNumberOfItemsToArray() const //override
|
||||||
|
{
|
||||||
|
// only handle single items
|
||||||
|
return (m_item != NULL) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOARD_ITEM* getNthItemToArray( int n ) const //override
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( n == 0, "Legacy array tool can only handle a single item" );
|
||||||
|
return m_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOARD* getBoard() const //override
|
||||||
|
{
|
||||||
|
return m_parent.GetBoard();
|
||||||
|
}
|
||||||
|
|
||||||
|
MODULE* getModule() const //override
|
||||||
|
{
|
||||||
|
return dynamic_cast<MODULE*>( m_item->GetParent() );
|
||||||
|
}
|
||||||
|
|
||||||
|
wxPoint getRotationCentre() const //override
|
||||||
|
{
|
||||||
|
return m_item->GetCenter();
|
||||||
|
}
|
||||||
|
|
||||||
|
void finalise() // override
|
||||||
|
{
|
||||||
|
m_parent.GetCanvas()->Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOARD_ITEM* m_item; // only have the one
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void PCB_BASE_EDIT_FRAME::createArray()
|
void PCB_BASE_EDIT_FRAME::createArray()
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = GetScreen()->GetCurItem();
|
LEGACY_ARRAY_CREATOR array_creator( *this );
|
||||||
|
|
||||||
if( !item )
|
array_creator.Invoke();
|
||||||
return;
|
|
||||||
|
|
||||||
// Note: original item is no more modified.
|
|
||||||
|
|
||||||
bool editingModule = NULL != dynamic_cast<FOOTPRINT_EDIT_FRAME*>( this );
|
|
||||||
|
|
||||||
BOARD* board = GetBoard();
|
|
||||||
|
|
||||||
// Remember this is valid and used only in the module editor.
|
|
||||||
// in board editor, the parent of items is usually the board.
|
|
||||||
MODULE* module = static_cast<MODULE*>( item->GetParent() );
|
|
||||||
|
|
||||||
DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* array_opts = NULL;
|
|
||||||
|
|
||||||
const wxPoint rotPoint = item->GetCenter();
|
|
||||||
|
|
||||||
DIALOG_CREATE_ARRAY dialog( this, rotPoint, &array_opts );
|
|
||||||
int ret = dialog.ShowModal();
|
|
||||||
|
|
||||||
if( ret == wxID_OK && array_opts != NULL )
|
|
||||||
{
|
|
||||||
PICKED_ITEMS_LIST newItemsList;
|
|
||||||
|
|
||||||
if( item->Type() == PCB_PAD_T && !editingModule )
|
|
||||||
{
|
|
||||||
// If it is not the module editor, then duplicate the parent module instead
|
|
||||||
item = static_cast<MODULE*>( item )->GetParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( editingModule )
|
|
||||||
{
|
|
||||||
// modedit saves everything upfront
|
|
||||||
SaveCopyInUndoList( board->m_Modules, UR_MODEDIT );
|
|
||||||
}
|
|
||||||
|
|
||||||
#define INCREMENT_REF false
|
|
||||||
#define INCREMENT_PADNUMBER true
|
|
||||||
|
|
||||||
// The first item in list is the original item. We do not modify it
|
|
||||||
for( int ptN = 1; ptN < array_opts->GetArraySize(); ptN++ )
|
|
||||||
{
|
|
||||||
BOARD_ITEM* new_item;
|
|
||||||
|
|
||||||
if( editingModule )
|
|
||||||
new_item = module->DuplicateAndAddItem( item, INCREMENT_PADNUMBER );
|
|
||||||
else
|
|
||||||
new_item = board->DuplicateAndAddItem( item, INCREMENT_REF );
|
|
||||||
|
|
||||||
if( new_item )
|
|
||||||
{
|
|
||||||
array_opts->TransformItem( ptN, new_item, rotPoint );
|
|
||||||
newItemsList.PushItem( new_item ); // For undo list
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !new_item || !array_opts->ShouldRenumberItems() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Renumber pads. Only new pad number renumbering has meaning,
|
|
||||||
// in the footprint editor.
|
|
||||||
if( new_item->Type() == PCB_PAD_T )
|
|
||||||
{
|
|
||||||
const wxString padName = array_opts->GetItemNumber( ptN );
|
|
||||||
static_cast<D_PAD*>( new_item )->SetPadName( padName );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !editingModule )
|
|
||||||
{
|
|
||||||
// pcbnew saves the new items like this
|
|
||||||
SaveCopyInUndoList( newItemsList, UR_NEW );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_canvas->Refresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <kiway.h>
|
#include <kiway.h>
|
||||||
#include <class_draw_panel_gal.h>
|
#include <class_draw_panel_gal.h>
|
||||||
#include <module_editor_frame.h>
|
#include <module_editor_frame.h>
|
||||||
|
#include <array_creator.h>
|
||||||
|
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <view/view_controls.h>
|
#include <view/view_controls.h>
|
||||||
|
@ -51,7 +52,6 @@
|
||||||
|
|
||||||
#include <router/router_tool.h>
|
#include <router/router_tool.h>
|
||||||
|
|
||||||
#include <dialogs/dialog_create_array.h>
|
|
||||||
#include <dialogs/dialog_move_exact.h>
|
#include <dialogs/dialog_move_exact.h>
|
||||||
#include <dialogs/dialog_track_via_properties.h>
|
#include <dialogs/dialog_track_via_properties.h>
|
||||||
|
|
||||||
|
@ -794,7 +794,81 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
||||||
decUndoInhibit();
|
decUndoInhibit();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class GAL_ARRAY_CREATOR: public ARRAY_CREATOR
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
GAL_ARRAY_CREATOR( PCB_BASE_FRAME& editFrame, bool editModules,
|
||||||
|
RN_DATA* ratsnest,
|
||||||
|
const SELECTION& selection ):
|
||||||
|
ARRAY_CREATOR( editFrame ),
|
||||||
|
m_editModules( editModules ),
|
||||||
|
m_ratsnest( ratsnest ),
|
||||||
|
m_selection( selection )
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int getNumberOfItemsToArray() const //override
|
||||||
|
{
|
||||||
|
// only handle single items
|
||||||
|
return m_selection.Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOARD_ITEM* getNthItemToArray( int n ) const //override
|
||||||
|
{
|
||||||
|
return m_selection.Item<BOARD_ITEM>( n );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOARD* getBoard() const //override
|
||||||
|
{
|
||||||
|
return m_parent.GetBoard();
|
||||||
|
}
|
||||||
|
|
||||||
|
MODULE* getModule() const //override
|
||||||
|
{
|
||||||
|
// Remember this is valid and used only in the module editor.
|
||||||
|
// in board editor, the parent of items is usually the board.
|
||||||
|
return m_editModules ? m_parent.GetBoard()->m_Modules.GetFirst() : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxPoint getRotationCentre() const //override
|
||||||
|
{
|
||||||
|
const VECTOR2I rp = m_selection.GetCenter();
|
||||||
|
return wxPoint( rp.x, rp.y );
|
||||||
|
}
|
||||||
|
|
||||||
|
void prePushAction( BOARD_ITEM* new_item ) // override
|
||||||
|
{
|
||||||
|
m_parent.GetToolManager()->RunAction( COMMON_ACTIONS::unselectItem,
|
||||||
|
true, new_item );
|
||||||
|
}
|
||||||
|
|
||||||
|
void postPushAction( BOARD_ITEM* new_item ) //override
|
||||||
|
{
|
||||||
|
KIGFX::VIEW* view = m_parent.GetToolManager()->GetView();
|
||||||
|
if( new_item->Type() == PCB_MODULE_T)
|
||||||
|
{
|
||||||
|
static_cast<MODULE*>( new_item )->RunOnChildren(
|
||||||
|
boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_parent.GetGalCanvas()->GetView()->Add( new_item );
|
||||||
|
m_ratsnest->Update( new_item );
|
||||||
|
}
|
||||||
|
|
||||||
|
void finalise() // override
|
||||||
|
{
|
||||||
|
m_ratsnest->Recalculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool m_editModules;
|
||||||
|
RN_DATA* m_ratsnest;
|
||||||
|
const SELECTION& m_selection;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
|
int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
|
||||||
|
@ -803,113 +877,19 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
|
||||||
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||||
const SELECTION& selection = selTool->GetSelection();
|
const SELECTION& selection = selTool->GetSelection();
|
||||||
|
|
||||||
// Be sure that there is at least one item that we can modify
|
// pick up items under the cursor if needed
|
||||||
if( !hoverSelection( selection ) )
|
hoverSelection( selection );
|
||||||
return 0;
|
|
||||||
|
|
||||||
// we have a selection to work on now, so start the tool process
|
// we have a selection to work on now, so start the tool process
|
||||||
|
|
||||||
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
|
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
editFrame->OnModify();
|
editFrame->OnModify();
|
||||||
|
|
||||||
if( m_editModules )
|
GAL_ARRAY_CREATOR array_creator( *editFrame, m_editModules,
|
||||||
{
|
getModel<BOARD>()->GetRatsnest(),
|
||||||
// Module editors do their undo point upfront for the whole module
|
selection );
|
||||||
editFrame->SaveCopyInUndoList( editFrame->GetBoard()->m_Modules, UR_MODEDIT );
|
|
||||||
}
|
|
||||||
|
|
||||||
DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* array_opts = NULL;
|
array_creator.Invoke();
|
||||||
|
|
||||||
VECTOR2I rp = selection.GetCenter();
|
|
||||||
const wxPoint rotPoint( rp.x, rp.y );
|
|
||||||
|
|
||||||
DIALOG_CREATE_ARRAY dialog( editFrame, rotPoint, &array_opts );
|
|
||||||
int ret = dialog.ShowModal();
|
|
||||||
|
|
||||||
if( ret == wxID_OK && array_opts != NULL )
|
|
||||||
{
|
|
||||||
PICKED_ITEMS_LIST newItemList;
|
|
||||||
|
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
|
||||||
{
|
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
|
|
||||||
if( !item )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// iterate across the array, laying out the item at the
|
|
||||||
// correct position
|
|
||||||
const unsigned nPoints = array_opts->GetArraySize();
|
|
||||||
|
|
||||||
// The first item in list is the original item. We do not modify it
|
|
||||||
for( unsigned ptN = 1; ptN < nPoints; ++ptN )
|
|
||||||
{
|
|
||||||
BOARD_ITEM* newItem = NULL;
|
|
||||||
|
|
||||||
// Some items cannot be duplicated
|
|
||||||
// i.e. the ref and value fields of a footprint or zones
|
|
||||||
// therefore newItem can be null
|
|
||||||
|
|
||||||
#define INCREMENT_REF false
|
|
||||||
#define INCREMENT_PADNUMBER true
|
|
||||||
|
|
||||||
if( m_editModules )
|
|
||||||
newItem = editFrame->GetBoard()->m_Modules->DuplicateAndAddItem(
|
|
||||||
item, INCREMENT_PADNUMBER );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
// @TODO: see if we allow zone duplication here
|
|
||||||
// Duplicate zones is especially tricky (overlaping zones must be merged)
|
|
||||||
// so zones are not duplicated
|
|
||||||
if( item->Type() == PCB_ZONE_AREA_T )
|
|
||||||
newItem = NULL;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
newItem = editFrame->GetBoard()->DuplicateAndAddItem(
|
|
||||||
item, INCREMENT_REF );
|
|
||||||
// @TODO: we should merge zones. This is a bit tricky, because
|
|
||||||
// the undo command needs saving old area, if it is merged.
|
|
||||||
}
|
|
||||||
|
|
||||||
if( newItem )
|
|
||||||
{
|
|
||||||
array_opts->TransformItem( ptN, newItem, rotPoint );
|
|
||||||
|
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::unselectItem, true, newItem );
|
|
||||||
|
|
||||||
newItemList.PushItem( newItem );
|
|
||||||
|
|
||||||
if( newItem->Type() == PCB_MODULE_T)
|
|
||||||
{
|
|
||||||
static_cast<MODULE*>( newItem )->RunOnChildren( boost::bind( &KIGFX::VIEW::Add,
|
|
||||||
getView(), _1 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
editFrame->GetGalCanvas()->GetView()->Add( newItem );
|
|
||||||
getModel<BOARD>()->GetRatsnest()->Update( newItem );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only renumbering pads has meaning:
|
|
||||||
if( newItem && array_opts->ShouldRenumberItems() )
|
|
||||||
{
|
|
||||||
if( newItem->Type() == PCB_PAD_T )
|
|
||||||
{
|
|
||||||
const wxString padName = array_opts->GetItemNumber( ptN );
|
|
||||||
static_cast<D_PAD*>( newItem )->SetPadName( padName );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !m_editModules )
|
|
||||||
{
|
|
||||||
// Add all items as a single undo point for PCB editors
|
|
||||||
editFrame->SaveCopyInUndoList( newItemList, UR_NEW );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getModel<BOARD>()->GetRatsnest()->Recalculate();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue