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() FOOTPRINT_WIZARD* FOOTPRINT_WIZARD_FRAME::GetMyWizard()
{ {
if( m_wizardName.Length()==0 ) if( m_wizardName.Length() == 0 )
return NULL; return NULL;
FOOTPRINT_WIZARD* footprintWizard = FOOTPRINT_WIZARDS::GetWizard( m_wizardName ); 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 ) void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxGridEvent& event )
{ {
int page = m_pageList->GetSelection(); int page = m_pageList->GetSelection();
@ -195,21 +191,29 @@ void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxGridEvent& event )
if( !footprintWizard ) if( !footprintWizard )
return; return;
if( page<0 ) if( page < 0 )
return; return;
int n = m_parameterGrid->GetNumberRows(); wxArrayString prmValues = footprintWizard->GetParameterValues( page );
wxArrayString arr;
wxArrayString ptList = footprintWizard->GetParameterTypes( 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 // if this parameter is expected to be an internal
// unit convert it back from the user format // 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; LOCALE_IO toggle;
double dValue; double dValue;
@ -220,18 +224,34 @@ void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxGridEvent& event )
dValue = dValue / 1000.0; dValue = dValue / 1000.0;
dValue = From_User_Unit( g_UserUnit, dValue ); 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 if( prmValues[prm_id] != value )
// to be scripting compatible {
arr.Add( value ); has_changed = true;
prmValues[prm_id] = value;
}
} }
wxString res = footprintWizard->SetParameterValues( page, arr ); if( has_changed )
{
wxString res = footprintWizard->SetParameterValues( page, prmValues );
ReloadFootprint(); if( !res.IsEmpty() )
DisplayWizardInfos(); wxMessageBox( res );
ReloadFootprint();
DisplayWizardInfos();
}
} }

View File

@ -75,22 +75,16 @@ BEGIN_EVENT_TABLE( FOOTPRINT_WIZARD_FRAME, EDA_DRAW_FRAME )
// listbox events // listbox events
EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PAGE_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnPageList ) 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, EVT_GRID_CMD_CELL_CHANGED( ID_FOOTPRINT_WIZARD_PARAMETER_LIST,
FOOTPRINT_WIZARD_FRAME::ParametersUpdated ) 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 ) EVT_MENU( ID_SET_RELATIVE_OFFSET, FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset )
END_EVENT_TABLE() 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" ) #define FOOTPRINT_WIZARD_FRAME_NAME wxT( "FootprintWizard" )
@ -131,6 +125,14 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway,
LoadSettings( config() ); LoadSettings( config() );
SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y ); 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 ); GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
ReCreateHToolbar(); ReCreateHToolbar();
@ -147,9 +149,9 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway,
m_parameterGrid->CreateGrid( 1, 3 ); m_parameterGrid->CreateGrid( 1, 3 );
// Columns // Columns
m_parameterGrid->SetColLabelValue( 0, _( "Parameter" ) ); m_parameterGrid->SetColLabelValue( m_columnPrmName, _( "Parameter" ) );
m_parameterGrid->SetColLabelValue( 1, _( "Value" ) ); m_parameterGrid->SetColLabelValue( m_columnPrmValue, _( "Value" ) );
m_parameterGrid->SetColLabelValue( 2, _( "Units" ) ); m_parameterGrid->SetColLabelValue( m_columnPrmUnit, _( "Units" ) );
m_parameterGrid->SetColLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTRE ); m_parameterGrid->SetColLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTRE );
m_parameterGrid->AutoSizeColumns(); m_parameterGrid->AutoSizeColumns();
@ -319,14 +321,13 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList()
m_parameterGrid->DeleteRows( 0, m_parameterGrid->GetNumberRows() ); m_parameterGrid->DeleteRows( 0, m_parameterGrid->GetNumberRows() );
m_parameterGrid->AppendRows( fpList.size() ); m_parameterGrid->AppendRows( fpList.size() );
wxString name, value, units; wxString value, units;
for( unsigned int i = 0; i<fpList.size(); i++ ) for( unsigned int i = 0; i< fpList.size(); i++ )
{ {
name = fpList[i];
value = fvList[i]; value = fvList[i];
m_parameterGrid->SetCellValue( i, 0, name ); m_parameterGrid->SetCellValue( i, m_columnPrmName, fpList[i] );
m_parameterGrid->SetReadOnly( i, 0 ); m_parameterGrid->SetReadOnly( i, m_columnPrmName );
if( ptList[i]==wxT( "IU" ) ) if( ptList[i]==wxT( "IU" ) )
{ {
@ -350,6 +351,8 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList()
units = wxT( "mm" ); 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 ); std::string s = Double2Str( dValue );
value = FROM_UTF8( s.c_str() ); value = FROM_UTF8( s.c_str() );
} }
@ -358,9 +361,9 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList()
units = wxT( "" ); units = wxT( "" );
} }
m_parameterGrid->SetCellValue( i, 1, value ); m_parameterGrid->SetCellValue( i, m_columnPrmValue, value );
m_parameterGrid->SetCellValue( i, 2, units ); m_parameterGrid->SetCellValue( i, m_columnPrmUnit, units );
m_parameterGrid->SetReadOnly( i, 2 ); m_parameterGrid->SetReadOnly( i, m_columnPrmUnit );
} }
m_parameterGrid->AutoSizeColumns(); m_parameterGrid->AutoSizeColumns();
@ -596,14 +599,11 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateHToolbar()
m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString,
KiBitmap( zoom_fit_in_page_xpm ), msg ); KiBitmap( zoom_fit_in_page_xpm ), msg );
if( IsModal() ) // The footprint wizard always can export the current footprint
{ m_mainToolBar->AddSeparator();
// The library browser is called from a "load component" command m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_DONE,
m_mainToolBar->AddSeparator(); wxEmptyString, KiBitmap( export_footprint_names_xpm ),
m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_DONE, _( "Export the footprint to the editor" ) );
wxEmptyString, KiBitmap( export_footprint_names_xpm ),
_( "Add footprint to board" ) );
}
// after adding the buttons to the toolbar, must call Realize() to // after adding the buttons to the toolbar, must call Realize() to
// reflect the changes // reflect the changes
@ -616,4 +616,5 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateHToolbar()
void FOOTPRINT_WIZARD_FRAME::ReCreateVToolbar() void FOOTPRINT_WIZARD_FRAME::ReCreateVToolbar()
{ {
// Currently, there is no vertical toolbar
} }

View File

@ -54,6 +54,11 @@ private:
// Flags // Flags
wxString m_configPath; ///< subpath for configuration 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: protected:
wxString m_wizardName; ///< name of the current wizard wxString m_wizardName; ///< name of the current wizard
wxString m_wizardDescription; ///< description of the wizard wxString m_wizardDescription; ///< description of the wizard
@ -151,9 +156,12 @@ private:
void SelectCurrentWizard( wxCommandEvent& event ); void SelectCurrentWizard( wxCommandEvent& event );
/**
* Function ParametersUpdated
* Update the footprint python parameters values from the values in grid
*/
void ParametersUpdated( wxGridEvent& event ); void ParametersUpdated( wxGridEvent& event );
bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ); 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( PyErr_Occurred() )
{ {
#if 1 // defined(DEBUG)
wxMessageBox( PyErrStringWithTraceback(), wxMessageBox( PyErrStringWithTraceback(),
wxT( "Exception on python footprint wizard code" ), wxT( "Exception on python footprint wizard code" ),
wxICON_ERROR | wxOK ); wxICON_ERROR | wxOK );
#endif
} }
if( result ) if( result )
@ -213,7 +215,7 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterNames( int aPage )
ret = CallRetArrayStrMethod( "GetParameterNames", arglist ); ret = CallRetArrayStrMethod( "GetParameterNames", arglist );
Py_DECREF( arglist ); Py_DECREF( arglist );
for( unsigned i = 0; i<ret.GetCount(); i++ ) for( unsigned i = 0; i < ret.GetCount(); i++ )
{ {
wxString rest; wxString rest;
wxString item = ret[i]; wxString item = ret[i];
@ -262,7 +264,6 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterValues( int aPage )
PyLOCK lock; PyLOCK lock;
PyObject* arglist = Py_BuildValue( "(i)", aPage ); PyObject* arglist = Py_BuildValue( "(i)", aPage );
wxArrayString ret = CallRetArrayStrMethod( "GetParameterValues", arglist ); wxArrayString ret = CallRetArrayStrMethod( "GetParameterValues", arglist );
Py_DECREF( arglist ); Py_DECREF( arglist );
@ -276,7 +277,6 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterErrors( int aPage )
PyLOCK lock; PyLOCK lock;
PyObject* arglist = Py_BuildValue( "(i)", aPage ); PyObject* arglist = Py_BuildValue( "(i)", aPage );
wxArrayString ret = CallRetArrayStrMethod( "GetParameterErrors", arglist ); wxArrayString ret = CallRetArrayStrMethod( "GetParameterErrors", arglist );
Py_DECREF( arglist ); Py_DECREF( arglist );
@ -293,9 +293,9 @@ wxString PYTHON_FOOTPRINT_WIZARD::SetParameterValues( int aPage, wxArrayString&
PyObject* py_list = PyList_New( len ); 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() ); PyObject* py_str = PyString_FromString( (const char*) str.mb_str() );
PyList_SetItem( py_list, i, py_str ); PyList_SetItem( py_list, i, py_str );
} }

View File

@ -54,7 +54,8 @@ public:
wxArrayString GetParameterTypes( int aPage ); wxArrayString GetParameterTypes( int aPage );
wxArrayString GetParameterValues( int aPage ); wxArrayString GetParameterValues( int aPage );
wxArrayString GetParameterErrors( 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(); MODULE* GetModule();
void* GetObject(); void* GetObject();
}; };

View File

@ -147,10 +147,18 @@ class FootprintWizardParameterManager:
self._PrintParameterErrors() self._PrintParameterErrors()
return False 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:" print ("Building new %s footprint with the following parameters:"
% self.name) % self.name)
self._PrintParameterTable() self._PrintParameterTable()
"""
return True return True
################################################################# #################################################################

View File

@ -38,6 +38,17 @@
* available in the system * 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 %pythoncode
{ {
@ -62,7 +73,7 @@ def ReloadPlugins():
now_mtime = os.path.getmtime(filename) now_mtime = os.path.getmtime(filename)
if mtime!=now_mtime: if mtime!=now_mtime:
print filename, " is modified, reloading" # /* print filename, " is modified, reloading" */
KICAD_PLUGINS[k]["modification_time"]=now_mtime KICAD_PLUGINS[k]["modification_time"]=now_mtime
ReloadPlugin(k) ReloadPlugin(k)
@ -214,7 +225,6 @@ class FootprintWizardPlugin(KiCadPlugin):
for key in keys: for key in keys:
val = self.TryConvertToFloat(values[n]) val = self.TryConvertToFloat(values[n])
self.parameters[name][key] = val self.parameters[name][key] = val
print "[%s][%s]<="%(name,key),val
n+=1 n+=1