61#if defined( __WXGTK__ ) || defined( __WXMSW__ )
120 [&]() -> nlohmann::json
122 nlohmann::json ret = {};
124 for(
const std::pair<wxString, ENV_VAR_ITEM> entry :
m_Env.
vars )
126 const ENV_VAR_ITEM& var = entry.second;
128 wxASSERT( entry.first == var.GetKey() );
131 if( var.IsDefault() )
133 wxLogTrace( traceEnvVars,
134 wxS(
"COMMON_SETTINGS: Env var %s skipping save (default)" ),
139 wxString value = var.GetValue();
143 if( var.GetDefinedExternally() )
145 if( var.GetDefinedInSettings() )
147 wxLogTrace( traceEnvVars,
148 wxS(
"COMMON_SETTINGS: Env var %s was overridden "
149 "externally, saving previously-loaded value %s" ),
150 var.GetKey(), var.GetSettingsValue() );
151 value = var.GetSettingsValue();
155 wxLogTrace( traceEnvVars,
156 wxS(
"COMMON_SETTINGS: Env var %s skipping save "
164 wxS(
"COMMON_SETTINGS: Saving env var %s = %s" ),
165 var.GetKey(), value);
167 std::string key( var.GetKey().ToUTF8() );
168 ret[ std::move( key ) ] = value;
173 [&](
const nlohmann::json& aJson )
175 if( !aJson.is_object() )
178 for(
const auto& entry : aJson.items() )
180 wxString key = wxString( entry.key().c_str(), wxConvUTF8 );
181 wxString val = entry.value().get<wxString>();
183 if( m_Env.vars.count( key ) )
185 if( m_Env.vars[key].GetDefinedExternally() )
188 wxS(
"COMMON_SETTINGS: %s is defined externally" ),
190 m_Env.vars[key].SetDefinedInSettings();
191 m_Env.vars[key].SetSettingsValue( val );
197 wxS(
"COMMON_SETTINGS: Updating %s: %s -> %s"),
198 key, m_Env.vars[key].GetValue(), val );
199 m_Env.vars[key].SetValue( val );
205 wxS(
"COMMON_SETTINGS: Loaded new var: %s = %s" ),
210 m_Env.vars[key].SetDefinedInSettings();
211 m_Env.vars[key].SetSettingsValue( val );
216 m_params.emplace_back(
new PARAM<bool>(
"input.focus_follow_sch_pcb",
217 &m_Input.focus_follow_sch_pcb,
false ) );
219 m_params.emplace_back(
new PARAM<bool>(
"input.auto_pan", &m_Input.auto_pan,
false ) );
221 m_params.emplace_back(
new PARAM<int>(
"input.auto_pan_acceleration",
222 &m_Input.auto_pan_acceleration, 5 ) );
224 m_params.emplace_back(
new PARAM<bool>(
"input.center_on_zoom",
225 &m_Input.center_on_zoom,
true ) );
227 m_params.emplace_back(
new PARAM<bool>(
"input.immediate_actions",
228 &m_Input.immediate_actions,
true ) );
230 m_params.emplace_back(
new PARAM<bool>(
"input.warp_mouse_on_move",
231 &m_Input.warp_mouse_on_move,
true ) );
233 m_params.emplace_back(
new PARAM<bool>(
"input.horizontal_pan",
234 &m_Input.horizontal_pan,
false ) );
236 m_params.emplace_back(
new PARAM<bool>(
"input.hotkey_feedback",
237 &m_Input.hotkey_feedback,
true ) );
239 m_params.emplace_back(
new PARAM<bool>(
"input.zoom_acceleration",
240 &m_Input.zoom_acceleration,
false ) );
243 int default_zoom_speed = 5;
245 int default_zoom_speed = 1;
248 m_params.emplace_back(
new PARAM<int>(
"input.zoom_speed",
249 &m_Input.zoom_speed, default_zoom_speed ) );
251 m_params.emplace_back(
new PARAM<bool>(
"input.zoom_speed_auto",
252 &m_Input.zoom_speed_auto,
true ) );
254 m_params.emplace_back(
new PARAM<int>(
"input.scroll_modifier_zoom",
255 &m_Input.scroll_modifier_zoom, 0 ) );
257 m_params.emplace_back(
new PARAM<int>(
"input.scroll_modifier_pan_h",
258 &m_Input.scroll_modifier_pan_h, WXK_CONTROL ) );
260 m_params.emplace_back(
new PARAM<int>(
"input.scroll_modifier_pan_v",
261 &m_Input.scroll_modifier_pan_v, WXK_SHIFT ) );
263 m_params.emplace_back(
new PARAM<bool>(
"input.reverse_scroll_pan_h",
264 &m_Input.reverse_scroll_pan_h,
false ) );
278 m_params.emplace_back(
new PARAM<int>(
"graphics.opengl_antialiasing_mode",
279 &m_Graphics.opengl_aa_mode, 1, 0, 2 ) );
281 m_params.emplace_back(
new PARAM<int>(
"graphics.cairo_antialiasing_mode",
282 &m_Graphics.cairo_aa_mode, 0, 0, 2 ) );
284 m_params.emplace_back(
new PARAM<int>(
"system.autosave_interval",
285 &m_System.autosave_interval, 600 ) );
289 &m_System.text_editor, wxS(
"/usr/bin/open -e" ) ) );
292 &m_System.text_editor, wxS(
"" ) ) );
295 m_params.emplace_back(
new PARAM<int>(
"system.file_history_size",
296 &m_System.file_history_size, 9 ) );
299 &m_System.language, wxS(
"Default" ) ) );
302 &m_System.pdf_viewer_name, wxS(
"" ) ) );
304 m_params.emplace_back(
new PARAM<bool>(
"system.use_system_pdf_viewer",
305 &m_System.use_system_pdf_viewer,
true ) );
308 &m_System.working_dir, wxS(
"" ) ) );
310 m_params.emplace_back(
new PARAM<int>(
"system.clear_3d_cache_interval",
311 &m_System.clear_3d_cache_interval, 30 ) );
313 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.zone_fill_warning",
314 &m_DoNotShowAgain.zone_fill_warning,
false ) );
316 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.env_var_overwrite_warning",
317 &m_DoNotShowAgain.env_var_overwrite_warning,
false ) );
319 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.scaled_3d_models_warning",
320 &m_DoNotShowAgain.scaled_3d_models_warning,
false ) );
322 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.data_collection_prompt",
323 &m_DoNotShowAgain.data_collection_prompt,
false ) );
325 m_params.emplace_back(
new PARAM<bool>(
"do_not_show_again.update_check_prompt",
326 &m_DoNotShowAgain.update_check_prompt,
false ) );
328 m_params.emplace_back(
new PARAM<bool>(
"session.remember_open_files",
329 &m_Session.remember_open_files,
false ) );
332 &m_Session.pinned_symbol_libs, {} ) );
335 &m_Session.pinned_fp_libs, {} ) );
337 m_params.emplace_back(
new PARAM<int>(
"netclass_panel.sash_pos",
338 &m_NetclassPanel.sash_pos, 160 ) );
340 m_params.emplace_back(
new PARAM<int>(
"package_manager.sash_pos",
341 &m_PackageManager.sash_pos, 380 ) );
344 [&]() -> nlohmann::json
346 nlohmann::json ret = {};
348 for(
const GIT_REPOSITORY& repo : m_Git.repositories )
350 nlohmann::json repoJson = {};
352 repoJson[
"name"] = repo.name;
353 repoJson[
"path"] = repo.path;
354 repoJson[
"authType"] = repo.authType;
355 repoJson[
"username"] = repo.username;
356 repoJson[
"ssh_path"] = repo.ssh_path;
357 repoJson[
"active"] = repo.active;
359 ret.push_back( repoJson );
364 [&](
const nlohmann::json& aJson )
366 if( !aJson.is_array() )
369 m_Git.repositories.clear();
371 for(
const auto& repoJson : aJson )
375 repo.name = repoJson[
"name"].get<wxString>();
376 repo.path = repoJson[
"path"].get<wxString>();
377 repo.authType = repoJson[
"authType"].get<wxString>();
378 repo.username = repoJson[
"username"].get<wxString>();
379 repo.ssh_path = repoJson[
"ssh_path"].get<wxString>();
380 repo.active = repoJson[
"active"].get<
bool>();
381 repo.checkValid =
true;
383 m_Git.repositories.push_back( repo );
389 &m_Git.authorName, wxS(
"" ) ) );
392 &m_Git.authorEmail, wxS(
"" ) ) );
394 m_params.emplace_back(
new PARAM<bool>(
"git.useDefaultAuthor",
395 &m_Git.useDefaultAuthor,
true ) );
413 nlohmann::json::json_pointer mwp_pointer(
"/input/mousewheel_pan"_json_pointer );
420 m_internals->At(
"input" ).erase(
"mousewheel_pan" );
424 wxLogTrace(
traceSettings, wxT(
"COMMON_SETTINGS::Migrate 0->1: mousewheel_pan not found" ) );
429 ( *m_internals )[nlohmann::json::json_pointer(
"/input/horizontal_pan" )] =
true;
431 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_pan_h" )] = WXK_SHIFT;
432 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_pan_v" )] = 0;
433 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_zoom" )] = WXK_CONTROL;
437 ( *m_internals )[nlohmann::json::json_pointer(
"/input/horizontal_pan" )] =
false;
439 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_pan_h" )] = WXK_CONTROL;
440 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_pan_v" )] = WXK_SHIFT;
441 ( *m_internals )[nlohmann::json::json_pointer(
"/input/scroll_modifier_zoom" )] = 0;
450 nlohmann::json::json_pointer v1_pointer(
"/input/prefer_select_to_drag"_json_pointer );
452 bool prefer_selection =
false;
457 m_internals->at( nlohmann::json::json_pointer(
"/input"_json_pointer ) ).erase(
"prefer_select_to_drag" );
461 wxLogTrace(
traceSettings, wxT(
"COMMON_SETTINGS::Migrate 1->2: prefer_select_to_drag not found" ) );
464 if( prefer_selection )
465 ( *m_internals )[nlohmann::json::json_pointer(
"/input/mouse_left" )] = MOUSE_DRAG_ACTION::SELECT;
467 ( *
m_internals )[nlohmann::json::json_pointer(
"/input/mouse_left" )] = MOUSE_DRAG_ACTION::DRAG_ANY;
477 cfgpath.AppendDir( wxT(
"3d" ) );
478 cfgpath.SetFullName( wxS(
"3Dresolver.cfg" ) );
479 cfgpath.MakeAbsolute();
481 std::vector<LEGACY_3D_SEARCH_PATH> legacyPaths;
485 wxRegEx nonValidCharsRegex( wxS(
"[^A-Z0-9_]+" ), wxRE_ADVANCED );
489 wxString key =
path.m_Alias;
490 const wxString& val =
path.m_Pathvar;
498 key.Replace( wxS(
"-" ), wxS(
"_" ) );
501 nonValidCharsRegex.Replace( &key, wxEmptyString );
505 wxLogTrace(
traceEnvVars, wxS(
"COMMON_SETTINGS: Loaded new var: %s = %s" ), key, val );
510 if( cfgpath.FileExists() )
512 wxRemoveFile( cfgpath.GetFullPath() );
523 ret &= fromLegacy<double>( aCfg,
"CanvasScale",
"appearance.canvas_scale" );
524 ret &= fromLegacy<int>( aCfg,
"IconScale",
"appearance.icon_scale" );
525 ret &= fromLegacy<bool>( aCfg,
"UseIconsInMenus",
"appearance.use_icons_in_menus" );
526 ret &= fromLegacy<bool>( aCfg,
"ShowEnvVarWarningDialog",
"environment.show_warning_dialog" );
533 nlohmann::json::json_pointer ptr =
m_internals->PointerFromString(
"environment.vars" );
535 aCfg->SetPath(
"EnvironmentVariables" );
536 ( *m_internals )[ptr] = nlohmann::json( {} );
538 while( aCfg->GetNextEntry( key, index ) )
543 wxT(
"Migrate Env: %s is blacklisted; skipping." ), key );
547 value = aCfg->Read( key, wxEmptyString );
549 if( !value.IsEmpty() )
551 ptr.push_back( key.ToStdString() );
554 ptr.to_string(), value );
555 ( *m_internals )[ptr] = value.ToUTF8();
561 aCfg->SetPath(
".." );
566 bool mousewheel_pan =
false;
568 if( aCfg->Read(
"MousewheelPAN", &mousewheel_pan ) && mousewheel_pan )
570 Set(
"input.horizontal_pan",
true );
571 Set(
"input.scroll_modifier_pan_h",
static_cast<int>( WXK_SHIFT ) );
572 Set(
"input.scroll_modifier_pan_v", 0 );
573 Set(
"input.scroll_modifier_zoom",
static_cast<int>( WXK_CONTROL ) );
576 ret &= fromLegacy<bool>( aCfg,
"AutoPAN",
"input.auto_pan" );
577 ret &= fromLegacy<bool>( aCfg,
"ImmediateActions",
"input.immediate_actions" );
578 ret &= fromLegacy<bool>( aCfg,
"PreferSelectionToDragging",
"input.prefer_select_to_drag" );
579 ret &= fromLegacy<bool>( aCfg,
"MoveWarpsCursor",
"input.warp_mouse_on_move" );
580 ret &= fromLegacy<bool>( aCfg,
"ZoomNoCenter",
"input.center_on_zoom" );
583 if( std::optional<bool> value = Get<bool>(
"input.center_on_zoom" ) )
584 Set(
"input.center_on_zoom", !( *value ) );
586 ret &= fromLegacy<int>( aCfg,
"OpenGLAntialiasingMode",
"graphics.opengl_antialiasing_mode" );
587 ret &= fromLegacy<int>( aCfg,
"CairoAntialiasingMode",
"graphics.cairo_antialiasing_mode" );
589 ret &= fromLegacy<int>( aCfg,
"AutoSaveInterval",
"system.autosave_interval" );
591 ret &= fromLegacy<int>( aCfg,
"FileHistorySize",
"system.file_history_size" );
593 ret &=
fromLegacyString( aCfg,
"PdfBrowserName",
"system.pdf_viewer_name" );
594 ret &= fromLegacy<bool>( aCfg,
"UseSystemBrowser",
"system.use_system_pdf_viewer" );
604 [&](
const wxString& aKey,
const wxString& aDefault )
610 if( wxGetEnv( aKey, &envValue ) ==
true && !envValue.IsEmpty() )
615 wxS(
"InitializeEnvironment: Entry %s defined externally as %s" ), aKey,
620 wxLogTrace(
traceEnvVars, wxS(
"InitializeEnvironment: Setting entry %s to "
628 wxFileName
path( basePath );
629 path.AppendDir( wxT(
"footprints" ) );
633 path.AppendDir( wxT(
"3dmodels" ) );
645 path.AppendDir( wxT(
"symbols" ) );
651 std::vector<LEGACY_3D_SEARCH_PATH>& aSearchPaths )
653 wxFileName cfgpath(
path );
659 wxString cfgname = cfgpath.GetFullPath();
661 std::ifstream cfgFile;
664 if( !wxFileName::Exists( cfgname ) )
666 std::ostringstream ostr;
667 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
668 wxString errmsg =
"no 3D configuration file";
669 ostr <<
" * " << errmsg.ToUTF8() <<
" '";
670 ostr << cfgname.ToUTF8() <<
"'";
675 cfgFile.open( cfgname.ToUTF8() );
677 if( !cfgFile.is_open() )
679 std::ostringstream ostr;
680 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
681 wxString errmsg = wxS(
"Could not open configuration file" );
682 ostr <<
" * " << errmsg.ToUTF8() <<
" '" << cfgname.ToUTF8() <<
"'";
683 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
692 while( cfgFile.good() )
695 std::getline( cfgFile, cfgLine );
698 if( cfgLine.empty() )
706 if( 1 == lineno && cfgLine.compare( 0, 2,
"#V" ) == 0 )
709 if( cfgLine.size() > 2 )
711 std::istringstream istr;
712 istr.str( cfgLine.substr( 2 ) );
726 wxString versionedPath = wxString::Format( wxS(
"${%s}" ),
729 if( al.
m_Alias == versionedPath || al.
m_Alias == wxS(
"${KIPRJMOD}" )
730 || al.
m_Alias == wxS(
"$(KIPRJMOD)" ) || al.
m_Alias == wxS(
"${KISYS3DMOD}" )
731 || al.
m_Alias == wxS(
"$(KISYS3DMOD)" ) )
742 aSearchPaths.push_back( al );
756 if( aIndex >= aString.size() )
758 std::ostringstream ostr;
759 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
760 wxString errmsg = wxS(
"bad Hollerith string on line" );
761 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
762 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
767 size_t i2 = aString.find(
'"', aIndex );
769 if( std::string::npos == i2 )
771 std::ostringstream ostr;
772 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
773 wxString errmsg = wxS(
"missing opening quote mark in config file" );
774 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
775 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
782 if( i2 >= aString.size() )
784 std::ostringstream ostr;
785 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
786 wxString errmsg = wxS(
"invalid entry (unexpected end of line)" );
787 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
788 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
795 while( aString[i2] >=
'0' && aString[i2] <=
'9' )
796 tnum.append( 1, aString[i2++] );
798 if( tnum.empty() || aString[i2++] !=
':' )
800 std::ostringstream ostr;
801 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
802 wxString errmsg = wxS(
"bad Hollerith string on line" );
803 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
804 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
809 std::istringstream istr;
814 if( ( i2 + nchars ) >= aString.size() )
816 std::ostringstream ostr;
817 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
818 wxString errmsg = wxS(
"invalid entry (unexpected end of line)" );
819 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
820 wxLogTrace(
traceSettings, wxS(
"%s\n" ), ostr.str().c_str() );
827 aResult = wxString::FromUTF8( aString.substr( i2, nchars ).c_str() );
831 if( i2 >= aString.size() || aString[i2] !=
'"' )
833 std::ostringstream ostr;
834 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
835 wxString errmsg = wxS(
"missing closing quote mark in config file" );
836 ostr <<
" * " << errmsg.ToUTF8() <<
"\n'" << aString <<
"'";
837 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().