From 2ee2d9014a3a9478880a7e8cd4a8790038deebde Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 19 Nov 2018 14:44:26 +0100 Subject: [PATCH] Populate BOM plugins list if the list is empty Fixes: lp:1464893 * https://bugs.launchpad.net/kicad/+bug/1464893 --- eeschema/bom_plugins.cpp | 15 ++++ eeschema/bom_plugins.h | 7 ++ eeschema/dialogs/dialog_bom.cpp | 129 ++++++++++++++++++++++++++------ 3 files changed, 127 insertions(+), 24 deletions(-) diff --git a/eeschema/bom_plugins.cpp b/eeschema/bom_plugins.cpp index 864cb2b07b..98bc56b73f 100644 --- a/eeschema/bom_plugins.cpp +++ b/eeschema/bom_plugins.cpp @@ -57,6 +57,21 @@ BOM_PLUGIN::BOM_PLUGIN( const wxString& aFile ) } +bool BOM_PLUGIN::IsPlugin( const wxString& aFile ) +{ + wxFileName fn( aFile ); + wxString ext = fn.GetExt().Lower(); + + for( const auto& pluginExt : { "xsl", "py", "pyw" } ) + { + if( pluginExt == ext ) + return true; + } + + return false; +} + + wxString BOM_PLUGIN::readHeader( const wxString& aEndSection ) { if( aEndSection.IsEmpty() ) diff --git a/eeschema/bom_plugins.h b/eeschema/bom_plugins.h index a2d542d5ae..38b0bd73a4 100644 --- a/eeschema/bom_plugins.h +++ b/eeschema/bom_plugins.h @@ -45,6 +45,12 @@ public: */ BOM_PLUGIN( const wxString& aFile ); + /** + * Returns true if a file name matches a recognized plugin format. + * @param aFile is path to the plugin file. + */ + static bool IsPlugin( const wxString& aFile ); + /** * Returns plugin description stored in the plugin header file (if available). */ @@ -121,6 +127,7 @@ protected: ///> Description of the plugin (normally from the plugin header) wxString m_info; + ///> Plugin specific options wxArrayString m_options; }; diff --git a/eeschema/dialogs/dialog_bom.cpp b/eeschema/dialogs/dialog_bom.cpp index d28762ba83..4fe5a52d72 100644 --- a/eeschema/dialogs/dialog_bom.cpp +++ b/eeschema/dialogs/dialog_bom.cpp @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -45,6 +44,8 @@ #include #include +static constexpr wxChar BOM_TRACE[] = wxT( "BOM_PLUGINS" ); + static constexpr wxChar BOM_PLUGINS_KEY[] = wxT( "bom_plugins" ); static constexpr wxChar BOM_PLUGIN_SELECTED_KEY[] = wxT( "bom_plugin_selected" ); @@ -186,6 +187,8 @@ private: void pluginInit(); void installPluginsList(); + BOM_PLUGIN* addPlugin( const wxString& aPath, const wxString& aName = wxEmptyString ); + bool pluginExists( const wxString& aName ); BOM_PLUGIN* selectedPlugin() { @@ -232,6 +235,7 @@ DIALOG_BOM::DIALOG_BOM( SCH_EDIT_FRAME* parent ) : SetInitialFocus( m_lbPlugins ); m_sdbSizer1OK->SetDefault(); + wxLogDebug( "TEEEEST" ); // Now all widgets have the size fixed, call FinishDialogSettings FinishDialogSettings(); @@ -299,21 +303,105 @@ void DIALOG_BOM::installPluginsList() { DisplayError( nullptr, e.what() ); } + + // Populate list box + for( unsigned ii = 0; ii < m_plugins.size(); ii++ ) + { + m_lbPlugins->Append( m_plugins[ii]->GetName() ); + + if( active_plugin_name == m_plugins[ii]->GetName() ) + m_lbPlugins->SetSelection( ii ); + } } - // Populate list box - for( unsigned ii = 0; ii < m_plugins.size(); ii++ ) + if( m_plugins.empty() ) // No plugins found? { - m_lbPlugins->Append( m_plugins[ii]->GetName() ); + // Load plugins from the default locations + std::vector pluginPaths = { +#if defined(__WXGTK__) + "/usr/share/kicad/plugins", + "/usr/local/share/kicad/plugins", +#elif defined(__WXMSW__) + wxString::Format( "%s\\scripting\\plugins", Pgm().GetExecutablePath() ), +#elif defined(__WXMAC__) + wxString::Format( "%s/plugins", GetOSXKicadDataDir() ), +#endif + }; - if( active_plugin_name == m_plugins[ii]->GetName() ) - m_lbPlugins->SetSelection( ii ); + wxFileName pluginPath; + + for( const auto& path : pluginPaths ) + { + wxLogDebug( wxString::Format( "Searching directory %s for BOM plugins", path ) ); + wxDir dir( path ); + + if( !dir.IsOpened() ) + continue; + + pluginPath.AssignDir( dir.GetName() ); + wxString fileName; + bool cont = dir.GetFirst( &fileName, "*", wxDIR_FILES ); + + while( cont ) + { + try + { + wxLogTrace( BOM_TRACE, wxString::Format( "Checking if %s is a BOM plugin", fileName ) ); + + if( BOM_PLUGIN::IsPlugin( fileName ) ) + { + pluginPath.SetFullName( fileName ); + addPlugin( pluginPath.GetFullPath() ); + } + } + catch( ... ) { /* well, no big deal */ } + + cont = dir.GetNext( &fileName ); + } + } } + pluginInit(); } +BOM_PLUGIN* DIALOG_BOM::addPlugin( const wxString& aPath, const wxString& aName ) +{ + BOM_PLUGIN* ret = nullptr; + auto plugin = std::make_unique( aPath ); + + if( !plugin ) + return nullptr; + + if( !aName.IsEmpty() ) + { + plugin->SetName( aName ); + m_lbPlugins->Append( aName ); + } + else + { + m_lbPlugins->Append( plugin->GetName() ); + } + + ret = plugin.get(); + m_plugins.push_back( std::move( plugin ) ); + return ret; +} + + +bool DIALOG_BOM::pluginExists( const wxString& aName ) +{ + for( unsigned ii = 0; ii < m_plugins.size(); ii++ ) + { + if( aName == m_plugins[ii]->GetName() ) + return true; + } + + return false; +} + + void DIALOG_BOM::OnPluginSelected( wxCommandEvent& event ) { pluginInit(); @@ -338,7 +426,7 @@ void DIALOG_BOM::pluginInit() m_Messages->SetSelection( 0, 0 ); #ifdef __WINDOWS__ - if( plugin.Options().Index( wxT( "show_console" ) ) == wxNOT_FOUND ) + if( plugin->Options().Index( wxT( "show_console" ) ) == wxNOT_FOUND ) m_checkBoxShowConsole->SetValue( false ); else m_checkBoxShowConsole->SetValue( true ); @@ -406,29 +494,22 @@ void DIALOG_BOM::OnAddPlugin( wxCommandEvent& event ) return; // Verify if it does not exists - for( unsigned ii = 0; ii < m_plugins.size(); ii++ ) + if( pluginExists( name ) ) { - if( name == m_plugins[ii]->GetName() ) - { - wxMessageBox( wxString::Format( _( "Nickname \"%s\" already in use." ), name ) ); - return; - } + wxMessageBox( wxString::Format( _( "Nickname \"%s\" already in use." ), name ) ); + return; } try { - auto plugin = std::make_unique( fn.GetFullPath() ); + auto plugin = addPlugin( fn.GetFullPath(), name ); - if( !plugin ) - return; - - plugin->SetName( name ); - m_lbPlugins->Append( name ); - m_lbPlugins->SetSelection( m_lbPlugins->GetCount() - 1 ); - m_textCtrlCommand->SetValue( plugin->GetCommand() ); - - m_plugins.push_back( std::move( plugin ) ); - pluginInit(); + if( plugin ) + { + m_lbPlugins->SetSelection( m_lbPlugins->GetCount() - 1 ); + m_textCtrlCommand->SetValue( plugin->GetCommand() ); + pluginInit(); + } } catch( const std::runtime_error& e ) {