65#if defined( __WXGTK__ ) || defined( __WXMSW__ ) 
  114            &
m_Appearance.zoom_correction_factor, 1.0, 0.1, 10.0 ) );
 
  119            &
m_Backup.limit_total_size, 104857600 ) );
 
  122            [&]() -> nlohmann::json
 
  124                nlohmann::json ret = {};
 
  126                for( 
const std::pair<wxString, ENV_VAR_ITEM> entry : 
m_Env.vars )
 
  128                    const ENV_VAR_ITEM& var = entry.second;
 
  130                    wxASSERT( entry.first == var.GetKey() );
 
  133                    if( var.IsDefault() )
 
  135                        wxLogTrace( traceEnvVars,
 
  136                                    wxS( 
"COMMON_SETTINGS: Env var %s skipping save (default)" ),
 
  141                    wxString value = var.GetValue();
 
  143                    value.Trim( 
true ).Trim( 
false ); 
 
  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().Trim( 
true ).Trim( 
false ).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 ).Trim( 
true ).Trim( 
false );
 
  185                    wxString val = entry.value().get<wxString>().Trim( 
true ).Trim( 
false );
 
  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 );
 
  219    envVarsParam->SetClearUnknownKeys();
 
  221    m_params.emplace_back( 
new PARAM<bool>( 
"input.focus_follow_sch_pcb",
 
  222            &m_Input.focus_follow_sch_pcb, 
false ) );
 
  224    m_params.emplace_back( 
new PARAM<bool>( 
"input.auto_pan", &m_Input.auto_pan, 
false ) );
 
  226    m_params.emplace_back( 
new PARAM<int>( 
"input.auto_pan_acceleration",
 
  227            &m_Input.auto_pan_acceleration, 5 ) );
 
  229    m_params.emplace_back( 
new PARAM<bool>( 
"input.center_on_zoom",
 
  230            &m_Input.center_on_zoom, 
true ) );
 
  232    m_params.emplace_back( 
new PARAM<bool>( 
"input.immediate_actions",
 
  233            &m_Input.immediate_actions, 
true ) );
 
  235    m_params.emplace_back( 
new PARAM<bool>( 
"input.warp_mouse_on_move",
 
  236            &m_Input.warp_mouse_on_move, 
true ) );
 
  238    m_params.emplace_back( 
new PARAM<bool>( 
"input.horizontal_pan",
 
  239            &m_Input.horizontal_pan, 
false ) );
 
  241    m_params.emplace_back( 
new PARAM<bool>( 
"input.hotkey_feedback",
 
  242            &m_Input.hotkey_feedback, 
true ) );
 
  244    m_params.emplace_back( 
new PARAM<bool>( 
"input.zoom_acceleration",
 
  245            &m_Input.zoom_acceleration, 
false ) );
 
  248    int default_zoom_speed = 5;
 
  250    int default_zoom_speed = 1;
 
  253    m_params.emplace_back( 
new PARAM<int>( 
"input.zoom_speed",
 
  254            &m_Input.zoom_speed, default_zoom_speed ) );
 
  256    m_params.emplace_back( 
new PARAM<bool>( 
"input.zoom_speed_auto",
 
  257            &m_Input.zoom_speed_auto, 
true ) );
 
  259    m_params.emplace_back( 
new PARAM<int>( 
"input.scroll_modifier_zoom",
 
  260            &m_Input.scroll_modifier_zoom, 0 ) );
 
  262    m_params.emplace_back( 
new PARAM<int>( 
"input.scroll_modifier_pan_h",
 
  263            &m_Input.scroll_modifier_pan_h, WXK_CONTROL ) );
 
  265    m_params.emplace_back( 
new PARAM<int>( 
"input.scroll_modifier_pan_v",
 
  266            &m_Input.scroll_modifier_pan_v, WXK_SHIFT ) );
 
  268    m_params.emplace_back( 
new PARAM<int>( 
"input.motion_pan_modifier",
 
  269            &m_Input.motion_pan_modifier, 0 ) );
 
  271    m_params.emplace_back( 
new PARAM<bool>( 
"input.reverse_scroll_zoom",
 
  272            &m_Input.reverse_scroll_zoom, 
false ) );
 
  274    m_params.emplace_back( 
new PARAM<bool>( 
"input.reverse_scroll_pan_h",
 
  275            &m_Input.reverse_scroll_pan_h, 
false ) );
 
  289    m_params.emplace_back( 
new PARAM<int>( 
"spacemouse.rotate_speed",
 
  290            &m_SpaceMouse.rotate_speed, 5, 1, 10 ) );
 
  292    m_params.emplace_back( 
new PARAM<int>( 
"spacemouse.pan_speed",
 
  293            &m_SpaceMouse.pan_speed, 5, 1, 10 ) );
 
  295    m_params.emplace_back( 
new PARAM<bool>( 
"spacemouse.reverse_rotate",
 
  296            &m_SpaceMouse.reverse_rotate, 
false ) );
 
  298    m_params.emplace_back( 
new PARAM<bool>( 
"spacemouse.reverse_pan_x",
 
  299            &m_SpaceMouse.reverse_pan_x, 
false ) );
 
  301    m_params.emplace_back( 
new PARAM<bool>( 
"spacemouse.reverse_pan_y",
 
  302            &m_SpaceMouse.reverse_pan_y, 
false ) );
 
  304    m_params.emplace_back( 
new PARAM<bool>( 
"spacemouse.reverse_zoom",
 
  305            &m_SpaceMouse.reverse_zoom, 
false ) );
 
  307    m_params.emplace_back( 
new PARAM<int>( 
"graphics.canvas_type",
 
  310    m_params.emplace_back( 
new PARAM<int>( 
"graphics.antialiasing_mode",
 
  311            &m_Graphics.aa_mode, 2, 0, 2 ) );
 
  313    m_params.emplace_back( 
new PARAM<bool>( 
"system.local_history_enabled",
 
  314            &m_System.local_history_enabled, 
true ) );
 
  315    m_params.emplace_back( 
new PARAM<int>( 
"system.local_history_debounce",
 
  316            &m_System.local_history_debounce, 5, 0, 100000 ) );
 
  320            &m_System.text_editor, wxS( 
"/usr/bin/open -e" ) ) );
 
  323            &m_System.text_editor, wxS( 
"" ) ) );
 
  326#if defined( __WINDOWS__ ) 
  328            &m_System.file_explorer, wxS( 
"explorer.exe /n,/select,%F" ) ) );
 
  331            &m_System.file_explorer, wxS( 
"" ) ) );
 
  334    m_params.emplace_back( 
new PARAM<int>( 
"system.file_history_size",
 
  335            &m_System.file_history_size, 9 ) );
 
  338            &m_System.language, wxS( 
"Default" ) ) );
 
  341            &m_System.pdf_viewer_name, wxS( 
"" ) ) );
 
  343    m_params.emplace_back( 
new PARAM<bool>( 
"system.use_system_pdf_viewer",
 
  344            &m_System.use_system_pdf_viewer, 
true ) );
 
  347            &m_System.working_dir, wxS( 
"" ) ) );
 
  349    m_params.emplace_back( 
new PARAM<int>( 
"system.clear_3d_cache_interval",
 
  350            &m_System.clear_3d_cache_interval, 30 ) );
 
  352    m_params.emplace_back( 
new PARAM<bool>( 
"do_not_show_again.zone_fill_warning",
 
  353            &m_DoNotShowAgain.zone_fill_warning, 
false ) );
 
  355    m_params.emplace_back( 
new PARAM<bool>( 
"do_not_show_again.env_var_overwrite_warning",
 
  356            &m_DoNotShowAgain.env_var_overwrite_warning, 
false ) );
 
  358    m_params.emplace_back( 
new PARAM<bool>( 
"do_not_show_again.scaled_3d_models_warning",
 
  359            &m_DoNotShowAgain.scaled_3d_models_warning, 
false ) );
 
  361    m_params.emplace_back( 
new PARAM<bool>( 
"do_not_show_again.data_collection_prompt",
 
  362            &m_DoNotShowAgain.data_collection_prompt, 
false ) );
 
  364    m_params.emplace_back( 
new PARAM<bool>( 
"do_not_show_again.update_check_prompt",
 
  365            &m_DoNotShowAgain.update_check_prompt, 
false ) );
 
  367    m_params.emplace_back( 
new PARAM<bool>( 
"session.remember_open_files",
 
  368            &m_Session.remember_open_files, 
false ) );
 
  371            &m_Session.pinned_symbol_libs, {} ) );
 
  374            &m_Session.pinned_fp_libs, {} ) );
 
  377            &m_Session.pinned_design_block_libs, {} ) );
 
  379    m_params.emplace_back( 
new PARAM<int>( 
"netclass_panel.sash_pos",
 
  380            &m_NetclassPanel.sash_pos, 160 ) );
 
  382    m_params.emplace_back( 
new PARAM<wxString>( 
"netclass_panel.eeschema_shown_columns",
 
  383            &m_NetclassPanel.eeschema_visible_columns, 
"0 11 12 13 14" ) );
 
  385    m_params.emplace_back( 
new PARAM<wxString>( 
"netclass_panel.pcbnew_shown_columns",
 
  386            &m_NetclassPanel.pcbnew_visible_columns, 
"0 1 2 3 4 5 6 7 8 9 10" ) );
 
  388    m_params.emplace_back( 
new PARAM<int>( 
"package_manager.sash_pos",
 
  389            &m_PackageManager.sash_pos, 380 ) );
 
  392            [&]() -> nlohmann::json
 
  394                nlohmann::json ret = {};
 
  396                for( 
const GIT_REPOSITORY& repo : m_Git.repositories )
 
  398                    nlohmann::json repoJson = {};
 
  400                    repoJson[
"name"] = repo.name;
 
  401                    repoJson[
"path"] = repo.path;
 
  402                    repoJson[
"authType"] = repo.authType;
 
  403                    repoJson[
"username"] = repo.username;
 
  404                    repoJson[
"ssh_path"] = repo.ssh_path;
 
  405                    repoJson[
"active"] = repo.active;
 
  407                    ret.push_back( repoJson );
 
  412            [&]( 
const nlohmann::json& aJson )
 
  414                if( !aJson.is_array() )
 
  417                m_Git.repositories.clear();
 
  419                for( 
const auto& repoJson : aJson )
 
  423                    repo.name = repoJson[
"name"].get<wxString>();
 
  424                    repo.path = repoJson[
"path"].get<wxString>();
 
  425                    repo.authType = repoJson[
"authType"].get<wxString>();
 
  426                    repo.username = repoJson[
"username"].get<wxString>();
 
  427                    repo.ssh_path = repoJson[
"ssh_path"].get<wxString>();
 
  428                    repo.active = repoJson[
"active"].get<
bool>();
 
  429                    repo.checkValid = 
true;
 
  431                    m_Git.repositories.push_back( repo );
 
  437            &m_Git.authorName, wxS( 
"" ) ) );
 
  440            &m_Git.authorEmail, wxS( 
"" ) ) );
 
  442    m_params.emplace_back( 
new PARAM<bool>( 
"git.useDefaultAuthor",
 
  443            &m_Git.useDefaultAuthor, 
true ) );
 
  445    m_params.emplace_back( 
new PARAM<bool>( 
"git.enableGit",
 
  446            &m_Git.enableGit, 
true ) );
 
  448    m_params.emplace_back( 
new PARAM<int>( 
"git.updatInterval",
 
  449            &m_Git.updatInterval, 5 ) );
 
  452            &m_Api.python_interpreter, wxS( 
"" ) ) );
 
  454    m_params.emplace_back( 
new PARAM<bool>( 
"api.enable_server",
 
  455            &m_Api.enable_server, 
false ) );
 
  458            [&]() -> nlohmann::json
 
  460                nlohmann::json ret = nlohmann::json::object();
 
  462                for( const auto& dlg : m_dialogControlValues )
 
  463                    ret[ dlg.first ] = dlg.second;
 
  467            [&]( 
const nlohmann::json& aVal )
 
  469                m_dialogControlValues.clear();
 
  471                if( !aVal.is_object() )
 
  474                for( auto& [dlgKey, dlgVal] : aVal.items() )
 
  476                    if( !dlgVal.is_object() )
 
  479                    for( auto& [ctrlKey, ctrlVal] : dlgVal.items() )
 
  480                        m_dialogControlValues[ dlgKey ][ ctrlKey ] = ctrlVal;
 
  483            nlohmann::json::object() ) );
 
 
  615        const nlohmann::json::json_pointer v3_pointer_eeschema( 
"/netclass_panel/eeschema_shown_columns"_json_pointer );
 
  616        wxString                           eeSchemaColumnList_old = 
m_internals->at( v3_pointer_eeschema );
 
  618        wxStringTokenizer eeSchemaShownTokens( eeSchemaColumnList_old, 
" \t\r\n" );
 
  619        wxString          eeSchemaColumnList_new;
 
  621        while( eeSchemaShownTokens.HasMoreTokens() )
 
  624            eeSchemaShownTokens.GetNextToken().ToLong( &colNumber );
 
  626            if( colNumber >= 10 )
 
  629            eeSchemaColumnList_new += wxString::Format( wxT( 
"%ld " ), colNumber );
 
  632        eeSchemaColumnList_new.Trim( 
true );
 
  633        eeSchemaColumnList_new.Trim( 
false );
 
  635        m_internals->at( v3_pointer_eeschema ) = eeSchemaColumnList_new.ToUTF8();
 
  638        const nlohmann::json::json_pointer v3_pointer_pcbnew( 
"/netclass_panel/pcbnew_shown_columns"_json_pointer );
 
  639        wxString                           pcbnewColumnList_old = 
m_internals->at( v3_pointer_pcbnew );
 
  641        wxStringTokenizer pcbnewShownTokens( pcbnewColumnList_old, 
" \t\r\n" );
 
  642        wxString          pcbnewColumnList_new;
 
  644        while( pcbnewShownTokens.HasMoreTokens() )
 
  647            pcbnewShownTokens.GetNextToken().ToLong( &colNumber );
 
  649            if( colNumber >= 10 )
 
  652            pcbnewColumnList_new += wxString::Format( wxT( 
"%ld " ), colNumber );
 
  655        pcbnewColumnList_new.Trim( 
true );
 
  656        pcbnewColumnList_new.Trim( 
false );
 
  658        m_internals->at( v3_pointer_pcbnew ) = pcbnewColumnList_new.ToUTF8();
 
  662        wxLogTrace( 
traceSettings, wxT( 
"COMMON_SETTINGS::Migrate 3->4: /netclass_panel/shown_columns not found" ) );