BOM plugins refactor

Extended BOM_PLUGIN to a class and moved the plugin construction related code there.
This commit is contained in:
Maciej Suminski 2018-11-12 14:45:07 +01:00
parent 240051fb26
commit 15772e4b0b
4 changed files with 314 additions and 254 deletions

View File

@ -130,6 +130,7 @@ set( EESCHEMA_SRCS
${EESCHEMA_DLGS} ${EESCHEMA_DLGS}
${EESCHEMA_WIDGETS} ${EESCHEMA_WIDGETS}
${EESCHEMA_LIBEDIT_SRCS} ${EESCHEMA_LIBEDIT_SRCS}
bom_plugins.cpp
sch_view.cpp sch_view.cpp
sch_painter.cpp sch_painter.cpp
annotate.cpp annotate.cpp

90
eeschema/bom_plugins.cpp Normal file
View File

@ -0,0 +1,90 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "bom_plugins.h"
BOM_PLUGIN::BOM_PLUGIN( const wxString& aFile )
: m_file( aFile )
{
if( !wxFile::Exists( aFile ) )
throw std::runtime_error( _( "Cannot open plugin " ) + aFile.ToStdString() );
m_name = m_file.GetName();
wxString extension = m_file.GetExt().Lower();
if( extension == "xsl" )
{
m_info = readHeader( "-->" );
m_cmd = wxString::Format( "xsltproc -o \"%%O\" \"%s\" \"%%I\"", m_file.GetFullPath() );
}
else if( extension == "py" )
{
m_info = readHeader( "\"\"\"" );
m_cmd = wxString::Format( "python \"%s\" \"%%I\" \"%%O\"", m_file.GetFullPath() );
}
#ifdef __WINDOWS__
else if( extension == "pyw" )
{
m_info = readHeader( "\"\"\"" );
m_cmd = wxString::Format( "pythonw \"%s\" \"%%I\" \"%%O\"", m_file.GetFullPath() );
}
#endif /* __WINDOWS__ */
else // fallback
{
m_cmd = m_file.GetFullPath();
}
}
wxString BOM_PLUGIN::readHeader( const wxString& aEndSection )
{
if( aEndSection.IsEmpty() )
return wxEmptyString;
wxFile fdata( m_file.GetFullPath() ); // dtor will close the file
wxString data;
if( !fdata.ReadAll( &data ) )
return wxEmptyString;
const wxString header( "@package" );
// Extract substring between @package and endsection
int strstart = data.Find( header );
if( strstart == wxNOT_FOUND )
return wxEmptyString;
strstart += header.Length();
int strend = data.find( aEndSection, strstart );
if( strend == wxNOT_FOUND)
return wxEmptyString;
// Remove empty line if any
while( data[strstart] < ' ' )
strstart++;
return data.SubString( strstart, strend - 1 );
}

127
eeschema/bom_plugins.h Normal file
View File

@ -0,0 +1,127 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef BOM_PLUGINS_H
#define BOM_PLUGINS_H
#include <wx/arrstr.h>
#include <wx/file.h>
#include <wx/filename.h>
#include <memory>
/**
* Class representing a Bill of Material output plugin.
*/
class BOM_PLUGIN
{
public:
typedef std::unique_ptr<BOM_PLUGIN> PTR;
/**
* Constructor.
* @param aFile is path to the plugin file.
*/
BOM_PLUGIN( const wxString& aFile );
/**
* Returns plugin description stored in the plugin header file (if available).
*/
const wxString& GetInfo() const
{
return m_info;
}
/**
* Returns the file name of the plugin.
*/
const wxFileName& GetFile() const
{
return m_file;
}
/**
* Returns the customisable plugin name.
*/
const wxString& GetName() const
{
return m_name;
}
/**
* Sets the customisable plugin name.
* @param aName is the new name.
*/
void SetName( const wxString& aName )
{
m_name = aName;
}
/**
* Returns the command to execute the plugin.
*/
const wxString& GetCommand() const
{
return m_cmd;
}
/**
* Sets the command to execute the plugin.
*/
void SetCommand( const wxString& aCommand )
{
m_cmd = aCommand;
}
/**
* Accessor to array of options.
*/
wxArrayString& Options()
{
return m_options;
}
protected:
/**
* Reads the plugin file header.
* @param aEndSection is a string marking end of the header.
*/
wxString readHeader( const wxString& aEndSection );
///> Path to the plugin
const wxFileName m_file;
///> User customisable name
wxString m_name;
///> Command to execute the plugin
wxString m_cmd;
///> Description of the plugin (normally from the plugin header)
wxString m_info;
wxArrayString m_options;
};
#endif /* BOM_PLUGINS_H */

View File

@ -42,11 +42,13 @@
#include <dialog_bom_base.h> #include <dialog_bom_base.h>
#include <html_messagebox.h> #include <html_messagebox.h>
#include <reporter.h> #include <reporter.h>
#include <bom_plugins.h>
#include <make_unique.h>
#define BOM_PLUGINS_KEY wxT("bom_plugins") static constexpr wxChar BOM_PLUGINS_KEY[] = wxT( "bom_plugins" );
#define BOM_PLUGIN_SELECTED_KEY wxT("bom_plugin_selected") static constexpr wxChar BOM_PLUGIN_SELECTED_KEY[] = wxT( "bom_plugin_selected" );
const char * s_bomHelpInfo = static const char* s_bomHelpInfo =
#include <dialog_bom_help_html.h> #include <dialog_bom_help_html.h>
; ;
@ -54,24 +56,7 @@ const char * s_bomHelpInfo =
using namespace T_BOMCFG_T; using namespace T_BOMCFG_T;
typedef std::vector<BOM_PLUGIN::PTR> BOM_PLUGIN_ARRAY;
/**
* Hold data of the BOM plugin.
*/
struct BOM_PLUGIN
{
wxString Name;
wxString Command;
wxArrayString Options;
};
/**
* Define wxArray of BOM_PLUGIN.
*/
WX_DECLARE_OBJARRAY( BOM_PLUGIN, BOM_PLUGIN_ARRAY );
#include <wx/arrimpl.cpp>
WX_DEFINE_OBJARRAY( BOM_PLUGIN_ARRAY )
/** /**
@ -129,10 +114,9 @@ void BOM_CFG_PARSER::Parse()
void BOM_CFG_PARSER::parsePlugin() void BOM_CFG_PARSER::parsePlugin()
{ {
BOM_PLUGIN plugin;
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
plugin.Name = FromUTF8(); wxString name = FromUTF8();
auto plugin = std::make_unique<BOM_PLUGIN>( name );
T token; T token;
@ -148,13 +132,19 @@ void BOM_CFG_PARSER::parsePlugin()
case T_cmd: case T_cmd:
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
plugin.Command = FromUTF8();
if( plugin )
plugin->SetCommand( FromUTF8() );
NeedRIGHT(); NeedRIGHT();
break; break;
case T_opts: case T_opts:
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
plugin.Options.Add( FromUTF8() );
if( plugin )
plugin->Options().Add( FromUTF8() );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -164,8 +154,8 @@ void BOM_CFG_PARSER::parsePlugin()
} }
} }
if( ! plugin.Name.IsEmpty() ) if( plugin )
m_pluginsList->Add( plugin ); m_pluginsList->push_back( std::move( plugin ) );
} }
@ -197,13 +187,15 @@ private:
void pluginInit(); void pluginInit();
void installPluginsList(); void installPluginsList();
wxString getPluginFileName( const wxString& aCommand ); BOM_PLUGIN* selectedPlugin()
{
int idx = m_lbPlugins->GetSelection();
/* if( idx < 0 || idx >= m_plugins.size() )
* Display the text found between the keyword @package (compatible with doxygen comments) return nullptr;
* and the end of comment block (""" in python, --> in xml)
*/ return m_plugins[idx].get();
void displayPluginInfo( FILE * aFile, const wxString& aFilename ); }
wxString choosePlugin(); wxString choosePlugin();
}; };
@ -258,16 +250,16 @@ DIALOG_BOM::~DIALOG_BOM()
STRING_FORMATTER writer; STRING_FORMATTER writer;
writer.Print( 0, "(plugins" ); writer.Print( 0, "(plugins" );
for( unsigned ii = 0; ii < m_plugins.GetCount(); ii++ ) for( auto& plugin : m_plugins )
{ {
writer.Print( 1, "(plugin %s (cmd %s)", writer.Print( 1, "(plugin %s (cmd %s)",
writer.Quotew( m_plugins.Item( ii ).Name ).c_str(), writer.Quotew( plugin->GetFile().GetFullPath() ).c_str(),
writer.Quotew( m_plugins.Item( ii ).Command ).c_str() ); writer.Quotew( plugin->GetCommand() ).c_str() );
for( unsigned jj = 0; jj < m_plugins.Item( ii ).Options.GetCount(); jj++ ) for( unsigned jj = 0; jj < plugin->Options().GetCount(); jj++ )
{ {
writer.Print( 1, "(opts %s)", writer.Print( 1, "(opts %s)",
writer.Quotew( m_plugins.Item( ii ).Options.Item( jj ) ).c_str() ); writer.Quotew( plugin->Options().Item( jj ) ).c_str() );
} }
writer.Print( 0, ")" ); writer.Print( 0, ")" );
@ -281,7 +273,6 @@ DIALOG_BOM::~DIALOG_BOM()
wxString active_plugin_name = m_lbPlugins->GetStringSelection( ); wxString active_plugin_name = m_lbPlugins->GetStringSelection( );
m_config->Write( BOM_PLUGIN_SELECTED_KEY, active_plugin_name ); m_config->Write( BOM_PLUGIN_SELECTED_KEY, active_plugin_name );
} }
@ -304,14 +295,18 @@ void DIALOG_BOM::installPluginsList()
{ {
// wxLogMessage( ioe.What() ); // wxLogMessage( ioe.What() );
} }
catch( std::runtime_error& e )
{
DisplayError( nullptr, e.what() );
}
} }
// Populate list box // Populate list box
for( unsigned ii = 0; ii < m_plugins.GetCount(); ii++ ) for( unsigned ii = 0; ii < m_plugins.size(); ii++ )
{ {
m_lbPlugins->Append( m_plugins.Item( ii ).Name ); m_lbPlugins->Append( m_plugins[ii]->GetName() );
if( active_plugin_name == m_plugins.Item( ii ).Name ) if( active_plugin_name == m_plugins[ii]->GetName() )
m_lbPlugins->SetSelection( ii ); m_lbPlugins->SetSelection( ii );
} }
@ -327,86 +322,27 @@ void DIALOG_BOM::OnPluginSelected( wxCommandEvent& event )
void DIALOG_BOM::pluginInit() void DIALOG_BOM::pluginInit()
{ {
int ii = m_lbPlugins->GetSelection(); auto plugin = selectedPlugin();
if( ii < 0 ) if( !plugin )
{ {
m_textCtrlName->SetValue( wxEmptyString ); m_textCtrlName->SetValue( wxEmptyString );
m_textCtrlCommand->SetValue( wxEmptyString ); m_textCtrlCommand->SetValue( wxEmptyString );
m_Messages->SetValue( wxEmptyString );
return; return;
} }
m_textCtrlName->SetValue( m_plugins.Item( ii ).Name ); m_textCtrlName->SetValue( plugin->GetName() );
m_textCtrlCommand->SetValue( m_plugins.Item( ii ).Command ); m_textCtrlCommand->SetValue( plugin->GetCommand() );
m_Messages->SetValue( plugin->GetInfo() );
m_Messages->SetSelection( 0, 0 );
#ifdef __WINDOWS__ #ifdef __WINDOWS__
if( m_plugins.Item( ii ).Options.Index( wxT( "show_console" ) ) == wxNOT_FOUND ) if( plugin.Options().Index( wxT( "show_console" ) ) == wxNOT_FOUND )
m_checkBoxShowConsole->SetValue( false ); m_checkBoxShowConsole->SetValue( false );
else else
m_checkBoxShowConsole->SetValue( true ); m_checkBoxShowConsole->SetValue( true );
#endif #endif
wxString pluginName = getPluginFileName( m_textCtrlCommand->GetValue() );
if( pluginName.IsEmpty() )
return;
FILE* pluginFile = wxFopen( pluginName, "rt" );
if( !pluginFile )
{
DisplayError( this, wxString::Format( _( "Failed to open file \"%s\"." ), pluginName ) );
return;
}
displayPluginInfo( pluginFile, pluginName );
}
void DIALOG_BOM::displayPluginInfo( FILE * aFile, const wxString& aFilename )
{
m_Messages->Clear();
// Display the text found between the keyword @package (compatible with doxygen comments)
// and the end of comment block (""" in python, --> in xml)
wxString data;
wxFFile fdata( aFile ); // dtor will close the file
if( !fdata.ReadAll( &data ) )
return;
wxString header( "@package" );
wxString endsection;
wxFileName fn( aFilename );
if( fn.GetExt().IsSameAs( "py", false ) )
endsection = "\"\"\"";
else if( fn.GetExt().IsSameAs( "xsl", false ) )
endsection = "-->";
else
// If this is not a python or xsl file, then we don't know how to find the info
return;
// Extract substring between @package and endsection
int strstart = data.Find( header );
if( strstart == wxNOT_FOUND )
return;
strstart += header.Length();
int strend = data.find( endsection, strstart );
if( strend == wxNOT_FOUND)
return;
// Remove empty line if any
while( data[strstart] < ' ' )
strstart++;
m_Messages->SetValue( data.SubString( strstart, strend-1 ) );
m_Messages->SetSelection( 0, 0 );
} }
@ -444,8 +380,7 @@ void DIALOG_BOM::OnRemovePlugin( wxCommandEvent& event )
return; return;
m_lbPlugins->Delete( ii ); m_lbPlugins->Delete( ii );
m_plugins.erase( m_plugins.begin() + ii );
m_plugins.RemoveAt( ii );
// Select the next item, if exists // Select the next item, if exists
if( m_lbPlugins->GetCount() ) if( m_lbPlugins->GetCount() )
@ -457,14 +392,13 @@ void DIALOG_BOM::OnRemovePlugin( wxCommandEvent& event )
void DIALOG_BOM::OnAddPlugin( wxCommandEvent& event ) void DIALOG_BOM::OnAddPlugin( wxCommandEvent& event )
{ {
wxString cmdLine = choosePlugin(); wxString filename = choosePlugin();
BOM_PLUGIN newPlugin;
if( cmdLine.IsEmpty() ) if( filename.IsEmpty() )
return; return;
// Creates a new plugin entry // Creates a new plugin entry
wxFileName fn( getPluginFileName( cmdLine ) ); wxFileName fn( filename );
wxString name = wxGetTextFromUser( _( "Plugin nickname:" ), _( "Add Plugin" ), wxString name = wxGetTextFromUser( _( "Plugin nickname:" ), _( "Add Plugin" ),
fn.GetName(), this ); fn.GetName(), this );
@ -472,31 +406,40 @@ void DIALOG_BOM::OnAddPlugin( wxCommandEvent& event )
return; return;
// Verify if it does not exists // Verify if it does not exists
for( unsigned ii = 0; ii < m_plugins.GetCount(); ii++ ) for( unsigned ii = 0; ii < m_plugins.size(); ii++ )
{ {
if( name == m_plugins.Item( ii ).Name ) if( name == m_plugins[ii]->GetName() )
{ {
wxMessageBox( wxString::Format( _( "Nickname \"%s\" already in use." ), name ) ); wxMessageBox( wxString::Format( _( "Nickname \"%s\" already in use." ), name ) );
return; return;
} }
} }
// Append the new plugin try
newPlugin.Name = name; {
newPlugin.Command = wxEmptyString; auto plugin = std::make_unique<BOM_PLUGIN>( fn.GetFullPath() );
m_plugins.Add( newPlugin );
if( !plugin )
return;
plugin->SetName( name );
m_lbPlugins->Append( name ); m_lbPlugins->Append( name );
m_lbPlugins->SetSelection( m_lbPlugins->GetCount() - 1 ); m_lbPlugins->SetSelection( m_lbPlugins->GetCount() - 1 );
m_textCtrlCommand->SetValue( cmdLine ); m_textCtrlCommand->SetValue( plugin->GetCommand() );
m_plugins.push_back( std::move( plugin ) );
pluginInit(); pluginInit();
}
catch( const std::runtime_error& e )
{
DisplayError( this, e.what() );
}
} }
wxString DIALOG_BOM::choosePlugin() wxString DIALOG_BOM::choosePlugin()
{ {
static wxString lastPath; static wxString lastPath;
wxString mask = "*";
if( lastPath.IsEmpty() ) if( lastPath.IsEmpty() )
{ {
@ -507,135 +450,33 @@ wxString DIALOG_BOM::choosePlugin()
#endif #endif
} }
wxString fullFileName = EDA_FILE_SELECTOR( _( "Plugin files:" ), wxString fullFileName = EDA_FILE_SELECTOR( _( "Plugin files:" ), lastPath, wxEmptyString,
lastPath, wxEmptyString, "*", this, wxFD_OPEN, true );
wxEmptyString,
wxEmptyString,
mask,
this,
wxFD_OPEN,
true );
if( fullFileName.IsEmpty() )
return wxEmptyString;
// Creates a default command line, return fullFileName;
// suitable to run the external tool xslproc or python
// The default command line depending on plugin extension, currently
// "xsl" or "exe" or "py" or "pyw"
wxString cmdLine;
wxFileName fn( fullFileName );
wxString ext = fn.GetExt();
lastPath = fn.GetPath();
// Python requires on Windows the path of the script ends by '/' instead of '\'
// otherwise import does not find modules in the same folder as the python script
// We cannot change all '\' to '/' in command line because it causes issues with files
// that are stored on network resources and pointed to using the Windows
// Universal Naming Convention format. (full filename starting by \\server\)
//
// I hope changing the last separator only to '/' will work.
#ifdef __WINDOWS__
if( ext == "py" || ext == "pyw" )
{
wxString sc_path = fn.GetPathWithSep();
sc_path.RemoveLast();
fullFileName = sc_path + '/' + fn.GetFullName();;
}
#endif
if( ext == "xsl" )
cmdLine.Printf( "xsltproc -o \"%%O\" \"%s\" \"%%I\"", GetChars( fullFileName ) );
else if( ext == "exe" )
cmdLine.Printf( "\"%s\" < \"%%I\" > \"%%O\"", GetChars( fullFileName ) );
else if( ext == "py" )
cmdLine.Printf( "python \"%s\" \"%%I\" \"%%O\"", GetChars( fullFileName ) );
else if( ext == "pyw" )
#ifdef __WINDOWS__
cmdLine.Printf( "pythonw \"%s\" \"%%I\" \"%%O\"", GetChars( fullFileName ) );
#else
cmdLine.Printf( "python \"%s\" \"%%I\" \"%%O\"", GetChars( fullFileName ) );
#endif
else
cmdLine.Printf( "\"%s\"", GetChars( fullFileName ) );
return cmdLine;
} }
wxString DIALOG_BOM::getPluginFileName( const wxString& aCommand )
{
wxString pluginName;
// Try to find the plugin name.
// This is possible if the name ends by .py or .pyw or .xsl or .exe
int pos = -1;
if( (pos = aCommand.Find( ".pyw" )) != wxNOT_FOUND )
pos += 3;
else if( (pos = aCommand.Find( ".py" )) != wxNOT_FOUND )
pos += 2;
else if( (pos = aCommand.Find( ".xsl" )) != wxNOT_FOUND )
pos += 3;
else if( (pos = aCommand.Find( ".exe" )) != wxNOT_FOUND )
pos += 3;
// the end of plugin name is at position pos.
if( pos > 0 )
{
// Be sure this is the end of the name: the next char is " or space
int eos = aCommand[pos+1];
if( eos == ' '|| eos == '\"' )
{
// search for the starting point of the name
int jj = pos-1;
while( jj >= 0 )
if( aCommand[jj] != eos )
jj--;
else
break;
// extract the name
if( jj >= 0 )
{
eos = aCommand[jj];
if( eos == ' '|| eos == '\"' ) // do not include delimiters
jj++;
pluginName = aCommand.SubString( jj, pos );
}
}
}
// Using a format like %P is possible in plugin name, so expand it
wxString prj_dir = Prj().GetProjectPath();
if( prj_dir.EndsWith( '/' ) || prj_dir.EndsWith( '\\' ) )
prj_dir.RemoveLast();
pluginName.Replace( "%P", prj_dir.GetData(), true );
return pluginName;
}
void DIALOG_BOM::OnEditPlugin( wxCommandEvent& event ) void DIALOG_BOM::OnEditPlugin( wxCommandEvent& event )
{ {
wxString pluginName = getPluginFileName( m_textCtrlCommand->GetValue() ); auto plugin = selectedPlugin();
if( pluginName.Length() <= 2 ) // if name != "" if( !plugin )
return;
wxString pluginFile = plugin->GetFile().GetFullPath();
if( pluginFile.Length() <= 2 ) // if name != ""
{ {
wxMessageBox( _( "Plugin file name not found." ) ); wxMessageBox( _( "Plugin file name not found." ) );
return; return;
} }
AddDelimiterString( pluginName ); AddDelimiterString( pluginFile );
wxString editorname = Pgm().GetEditorName(); wxString editorname = Pgm().GetEditorName();
if( !editorname.IsEmpty() ) if( !editorname.IsEmpty() )
ExecuteFile( this, editorname, pluginName ); ExecuteFile( this, editorname, pluginFile );
else else
wxMessageBox( _( "No text editor selected in KiCad. Please choose one." ) ); wxMessageBox( _( "No text editor selected in KiCad. Please choose one." ) );
} }
@ -643,7 +484,7 @@ void DIALOG_BOM::OnEditPlugin( wxCommandEvent& event )
void DIALOG_BOM::OnHelp( wxCommandEvent& event ) void DIALOG_BOM::OnHelp( wxCommandEvent& event )
{ {
HTML_MESSAGE_BOX help_Dlg( this, _( "Bom Generation Help" ) ); HTML_MESSAGE_BOX help_Dlg( this, _( "Bill of Material Generation Help" ) );
help_Dlg.SetDialogSizeInDU( 500, 350 ); help_Dlg.SetDialogSizeInDU( 500, 350 );
wxString msg = FROM_UTF8( s_bomHelpInfo ); wxString msg = FROM_UTF8( s_bomHelpInfo );
@ -654,12 +495,10 @@ void DIALOG_BOM::OnHelp( wxCommandEvent& event )
void DIALOG_BOM::OnCommandLineEdited( wxCommandEvent& event ) void DIALOG_BOM::OnCommandLineEdited( wxCommandEvent& event )
{ {
int ii = m_lbPlugins->GetSelection(); auto plugin = selectedPlugin();
if( ii < 0 ) if( plugin )
return; plugin->SetCommand( m_textCtrlCommand->GetValue() );
m_plugins.Item( ii ).Command = m_textCtrlCommand->GetValue();
} }
@ -670,26 +509,29 @@ void DIALOG_BOM::OnNameEdited( wxCommandEvent& event )
if( ii < 0 ) if( ii < 0 )
return; return;
m_plugins.Item( ii ).Name = m_textCtrlName->GetValue(); m_plugins[ii]->SetName( m_textCtrlName->GetValue() );
m_lbPlugins->SetString( ii, m_plugins.Item( ii ).Name ); m_lbPlugins->SetString( ii, m_plugins[ii]->GetName() );
} }
void DIALOG_BOM::OnShowConsoleChanged( wxCommandEvent& event ) void DIALOG_BOM::OnShowConsoleChanged( wxCommandEvent& event )
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
int ii = m_lbPlugins->GetSelection(); static constexpr wxChar OPT_SHOW_CONSOLE[] = wxT( "show_console" );
if( ii < 0 ) auto plugin = selectedPlugin();
if( !plugin )
return; return;
if( m_checkBoxShowConsole->IsChecked() ) if( m_checkBoxShowConsole->IsChecked() )
{ {
if( m_plugins.Item( ii ).Options.Index( "show_console" ) == wxNOT_FOUND ) if( plugin->Options().Index( OPT_SHOW_CONSOLE ) == wxNOT_FOUND )
m_plugins.Item( ii ).Options.Add( "show_console" ); plugin->Options().Add( OPT_SHOW_CONSOLE );
} }
else else
{ {
m_plugins.Item( ii ).Options.Remove( "show_console" ); plugin->Options().Remove( OPT_SHOW_CONSOLE );
} }
#endif #endif
} }