41 wxT(
"KICAD7_SYMBOL_DIR" ),
42 wxT(
"KICAD7_FOOTPRINT_DIR" ),
43 wxT(
"KICAD7_TEMPLATES_DIR" ),
44 wxT(
"KICAD7_3DMODEL_DIR" )
67#if defined( __WXGTK__ ) || defined( __WXMSW__ )
78#if defined( __WXGTK__ ) || defined( __WXMSW__ )
134 [&]() -> nlohmann::json
136 nlohmann::json ret = {};
138 for(
const std::pair<wxString, ENV_VAR_ITEM> entry :
m_Env.
vars )
140 const ENV_VAR_ITEM& var = entry.second;
142 wxASSERT( entry.first == var.GetKey() );
145 if( var.IsDefault() )
147 wxLogTrace( traceEnvVars,
148 wxS(
"COMMON_SETTINGS: Env var %s skipping save (default)" ),
153 wxString value = var.GetValue();
157 if( var.GetDefinedExternally() )
159 if( var.GetDefinedInSettings() )
161 wxLogTrace( traceEnvVars,
162 wxS(
"COMMON_SETTINGS: Env var %s was overridden externally, " )
163 "saving previously-loaded value %s",
164 var.GetKey(), var.GetSettingsValue() );
165 value = var.GetSettingsValue();
169 wxLogTrace( traceEnvVars,
170 wxS(
"COMMON_SETTINGS: Env var %s skipping save (external)" ),
177 wxS(
"COMMON_SETTINGS: Saving env var %s = %s" ),
178 var.GetKey(), value);
180 std::string key( var.GetKey().ToUTF8() );
186 [&](
const nlohmann::json& aJson )
188 if( !aJson.is_object() )
191 for(
const auto& entry : aJson.items() )
193 wxString key = wxString( entry.key().c_str(), wxConvUTF8 );
194 wxString val = entry.value().get<wxString>();
196 if( m_Env.vars.count( key ) )
198 if( m_Env.vars[key].GetDefinedExternally() )
200 wxLogTrace(
traceEnvVars, wxS(
"COMMON_SETTINGS: %s is defined externally" ),
202 m_Env.vars[key].SetDefinedInSettings();
203 m_Env.vars[key].SetSettingsValue( val );
208 wxLogTrace(
traceEnvVars, wxS(
"COMMON_SETTINGS: Updating %s: %s -> %s"),
209 key, m_Env.vars[key].GetValue(), val );
210 m_Env.vars[key].SetValue( val );
215 wxLogTrace(
traceEnvVars, wxS(
"COMMON_SETTINGS: Loaded new var: %s = %s" ),
220 m_Env.vars[key].SetDefinedInSettings();
221 m_Env.vars[key].SetSettingsValue( val );
226 m_params.emplace_back(
new PARAM<bool>(
"input.focus_follow_sch_pcb",
227 &m_Input.focus_follow_sch_pcb,
false ) );
229 m_params.emplace_back(
new PARAM<bool>(
"input.auto_pan", &m_Input.auto_pan,
false ) );
231 m_params.emplace_back(
new PARAM<int>(
"input.auto_pan_acceleration",
232 &m_Input.auto_pan_acceleration, 5 ) );
234 m_params.emplace_back(
new PARAM<bool>(
"input.center_on_zoom",
235 &m_Input.center_on_zoom,
true ) );
237 m_params.emplace_back(
new PARAM<bool>(
"input.immediate_actions",
238 &m_Input.immediate_actions,
true ) );
240 m_params.emplace_back(
new PARAM<bool>(
"input.warp_mouse_on_move",
241 &m_Input.warp_mouse_on_move,
true ) );
243 m_params.emplace_back(
new PARAM<bool>(
"input.horizontal_pan",
244 &m_Input.horizontal_pan,
false ) );
246 m_params.emplace_back(
new PARAM<bool>(
"input.hotkey_feedback",
247 &m_Input.hotkey_feedback,
true ) );
249 m_params.emplace_back(
new PARAM<bool>(
"input.zoom_acceleration",
250 &m_Input.zoom_acceleration,
false ) );
253 int default_zoom_speed = 5;
255 int default_zoom_speed = 1;
258 m_params.emplace_back(
new PARAM<int>(
"input.zoom_speed",
259 &m_Input.zoom_speed, default_zoom_speed ) );
261 m_params.emplace_back(
new PARAM<bool>(
"input.zoom_speed_auto",
262 &m_Input.zoom_speed_auto,
true ) );
264 m_params.emplace_back(
new PARAM<int>(
"input.scroll_modifier_zoom",
265 &m_Input.scroll_modifier_zoom, 0 ) );
267 m_params.emplace_back(
new PARAM<int>(
"input.scroll_modifier_pan_h",
268 &m_Input.scroll_modifier_pan_h, WXK_CONTROL ) );
270 m_params.emplace_back(
new PARAM<int>(
"input.scroll_modifier_pan_v",
271 &m_Input.scroll_modifier_pan_v, WXK_SHIFT ) );
273 m_params.emplace_back(
new PARAM<bool>(
"input.reverse_scroll_pan_h",
274 &m_Input.reverse_scroll_pan_h,
false ) );
288 m_params.emplace_back(
new PARAM<int>(
"graphics.opengl_antialiasing_mode",
289 &m_Graphics.opengl_aa_mode, 1, 0, 2 ) );
291 m_params.emplace_back(
new PARAM<int>(
"graphics.cairo_antialiasing_mode",
292 &m_Graphics.cairo_aa_mode, 0, 0, 2 ) );
294 m_params.emplace_back(
new PARAM<int>(
"system.autosave_interval",
295 &m_System.autosave_interval, 600 ) );
299 &m_System.text_editor, wxS(
"/usr/bin/open -e" ) ) );
302 &m_System.text_editor, wxS(
"" ) ) );
305 m_params.emplace_back(
new PARAM<int>(
"system.file_history_size",
306 &m_System.file_history_size, 9 ) );
309 &m_System.language, wxS(
"Default" ) ) );
312 &m_System.pdf_viewer_name, wxS(
"" ) ) );
314 m_params.emplace_back(
new PARAM<bool>(
"system.use_system_pdf_viewer",
315 &m_System.use_system_pdf_viewer,
true ) );
318 &m_System.working_dir, wxS(
"" ) ) );
320 m_params.emplace_back(
new PARAM<int>(
"system.clear_3d_cache_interval",
321 &m_System.clear_3d_cache_interval, 30 ) );
323 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.zone_fill_warning",
324 &m_DoNotShowAgain.zone_fill_warning,
false ) );
326 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.env_var_overwrite_warning",
327 &m_DoNotShowAgain.env_var_overwrite_warning,
false ) );
329 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.scaled_3d_models_warning",
330 &m_DoNotShowAgain.scaled_3d_models_warning,
false ) );
332 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.data_collection_prompt",
333 &m_DoNotShowAgain.data_collection_prompt,
false ) );
335 m_params.emplace_back(
new PARAM<bool>(
"session.remember_open_files",
336 &m_Session.remember_open_files,
false ) );
339 &m_Session.pinned_symbol_libs, {} ) );
342 &m_Session.pinned_fp_libs, {} ) );
344 m_params.emplace_back(
new PARAM<int>(
"netclass_panel.sash_pos",
345 &m_NetclassPanel.sash_pos, 160 ) );
347 m_params.emplace_back(
new PARAM<int>(
"package_manager.sash_pos",
348 &m_PackageManager.sash_pos, 380 ) );
364 nlohmann::json::json_pointer mwp_pointer(
"/input/mousewheel_pan"_json_pointer );
371 m_internals->At(
"input" ).erase(
"mousewheel_pan" );
375 wxLogTrace(
traceSettings, wxT(
"COMMON_SETTINGS::Migrate 0->1: mousewheel_pan not found" ) );
380 ( *m_internals )[nlohmann::json::json_pointer(
"/input/horizontal_pan" )] =
true;
382 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_pan_h" )] = WXK_SHIFT;
383 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_pan_v" )] = 0;
384 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_zoom" )] = WXK_CONTROL;
388 ( *m_internals )[nlohmann::json::json_pointer(
"/input/horizontal_pan" )] =
false;
390 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_pan_h" )] = WXK_CONTROL;
391 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_pan_v" )] = WXK_SHIFT;
392 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_zoom" )] = 0;
401 nlohmann::json::json_pointer v1_pointer(
"/input/prefer_select_to_drag"_json_pointer );
403 bool prefer_selection =
false;
408 m_internals->at( nlohmann::json::json_pointer(
"/input"_json_pointer ) ).erase(
"prefer_select_to_drag" );
412 wxLogTrace(
traceSettings, wxT(
"COMMON_SETTINGS::Migrate 1->2: prefer_select_to_drag not found" ) );
415 if( prefer_selection )
416 ( *m_internals )[nlohmann::json::json_pointer(
"/input/mouse_left" )] = MOUSE_DRAG_ACTION::SELECT;
418 ( *
m_internals )[nlohmann::json::json_pointer(
"/input/mouse_left" )] = MOUSE_DRAG_ACTION::DRAG_ANY;
428 cfgpath.AppendDir( wxT(
"3d" ) );
429 cfgpath.SetFullName( wxS(
"3Dresolver.cfg" ) );
430 cfgpath.MakeAbsolute();
432 std::vector<LEGACY_3D_SEARCH_PATH> legacyPaths;
436 wxRegEx nonValidCharsRegex( wxS(
"[^A-Z0-9_]+" ), wxRE_ADVANCED );
440 wxString key =
path.m_Alias;
441 const wxString& val =
path.m_Pathvar;
449 key.Replace( wxS(
"-" ), wxS(
"_" ) );
452 nonValidCharsRegex.Replace( &key, wxEmptyString );
456 wxLogTrace(
traceEnvVars, wxS(
"COMMON_SETTINGS: Loaded new var: %s = %s" ), key, val );
461 if( cfgpath.FileExists() )
463 wxRemoveFile( cfgpath.GetFullPath() );
474 ret &= fromLegacy<double>( aCfg,
"CanvasScale",
"appearance.canvas_scale" );
475 ret &= fromLegacy<int>( aCfg,
"IconScale",
"appearance.icon_scale" );
476 ret &= fromLegacy<bool>( aCfg,
"UseIconsInMenus",
"appearance.use_icons_in_menus" );
477 ret &= fromLegacy<bool>( aCfg,
"ShowEnvVarWarningDialog",
"environment.show_warning_dialog" );
484 nlohmann::json::json_pointer ptr =
m_internals->PointerFromString(
"environment.vars" );
486 aCfg->SetPath(
"EnvironmentVariables" );
487 ( *m_internals )[ptr] = nlohmann::json( {} );
489 while( aCfg->GetNextEntry( key, index ) )
493 wxLogTrace(
traceSettings, wxT(
"Migrate Env: %s is blacklisted; skipping." ), key );
497 value = aCfg->Read( key, wxEmptyString );
499 if( !value.IsEmpty() )
501 ptr.push_back( key.ToStdString() );
503 wxLogTrace(
traceSettings, wxT(
"Migrate Env: %s=%s" ), ptr.to_string(), value );
504 ( *m_internals )[ptr] = value.ToUTF8();
510 aCfg->SetPath(
".." );
515 bool mousewheel_pan =
false;
517 if( aCfg->Read(
"MousewheelPAN", &mousewheel_pan ) && mousewheel_pan )
519 Set(
"input.horizontal_pan",
true );
520 Set(
"input.scroll_modifier_pan_h",
static_cast<int>( WXK_SHIFT ) );
521 Set(
"input.scroll_modifier_pan_v", 0 );
522 Set(
"input.scroll_modifier_zoom",
static_cast<int>( WXK_CONTROL ) );
525 ret &= fromLegacy<bool>( aCfg,
"AutoPAN",
"input.auto_pan" );
526 ret &= fromLegacy<bool>( aCfg,
"ImmediateActions",
"input.immediate_actions" );
527 ret &= fromLegacy<bool>( aCfg,
"PreferSelectionToDragging",
"input.prefer_select_to_drag" );
528 ret &= fromLegacy<bool>( aCfg,
"MoveWarpsCursor",
"input.warp_mouse_on_move" );
529 ret &= fromLegacy<bool>( aCfg,
"ZoomNoCenter",
"input.center_on_zoom" );
532 if( std::optional<bool> value = Get<bool>(
"input.center_on_zoom" ) )
533 Set(
"input.center_on_zoom", !( *value ) );
535 ret &= fromLegacy<int>( aCfg,
"OpenGLAntialiasingMode",
"graphics.opengl_antialiasing_mode" );
536 ret &= fromLegacy<int>( aCfg,
"CairoAntialiasingMode",
"graphics.cairo_antialiasing_mode" );
538 ret &= fromLegacy<int>( aCfg,
"AutoSaveInterval",
"system.autosave_interval" );
540 ret &= fromLegacy<int>( aCfg,
"FileHistorySize",
"system.file_history_size" );
542 ret &=
fromLegacyString( aCfg,
"PdfBrowserName",
"system.pdf_viewer_name" );
543 ret &= fromLegacy<bool>( aCfg,
"UseSystemBrowser",
"system.use_system_pdf_viewer" );
553 [&](
const wxString& aKey,
const wxString& aDefault )
559 if( wxGetEnv( aKey, &envValue ) ==
true && !envValue.IsEmpty() )
564 wxS(
"InitializeEnvironment: Entry %s defined externally as %s" ), aKey,
569 wxLogTrace(
traceEnvVars, wxS(
"InitializeEnvironment: Setting entry %s to default %s" ),
576 wxFileName
path( basePath );
577 path.AppendDir( wxT(
"footprints" ) );
578 addVar( wxT(
"KICAD7_FOOTPRINT_DIR" ),
path.GetFullPath() );
581 path.AppendDir( wxT(
"3dmodels" ) );
582 addVar( wxT(
"KICAD7_3DMODEL_DIR" ),
path.GetFullPath() );
591 path.AppendDir( wxT(
"symbols" ) );
592 addVar( wxT(
"KICAD7_SYMBOL_DIR" ),
path.GetFullPath() );
597 std::vector<LEGACY_3D_SEARCH_PATH>& aSearchPaths )
599 wxFileName cfgpath(
path );
605 wxString cfgname = cfgpath.GetFullPath();
607 std::ifstream cfgFile;
610 if( !wxFileName::Exists( cfgname ) )
612 std::ostringstream ostr;
613 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
614 wxString errmsg =
"no 3D configuration file";
615 ostr <<
" * " << errmsg.ToUTF8() <<
" '";
616 ostr << cfgname.ToUTF8() <<
"'";
621 cfgFile.open( cfgname.ToUTF8() );
623 if( !cfgFile.is_open() )
625 std::ostringstream ostr;
626 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
627 wxString errmsg = wxS(
"Could not open configuration file" );
628 ostr <<
" * " << errmsg.ToUTF8() <<
" '" << cfgname.ToUTF8() <<
"'";
629 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
638 while( cfgFile.good() )
641 std::getline( cfgFile, cfgLine );
644 if( cfgLine.empty() )
652 if( 1 == lineno && cfgLine.compare( 0, 2,
"#V" ) == 0 )
655 if( cfgLine.size() > 2 )
657 std::istringstream istr;
658 istr.str( cfgLine.substr( 2 ) );
672 if( al.
m_Alias == wxS(
"${KICAD7_3DMODEL_DIR}" ) || al.
m_Alias == wxS(
"${KIPRJMOD}" )
673 || al.
m_Alias == wxS(
"$(KIPRJMOD)" ) || al.
m_Alias == wxS(
"${KISYS3DMOD}" )
674 || al.
m_Alias == wxS(
"$(KISYS3DMOD)" ) )
685 aSearchPaths.push_back( al );
699 if( aIndex >= aString.size() )
701 std::ostringstream ostr;
702 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
703 wxString errmsg = wxS(
"bad Hollerith string on line" );
704 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
705 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
710 size_t i2 = aString.find(
'"', aIndex );
712 if( std::string::npos == i2 )
714 std::ostringstream ostr;
715 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
716 wxString errmsg = wxS(
"missing opening quote mark in config file" );
717 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
718 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
725 if( i2 >= aString.size() )
727 std::ostringstream ostr;
728 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
729 wxString errmsg = wxS(
"invalid entry (unexpected end of line)" );
730 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
731 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
738 while( aString[i2] >=
'0' && aString[i2] <=
'9' )
739 tnum.append( 1, aString[i2++] );
741 if( tnum.empty() || aString[i2++] !=
':' )
743 std::ostringstream ostr;
744 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
745 wxString errmsg = wxS(
"bad Hollerith string on line" );
746 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
747 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
752 std::istringstream istr;
757 if( ( i2 + nchars ) >= aString.size() )
759 std::ostringstream ostr;
760 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
761 wxString errmsg = wxS(
"invalid entry (unexpected end of line)" );
762 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
763 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
770 aResult = wxString::FromUTF8( aString.substr( i2, nchars ).c_str() );
774 if( i2 >= aString.size() || aString[i2] !=
'"' )
776 std::ostringstream ostr;
777 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
778 wxString errmsg = wxS(
"missing closing quote mark in config file" );
779 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
780 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
static bool getLegacy3DHollerith(const std::string &aString, size_t &aIndex, wxString &aResult)
bool readLegacy3DResolverCfg(const wxString &aPath, std::vector< LEGACY_3D_SEARCH_PATH > &aSearchPaths)
void InitializeEnvironment()
Creates the built-in environment variables and sets their default values.
virtual bool MigrateFromLegacy(wxConfigBase *aLegacyConfig) override
Migrates from wxConfig to JSON-based configuration.
KiCad uses environment variables internally for determining the base paths for libraries,...
bool fromLegacyString(wxConfigBase *aConfig, const std::string &aKey, const std::string &aDest)
Translates a legacy wxConfig string value to a given JSON pointer value.
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
void Set(const std::string &aPath, ValueType aVal)
Stores a value into the JSON document Will throw an exception if ValueType isn't something that the l...
std::unique_ptr< JSON_SETTINGS_INTERNALS > m_internals
Stores an enum as an integer.
Like a normal param, but with custom getter and setter functions.
static wxString GetUserTemplatesPath()
Gets the user path for custom templates.
static wxString GetStockEDALibraryPath()
Gets the stock (install) EDA library data path, which is the base path for templates,...
static wxString GetDefault3rdPartyPath()
Gets the default path for PCM packages.
static wxString GetStockTemplatesPath()
Gets the stock (install) templates path.
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
const std::set< wxString > envVarBlacklist
! The following environment variables will never be migrated from a previous version
const int commonSchemaVersion
! Update the schema version whenever a migration is required
const wxChar *const traceEnvVars
Flag to enable debug output of environment variable operations.
const wxChar *const traceSettings
Flag to enable debug output of settings operations and management.
@ USER
The main config directory (e.g. ~/.config/kicad/)
bool apply_icon_scale_to_fonts
double hicontrast_dimming_factor
int min_interval
Minimum time, in seconds, between subsequent backups.
bool backup_on_autosave
Trigger a backup on autosave.
unsigned long long limit_total_size
Maximum total size of backups (bytes), 0 for unlimited.
int limit_total_files
Maximum number of backup archives to retain.
int limit_daily_files
Maximum files to keep per day, 0 for unlimited.
bool enabled
Automatically back up the project when files are saved.
System directories search utilities.
wxLogTrace helper definitions.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().