KiCad PCB EDA Suite
common_settings.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
5  * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation, either version 3 of the License, or (at your
10  * option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
22 #include <settings/parameters.h>
23 #include <view/view_controls.h>
24 #include <view/zoom_controller.h>
25 #include <wx/config.h>
26 #include <wx/log.h>
27 
29 
30 
31 extern const char* traceSettings;
32 
33 
35 const int commonSchemaVersion = 1;
36 
39  m_Appearance(), m_Env(), m_Input(), m_Graphics(), m_System()
40 {
41  // This only effect the first time KiCad is run. The user's setting will be used for all
42  // subsequent runs.
43  // Menu icons are off by default on OSX and on for all other platforms.
44  // Use automatic canvas scaling on OSX, but not on the other platforms (their detection isn't as good).
45 #if defined( __WXMAC__ )
46  bool defaultUseIconsInMenus = false;
47  double canvasScale = 0.0;
48 #else
49  bool defaultUseIconsInMenus = true;
50  double canvasScale = 1.0;
51 #endif
52 
53  m_params.emplace_back( new PARAM<double>( "appearance.canvas_scale",
54  &m_Appearance.canvas_scale, canvasScale ) );
55 
56  m_params.emplace_back( new PARAM<int>( "appearance.icon_scale",
57  &m_Appearance.icon_scale, 0 ) );
58 
59  m_params.emplace_back( new PARAM<bool>( "appearance.use_icons_in_menus",
60  &m_Appearance.use_icons_in_menus, defaultUseIconsInMenus ) );
61 
62  m_params.emplace_back( new PARAM<bool>( "environment.show_warning_dialog",
63  &m_Env.show_warning_dialog, false ) );
64 
65  m_params.emplace_back( new PARAM_MAP<wxString>( "environment.vars", &m_Env.vars, {} ) );
66 
67  m_params.emplace_back( new PARAM<bool>( "input.auto_pan", &m_Input.auto_pan, false ) );
68 
69  m_params.emplace_back(
70  new PARAM<int>( "input.auto_pan_acceleration", &m_Input.auto_pan_acceleration, 5 ) );
71 
72  m_params.emplace_back(
73  new PARAM<bool>( "input.center_on_zoom", &m_Input.center_on_zoom, true ) );
74 
75  m_params.emplace_back( new PARAM<bool>( "input.immediate_actions",
76  &m_Input.immediate_actions, true ) );
77 
78  m_params.emplace_back( new PARAM<bool>( "input.prefer_select_to_drag",
79  &m_Input.prefer_select_to_drag, true ) );
80 
81  m_params.emplace_back( new PARAM<bool>( "input.warp_mouse_on_move",
82  &m_Input.warp_mouse_on_move, true ) );
83 
84  m_params.emplace_back(
85  new PARAM<bool>( "input.horizontal_pan", &m_Input.horizontal_pan, false ) );
86 
87 #if defined(__WXMAC__) || defined(__WXGTK3__)
88  bool default_zoom_acceleration = false;
89 #else
90  bool default_zoom_acceleration = true;
91 #endif
92 
93  m_params.emplace_back( new PARAM<bool>(
94  "input.zoom_acceleration", &m_Input.zoom_acceleration, default_zoom_acceleration ) );
95 
96 #ifdef __WXMAC__
97  int default_zoom_speed = 5;
98 #else
99  int default_zoom_speed = 1;
100 #endif
101 
102  m_params.emplace_back(
103  new PARAM<int>( "input.zoom_speed", &m_Input.zoom_speed, default_zoom_speed ) );
104 
105  m_params.emplace_back(
106  new PARAM<bool>( "input.zoom_speed_auto", &m_Input.zoom_speed_auto, true ) );
107 
108  m_params.emplace_back(
109  new PARAM<int>( "input.scroll_modifier_zoom", &m_Input.scroll_modifier_zoom, 0 ) );
110 
111  m_params.emplace_back( new PARAM<int>(
112  "input.scroll_modifier_pan_h", &m_Input.scroll_modifier_pan_h, WXK_CONTROL ) );
113 
114  m_params.emplace_back( new PARAM<int>(
115  "input.scroll_modifier_pan_v", &m_Input.scroll_modifier_pan_v, WXK_SHIFT ) );
116 
117  m_params.emplace_back( new PARAM<int>( "input.mouse_middle", &m_Input.drag_middle,
118  static_cast<int>( MOUSE_DRAG_ACTION::PAN ),
119  static_cast<int>( MOUSE_DRAG_ACTION::SELECT ),
120  static_cast<int>( MOUSE_DRAG_ACTION::NONE ) ) );
121 
122  m_params.emplace_back( new PARAM<int>( "input.mouse_right", &m_Input.drag_right,
123  static_cast<int>( MOUSE_DRAG_ACTION::PAN ),
124  static_cast<int>( MOUSE_DRAG_ACTION::SELECT ),
125  static_cast<int>( MOUSE_DRAG_ACTION::NONE ) ) );
126 
127  m_params.emplace_back( new PARAM<int>( "graphics.opengl_antialiasing_mode",
128  &m_Graphics.opengl_aa_mode, 0, 0, 4 ) );
129 
130  m_params.emplace_back( new PARAM<int>( "graphics.cairo_antialiasing_mode",
131  &m_Graphics.cairo_aa_mode, 0, 0, 3 ) );
132 
133  m_params.emplace_back( new PARAM<int>( "system.autosave_interval",
134  &m_System.autosave_interval, 600 ) );
135 
136  m_params.emplace_back( new PARAM<wxString>( "system.editor_name",
137  &m_System.editor_name, "" ) );
138 
139  m_params.emplace_back( new PARAM<int>( "system.file_history_size",
140  &m_System.file_history_size, 9 ) );
141 
142  m_params.emplace_back( new PARAM<wxString>( "system.language",
143  &m_System.language, "Default" ) );
144 
145  m_params.emplace_back( new PARAM<wxString>( "system.pdf_viewer_name",
146  &m_System.pdf_viewer_name, "" ) );
147 
148  m_params.emplace_back( new PARAM<bool>( "system.use_system_pdf_viewer",
149  &m_System.use_system_pdf_viewer, true ) );
150 
151  m_params.emplace_back( new PARAM<wxString>( "system.working_dir",
152  &m_System.working_dir, "" ) );
153 }
154 
155 
157 {
158  bool ret = true;
159  int filever = at( PointerFromString( "meta.version" ) ).get<int>();
160 
161  if( filever == 0 )
162  {
163  ret &= migrateSchema0to1();
164 
165  if( ret )
166  {
167  ( *this )[PointerFromString( "meta.version" )] = 1;
168  }
169  }
170 
171  return ret;
172 }
173 
174 
176 {
183  nlohmann::json::json_pointer mwp_pointer( "/input/mousewheel_pan"_json_pointer );
184 
185  bool mwp = false;
186 
187  try
188  {
189  mwp = at( mwp_pointer );
190  at( nlohmann::json::json_pointer( "/input"_json_pointer ) ).erase( "mousewheel_pan" );
191  }
192  catch( ... )
193  {
194  wxLogTrace( traceSettings, "COMMON_SETTINGS::Migrate 0->1: mousewheel_pan not found" );
195  }
196 
197  if( mwp )
198  {
199  ( *this )[nlohmann::json::json_pointer( "/input/horizontal_pan" )] = true;
200 
201  ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_h" )] = WXK_SHIFT;
202  ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_v" )] = 0;
203  ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_zoom" )] = WXK_CONTROL;
204  }
205  else
206  {
207  ( *this )[nlohmann::json::json_pointer( "/input/horizontal_pan" )] = false;
208 
209  ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_h" )] = WXK_CONTROL;
210  ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_v" )] = WXK_SHIFT;
211  ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_zoom" )] = 0;
212  }
213 
214  return true;
215 }
216 
217 
218 bool COMMON_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
219 {
220  bool ret = true;
221 
222  ret &= fromLegacy<double>( aCfg, "CanvasScale", "appearance.canvas_scale" );
223  ret &= fromLegacy<int>( aCfg, "IconScale", "appearance.icon_scale" );
224  ret &= fromLegacy<bool>( aCfg, "UseIconsInMenus", "appearance.use_icons_in_menus" );
225 
226 // Force OSX to automatically scale the canvas. Before v6, the user setting wasn't used on OSX and was
227 // set to 1.0. In v6, the setting is now used by OSX and should default to automatic scaling.
228 #ifdef __WXMAC__
229  ( *this )[PointerFromString( "appearance.canvas_scale" )] = 0.0;
230 #endif
231 
232  ret &= fromLegacy<bool>( aCfg, "ShowEnvVarWarningDialog", "environment.show_warning_dialog" );
233 
234  auto load_env_vars = [&] () {
235  wxString key, value;
236  long index = 0;
237  nlohmann::json::json_pointer ptr = PointerFromString( "environment.vars" );
238 
239  aCfg->SetPath( "EnvironmentVariables" );
240  ( *this )[ptr] = nlohmann::json( {} );
241 
242  while( aCfg->GetNextEntry( key, index ) )
243  {
244  value = aCfg->Read( key, wxEmptyString );
245 
246  if( !value.IsEmpty() )
247  {
248  ptr.push_back( key.ToStdString() );
249 
250  wxLogTrace( traceSettings, "Migrate Env: %s=%s", ptr.to_string(), value );
251  ( *this )[ptr] = value.ToUTF8();
252 
253  ptr.pop_back();
254  }
255  }
256 
257  aCfg->SetPath( ".." );
258  };
259 
260  load_env_vars();
261 
262  bool mousewheel_pan = false;
263 
264  if( aCfg->Read( "MousewheelPAN", &mousewheel_pan ) && mousewheel_pan )
265  {
266  ( *this )[PointerFromString( "input.horizontal_pan" )] = true;
267 
268  ( *this )[PointerFromString( "input.scroll_modifier_pan_h" )] = WXK_SHIFT;
269  ( *this )[PointerFromString( "input.scroll_modifier_pan_v" )] = 0;
270  ( *this )[PointerFromString( "input.scroll_modifier_zoom" )] = WXK_CONTROL;
271  }
272 
273  ret &= fromLegacy<bool>( aCfg, "AutoPAN", "input.auto_pan" );
274  ret &= fromLegacy<bool>( aCfg, "ImmediateActions", "input.immediate_actions" );
275  ret &= fromLegacy<bool>( aCfg, "PreferSelectionToDragging", "input.prefer_select_to_drag" );
276  ret &= fromLegacy<bool>( aCfg, "MoveWarpsCursor", "input.warp_mouse_on_move" );
277  ret &= fromLegacy<bool>( aCfg, "ZoomNoCenter", "input.center_on_zoom" );
278 
279  // This was stored inverted in legacy config
280  if( ret )
281  {
282  auto p = PointerFromString( "input.center_on_zoom" );
283  ( *this )[p] = !( *this )[p];
284  }
285 
286  ret &= fromLegacy<int>( aCfg, "OpenGLAntialiasingMode", "graphics.opengl_antialiasing_mode" );
287  ret &= fromLegacy<int>( aCfg, "CairoAntialiasingMode", "graphics.cairo_antialiasing_mode" );
288 
289  ret &= fromLegacy<int>( aCfg, "AutoSaveInterval", "system.autosave_interval" );
290  ret &= fromLegacyString( aCfg, "Editor", "system.editor_name" );
291  ret &= fromLegacy<int>( aCfg, "FileHistorySize", "system.file_history_size" );
292  ret &= fromLegacyString( aCfg, "LanguageID", "system.language" );
293  ret &= fromLegacyString( aCfg, "PdfBrowserName", "system.pdf_viewer_name" );
294  ret &= fromLegacy<bool>( aCfg, "UseSystemBrowser", "system.use_system_pdf_viewer" );
295  ret &= fromLegacyString( aCfg, "WorkingDir", "system.working_dir" );
296 
297  return ret;
298 }
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
MOUSE_DRAG_ACTION
Action to perform when the mouse is dragged
Definition: view_controls.h:45
VIEW_CONTROLS class definition.
Represents a map of <std::string, Value>.
Definition: parameters.h:574
const int commonSchemaVersion
! Update the schema version whenever a migration is required
SETTINGS_LOC
Definition: json_settings.h:36
APPEARANCE m_Appearance
virtual bool MigrateFromLegacy(wxConfigBase *aLegacyConfig) override
Migrates from wxConfig to JSON-based configuration.
nlohmann::json json
Definition: gerbview.cpp:40
bool Migrate() override
Migrates the schema of this settings from the version in the file to the latest version.
std::map< std::string, wxString > vars
ENVIRONMENT m_Env
bool fromLegacyString(wxConfigBase *aConfig, const std::string &aKey, const std::string &aDest)
Translates a legacy wxConfig string value to a given JSON pointer value.
The main config directory (e.g. ~/.config/kicad/)
const char * traceSettings
Flag to enable settings tracing.
static nlohmann::json::json_pointer PointerFromString(std::string aPath)
Builds a JSON pointer based on a given string.