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
|
||||
pcb_base_edit_frame.cpp
|
||||
append_board_to_current.cpp
|
||||
array_creator.cpp
|
||||
attribut.cpp
|
||||
board_items_to_polygon_shape_transform.cpp
|
||||
board_undo_redo.cpp
|
||||
|
|
|
@ -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 <base_units.h>
|
||||
#include <macros.h>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
|
||||
#include <class_drawpanel.h>
|
||||
#include <class_board.h>
|
||||
|
@ -37,12 +38,14 @@
|
|||
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::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent,
|
||||
bool enableNumbering,
|
||||
wxPoint aOrigPos ) :
|
||||
DIALOG_CREATE_ARRAY_BASE( aParent ),
|
||||
CONFIG_SAVE_RESTORE_WINDOW( m_options.m_optionsSet ),
|
||||
m_settings( aSettings ),
|
||||
m_originalItemPosition( aOrigPos )
|
||||
m_settings( NULL ),
|
||||
m_originalItemPosition( aOrigPos ),
|
||||
m_numberingEnabled(enableNumbering)
|
||||
{
|
||||
// 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_entryGridSecNumberingOffset, m_options.m_gridSecNumberingOffset );
|
||||
|
||||
Add( m_rbGridStartNumberingOpt, m_options.m_gridNumberingScheme );
|
||||
Add( m_rbCircStartNumberingOpt, m_options.m_circNumberingScheme );
|
||||
|
||||
RestoreConfigToControls();
|
||||
|
||||
// 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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
static const std::string alphaNumeric = "0123456789";
|
||||
static const std::string alphaHex = "0123456789ABCDEF";
|
||||
static const std::string alphaFull = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
static const std::string alphaNoIOSQXZ = "ABCDEFGHJKLMNPRTUVWY";
|
||||
static const wxString alphaNumeric = "0123456789";
|
||||
static const wxString alphaHex = "0123456789ABCDEF";
|
||||
static const wxString alphaFull = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
static const wxString alphaNoIOSQXZ = "ABCDEFGHJKLMNPRTUVWY";
|
||||
|
||||
switch( type )
|
||||
{
|
||||
|
@ -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,
|
||||
int& offsetToFill )
|
||||
{
|
||||
const std::string alphabet = alphabetFromNumberingScheme( type );
|
||||
const wxString alphabet = alphabetFromNumberingScheme( type );
|
||||
|
||||
int offset = 0;
|
||||
const int radix = alphabet.length();
|
||||
|
||||
for( unsigned i = 0; i < str.length(); i++ )
|
||||
{
|
||||
int chIndex = alphabet.find( str[i], 0 );
|
||||
int chIndex = alphabet.Find( str[i], false );
|
||||
|
||||
if( chIndex == wxNOT_FOUND )
|
||||
return false;
|
||||
|
@ -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 )
|
||||
{
|
||||
ARRAY_OPTIONS* newSettings = NULL;
|
||||
|
||||
wxArrayString errorStrs;
|
||||
|
||||
const wxWindow* page = m_gridTypeNotebook->GetCurrentPage();
|
||||
|
||||
if( page == m_gridPanel )
|
||||
|
@ -207,8 +295,11 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
|
|||
bool ok = true;
|
||||
|
||||
// ints
|
||||
ok = ok && m_entryNx->GetValue().ToLong( &newGrid->m_nx );
|
||||
ok = ok && m_entryNy->GetValue().ToLong( &newGrid->m_ny );
|
||||
ok = ok && validateLongEntry(*m_entryNx, newGrid->m_nx, _("horizontal count"),
|
||||
errorStrs);
|
||||
ok = ok && validateLongEntry(*m_entryNy, newGrid->m_ny, _("vertical count"),
|
||||
errorStrs);
|
||||
|
||||
|
||||
newGrid->m_delta.x = DoubleValueFromString( g_UserUnit, m_entryDx->GetValue() );
|
||||
newGrid->m_delta.y = DoubleValueFromString( g_UserUnit, m_entryDy->GetValue() );
|
||||
|
@ -216,39 +307,37 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
|
|||
newGrid->m_offset.x = DoubleValueFromString( g_UserUnit, m_entryOffsetX->GetValue() );
|
||||
newGrid->m_offset.y = DoubleValueFromString( g_UserUnit, m_entryOffsetY->GetValue() );
|
||||
|
||||
ok = ok && m_entryStagger->GetValue().ToLong( &newGrid->m_stagger );
|
||||
ok = ok && validateLongEntry(*m_entryStagger, newGrid->m_stagger, _("stagger"),
|
||||
errorStrs);
|
||||
|
||||
newGrid->m_stagger_rows = m_radioBoxGridStaggerType->GetSelection() == 0;
|
||||
|
||||
newGrid->m_horizontalThenVertical = m_radioBoxGridNumberingAxis->GetSelection() == 0;
|
||||
newGrid->m_reverseNumberingAlternate = m_checkBoxGridReverseNumbering->GetValue();
|
||||
|
||||
newGrid->m_shouldNumber = m_numberingEnabled;
|
||||
|
||||
if ( m_numberingEnabled )
|
||||
{
|
||||
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 );
|
||||
bool numOk = validateNumberingTypeAndOffset(
|
||||
*m_entryGridPriNumberingOffset, *m_choicePriAxisNumbering,
|
||||
newGrid->m_priAxisNumType, newGrid->m_numberingOffsetX,
|
||||
errorStrs );
|
||||
|
||||
if( newGrid->m_2dArrayNumbering )
|
||||
ok = ok && getNumberingOffset(
|
||||
m_entryGridSecNumberingOffset->GetValue().ToStdString(),
|
||||
newGrid->m_secAxisNumType, newGrid->m_numberingOffsetY );
|
||||
{
|
||||
numOk = validateNumberingTypeAndOffset(
|
||||
*m_entryGridSecNumberingOffset, *m_choiceSecAxisNumbering,
|
||||
newGrid->m_secAxisNumType, newGrid->m_numberingOffsetY,
|
||||
errorStrs ) && numOk;
|
||||
}
|
||||
|
||||
newGrid->m_shouldRenumber = m_rbGridStartNumberingOpt->GetSelection() == 1;
|
||||
ok = ok && numOk;
|
||||
|
||||
newGrid->m_numberingStartIsSpecified = m_rbGridStartNumberingOpt->GetSelection() == 1;
|
||||
}
|
||||
|
||||
// Only use settings if all values are good
|
||||
if( ok )
|
||||
|
@ -265,13 +354,23 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
|
|||
newCirc->m_centre.y = DoubleValueFromString( g_UserUnit, m_entryCentreY->GetValue() );
|
||||
|
||||
newCirc->m_angle = DoubleValueFromString( DEGREES, m_entryCircAngle->GetValue() );
|
||||
ok = ok && m_entryCircCount->GetValue().ToLong( &newCirc->m_nPts );
|
||||
|
||||
ok = ok && validateLongEntry(*m_entryCircCount, newCirc->m_nPts,
|
||||
_("point count"), errorStrs);
|
||||
|
||||
newCirc->m_rotateItems = m_entryRotateItemsCb->GetValue();
|
||||
newCirc->m_shouldRenumber = m_rbCircStartNumberingOpt->GetSelection() == 1;
|
||||
|
||||
newCirc->m_shouldNumber = m_numberingEnabled;
|
||||
|
||||
if ( m_numberingEnabled )
|
||||
{
|
||||
newCirc->m_numberingStartIsSpecified = m_rbCircStartNumberingOpt->GetSelection() == 1;
|
||||
newCirc->m_numberingType = NUMBERING_NUMERIC;
|
||||
|
||||
ok = ok && m_entryCircNumberingStart->GetValue().ToLong( &newCirc->m_numberingOffset );
|
||||
ok = ok && validateLongEntry(*m_entryCircNumberingStart,
|
||||
newCirc->m_numberingOffset,
|
||||
_("numbering start"), errorStrs);
|
||||
}
|
||||
|
||||
// Only use settings if all values are good
|
||||
if( ok )
|
||||
|
@ -283,22 +382,32 @@ void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
|
|||
// If we got good settings, send them out and finish
|
||||
if( newSettings )
|
||||
{
|
||||
delete *m_settings;
|
||||
delete m_settings;
|
||||
|
||||
// assign pointer and ownership here
|
||||
*m_settings = newSettings;
|
||||
m_settings = newSettings;
|
||||
ReadConfigFromControls();
|
||||
|
||||
EndModal( wxID_OK );
|
||||
}
|
||||
|
||||
else
|
||||
wxMessageBox( _("Bad parameters" ) );
|
||||
{
|
||||
wxString errorStr;
|
||||
|
||||
if( errorStrs.IsEmpty() )
|
||||
errorStr = _("Bad parameters");
|
||||
else
|
||||
errorStr = boost::algorithm::join( errorStrs, "\n" );
|
||||
|
||||
wxMessageBox( errorStr );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_CREATE_ARRAY::setControlEnablement()
|
||||
{
|
||||
if ( m_numberingEnabled )
|
||||
{
|
||||
const bool renumber = m_rbGridStartNumberingOpt->GetSelection() == 1;
|
||||
|
||||
// If we're not renumbering, we can't set the numbering scheme
|
||||
|
@ -320,6 +429,23 @@ void DIALOG_CREATE_ARRAY::setControlEnablement()
|
|||
m_entryGridSecNumberingOffset->Enable( renumber && num2d );
|
||||
|
||||
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 --------------------------------------
|
||||
|
||||
std::string DIALOG_CREATE_ARRAY::ARRAY_OPTIONS::getCoordinateNumber( int n,
|
||||
wxString DIALOG_CREATE_ARRAY::ARRAY_OPTIONS::getCoordinateNumber( int n,
|
||||
ARRAY_NUMBERING_TYPE_T type )
|
||||
{
|
||||
std::string itemNum;
|
||||
const std::string& alphabet = alphabetFromNumberingScheme( type );
|
||||
wxString itemNum;
|
||||
const wxString& alphabet = alphabetFromNumberingScheme( type );
|
||||
|
||||
const bool nonUnitColsStartAt0 = schemeNonUnitColsStartAt0( type );
|
||||
|
||||
bool firstRound = true;
|
||||
int radix = alphabet.length();
|
||||
int radix = alphabet.Length();
|
||||
|
||||
do {
|
||||
int modN = n % radix;
|
||||
|
@ -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
|
||||
{
|
||||
// The first new pad has aN number == 1, not 0
|
||||
if( m_shouldRenumber ) // numbering pad from initial user value
|
||||
return getCoordinateNumber( aN - 1 + m_numberingOffset, m_numberingType );
|
||||
else // numbering pad from inital pad number
|
||||
return getCoordinateNumber( aN + m_numberingOffset, m_numberingType );
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
// Include the wxFormBuider header base:
|
||||
#include <dialog_create_array_base.h>
|
||||
|
||||
#include <class_board_item.h>
|
||||
#include <wxBasePcbFrame.h>
|
||||
|
||||
#include <boost/bimap.hpp>
|
||||
|
||||
class CONFIG_SAVE_RESTORE_WINDOW
|
||||
|
@ -72,7 +75,7 @@ protected:
|
|||
ctrls.push_back( ctrlInfo );
|
||||
}
|
||||
|
||||
void Add( wxTextCtrl* ctrl, std::string& dest )
|
||||
void Add( wxTextCtrl* ctrl, wxString& dest )
|
||||
{
|
||||
CONFIG_CTRL_T ctrlInfo = { ctrl, CFG_CTRL_TEXT, (void*) &dest };
|
||||
|
||||
|
@ -105,7 +108,7 @@ protected:
|
|||
break;
|
||||
|
||||
case CFG_CTRL_TEXT:
|
||||
*(std::string*) iter->dest = static_cast<wxTextCtrl*>( iter->control )->GetValue();
|
||||
*(wxString*) iter->dest = static_cast<wxTextCtrl*>( iter->control )->GetValue();
|
||||
break;
|
||||
|
||||
case CFG_CTRL_CHOICE:
|
||||
|
@ -144,7 +147,7 @@ protected:
|
|||
break;
|
||||
|
||||
case CFG_CTRL_TEXT:
|
||||
static_cast<wxTextCtrl*>( iter->control )->SetValue( *(std::string*) iter->dest );
|
||||
static_cast<wxTextCtrl*>( iter->control )->SetValue( *(wxString*) iter->dest );
|
||||
break;
|
||||
|
||||
case CFG_CTRL_CHOICE:
|
||||
|
@ -201,13 +204,13 @@ public:
|
|||
{
|
||||
ARRAY_OPTIONS( ARRAY_TYPE_T aType ) :
|
||||
m_type( aType ),
|
||||
m_shouldRenumber( false )
|
||||
m_shouldNumber( false ),
|
||||
m_numberingStartIsSpecified( false )
|
||||
{}
|
||||
|
||||
virtual ~ARRAY_OPTIONS() {};
|
||||
|
||||
ARRAY_TYPE_T m_type;
|
||||
bool m_shouldRenumber;
|
||||
|
||||
/*!
|
||||
* Function GetArrayPositions
|
||||
|
@ -222,13 +225,37 @@ public:
|
|||
virtual wxString GetItemNumber( int n ) const = 0;
|
||||
virtual wxString InterpolateNumberIntoString( int n, const wxString& pattern ) const;
|
||||
|
||||
bool ShouldRenumberItems() const
|
||||
/*!
|
||||
* @return are the items in this array numberred, or are all the
|
||||
* items numbered the same
|
||||
*/
|
||||
bool ShouldNumberItems() const
|
||||
{
|
||||
return m_shouldRenumber;
|
||||
return m_shouldNumber;
|
||||
}
|
||||
|
||||
protected:
|
||||
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
|
||||
|
@ -289,16 +316,27 @@ private:
|
|||
};
|
||||
|
||||
// Constructor and destructor
|
||||
DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrigPos, ARRAY_OPTIONS** settings );
|
||||
virtual ~DIALOG_CREATE_ARRAY() {};
|
||||
DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, bool enableNumbering,
|
||||
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:
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -329,7 +367,7 @@ private:
|
|||
|
||||
bool m_optionsSet;
|
||||
|
||||
std::string m_gridNx, m_gridNy,
|
||||
wxString m_gridNx, m_gridNy,
|
||||
m_gridDx, m_gridDy,
|
||||
m_gridOffsetX, m_gridOffsetY,
|
||||
m_gridStagger;
|
||||
|
@ -338,18 +376,19 @@ private:
|
|||
bool m_gridNumberingReverseAlternate;
|
||||
int m_grid2dArrayNumbering;
|
||||
int m_gridPriAxisNumScheme, m_gridSecAxisNumScheme;
|
||||
std::string m_gridPriNumberingOffset, m_gridSecNumberingOffset;
|
||||
wxString m_gridPriNumberingOffset, m_gridSecNumberingOffset;
|
||||
|
||||
std::string m_circCentreX, m_circCentreY,
|
||||
wxString m_circCentreX, m_circCentreY,
|
||||
m_circAngle, m_circCount, m_circNumberingOffset;
|
||||
bool m_circRotate;
|
||||
int m_arrayTypeTab;
|
||||
int m_gridNumberingScheme;
|
||||
int m_circNumberingScheme;
|
||||
};
|
||||
|
||||
static CREATE_ARRAY_DIALOG_ENTRIES m_options;
|
||||
// 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__
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Jan 1 2016)
|
||||
// C++ code generated with wxFormBuilder (version Mar 9 2016)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
|
@ -100,51 +100,50 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
|
|||
|
||||
bSizer2->Add( gbSizer1, 1, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bSizer3;
|
||||
bSizer3 = new wxBoxSizer( wxVERTICAL );
|
||||
m_gridPadNumberingSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxString m_radioBoxGridNumberingAxisChoices[] = { _("Horizontal, then vertical"), _("Vertical, then horizontal") };
|
||||
int m_radioBoxGridNumberingAxisNChoices = sizeof( m_radioBoxGridNumberingAxisChoices ) / sizeof( wxString );
|
||||
m_radioBoxGridNumberingAxis = new wxRadioBox( m_gridPanel, wxID_ANY, _("Pad Numbering Direction"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingAxisNChoices, m_radioBoxGridNumberingAxisChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_radioBoxGridNumberingAxis->SetSelection( 0 );
|
||||
bSizer3->Add( m_radioBoxGridNumberingAxis, 0, wxALL|wxEXPAND, 5 );
|
||||
m_gridPadNumberingSizer->Add( m_radioBoxGridNumberingAxis, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_checkBoxGridReverseNumbering = new wxCheckBox( m_gridPanel, wxID_ANY, _("Reverse pad numbering on alternate rows or columns"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizer3->Add( m_checkBoxGridReverseNumbering, 0, wxALL, 5 );
|
||||
m_gridPadNumberingSizer->Add( m_checkBoxGridReverseNumbering, 0, wxALL, 5 );
|
||||
|
||||
wxString m_rbGridStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") };
|
||||
int m_rbGridStartNumberingOptNChoices = sizeof( m_rbGridStartNumberingOptChoices ) / sizeof( wxString );
|
||||
m_rbGridStartNumberingOpt = new wxRadioBox( m_gridPanel, wxID_ANY, _("Initial pad number"), wxDefaultPosition, wxDefaultSize, m_rbGridStartNumberingOptNChoices, m_rbGridStartNumberingOptChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_rbGridStartNumberingOpt->SetSelection( 1 );
|
||||
bSizer3->Add( m_rbGridStartNumberingOpt, 0, wxALL|wxEXPAND, 5 );
|
||||
m_gridPadNumberingSizer->Add( m_rbGridStartNumberingOpt, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
wxString m_radioBoxGridNumberingSchemeChoices[] = { _("Continuous (1, 2, 3...)"), _("Coordinate (A1, A2, ... B1, ...)") };
|
||||
int m_radioBoxGridNumberingSchemeNChoices = sizeof( m_radioBoxGridNumberingSchemeChoices ) / sizeof( wxString );
|
||||
m_radioBoxGridNumberingScheme = new wxRadioBox( m_gridPanel, wxID_ANY, _("Pad Numbering Scheme"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingSchemeNChoices, m_radioBoxGridNumberingSchemeChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_radioBoxGridNumberingScheme->SetSelection( 1 );
|
||||
bSizer3->Add( m_radioBoxGridNumberingScheme, 0, wxALL|wxEXPAND, 5 );
|
||||
m_gridPadNumberingSizer->Add( m_radioBoxGridNumberingScheme, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_labelPriAxisNumbering = new wxStaticText( m_gridPanel, wxID_ANY, _("Primary axis numbering:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_labelPriAxisNumbering->Wrap( -1 );
|
||||
bSizer3->Add( m_labelPriAxisNumbering, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
|
||||
m_gridPadNumberingSizer->Add( m_labelPriAxisNumbering, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
|
||||
|
||||
wxArrayString m_choicePriAxisNumberingChoices;
|
||||
m_choicePriAxisNumbering = new wxChoice( m_gridPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choicePriAxisNumberingChoices, 0 );
|
||||
m_choicePriAxisNumbering->SetSelection( 0 );
|
||||
bSizer3->Add( m_choicePriAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
m_gridPadNumberingSizer->Add( m_choicePriAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_labelSecAxisNumbering = new wxStaticText( m_gridPanel, wxID_ANY, _("Secondary axis numbering:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_labelSecAxisNumbering->Wrap( -1 );
|
||||
m_labelSecAxisNumbering->Enable( false );
|
||||
|
||||
bSizer3->Add( m_labelSecAxisNumbering, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
m_gridPadNumberingSizer->Add( m_labelSecAxisNumbering, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
wxArrayString m_choiceSecAxisNumberingChoices;
|
||||
m_choiceSecAxisNumbering = new wxChoice( m_gridPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceSecAxisNumberingChoices, 0 );
|
||||
m_choiceSecAxisNumbering->SetSelection( 0 );
|
||||
m_choiceSecAxisNumbering->Enable( false );
|
||||
|
||||
bSizer3->Add( m_choiceSecAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
m_gridPadNumberingSizer->Add( m_choiceSecAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
wxBoxSizer* bSizer5;
|
||||
bSizer5 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
@ -160,10 +159,10 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
|
|||
bSizer5->Add( m_entryGridSecNumberingOffset, 0, wxALL, 5 );
|
||||
|
||||
|
||||
bSizer3->Add( bSizer5, 0, wxEXPAND, 5 );
|
||||
m_gridPadNumberingSizer->Add( bSizer5, 0, wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizer2->Add( bSizer3, 0, wxALL|wxEXPAND, 5 );
|
||||
bSizer2->Add( m_gridPadNumberingSizer, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_gridPanel->SetSizer( bSizer2 );
|
||||
|
@ -244,30 +243,29 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
|
|||
|
||||
bSizer4->Add( gbSizer2, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
wxStaticBoxSizer* sbcircPadNumberingSizer;
|
||||
sbcircPadNumberingSizer = new wxStaticBoxSizer( new wxStaticBox( m_circularPanel, wxID_ANY, _("Pad Numbering Options") ), wxVERTICAL );
|
||||
m_circPadNumberingSizer = new wxStaticBoxSizer( new wxStaticBox( m_circularPanel, wxID_ANY, _("Pad Numbering Options") ), wxVERTICAL );
|
||||
|
||||
wxString m_rbCircStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") };
|
||||
int m_rbCircStartNumberingOptNChoices = sizeof( m_rbCircStartNumberingOptChoices ) / sizeof( wxString );
|
||||
m_rbCircStartNumberingOpt = new wxRadioBox( sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Initial pad number"), wxDefaultPosition, wxDefaultSize, m_rbCircStartNumberingOptNChoices, m_rbCircStartNumberingOptChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_rbCircStartNumberingOpt = new wxRadioBox( m_circPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Initial pad number"), wxDefaultPosition, wxDefaultSize, m_rbCircStartNumberingOptNChoices, m_rbCircStartNumberingOptChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_rbCircStartNumberingOpt->SetSelection( 0 );
|
||||
sbcircPadNumberingSizer->Add( m_rbCircStartNumberingOpt, 0, wxALL|wxEXPAND, 5 );
|
||||
m_circPadNumberingSizer->Add( m_rbCircStartNumberingOpt, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bSizer7;
|
||||
bSizer7 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_labelCircNumStart = new wxStaticText( sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Pad numbering start value:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_labelCircNumStart = new wxStaticText( m_circPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Pad numbering start value:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_labelCircNumStart->Wrap( -1 );
|
||||
bSizer7->Add( m_labelCircNumStart, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_entryCircNumberingStart = new wxTextCtrl( sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_entryCircNumberingStart = new wxTextCtrl( m_circPadNumberingSizer->GetStaticBox(), wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizer7->Add( m_entryCircNumberingStart, 1, wxALL, 5 );
|
||||
|
||||
|
||||
sbcircPadNumberingSizer->Add( bSizer7, 0, wxEXPAND, 5 );
|
||||
m_circPadNumberingSizer->Add( bSizer7, 0, wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizer4->Add( sbcircPadNumberingSizer, 1, wxEXPAND|wxALL, 5 );
|
||||
bSizer4->Add( m_circPadNumberingSizer, 1, wxEXPAND|wxALL, 5 );
|
||||
|
||||
|
||||
m_circularPanel->SetSizer( bSizer4 );
|
||||
|
|
|
@ -1978,9 +1978,9 @@
|
|||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="0">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizer3</property>
|
||||
<property name="name">m_gridPadNumberingSizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="permission">protected</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
|
@ -4397,10 +4397,9 @@
|
|||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Pad Numbering Options</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">sbcircPadNumberingSizer</property>
|
||||
<property name="name">m_circPadNumberingSizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="parent">1</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="permission">protected</property>
|
||||
<event name="OnUpdateUI"></event>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Jan 1 2016)
|
||||
// C++ code generated with wxFormBuilder (version Mar 9 2016)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
|
@ -68,6 +68,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
|
|||
wxStaticText* m_labelStagger;
|
||||
wxTextCtrl* m_entryStagger;
|
||||
wxRadioBox* m_radioBoxGridStaggerType;
|
||||
wxBoxSizer* m_gridPadNumberingSizer;
|
||||
wxRadioBox* m_radioBoxGridNumberingAxis;
|
||||
wxCheckBox* m_checkBoxGridReverseNumbering;
|
||||
wxRadioBox* m_rbGridStartNumberingOpt;
|
||||
|
@ -95,6 +96,7 @@ class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
|
|||
wxTextCtrl* m_entryCircCount;
|
||||
wxStaticText* m_labelCircRotate;
|
||||
wxCheckBox* m_entryRotateItemsCb;
|
||||
wxStaticBoxSizer* m_circPadNumberingSizer;
|
||||
wxRadioBox* m_rbCircStartNumberingOpt;
|
||||
wxStaticText* m_labelCircNumStart;
|
||||
wxTextCtrl* m_entryCircNumberingStart;
|
||||
|
|
127
pcbnew/edit.cpp
127
pcbnew/edit.cpp
|
@ -53,9 +53,9 @@
|
|||
#include <dialog_drc.h>
|
||||
#include <dialog_global_edit_tracks_and_vias.h>
|
||||
#include <invoke_pcb_dialog.h>
|
||||
#include <array_creator.h>
|
||||
|
||||
#include <dialog_move_exact.h>
|
||||
#include <dialog_create_array.h>
|
||||
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/common_actions.h>
|
||||
|
@ -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()
|
||||
{
|
||||
BOARD_ITEM* item = GetScreen()->GetCurItem();
|
||||
LEGACY_ARRAY_CREATOR array_creator( *this );
|
||||
|
||||
if( !item )
|
||||
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();
|
||||
}
|
||||
array_creator.Invoke();
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <kiway.h>
|
||||
#include <class_draw_panel_gal.h>
|
||||
#include <module_editor_frame.h>
|
||||
#include <array_creator.h>
|
||||
|
||||
#include <tool/tool_manager.h>
|
||||
#include <view/view_controls.h>
|
||||
|
@ -51,7 +52,6 @@
|
|||
|
||||
#include <router/router_tool.h>
|
||||
|
||||
#include <dialogs/dialog_create_array.h>
|
||||
#include <dialogs/dialog_move_exact.h>
|
||||
#include <dialogs/dialog_track_via_properties.h>
|
||||
|
||||
|
@ -794,7 +794,81 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
|||
decUndoInhibit();
|
||||
|
||||
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 )
|
||||
|
@ -803,113 +877,19 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
|
|||
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||
const SELECTION& selection = selTool->GetSelection();
|
||||
|
||||
// Be sure that there is at least one item that we can modify
|
||||
if( !hoverSelection( selection ) )
|
||||
return 0;
|
||||
// pick up items under the cursor if needed
|
||||
hoverSelection( selection );
|
||||
|
||||
// we have a selection to work on now, so start the tool process
|
||||
|
||||
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
|
||||
editFrame->OnModify();
|
||||
|
||||
if( m_editModules )
|
||||
{
|
||||
// Module editors do their undo point upfront for the whole module
|
||||
editFrame->SaveCopyInUndoList( editFrame->GetBoard()->m_Modules, UR_MODEDIT );
|
||||
}
|
||||
GAL_ARRAY_CREATOR array_creator( *editFrame, m_editModules,
|
||||
getModel<BOARD>()->GetRatsnest(),
|
||||
selection );
|
||||
|
||||
DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* array_opts = NULL;
|
||||
|
||||
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();
|
||||
array_creator.Invoke();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue