diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list.cpp b/pcbnew/dialogs/dialog_footprint_wizard_list.cpp
index e2c2a40f62..5e95586637 100644
--- a/pcbnew/dialogs/dialog_footprint_wizard_list.cpp
+++ b/pcbnew/dialogs/dialog_footprint_wizard_list.cpp
@@ -108,7 +108,10 @@ DIALOG_FOOTPRINT_WIZARD_LIST::DIALOG_FOOTPRINT_WIZARD_LIST( wxWindow* aParent )
// Display info about scripts: unloadable scripts (due to syntax errors is python source)
pcbnewGetUnloadableScriptNames( message );
if( message.IsEmpty() )
+ {
m_tcNotLoaded->SetValue( _( "All footprint generator scripts were loaded" ) );
+ m_buttonShowTrace->Show( false );
+ }
else
m_tcNotLoaded->SetValue( message );
@@ -132,7 +135,7 @@ void DIALOG_FOOTPRINT_WIZARD_LIST::OnCellFpGeneratorClick( wxGridEvent& event )
int click_row = event.GetRow();
m_footprintWizard = FOOTPRINT_WIZARDS::GetWizard( click_row );
m_footprintGeneratorsGrid->SelectRow( event.GetRow(), false );
- // Move the grid cursor, mainly for aesthetic reasons:
+ // Move the grid cursor to the active line, mainly for aesthetic reasons:
m_footprintGeneratorsGrid->GoToCell( event.GetRow(), FP_GEN_ROW_NUMBER );
}
@@ -142,6 +145,40 @@ void DIALOG_FOOTPRINT_WIZARD_LIST::OnCellFpGeneratorDoubleClick( wxGridEvent& ev
EndModal( wxID_OK );
}
+void DIALOG_FOOTPRINT_WIZARD_LIST::onShowTrace( wxCommandEvent& event )
+{
+ wxString trace;
+ pcbnewGetWizardsBackTrace( trace );
+
+ // Filter message before displaying them
+ // a trace starts by "Traceback" and is followed by 2 useless lines
+ // for our purpose
+ wxArrayString traces;
+ wxStringSplit( trace, traces, '\n' );
+
+ // Build the filtered message (remove useless lines)
+ trace.Clear();
+
+ for( unsigned ii = 0; ii < traces.Count(); ++ii )
+ {
+ if( traces[ii].Contains( "Traceback" ) )
+ {
+ ii += 2; // Skip this line and next lines which are related to pcbnew.py module
+
+ if( !trace.IsEmpty() ) // Add separator for the next trace block
+ trace << "\n**********************************\n";
+ }
+ else
+ trace += traces[ii] + "\n";
+ }
+
+ // Now display the filtered trace in our dialog
+ // (a simple wxMessageBox is really not suitable for long messages)
+ DIALOG_FOOTPRINT_WIZARD_LOG logWindow( this );
+ logWindow.m_Message->SetValue( trace );
+ logWindow.ShowModal();
+}
+
FOOTPRINT_WIZARD* DIALOG_FOOTPRINT_WIZARD_LIST::GetWizard()
{
diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list.h b/pcbnew/dialogs/dialog_footprint_wizard_list.h
index eccfb78f8a..d8d411f986 100644
--- a/pcbnew/dialogs/dialog_footprint_wizard_list.h
+++ b/pcbnew/dialogs/dialog_footprint_wizard_list.h
@@ -43,6 +43,7 @@ public:
private:
void OnCellFpGeneratorClick( wxGridEvent& event ) override;
void OnCellFpGeneratorDoubleClick( wxGridEvent& event ) override;
+ void onShowTrace( wxCommandEvent& event ) override;
};
#endif // _DIALOG_FOOTPRINT_WIZARD_LIST_H_
diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp b/pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp
index e0f19706b1..efdf3035bc 100644
--- a/pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp
+++ b/pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp
@@ -83,6 +83,9 @@ DIALOG_FOOTPRINT_WIZARD_LIST_BASE::DIALOG_FOOTPRINT_WIZARD_LIST_BASE( wxWindow*
m_bsizerPanelInfo->Add( m_tcNotLoaded, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+ m_buttonShowTrace = new wxButton( m_panelInfo, wxID_ANY, _("Show Trace"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_bsizerPanelInfo->Add( m_buttonShowTrace, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
m_panelInfo->SetSizer( m_bsizerPanelInfo );
m_panelInfo->Layout();
@@ -101,7 +104,7 @@ DIALOG_FOOTPRINT_WIZARD_LIST_BASE::DIALOG_FOOTPRINT_WIZARD_LIST_BASE( wxWindow*
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
- bSizerMain->Add( m_sdbSizer, 0, wxEXPAND|wxALL, 5 );
+ bSizerMain->Add( m_sdbSizer, 0, wxALL|wxALIGN_RIGHT, 5 );
this->SetSizer( bSizerMain );
@@ -112,6 +115,7 @@ DIALOG_FOOTPRINT_WIZARD_LIST_BASE::DIALOG_FOOTPRINT_WIZARD_LIST_BASE( wxWindow*
// Connect Events
m_footprintGeneratorsGrid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::OnCellFpGeneratorClick ), NULL, this );
m_footprintGeneratorsGrid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::OnCellFpGeneratorDoubleClick ), NULL, this );
+ m_buttonShowTrace->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::onShowTrace ), NULL, this );
}
DIALOG_FOOTPRINT_WIZARD_LIST_BASE::~DIALOG_FOOTPRINT_WIZARD_LIST_BASE()
@@ -119,5 +123,34 @@ DIALOG_FOOTPRINT_WIZARD_LIST_BASE::~DIALOG_FOOTPRINT_WIZARD_LIST_BASE()
// Disconnect Events
m_footprintGeneratorsGrid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::OnCellFpGeneratorClick ), NULL, this );
m_footprintGeneratorsGrid->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::OnCellFpGeneratorDoubleClick ), NULL, this );
+ m_buttonShowTrace->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::onShowTrace ), NULL, this );
}
+
+DIALOG_FOOTPRINT_WIZARD_LOG::DIALOG_FOOTPRINT_WIZARD_LOG( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( 600,350 ), wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ m_Message = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY );
+ bSizerMain->Add( m_Message, 1, wxALL|wxEXPAND, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizer->Realize();
+
+ bSizerMain->Add( m_sdbSizer, 0, wxALIGN_RIGHT|wxALL, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_FOOTPRINT_WIZARD_LOG::~DIALOG_FOOTPRINT_WIZARD_LOG()
+{
+}
diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list_base.fbp b/pcbnew/dialogs/dialog_footprint_wizard_list_base.fbp
index 0104a1a5f9..093631e7ff 100644
--- a/pcbnew/dialogs/dialog_footprint_wizard_list_base.fbp
+++ b/pcbnew/dialogs/dialog_footprint_wizard_list_base.fbp
@@ -835,6 +835,94 @@
+
@@ -923,7 +1011,7 @@
5
- wxEXPAND|wxALL
+ wxALL|wxALIGN_RIGHT
0
0
@@ -949,5 +1037,191 @@
+
+ 0
+ wxAUI_MGR_DEFAULT
+
+ wxBOTH
+
+ 1
+ 1
+ impl_virtual
+
+
+
+ 0
+ wxID_ANY
+
+ 600,350
+ DIALOG_FOOTPRINT_WIZARD_LOG
+
+ 646,361
+ wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER
+ DIALOG_SHIM; dialog_shim.h
+ Traceback of errors in not loadable python scripts
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ bSizerMain
+ wxVERTICAL
+ none
+
+ 5
+ wxALL|wxEXPAND
+ 1
+
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+
+ 0
+
+ 0
+
+ 0
+ -1,-1
+ 1
+ m_Message
+ 1
+
+
+ public
+ 1
+
+ Resizable
+ 1
+
+ wxTE_MULTILINE|wxTE_READONLY
+
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5
+ wxALIGN_RIGHT|wxALL
+ 0
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+
+ m_sdbSizer
+ protected
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list_base.h b/pcbnew/dialogs/dialog_footprint_wizard_list_base.h
index 791c7d4e63..0ec920b42e 100644
--- a/pcbnew/dialogs/dialog_footprint_wizard_list_base.h
+++ b/pcbnew/dialogs/dialog_footprint_wizard_list_base.h
@@ -27,9 +27,9 @@ class DIALOG_SHIM;
#include
#include
#include
+#include
#include
#include
-#include
#include
///////////////////////////////////////////////////////////////////////////
@@ -51,6 +51,7 @@ class DIALOG_FOOTPRINT_WIZARD_LIST_BASE : public DIALOG_SHIM
wxTextCtrl* m_tcSearchPaths;
wxStaticText* m_staticText11;
wxTextCtrl* m_tcNotLoaded;
+ wxButton* m_buttonShowTrace;
wxStaticLine* m_staticline;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
@@ -59,6 +60,7 @@ class DIALOG_FOOTPRINT_WIZARD_LIST_BASE : public DIALOG_SHIM
// Virtual event handlers, overide them in your derived class
virtual void OnCellFpGeneratorClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnCellFpGeneratorDoubleClick( wxGridEvent& event ) { event.Skip(); }
+ virtual void onShowTrace( wxCommandEvent& event ) { event.Skip(); }
public:
@@ -68,4 +70,23 @@ class DIALOG_FOOTPRINT_WIZARD_LIST_BASE : public DIALOG_SHIM
};
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_FOOTPRINT_WIZARD_LOG
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_FOOTPRINT_WIZARD_LOG : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+
+ public:
+ wxTextCtrl* m_Message;
+
+ DIALOG_FOOTPRINT_WIZARD_LOG( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Traceback of errors in not loadable python scripts"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 646,361 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_FOOTPRINT_WIZARD_LOG();
+
+};
+
#endif //__DIALOG_FOOTPRINT_WIZARD_LIST_BASE_H__
diff --git a/pcbnew/swig/python_scripting.cpp b/pcbnew/swig/python_scripting.cpp
index 3c574266c9..2bc4e7779d 100644
--- a/pcbnew/swig/python_scripting.cpp
+++ b/pcbnew/swig/python_scripting.cpp
@@ -258,6 +258,11 @@ void pcbnewGetScriptsSearchPaths( wxString& aNames )
pcbnewRunPythonMethodWithReturnedString( "pcbnew.GetWizardsSearchPaths", aNames );
}
+void pcbnewGetWizardsBackTrace( wxString& aNames )
+{
+ pcbnewRunPythonMethodWithReturnedString( "pcbnew.GetWizardsBackTrace", aNames );
+}
+
void pcbnewFinishPythonScripting()
{
diff --git a/pcbnew/swig/python_scripting.h b/pcbnew/swig/python_scripting.h
index 42fbf57e92..861d166855 100644
--- a/pcbnew/swig/python_scripting.h
+++ b/pcbnew/swig/python_scripting.h
@@ -64,6 +64,14 @@ void pcbnewGetUnloadableScriptNames( wxString& aNames );
* @param aNames is a wxString which will contain the paths (separated by '\n')
*/
void pcbnewGetScriptsSearchPaths( wxString& aNames );
+
+/**
+ * Function pcbnewGetWizardsBackTrace
+ * returns the backtrace of errors (if any) when wizard python scripts are loaded
+ * @param aNames is a wxString which will contain the trace
+ */
+void pcbnewGetWizardsBackTrace( wxString& aNames );
+
#ifdef KICAD_SCRIPTING_WXPYTHON
void RedirectStdio();
diff --git a/scripting/kicadplugins.i b/scripting/kicadplugins.i
index 5380f543f1..324f92550c 100644
--- a/scripting/kicadplugins.i
+++ b/scripting/kicadplugins.i
@@ -65,16 +65,21 @@ NOT_LOADED_WIZARDS=""
"""
PLUGIN_DIRECTORIES_SEARCH=""
+""" the trace of errors during execution of footprint wizards scripts
+"""
+FULL_BACK_TRACE=""
def GetUnLoadableWizards():
global NOT_LOADED_WIZARDS
return NOT_LOADED_WIZARDS
-
def GetWizardsSearchPaths():
global PLUGIN_DIRECTORIES_SEARCH
return PLUGIN_DIRECTORIES_SEARCH
+def GetWizardsBackTrace():
+ global FULL_BACK_TRACE
+ return FULL_BACK_TRACE
def ReloadPlugin(name):
if not KICAD_PLUGINS.has_key(name):
@@ -132,6 +137,7 @@ def LoadPlugins(bundlepath=None):
"""
import os
import sys
+ import traceback
import pcbnew
kicad_path = os.environ.get('KICAD_PATH')
@@ -162,6 +168,8 @@ def LoadPlugins(bundlepath=None):
PLUGIN_DIRECTORIES_SEARCH += "\n"
PLUGIN_DIRECTORIES_SEARCH += plugins_dir
+ global FULL_BACK_TRACE
+ FULL_BACK_TRACE=""
failed_wizards_list=""
for plugins_dir in plugin_directories:
@@ -191,6 +199,7 @@ def LoadPlugins(bundlepath=None):
if failed_wizards_list != "" :
failed_wizards_list += "\n"
failed_wizards_list += module_filename
+ FULL_BACK_TRACE += traceback.format_exc(sys.exc_info())
pass
global NOT_LOADED_WIZARDS