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-2022 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 <common.h>
23#include <eda_units.h>
24#include <layer_ids.h>
25#include <pgm_base.h>
29#include <settings/parameters.h>
30#include <base_units.h>
31
32
33APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaVersion ) :
34 JSON_SETTINGS( aFilename, SETTINGS_LOC::USER, aSchemaVersion ),
35 m_CrossProbing(),
36 m_FindReplace(),
37 m_Graphics(),
38 m_ColorPicker(),
39 m_LibTree(),
40 m_Printing(),
41 m_System(),
42 m_Window(),
43 m_appSettingsSchemaVersion( aSchemaVersion )
44{
45 // Make Coverity happy:
47
48 // Build parameters list:
49 m_params.emplace_back(
50 new PARAM<int>( "find_replace.match_mode", &m_FindReplace.match_mode, 0 ) );
51
52 m_params.emplace_back(
53 new PARAM<bool>( "find_replace.match_case", &m_FindReplace.match_case, false ) );
54
55 m_params.emplace_back( new PARAM<bool>( "find_replace.search_and_replace",
57
58 m_params.emplace_back( new PARAM<wxString>( "find_replace.find_string",
60
61 m_params.emplace_back( new PARAM_LIST<wxString>( "find_replace.find_history",
63
64 m_params.emplace_back( new PARAM<wxString>( "find_replace.replace_string",
66
67 m_params.emplace_back( new PARAM_LIST<wxString>( "find_replace.replace_history",
69
70 m_params.emplace_back( new PARAM<int>( "graphics.canvas_type",
72
73 m_params.emplace_back( new PARAM<float>( "graphics.highlight_factor",
74 &m_Graphics.highlight_factor, 0.5f, 0.0, 1.0f ) );
75
76 m_params.emplace_back( new PARAM<float>( "graphics.select_factor",
77 &m_Graphics.select_factor, 0.75f, 0.0, 1.0f ) );
78
79 m_params.emplace_back( new PARAM<int>( "color_picker.default_tab",
81
82 m_params.emplace_back( new PARAM_LIST<wxString>( "lib_tree.columns", &m_LibTree.columns, {} ) );
83
84 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "lib_tree.column_widths",
85 [&]() -> nlohmann::json
86 {
87 nlohmann::json ret = {};
88
89 for( const std::pair<const wxString, int>& pair : m_LibTree.column_widths )
90 ret[std::string( pair.first.ToUTF8() )] = pair.second;
91
92 return ret;
93 },
94 [&]( const nlohmann::json& aJson )
95 {
96 if( !aJson.is_object() )
97 return;
98
100
101 for( const auto& entry : aJson.items() )
102 {
103 if( !entry.value().is_number_integer() )
104 continue;
105
106 m_LibTree.column_widths[ entry.key() ] = entry.value().get<int>();
107 }
108 },
109 {} ) );
110
111 m_params.emplace_back( new PARAM<bool>( "printing.background",
112 &m_Printing.background, false ) );
113
114 m_params.emplace_back( new PARAM<bool>( "printing.monochrome",
115 &m_Printing.monochrome, true ) );
116
117 m_params.emplace_back( new PARAM<double>( "printing.scale",
118 &m_Printing.scale, 1.0 ) );
119
120 m_params.emplace_back( new PARAM<bool>( "printing.use_theme",
121 &m_Printing.use_theme, false ) );
122
123 m_params.emplace_back( new PARAM<wxString>( "printing.color_theme",
124 &m_Printing.color_theme, "" ) );
125
126 m_params.emplace_back( new PARAM<bool>( "printing.title_block",
127 &m_Printing.title_block, false ) );
128
129 m_params.emplace_back( new PARAM_LIST<int>( "printing.layers",
130 &m_Printing.layers, {} ) );
131
132 m_params.emplace_back( new PARAM<bool>( "system.first_run_shown",
133 &m_System.first_run_shown, false ) );
134
135 m_params.emplace_back( new PARAM<int>( "system.max_undo_items",
136 &m_System.max_undo_items, 0 ) );
137
138 m_params.emplace_back( new PARAM_LIST<wxString>( "system.file_history",
139 &m_System.file_history, {} ) );
140
141 m_params.emplace_back( new PARAM<int>( "system.units",
142 &m_System.units, static_cast<int>( EDA_UNITS::MILLIMETRES ) ) );
143
144 m_params.emplace_back( new PARAM<int>( "system.last_metric_units",
145 &m_System.last_metric_units, static_cast<int>( EDA_UNITS::MILLIMETRES ) ) );
146
147 m_params.emplace_back( new PARAM<int>( "system.last_imperial_units",
148 &m_System.last_imperial_units, static_cast<int>( EDA_UNITS::INCHES ) ) );
149
150 m_params.emplace_back( new PARAM<wxString>( "appearance.color_theme",
151 &m_ColorTheme, "_builtin_default" ) );
152
153 addParamsForWindow( &m_Window, "window" );
154
155 m_params.emplace_back( new PARAM<bool>( "cross_probing.on_selection",
156 &m_CrossProbing.on_selection, true ) );
157
158 m_params.emplace_back( new PARAM<bool>( "cross_probing.center_on_items",
160
161 m_params.emplace_back( new PARAM<bool>( "cross_probing.zoom_to_fit",
162 &m_CrossProbing.zoom_to_fit, true ) );
163
164 m_params.emplace_back( new PARAM<bool>( "cross_probing.auto_highlight",
166}
167
168
169bool APP_SETTINGS_BASE::MigrateFromLegacy( wxConfigBase* aCfg )
170{
171 bool ret = true;
172
173 const std::string f = getLegacyFrameName();
174
175 ret &= fromLegacyString( aCfg, "LastFindString", "find_replace.find_string" );
176 ret &= fromLegacyString( aCfg, "LastReplaceString", "find_replace.replace_string" );
177
178 migrateFindReplace( aCfg );
179
180 ret &= fromLegacy<int>( aCfg, "canvas_type", "graphics.canvas_type" );
181
182 ret &= fromLegacy<int>( aCfg, "P22LIB_TREE_MODEL_ADAPTERSelectorColumnWidth",
183 "lib_tree.column_width" );
184
185 ret &= fromLegacy<bool>( aCfg, "PrintMonochrome", "printing.monochrome" );
186 ret &= fromLegacy<double>( aCfg, "PrintScale", "printing.scale" );
187 ret &= fromLegacy<bool>( aCfg, "PrintPageFrame", "printing.title_block" );
188
189 {
190 nlohmann::json js = nlohmann::json::array();
191 wxString key;
192 bool val = false;
193
194 for( unsigned i = 0; i < PCB_LAYER_ID_COUNT; ++i )
195 {
196 key.Printf( wxT( "PlotLayer_%d" ), i );
197
198 if( aCfg->Read( key, &val ) && val )
199 js.push_back( i );
200 }
201
202 Set( "printing.layers", js );
203 }
204
205 ret &= fromLegacy<bool>( aCfg, f + "FirstRunShown", "system.first_run_shown" );
206 ret &= fromLegacy<int>( aCfg, f + "DevelMaxUndoItems", "system.max_undo_items" );
207 ret &= fromLegacy<int>( aCfg, f + "Units", "system.units" );
208
209 {
210 int max_history_size = Pgm().GetCommonSettings()->m_System.file_history_size;
211 wxString file, key;
212 nlohmann::json js = nlohmann::json::array();
213
214 for( int i = 1; i <= max_history_size; i++ )
215 {
216 key.Printf( "file%d", i );
217 file = aCfg->Read( key, wxEmptyString );
218
219 if( !file.IsEmpty() )
220 js.push_back( file.ToStdString() );
221 }
222
223 Set( "system.file_history", js );
224 }
225
226 ret &= migrateWindowConfig( aCfg, f, "window" );
227
228 return ret;
229}
230
231
233{
234 const int find_replace_history_size = 10;
235 nlohmann::json find_history = nlohmann::json::array();
236 nlohmann::json replace_history = nlohmann::json::array();
237 wxString tmp, find_key, replace_key;
238
239 for( int i = 0; i < find_replace_history_size; ++i )
240 {
241 find_key.Printf( "FindStringHistoryList%d", i );
242 replace_key.Printf( "ReplaceStringHistoryList%d", i );
243
244 if( aCfg->Read( find_key, &tmp ) )
245 find_history.push_back( tmp.ToStdString() );
246
247 if( aCfg->Read( replace_key, &tmp ) )
248 replace_history.push_back( tmp.ToStdString() );
249 }
250
251 Set( "find_replace.find_history", find_history );
252 Set( "find_replace.replace_history", replace_history );
253}
254
255
256bool APP_SETTINGS_BASE::migrateWindowConfig( wxConfigBase* aCfg, const std::string& aFrame,
257 const std::string& aJsonPath )
258{
259 bool ret = true;
260
261 const std::string frameGDO = aFrame + "GalDisplayOptions";
262 const std::string cursorPath = aJsonPath + ".cursor";
263 const std::string gridPath = aJsonPath + ".grid";
264
265 ret &= fromLegacy<bool>( aCfg, aFrame + "Maximized", aJsonPath + ".maximized" );
266 ret &= fromLegacyString( aCfg, aFrame + "MostRecentlyUsedPath", aJsonPath + ".mru_path" );
267 ret &= fromLegacy<int>( aCfg, aFrame + "Size_x", aJsonPath + ".size_x" );
268 ret &= fromLegacy<int>( aCfg, aFrame + "Size_y", aJsonPath + ".size_y" );
269 ret &= fromLegacyString( aCfg, aFrame + "Perspective", aJsonPath + ".perspective" );
270 ret &= fromLegacy<int>( aCfg, aFrame + "Pos_x", aJsonPath + ".pos_x" );
271 ret &= fromLegacy<int>( aCfg, aFrame + "Pos_y", aJsonPath + ".pos_y" );
272
273 ret &= fromLegacy<bool>( aCfg, frameGDO + "ForceDisplayCursor", cursorPath + ".always_show_cursor" );
274 ret &= fromLegacy<bool>( aCfg, frameGDO + "CursorFullscreen", cursorPath + ".fullscreen_cursor" );
275
276 ret &= fromLegacy<int>( aCfg, aFrame + "_LastGridSize", gridPath + ".last_size" );
277
278 ret &= fromLegacy<int>( aCfg, aFrame + "FastGrid1", gridPath + ".fast_grid_1" );
279 ret &= fromLegacy<int>( aCfg, aFrame + "FastGrid2", gridPath + ".fast_grid_2" );
280
281 ret &= fromLegacy<bool>( aCfg, frameGDO + "GridAxesEnabled", gridPath + ".axes_enabled" );
282 ret &= fromLegacy<double>( aCfg, frameGDO + "GridLineWidth", gridPath + ".line_width" );
283 ret &= fromLegacy<double>( aCfg, frameGDO + "GridMaxDensity", gridPath + ".min_spacing" );
284 ret &= fromLegacy<bool>( aCfg, frameGDO + "ShowGrid", gridPath + ".show" );
285 ret &= fromLegacy<int>( aCfg, frameGDO + "GridStyle", gridPath + ".style" );
286 ret &= fromLegacyColor( aCfg, frameGDO + "GridColor", gridPath + ".color" );
287
288 return ret;
289}
290
291
292void APP_SETTINGS_BASE::addParamsForWindow( WINDOW_SETTINGS* aWindow, const std::string& aJsonPath )
293{
294 m_params.emplace_back( new PARAM<bool>( aJsonPath + ".maximized",
295 &aWindow->state.maximized, false ) );
296
297 m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".mru_path",
298 &aWindow->mru_path, "" ) );
299
300 m_params.emplace_back( new PARAM<int>( aJsonPath + ".size_x", &aWindow->state.size_x, 0 ) );
301
302 m_params.emplace_back( new PARAM<int>( aJsonPath + ".size_y", &aWindow->state.size_y, 0 ) );
303
304 m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".perspective",
305 &aWindow->perspective, "" ) );
306
307 m_params.emplace_back( new PARAM<int>( aJsonPath + ".pos_x", &aWindow->state.pos_x, 0 ) );
308
309 m_params.emplace_back( new PARAM<int>( aJsonPath + ".pos_y", &aWindow->state.pos_y, 0 ) );
310
311 m_params.emplace_back( new PARAM<unsigned int>( aJsonPath + ".display", &aWindow->state.display, 0 ) );
312
313 m_params.emplace_back( new PARAM_LIST<double>( aJsonPath + ".zoom_factors",
314 &aWindow->zoom_factors, {} ) );
315
316 m_params.emplace_back( new PARAM<bool>( aJsonPath + ".grid.axes_enabled",
317 &aWindow->grid.axes_enabled, false ) );
318
319 m_params.emplace_back( new PARAM_LIST<wxString>( aJsonPath + ".grid.sizes",
320 &aWindow->grid.sizes, DefaultGridSizeList() ) );
321
322 int defaultGridIdx;
323
324 if( m_filename == "eeschema" || m_filename == "symbol_editor" || m_filename == "pl_editor" )
325 defaultGridIdx = 1;
326 else
327 defaultGridIdx = 4;
328
329 m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.last_size",
330 &aWindow->grid.last_size_idx, defaultGridIdx ) );
331
332 m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.fast_grid_1",
333 &aWindow->grid.fast_grid_1, defaultGridIdx ) );
334
335 m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.fast_grid_2",
336 &aWindow->grid.fast_grid_2, defaultGridIdx + 1 ) );
337
338 // for grid user, use a default value compatible with eeschema and pcbnew (10 mils)
339 m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".grid.user_grid_x",
340 &aWindow->grid.user_grid_x, "10 mil" ) );
341 m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".grid.user_grid_y",
342 &aWindow->grid.user_grid_y, "10 mil" ) );
343
344 m_params.emplace_back( new PARAM<double>( aJsonPath + ".grid.line_width",
345 &aWindow->grid.line_width, 1.0 ) );
346
347 m_params.emplace_back( new PARAM<double>( aJsonPath + ".grid.min_spacing",
348 &aWindow->grid.min_spacing, 10 ) );
349
350 m_params.emplace_back( new PARAM<bool>( aJsonPath + ".grid.show",
351 &aWindow->grid.show, true ) );
352
353 m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.style",
354 &aWindow->grid.style, 0 ) );
355
356 m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.snap",
357 &aWindow->grid.snap, 0 ) );
358
359 m_params.emplace_back( new PARAM<bool>( aJsonPath + ".cursor.always_show_cursor",
360 &aWindow->cursor.always_show_cursor, true ) );
361
362 m_params.emplace_back( new PARAM<bool>( aJsonPath + ".cursor.fullscreen_cursor",
363 &aWindow->cursor.fullscreen_cursor, false ) );
364}
365
366
367const std::vector<wxString> APP_SETTINGS_BASE::DefaultGridSizeList() const
368{
369 return { "1000 mil",
370 "500 mil",
371 "250 mil",
372 "200 mil",
373 "100 mil",
374 "50 mil",
375 "25 mil",
376 "20 mil",
377 "10 mil",
378 "5 mil",
379 "2 mil",
380 "1 mil",
381 "5.0 mm",
382 "2.5 mm",
383 "1.0 mm",
384 "0.5 mm",
385 "0.25 mm",
386 "0.2 mm",
387 "0.1 mm",
388 "0.05 mm",
389 "0.025 mm",
390 "0.01 mm" };
391}
392
393
395{
396 // We used to store only the width of the first column, because there were only
397 // two possible columns.
398 if( std::optional<int> optWidth = Get<int>( "lib_tree.column_width" ) )
399 {
400 Set<nlohmann::json>( "lib_tree.column_widths", { { "Item", *optWidth } } );
401 At( "lib_tree" ).erase( "column_width" );
402 }
403
404 return true;
405}
WINDOW_SETTINGS m_Window
Definition: app_settings.h:184
APP_SETTINGS_BASE(const std::string &aFilename, int aSchemaVersion)
FIND_REPLACE m_FindReplace
Definition: app_settings.h:172
bool migrateWindowConfig(wxConfigBase *aCfg, const std::string &aFrameName, const std::string &aJsonPath)
Migrates legacy window settings into the JSON document.
void migrateFindReplace(wxConfigBase *aCfg)
! Migrates the find/replace history string lists
virtual const std::vector< wxString > DefaultGridSizeList() const
By default, this returns the list of grids available in PcbNew-based applications.
COLOR_PICKER m_ColorPicker
Definition: app_settings.h:176
virtual std::string getLegacyFrameName() const
Definition: app_settings.h:194
virtual bool MigrateFromLegacy(wxConfigBase *aCfg) override
Migrates from wxConfig to JSON-based configuration.
wxString m_ColorTheme
Active color theme name.
Definition: app_settings.h:187
CROSS_PROBING_SETTINGS m_CrossProbing
Definition: app_settings.h:170
void addParamsForWindow(WINDOW_SETTINGS *aWindow, const std::string &aJsonPath)
Adds parameters for the given window object.
bool migrateLibTreeWidth()
Migrates the library tree width setting from a single column (Item) to multi-column.
static constexpr GAL_TYPE GAL_FALLBACK
bool fromLegacyString(wxConfigBase *aConfig, const std::string &aKey, const std::string &aDest)
Translates a legacy wxConfig string value to a given JSON pointer value.
wxString m_filename
The filename (not including path) of this settings file (inicode)
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.
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
nlohmann::json & At(const std::string &aPath)
Wrappers for the underlying JSON API so that most consumers don't need json.hpp All of these function...
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...
The common library.
nlohmann::json json
Definition: gerbview.cpp:44
SETTINGS_LOC
Definition: json_settings.h:47
@ USER
The main config directory (e.g. ~/.config/kicad/)
@ PCB_LAYER_ID_COUNT
Definition: layer_ids.h:137
see class PGM_BASE
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111
std::vector< wxString > replace_history
Definition: app_settings.h:108
std::vector< wxString > find_history
Definition: app_settings.h:106
float highlight_factor
How much to brighten highlighted objects by.
Definition: app_settings.h:119
float select_factor
How much to brighten selected objects by.
Definition: app_settings.h:120
std::vector< wxString > columns
Ordered list of visible columns in the tree.
Definition: app_settings.h:130
std::map< wxString, int > column_widths
Column widths, keyed by header name.
Definition: app_settings.h:131
bool monochrome
Whether or not to print in monochrome.
Definition: app_settings.h:137
bool background
Whether or not to print background color.
Definition: app_settings.h:136
std::vector< int > layers
List of enabled layers for printing.
Definition: app_settings.h:142
wxString color_theme
Color theme to use for printing.
Definition: app_settings.h:140
double scale
Printout scale.
Definition: app_settings.h:138
bool title_block
Whether or not to print title block.
Definition: app_settings.h:141
bool use_theme
If false, display color theme will be used.
Definition: app_settings.h:139
std::vector< wxString > file_history
Definition: app_settings.h:149
bool on_selection
Synchronize the selection for multiple items too.
Definition: app_settings.h:32
bool zoom_to_fit
Zoom to fit items (ignored if center_on_items is off)
Definition: app_settings.h:34
bool center_on_items
Automatically pan to cross-probed items.
Definition: app_settings.h:33
bool auto_highlight
Automatically turn on highlight mode in the target frame.
Definition: app_settings.h:35
bool always_show_cursor
Definition: app_settings.h:43
bool fullscreen_cursor
Definition: app_settings.h:44
wxString user_grid_x
Definition: app_settings.h:54
double line_width
Definition: app_settings.h:59
wxString user_grid_y
Definition: app_settings.h:55
double min_spacing
Definition: app_settings.h:60
std::vector< wxString > sizes
Definition: app_settings.h:53
Stores the common settings that are saved and loaded for each window / frame.
Definition: app_settings.h:83
CURSOR_SETTINGS cursor
Definition: app_settings.h:89
WINDOW_STATE state
Definition: app_settings.h:84
GRID_SETTINGS grid
Definition: app_settings.h:90
wxString mru_path
Definition: app_settings.h:85
std::vector< double > zoom_factors
Definition: app_settings.h:87
wxString perspective
Definition: app_settings.h:86
unsigned int display
Definition: app_settings.h:76