KiCad PCB EDA Suite
app_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 <[email protected]>
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 
21 #include <class_draw_panel_gal.h>
22 #include <common.h>
23 #include <layer_ids.h>
24 #include <pgm_base.h>
25 #include <settings/app_settings.h>
28 #include <settings/parameters.h>
29 #include <base_units.h>
30 
33 
34 
35 APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaVersion ) :
36  JSON_SETTINGS( aFilename, SETTINGS_LOC::USER, aSchemaVersion ),
37  m_CrossProbing(),
38  m_FindReplace(),
39  m_Graphics(),
40  m_ColorPicker(),
41  m_LibTree(),
42  m_Printing(),
43  m_System(),
44  m_Window(),
45  m_appSettingsSchemaVersion( aSchemaVersion )
46 {
47  // Make Coverity happy:
48  m_LibTree.column_width = 360;
50 
51  // Build parameters list:
52  m_params.emplace_back( new PARAM<int>( "find_replace.flags", &m_FindReplace.flags, 1 ) );
53 
54  m_params.emplace_back( new PARAM<wxString>( "find_replace.find_string",
55  &m_FindReplace.find_string, "" ) );
56 
57  m_params.emplace_back( new PARAM_LIST<wxString>( "find_replace.find_history",
58  &m_FindReplace.find_history, {} ) );
59 
60  m_params.emplace_back( new PARAM<wxString>( "find_replace.replace_string",
62 
63  m_params.emplace_back( new PARAM_LIST<wxString>( "find_replace.replace_history",
65 
66  m_params.emplace_back( new PARAM<int>( "graphics.canvas_type",
68 
69  m_params.emplace_back( new PARAM<float>(
70  "graphics.highlight_factor", &m_Graphics.highlight_factor, 0.5f, 0.0, 1.0f ) );
71 
72  m_params.emplace_back( new PARAM<float>(
73  "graphics.select_factor", &m_Graphics.select_factor, 0.75f, 0.0, 1.0f ) );
74 
75  m_params.emplace_back( new PARAM<float>(
76  "graphics.high_contrast_factor", &m_Graphics.high_contrast_factor, 0.35f, 0.0, 1.0f ) );
77 
78  m_params.emplace_back( new PARAM<int>( "color_picker.default_tab",
79  &m_ColorPicker.default_tab, 0 ) );
80 
81  m_params.emplace_back( new PARAM<int>( "lib_tree.column_width",
82  &m_LibTree.column_width, 360 ) );
83 
84  // Now that we allow hiding/showing of the tree control, it's never terribly useful to
85  // decrease the width to nothing, and wxWidgets appears to have some bugs where it sets it
86  // way too narrow.
87  if( m_LibTree.column_width < 360 )
88  m_LibTree.column_width = 360;
89 
90  m_params.emplace_back( new PARAM<bool>( "printing.background",
91  &m_Printing.background, false ) );
92 
93  m_params.emplace_back( new PARAM<bool>( "printing.monochrome",
94  &m_Printing.monochrome, true ) );
95 
96  m_params.emplace_back( new PARAM<double>( "printing.scale",
97  &m_Printing.scale, 1.0 ) );
98 
99  m_params.emplace_back( new PARAM<bool>( "printing.use_theme",
100  &m_Printing.use_theme, false ) );
101 
102  m_params.emplace_back( new PARAM<wxString>( "printing.color_theme",
103  &m_Printing.color_theme, "" ) );
104 
105  m_params.emplace_back( new PARAM<bool>( "printing.title_block",
106  &m_Printing.title_block, false ) );
107 
108  m_params.emplace_back( new PARAM_LIST<int>( "printing.layers",
109  &m_Printing.layers, {} ) );
110 
111  m_params.emplace_back( new PARAM<bool>( "system.first_run_shown",
112  &m_System.first_run_shown, false ) );
113 
114  m_params.emplace_back( new PARAM<int>( "system.max_undo_items",
115  &m_System.max_undo_items, 0 ) );
116 
117 
118  m_params.emplace_back( new PARAM_LIST<wxString>( "system.file_history",
119  &m_System.file_history, {} ) );
120 
121  m_params.emplace_back( new PARAM<int>( "system.units",
122  &m_System.units, static_cast<int>( EDA_UNITS::MILLIMETRES ) ) );
123 
124  m_params.emplace_back( new PARAM<int>( "system.last_metric_units",
125  &m_System.last_metric_units, static_cast<int>( EDA_UNITS::MILLIMETRES ) ) );
126 
127  m_params.emplace_back( new PARAM<int>( "system.last_imperial_units",
128  &m_System.last_imperial_units, static_cast<int>( EDA_UNITS::INCHES ) ) );
129 
130  m_params.emplace_back( new PARAM<wxString>( "appearance.color_theme",
131  &m_ColorTheme, "_builtin_default" ) );
132 
133  addParamsForWindow( &m_Window, "window" );
134 
135  m_params.emplace_back( new PARAM<bool>( "cross_probing.center_on_items",
136  &m_CrossProbing.center_on_items, true ) );
137 
138  m_params.emplace_back( new PARAM<bool>( "cross_probing.zoom_to_fit",
139  &m_CrossProbing.zoom_to_fit, true ) );
140 
141  m_params.emplace_back( new PARAM<bool>( "cross_probing.auto_highlight",
142  &m_CrossProbing.auto_highlight, true ) );
143 }
144 
145 
146 bool APP_SETTINGS_BASE::MigrateFromLegacy( wxConfigBase* aCfg )
147 {
148  bool ret = true;
149 
150  const std::string f = getLegacyFrameName();
151 
152  ret &= fromLegacyString( aCfg, "LastFindString", "find_replace.find_string" );
153  ret &= fromLegacyString( aCfg, "LastReplaceString", "find_replace.replace_string" );
154 
155  migrateFindReplace( aCfg );
156 
157  ret &= fromLegacy<int>( aCfg, "canvas_type", "graphics.canvas_type" );
158 
159  ret &= fromLegacy<int>( aCfg, "P22LIB_TREE_MODEL_ADAPTERSelectorColumnWidth",
160  "lib_tree.column_width" );
161 
162  ret &= fromLegacy<bool>( aCfg, "PrintMonochrome", "printing.monochrome" );
163  ret &= fromLegacy<double>( aCfg, "PrintScale", "printing.scale" );
164  ret &= fromLegacy<bool>( aCfg, "PrintPageFrame", "printing.title_block" );
165 
166  {
167  nlohmann::json js = nlohmann::json::array();
168  wxString key;
169  bool val = false;
170 
171  for( unsigned i = 0; i < PCB_LAYER_ID_COUNT; ++i )
172  {
173  key.Printf( wxT( "PlotLayer_%d" ), i );
174 
175  if( aCfg->Read( key, &val ) && val )
176  js.push_back( i );
177  }
178 
179  Set( "printing.layers", js );
180  }
181 
182  ret &= fromLegacy<bool>( aCfg, f + "FirstRunShown", "system.first_run_shown" );
183  ret &= fromLegacy<int>( aCfg, f + "DevelMaxUndoItems", "system.max_undo_items" );
184  ret &= fromLegacy<int>( aCfg, f + "Units", "system.units" );
185 
186  {
187  int max_history_size = Pgm().GetCommonSettings()->m_System.file_history_size;
188  wxString file, key;
189  nlohmann::json js = nlohmann::json::array();
190 
191  for( int i = 1; i <= max_history_size; i++ )
192  {
193  key.Printf( "file%d", i );
194  file = aCfg->Read( key, wxEmptyString );
195 
196  if( !file.IsEmpty() )
197  js.push_back( file.ToStdString() );
198  }
199 
200  Set( "system.file_history", js );
201  }
202 
203  ret &= migrateWindowConfig( aCfg, f, "window" );
204 
205  return ret;
206 }
207 
208 
209 void APP_SETTINGS_BASE::migrateFindReplace( wxConfigBase* aCfg )
210 {
211  const int find_replace_history_size = 10;
212  nlohmann::json find_history = nlohmann::json::array();
213  nlohmann::json replace_history = nlohmann::json::array();
214  wxString tmp, find_key, replace_key;
215 
216  for( int i = 0; i < find_replace_history_size; ++i )
217  {
218  find_key.Printf( "FindStringHistoryList%d", i );
219  replace_key.Printf( "ReplaceStringHistoryList%d", i );
220 
221  if( aCfg->Read( find_key, &tmp ) )
222  find_history.push_back( tmp.ToStdString() );
223 
224  if( aCfg->Read( replace_key, &tmp ) )
225  replace_history.push_back( tmp.ToStdString() );
226  }
227 
228  Set( "find_replace.find_history", find_history );
229  Set( "find_replace.replace_history", replace_history );
230 }
231 
232 
233 bool APP_SETTINGS_BASE::migrateWindowConfig( wxConfigBase* aCfg, const std::string& aFrame,
234  const std::string& aJsonPath )
235 {
236  bool ret = true;
237 
238  const std::string frameGDO = aFrame + "GalDisplayOptions";
239  const std::string cursorPath = aJsonPath + ".cursor";
240  const std::string gridPath = aJsonPath + ".grid";
241 
242  ret &= fromLegacy<bool>( aCfg, aFrame + "Maximized", aJsonPath + ".maximized" );
243  ret &= fromLegacyString( aCfg, aFrame + "MostRecentlyUsedPath", aJsonPath + ".mru_path" );
244  ret &= fromLegacy<int>( aCfg, aFrame + "Size_x", aJsonPath + ".size_x" );
245  ret &= fromLegacy<int>( aCfg, aFrame + "Size_y", aJsonPath + ".size_y" );
246  ret &= fromLegacyString( aCfg, aFrame + "Perspective", aJsonPath + ".perspective" );
247  ret &= fromLegacy<int>( aCfg, aFrame + "Pos_x", aJsonPath + ".pos_x" );
248  ret &= fromLegacy<int>( aCfg, aFrame + "Pos_y", aJsonPath + ".pos_y" );
249 
250  ret &= fromLegacy<bool>( aCfg, frameGDO + "ForceDisplayCursor", cursorPath + ".always_show_cursor" );
251  ret &= fromLegacy<bool>( aCfg, frameGDO + "CursorFullscreen", cursorPath + ".fullscreen_cursor" );
252 
253  ret &= fromLegacy<int>( aCfg, aFrame + "_LastGridSize", gridPath + ".last_size" );
254 
255  ret &= fromLegacy<int>( aCfg, aFrame + "FastGrid1", gridPath + ".fast_grid_1" );
256  ret &= fromLegacy<int>( aCfg, aFrame + "FastGrid2", gridPath + ".fast_grid_2" );
257 
258  ret &= fromLegacy<bool>( aCfg, frameGDO + "GridAxesEnabled", gridPath + ".axes_enabled" );
259  ret &= fromLegacy<double>( aCfg, frameGDO + "GridLineWidth", gridPath + ".line_width" );
260  ret &= fromLegacy<double>( aCfg, frameGDO + "GridMaxDensity", gridPath + ".min_spacing" );
261  ret &= fromLegacy<bool>( aCfg, frameGDO + "ShowGrid", gridPath + ".show" );
262  ret &= fromLegacy<int>( aCfg, frameGDO + "GridStyle", gridPath + ".style" );
263  ret &= fromLegacyColor( aCfg, frameGDO + "GridColor", gridPath + ".color" );
264 
265  return ret;
266 }
267 
268 
269 void APP_SETTINGS_BASE::addParamsForWindow( WINDOW_SETTINGS* aWindow, const std::string& aJsonPath )
270 {
271  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".maximized",
272  &aWindow->state.maximized, false ) );
273 
274  m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".mru_path",
275  &aWindow->mru_path, "" ) );
276 
277  m_params.emplace_back( new PARAM<int>( aJsonPath + ".size_x", &aWindow->state.size_x, 0 ) );
278 
279  m_params.emplace_back( new PARAM<int>( aJsonPath + ".size_y", &aWindow->state.size_y, 0 ) );
280 
281  m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".perspective",
282  &aWindow->perspective, "" ) );
283 
284  m_params.emplace_back( new PARAM<int>( aJsonPath + ".pos_x", &aWindow->state.pos_x, 0 ) );
285 
286  m_params.emplace_back( new PARAM<int>( aJsonPath + ".pos_y", &aWindow->state.pos_y, 0 ) );
287 
288  m_params.emplace_back( new PARAM<unsigned int>( aJsonPath + ".display", &aWindow->state.display, 0 ) );
289 
290  m_params.emplace_back( new PARAM_LIST<double>( aJsonPath + ".zoom_factors",
291  &aWindow->zoom_factors, {} ) );
292 
293  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".grid.axes_enabled",
294  &aWindow->grid.axes_enabled, false ) );
295 
296  m_params.emplace_back( new PARAM_LIST<wxString>( aJsonPath + ".grid.sizes",
297  &aWindow->grid.sizes, DefaultGridSizeList() ) );
298 
299  // pcbnew default grid doesn't matter much, but eeschema does, so default to the index
300  // of the 50mil grid in eeschema
301  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.last_size",
302  &aWindow->grid.last_size_idx, 1 ) );
303 
304  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.fast_grid_1",
305  &aWindow->grid.fast_grid_1, 1 ) );
306 
307  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.fast_grid_2",
308  &aWindow->grid.fast_grid_2, 2 ) );
309 
310  // for grid user, use a default value compatible with eeschema and pcbnew (10 mils)
311  m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".grid.user_grid_x",
312  &aWindow->grid.user_grid_x, "10 mil" ) );
313  m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".grid.user_grid_y",
314  &aWindow->grid.user_grid_y, "10 mil" ) );
315 
316  m_params.emplace_back( new PARAM<double>( aJsonPath + ".grid.line_width",
317  &aWindow->grid.line_width, 1.0 ) );
318 
319  m_params.emplace_back( new PARAM<double>( aJsonPath + ".grid.min_spacing",
320  &aWindow->grid.min_spacing, 10 ) );
321 
322  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".grid.show",
323  &aWindow->grid.show, true ) );
324 
325  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.style",
326  &aWindow->grid.style, 0 ) );
327 
328  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.snap",
329  &aWindow->grid.snap, 0 ) );
330 
331  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".cursor.always_show_cursor",
332  &aWindow->cursor.always_show_cursor, true ) );
333 
334  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".cursor.fullscreen_cursor",
335  &aWindow->cursor.fullscreen_cursor, false ) );
336 }
337 
338 
339 const std::vector<wxString> APP_SETTINGS_BASE::DefaultGridSizeList() const
340 {
341  return { "1000 mil",
342  "500 mil",
343  "250 mil",
344  "200 mil",
345  "100 mil",
346  "50 mil",
347  "25 mil",
348  "20 mil",
349  "10 mil",
350  "5 mil",
351  "2 mil",
352  "1 mil",
353  "5.0 mm",
354  "2.5 mm",
355  "1.0 mm",
356  "0.5 mm",
357  "0.25 mm",
358  "0.2 mm",
359  "0.1 mm",
360  "0.05 mm",
361  "0.025 mm",
362  "0.01 mm" };
363 }
wxString mru_path
Definition: app_settings.h:84
void addParamsForWindow(WINDOW_SETTINGS *aWindow, const std::string &aJsonPath)
Adds parameters for the given window object.
bool fullscreen_cursor
Definition: app_settings.h:43
std::vector< wxString > file_history
Definition: app_settings.h:146
wxString user_grid_y
Definition: app_settings.h:54
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)
wxString user_grid_x
Definition: app_settings.h:53
std::vector< wxString > find_history
Definition: app_settings.h:108
Implementation of conversion functions that require both schematic and board internal units.
double min_spacing
Definition: app_settings.h:59
virtual bool MigrateFromLegacy(wxConfigBase *aCfg) override
Migrates from wxConfig to JSON-based configuration.
const int appSettingsSchemaVersion
! Update the schema version whenever a migration is required
static constexpr GAL_TYPE GAL_FALLBACK
SETTINGS_LOC
Definition: json_settings.h:46
wxString color_theme
Color theme to use for printing.
Definition: app_settings.h:137
bool title_block
Whether or not to print title block.
Definition: app_settings.h:138
void migrateFindReplace(wxConfigBase *aCfg)
! Migrates the find/replace history string lists
bool use_theme
If false, display color theme will be used.
Definition: app_settings.h:136
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
nlohmann::json json
Definition: gerbview.cpp:41
float high_contrast_factor
How much to darken inactive layers by.
Definition: app_settings.h:118
bool always_show_cursor
Definition: app_settings.h:42
std::vector< double > zoom_factors
Definition: app_settings.h:86
bool monochrome
Whether or not to print in monochrome.
Definition: app_settings.h:134
double line_width
Definition: app_settings.h:58
virtual std::string getLegacyFrameName() const
Definition: app_settings.h:191
Stores the common settings that are saved and loaded for each window / frame.
Definition: app_settings.h:81
wxString perspective
Definition: app_settings.h:85
std::vector< wxString > sizes
Definition: app_settings.h:52
CURSOR_SETTINGS cursor
Definition: app_settings.h:88
FIND_REPLACE m_FindReplace
Definition: app_settings.h:169
GRID_SETTINGS grid
Definition: app_settings.h:89
APP_SETTINGS_BASE(const std::string &aFilename, int aSchemaVersion)
std::vector< int > layers
List of enabled layers for printing.
Definition: app_settings.h:139
std::vector< wxString > replace_history
Definition: app_settings.h:110
float select_factor
How much to brighten selected objects by.
Definition: app_settings.h:117
bool background
Whether or not to print background color.
Definition: app_settings.h:133
bool zoom_to_fit
Zoom to fit items (ignored if center_on_items is off)
Definition: app_settings.h:33
WINDOW_SETTINGS m_Window
Definition: app_settings.h:181
bool auto_highlight
Automatically turn on highlight mode in the target frame.
Definition: app_settings.h:34
bool fromLegacyString(wxConfigBase *aConfig, const std::string &aKey, const std::string &aDest)
Translates a legacy wxConfig string value to a given JSON pointer value.
float highlight_factor
How much to brighten highlighted objects by.
Definition: app_settings.h:116
bool fromLegacyColor(wxConfigBase *aConfig, const std::string &aKey, const std::string &aDest)
Translates a legacy COLOR4D stored in a wxConfig string to a given JSON pointer value.
see class PGM_BASE
double scale
Printout scale.
Definition: app_settings.h:135
WINDOW_STATE state
Definition: app_settings.h:83
The main config directory (e.g. ~/.config/kicad/)
The common library.
CROSS_PROBING_SETTINGS m_CrossProbing
Definition: app_settings.h:167
COLOR_PICKER m_ColorPicker
Definition: app_settings.h:173
unsigned int display
Definition: app_settings.h:75
bool center_on_items
Automatically pan to cross-probed items.
Definition: app_settings.h:32
bool migrateWindowConfig(wxConfigBase *aCfg, const std::string &aFrameName, const std::string &aJsonPath)
Migrates legacy window settings into the JSON document.
virtual const std::vector< wxString > DefaultGridSizeList() const
By default, this returns the list of grids available in PcbNew-based applications.
wxString m_ColorTheme
Active color theme name.
Definition: app_settings.h:184