diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index 2173b8c01e..179517c169 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -315,6 +315,7 @@ bool PCB_EDIT_FRAME::Files_io_from_id( int id ) ProjectFileExtension ); Prj().SetProjectFullName( fn.GetFullPath() ); + PythonSyncProjectName(); fn.SetExt( PcbFileExtension ); @@ -461,6 +462,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in // it knows what consequences that will have on other KIFACEs running and using // this same PROJECT. It can be very harmful if that calling code is stupid. Prj().SetProjectFullName( pro.GetFullPath() ); + PythonSyncProjectName(); // load project settings before BOARD LoadProjectSettings(); diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 0eae92cded..bcd26ed01f 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -454,6 +454,10 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : enableGALSpecificMenus(); + // Ensure the Python interpreter is up to date with its environment variables + PythonSyncEnvironmentVariables(); + PythonSyncProjectName(); + // disable Export STEP item if kicad2step does not exist wxString strK2S = Pgm().GetExecutablePath(); @@ -1138,6 +1142,10 @@ void PCB_EDIT_FRAME::OnConfigurePaths( wxCommandEvent& aEvent ) { DIALOG_CONFIGURE_PATHS dlg( this, Prj().Get3DCacheManager()->GetResolver() ); dlg.ShowModal(); + + // Ensure the Python interpreter is up to date with its environment variables + PythonSyncEnvironmentVariables(); + PythonSyncProjectName(); } @@ -1270,6 +1278,29 @@ void PCB_EDIT_FRAME::PythonPluginsReload() } +void PCB_EDIT_FRAME::PythonSyncEnvironmentVariables() +{ +#if defined( KICAD_SCRIPTING ) + const ENV_VAR_MAP& varMap = Pgm().GetLocalEnvVariables(); + + for( ENV_VAR_MAP_CITER it = varMap.begin(); it != varMap.end(); ++it ) + { + pcbnewUpdatePythonEnvVar( it->first, it->second.GetValue() ); + } +#endif +} + + +void PCB_EDIT_FRAME::PythonSyncProjectName() +{ +#if defined( KICAD_SCRIPTING ) + wxString evValue; + wxGetEnv( PROJECT_VAR_NAME, &evValue ); + pcbnewUpdatePythonEnvVar( wxString( PROJECT_VAR_NAME ).ToStdString(), evValue ); +#endif +} + + void PCB_EDIT_FRAME::InstallFootprintPropertiesDialog( MODULE* Module, wxDC* DC ) { if( Module == NULL ) diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index d27551cb00..604b9a3c3b 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -312,6 +312,18 @@ public: */ void PythonPluginsReload(); + /** + * Synchronize the environment variables from KiCad's environment into the Python interpreter. + * Do nothing if KICAD_SCRIPTING is not defined. + */ + void PythonSyncEnvironmentVariables(); + + /** + * Synchronize the project name from KiCad's environment into the Python interpreter. + * Do nothing if KICAD_SCRIPTING is not defined. + */ + void PythonSyncProjectName(); + /** * Update the layer manager and other widgets from the board setup * (layer and items visibility, colors ...) diff --git a/pcbnew/swig/python_scripting.cpp b/pcbnew/swig/python_scripting.cpp index 3cbb342f0a..484cb55ed5 100644 --- a/pcbnew/swig/python_scripting.cpp +++ b/pcbnew/swig/python_scripting.cpp @@ -210,7 +210,8 @@ bool pcbnewInitPythonScripting( const char * aUserScriptingPath ) { PyLOCK lock; - snprintf( cmd, sizeof( cmd ), "import sys, traceback\n" + // 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\")", aUserScriptingPath ); @@ -318,6 +319,29 @@ void pcbnewFinishPythonScripting() } +void pcbnewUpdatePythonEnvVar( const wxString& aVar, const wxString& aValue ) +{ + char cmd[1024]; + + // Ensure the interpreter is initalized before we try to interact with it + if( !Py_IsInitialized() ) + return; + + snprintf( cmd, sizeof( cmd ), + "# coding=utf-8\n" // The values could potentially be UTF8 + "os.environ[\"%s\"]=\"%s\"\n", + TO_UTF8( aVar ), + TO_UTF8( aValue ) ); + + PyLOCK lock; + + int retv = PyRun_SimpleString( cmd ); + + if( retv != 0 ) + wxLogError( "Python error %d occurred running command:\n\n`%s`", retv, cmd ); +} + + #if defined( KICAD_SCRIPTING_WXPYTHON ) void RedirectStdio() { diff --git a/pcbnew/swig/python_scripting.h b/pcbnew/swig/python_scripting.h index 369d50c8d4..d210c671c3 100644 --- a/pcbnew/swig/python_scripting.h +++ b/pcbnew/swig/python_scripting.h @@ -78,6 +78,14 @@ void pcbnewGetScriptsSearchPaths( wxString& aNames ); */ void pcbnewGetWizardsBackTrace( wxString& aNames ); +/** + * Set an environment variable in the current Python interpreter. + * + * @param aVar is the variable to set + * @param aValue is the value to give it + */ +void pcbnewUpdatePythonEnvVar( const wxString& aVar, const wxString& aValue ); + #ifdef KICAD_SCRIPTING_WXPYTHON void RedirectStdio(); wxWindow* CreatePythonShellWindow( wxWindow* parent, const wxString& aFramenameId );