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_LibTree(),
40  m_Printing(),
41  m_System(),
42  m_Window(),
43  m_appSettingsSchemaVersion( aSchemaVersion )
44 {
45  // Make Coverity happy:
46  m_LibTree.column_width = 360;
48 
49  // Build parameters list:
50  m_params.emplace_back( new PARAM<int>( "find_replace.flags", &m_FindReplace.flags, 1 ) );
51 
52  m_params.emplace_back( new PARAM<wxString>( "find_replace.find_string",
53  &m_FindReplace.find_string, "" ) );
54 
55  m_params.emplace_back( new PARAM_LIST<wxString>( "find_replace.find_history",
56  &m_FindReplace.find_history, {} ) );
57 
58  m_params.emplace_back( new PARAM<wxString>( "find_replace.replace_string",
60 
61  m_params.emplace_back( new PARAM_LIST<wxString>( "find_replace.replace_history",
63 
64 #ifdef __WXMAC__
65  // Cairo renderer doesn't handle Retina displays so default to OpenGL
66  m_params.emplace_back( new PARAM<int>( "graphics.canvas_type", &m_Graphics.canvas_type,
68 #else
69  m_params.emplace_back( new PARAM<int>( "graphics.canvas_type", &m_Graphics.canvas_type,
71 #endif
72 
73  m_params.emplace_back(
74  new PARAM<int>( "lib_tree.column_width", &m_LibTree.column_width, 360 ) );
75 
76  m_params.emplace_back(
77  new PARAM<bool>( "printing.background", &m_Printing.background, false ) );
78 
79  m_params.emplace_back( new PARAM<bool>( "printing.monochrome", &m_Printing.monochrome, true ) );
80 
81  m_params.emplace_back( new PARAM<double>( "printing.scale", &m_Printing.scale, 1.0 ) );
82 
83  m_params.emplace_back(
84  new PARAM<bool>( "printing.use_theme", &m_Printing.use_theme, false ) );
85 
86  m_params.emplace_back(
87  new PARAM<wxString>( "printing.color_theme", &m_Printing.color_theme, "" ) );
88 
89  m_params.emplace_back( new PARAM<bool>( "printing.title_block",
90  &m_Printing.title_block, false ) );
91 
92  m_params.emplace_back( new PARAM_LIST<int>( "printing.layers", &m_Printing.layers, {} ) );
93 
94  m_params.emplace_back( new PARAM<bool>( "system.first_run_shown",
95  &m_System.first_run_shown, false ) );
96 
97  m_params.emplace_back( new PARAM<int>( "system.max_undo_items", &m_System.max_undo_items, 0 ) );
98 
99 
100  m_params.emplace_back( new PARAM_LIST<wxString>( "system.file_history",
101  &m_System.file_history, {} ) );
102 
103  m_params.emplace_back( new PARAM<int>( "system.units", &m_System.units,
104  static_cast<int>( EDA_UNITS::MILLIMETRES ) ) );
105 
106  m_params.emplace_back( new PARAM<wxString>( "appearance.color_theme", &m_ColorTheme, "user" ) );
107 
108  addParamsForWindow( &m_Window, "window" );
109 
110  m_params.emplace_back( new PARAM<bool>(
111  "cross_probing.center_on_items", &m_CrossProbing.center_on_items, true ) );
112 
113  m_params.emplace_back(
114  new PARAM<bool>( "cross_probing.zoom_to_fit", &m_CrossProbing.zoom_to_fit, true ) );
115 
116  m_params.emplace_back( new PARAM<bool>(
117  "cross_probing.auto_highlight", &m_CrossProbing.auto_highlight, true ) );
118 }
119 
120 
121 bool APP_SETTINGS_BASE::MigrateFromLegacy( wxConfigBase* aCfg )
122 {
123  bool ret = true;
124 
125  const std::string f = getLegacyFrameName();
126 
127  ret &= fromLegacyString( aCfg, "LastFindString", "find_replace.find_string" );
128  ret &= fromLegacyString( aCfg, "LastReplaceString", "find_replace.replace_string" );
129 
130  migrateFindReplace( aCfg );
131 
132  ret &= fromLegacy<int>( aCfg, "canvas_type", "graphics.canvas_type" );
133 
134  ret &= fromLegacy<int>( aCfg, "P22LIB_TREE_MODEL_ADAPTERSelectorColumnWidth",
135  "lib_tree.column_width" );
136 
137  ret &= fromLegacy<bool>( aCfg, "PrintMonochrome", "printing.monochrome" );
138  ret &= fromLegacy<double>( aCfg, "PrintScale", "printing.scale" );
139  ret &= fromLegacy<bool>( aCfg, "PrintPageFrame", "printing.title_block" );
140 
141  {
142  nlohmann::json js = nlohmann::json::array();
143  wxString key;
144  bool val = false;
145 
146  for( unsigned i = 0; i < PCB_LAYER_ID_COUNT; ++i )
147  {
148  key.Printf( wxT( "PlotLayer_%d" ), i );
149 
150  if( aCfg->Read( key, &val ) && val )
151  js.push_back( i );
152  }
153 
154  ( *this )[PointerFromString( "printing.layers" ) ] = js;
155  }
156 
157  ret &= fromLegacy<bool>( aCfg, f + "FirstRunShown", "system.first_run_shown" );
158  ret &= fromLegacy<int>( aCfg, f + "DevelMaxUndoItems", "system.max_undo_items" );
159  ret &= fromLegacy<int>( aCfg, f + "Units", "system.units" );
160 
161  {
162  int max_history_size = Pgm().GetCommonSettings()->m_System.file_history_size;
163  wxString file, key;
164  nlohmann::json js = nlohmann::json::array();
165 
166  for( int i = 1; i <= max_history_size; i++ )
167  {
168  key.Printf( "file%d", i );
169  file = aCfg->Read( key, wxEmptyString );
170 
171  if( !file.IsEmpty() )
172  js.push_back( file.ToStdString() );
173  }
174 
175  ( *this )[PointerFromString( "system.file_history" )] = js;
176  }
177 
178  ret &= migrateWindowConfig( aCfg, f, "window" );
179 
180  return ret;
181 }
182 
183 
184 void APP_SETTINGS_BASE::migrateFindReplace( wxConfigBase* aCfg )
185 {
186  const int find_replace_history_size = 10;
187  nlohmann::json find_history = nlohmann::json::array();
188  nlohmann::json replace_history = nlohmann::json::array();
189  wxString tmp, find_key, replace_key;
190 
191  for( int i = 0; i < find_replace_history_size; ++i )
192  {
193  find_key.Printf( "FindStringHistoryList%d", i );
194  replace_key.Printf( "ReplaceStringHistoryList%d", i );
195 
196  if( aCfg->Read( find_key, &tmp ) )
197  find_history.push_back( tmp.ToStdString() );
198 
199  if( aCfg->Read( replace_key, &tmp ) )
200  replace_history.push_back( tmp.ToStdString() );
201  }
202 
203  ( *this )[PointerFromString( "find_replace.find_history" )] = find_history;
204  ( *this )[PointerFromString( "find_replace.replace_history" )] = replace_history;
205 }
206 
207 
208 bool APP_SETTINGS_BASE::migrateWindowConfig( wxConfigBase* aCfg, const std::string& aFrame,
209  const std::string& aJsonPath )
210 {
211  bool ret = true;
212 
213  const std::string frameGDO = aFrame + "GalDisplayOptions";
214  const std::string cursorPath = aJsonPath + ".cursor";
215  const std::string gridPath = aJsonPath + ".grid";
216 
217  ret &= fromLegacy<bool>( aCfg, aFrame + "Maximized", aJsonPath + ".maximized" );
218  ret &= fromLegacyString( aCfg, aFrame + "MostRecentlyUsedPath", aJsonPath + ".mru_path" );
219  ret &= fromLegacy<int>( aCfg, aFrame + "Size_x", aJsonPath + ".size_x" );
220  ret &= fromLegacy<int>( aCfg, aFrame + "Size_y", aJsonPath + ".size_y" );
221  ret &= fromLegacyString( aCfg, aFrame + "Perspective", aJsonPath + ".perspective" );
222  ret &= fromLegacy<int>( aCfg, aFrame + "Pos_x", aJsonPath + ".pos_x" );
223  ret &= fromLegacy<int>( aCfg, aFrame + "Pos_y", aJsonPath + ".pos_y" );
224 
225  ret &= fromLegacy<bool>( aCfg, frameGDO + "ForceDisplayCursor", cursorPath + ".always_show_cursor" );
226  ret &= fromLegacy<bool>( aCfg, frameGDO + "CursorFullscreen", cursorPath + ".fullscreen_cursor" );
227 
228  ret &= fromLegacy<int>( aCfg, aFrame + "_LastGridSize", gridPath + ".last_size" );
229 
230  ret &= fromLegacy<int>( aCfg, aFrame + "FastGrid1", gridPath + ".fast_grid_1" );
231  ret &= fromLegacy<int>( aCfg, aFrame + "FastGrid2", gridPath + ".fast_grid_2" );
232 
233  ret &= fromLegacy<bool>( aCfg, frameGDO + "GridAxesEnabled", gridPath + ".axes_enabled" );
234  ret &= fromLegacy<double>( aCfg, frameGDO + "GridLineWidth", gridPath + ".line_width" );
235  ret &= fromLegacy<double>( aCfg, frameGDO + "GridMaxDensity", gridPath + ".min_spacing" );
236  ret &= fromLegacy<bool>( aCfg, frameGDO + "ShowGrid", gridPath + ".show" );
237  ret &= fromLegacy<int>( aCfg, frameGDO + "GridStyle", gridPath + ".style" );
238  ret &= fromLegacyColor( aCfg, frameGDO + "GridColor", gridPath + ".color" );
239 
240  return ret;
241 }
242 
243 
244 void APP_SETTINGS_BASE::addParamsForWindow( WINDOW_SETTINGS* aWindow, const std::string& aJsonPath )
245 {
246  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".maximized",
247  &aWindow->maximized, false ) );
248 
249  m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".mru_path",
250  &aWindow->mru_path, "" ) );
251 
252  m_params.emplace_back( new PARAM<int>( aJsonPath + ".size_x", &aWindow->size_x, 0 ) );
253 
254  m_params.emplace_back( new PARAM<int>( aJsonPath + ".size_y", &aWindow->size_y, 0 ) );
255 
256  m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".perspective",
257  &aWindow->perspective, "" ) );
258 
259  m_params.emplace_back( new PARAM<int>( aJsonPath + ".pos_x", &aWindow->pos_x, 0 ) );
260 
261  m_params.emplace_back( new PARAM<int>( aJsonPath + ".pos_y", &aWindow->pos_y, 0 ) );
262 
263  m_params.emplace_back( new PARAM<unsigned int>( aJsonPath + ".display", &aWindow->display, 0 ) );
264 
265  m_params.emplace_back( new PARAM_LIST<double>( aJsonPath + ".zoom_factors",
266  &aWindow->zoom_factors, {} ) );
267 
268  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".grid.axes_enabled",
269  &aWindow->grid.axes_enabled, false ) );
270 
271  m_params.emplace_back( new PARAM_LIST<wxString>( aJsonPath + ".grid.sizes",
272  &aWindow->grid.sizes, {} ) );
273 
274  // pcbnew default grid doesn't matter much, but eeschema does, so default to the index
275  // of the 50mil grid in eeschema
276  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.last_size",
277  &aWindow->grid.last_size_idx, 1 ) );
278 
279  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.fast_grid_1",
280  &aWindow->grid.fast_grid_1, 1 ) );
281 
282  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.fast_grid_2",
283  &aWindow->grid.fast_grid_2, 2 ) );
284 
285  // for grid user, use a default value compatible with eeschema and pcbnew (10 mils)
286  m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".grid.user_grid_x",
287  &aWindow->grid.user_grid_x, "10 mil" ) );
288  m_params.emplace_back( new PARAM<wxString>( aJsonPath + ".grid.user_grid_y",
289  &aWindow->grid.user_grid_y, "10 mil" ) );
290 
291  m_params.emplace_back( new PARAM<double>( aJsonPath + ".grid.line_width",
292  &aWindow->grid.line_width, 1.0 ) );
293 
294  m_params.emplace_back( new PARAM<double>( aJsonPath + ".grid.min_spacing",
295  &aWindow->grid.min_spacing, 10 ) );
296 
297  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".grid.show",
298  &aWindow->grid.show, true ) );
299 
300  m_params.emplace_back( new PARAM<int>( aJsonPath + ".grid.style",
301  &aWindow->grid.style, 0 ) );
302 
303  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".cursor.always_show_cursor",
304  &aWindow->cursor.always_show_cursor, true ) );
305 
306  m_params.emplace_back( new PARAM<bool>( aJsonPath + ".cursor.fullscreen_cursor",
307  &aWindow->cursor.fullscreen_cursor, false ) );
308 }
wxString mru_path
Definition: app_settings.h:71
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:131
wxString user_grid_y
Definition: app_settings.h:54
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:104
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:101
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
SETTINGS_LOC
Definition: json_settings.h:36
wxString color_theme
Color theme to use for printing.
Definition: app_settings.h:122
bool title_block
Whether or not to print title block.
Definition: app_settings.h:123
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:121
nlohmann::json json
Definition: gerbview.cpp:40
bool always_show_cursor
Definition: app_settings.h:42
std::vector< double > zoom_factors
Definition: app_settings.h:79
bool monochrome
Whether or not to print in monochrome.
Definition: app_settings.h:119
double line_width
Definition: app_settings.h:58
virtual std::string getLegacyFrameName() const
Definition: app_settings.h:164
Stores the common settings that are saved and loaded for each window / frame.
Definition: app_settings.h:68
wxString perspective
Definition: app_settings.h:74
std::vector< wxString > sizes
Definition: app_settings.h:52
CURSOR_SETTINGS cursor
Definition: app_settings.h:81
FIND_REPLACE m_FindReplace
Definition: app_settings.h:144
GRID_SETTINGS grid
Definition: app_settings.h:82
APP_SETTINGS_BASE(const std::string &aFilename, int aSchemaVersion)
std::vector< int > layers
List of enabled layers for printing.
Definition: app_settings.h:124
std::vector< wxString > replace_history
Definition: app_settings.h:103
bool background
Whether or not to print background color.
Definition: app_settings.h:118
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:154
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.
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:120
The main config directory (e.g. ~/.config/kicad/)
The common library.
CROSS_PROBING_SETTINGS m_CrossProbing
Definition: app_settings.h:142
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.
unsigned int display
Definition: app_settings.h:77
wxString m_ColorTheme
Active color theme name.
Definition: app_settings.h:157