You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

292 lines
11 KiB

  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. #include <settings/common_settings.h>
  21. #include <settings/parameters.h>
  22. #include <view/view_controls.h>
  23. #include <view/zoom_controller.h>
  24. #include <wx/config.h>
  25. #include <wx/log.h>
  26. using KIGFX::MOUSE_DRAG_ACTION;
  27. extern const char* traceSettings;
  28. ///! Update the schema version whenever a migration is required
  29. const int commonSchemaVersion = 1;
  30. COMMON_SETTINGS::COMMON_SETTINGS() :
  31. JSON_SETTINGS( "kicad_common", SETTINGS_LOC::USER, commonSchemaVersion ),
  32. m_Appearance(), m_Env(), m_Input(), m_Graphics(), m_System()
  33. {
  34. // This only effect the first time KiCad is run. The user's setting will be used for all
  35. // subsequent runs.
  36. // Menu icons are off by default on OSX and on for all other platforms.
  37. // Use automatic canvas scaling on OSX, but not on the other platforms (their detection isn't as good).
  38. #if defined( __WXMAC__ )
  39. bool defaultUseIconsInMenus = false;
  40. double canvasScale = 0.0;
  41. #else
  42. bool defaultUseIconsInMenus = true;
  43. double canvasScale = 1.0;
  44. #endif
  45. m_params.emplace_back( new PARAM<double>( "appearance.canvas_scale",
  46. &m_Appearance.canvas_scale, canvasScale ) );
  47. m_params.emplace_back( new PARAM<int>( "appearance.icon_scale",
  48. &m_Appearance.icon_scale, 0 ) );
  49. m_params.emplace_back( new PARAM<bool>( "appearance.use_icons_in_menus",
  50. &m_Appearance.use_icons_in_menus, defaultUseIconsInMenus ) );
  51. m_params.emplace_back( new PARAM<bool>( "environment.show_warning_dialog",
  52. &m_Env.show_warning_dialog, false ) );
  53. m_params.emplace_back( new PARAM_MAP<wxString>( "environment.vars", &m_Env.vars, {} ) );
  54. m_params.emplace_back( new PARAM<bool>( "input.auto_pan", &m_Input.auto_pan, false ) );
  55. m_params.emplace_back(
  56. new PARAM<int>( "input.auto_pan_acceleration", &m_Input.auto_pan_acceleration, 5 ) );
  57. m_params.emplace_back(
  58. new PARAM<bool>( "input.center_on_zoom", &m_Input.center_on_zoom, true ) );
  59. m_params.emplace_back( new PARAM<bool>( "input.immediate_actions",
  60. &m_Input.immediate_actions, true ) );
  61. m_params.emplace_back( new PARAM<bool>( "input.prefer_select_to_drag",
  62. &m_Input.prefer_select_to_drag, true ) );
  63. m_params.emplace_back( new PARAM<bool>( "input.warp_mouse_on_move",
  64. &m_Input.warp_mouse_on_move, true ) );
  65. m_params.emplace_back(
  66. new PARAM<bool>( "input.horizontal_pan", &m_Input.horizontal_pan, false ) );
  67. #if defined(__WXMAC__) || defined(__WXGTK3__)
  68. bool default_zoom_acceleration = false;
  69. #else
  70. bool default_zoom_acceleration = true;
  71. #endif
  72. m_params.emplace_back( new PARAM<bool>(
  73. "input.zoom_acceleration", &m_Input.zoom_acceleration, default_zoom_acceleration ) );
  74. #ifdef __WXMAC__
  75. int default_zoom_speed = 5;
  76. #else
  77. int default_zoom_speed = 1;
  78. #endif
  79. m_params.emplace_back(
  80. new PARAM<int>( "input.zoom_speed", &m_Input.zoom_speed, default_zoom_speed ) );
  81. m_params.emplace_back(
  82. new PARAM<bool>( "input.zoom_speed_auto", &m_Input.zoom_speed_auto, true ) );
  83. m_params.emplace_back(
  84. new PARAM<int>( "input.scroll_modifier_zoom", &m_Input.scroll_modifier_zoom, 0 ) );
  85. m_params.emplace_back( new PARAM<int>(
  86. "input.scroll_modifier_pan_h", &m_Input.scroll_modifier_pan_h, WXK_CONTROL ) );
  87. m_params.emplace_back( new PARAM<int>(
  88. "input.scroll_modifier_pan_v", &m_Input.scroll_modifier_pan_v, WXK_SHIFT ) );
  89. m_params.emplace_back( new PARAM<int>( "input.mouse_middle", &m_Input.drag_middle,
  90. static_cast<int>( MOUSE_DRAG_ACTION::PAN ),
  91. static_cast<int>( MOUSE_DRAG_ACTION::SELECT ),
  92. static_cast<int>( MOUSE_DRAG_ACTION::NONE ) ) );
  93. m_params.emplace_back( new PARAM<int>( "input.mouse_right", &m_Input.drag_right,
  94. static_cast<int>( MOUSE_DRAG_ACTION::PAN ),
  95. static_cast<int>( MOUSE_DRAG_ACTION::SELECT ),
  96. static_cast<int>( MOUSE_DRAG_ACTION::NONE ) ) );
  97. m_params.emplace_back( new PARAM<int>( "graphics.opengl_antialiasing_mode",
  98. &m_Graphics.opengl_aa_mode, 0, 0, 4 ) );
  99. m_params.emplace_back( new PARAM<int>( "graphics.cairo_antialiasing_mode",
  100. &m_Graphics.cairo_aa_mode, 0, 0, 3 ) );
  101. m_params.emplace_back( new PARAM<int>( "system.autosave_interval",
  102. &m_System.autosave_interval, 600 ) );
  103. m_params.emplace_back( new PARAM<wxString>( "system.editor_name",
  104. &m_System.editor_name, "" ) );
  105. m_params.emplace_back( new PARAM<int>( "system.file_history_size",
  106. &m_System.file_history_size, 9 ) );
  107. m_params.emplace_back( new PARAM<wxString>( "system.language",
  108. &m_System.language, "Default" ) );
  109. m_params.emplace_back( new PARAM<wxString>( "system.pdf_viewer_name",
  110. &m_System.pdf_viewer_name, "" ) );
  111. m_params.emplace_back( new PARAM<bool>( "system.use_system_pdf_viewer",
  112. &m_System.use_system_pdf_viewer, true ) );
  113. m_params.emplace_back( new PARAM<wxString>( "system.working_dir",
  114. &m_System.working_dir, "" ) );
  115. }
  116. bool COMMON_SETTINGS::Migrate()
  117. {
  118. bool ret = true;
  119. int filever = at( PointerFromString( "meta.version" ) ).get<int>();
  120. if( filever == 0 )
  121. {
  122. ret &= migrateSchema0to1();
  123. if( ret )
  124. {
  125. ( *this )[PointerFromString( "meta.version" )] = 1;
  126. }
  127. }
  128. return ret;
  129. }
  130. bool COMMON_SETTINGS::migrateSchema0to1()
  131. {
  132. /**
  133. * Schema version 0 to 1:
  134. *
  135. * mousewheel_pan is replaced by explicit settings for scroll wheel behavior
  136. */
  137. nlohmann::json::json_pointer mwp_pointer( "/input/mousewheel_pan"_json_pointer );
  138. bool mwp = false;
  139. try
  140. {
  141. mwp = at( mwp_pointer );
  142. at( nlohmann::json::json_pointer( "/input"_json_pointer ) ).erase( "mousewheel_pan" );
  143. }
  144. catch( ... )
  145. {
  146. wxLogTrace( traceSettings, "COMMON_SETTINGS::Migrate 0->1: mousewheel_pan not found" );
  147. }
  148. if( mwp )
  149. {
  150. ( *this )[nlohmann::json::json_pointer( "/input/horizontal_pan" )] = true;
  151. ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_h" )] = WXK_SHIFT;
  152. ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_v" )] = 0;
  153. ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_zoom" )] = WXK_CONTROL;
  154. }
  155. else
  156. {
  157. ( *this )[nlohmann::json::json_pointer( "/input/horizontal_pan" )] = false;
  158. ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_h" )] = WXK_CONTROL;
  159. ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_pan_v" )] = WXK_SHIFT;
  160. ( *this )[nlohmann::json::json_pointer( "/input/scroll_modifier_zoom" )] = 0;
  161. }
  162. return true;
  163. }
  164. bool COMMON_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
  165. {
  166. bool ret = true;
  167. ret &= fromLegacy<double>( aCfg, "CanvasScale", "appearance.canvas_scale" );
  168. ret &= fromLegacy<int>( aCfg, "IconScale", "appearance.icon_scale" );
  169. ret &= fromLegacy<bool>( aCfg, "UseIconsInMenus", "appearance.use_icons_in_menus" );
  170. ret &= fromLegacy<bool>( aCfg, "ShowEnvVarWarningDialog", "environment.show_warning_dialog" );
  171. auto load_env_vars = [&] () {
  172. wxString key, value;
  173. long index = 0;
  174. nlohmann::json::json_pointer ptr = PointerFromString( "environment.vars" );
  175. aCfg->SetPath( "EnvironmentVariables" );
  176. ( *this )[ptr] = nlohmann::json( {} );
  177. while( aCfg->GetNextEntry( key, index ) )
  178. {
  179. value = aCfg->Read( key, wxEmptyString );
  180. if( !value.IsEmpty() )
  181. {
  182. ptr.push_back( key.ToStdString() );
  183. wxLogTrace( traceSettings, "Migrate Env: %s=%s", ptr.to_string(), value );
  184. ( *this )[ptr] = value.ToUTF8();
  185. ptr.pop_back();
  186. }
  187. }
  188. aCfg->SetPath( ".." );
  189. };
  190. load_env_vars();
  191. bool mousewheel_pan = false;
  192. if( aCfg->Read( "MousewheelPAN", &mousewheel_pan ) && mousewheel_pan )
  193. {
  194. ( *this )[PointerFromString( "input.horizontal_pan" )] = true;
  195. ( *this )[PointerFromString( "input.scroll_modifier_pan_h" )] = WXK_SHIFT;
  196. ( *this )[PointerFromString( "input.scroll_modifier_pan_v" )] = 0;
  197. ( *this )[PointerFromString( "input.scroll_modifier_zoom" )] = WXK_CONTROL;
  198. }
  199. ret &= fromLegacy<bool>( aCfg, "AutoPAN", "input.auto_pan" );
  200. ret &= fromLegacy<bool>( aCfg, "ImmediateActions", "input.immediate_actions" );
  201. ret &= fromLegacy<bool>( aCfg, "PreferSelectionToDragging", "input.prefer_select_to_drag" );
  202. ret &= fromLegacy<bool>( aCfg, "MoveWarpsCursor", "input.warp_mouse_on_move" );
  203. ret &= fromLegacy<bool>( aCfg, "ZoomNoCenter", "input.center_on_zoom" );
  204. // This was stored inverted in legacy config
  205. if( ret )
  206. {
  207. auto p = PointerFromString( "input.center_on_zoom" );
  208. ( *this )[p] = !( *this )[p];
  209. }
  210. ret &= fromLegacy<int>( aCfg, "OpenGLAntialiasingMode", "graphics.opengl_antialiasing_mode" );
  211. ret &= fromLegacy<int>( aCfg, "CairoAntialiasingMode", "graphics.cairo_antialiasing_mode" );
  212. ret &= fromLegacy<int>( aCfg, "AutoSaveInterval", "system.autosave_interval" );
  213. ret &= fromLegacyString( aCfg, "Editor", "system.editor_name" );
  214. ret &= fromLegacy<int>( aCfg, "FileHistorySize", "system.file_history_size" );
  215. ret &= fromLegacyString( aCfg, "LanguageID", "system.language" );
  216. ret &= fromLegacyString( aCfg, "PdfBrowserName", "system.pdf_viewer_name" );
  217. ret &= fromLegacy<bool>( aCfg, "UseSystemBrowser", "system.use_system_pdf_viewer" );
  218. ret &= fromLegacyString( aCfg, "WorkingDir", "system.working_dir" );
  219. return ret;
  220. }