Add Python Tool to pcbnew

This commit is contained in:
Seth Hillbrand 2021-03-19 16:06:29 -07:00
parent c7d188a8d0
commit bf1437899e
22 changed files with 277 additions and 185 deletions

View File

@ -483,6 +483,7 @@ target_link_libraries( common
kimath
kiplatform
gal
scripting
pybind11::embed
${Boost_LIBRARIES}
${CURL_LIBRARIES}

View File

@ -50,6 +50,7 @@
#include <lockfile.h>
#include <menus_helpers.h>
#include <pgm_base.h>
#include <python_scripting.h>
#include <settings/common_settings.h>
#include <settings/settings_manager.h>
#include <systemdirsappend.h>
@ -204,7 +205,6 @@ const wxString PGM_BASE::AskUserForPreferredEditor( const wxString& aDefaultEdit
bool PGM_BASE::InitPgm( bool aHeadless )
{
printf("InitPgm()\n");
wxFileName pgm_name( App().argv[0] );
wxInitAllImageHandlers();
@ -286,6 +286,8 @@ bool PGM_BASE::InitPgm( bool aHeadless )
ReadPdfBrowserInfos(); // needs GetCommonSettings()
m_python_scripting = std::make_unique<SCRIPTING>();
#ifdef __WXMAC__
// Always show filters on Open dialog to be able to choose plugin
wxSystemOptions::SetOption( wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES, 1 );

View File

@ -47,6 +47,7 @@ class wxWindow;
class COMMON_SETTINGS;
class SETTINGS_MANAGER;
class SCRIPTING;
/**
* A small class to handle the list of existing translations.
@ -305,6 +306,8 @@ protected:
std::unique_ptr<SETTINGS_MANAGER> m_settings_manager;
std::unique_ptr<SCRIPTING> m_python_scripting;
/// prevents multiple instances of a program from being run at the same time.
wxSingleInstanceChecker* m_pgm_checker;

View File

@ -370,6 +370,7 @@ set( PCBNEW_SCRIPTING_PYTHON_HELPERS
swig/pcbnew_footprint_wizards.cpp
swig/pcbnew_scripting_helpers.cpp
swig/pcbnew_scripting.cpp
swig/pcb_scripting_tool.cpp
)

View File

@ -18,19 +18,20 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <kiface_i.h>
#include <pcb_edit_frame.h>
#include <pcbnew_settings.h>
#include <panel_pcbnew_action_plugins.h>
#include <dialog_footprint_wizard_list.h>
#include <widgets/paged_dialog.h>
#include <widgets/grid_icon_text_helpers.h>
#include <bitmaps.h>
#include <action_plugin.h>
#include <bitmaps.h>
#include <dialog_footprint_wizard_list.h>
#include <grid_tricks.h>
#include <widgets/wx_grid.h>
#include <kiface_i.h>
#include <panel_pcbnew_action_plugins.h>
#include <pcb_edit_frame.h>
#include <pcbnew_scripting.h>
#include <pcbnew_settings.h>
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <widgets/grid_icon_text_helpers.h>
#include <widgets/paged_dialog.h>
#include <widgets/wx_grid.h>
#define GRID_CELL_MARGIN 4
@ -138,7 +139,7 @@ void PANEL_PCBNEW_ACTION_PLUGINS::SwapRows( int aRowA, int aRowB )
void PANEL_PCBNEW_ACTION_PLUGINS::OnReloadButtonClick( wxCommandEvent& event )
{
m_frame->PythonPluginsReload();
m_frame->GetToolManager()->RunAction( PCB_ACTIONS::pluginsReload, true );
TransferDataToWindow();
}
@ -231,7 +232,7 @@ bool PANEL_PCBNEW_ACTION_PLUGINS::TransferDataToWindow()
void PANEL_PCBNEW_ACTION_PLUGINS::OnOpenDirectoryButtonClick( wxCommandEvent& event )
{
m_frame->PythonPluginsShowFolder();
m_frame->GetToolManager()->RunAction( PCB_ACTIONS::pluginsShowFolder );
}
void PANEL_PCBNEW_ACTION_PLUGINS::OnShowErrorsButtonClick( wxCommandEvent& event )

View File

@ -31,6 +31,7 @@
#include "tools/placement_tool.h"
#include "tools/pcb_point_editor.h"
#include "tools/pcb_selection_tool.h"
#include <swig/pcb_scripting_tool.h>
#include <3d_viewer/eda_3d_viewer.h>
#include <bitmaps.h>
#include <board.h>
@ -943,6 +944,7 @@ void FOOTPRINT_EDIT_FRAME::setupTools()
m_toolManager->RegisterTool( new PCB_VIEWER_TOOLS );
m_toolManager->RegisterTool( new GROUP_TOOL );
m_toolManager->RegisterTool( new CONVERT_TOOL );
m_toolManager->RegisterTool( new SCRIPTING_TOOL );
m_toolManager->GetTool<PCB_SELECTION_TOOL>()->SetIsFootprintEditor( true );
m_toolManager->GetTool<EDIT_TOOL>()->SetIsFootprintEditor( true );
@ -953,6 +955,7 @@ void FOOTPRINT_EDIT_FRAME::setupTools()
m_toolManager->GetTool<PCB_PICKER_TOOL>()->SetIsFootprintEditor( true );
m_toolManager->GetTool<POSITION_RELATIVE_TOOL>()->SetIsFootprintEditor( true );
m_toolManager->GetTool<GROUP_TOOL>()->SetIsFootprintEditor( true );
m_toolManager->GetTool<SCRIPTING_TOOL>()->SetIsFootprintEditor( true );
m_toolManager->GetTool<PCB_VIEWER_TOOLS>()->SetFootprintFrame( true );
m_toolManager->InitTools();

View File

@ -647,7 +647,7 @@ void FOOTPRINT_WIZARD_FRAME::PythonPluginsReload()
auto brd_frame = static_cast<PCB_EDIT_FRAME*>( Kiway().Player( FRAME_PCB_EDITOR, false ) );
if( brd_frame )
brd_frame->PythonPluginsReload();
brd_frame->GetToolManager()->RunAction( PCB_ACTIONS::pluginsReload );
else
PythonPluginsReloadBase();
GetToolManager()->RunAction( PCB_ACTIONS::pluginsReload );
}

View File

@ -413,21 +413,9 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
submenuActionPlugins->SetTitle( _( "External Plugins" ) );
submenuActionPlugins->SetIcon( BITMAPS::puzzle_piece );
submenuActionPlugins->Add( _( "Refresh Plugins" ),
_( "Reload all python plugins and refresh plugin menus" ),
ID_TOOLBARH_PCB_ACTION_PLUGIN_REFRESH,
BITMAPS::reload );
#ifdef __APPLE__
submenuActionPlugins->Add( _( "Reveal Plugin Folder in Finder" ),
_( "Reveals the plugins folder in a Finder window" ),
ID_TOOLBARH_PCB_ACTION_PLUGIN_SHOW_FOLDER,
BITMAPS::directory_open );
#else
submenuActionPlugins->Add( _( "Open Plugin Directory" ),
_( "Opens the directory in the default system file manager" ),
ID_TOOLBARH_PCB_ACTION_PLUGIN_SHOW_FOLDER,
BITMAPS::directory_open );
#endif
submenuActionPlugins->Add( PCB_ACTIONS::pluginsReload );
submenuActionPlugins->Add( PCB_ACTIONS::pluginsShowFolder );
// Populate the Action Plugin sub-menu: Must be done before Add
// Since the object is cloned by Add
submenuActionPlugins->AppendSeparator();

View File

@ -84,6 +84,7 @@
#include <router/router_tool.h>
#include <router/length_tuner_tool.h>
#include <autorouter/autoplace_tool.h>
#include <swig/pcb_scripting_tool.h>
#include <gestfich.h>
#include <executable_names.h>
#include <netlist_reader/board_netlist_updater.h>
@ -147,9 +148,6 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
EVT_CHOICE( ID_AUX_TOOLBAR_PCB_TRACK_WIDTH, PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event )
EVT_CHOICE( ID_AUX_TOOLBAR_PCB_VIA_SIZE, PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event )
EVT_TOOL( ID_TOOLBARH_PCB_ACTION_PLUGIN_REFRESH, PCB_EDIT_FRAME::OnActionPluginRefresh )
EVT_TOOL( ID_TOOLBARH_PCB_ACTION_PLUGIN_SHOW_FOLDER, PCB_EDIT_FRAME::OnActionPluginShowFolder )
// Tracks and vias sizes general options
EVT_MENU_RANGE( ID_POPUP_PCB_SELECT_WIDTH_START_RANGE, ID_POPUP_PCB_SELECT_WIDTH_END_RANGE,
PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event )
@ -496,6 +494,7 @@ void PCB_EDIT_FRAME::setupTools()
m_toolManager->RegisterTool( new PCB_VIEWER_TOOLS );
m_toolManager->RegisterTool( new CONVERT_TOOL );
m_toolManager->RegisterTool( new GROUP_TOOL );
m_toolManager->RegisterTool( new SCRIPTING_TOOL );
m_toolManager->InitTools();
// Run the selection tool, it is supposed to be always active
@ -1498,43 +1497,6 @@ void PCB_EDIT_FRAME::RunEeschema()
}
void PCB_EDIT_FRAME::PythonPluginsReload()
{
// Reload Python plugins if they are newer than the already loaded, and load new plugins
// Remove all action plugins so that we don't keep references to old versions
ACTION_PLUGINS::UnloadAll();
// Reload plugin list: reload Python plugins if they are newer than the already loaded,
// and load new plugins
PythonPluginsReloadBase();
// Action plugins can be modified, therefore the plugins menu must be updated:
ReCreateMenuBar();
// Recreate top toolbar to add action plugin buttons
ReCreateHToolbar();
}
void PCB_EDIT_FRAME::PythonPluginsShowFolder()
{
#ifdef __WXMAC__
wxString msg;
// Quote in case there are spaces in the path.
msg.Printf( "open \"%s\"", PyPluginsPath( true ) );
system( msg.c_str() );
#else
wxString pypath( PyPluginsPath( true ) );
// Quote in case there are spaces in the path.
AddDelimiterString( pypath );
wxLaunchDefaultApplication( pypath );
#endif
}
void PCB_EDIT_FRAME::PythonSyncEnvironmentVariables()
{
const ENV_VAR_MAP& vars = Pgm().GetLocalEnvVariables();

View File

@ -93,12 +93,6 @@ public:
*/
bool IsContentModified() const override;
/**
* Reload the Python plugins if they are newer than the already loaded, and load new
* plugins if any.
*/
void PythonPluginsReload();
/**
* Open the plugins folder in the default system file browser.
*/

View File

@ -216,26 +216,6 @@ PGM_BASE* PgmOrNull()
}
#endif
void PythonPluginsReloadBase()
{
// Reload plugin list: reload Python plugins if they are newer than the already loaded,
// and load new plugins
char cmd[1024];
snprintf( cmd, sizeof( cmd ), "pcbnew.LoadPlugins(\"%s\", \"%s\")", TO_UTF8( PyScriptingPath() ),
TO_UTF8( PyScriptingPath( true ) ) );
PyLOCK lock;
// ReRun the Python method pcbnew.LoadPlugins (already called when starting Pcbnew)
int retv = PyRun_SimpleString( cmd );
if( retv != 0 )
wxLogError( "Python error %d occurred running command:\n\n`%s`", retv, cmd );
}
/// The global footprint library table. This is not dynamically allocated because
/// in a multiple project environment we must keep its address constant (since it is
/// the fallback table for multiple projects).

View File

@ -33,14 +33,4 @@
#define TEXTS_MAX_WIDTH Mils2iu( 10000 ) ///< Maximum text width in internal units (10 inches)
/**
* Helper function PythonPluginsReloadBase
* Reload Python plugins if they are newer than
* the already loaded, and load new plugins if any
* It calls the LoadPlugins(bundlepath) Python method
* see kicadplugins.i
*/
void PythonPluginsReloadBase();
#endif // PCBNEW_H

View File

@ -88,8 +88,6 @@ enum pcbnew_ids
ID_GEN_EXPORT_FILE_GENCADFORMAT,
ID_TOOLBARH_PCB_ACTION_PLUGIN,
ID_TOOLBARH_PCB_ACTION_PLUGIN_REFRESH,
ID_TOOLBARH_PCB_ACTION_PLUGIN_SHOW_FOLDER,
ID_PCB_GEN_CMP_FILE,
ID_PCB_GEN_BOM_FILE_FROM_BOARD,

View File

@ -0,0 +1,155 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* 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:
* http://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 "pcb_scripting_tool.h"
#include <action_plugin.h>
#include <gestfich.h>
#include <kiface_ids.h>
#include <kiway.h>
#include <python_scripting.h>
#include <tools/pcb_actions.h>
#include <pybind11/eval.h>
#include <Python.h>
#include <wx/string.h>
using initfunc = PyObject* (*)(void);
SCRIPTING_TOOL::SCRIPTING_TOOL() :
PCB_TOOL_BASE( "pcbnew.ScriptingTool" )
{}
SCRIPTING_TOOL::~SCRIPTING_TOOL()
{}
void SCRIPTING_TOOL::Reset( RESET_REASON aReason )
{
}
bool SCRIPTING_TOOL::Init()
{
PyLOCK lock;
PyObject* mod_name = PyUnicode_FromString( "_pcbnew" );
if( PyObject* existing_mod = PyImport_GetModule( mod_name ) )
{
Py_DecRef( existing_mod );
}
else
{
KIFACE* kiface = frame()->Kiway().KiFACE( KIWAY::FACE_PCB );
initfunc pcbnew_init = reinterpret_cast<initfunc>( kiface->IfaceOrAddress( KIFACE_SCRIPTING_LEGACY ) );
PyImport_AddModule( "_pcbnew" );
PyObject* mod = pcbnew_init();
PyObject* sys_mod = PyImport_GetModuleDict();
PyDict_SetItemString( sys_mod, "_pcbnew", mod );
Py_DECREF( mod );
}
Py_DecRef( mod_name );
// Load pcbnew inside Python and load all the user plugins and package-based plugins
{
using namespace pybind11::literals;
auto locals = pybind11::dict( "sys_path"_a = TO_UTF8( SCRIPTING::PyScriptingPath( false ) ),
"user_path"_a = TO_UTF8( SCRIPTING::PyScriptingPath( true ) ) );
pybind11::exec( R"(
import sys
import pcbnew
pcbnew.LoadPlugins( sys_path, user_path )
)", pybind11::globals(), locals );
}
return true;
}
int SCRIPTING_TOOL::reloadPlugins( const TOOL_EVENT& aEvent )
{
if( !m_isFootprintEditor )
// Reload Python plugins if they are newer than the already loaded, and load new plugins
// Remove all action plugins so that we don't keep references to old versions
ACTION_PLUGINS::UnloadAll();
{
PyLOCK lock;
using namespace pybind11::literals;
auto locals = pybind11::dict( "sys_path"_a = SCRIPTING::PyScriptingPath( false ),
"user_path"_a = SCRIPTING::PyScriptingPath( true ) );
pybind11::exec( R"(
import sys
import pcbnew
pcbnew.LoadPlugins( sys_path, user_path )
)", pybind11::globals(), locals );
}
if( !m_isFootprintEditor )
{
// Action plugins can be modified, therefore the plugins menu must be updated:
frame()->ReCreateMenuBar();
// Recreate top toolbar to add action plugin buttons
frame()->ReCreateHToolbar();
}
return 0;
}
int SCRIPTING_TOOL::showPluginFolder( const TOOL_EVENT& aEvent )
{
#ifdef __WXMAC__
wxString msg;
// Quote in case there are spaces in the path.
msg.Printf( "open \"%s\"", SCRIPTING::PyPluginsPath( true ) );
system( msg.c_str() );
#else
wxString pypath( SCRIPTING::PyPluginsPath( true ) );
// Quote in case there are spaces in the path.
AddDelimiterString( pypath );
wxLaunchDefaultApplication( pypath );
#endif
return 0;
}
void SCRIPTING_TOOL::setTransitions()
{
Go( &SCRIPTING_TOOL::reloadPlugins, PCB_ACTIONS::pluginsReload.MakeEvent() );
Go( &SCRIPTING_TOOL::showPluginFolder, PCB_ACTIONS::pluginsShowFolder.MakeEvent() );
}

View File

@ -0,0 +1,61 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* 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:
* http://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 PCBNEW_PCB_SCRIPTING_TOOL_H_
#define PCBNEW_PCB_SCRIPTING_TOOL_H_
#include <tools/pcb_tool_base.h>
class ACTION_MENU;
/**
* Tool relating to pads and pad settings.
*/
class SCRIPTING_TOOL : public PCB_TOOL_BASE
{
public:
SCRIPTING_TOOL();
~SCRIPTING_TOOL();
///< React to model/view changes
void Reset( RESET_REASON aReason ) override;
///< Basic initialization
bool Init() override;
private:
///< Reload Python plugins and reset toolbar (if in pcbnew)
int reloadPlugins( const TOOL_EVENT& aEvent );
///< Open the user's plugin folder in the system browser
int showPluginFolder( const TOOL_EVENT& aEvent );
///< Bind handlers to corresponding TOOL_ACTIONs.
void setTransitions() override;
};
#endif /* PCBNEW_PCB_SCRIPTING_TOOL_H_ */

View File

@ -197,6 +197,7 @@ void PCB_EDIT_FRAME::OnActionPluginMenu( wxCommandEvent& aEvent )
RunActionPlugin( actionPlugin );
}
void PCB_EDIT_FRAME::OnActionPluginButton( wxCommandEvent& aEvent )
{
ACTION_PLUGIN* actionPlugin = ACTION_PLUGINS::GetActionByButton( aEvent.GetId() );

View File

@ -49,35 +49,6 @@
#include <config.h>
/**
* Initialize the python environment and publish the Pcbnew interface inside it.
*
* This initializes all the wxPython interface and returns the python thread control structure
*/
bool pcbnewInitPythonScripting( const char* aStockScriptingPath, const char* aUserScriptingPath )
{
int retv;
char cmd[1024];
// Load pcbnew inside Python and load all the user plugins and package-based plugins
{
PyLOCK lock;
// Load os so that we can modify the environment variables through python
snprintf( cmd, sizeof( cmd ), "import sys, os, traceback\n"
"sys.path.append(\".\")\n"
"import pcbnew\n"
"pcbnew.LoadPlugins(\"%s\", \"%s\")",
aStockScriptingPath, aUserScriptingPath );
retv = PyRun_SimpleString( cmd );
if( retv != 0 )
wxLogError( "Python error %d occurred running command:\n\n`%s`", retv, cmd );
}
return true;
}
/**
* Run a python method from the pcbnew module.

View File

@ -27,11 +27,6 @@
#include <wx/string.h>
/**
* Initialize the Python engine inside pcbnew.
*/
bool pcbnewInitPythonScripting( const char* aStockScriptingPath, const char* aUserScriptingPath );
/**
* Collect the list of python scripts which could not be loaded.
*

View File

@ -539,6 +539,22 @@ TOOL_ACTION PCB_ACTIONS::defaultPadProperties( "pcbnew.PadTool.defaultPadPropert
BITMAPS::options_pad );
// SCRIPTING TOOL
//
TOOL_ACTION PCB_ACTIONS::pluginsReload( "pcbnew.ScriptingTool.pluginsReload",
AS_GLOBAL, 0, "",
_( "Refresh Plugins" ), _( "Reload all python plugins and refresh plugin menus" ),
BITMAPS::reload );
TOOL_ACTION PCB_ACTIONS::pluginsShowFolder( "pcbnew.ScriptingTool.pluginsShowFolder",
AS_GLOBAL, 0, "",
#ifdef __WXMAC__
_( "Reveal Plugin Folder in Finder" ), _( "Reveals the plugins folder in a Finder window" ),
#else
_( "Open Plugin Directory" ), _( "Opens the directory in the default system file manager" ),
#endif
BITMAPS::directory_open );
// BOARD_EDITOR_CONTROL
//
TOOL_ACTION PCB_ACTIONS::boardSetup( "pcbnew.EditorControl.boardSetup",

View File

@ -315,6 +315,10 @@ public:
/// Duplicate zone onto another layer
static TOOL_ACTION zoneDuplicate;
/// Scripting Actions
static TOOL_ACTION pluginsReload;
static TOOL_ACTION pluginsShowFolder;
// Global edit tool
static TOOL_ACTION boardSetup;
static TOOL_ACTION editTracksAndVias;

View File

@ -41,7 +41,6 @@
#include <macros.h>
#include <kiface_ids.h>
#include <kiway.h>
#include <paths.h>
#include <pgm_base.h>
#include <settings/settings_manager.h>
@ -52,22 +51,15 @@
#include <config.h>
using initfunc = PyObject* (*)(void);
SCRIPTING::SCRIPTING( KIWAY* aKiway )
SCRIPTING::SCRIPTING()
{
int retv;
char cmd[1024];
scriptingSetup();
KIFACE* pcbnew_kiface = nullptr;
pcbnew_kiface = aKiway->KiFACE( KIWAY::FACE_PCB );
initfunc pcbnew_init = reinterpret_cast<initfunc>( pcbnew_kiface->IfaceOrAddress( KIFACE_SCRIPTING_LEGACY ) );
PyImport_AppendInittab( "_pcbnew", pcbnew_init );
#ifdef _MSC_VER
// Under vcpkg/msvc, we need to explicitly set the python home
// or else it'll start consuming system python registry keys and the like instead
@ -85,35 +77,12 @@ SCRIPTING::SCRIPTING( KIWAY* aKiway )
Py_SetPythonHome( pyHome.GetFullPath().c_str() );
}
#endif
//
// Py_Initialize();
pybind11::initialize_interpreter();
// PySys_SetArgv( Pgm().App().argc, Pgm().App().argv );
#if PY_VERSION_HEX < 0x03070000 // PyEval_InitThreads() is called by Py_Initialize() starting with version 3.7
PyEval_InitThreads();
#endif // if PY_VERSION_HEX < 0x03070000
// Save the current Python thread state and release the
// Global Interpreter Lock.
m_python_thread_state = PyEval_SaveThread();
// Load pcbnew inside Python and load all the user plugins and package-based plugins
{
PyLOCK lock;
// Load os so that we can modify the environment variables through python
snprintf( cmd, sizeof( cmd ), "import sys, os, traceback\n"
"sys.path.append(\".\")\n"
"import pcbnew\n"
"pcbnew.LoadPlugins(\"%s\", \"%s\")",
TO_UTF8( PyScriptingPath() ), TO_UTF8( PyScriptingPath( true) ) );
retv = PyRun_SimpleString( cmd );
if( retv != 0 )
wxLogError( "Python error %d occurred running command:\n\n`%s`", retv, cmd );
}
}
SCRIPTING::~SCRIPTING()
@ -316,6 +285,7 @@ void UpdatePythonEnvVar( const wxString& aVar, const wxString& aValue )
snprintf( cmd, sizeof( cmd ),
"# coding=utf-8\n" // The values could potentially be UTF8
"import os\n"
"os.environ[\"%s\"]=\"%s\"\n",
TO_UTF8( escapedVar ),
TO_UTF8( escapedVal ) );
@ -444,7 +414,7 @@ wxString PyErrStringWithTraceback()
/**
* Find the Python scripting path.
*/
wxString PyScriptingPath( bool aUserPath )
wxString SCRIPTING::PyScriptingPath( bool aUserPath )
{
wxString path;
@ -471,7 +441,7 @@ wxString PyScriptingPath( bool aUserPath )
}
wxString PyPluginsPath( bool aUserPath )
wxString SCRIPTING::PyPluginsPath( bool aUserPath )
{
// Note we are using unix path separator, because window separator sometimes
// creates issues when passing a command string to a python method by PyRun_SimpleString

View File

@ -45,12 +45,10 @@
#include <wx/string.h>
#include <wx/arrstr.h>
class KIWAY;
class SCRIPTING
{
public:
SCRIPTING( KIWAY* aKiway );
SCRIPTING();
~SCRIPTING();
/// We do not allow secondary creation of the scripting system
@ -59,13 +57,14 @@ public:
static bool IsWxAvailable();
static wxString PyScriptingPath( bool aUserPath = false );
static wxString PyPluginsPath( bool aUserPath = false );
private:
bool scriptingSetup();
PyThreadState* m_python_thread_state;
KIWAY* aKiway;
};
/**
@ -93,7 +92,4 @@ wxString PyStringToWx( PyObject* str );
wxArrayString PyArrayStringToWx( PyObject* arr );
wxString PyErrStringWithTraceback();
wxString PyScriptingPath( bool aUserPath = false );
wxString PyPluginsPath( bool aUserPath = false );
#endif // __PYTHON_SCRIPTING_H