kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #17979
[PATCH] Add error checking to array create dialog
Hey
Currently array create dialog doesn't give any errors if some fields are
invalid, it just doesn't do anything. This patch adds error checking to
array create dialog which informs the user about the invalid parameters
with a message box.
Other fixes:
* Change the numbering start fields to default value if alphabet is
changed and numbering start isn't found in the alphabet.
* Avoid hang when creating arrays with negative count. This could also
be fixed in the code that generates the array.
* Use getNumberingOffset also for circular arrays.
Henrik Forstén
=== modified file 'pcbnew/dialogs/dialog_create_array.cpp'
--- pcbnew/dialogs/dialog_create_array.cpp 2015-04-09 23:41:08 +0000
+++ pcbnew/dialogs/dialog_create_array.cpp 2015-04-19 06:47:27 +0000
@@ -32,6 +32,11 @@
#include "dialog_create_array.h"
+static const std::string& alphabetFromNumberingScheme(
+ DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T type );
+static bool getNumberingOffset( const std::string& str,
+ DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T type,
+ int& offsetToFill );
// initialise statics
DIALOG_CREATE_ARRAY::CREATE_ARRAY_DIALOG_ENTRIES DIALOG_CREATE_ARRAY::m_options;
@@ -130,6 +135,57 @@
{
calculateCircularArrayProperties();
}
+ // If alphabet was changed, check that start of numbering is in the
+ // alphabet. If not set the default value.
+ if ( evObj == m_choicePriAxisNumbering || evObj == m_choiceSecAxisNumbering )
+ {
+ DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T priAxisNumType, secAxisNumType;
+
+ bool ok = m_choicePriAxisNumbering->GetSelection() < NUMBERING_TYPE_Max
+ && m_choiceSecAxisNumbering->GetSelection() < NUMBERING_TYPE_Max;
+
+ if( !ok )
+ {
+ return;
+ }
+
+ priAxisNumType =
+ (ARRAY_NUMBERING_TYPE_T) m_choicePriAxisNumbering->GetSelection();
+ secAxisNumType =
+ (ARRAY_NUMBERING_TYPE_T) m_choiceSecAxisNumbering->GetSelection();
+
+ int dummy;
+
+ // Check primary axis numbering
+ if ( !getNumberingOffset(
+ m_entryGridPriNumberingOffset->GetValue().ToStdString(),
+ priAxisNumType, dummy ) )
+ {
+ const std::string alphabet = alphabetFromNumberingScheme( priAxisNumType );
+ if (alphabet.length() > 0)
+ {
+ wxString start = alphabet[0];
+ if ( start == "0" )
+ start = "1";
+ m_entryGridPriNumberingOffset->SetValue( start );
+ }
+ }
+
+ // Secondary axis
+ if ( !getNumberingOffset(
+ m_entryGridSecNumberingOffset->GetValue().ToStdString(),
+ secAxisNumType, dummy ) )
+ {
+ const std::string alphabet = alphabetFromNumberingScheme( secAxisNumType );
+ if (alphabet.length() > 0)
+ {
+ wxString start = alphabet[0];
+ if ( start == "0" )
+ start = "1";
+ m_entryGridSecNumberingOffset->SetValue( start );
+ }
+ }
+ }
}
@@ -218,18 +274,35 @@
void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
{
ARRAY_OPTIONS* newSettings = NULL;
+ ARRAY_GRID_OPTIONS* newGrid;
+ ARRAY_CIRCULAR_OPTIONS* newCirc;
const wxWindow* page = m_gridTypeNotebook->GetCurrentPage();
+ UTF8 msg;
+
if( page == m_gridPanel )
{
- ARRAY_GRID_OPTIONS* newGrid = new ARRAY_GRID_OPTIONS();
+ newGrid = new ARRAY_GRID_OPTIONS();
bool ok = true;
// ints
ok = ok && m_entryNx->GetValue().ToLong( &newGrid->m_nx );
+
+ if( !ok || newGrid->m_nx < 0 )
+ {
+ msg = StrPrintf("Invalid x count");
+ goto grid_err;
+ }
+
ok = ok && m_entryNy->GetValue().ToLong( &newGrid->m_ny );
+ if( !ok || newGrid->m_ny < 0 )
+ {
+ msg = StrPrintf("Invalid y count");
+ goto grid_err;
+ }
+
newGrid->m_delta.x = DoubleValueFromString( g_UserUnit, m_entryDx->GetValue() );
newGrid->m_delta.y = DoubleValueFromString( g_UserUnit, m_entryDy->GetValue() );
@@ -238,6 +311,12 @@
ok = ok && m_entryStagger->GetValue().ToLong( &newGrid->m_stagger );
+ if( !ok )
+ {
+ msg = StrPrintf("Invalid stagger value");
+ goto grid_err;
+ }
+
newGrid->m_stagger_rows = m_radioBoxGridStaggerType->GetSelection() == 0;
newGrid->m_horizontalThenVertical = m_radioBoxGridNumberingAxis->GetSelection() == 0;
@@ -257,28 +336,51 @@
newGrid->m_secAxisNumType =
(ARRAY_NUMBERING_TYPE_T) m_choiceSecAxisNumbering->GetSelection();
}
+ else
+ {
+ msg = StrPrintf("Invalid primary or secondary axis numbering");
+ goto grid_err;
+ }
// Work out the offsets for the numbering
ok = ok && getNumberingOffset(
m_entryGridPriNumberingOffset->GetValue().ToStdString(),
newGrid->m_priAxisNumType, newGrid->m_numberingOffsetX );
+ if ( !ok )
+ {
+ msg = StrPrintf("Primary axis numbering start not found in the primary axis alphabet");
+ goto grid_err;
+ }
+
if( newGrid->m_2dArrayNumbering )
ok = ok && getNumberingOffset(
m_entryGridSecNumberingOffset->GetValue().ToStdString(),
newGrid->m_secAxisNumType, newGrid->m_numberingOffsetY );
+ if ( !ok )
+ {
+ msg = StrPrintf("Secondary axis numbering start not found in the secondary axis alphabet");
+ goto grid_err;
+ }
+
newGrid->m_shouldRenumber = m_checkBoxGridRestartNumbering->GetValue();
// Only use settings if all values are good
if( ok )
+ {
newSettings = newGrid;
+ }
else
- delete newGrid;
+ {
+ msg = StrPrintf("Failed to generate array");
+ goto grid_err;
+ }
+
}
else if( page == m_circularPanel )
{
- ARRAY_CIRCULAR_OPTIONS* newCirc = new ARRAY_CIRCULAR_OPTIONS();
+ newCirc = new ARRAY_CIRCULAR_OPTIONS();
bool ok = true;
newCirc->m_centre.x = DoubleValueFromString( g_UserUnit, m_entryCentreX->GetValue() );
@@ -287,6 +389,18 @@
newCirc->m_angle = DoubleValueFromString( DEGREES, m_entryCircAngle->GetValue() );
ok = ok && m_entryCircCount->GetValue().ToLong( &newCirc->m_nPts );
+ if ( !ok )
+ {
+ msg = StrPrintf("Invalid count");
+ goto circ_err;
+ }
+
+ if ( newCirc->m_nPts < 0 )
+ {
+ msg = StrPrintf("Count must be positive");
+ goto circ_err;
+ }
+
newCirc->m_rotateItems = m_entryRotateItemsCb->GetValue();
newCirc->m_shouldRenumber = m_checkBoxCircRestartNumbering->GetValue();
@@ -296,16 +410,30 @@
// Mind undefined casts to enums (should not be able to happen)
if( ok )
+ {
newCirc->m_numberingType =
(ARRAY_NUMBERING_TYPE_T) m_choiceCircNumberingType->GetSelection();
+ }
+ else
+ {
+ msg = StrPrintf("Invalid numbering");
+ goto circ_err;
+ }
- ok = ok && m_entryCircNumberingStart->GetValue().ToLong( &newCirc->m_numberingOffset );
+ ok = ok && getNumberingOffset(
+ m_entryCircNumberingStart->GetValue().ToStdString(),
+ newCirc->m_numberingType, newCirc->m_numberingOffset );
// Only use settings if all values are good
if( ok )
+ {
newSettings = newCirc;
+ }
else
- delete newCirc;
+ {
+ msg = StrPrintf("Invalid numbering offset");
+ goto circ_err;
+ }
}
// If we got good settings, send them out and finish
@@ -320,6 +448,17 @@
EndModal( CREATE_ARRAY_OK );
}
+
+ return;
+
+grid_err:
+ wxMessageBox( msg );
+ delete newGrid;
+ return;
+circ_err:
+ wxMessageBox( msg );
+ delete newCirc;
+ return;
}
=== modified file 'pcbnew/dialogs/dialog_create_array.h'
--- pcbnew/dialogs/dialog_create_array.h 2015-04-05 09:52:41 +0000
+++ pcbnew/dialogs/dialog_create_array.h 2015-04-19 06:40:48 +0000
@@ -286,7 +286,7 @@
wxPoint m_centre;
bool m_rotateItems;
ARRAY_NUMBERING_TYPE_T m_numberingType;
- long m_numberingOffset;
+ int m_numberingOffset;
void TransformItem( int n, BOARD_ITEM* item, const wxPoint& rotPoint ) const; // override virtual
int GetArraySize() const; // override virtual
=== modified file 'pcbnew/dialogs/dialog_create_array_base.cpp'
--- pcbnew/dialogs/dialog_create_array_base.cpp 2015-04-05 09:52:41 +0000
+++ pcbnew/dialogs/dialog_create_array_base.cpp 2015-04-19 06:01:51 +0000
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// C++ code generated with wxFormBuilder (version Nov 10 2014)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@@ -310,6 +310,8 @@
m_entryStagger->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_checkBoxGridRestartNumbering->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_radioBoxGridNumberingScheme->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_choicePriAxisNumbering->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_choiceSecAxisNumbering->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCentreX->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCentreY->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCircAngle->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
@@ -331,6 +333,8 @@
m_entryStagger->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_checkBoxGridRestartNumbering->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_radioBoxGridNumberingScheme->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_choicePriAxisNumbering->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_choiceSecAxisNumbering->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCentreX->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCentreY->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCircAngle->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
=== modified file 'pcbnew/dialogs/dialog_create_array_base.fbp'
--- pcbnew/dialogs/dialog_create_array_base.fbp 2015-04-05 09:52:41 +0000
+++ pcbnew/dialogs/dialog_create_array_base.fbp 2015-04-19 06:01:49 +0000
@@ -2569,7 +2569,7 @@
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
- <event name="OnChoice"></event>
+ <event name="OnChoice">OnParameterChanged</event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
@@ -2740,7 +2740,7 @@
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
- <event name="OnChoice"></event>
+ <event name="OnChoice">OnParameterChanged</event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
=== modified file 'pcbnew/dialogs/dialog_create_array_base.h'
--- pcbnew/dialogs/dialog_create_array_base.h 2015-04-05 09:52:41 +0000
+++ pcbnew/dialogs/dialog_create_array_base.h 2015-04-19 05:41:36 +0000
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// C++ code generated with wxFormBuilder (version Nov 10 2014)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!