From 4f46f79cf0d601ec18fe685a414e8a778a9c143b Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 9 Jan 2017 14:44:07 +0100 Subject: [PATCH] dialog_footprint_wizard_list.cpp: allows updating (on request) python modules from this dialog. This option reloads modules which are more recent than already loaded modules, and load new modules. --- pcbnew/class_footprint_wizard.cpp | 26 ++- pcbnew/class_footprint_wizard.h | 4 +- .../dialogs/dialog_footprint_wizard_list.cpp | 69 +++++--- pcbnew/dialogs/dialog_footprint_wizard_list.h | 2 + .../dialog_footprint_wizard_list_base.cpp | 21 ++- .../dialog_footprint_wizard_list_base.fbp | 159 +++++++++++++++--- .../dialog_footprint_wizard_list_base.h | 4 +- pcbnew/swig/python_scripting.cpp | 1 - scripting/kicadplugins.i | 59 +++---- 9 files changed, 260 insertions(+), 85 deletions(-) diff --git a/pcbnew/class_footprint_wizard.cpp b/pcbnew/class_footprint_wizard.cpp index 2d503c2a8b..5c5c8b59cc 100644 --- a/pcbnew/class_footprint_wizard.cpp +++ b/pcbnew/class_footprint_wizard.cpp @@ -76,6 +76,26 @@ int FOOTPRINT_WIZARDS::GetWizardsCount() void FOOTPRINT_WIZARDS::register_wizard( FOOTPRINT_WIZARD* aWizard ) { + // Search for this entry do not register twice this wizard): + for( int ii = 0; ii < GetWizardsCount(); ii++ ) + { + if( aWizard == GetWizard( ii ) ) // Already registered + return; + } + + // Search for a wizard with the same name, and remove it if found + for( int ii = 0; ii < GetWizardsCount(); ii++ ) + { + FOOTPRINT_WIZARD* wizard = GetWizard( ii ); + + if( wizard->GetName() == aWizard->GetName() ) + { + m_FootprintWizards.erase( m_FootprintWizards.begin() + ii ); + delete wizard; + break; + } + } + m_FootprintWizards.push_back( aWizard ); } @@ -84,13 +104,13 @@ bool FOOTPRINT_WIZARDS::deregister_object( void* aObject ) { int max = GetWizardsCount(); - for( int i = 0; iGetObject() == aObject ) { - m_FootprintWizards.erase( m_FootprintWizards.begin() + i ); + m_FootprintWizards.erase( m_FootprintWizards.begin() + ii ); delete wizard; return true; } diff --git a/pcbnew/class_footprint_wizard.h b/pcbnew/class_footprint_wizard.h index 2ffc65811d..f621ab564b 100644 --- a/pcbnew/class_footprint_wizard.h +++ b/pcbnew/class_footprint_wizard.h @@ -182,7 +182,9 @@ public: * Function register_wizard * A footprint wizard calls this static method when it wants to register itself * into the system wizards - * + * Note: if it is already registered, this function do nothing + * if n existing wizard with the same name exists, this existing wizard will be + * unregistered. * @param aWizard is the footprint wizard to be registered */ static void register_wizard( FOOTPRINT_WIZARD* aWizard ); diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list.cpp b/pcbnew/dialogs/dialog_footprint_wizard_list.cpp index 16716e00c6..00a642eec2 100644 --- a/pcbnew/dialogs/dialog_footprint_wizard_list.cpp +++ b/pcbnew/dialogs/dialog_footprint_wizard_list.cpp @@ -56,19 +56,52 @@ enum FPGeneratorRowNames DIALOG_FOOTPRINT_WIZARD_LIST::DIALOG_FOOTPRINT_WIZARD_LIST( wxWindow* aParent ) : DIALOG_FOOTPRINT_WIZARD_LIST_BASE( aParent ) { - int n_wizards = FOOTPRINT_WIZARDS::GetWizardsCount(); m_config = Kiface().KifaceSettings(); + initLists(); + if( m_config ) + { + wxSize size; + m_config->Read( FPWIZARTDLIST_WIDTH_KEY, &size.x, -1 ); + m_config->Read( FPWIZARTDLIST_HEIGHT_KEY, &size.y, -1 ); + SetSize( size ); + } + + + m_sdbSizerOK->SetDefault(); + FinishDialogSettings(); + + Center(); +} + + +DIALOG_FOOTPRINT_WIZARD_LIST::~DIALOG_FOOTPRINT_WIZARD_LIST() +{ + if( m_config && !IsIconized() ) + { + m_config->Write( FPWIZARTDLIST_WIDTH_KEY, GetSize().x ); + m_config->Write( FPWIZARTDLIST_HEIGHT_KEY, GetSize().y ); + } +} + + +void DIALOG_FOOTPRINT_WIZARD_LIST::initLists() +{ // Current wizard selection, empty or first m_footprintWizard = NULL; + int n_wizards = FOOTPRINT_WIZARDS::GetWizardsCount(); + if( n_wizards ) m_footprintWizard = FOOTPRINT_WIZARDS::GetWizard( 0 ); // Choose selection mode and insert the needed rows m_footprintGeneratorsGrid->SetSelectionMode( wxGrid::wxGridSelectRows ); - m_footprintGeneratorsGrid->InsertRows( 0, n_wizards, true ); + + int curr_row_cnt = m_footprintGeneratorsGrid->GetNumberRows(); + m_footprintGeneratorsGrid->DeleteRows( 0, curr_row_cnt ); + m_footprintGeneratorsGrid->InsertRows( 0, n_wizards ); // Put all wizards in the list for( int ii = 0; ii < n_wizards; ii++ ) @@ -99,15 +132,6 @@ DIALOG_FOOTPRINT_WIZARD_LIST::DIALOG_FOOTPRINT_WIZARD_LIST( wxWindow* aParent ) m_footprintGeneratorsGrid->ClearSelection(); m_footprintGeneratorsGrid->SelectRow( 0, false ); - if( m_config ) - { - wxSize size; - m_config->Read( FPWIZARTDLIST_WIDTH_KEY, &size.x, -1 ); - m_config->Read( FPWIZARTDLIST_HEIGHT_KEY, &size.y, -1 ); - SetSize( size ); - } - - // Display info about scripts: Search paths wxString message; pcbnewGetScriptsSearchPaths( message ); @@ -121,23 +145,22 @@ DIALOG_FOOTPRINT_WIZARD_LIST::DIALOG_FOOTPRINT_WIZARD_LIST( wxWindow* aParent ) } else m_tcNotLoaded->SetValue( message ); - - m_sdbSizerOK->SetDefault(); - FinishDialogSettings(); - - Center(); } -DIALOG_FOOTPRINT_WIZARD_LIST::~DIALOG_FOOTPRINT_WIZARD_LIST() +void DIALOG_FOOTPRINT_WIZARD_LIST::onUpdatePythonModulesClick( wxCommandEvent& event ) { - if( m_config && !IsIconized() ) - { - m_config->Write( FPWIZARTDLIST_WIDTH_KEY, GetSize().x ); - m_config->Write( FPWIZARTDLIST_HEIGHT_KEY, GetSize().y ); - } -} +#if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON) + char cmd[1024]; + snprintf( cmd, sizeof(cmd), + "pcbnew.LoadPlugins(\"%s\")", TO_UTF8( PyScriptingPath() ) ); + PyLOCK lock; + // ReRun the Python method pcbnew.LoadPlugins (already called when starting Pcbnew) + PyRun_SimpleString( cmd ); + initLists(); +#endif +} void DIALOG_FOOTPRINT_WIZARD_LIST::OnCellFpGeneratorClick( wxGridEvent& event ) diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list.h b/pcbnew/dialogs/dialog_footprint_wizard_list.h index 1566fd84f5..7c02a9e105 100644 --- a/pcbnew/dialogs/dialog_footprint_wizard_list.h +++ b/pcbnew/dialogs/dialog_footprint_wizard_list.h @@ -41,9 +41,11 @@ public: FOOTPRINT_WIZARD* GetWizard(); private: + void initLists(); void OnCellFpGeneratorClick( wxGridEvent& event ) override; void OnCellFpGeneratorDoubleClick( wxGridEvent& event ) override; void onShowTrace( wxCommandEvent& event ) override; + void onUpdatePythonModulesClick( 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 e616e4133c..d91908dcc5 100644 --- a/pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp +++ b/pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Dec 4 2016) +// C++ code generated with wxFormBuilder (version May 6 2016) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -92,6 +92,18 @@ DIALOG_FOOTPRINT_WIZARD_LIST_BASE::DIALOG_FOOTPRINT_WIZARD_LIST_BASE( wxWindow* bSizerMain->Add( m_notebook, 1, wxEXPAND | wxALL, 5 ); + wxBoxSizer* bSizerLower; + bSizerLower = new wxBoxSizer( wxHORIZONTAL ); + + + bSizerLower->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_buttonUpdateModules = new wxButton( this, wxID_ANY, _("Update Python Modules"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerLower->Add( m_buttonUpdateModules, 0, wxALL, 5 ); + + + bSizerLower->Add( 0, 0, 0, wxRIGHT|wxLEFT, 5 ); + m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizerOK = new wxButton( this, wxID_OK ); m_sdbSizer->AddButton( m_sdbSizerOK ); @@ -99,7 +111,10 @@ DIALOG_FOOTPRINT_WIZARD_LIST_BASE::DIALOG_FOOTPRINT_WIZARD_LIST_BASE( wxWindow* m_sdbSizer->AddButton( m_sdbSizerCancel ); m_sdbSizer->Realize(); - bSizerMain->Add( m_sdbSizer, 0, wxALL|wxALIGN_RIGHT, 5 ); + bSizerLower->Add( m_sdbSizer, 0, wxALL|wxALIGN_RIGHT, 5 ); + + + bSizerMain->Add( bSizerLower, 0, wxEXPAND, 5 ); this->SetSizer( bSizerMain ); @@ -111,6 +126,7 @@ DIALOG_FOOTPRINT_WIZARD_LIST_BASE::DIALOG_FOOTPRINT_WIZARD_LIST_BASE( wxWindow* 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 ); + m_buttonUpdateModules->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::onUpdatePythonModulesClick ), NULL, this ); } DIALOG_FOOTPRINT_WIZARD_LIST_BASE::~DIALOG_FOOTPRINT_WIZARD_LIST_BASE() @@ -119,6 +135,7 @@ DIALOG_FOOTPRINT_WIZARD_LIST_BASE::~DIALOG_FOOTPRINT_WIZARD_LIST_BASE() 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 ); + m_buttonUpdateModules->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::onUpdatePythonModulesClick ), NULL, this ); } diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list_base.fbp b/pcbnew/dialogs/dialog_footprint_wizard_list_base.fbp index 404afb48d7..e02a56f271 100644 --- a/pcbnew/dialogs/dialog_footprint_wizard_list_base.fbp +++ b/pcbnew/dialogs/dialog_footprint_wizard_list_base.fbp @@ -930,28 +930,147 @@ 5 - wxALL|wxALIGN_RIGHT + wxEXPAND 0 - - 0 - 1 - 0 - 0 - 0 - 1 - 0 - 0 + - m_sdbSizer - protected - - - - - - - - + bSizerLower + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Update Python Modules + + 0 + + + 0 + + 1 + m_buttonUpdateModules + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + onUpdatePythonModulesClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxRIGHT|wxLEFT + 0 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_RIGHT + 0 + + 0 + 1 + 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 3bcde2e2a2..38a610febf 100644 --- a/pcbnew/dialogs/dialog_footprint_wizard_list_base.h +++ b/pcbnew/dialogs/dialog_footprint_wizard_list_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Dec 4 2016) +// C++ code generated with wxFormBuilder (version May 6 2016) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -51,6 +51,7 @@ class DIALOG_FOOTPRINT_WIZARD_LIST_BASE : public DIALOG_SHIM wxStaticText* m_staticText11; wxTextCtrl* m_tcNotLoaded; wxButton* m_buttonShowTrace; + wxButton* m_buttonUpdateModules; wxStdDialogButtonSizer* m_sdbSizer; wxButton* m_sdbSizerOK; wxButton* m_sdbSizerCancel; @@ -59,6 +60,7 @@ class DIALOG_FOOTPRINT_WIZARD_LIST_BASE : public DIALOG_SHIM virtual void OnCellFpGeneratorClick( wxGridEvent& event ) { event.Skip(); } virtual void OnCellFpGeneratorDoubleClick( wxGridEvent& event ) { event.Skip(); } virtual void onShowTrace( wxCommandEvent& event ) { event.Skip(); } + virtual void onUpdatePythonModulesClick( wxCommandEvent& event ) { event.Skip(); } public: diff --git a/pcbnew/swig/python_scripting.cpp b/pcbnew/swig/python_scripting.cpp index 2bc4e7779d..ece4fcf7d6 100644 --- a/pcbnew/swig/python_scripting.cpp +++ b/pcbnew/swig/python_scripting.cpp @@ -448,7 +448,6 @@ wxString PyScriptingPath() #endif wxFileName scriptPath( path ); - scriptPath.MakeAbsolute(); return scriptPath.GetFullPath(); diff --git a/scripting/kicadplugins.i b/scripting/kicadplugins.i index 324f92550c..57a3405dc0 100644 --- a/scripting/kicadplugins.i +++ b/scripting/kicadplugins.i @@ -54,8 +54,10 @@ KICAD_PLUGINS={} # the list of loaded footprint wizards -""" the list of not loaded python scripts (due to a synthax error in python script) - this is the python script full filenames, separated by '\n' +""" the list of not loaded python scripts + (usually because there is a syntax error in python script) + this is the python script full filenames list. + filenames are separated by '\n' """ NOT_LOADED_WIZARDS="" @@ -81,29 +83,6 @@ def GetWizardsBackTrace(): global FULL_BACK_TRACE return FULL_BACK_TRACE -def ReloadPlugin(name): - if not KICAD_PLUGINS.has_key(name): - return False - - KICAD_PLUGINS[name]["object"].deregister() - mod = reload(KICAD_PLUGINS[name]["module"]) - KICAD_PLUGINS[name]["object"]= mod.register() - - -def ReloadPlugins(): - import os.path - for k in KICAD_PLUGINS.keys(): - plugin = KICAD_PLUGINS[k] - - filename = plugin["filename"] - mtime = plugin["modification_time"] - now_mtime = os.path.getmtime(filename) - - if mtime!=now_mtime: - # /* print filename, " is modified, reloading" */ - KICAD_PLUGINS[k]["modification_time"]=now_mtime - ReloadPlugin(k) - def LoadPlugins(bundlepath=None): """ @@ -169,9 +148,11 @@ def LoadPlugins(bundlepath=None): PLUGIN_DIRECTORIES_SEARCH += plugins_dir global FULL_BACK_TRACE - FULL_BACK_TRACE="" + FULL_BACK_TRACE="" # clear any existing trace failed_wizards_list="" + global KICAD_PLUGINS + for plugins_dir in plugin_directories: if not os.path.isdir(plugins_dir): continue @@ -187,14 +168,22 @@ def LoadPlugins(bundlepath=None): try: # If there is an error loading the script, skip it module_filename = plugins_dir + "/" + module - mod = __import__(module[:-3], locals(), globals()) mtime = os.path.getmtime(module_filename) - if hasattr(mod,'register'): - KICAD_PLUGINS[module]={"filename":module_filename, - "modification_time":mtime, - "object":mod.register(), - "module":mod} + if KICAD_PLUGINS.has_key(module): + plugin = KICAD_PLUGINS[module] + if not plugin["modification_time"] == mtime: + mod = reload(plugin["module"]) + plugin["modification_time"] = mtime + else: + mod = plugin["module"] + else: + mod = __import__(module[:-3], locals(), globals() ) + + KICAD_PLUGINS[module]={"filename":module_filename, + "modification_time":mtime, + "module":mod} + except: if failed_wizards_list != "" : failed_wizards_list += "\n" @@ -213,6 +202,7 @@ class KiCadPlugin: def register(self): if isinstance(self,FilePlugin): pass # register to file plugins in C++ + if isinstance(self,FootprintWizardPlugin): PYTHON_FOOTPRINT_WIZARDS.register_wizard(self) return @@ -224,13 +214,14 @@ class KiCadPlugin: def deregister(self): if isinstance(self,FilePlugin): - pass # register to file plugins in C++ + pass # deregister to file plugins in C++ + if isinstance(self,FootprintWizardPlugin): PYTHON_FOOTPRINT_WIZARDS.deregister_wizard(self) return if isinstance(self,ActionPlugin): - pass # register to action plugins in C++ + pass # deregister to action plugins in C++ return