Ensure the environment variables are synchronized between KiCad and Python
Before this, the environment variables inside Python wouldn't reflect the updates to them made after the interpreter was started in Pcbnew. This will call into Python and set the variables when they are changed, since Python can't synchronize itself when running in an embedded interpreter. Fixes https://gitlab.com/kicad/code/kicad/issues/5071
This commit is contained in:
parent
e57499fde9
commit
c458b50fd9
|
@ -473,9 +473,9 @@ void KIWAY::SetLanguage( int aLanguage )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void KIWAY::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
|
||||
{
|
||||
#if 1
|
||||
if( m_ctl & KFCTL_CPP_PROJECT_SUITE )
|
||||
{
|
||||
// A dynamic_cast could be better, but creates link issues
|
||||
|
@ -486,7 +486,6 @@ void KIWAY::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
|
|||
if( top )
|
||||
top->CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
|
||||
}
|
||||
#endif
|
||||
|
||||
for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
|
||||
{
|
||||
|
@ -498,6 +497,29 @@ void KIWAY::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
|
|||
}
|
||||
|
||||
|
||||
void KIWAY::ProjectChanged()
|
||||
{
|
||||
if( m_ctl & KFCTL_CPP_PROJECT_SUITE )
|
||||
{
|
||||
// A dynamic_cast could be better, but creates link issues
|
||||
// (some basic_frame functions not found) on some platforms,
|
||||
// so a static_cast is used.
|
||||
EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
|
||||
|
||||
if( top )
|
||||
top->ProjectChanged();
|
||||
}
|
||||
|
||||
for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
|
||||
{
|
||||
KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
|
||||
|
||||
if( frame )
|
||||
frame->ProjectChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool KIWAY::ProcessEvent( wxEvent& aEvent )
|
||||
{
|
||||
KIWAY_EXPRESS* mail = dynamic_cast<KIWAY_EXPRESS*>( &aEvent );
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <confirm.h>
|
||||
#include <dialogs/dialog_migrate_settings.h>
|
||||
#include <gestfich.h>
|
||||
#include <kiway.h>
|
||||
#include <macros.h>
|
||||
#include <project.h>
|
||||
#include <project/project_archiver.h>
|
||||
|
@ -53,6 +54,7 @@ const char* traceSettings = "SETTINGS";
|
|||
|
||||
SETTINGS_MANAGER::SETTINGS_MANAGER( bool aHeadless ) :
|
||||
m_headless( aHeadless ),
|
||||
m_kiway( nullptr ),
|
||||
m_common_settings( nullptr ),
|
||||
m_migration_source()
|
||||
{
|
||||
|
@ -715,6 +717,9 @@ bool SETTINGS_MANAGER::LoadProject( const wxString& aFullPath, bool aSetActive )
|
|||
m_projects[fullPath]->setLocalSettings( settings );
|
||||
settings->SetProject( m_projects[fullPath].get() );
|
||||
|
||||
if( m_kiway )
|
||||
m_kiway->ProjectChanged();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -731,6 +736,12 @@ bool SETTINGS_MANAGER::UnloadProject( PROJECT* aProject, bool aSave )
|
|||
|
||||
m_projects.erase( aProject->GetProjectFullName() );
|
||||
|
||||
// Remove the reference in the environment to the previous project
|
||||
wxSetEnv( PROJECT_VAR_NAME, "" );
|
||||
|
||||
if( m_kiway )
|
||||
m_kiway->ProjectChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -359,6 +359,8 @@ bool PGM_SINGLE_TOP::OnPgmInit()
|
|||
}
|
||||
}
|
||||
|
||||
// Tell the settings manager about the current Kiway
|
||||
GetSettingsManager().SetKiway( &Kiway );
|
||||
|
||||
// Use KIWAY to create a top window, which registers its existence also.
|
||||
// "TOP_FRAME" is a macro that is passed on compiler command line from CMake,
|
||||
|
|
|
@ -496,6 +496,11 @@ public:
|
|||
*/
|
||||
void CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged ) override;
|
||||
|
||||
/**
|
||||
* Notification event that the project has changed.
|
||||
*/
|
||||
virtual void ProjectChanged() {}
|
||||
|
||||
const wxString& GetAboutTitle() const { return m_AboutTitle; }
|
||||
|
||||
/**
|
||||
|
|
|
@ -382,6 +382,12 @@ public:
|
|||
*/
|
||||
VTBL_ENTRY void CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged );
|
||||
|
||||
/**
|
||||
* Calls ProjectChanged() on all KIWAY_PLAYERs.
|
||||
* Used after changing the project to ensure all players are updated correctly.
|
||||
*/
|
||||
VTBL_ENTRY void ProjectChanged();
|
||||
|
||||
KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop = NULL );
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
class COLOR_SETTINGS;
|
||||
class COMMON_SETTINGS;
|
||||
class KIWAY;
|
||||
class PROJECT;
|
||||
class PROJECT_FILE;
|
||||
class REPORTER;
|
||||
|
@ -43,6 +44,13 @@ public:
|
|||
*/
|
||||
bool IsOK() { return m_ok; }
|
||||
|
||||
/**
|
||||
* Associate this setting manager with the given Kiway.
|
||||
*
|
||||
* @param aKiway is the kiway this settings manager should use
|
||||
*/
|
||||
void SetKiway( KIWAY* aKiway ) { m_kiway = aKiway; }
|
||||
|
||||
/**
|
||||
* Takes ownership of the pointer passed in
|
||||
* @param aSettings is a settings object to register
|
||||
|
@ -350,6 +358,9 @@ private:
|
|||
/// True if running outside a UI context
|
||||
bool m_headless;
|
||||
|
||||
/// The kiway this settings manager interacts with
|
||||
KIWAY* m_kiway;
|
||||
|
||||
std::vector<std::unique_ptr<JSON_SETTINGS>> m_settings;
|
||||
|
||||
std::unordered_map<wxString, COLOR_SETTINGS*> m_color_settings;
|
||||
|
|
|
@ -92,6 +92,7 @@ bool PGM_KICAD::OnPgmInit()
|
|||
|
||||
m_bm.InitSettings( new KICAD_SETTINGS );
|
||||
GetSettingsManager().RegisterSettings( PgmSettings() );
|
||||
GetSettingsManager().SetKiway( &Kiway );
|
||||
m_bm.Init();
|
||||
|
||||
// Add search paths to feed the PGM_KICAD::SysSearch() function,
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include <functional>
|
||||
#include <project/project_file.h>
|
||||
#include <project/net_settings.h>
|
||||
#include <settings/common_settings.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <swig/python_scripting.h>
|
||||
#include <tool/tool_manager.h>
|
||||
|
@ -323,6 +324,10 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
|||
|
||||
InitExitKey();
|
||||
|
||||
// Ensure the Python interpreter is up to date with its environment variables
|
||||
PythonSyncEnvironmentVariables();
|
||||
PythonSyncProjectName();
|
||||
|
||||
GetCanvas()->SwitchBackend( m_canvasType );
|
||||
ActivateGalCanvas();
|
||||
|
||||
|
@ -1265,6 +1270,27 @@ void PCB_EDIT_FRAME::PythonPluginsShowFolder()
|
|||
}
|
||||
|
||||
|
||||
void PCB_EDIT_FRAME::PythonSyncEnvironmentVariables()
|
||||
{
|
||||
#if defined( KICAD_SCRIPTING )
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
|
||||
for( auto& var : settings->m_Env.vars )
|
||||
pcbnewUpdatePythonEnvVar( var.first, var.second );
|
||||
#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 )
|
||||
{
|
||||
if( Module == NULL )
|
||||
|
@ -1338,11 +1364,21 @@ void PCB_EDIT_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVars
|
|||
if( aTextVarsChanged )
|
||||
GetCanvas()->GetView()->UpdateAllItems( KIGFX::ALL );
|
||||
|
||||
// Update the environment variables in the Python interpreter
|
||||
if( aEnvVarsChanged )
|
||||
PythonSyncEnvironmentVariables();
|
||||
|
||||
Layout();
|
||||
SendSizeEvent();
|
||||
}
|
||||
|
||||
|
||||
void PCB_EDIT_FRAME::ProjectChanged()
|
||||
{
|
||||
PythonSyncProjectName();
|
||||
}
|
||||
|
||||
|
||||
void PCB_EDIT_FRAME::LockModule( MODULE* aModule, bool aLocked )
|
||||
{
|
||||
const wxString ModulesMaskSelection = wxT( "*" );
|
||||
|
|
|
@ -304,6 +304,18 @@ public:
|
|||
*/
|
||||
void PythonPluginsShowFolder();
|
||||
|
||||
/**
|
||||
* 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 ...)
|
||||
|
@ -948,6 +960,8 @@ public:
|
|||
*/
|
||||
void CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged ) override;
|
||||
|
||||
void ProjectChanged() override;
|
||||
|
||||
void SyncToolbars() override;
|
||||
|
||||
wxString GetCurrentFileName() const override;
|
||||
|
|
|
@ -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,30 @@ void pcbnewFinishPythonScripting()
|
|||
}
|
||||
|
||||
|
||||
void pcbnewUpdatePythonEnvVar( const std::string& 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",
|
||||
aVar.c_str(),
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -78,6 +78,15 @@ 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 std::string& aVar, const wxString& aValue );
|
||||
|
||||
|
||||
#ifdef KICAD_SCRIPTING_WXPYTHON
|
||||
void RedirectStdio();
|
||||
wxWindow* CreatePythonShellWindow( wxWindow* parent, const wxString& aFramenameId );
|
||||
|
|
Loading…
Reference in New Issue