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 <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 
21 #include <class_draw_panel_gal.h>
22 #include <common.h>
24 #include <pgm_base.h>
25 #include <settings/app_settings.h>
27 #include <settings/parameters.h>
28 #include <base_units.h>
29 
32 
33 
34 APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaVersion ) :
35  JSON_SETTINGS( aFilename, SETTINGS_LOC::USER, aSchemaVersion ),
36  m_CrossProbing(),
37  m_FindReplace(),
38  m_Graphics(),
39  m_ColorPicker(),
40  m_LibTree(),
41  m_Printing(),
42  m_System(),
43  m_Window(),
44  m_appSettingsSchemaVersion( aSchemaVersion )
45 {
46  // Make Coverity happy:
47  m_LibTree.column_width = 360;
49 
50  // Build parameters list:
51  m_params.emplace_back( new PARAM<int>( "find_replace.flags", &m_FindReplace.flags, 1 ) );
52 
53  m_params.emplace_back( new PARAM<wxString>( "find_replace.find_string",
54  &m_FindReplace.find_string, "" ) );
55 
56  m_params.emplace_back( new PARAM_LIST<wxString>( "find_replace.find_history",
57  &m_FindReplace.find_history, {} ) );
58 
59  m_params.emplace_back( new PARAM<wxString>( "find_replace.replace_string",
61 
62  m_params.emplace_back( new PARAM_LIST<wxString>( "find_replace.replace_history",
64 
65  m_params.emplace_back( new PARAM<int>( "graphics.canvas_type",
67 
68  m_params.emplace_back( new PARAM<float>(
69  "graphics.highlight_factor", &m_Graphics.highlight_factor, 0.5f, 0.0, 1.0f ) );
70 
71  m_params.emplace_back( new PARAM<float>(
72  "graphics.select_factor", &m_Graphics.select_factor, 0.75f, 0.0, 1.0f ) );
73 
74  m_params.emplace_back( new PARAM<float>(
75  "graphics.high_contrast_factor", &m_Graphics.high_contrast_factor, 0.35f, 0.0, 1.0f ) );
76 
77  m_params.emplace_back( new PARAM<int>( "color_picker.default_tab",
78  &m_ColorPicker.default_tab, 0 ) );
79 
80  m_params.emplace_back( new PARAM<int>( "lib_tree.column_width",
81  &m_LibTree.column_width, 360 ) );
82 
83  m_params.emplace_back( new PARAM<bool>( "printing.background",
84  &m_Printing.background, false ) );
85 
86  m_params.emplace_back( new PARAM<bool>( "printing.monochrome",
87  &m_Printing.monochrome, true ) );
88 
89  m_params.emplace_back( new PARAM<double>( "printing.scale",
90  &m_Printing.scale, 1.0 ) );
91 
92  m_params.emplace_back( new PARAM<bool>( "printing.use_theme",
93  &m_Printing.use_theme, false ) );
94 
95  m_params.emplace_back( new PARAM<wxString>( "printing.color_theme",
96  &m_Printing.color_theme, "" ) );
97 
98  m_params.emplace_back( new PARAM<bool>( "printing.title_block",
99  &m_Printing.title_block, false ) );
100 
101  m_params.emplace_back( new PARAM_LIST<int>( "printing.layers",
102  &m_Printing.layers, {} ) );
103 
104  m_params.emplace_back( new PARAM<bool>( "system.first_run_shown",
105  &m_System.first_run_shown, false ) );
106 
107  m_params.emplace_back( new PARAM<int>( "system.max_undo_items",
108  &m_System.max_undo_items, 0 ) );
109 
110 
111  m_params.emplace_back( new PARAM_LIST<wxString>( "system.file_history",
112  &m_System.file_history, {} ) );
113 
114  m_params.emplace_back( new PARAM<int>( "system.units",
115  &m_System.units, static_cast<int>( EDA_UNITS::MILLIMETRES ) ) );
116 
117  m_params.emplace_back( new PARAM<int>( "system.last_metric_units",
118  &m_System.last_metric_units, static_cast<int>( EDA_UNITS::MILLIMETRES ) ) );
119 
120  m_params.emplace_back( new PARAM<int>( "system.last_imperial_units",
121  &m_System.last_imperial_units, static_cast<int>( EDA_UNITS::INCHES ) ) );
122 
123  m_params.emplace_back( new PARAM<wxString>( "appearance.color_theme",
124  &m_ColorTheme, "_builtin_default" ) );
125 
126  addParamsForWindow( &m_Window, "window" );
127 
128  m_params.emplace_back( new PARAM<bool>( "cross_probing.center_on_items",
129  &m_CrossProbing.center_on_items, true ) );
130 
131  m_params.emplace_back( new PARAM<bool>( "cross_probing.zoom_to_fit",
132  &m_CrossProbing.zoom_to_fit, true ) );
133 
134  m_params.emplace_back( new PARAM<bool>( "cross_probing.auto_highlight",
135  &m_CrossProbing.auto_highlight, true ) );
136 }
137 
138 
139 bool APP_SETTINGS_BASE::MigrateFromLegacy( wxConfigBase* aCfg )
140 {
141  bool ret = true;
142 
143  const std::string f = getLegacyFrameName();
144 
145  ret &= fromLegacyString( aCfg, "LastFindString", "find_replace.find_string" );
146  ret &= fromLegacyString( aCfg, "LastReplaceString", "find_replace.replace_string" );
147 
148  migrateFindReplace( aCfg );
149 
150  ret &= fromLegacy<int>( aCfg, "canvas_type", "graphics.canvas_type" );
151 
152  ret &= fromLegacy<int>( aCfg, "P22LIB_TREE_MODEL_ADAPTERSelectorColumnWidth",
153  "lib_tree.column_width" );
154 
155  ret &= fromLegacy<bool>( aCfg, "PrintMonochrome", "printing.monochrome" );
156  ret &= fromLegacy<double>( aCfg, "PrintScale", "printing.scale" );
157  ret &= fromLegacy<bool>( aCfg, "PrintPageFrame", "printing.title_block" );
158 
159  {
160  nlohmann::json js = nlohmann::json::array();
161  wxString key;
162  bool val = false;
163 
164  for( unsigned i = 0; i < PCB_LAYER_ID_COUNT; ++i )
165  {
166  key.Printf( wxT( "PlotLayer_%d" ), i );
167 
168  if( aCfg->Read( key, &val ) && val )
169  js.push_back( i );
170  }
171 
172  ( *this )[PointerFromString( "printing.layers" ) ] = js;
173  }
174 
175  ret &= fromLegacy<bool>( aCfg, f + "FirstRunShown", "system.first_run_shown" );
176  ret &= fromLegacy<int>( aCfg, f + "DevelMaxUndoItems", "system.max_undo_items" );
177  ret &= fromLegacy<int>( aCfg, f + "Units", "system.units" );
178 
179  {
180  int max_history_size = Pgm().GetCommonSettings()->m_System.file_history_size;
181  wxString file, key;
182  nlohmann::json js = nlohmann::json::array();
183 
184  for( int i = 1; i <= max_history_size; i++ )
185  {
186  key.Printf( "file%d", i );
187  file = aCfg->Read( key, wxEmptyString );
188 
189  if( !file.IsEmpty() )
190  js.push_back( file.ToStdString() );
191  }
192 
193  ( *this )[PointerFromString( "system.file_history" )] = js;
194  }
195 
196  ret &= migrateWindowConfig( aCfg, f, "window" );
197 
198  return ret;
199 }
200 
201 
202 void APP_SETTINGS_BASE::migrateFindReplace( wxConfigBase* aCfg )
203 {
204  const int find_replace_history_size = 10;
205  nlohmann::json find_history = nlohmann::json::array();
206  nlohmann::json replace_history = nlohmann::json::array();
207  wxString tmp, find_key, replace_key;
208 
209  for( int i = 0; i < find_replace_history_size; ++i )
210  {
211  find_key.Printf( "FindStringHistoryList%d", i );
212  replace_key.Printf( "ReplaceStringHistoryList%d", i );
213 
214  if( aCfg->Read( find_key, &tmp ) )
215  find_history.push_back( tmp.ToStdString() );
216 
217  if( aCfg->Read( replace_key, &tmp ) )
218  replace_history.push_back( tmp.ToStdString() );
219  }
220 
221  ( *this )[PointerFromString( "find_replace.find_history" )] = find_history;
222  ( *this )[PointerFromString( "find_replace.replace_history" )] = replace_history;
223 }
224 
225 
226 bool APP_SETTINGS_BASE::migrateWindowConfig( wxConfigBase* aCfg, const std::string& aFrame,
227  const std::string& aJsonPath )
228 {
229  bool ret = true;
230 
231  const std::string frameGDO = aFrame + "GalDisplayOptions";
232  const std::string cursorPath = aJsonPath + ".cursor";
233  const std::string gridPath = aJsonPath + ".grid";
234 
235  ret &= fromLegacy<bool>( aCfg, aFrame + "Maximized", aJsonPath + ".maximized" );
236  ret &= fromLegacyString( aCfg, aFrame + "MostRecentlyUsedPath", aJsonPath + ".mru_path" );
237  ret &= fromLegacy<int>( aCfg, aFrame + "Size_x", aJsonPath + ".size_x" );
238  ret &= fromLegacy<int>( aCfg, aFrame + "Size_y", aJsonPath + ".size_y" );
239  ret &= fromLegacyString( aCfg, aFrame + "Perspective", aJsonPath + ".perspective" );
240  ret &= fromLegacy<int>( aCfg, aFrame + "Pos_x", aJsonPath + ".pos_x" );
241  ret &= fromLegacy<int>( aCfg, aFrame + "Pos_y", aJsonPath + ".pos_y" );
242 
243  ret &= fromLegacy<bool>( aCfg, frameGDO + "ForceDisplayCursor", cursorPath + ".always_show_cursor" );
244  ret &= fromLegacy<bool>( aCfg, frameGDO + "CursorFullscreen", cursorPath + ".fullscreen_cursor" );
245 
246  ret &= fromLegacy<int>( aCfg, aFrame + "_LastGridSize", gridPath + ".last_size" );
247 
248  ret &= fromLegacy<int>( aCfg, aFrame + "FastGrid1", gridPath + ".fast_grid_1" );
249  ret &= fromLegacy<int>( aCfg, aFrame + "FastGrid2", gridPath + ".fast_grid_2" );
250 
251  ret &= fromLegacy<bool>( aCfg, frameGDO + "GridAxesEnabled", gridPath + ".axes_enabled" );
252  ret &= fromLegacy<double>( aCfg, frameGDO + "GridLineWidth", gridPath + ".line_width" );
253  ret &= fromLegacy<double>( aCfg, frameGDO + "GridMaxDensity", gridPath + ".min_spacing" );
254  ret &= fromLegacy<bool>( aCfg, frameGDO + "ShowGrid", gridPath + ".show" );
255  ret &= fromLegacy<int>( aCfg, frameGDO + "GridStyle", gridPath + ".style" );
256  ret &= fromLegacyColor( aCfg, frameGDO + "GridColor", gridPath + ".color" );
257 
258  return ret;
259 }
260 
261 
262 void APP_SETTINGS_BASE::addParamsForWindow( WINDOW_SETTINGS* aWindow, const std::string& aJsonPath )
263 {
264  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".maximized",
265  &aWindow->state.maximized, false ) );
266 
267  m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".mru_path",
268  &aWindow->mru_path, "" ) );
269 
270  m_params.emplace_back( new PARAM<int>( aJsonPath + ".size_x", &aWindow->state.size_x, 0 ) );
271 
272  m_params.emplace_back( new PARAM<int>( aJsonPath + ".size_y", &aWindow->state.size_y, 0 ) );
273 
274  m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".perspective",
275  &aWindow->perspective, "" ) );
276 
277  m_params.emplace_back( new PARAM<int>( aJsonPath + ".pos_x", &aWindow->state.pos_x, 0 ) );
278 
279  m_params.emplace_back( new PARAM<int>( aJsonPath + ".pos_y", &aWindow->state.pos_y, 0 ) );
280 
281  m_params.emplace_back( new PARAM<unsigned int>( aJsonPath + ".display", &aWindow->state.display, 0 ) );
282 
283  m_params.emplace_back( new PARAM_LIST<double>( aJsonPath + ".zoom_factors",
284  &aWindow->zoom_factors, {} ) );
285 
286  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".grid.axes_enabled",
287  &aWindow->grid.axes_enabled, false ) );
288 
289  m_params.emplace_back( new PARAM_LIST<wxString>( aJsonPath + ".grid.sizes",
290  &aWindow->grid.sizes, DefaultGridSizeList() ) );
291 
292  // pcbnew default grid doesn't matter much, but eeschema does, so default to the index
293  // of the 50mil grid in eeschema
294  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.last_size",
295  &aWindow->grid.last_size_idx, 1 ) );
296 
297  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.fast_grid_1",
298  &aWindow->grid.fast_grid_1, 1 ) );
299 
300  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.fast_grid_2",
301  &aWindow->grid.fast_grid_2, 2 ) );
302 
303  // for grid user, use a default value compatible with eeschema and pcbnew (10 mils)
304  m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".grid.user_grid_x",
305  &aWindow->grid.user_grid_x, "10 mil" ) );
306  m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".grid.user_grid_y",
307  &aWindow->grid.user_grid_y, "10 mil" ) );
308 
309  m_params.emplace_back( new PARAM<double>( aJsonPath + ".grid.line_width",
310  &aWindow->grid.line_width, 1.0 ) );
311 
312  m_params.emplace_back( new PARAM<double>( aJsonPath + ".grid.min_spacing",
313  &aWindow->grid.min_spacing, 10 ) );
314 
315  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".grid.show",
316  &aWindow->grid.show, true ) );
317 
318  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.style",
319  &aWindow->grid.style, 0 ) );
320 
321  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.snap",
322  &aWindow->grid.snap, 0 ) );
323 
324  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".cursor.always_show_cursor",
325  &aWindow->cursor.always_show_cursor, true ) );
326 
327  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".cursor.fullscreen_cursor",
328  &aWindow->cursor.fullscreen_cursor, false ) );
329 }
330 
331 
332 const std::vector<wxString> APP_SETTINGS_BASE::DefaultGridSizeList() const
333 {
334  return { "1000 mil",
335  "500 mil",
336  "250 mil",
337  "200 mil",
338  "100 mil",
339  "50 mil",
340  "25 mil",
341  "20 mil",
342  "10 mil",
343  "5 mil",
344  "2 mil",
345  "1 mil",
346  "5.0 mm",
347  "2.5 mm",
348  "1.0 mm",
349  "0.5 mm",
350  "0.25 mm",
351  "0.2 mm",
352  "0.1 mm",
353  "0.05 mm",
354  "0.025 mm",
355  "0.01 mm" };
356 }
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
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:44
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:40
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
Board layer functions and definitions.
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
static nlohmann::json::json_pointer PointerFromString(std::string aPath)
Builds a JSON pointer based on a given string.
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