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, {} ) );
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 }
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:102
nlohmann::json json
Definition: gerbview.cpp:39
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:183
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:161
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:173
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:159
COLOR_PICKER m_ColorPicker
Definition: app_settings.h:165
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.
wxString m_ColorTheme
Active color theme name.
Definition: app_settings.h:176