Refactor environment variable storage
CHANGED: Environment variables defined outside of KiCad will no longer be saved in the settings file. Paths can be configured via the Configure Paths dialog and those changes will be saved in the settings file if the new path is different from the default and the path variable was not defined in the system environment.
This commit is contained in:
parent
a82a693d20
commit
5b040f16a3
|
@ -229,19 +229,17 @@ bool DIALOG_CONFIGURE_PATHS::TransferDataFromWindow()
|
||||||
|
|
||||||
// Environment variables
|
// Environment variables
|
||||||
|
|
||||||
ENV_VAR_MAP envVarMap;
|
ENV_VAR_MAP& envVarMap = Pgm().GetLocalEnvVariables();
|
||||||
|
|
||||||
for( int row = 0; row < m_EnvVars->GetNumberRows(); ++row )
|
for( int row = 0; row < m_EnvVars->GetNumberRows(); ++row )
|
||||||
{
|
{
|
||||||
wxString name = m_EnvVars->GetCellValue( row, TV_NAME_COL );
|
wxString name = m_EnvVars->GetCellValue( row, TV_NAME_COL );
|
||||||
wxString path = m_EnvVars->GetCellValue( row, TV_VALUE_COL );
|
wxString path = m_EnvVars->GetCellValue( row, TV_VALUE_COL );
|
||||||
wxString external = m_EnvVars->GetCellValue( row, TV_FLAG_COL );
|
bool external = !m_EnvVars->GetCellValue( row, TV_FLAG_COL ).IsEmpty();
|
||||||
ENV_VAR_ITEM var( path );
|
|
||||||
|
|
||||||
if( external.Length() )
|
if( external )
|
||||||
{
|
{
|
||||||
// Don't check for consistency on external variables, just use them as-is
|
// Don't check for consistency on external variables, just use them as-is
|
||||||
var.SetDefinedExternally( true );
|
|
||||||
}
|
}
|
||||||
else if( name.IsEmpty() )
|
else if( name.IsEmpty() )
|
||||||
{
|
{
|
||||||
|
@ -260,10 +258,13 @@ bool DIALOG_CONFIGURE_PATHS::TransferDataFromWindow()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
envVarMap[ name ] = var;
|
if( envVarMap.count( name ) )
|
||||||
|
envVarMap.at( name ).SetValue( path );
|
||||||
|
else
|
||||||
|
envVarMap[ name ] = ENV_VAR_ITEM( name, path );
|
||||||
}
|
}
|
||||||
|
|
||||||
Pgm().SetLocalEnvVariables( envVarMap );
|
Pgm().SetLocalEnvVariables();
|
||||||
|
|
||||||
// 3D search paths
|
// 3D search paths
|
||||||
|
|
||||||
|
|
|
@ -278,148 +278,10 @@ bool PGM_BASE::InitPgm()
|
||||||
if( !m_settings_manager->IsOK() )
|
if( !m_settings_manager->IsOK() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wxFileName baseSharePath;
|
// Set up built-in environment variables (and override them from the system enviroment if set)
|
||||||
baseSharePath.AssignDir( PATHS::GetStockEDALibraryPath() );
|
GetCommonSettings()->InitializeEnvironment();
|
||||||
|
|
||||||
// KICAD6_FOOTPRINT_DIR
|
|
||||||
wxString envVarName = wxT( "KICAD6_FOOTPRINT_DIR" );
|
|
||||||
ENV_VAR_ITEM envVarItem;
|
|
||||||
wxString envValue;
|
|
||||||
wxFileName tmpFileName;
|
|
||||||
|
|
||||||
if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() )
|
|
||||||
{
|
|
||||||
tmpFileName.AssignDir( envValue );
|
|
||||||
envVarItem.SetDefinedExternally( true );
|
|
||||||
wxLogTrace( traceEnvVars, "PGM_BASE::InitPgm: Found entry %s externally", envVarName );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tmpFileName = baseSharePath;
|
|
||||||
tmpFileName.AppendDir( "modules" );
|
|
||||||
envVarItem.SetDefinedExternally( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
envVarItem.SetValue( tmpFileName.GetPath() );
|
|
||||||
wxLogTrace( traceEnvVars, "PGM_BASE::InitPgm: Setting entry %s = %s",
|
|
||||||
envVarName, envVarItem.GetValue() );
|
|
||||||
m_local_env_vars[ envVarName ] = envVarItem;
|
|
||||||
|
|
||||||
// KICAD6_3DMODEL_DIR
|
|
||||||
envVarName = wxT( "KICAD6_3DMODEL_DIR" );
|
|
||||||
|
|
||||||
if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() )
|
|
||||||
{
|
|
||||||
tmpFileName.AssignDir( envValue );
|
|
||||||
envVarItem.SetDefinedExternally( true );
|
|
||||||
wxLogTrace( traceEnvVars, "PGM_BASE::InitPgm: Found entry %s externally", envVarName );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tmpFileName = baseSharePath;
|
|
||||||
tmpFileName.AppendDir( "3dmodels" );
|
|
||||||
envVarItem.SetDefinedExternally( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
envVarItem.SetValue( tmpFileName.GetFullPath() );
|
|
||||||
wxLogTrace( traceEnvVars, "PGM_BASE::InitPgm: Setting entry %s = %s",
|
|
||||||
envVarName, envVarItem.GetValue() );
|
|
||||||
m_local_env_vars[ envVarName ] = envVarItem;
|
|
||||||
|
|
||||||
// KICAD6_TEMPLATE_DIR
|
|
||||||
envVarName = "KICAD6_TEMPLATE_DIR";
|
|
||||||
|
|
||||||
if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() )
|
|
||||||
{
|
|
||||||
tmpFileName.AssignDir( envValue );
|
|
||||||
envVarItem.SetDefinedExternally( true );
|
|
||||||
wxLogTrace( traceEnvVars, "PGM_BASE::InitPgm: Found entry %s externally", envVarName );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Attempt to find the best default template path.
|
|
||||||
SEARCH_STACK bases;
|
|
||||||
SEARCH_STACK templatePaths;
|
|
||||||
|
|
||||||
SystemDirsAppend( &bases );
|
|
||||||
|
|
||||||
for( unsigned i = 0; i < bases.GetCount(); ++i )
|
|
||||||
{
|
|
||||||
wxFileName fn( bases[i], wxEmptyString );
|
|
||||||
|
|
||||||
// Add KiCad template file path to search path list.
|
|
||||||
fn.AppendDir( "template" );
|
|
||||||
|
|
||||||
// Only add path if exists and can be read by the user.
|
|
||||||
if( fn.DirExists() && fn.IsDirReadable() )
|
|
||||||
{
|
|
||||||
wxLogTrace( tracePathsAndFiles, "Checking template path '%s' exists",
|
|
||||||
fn.GetPath() );
|
|
||||||
templatePaths.AddPaths( fn.GetPath() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( templatePaths.IsEmpty() )
|
|
||||||
{
|
|
||||||
tmpFileName = baseSharePath;
|
|
||||||
tmpFileName.AppendDir( "template" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Take the first one. There may be more but this will likely be the best option.
|
|
||||||
tmpFileName.AssignDir( templatePaths[0] );
|
|
||||||
}
|
|
||||||
|
|
||||||
envVarItem.SetDefinedExternally( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
envVarItem.SetValue( tmpFileName.GetPath() );
|
|
||||||
wxLogTrace( traceEnvVars, "PGM_BASE::InitPgm: Setting entry %s = %s", envVarName,
|
|
||||||
envVarItem.GetValue() );
|
|
||||||
m_local_env_vars[ envVarName ] = envVarItem;
|
|
||||||
|
|
||||||
// KICAD_USER_TEMPLATE_DIR
|
|
||||||
envVarName = "KICAD_USER_TEMPLATE_DIR";
|
|
||||||
|
|
||||||
if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() )
|
|
||||||
{
|
|
||||||
tmpFileName.AssignDir( envValue );
|
|
||||||
envVarItem.SetDefinedExternally( true );
|
|
||||||
wxLogTrace( traceEnvVars, "PGM_BASE::InitPgm: Found entry %s externally", envVarName );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Default user template path.
|
|
||||||
tmpFileName.AssignDir( PATHS::GetUserTemplatesPath() );
|
|
||||||
envVarItem.SetDefinedExternally( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
envVarItem.SetValue( tmpFileName.GetPath() );
|
|
||||||
wxLogTrace( traceEnvVars, "PGM_BASE::InitPgm: Setting entry %s = %s",
|
|
||||||
envVarName, envVarItem.GetValue() );
|
|
||||||
m_local_env_vars[ envVarName ] = envVarItem;
|
|
||||||
|
|
||||||
// KICAD_SYMBOLS
|
|
||||||
envVarName = wxT( "KICAD6_SYMBOL_DIR" );
|
|
||||||
|
|
||||||
if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() )
|
|
||||||
{
|
|
||||||
tmpFileName.AssignDir( envValue );
|
|
||||||
envVarItem.SetDefinedExternally( true );
|
|
||||||
wxLogTrace( traceEnvVars, "PGM_BASE::InitPgm: Found entry %s externally", envVarName );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tmpFileName = baseSharePath;
|
|
||||||
tmpFileName.AppendDir( "library" );
|
|
||||||
envVarItem.SetDefinedExternally( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
envVarItem.SetValue( tmpFileName.GetPath() );
|
|
||||||
wxLogTrace( traceEnvVars, "PGM_BASE::InitPgm: Setting entry %s = %s",
|
|
||||||
envVarName, envVarItem.GetValue() );
|
|
||||||
m_local_env_vars[ envVarName ] = envVarItem;
|
|
||||||
|
|
||||||
|
// Load common settings from disk after setting up env vars
|
||||||
GetSettingsManager().Load( GetCommonSettings() );
|
GetSettingsManager().Load( GetCommonSettings() );
|
||||||
|
|
||||||
// Init user language *before* calling loadCommonSettings, because
|
// Init user language *before* calling loadCommonSettings, because
|
||||||
|
@ -499,28 +361,26 @@ void PGM_BASE::loadCommonSettings()
|
||||||
m_show_env_var_dialog = GetCommonSettings()->m_Env.show_warning_dialog;
|
m_show_env_var_dialog = GetCommonSettings()->m_Env.show_warning_dialog;
|
||||||
m_editor_name = GetCommonSettings()->m_System.editor_name;
|
m_editor_name = GetCommonSettings()->m_System.editor_name;
|
||||||
|
|
||||||
for( const auto& it : GetCommonSettings()->m_Env.vars )
|
for( const std::pair<wxString, ENV_VAR_ITEM> it : GetCommonSettings()->m_Env.vars )
|
||||||
{
|
{
|
||||||
wxString key( it.first.c_str(), wxConvUTF8 );
|
|
||||||
wxLogTrace( traceEnvVars, "PGM_BASE::loadCommonSettings: Found entry %s = %s",
|
wxLogTrace( traceEnvVars, "PGM_BASE::loadCommonSettings: Found entry %s = %s",
|
||||||
key, it.second );
|
it.first, it.second.GetValue() );
|
||||||
|
|
||||||
// Do not store the env var PROJECT_VAR_NAME ("KIPRJMOD") definition if for some reason
|
// Do not store the env var PROJECT_VAR_NAME ("KIPRJMOD") definition if for some reason
|
||||||
// it is found in config. (It is reserved and defined as project path)
|
// it is found in config. (It is reserved and defined as project path)
|
||||||
if( key == PROJECT_VAR_NAME )
|
if( it.first == PROJECT_VAR_NAME )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( m_local_env_vars[ key ].GetDefinedExternally() )
|
// Don't set bogus empty entries in the environment
|
||||||
|
if( it.first.IsEmpty() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wxLogTrace( traceEnvVars, "PGM_BASE::loadCommonSettings: Updating entry %s = %s",
|
// Do not overwrite vars set by the system environment with values from the settings file
|
||||||
key, it.second );
|
if( it.second.GetDefinedExternally() )
|
||||||
|
continue;
|
||||||
|
|
||||||
m_local_env_vars[ key ] = ENV_VAR_ITEM( it.second, wxGetEnv( it.first, nullptr ) );
|
SetLocalEnvVariable( it.first, it.second.GetValue() );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( auto& m_local_env_var : m_local_env_vars )
|
|
||||||
SetLocalEnvVariable( m_local_env_var.first, m_local_env_var.second.GetValue() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -532,36 +392,6 @@ void PGM_BASE::SaveCommonSettings()
|
||||||
{
|
{
|
||||||
GetCommonSettings()->m_System.working_dir = wxGetCwd();
|
GetCommonSettings()->m_System.working_dir = wxGetCwd();
|
||||||
GetCommonSettings()->m_Env.show_warning_dialog = m_show_env_var_dialog;
|
GetCommonSettings()->m_Env.show_warning_dialog = m_show_env_var_dialog;
|
||||||
|
|
||||||
// remove only the old env vars that do not exist in list.
|
|
||||||
// We do not clear the full list because some are defined externally,
|
|
||||||
// and we cannot modify or delete them
|
|
||||||
std::map<std::string, wxString>& curr_vars = GetCommonSettings()->m_Env.vars;
|
|
||||||
|
|
||||||
for( auto it = curr_vars.begin(); it != curr_vars.end(); )
|
|
||||||
{
|
|
||||||
const std::string& key = it->first;
|
|
||||||
|
|
||||||
if( m_local_env_vars.find( key ) == m_local_env_vars.end() )
|
|
||||||
it = curr_vars.erase( it ); // This entry no longer exists in new list
|
|
||||||
else
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the local environment variables.
|
|
||||||
for( auto& m_local_env_var : m_local_env_vars )
|
|
||||||
{
|
|
||||||
if( m_local_env_var.second.GetDefinedExternally() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
wxLogTrace( traceEnvVars,
|
|
||||||
"PGM_BASE::SaveCommonSettings: Saving environment variable config "
|
|
||||||
"entry %s as %s",
|
|
||||||
m_local_env_var.first, m_local_env_var.second.GetValue() );
|
|
||||||
|
|
||||||
std::string key( m_local_env_var.first.ToUTF8() );
|
|
||||||
GetCommonSettings()->m_Env.vars[ key ] = m_local_env_var.second.GetValue();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -780,6 +610,14 @@ bool PGM_BASE::SetLocalEnvVariable( const wxString& aName, const wxString& aValu
|
||||||
{
|
{
|
||||||
wxString env;
|
wxString env;
|
||||||
|
|
||||||
|
if( aName.IsEmpty() )
|
||||||
|
{
|
||||||
|
wxLogTrace( traceEnvVars,
|
||||||
|
"PGM_BASE::SetLocalEnvVariable: Attempt to set empty variable to value %s",
|
||||||
|
aValue );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Check to see if the environment variable is already set.
|
// Check to see if the environment variable is already set.
|
||||||
if( wxGetEnv( aName, &env ) )
|
if( wxGetEnv( aName, &env ) )
|
||||||
{
|
{
|
||||||
|
@ -797,16 +635,11 @@ bool PGM_BASE::SetLocalEnvVariable( const wxString& aName, const wxString& aValu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PGM_BASE::SetLocalEnvVariables( const ENV_VAR_MAP& aEnvVarMap )
|
void PGM_BASE::SetLocalEnvVariables()
|
||||||
{
|
{
|
||||||
m_local_env_vars.clear();
|
|
||||||
m_local_env_vars = aEnvVarMap;
|
|
||||||
|
|
||||||
SaveCommonSettings();
|
|
||||||
|
|
||||||
// Overwrites externally defined environment variable until the next time the application
|
// Overwrites externally defined environment variable until the next time the application
|
||||||
// is run.
|
// is run.
|
||||||
for( auto& m_local_env_var : m_local_env_vars )
|
for( const std::pair<wxString, ENV_VAR_ITEM> m_local_env_var : GetCommonSettings()->m_Env.vars )
|
||||||
{
|
{
|
||||||
wxLogTrace( traceEnvVars,
|
wxLogTrace( traceEnvVars,
|
||||||
"PGM_BASE::SetLocalEnvVariables: Setting local environment variable %s to %s",
|
"PGM_BASE::SetLocalEnvVariables: Setting local environment variable %s to %s",
|
||||||
|
@ -815,3 +648,9 @@ void PGM_BASE::SetLocalEnvVariables( const ENV_VAR_MAP& aEnvVarMap )
|
||||||
wxSetEnv( m_local_env_var.first, m_local_env_var.second.GetValue() );
|
wxSetEnv( m_local_env_var.first, m_local_env_var.second.GetValue() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ENV_VAR_MAP& PGM_BASE::GetLocalEnvVariables() const
|
||||||
|
{
|
||||||
|
return GetCommonSettings()->m_Env.vars;
|
||||||
|
}
|
||||||
|
|
|
@ -19,8 +19,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include <paths.h>
|
||||||
|
#include <search_stack.h>
|
||||||
#include <settings/common_settings.h>
|
#include <settings/common_settings.h>
|
||||||
#include <settings/parameters.h>
|
#include <settings/parameters.h>
|
||||||
|
#include <systemdirsappend.h>
|
||||||
|
#include <trace_helpers.h>
|
||||||
#include <wx/config.h>
|
#include <wx/config.h>
|
||||||
#include <wx/log.h>
|
#include <wx/log.h>
|
||||||
|
|
||||||
|
@ -94,7 +99,98 @@ COMMON_SETTINGS::COMMON_SETTINGS() :
|
||||||
m_params.emplace_back( new PARAM<bool>( "environment.show_warning_dialog",
|
m_params.emplace_back( new PARAM<bool>( "environment.show_warning_dialog",
|
||||||
&m_Env.show_warning_dialog, false ) );
|
&m_Env.show_warning_dialog, false ) );
|
||||||
|
|
||||||
m_params.emplace_back( new PARAM_MAP<wxString>( "environment.vars", &m_Env.vars, {} ) );
|
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "environment.vars",
|
||||||
|
[&]() -> nlohmann::json
|
||||||
|
{
|
||||||
|
nlohmann::json ret = {};
|
||||||
|
|
||||||
|
for( const std::pair<wxString, ENV_VAR_ITEM> entry : m_Env.vars )
|
||||||
|
{
|
||||||
|
const ENV_VAR_ITEM& var = entry.second;
|
||||||
|
|
||||||
|
wxASSERT( entry.first == var.GetKey() );
|
||||||
|
|
||||||
|
// Default values are never persisted
|
||||||
|
if( var.IsDefault() )
|
||||||
|
{
|
||||||
|
wxLogTrace( traceEnvVars,
|
||||||
|
"COMMON_SETTINGS: Env var %s skipping save (default)",
|
||||||
|
var.GetKey() );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString value = var.GetValue();
|
||||||
|
|
||||||
|
// Vars that existed in JSON are persisted, but if they were overridden
|
||||||
|
// externally, we persist the old value (i.e. the one that was loaded from JSON)
|
||||||
|
if( var.GetDefinedExternally() )
|
||||||
|
{
|
||||||
|
if( var.GetDefinedInSettings() )
|
||||||
|
{
|
||||||
|
wxLogTrace( traceEnvVars,
|
||||||
|
"COMMON_SETTINGS: Env var %s was overridden externally, "
|
||||||
|
"saving previously-loaded value %s",
|
||||||
|
var.GetKey(), var.GetSettingsValue() );
|
||||||
|
value = var.GetSettingsValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLogTrace( traceEnvVars,
|
||||||
|
"COMMON_SETTINGS: Env var %s skipping save (external)",
|
||||||
|
var.GetKey() );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxLogTrace( traceEnvVars,
|
||||||
|
"COMMON_SETTINGS: Saving env var %s = %s",
|
||||||
|
var.GetKey(), value);
|
||||||
|
|
||||||
|
std::string key( var.GetKey().ToUTF8() );
|
||||||
|
ret[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
[&]( const nlohmann::json& aJson )
|
||||||
|
{
|
||||||
|
if( !aJson.is_object() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
for( const auto& entry : aJson.items() )
|
||||||
|
{
|
||||||
|
wxString key = wxString( entry.key().c_str(), wxConvUTF8 );
|
||||||
|
wxString val = entry.value().get<wxString>();
|
||||||
|
|
||||||
|
if( m_Env.vars.count( key ) )
|
||||||
|
{
|
||||||
|
if( m_Env.vars[key].GetDefinedExternally() )
|
||||||
|
{
|
||||||
|
wxLogTrace( traceEnvVars, "COMMON_SETTINGS: %s is defined externally",
|
||||||
|
key );
|
||||||
|
m_Env.vars[key].SetDefinedInSettings();
|
||||||
|
m_Env.vars[key].SetSettingsValue( val );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLogTrace( traceEnvVars, "COMMON_SETTINGS: Updating %s: %s -> %s",
|
||||||
|
key, m_Env.vars[key].GetValue(), val );
|
||||||
|
m_Env.vars[key].SetValue( val );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLogTrace( traceEnvVars, "COMMON_SETTINGS: Loaded new var: %s = %s",
|
||||||
|
key, val );
|
||||||
|
m_Env.vars[key] = ENV_VAR_ITEM( key, val );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Env.vars[key].SetDefinedInSettings();
|
||||||
|
m_Env.vars[key].SetSettingsValue( val );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{} ) );
|
||||||
|
|
||||||
m_params.emplace_back( new PARAM<bool>( "input.auto_pan", &m_Input.auto_pan, false ) );
|
m_params.emplace_back( new PARAM<bool>( "input.auto_pan", &m_Input.auto_pan, false ) );
|
||||||
|
|
||||||
|
@ -346,3 +442,84 @@ bool COMMON_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void COMMON_SETTINGS::InitializeEnvironment()
|
||||||
|
{
|
||||||
|
auto addVar =
|
||||||
|
[&]( const wxString& aKey, const wxString& aDefault )
|
||||||
|
{
|
||||||
|
m_Env.vars[aKey] = ENV_VAR_ITEM( aKey, aDefault, aDefault );
|
||||||
|
|
||||||
|
wxString envValue;
|
||||||
|
|
||||||
|
if( wxGetEnv( aKey, &envValue ) == true && !envValue.IsEmpty() )
|
||||||
|
{
|
||||||
|
m_Env.vars[aKey].SetValue( envValue );
|
||||||
|
m_Env.vars[aKey].SetDefinedExternally();
|
||||||
|
wxLogTrace( traceEnvVars,
|
||||||
|
"InitializeEnvironment: Entry %s defined externally as %s", aKey,
|
||||||
|
envValue );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLogTrace( traceEnvVars, "InitializeEnvironment: Setting entry %s to default %s",
|
||||||
|
aKey, aDefault );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
wxFileName basePath( PATHS::GetStockEDALibraryPath(), wxEmptyString );
|
||||||
|
|
||||||
|
wxFileName path( basePath );
|
||||||
|
path.AppendDir( wxT( "modules" ) );
|
||||||
|
addVar( wxT( "KICAD6_FOOTPRINT_DIR" ), path.GetFullPath() );
|
||||||
|
|
||||||
|
path = basePath;
|
||||||
|
path.AppendDir( wxT( "3dmodels" ) );
|
||||||
|
addVar( wxT( "KICAD6_3DMODEL_DIR" ), path.GetFullPath() );
|
||||||
|
|
||||||
|
// We don't have just one default template path, so use this logic that originally was in
|
||||||
|
// PGM_BASE::InitPgm to determine the best default template path
|
||||||
|
{
|
||||||
|
// Attempt to find the best default template path.
|
||||||
|
SEARCH_STACK bases;
|
||||||
|
SEARCH_STACK templatePaths;
|
||||||
|
|
||||||
|
SystemDirsAppend( &bases );
|
||||||
|
|
||||||
|
for( unsigned i = 0; i < bases.GetCount(); ++i )
|
||||||
|
{
|
||||||
|
wxFileName fn( bases[i], wxEmptyString );
|
||||||
|
|
||||||
|
// Add KiCad template file path to search path list.
|
||||||
|
fn.AppendDir( "template" );
|
||||||
|
|
||||||
|
// Only add path if exists and can be read by the user.
|
||||||
|
if( fn.DirExists() && fn.IsDirReadable() )
|
||||||
|
{
|
||||||
|
wxLogTrace( tracePathsAndFiles, "Checking template path '%s' exists",
|
||||||
|
fn.GetPath() );
|
||||||
|
templatePaths.AddPaths( fn.GetPath() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( templatePaths.IsEmpty() )
|
||||||
|
{
|
||||||
|
path = basePath;
|
||||||
|
path.AppendDir( "template" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Take the first one. There may be more but this will likely be the best option.
|
||||||
|
path.AssignDir( templatePaths[0] );
|
||||||
|
}
|
||||||
|
|
||||||
|
addVar( wxT( "KICAD6_TEMPLATE_DIR" ), path.GetFullPath() );
|
||||||
|
}
|
||||||
|
|
||||||
|
addVar( wxT( "KICAD_USER_TEMPLATE_DIR" ), PATHS::GetUserTemplatesPath() );
|
||||||
|
|
||||||
|
path = basePath;
|
||||||
|
path.AppendDir( wxT( "library" ) );
|
||||||
|
addVar( wxT( "KICAD6_SYMBOL_DIR" ), path.GetFullPath() );
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
#ifndef PATHS_H
|
#ifndef PATHS_H
|
||||||
#define PATHS_H
|
#define PATHS_H
|
||||||
|
|
||||||
|
#include <wx/filename.h>
|
||||||
|
#include <wx/string.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to centralize the paths used throughout kicad
|
* Helper class to centralize the paths used throughout kicad
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <search_stack.h>
|
#include <search_stack.h>
|
||||||
|
#include <settings/environment.h>
|
||||||
#include <wx/filename.h>
|
#include <wx/filename.h>
|
||||||
#include <wx/gdicmn.h>
|
#include <wx/gdicmn.h>
|
||||||
|
|
||||||
|
@ -74,46 +75,6 @@ struct LANGUAGE_DESCR
|
||||||
*/
|
*/
|
||||||
extern LANGUAGE_DESCR LanguagesList[];
|
extern LANGUAGE_DESCR LanguagesList[];
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple helper class to store environment variable values and the status of whether
|
|
||||||
* or not they were defined externally to the process created when any of the KiCad
|
|
||||||
* applications was launched.
|
|
||||||
*/
|
|
||||||
class ENV_VAR_ITEM
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ENV_VAR_ITEM( const wxString& aValue = wxEmptyString, bool aIsDefinedExternally = false ) :
|
|
||||||
m_value( aValue ),
|
|
||||||
m_isDefinedExternally( aIsDefinedExternally )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~ENV_VAR_ITEM() throw() {} // tell SWIG no exception
|
|
||||||
|
|
||||||
bool GetDefinedExternally() const { return m_isDefinedExternally; }
|
|
||||||
void SetDefinedExternally( bool aIsDefinedExternally )
|
|
||||||
{
|
|
||||||
m_isDefinedExternally = aIsDefinedExternally;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString& GetValue() const { return m_value; }
|
|
||||||
void SetValue( const wxString& aValue ) { m_value = aValue; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// The environment variable string value.
|
|
||||||
wxString m_value;
|
|
||||||
|
|
||||||
/// Flag to indicate if the environment variable was defined externally to the process.
|
|
||||||
bool m_isDefinedExternally;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef std::map<wxString, ENV_VAR_ITEM> ENV_VAR_MAP;
|
|
||||||
typedef std::map<wxString, ENV_VAR_ITEM>::iterator ENV_VAR_MAP_ITER;
|
|
||||||
typedef std::map<wxString, ENV_VAR_ITEM>::const_iterator ENV_VAR_MAP_CITER;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for data for KiCad programs.
|
* Container for data for KiCad programs.
|
||||||
*
|
*
|
||||||
|
@ -278,18 +239,13 @@ public:
|
||||||
virtual bool SetLocalEnvVariable( const wxString& aName, const wxString& aValue );
|
virtual bool SetLocalEnvVariable( const wxString& aName, const wxString& aValue );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the internal local environment variable map to \a aEnvVarMap, updates the entries
|
* Updates the local environment with the contents of the current ENV_VAR_MAP stored in the
|
||||||
* in the .kicad_common configuration file and sets the environment variable to the new
|
* COMMON_SETTINGS
|
||||||
* settings.
|
* @see GetLocalEnvVariables()
|
||||||
*
|
|
||||||
* @param aEnvVarMap is a #ENV_VAR_MAP object containing the new environment variables.
|
|
||||||
*/
|
*/
|
||||||
virtual void SetLocalEnvVariables( const ENV_VAR_MAP& aEnvVarMap );
|
virtual void SetLocalEnvVariables();
|
||||||
|
|
||||||
virtual const ENV_VAR_MAP& GetLocalEnvVariables() const
|
virtual ENV_VAR_MAP& GetLocalEnvVariables() const;
|
||||||
{
|
|
||||||
return m_local_env_vars;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a bare naked wxApp which may come from wxPython, SINGLE_TOP, or kicad.exe.
|
* Returns a bare naked wxApp which may come from wxPython, SINGLE_TOP, or kicad.exe.
|
||||||
|
@ -370,9 +326,6 @@ protected:
|
||||||
wxString m_editor_name;
|
wxString m_editor_name;
|
||||||
wxSize m_help_size;
|
wxSize m_help_size;
|
||||||
|
|
||||||
/// Local environment variable expansion settings such as KICAD6_FOOTPRINT_DIR, and KICAD6_3DMODEL_DIR.
|
|
||||||
ENV_VAR_MAP m_local_env_vars;
|
|
||||||
|
|
||||||
/// Flag to indicate if the environment variable overwrite warning dialog should be shown.
|
/// Flag to indicate if the environment variable overwrite warning dialog should be shown.
|
||||||
bool m_show_env_var_dialog;
|
bool m_show_env_var_dialog;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#ifndef _COMMON_SETTINGS_H
|
#ifndef _COMMON_SETTINGS_H
|
||||||
#define _COMMON_SETTINGS_H
|
#define _COMMON_SETTINGS_H
|
||||||
|
|
||||||
|
#include <settings/environment.h>
|
||||||
#include <settings/json_settings.h>
|
#include <settings/json_settings.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ public:
|
||||||
struct ENVIRONMENT
|
struct ENVIRONMENT
|
||||||
{
|
{
|
||||||
bool show_warning_dialog;
|
bool show_warning_dialog;
|
||||||
std::map<std::string, wxString> vars;
|
ENV_VAR_MAP vars;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct INPUT
|
struct INPUT
|
||||||
|
@ -128,6 +129,11 @@ public:
|
||||||
|
|
||||||
virtual bool MigrateFromLegacy( wxConfigBase* aLegacyConfig ) override;
|
virtual bool MigrateFromLegacy( wxConfigBase* aLegacyConfig ) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the built-in environment variables and sets their default values
|
||||||
|
*/
|
||||||
|
void InitializeEnvironment();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool migrateSchema0to1();
|
bool migrateSchema0to1();
|
||||||
bool migrateSchema1to2();
|
bool migrateSchema1to2();
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 KiCad Developers, see AUTHORS.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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KICAD_ENVIRONMENT_H
|
||||||
|
#define KICAD_ENVIRONMENT_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <wx/string.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KiCad uses environment variables internally for determining the base paths for libraries,
|
||||||
|
* templates, and other assets that can be relocated by packagers or users.
|
||||||
|
*
|
||||||
|
* Because setting environment variables is not user-friendly on most platforms, KiCad supports two
|
||||||
|
* backing stores for these internal variables: the system environment, and the settings system.
|
||||||
|
*
|
||||||
|
* We also want to make it possible to change the names and values of environment variables over
|
||||||
|
* time with minimal impact to users. Since most users do not customize these variables beyond any
|
||||||
|
* customization provided by the packager for their platform, an easy way to get this possibility
|
||||||
|
* with minimal user impact is to just not store environment variables if they match the internal
|
||||||
|
* (compiled-in) default.
|
||||||
|
*
|
||||||
|
* The way environment variables are resolved is (highest to lowest priority):
|
||||||
|
*
|
||||||
|
* 1) Variables set at runtime via the Configure Paths dialog
|
||||||
|
* 2) Variables set in the system environment
|
||||||
|
* 3) Variables loaded from the settings system (stored in COMMON_SETTINGS)
|
||||||
|
*
|
||||||
|
* For all KiCad system variables, we allow users to change the values at runtime via the Configure
|
||||||
|
* Paths dialog. If these variables were set in the system environment, we do not persist any
|
||||||
|
* changes made at runtime (and warn the user about this). If the variables were not set in the
|
||||||
|
* environment (meaning they were either the default value, or loaded from the settings system),
|
||||||
|
* we persist the changes via the settings system. Any variables that match the internal default
|
||||||
|
* are not saved in the settings, so that the internal defaults can be changed and the change will
|
||||||
|
* not be overridden by an old value cached in the settings file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple helper class to store environment variable definitions and values. This is used to
|
||||||
|
* initialize the environment variables that are built-in to KiCad, and also to store any variables
|
||||||
|
* created by the user.
|
||||||
|
*/
|
||||||
|
class ENV_VAR_ITEM
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ENV_VAR_ITEM( const wxString& aValue = wxEmptyString, bool aIsDefinedExternally = false ) :
|
||||||
|
m_value( aValue ),
|
||||||
|
m_isDefinedExternally( aIsDefinedExternally ),
|
||||||
|
m_isDefinedInSettings( false )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ENV_VAR_ITEM( const wxString& aKey, const wxString& aValue,
|
||||||
|
const wxString& aDefaultValue = wxEmptyString ) :
|
||||||
|
m_key( aKey ),
|
||||||
|
m_value( aValue ),
|
||||||
|
m_defaultValue( aDefaultValue ),
|
||||||
|
m_isBuiltin( true ),
|
||||||
|
m_isDefinedExternally( false ),
|
||||||
|
m_isDefinedInSettings( false )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~ENV_VAR_ITEM() throw() {} // tell SWIG no exception
|
||||||
|
|
||||||
|
bool GetDefinedExternally() const { return m_isDefinedExternally; }
|
||||||
|
void SetDefinedExternally( bool aIsDefinedExternally = true )
|
||||||
|
{
|
||||||
|
m_isDefinedExternally = aIsDefinedExternally;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetDefinedInSettings() const { return m_isDefinedInSettings; }
|
||||||
|
void SetDefinedInSettings( bool aDefined = true ) { m_isDefinedInSettings = aDefined; }
|
||||||
|
|
||||||
|
wxString GetKey() const { return m_key; }
|
||||||
|
|
||||||
|
const wxString& GetValue() const { return m_value; }
|
||||||
|
void SetValue( const wxString& aValue ) { m_value = aValue; }
|
||||||
|
|
||||||
|
wxString GetDefault() const { return m_defaultValue; }
|
||||||
|
|
||||||
|
wxString GetSettingsValue() const { return m_settingsValue; }
|
||||||
|
void SetSettingsValue( const wxString& aValue ) { m_settingsValue = aValue; }
|
||||||
|
|
||||||
|
bool GetBuiltin() const { return m_isBuiltin; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the variable matches its default value (always false for non-built-in vars)
|
||||||
|
* @return true if a built-in variable matches its default
|
||||||
|
*/
|
||||||
|
bool IsDefault() const
|
||||||
|
{
|
||||||
|
return m_isBuiltin && m_value == m_defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// The environment variable string key.
|
||||||
|
wxString m_key;
|
||||||
|
|
||||||
|
/// The environment variable string value.
|
||||||
|
wxString m_value;
|
||||||
|
|
||||||
|
/// The default value, for built-in variables that are always defined.
|
||||||
|
wxString m_defaultValue;
|
||||||
|
|
||||||
|
/// The value that was originally loaded from JSON
|
||||||
|
wxString m_settingsValue;
|
||||||
|
|
||||||
|
/// Set to true for KiCad built-in variables that are always defined one way or another.
|
||||||
|
bool m_isBuiltin;
|
||||||
|
|
||||||
|
/// Flag to indicate if the environment variable was defined externally to the process.
|
||||||
|
bool m_isDefinedExternally;
|
||||||
|
|
||||||
|
/// Flag to indicate if the environment variable was defined in the settings file.
|
||||||
|
bool m_isDefinedInSettings;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<wxString, ENV_VAR_ITEM> ENV_VAR_MAP;
|
||||||
|
typedef std::map<wxString, ENV_VAR_ITEM>::iterator ENV_VAR_MAP_ITER;
|
||||||
|
typedef std::map<wxString, ENV_VAR_ITEM>::const_iterator ENV_VAR_MAP_CITER;
|
||||||
|
|
||||||
|
#endif // KICAD_ENVIRONMENT_H
|
Loading…
Reference in New Issue