Footprint wizard: Fix IO exception error in python scripts which happens sometimes, due to the fact these scripts printed messages to a console, but when Pcbnew is not run from a console, there is no IO channel to read these messages.

The fix is not perfect (still no IO channel to read these messages) ,  but it works better.
Also, fix erroneous comments in code, and cleanup code.
This commit is contained in:
jean-pierre charras 2015-09-02 15:55:36 +02:00
parent 387054d83f
commit 4a56ee42c5
7 changed files with 104 additions and 56 deletions

View File

@ -120,7 +120,7 @@ void FOOTPRINT_WIZARD_FRAME::ReloadFootprint()
FOOTPRINT_WIZARD* FOOTPRINT_WIZARD_FRAME::GetMyWizard()
{
if( m_wizardName.Length()==0 )
if( m_wizardName.Length() == 0 )
return NULL;
FOOTPRINT_WIZARD* footprintWizard = FOOTPRINT_WIZARDS::GetWizard( m_wizardName );
@ -182,10 +182,6 @@ void FOOTPRINT_WIZARD_FRAME::SelectCurrentWizard( wxCommandEvent& event )
}
/**
* Function SelectCurrentFootprint
* Selects the current footprint name and display it
*/
void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxGridEvent& event )
{
int page = m_pageList->GetSelection();
@ -195,21 +191,29 @@ void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxGridEvent& event )
if( !footprintWizard )
return;
if( page<0 )
if( page < 0 )
return;
int n = m_parameterGrid->GetNumberRows();
wxArrayString arr;
wxArrayString prmValues = footprintWizard->GetParameterValues( page );
wxArrayString ptList = footprintWizard->GetParameterTypes( page );
for( int i = 0; i < n; i++ )
bool has_changed = false;
int count = m_parameterGrid->GetNumberRows();
// Skip extra event, useless
if( event.GetString() == m_parameterGrid->GetCellValue( event.GetRow(), m_columnPrmValue ) )
return;
for( int prm_id = 0; prm_id < count; ++prm_id )
{
wxString value = m_parameterGrid->GetCellValue( i, 1 );
wxString value = m_parameterGrid->GetCellValue( prm_id, m_columnPrmValue );
// if this parameter is expected to be an internal
// unit convert it back from the user format
if( ptList[i]==wxT( "IU" ) )
if( ptList[prm_id]==wxT( "IU" ) )
{
// If our locale is set to use, for decimal point, just change it
// to be scripting compatible
LOCALE_IO toggle;
double dValue;
@ -220,18 +224,34 @@ void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxGridEvent& event )
dValue = dValue / 1000.0;
dValue = From_User_Unit( g_UserUnit, dValue );
value.Printf( wxT( "%f" ), dValue );
// Internal units are int. Print them as int.
value.Printf( "%d", KiROUND( dValue ) );
if( prmValues[prm_id].EndsWith(".0") )
{
prmValues[prm_id].RemoveLast();
prmValues[prm_id].RemoveLast();
}
}
// If our locale is set to use , for decimal point, just change it
// to be scripting compatible
arr.Add( value );
if( prmValues[prm_id] != value )
{
has_changed = true;
prmValues[prm_id] = value;
}
}
wxString res = footprintWizard->SetParameterValues( page, arr );
if( has_changed )
{
wxString res = footprintWizard->SetParameterValues( page, prmValues );
if( !res.IsEmpty() )
wxMessageBox( res );
ReloadFootprint();
DisplayWizardInfos();
}
}

View File

@ -75,22 +75,16 @@ BEGIN_EVENT_TABLE( FOOTPRINT_WIZARD_FRAME, EDA_DRAW_FRAME )
// listbox events
EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PAGE_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnPageList )
#if wxCHECK_VERSION( 3, 0, 0 )
EVT_GRID_CMD_CELL_CHANGED( ID_FOOTPRINT_WIZARD_PARAMETER_LIST,
FOOTPRINT_WIZARD_FRAME::ParametersUpdated )
#else
EVT_GRID_CMD_CELL_CHANGE( ID_FOOTPRINT_WIZARD_PARAMETER_LIST,
FOOTPRINT_WIZARD_FRAME::ParametersUpdated )
#endif
EVT_GRID_CMD_EDITOR_HIDDEN( ID_FOOTPRINT_WIZARD_PARAMETER_LIST,
FOOTPRINT_WIZARD_FRAME::ParametersUpdated )
EVT_MENU( ID_SET_RELATIVE_OFFSET, FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset )
END_EVENT_TABLE()
// Column index to display parameters in m_parameterGrid
int FOOTPRINT_WIZARD_FRAME::m_columnPrmName = 0;
int FOOTPRINT_WIZARD_FRAME::m_columnPrmValue = 1;
int FOOTPRINT_WIZARD_FRAME::m_columnPrmUnit = 2;
#define FOOTPRINT_WIZARD_FRAME_NAME wxT( "FootprintWizard" )
@ -131,6 +125,14 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway,
LoadSettings( config() );
SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
// Set some display options here, because the FOOTPRINT_WIZARD_FRAME
// does not have a config menu to do that:
DISPLAY_OPTIONS* disp_opts = (DISPLAY_OPTIONS*) GetDisplayOptions();
disp_opts->m_DisplayPadIsol = false;
disp_opts->m_DisplayPadNum = true;
GetBoard()->SetElementVisibility( PCB_VISIBLE(NO_CONNECTS_VISIBLE), false );
GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
ReCreateHToolbar();
@ -147,9 +149,9 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway,
m_parameterGrid->CreateGrid( 1, 3 );
// Columns
m_parameterGrid->SetColLabelValue( 0, _( "Parameter" ) );
m_parameterGrid->SetColLabelValue( 1, _( "Value" ) );
m_parameterGrid->SetColLabelValue( 2, _( "Units" ) );
m_parameterGrid->SetColLabelValue( m_columnPrmName, _( "Parameter" ) );
m_parameterGrid->SetColLabelValue( m_columnPrmValue, _( "Value" ) );
m_parameterGrid->SetColLabelValue( m_columnPrmUnit, _( "Units" ) );
m_parameterGrid->SetColLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTRE );
m_parameterGrid->AutoSizeColumns();
@ -319,14 +321,13 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList()
m_parameterGrid->DeleteRows( 0, m_parameterGrid->GetNumberRows() );
m_parameterGrid->AppendRows( fpList.size() );
wxString name, value, units;
for( unsigned int i = 0; i<fpList.size(); i++ )
wxString value, units;
for( unsigned int i = 0; i< fpList.size(); i++ )
{
name = fpList[i];
value = fvList[i];
m_parameterGrid->SetCellValue( i, 0, name );
m_parameterGrid->SetReadOnly( i, 0 );
m_parameterGrid->SetCellValue( i, m_columnPrmName, fpList[i] );
m_parameterGrid->SetReadOnly( i, m_columnPrmName );
if( ptList[i]==wxT( "IU" ) )
{
@ -350,6 +351,8 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList()
units = wxT( "mm" );
}
// Use Double2Str to build the string, because useless trailing 0
// are removed. The %f format does not remove them
std::string s = Double2Str( dValue );
value = FROM_UTF8( s.c_str() );
}
@ -358,9 +361,9 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList()
units = wxT( "" );
}
m_parameterGrid->SetCellValue( i, 1, value );
m_parameterGrid->SetCellValue( i, 2, units );
m_parameterGrid->SetReadOnly( i, 2 );
m_parameterGrid->SetCellValue( i, m_columnPrmValue, value );
m_parameterGrid->SetCellValue( i, m_columnPrmUnit, units );
m_parameterGrid->SetReadOnly( i, m_columnPrmUnit );
}
m_parameterGrid->AutoSizeColumns();
@ -596,14 +599,11 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateHToolbar()
m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString,
KiBitmap( zoom_fit_in_page_xpm ), msg );
if( IsModal() )
{
// The library browser is called from a "load component" command
// The footprint wizard always can export the current footprint
m_mainToolBar->AddSeparator();
m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_DONE,
wxEmptyString, KiBitmap( export_footprint_names_xpm ),
_( "Add footprint to board" ) );
}
_( "Export the footprint to the editor" ) );
// after adding the buttons to the toolbar, must call Realize() to
// reflect the changes
@ -616,4 +616,5 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateHToolbar()
void FOOTPRINT_WIZARD_FRAME::ReCreateVToolbar()
{
// Currently, there is no vertical toolbar
}

View File

@ -54,6 +54,11 @@ private:
// Flags
wxString m_configPath; ///< subpath for configuration
// Column index to display parameters in m_parameterGrid
static int m_columnPrmName;
static int m_columnPrmValue;
static int m_columnPrmUnit;
protected:
wxString m_wizardName; ///< name of the current wizard
wxString m_wizardDescription; ///< description of the wizard
@ -151,9 +156,12 @@ private:
void SelectCurrentWizard( wxCommandEvent& event );
/**
* Function ParametersUpdated
* Update the footprint python parameters values from the values in grid
*/
void ParametersUpdated( wxGridEvent& event );
bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
/**

View File

@ -64,9 +64,11 @@ PyObject* PYTHON_FOOTPRINT_WIZARD::CallMethod( const char* aMethod, PyObject* aA
if( PyErr_Occurred() )
{
#if 1 // defined(DEBUG)
wxMessageBox( PyErrStringWithTraceback(),
wxT( "Exception on python footprint wizard code" ),
wxICON_ERROR | wxOK );
#endif
}
if( result )
@ -213,7 +215,7 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterNames( int aPage )
ret = CallRetArrayStrMethod( "GetParameterNames", arglist );
Py_DECREF( arglist );
for( unsigned i = 0; i<ret.GetCount(); i++ )
for( unsigned i = 0; i < ret.GetCount(); i++ )
{
wxString rest;
wxString item = ret[i];
@ -262,7 +264,6 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterValues( int aPage )
PyLOCK lock;
PyObject* arglist = Py_BuildValue( "(i)", aPage );
wxArrayString ret = CallRetArrayStrMethod( "GetParameterValues", arglist );
Py_DECREF( arglist );
@ -276,7 +277,6 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterErrors( int aPage )
PyLOCK lock;
PyObject* arglist = Py_BuildValue( "(i)", aPage );
wxArrayString ret = CallRetArrayStrMethod( "GetParameterErrors", arglist );
Py_DECREF( arglist );
@ -293,9 +293,9 @@ wxString PYTHON_FOOTPRINT_WIZARD::SetParameterValues( int aPage, wxArrayString&
PyObject* py_list = PyList_New( len );
for( int i = 0; i<len; i++ )
for( int i = 0; i < len; i++ )
{
wxString str = aValues[i];
wxString& str = aValues[i];
PyObject* py_str = PyString_FromString( (const char*) str.mb_str() );
PyList_SetItem( py_list, i, py_str );
}

View File

@ -54,7 +54,8 @@ public:
wxArrayString GetParameterTypes( int aPage );
wxArrayString GetParameterValues( int aPage );
wxArrayString GetParameterErrors( int aPage );
wxString SetParameterValues( int aPage, wxArrayString& aValues ); // < must return "OK" or error description
// must return an empty string or an error description
wxString SetParameterValues( int aPage, wxArrayString& aValues );
MODULE* GetModule();
void* GetObject();
};

View File

@ -147,10 +147,18 @@ class FootprintWizardParameterManager:
self._PrintParameterErrors()
return False
"""
Be aware print messages create IO exceptions, because the wizard
is run from Pcbnew. And if pcbnew is not run from a console, there is
no io channel to read the output of print function.
When the buffer is full, a IO exception is thrown.
"""
"""
print ("Building new %s footprint with the following parameters:"
% self.name)
self._PrintParameterTable()
"""
return True
#################################################################

View File

@ -38,6 +38,17 @@
* available in the system
*
*/
/*
* Remark:
* Avoid using the print function in python wizards
*
* Be aware print messages create IO exceptions, because the wizard
* is run from Pcbnew. And if pcbnew is not run from a console, there is
* no io channel to read the output of print function.
* When the io buffer is full, a IO exception is thrown.
*/
%pythoncode
{
@ -62,7 +73,7 @@ def ReloadPlugins():
now_mtime = os.path.getmtime(filename)
if mtime!=now_mtime:
print filename, " is modified, reloading"
# /* print filename, " is modified, reloading" */
KICAD_PLUGINS[k]["modification_time"]=now_mtime
ReloadPlugin(k)
@ -214,7 +225,6 @@ class FootprintWizardPlugin(KiCadPlugin):
for key in keys:
val = self.TryConvertToFloat(values[n])
self.parameters[name][key] = val
print "[%s][%s]<="%(name,key),val
n+=1