62#if defined( __WXGTK__ ) || defined( __WXMSW__ )
124 [&]() -> nlohmann::json
126 nlohmann::json ret = {};
128 for(
const std::pair<wxString, ENV_VAR_ITEM> entry :
m_Env.
vars )
130 const ENV_VAR_ITEM& var = entry.second;
132 wxASSERT( entry.first == var.GetKey() );
135 if( var.IsDefault() )
137 wxLogTrace( traceEnvVars,
138 wxS(
"COMMON_SETTINGS: Env var %s skipping save (default)" ),
143 wxString value = var.GetValue();
147 if( var.GetDefinedExternally() )
149 if( var.GetDefinedInSettings() )
151 wxLogTrace( traceEnvVars,
152 wxS(
"COMMON_SETTINGS: Env var %s was overridden "
153 "externally, saving previously-loaded value %s" ),
154 var.GetKey(), var.GetSettingsValue() );
155 value = var.GetSettingsValue();
159 wxLogTrace( traceEnvVars,
160 wxS(
"COMMON_SETTINGS: Env var %s skipping save "
168 wxS(
"COMMON_SETTINGS: Saving env var %s = %s" ),
169 var.GetKey(), value);
171 std::string key( var.GetKey().ToUTF8() );
172 ret[ std::move( key ) ] = value;
177 [&](
const nlohmann::json& aJson )
179 if( !aJson.is_object() )
182 for(
const auto& entry : aJson.items() )
184 wxString key = wxString( entry.key().c_str(), wxConvUTF8 );
185 wxString val = entry.value().get<wxString>();
187 if( m_Env.vars.count( key ) )
189 if( m_Env.vars[key].GetDefinedExternally() )
192 wxS(
"COMMON_SETTINGS: %s is defined externally" ),
194 m_Env.vars[key].SetDefinedInSettings();
195 m_Env.vars[key].SetSettingsValue( val );
201 wxS(
"COMMON_SETTINGS: Updating %s: %s -> %s"),
202 key, m_Env.vars[key].GetValue(), val );
203 m_Env.vars[key].SetValue( val );
209 wxS(
"COMMON_SETTINGS: Loaded new var: %s = %s" ),
214 m_Env.vars[key].SetDefinedInSettings();
215 m_Env.vars[key].SetSettingsValue( val );
220 m_params.emplace_back(
new PARAM<bool>(
"input.focus_follow_sch_pcb",
221 &m_Input.focus_follow_sch_pcb,
false ) );
223 m_params.emplace_back(
new PARAM<bool>(
"input.auto_pan", &m_Input.auto_pan,
false ) );
225 m_params.emplace_back(
new PARAM<int>(
"input.auto_pan_acceleration",
226 &m_Input.auto_pan_acceleration, 5 ) );
228 m_params.emplace_back(
new PARAM<bool>(
"input.center_on_zoom",
229 &m_Input.center_on_zoom,
true ) );
231 m_params.emplace_back(
new PARAM<bool>(
"input.immediate_actions",
232 &m_Input.immediate_actions,
true ) );
234 m_params.emplace_back(
new PARAM<bool>(
"input.warp_mouse_on_move",
235 &m_Input.warp_mouse_on_move,
true ) );
237 m_params.emplace_back(
new PARAM<bool>(
"input.horizontal_pan",
238 &m_Input.horizontal_pan,
false ) );
240 m_params.emplace_back(
new PARAM<bool>(
"input.hotkey_feedback",
241 &m_Input.hotkey_feedback,
true ) );
243 m_params.emplace_back(
new PARAM<bool>(
"input.zoom_acceleration",
244 &m_Input.zoom_acceleration,
false ) );
247 int default_zoom_speed = 5;
249 int default_zoom_speed = 1;
252 m_params.emplace_back(
new PARAM<int>(
"input.zoom_speed",
253 &m_Input.zoom_speed, default_zoom_speed ) );
255 m_params.emplace_back(
new PARAM<bool>(
"input.zoom_speed_auto",
256 &m_Input.zoom_speed_auto,
true ) );
258 m_params.emplace_back(
new PARAM<int>(
"input.scroll_modifier_zoom",
259 &m_Input.scroll_modifier_zoom, 0 ) );
261 m_params.emplace_back(
new PARAM<int>(
"input.scroll_modifier_pan_h",
262 &m_Input.scroll_modifier_pan_h, WXK_CONTROL ) );
264 m_params.emplace_back(
new PARAM<int>(
"input.scroll_modifier_pan_v",
265 &m_Input.scroll_modifier_pan_v, WXK_SHIFT ) );
267 m_params.emplace_back(
new PARAM<bool>(
"input.reverse_scroll_pan_h",
268 &m_Input.reverse_scroll_pan_h,
false ) );
282 m_params.emplace_back(
new PARAM<int>(
"graphics.opengl_antialiasing_mode",
283 &m_Graphics.opengl_aa_mode, 1, 0, 2 ) );
285 m_params.emplace_back(
new PARAM<int>(
"graphics.cairo_antialiasing_mode",
286 &m_Graphics.cairo_aa_mode, 0, 0, 2 ) );
288 m_params.emplace_back(
new PARAM<int>(
"system.autosave_interval",
289 &m_System.autosave_interval, 600 ) );
293 &m_System.text_editor, wxS(
"/usr/bin/open -e" ) ) );
296 &m_System.text_editor, wxS(
"" ) ) );
299 m_params.emplace_back(
new PARAM<int>(
"system.file_history_size",
300 &m_System.file_history_size, 9 ) );
303 &m_System.language, wxS(
"Default" ) ) );
306 &m_System.pdf_viewer_name, wxS(
"" ) ) );
308 m_params.emplace_back(
new PARAM<bool>(
"system.use_system_pdf_viewer",
309 &m_System.use_system_pdf_viewer,
true ) );
312 &m_System.working_dir, wxS(
"" ) ) );
314 m_params.emplace_back(
new PARAM<int>(
"system.clear_3d_cache_interval",
315 &m_System.clear_3d_cache_interval, 30 ) );
317 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.zone_fill_warning",
318 &m_DoNotShowAgain.zone_fill_warning,
false ) );
320 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.env_var_overwrite_warning",
321 &m_DoNotShowAgain.env_var_overwrite_warning,
false ) );
323 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.scaled_3d_models_warning",
324 &m_DoNotShowAgain.scaled_3d_models_warning,
false ) );
326 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.data_collection_prompt",
327 &m_DoNotShowAgain.data_collection_prompt,
false ) );
329 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.update_check_prompt",
330 &m_DoNotShowAgain.update_check_prompt,
false ) );
332 m_params.emplace_back(
new PARAM<bool>(
"session.remember_open_files",
333 &m_Session.remember_open_files,
false ) );
336 &m_Session.pinned_symbol_libs, {} ) );
339 &m_Session.pinned_fp_libs, {} ) );
341 m_params.emplace_back(
new PARAM<int>(
"netclass_panel.sash_pos",
342 &m_NetclassPanel.sash_pos, 160 ) );
344 m_params.emplace_back(
new PARAM<wxString>(
"netclass_panel.eeschema_shown_columns",
345 &m_NetclassPanel.eeschema_visible_columns,
"0 10 11 12 13" ) );
347 m_params.emplace_back(
new PARAM<wxString>(
"netclass_panel.pcbnew_shown_columns",
348 &m_NetclassPanel.pcbnew_visible_columns,
"0 1 2 3 4 5 6 7 8 9" ) );
350 m_params.emplace_back(
new PARAM<int>(
"package_manager.sash_pos",
351 &m_PackageManager.sash_pos, 380 ) );
354 [&]() -> nlohmann::json
356 nlohmann::json ret = {};
358 for(
const GIT_REPOSITORY& repo : m_Git.repositories )
360 nlohmann::json repoJson = {};
362 repoJson[
"name"] = repo.name;
363 repoJson[
"path"] = repo.path;
364 repoJson[
"authType"] = repo.authType;
365 repoJson[
"username"] = repo.username;
366 repoJson[
"ssh_path"] = repo.ssh_path;
367 repoJson[
"active"] = repo.active;
369 ret.push_back( repoJson );
374 [&](
const nlohmann::json& aJson )
376 if( !aJson.is_array() )
379 m_Git.repositories.clear();
381 for(
const auto& repoJson : aJson )
385 repo.name = repoJson[
"name"].get<wxString>();
386 repo.path = repoJson[
"path"].get<wxString>();
387 repo.authType = repoJson[
"authType"].get<wxString>();
388 repo.username = repoJson[
"username"].get<wxString>();
389 repo.ssh_path = repoJson[
"ssh_path"].get<wxString>();
390 repo.active = repoJson[
"active"].get<
bool>();
391 repo.checkValid =
true;
393 m_Git.repositories.push_back( repo );
399 &m_Git.authorName, wxS(
"" ) ) );
402 &m_Git.authorEmail, wxS(
"" ) ) );
404 m_params.emplace_back(
new PARAM<bool>(
"git.useDefaultAuthor",
405 &m_Git.useDefaultAuthor,
true ) );
408 &m_Api.python_interpreter, wxS(
"" ) ) );
410 m_params.emplace_back(
new PARAM<bool>(
"api.enable_server",
411 &m_Api.enable_server,
false ) );
427 nlohmann::json::json_pointer mwp_pointer(
"/input/mousewheel_pan"_json_pointer );
434 m_internals->At(
"input" ).erase(
"mousewheel_pan" );
438 wxLogTrace(
traceSettings, wxT(
"COMMON_SETTINGS::Migrate 0->1: mousewheel_pan not found" ) );
443 ( *m_internals )[nlohmann::json::json_pointer(
"/input/horizontal_pan" )] =
true;
445 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_pan_h" )] = WXK_SHIFT;
446 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_pan_v" )] = 0;
447 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_zoom" )] = WXK_CONTROL;
451 ( *m_internals )[nlohmann::json::json_pointer(
"/input/horizontal_pan" )] =
false;
453 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_pan_h" )] = WXK_CONTROL;
454 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_pan_v" )] = WXK_SHIFT;
455 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_zoom" )] = 0;
464 nlohmann::json::json_pointer v1_pointer(
"/input/prefer_select_to_drag"_json_pointer );
466 bool prefer_selection =
false;
471 m_internals->at( nlohmann::json::json_pointer(
"/input"_json_pointer ) ).erase(
"prefer_select_to_drag" );
475 wxLogTrace(
traceSettings, wxT(
"COMMON_SETTINGS::Migrate 1->2: prefer_select_to_drag not found" ) );
478 if( prefer_selection )
479 ( *m_internals )[nlohmann::json::json_pointer(
"/input/mouse_left" )] = MOUSE_DRAG_ACTION::SELECT;
481 ( *
m_internals )[nlohmann::json::json_pointer(
"/input/mouse_left" )] = MOUSE_DRAG_ACTION::DRAG_ANY;
491 cfgpath.AppendDir( wxT(
"3d" ) );
492 cfgpath.SetFullName( wxS(
"3Dresolver.cfg" ) );
493 cfgpath.MakeAbsolute();
495 std::vector<LEGACY_3D_SEARCH_PATH> legacyPaths;
499 wxRegEx nonValidCharsRegex( wxS(
"[^A-Z0-9_]+" ), wxRE_ADVANCED );
503 wxString key =
path.m_Alias;
504 const wxString& val =
path.m_Pathvar;
512 key.Replace( wxS(
"-" ), wxS(
"_" ) );
515 nonValidCharsRegex.Replace( &key, wxEmptyString );
519 wxLogTrace(
traceEnvVars, wxS(
"COMMON_SETTINGS: Loaded new var: %s = %s" ), key, val );
524 if( cfgpath.FileExists() )
526 wxRemoveFile( cfgpath.GetFullPath() );
537 ret &= fromLegacy<double>( aCfg,
"CanvasScale",
"appearance.canvas_scale" );
538 ret &= fromLegacy<int>( aCfg,
"IconScale",
"appearance.icon_scale" );
539 ret &= fromLegacy<bool>( aCfg,
"UseIconsInMenus",
"appearance.use_icons_in_menus" );
540 ret &= fromLegacy<bool>( aCfg,
"ShowEnvVarWarningDialog",
"environment.show_warning_dialog" );
547 nlohmann::json::json_pointer ptr =
m_internals->PointerFromString(
"environment.vars" );
549 aCfg->SetPath(
"EnvironmentVariables" );
550 ( *m_internals )[ptr] = nlohmann::json( {} );
552 while( aCfg->GetNextEntry( key, index ) )
557 wxT(
"Migrate Env: %s is blacklisted; skipping." ), key );
561 value = aCfg->Read( key, wxEmptyString );
563 if( !value.IsEmpty() )
565 ptr.push_back( key.ToStdString() );
568 ptr.to_string(), value );
569 ( *m_internals )[ptr] = value.ToUTF8();
575 aCfg->SetPath(
".." );
580 bool mousewheel_pan =
false;
582 if( aCfg->Read(
"MousewheelPAN", &mousewheel_pan ) && mousewheel_pan )
584 Set(
"input.horizontal_pan",
true );
585 Set(
"input.scroll_modifier_pan_h",
static_cast<int>( WXK_SHIFT ) );
586 Set(
"input.scroll_modifier_pan_v", 0 );
587 Set(
"input.scroll_modifier_zoom",
static_cast<int>( WXK_CONTROL ) );
590 ret &= fromLegacy<bool>( aCfg,
"AutoPAN",
"input.auto_pan" );
591 ret &= fromLegacy<bool>( aCfg,
"ImmediateActions",
"input.immediate_actions" );
592 ret &= fromLegacy<bool>( aCfg,
"PreferSelectionToDragging",
"input.prefer_select_to_drag" );
593 ret &= fromLegacy<bool>( aCfg,
"MoveWarpsCursor",
"input.warp_mouse_on_move" );
594 ret &= fromLegacy<bool>( aCfg,
"ZoomNoCenter",
"input.center_on_zoom" );
597 if( std::optional<bool> value = Get<bool>(
"input.center_on_zoom" ) )
598 Set(
"input.center_on_zoom", !( *value ) );
600 ret &= fromLegacy<int>( aCfg,
"OpenGLAntialiasingMode",
"graphics.opengl_antialiasing_mode" );
601 ret &= fromLegacy<int>( aCfg,
"CairoAntialiasingMode",
"graphics.cairo_antialiasing_mode" );
603 ret &= fromLegacy<int>( aCfg,
"AutoSaveInterval",
"system.autosave_interval" );
605 ret &= fromLegacy<int>( aCfg,
"FileHistorySize",
"system.file_history_size" );
607 ret &=
fromLegacyString( aCfg,
"PdfBrowserName",
"system.pdf_viewer_name" );
608 ret &= fromLegacy<bool>( aCfg,
"UseSystemBrowser",
"system.use_system_pdf_viewer" );
618 [&](
const wxString& aKey,
const wxString& aDefault )
624 if( wxGetEnv( aKey, &envValue ) ==
true && !envValue.IsEmpty() )
629 wxS(
"InitializeEnvironment: Entry %s defined externally as %s" ), aKey,
634 wxLogTrace(
traceEnvVars, wxS(
"InitializeEnvironment: Setting entry %s to "
642 wxFileName
path( basePath );
643 path.AppendDir( wxT(
"footprints" ) );
647 path.AppendDir( wxT(
"3dmodels" ) );
659 path.AppendDir( wxT(
"symbols" ) );
665 std::vector<LEGACY_3D_SEARCH_PATH>& aSearchPaths )
667 wxFileName cfgpath(
path );
673 wxString cfgname = cfgpath.GetFullPath();
675 std::ifstream cfgFile;
678 if( !wxFileName::Exists( cfgname ) )
680 std::ostringstream ostr;
681 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
682 wxString errmsg =
"no 3D configuration file";
683 ostr <<
" * " << errmsg.ToUTF8() <<
" '";
684 ostr << cfgname.ToUTF8() <<
"'";
689 cfgFile.open( cfgname.ToUTF8() );
691 if( !cfgFile.is_open() )
693 std::ostringstream ostr;
694 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
695 wxString errmsg = wxS(
"Could not open configuration file" );
696 ostr <<
" * " << errmsg.ToUTF8() <<
" '" << cfgname.ToUTF8() <<
"'";
697 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
706 while( cfgFile.good() )
709 std::getline( cfgFile, cfgLine );
712 if( cfgLine.empty() )
720 if( 1 == lineno && cfgLine.compare( 0, 2,
"#V" ) == 0 )
723 if( cfgLine.size() > 2 )
725 std::istringstream istr;
726 istr.str( cfgLine.substr( 2 ) );
740 wxString versionedPath = wxString::Format( wxS(
"${%s}" ),
743 if( al.
m_Alias == versionedPath || al.
m_Alias == wxS(
"${KIPRJMOD}" )
744 || al.
m_Alias == wxS(
"$(KIPRJMOD)" ) || al.
m_Alias == wxS(
"${KISYS3DMOD}" )
745 || al.
m_Alias == wxS(
"$(KISYS3DMOD)" ) )
756 aSearchPaths.push_back( al );
770 if( aIndex >= aString.size() )
772 std::ostringstream ostr;
773 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
774 wxString errmsg = wxS(
"bad Hollerith string on line" );
775 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
776 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
781 size_t i2 = aString.find(
'"', aIndex );
783 if( std::string::npos == i2 )
785 std::ostringstream ostr;
786 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
787 wxString errmsg = wxS(
"missing opening quote mark in config file" );
788 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
789 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
796 if( i2 >= aString.size() )
798 std::ostringstream ostr;
799 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
800 wxString errmsg = wxS(
"invalid entry (unexpected end of line)" );
801 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
802 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
809 while( aString[i2] >=
'0' && aString[i2] <=
'9' )
810 tnum.append( 1, aString[i2++] );
812 if( tnum.empty() || aString[i2++] !=
':' )
814 std::ostringstream ostr;
815 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
816 wxString errmsg = wxS(
"bad Hollerith string on line" );
817 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
818 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
823 std::istringstream istr;
828 if( ( i2 + nchars ) >= aString.size() )
830 std::ostringstream ostr;
831 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
832 wxString errmsg = wxS(
"invalid entry (unexpected end of line)" );
833 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
834 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
841 aResult = wxString::FromUTF8( aString.substr( i2, nchars ).c_str() );
845 if( i2 >= aString.size() || aString[i2] !=
'"' )
847 std::ostringstream ostr;
848 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
849 wxString errmsg = wxS(
"missing closing quote mark in config file" );
850 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
851 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.
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::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
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 int commonSchemaVersion
! Update the schema version whenever a migration is required
const wxRegEx versionedEnvVarRegex(wxS("KICAD[0-9]+_[A-Z0-9_]+(_DIR)?"))
! The following environment variables will never be migrated from a previous version
const wxRegEx versionedEnvVarRegex(wxS("KICAD[0-9]+_[A-Z0-9_]+(_DIR)?"))
Functions related to environment variables, including help functions.
const wxChar *const traceEnvVars
Flag to enable debug output of environment variable operations.
@ USER
The main config directory (e.g. ~/.config/kicad/)
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Constructs a versioned environment variable based on this KiCad major version.
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().