KiCad PCB EDA Suite
config_params.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) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
5  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 
27 #include <config_params.h> // for PARAM_CFG_INT_WITH_SCALE, PARAM_CFG_...
28 #include <locale_io.h>
29 #include <gal/color4d.h> // for COLOR4D
30 #include <math/util.h> // for KiROUND
31 #include <wx/config.h> // for wxConfigBase
32 #include <wx/debug.h> // for wxASSERT
33 
34 void wxConfigLoadParams( wxConfigBase* aCfg, const std::vector<PARAM_CFG*>& aList,
35  const wxString& aGroup )
36 {
37  wxASSERT( aCfg );
38 
39  for( PARAM_CFG* param : aList )
40  {
41  if( !!param->m_Group )
42  aCfg->SetPath( param->m_Group );
43  else
44  aCfg->SetPath( aGroup );
45 
46  if( param->m_Setup )
47  continue;
48 
49  param->ReadParam( aCfg );
50  }
51 }
52 
53 
54 void wxConfigLoadSetups( wxConfigBase* aCfg, const std::vector<PARAM_CFG*>& aList )
55 {
56  wxASSERT( aCfg );
57 
58  for( PARAM_CFG* param : aList )
59  {
60  if( !param->m_Setup )
61  continue;
62 
63  param->ReadParam( aCfg );
64  }
65 }
66 
67 
68 void wxConfigSaveParams( wxConfigBase* aCfg, const std::vector<PARAM_CFG*>& aList,
69  const wxString& aGroup )
70 {
71  wxASSERT( aCfg );
72 
73  for( PARAM_CFG* param : aList )
74  {
75  if( !!param->m_Group )
76  aCfg->SetPath( param->m_Group );
77  else
78  aCfg->SetPath( aGroup );
79 
80  if( param->m_Setup )
81  continue;
82 
83  if( param->m_Type == PARAM_COMMAND_ERASE ) // Erase all data
84  {
85  if( !!param->m_Ident )
86  aCfg->DeleteGroup( param->m_Ident );
87  }
88  else
89  {
90  param->SaveParam( aCfg );
91  }
92  }
93 }
94 
95 
96 void wxConfigSaveSetups( wxConfigBase* aCfg, const std::vector<PARAM_CFG*>& aList )
97 {
98  wxASSERT( aCfg );
99 
100  for( PARAM_CFG* param : aList )
101  {
102  if( !param->m_Setup )
103  continue;
104 
105  if( param->m_Type == PARAM_COMMAND_ERASE ) // Erase all data
106  {
107  if( !!param->m_Ident )
108  aCfg->DeleteGroup( param->m_Ident );
109  }
110  else
111  {
112  param->SaveParam( aCfg );
113  }
114  }
115 }
116 
117 
118 void ConfigBaseWriteDouble( wxConfigBase* aConfig, const wxString& aKey, double aValue )
119 {
120  // Use a single strategy, regardless of wx version.
121  // Want C locale float string.
122 
123  LOCALE_IO toggle;
124  wxString tnumber = wxString::Format( wxT( "%.16g" ), aValue );
125 
126  aConfig->Write( aKey, tnumber );
127 }
128 
129 
130 PARAM_CFG::PARAM_CFG( const wxString& ident, const paramcfg_id type,
131  const wxChar* group, const wxString& legacy )
132 {
133  m_Ident = ident;
134  m_Type = type;
135  m_Group = group;
136  m_Setup = false;
137 
138  m_Ident_legacy = legacy;
139 }
140 
141 
142 PARAM_CFG_INT::PARAM_CFG_INT( const wxString& ident, int* ptparam, int default_val,
143  int min, int max, const wxChar* group, const wxString& legacy ) :
144  PARAM_CFG( ident, PARAM_INT, group, legacy )
145 {
146  m_Pt_param = ptparam;
147  m_Default = default_val;
148  m_Min = min;
149  m_Max = max;
150 }
151 
152 
153 PARAM_CFG_INT::PARAM_CFG_INT( bool setup, const wxString& ident, int* ptparam, int default_val,
154  int min, int max, const wxChar* group, const wxString& legacy ) :
155  PARAM_CFG( ident, PARAM_INT, group, legacy )
156 {
157  m_Pt_param = ptparam;
158  m_Default = default_val;
159  m_Min = min;
160  m_Max = max;
161  m_Setup = setup;
162 }
163 
164 
165 void PARAM_CFG_INT::ReadParam( wxConfigBase* aConfig ) const
166 {
167  if( !m_Pt_param || !aConfig )
168  return;
169 
170  int itmp = m_Default;
171 
172  if( !aConfig->Read( m_Ident, &itmp ) && m_Ident_legacy != wxEmptyString )
173  aConfig->Read( m_Ident_legacy, &itmp );
174 
175  if( (itmp < m_Min) || (itmp > m_Max) )
176  itmp = m_Default;
177 
178  *m_Pt_param = itmp;
179 }
180 
181 
182 void PARAM_CFG_INT::SaveParam( wxConfigBase* aConfig ) const
183 {
184  if( !m_Pt_param || !aConfig )
185  return;
186 
187  aConfig->Write( m_Ident, *m_Pt_param );
188 }
189 
190 
191 PARAM_CFG_INT_WITH_SCALE::PARAM_CFG_INT_WITH_SCALE( const wxString& ident, int* ptparam,
192  int default_val, int min, int max,
193  const wxChar* group, double aBiu2cfgunit,
194  const wxString& legacy_ident ) :
195  PARAM_CFG_INT( ident, ptparam, default_val, min, max, group, legacy_ident )
196 {
198  m_BIU_to_cfgunit = aBiu2cfgunit;
199 }
200 
201 
202 PARAM_CFG_INT_WITH_SCALE::PARAM_CFG_INT_WITH_SCALE( bool setup, const wxString& ident, int* ptparam,
203  int default_val, int min, int max,
204  const wxChar* group, double aBiu2cfgunit,
205  const wxString& legacy_ident ) :
206  PARAM_CFG_INT( setup, ident, ptparam, default_val, min, max, group, legacy_ident )
207 {
209  m_BIU_to_cfgunit = aBiu2cfgunit;
210 }
211 
212 
213 void PARAM_CFG_INT_WITH_SCALE::ReadParam( wxConfigBase* aConfig ) const
214 {
215  if( !m_Pt_param || !aConfig )
216  return;
217 
218  double dtmp = (double) m_Default * m_BIU_to_cfgunit;
219  if( !aConfig->Read( m_Ident, &dtmp ) && m_Ident_legacy != wxEmptyString )
220  aConfig->Read( m_Ident_legacy, &dtmp );
221 
222  int itmp = KiROUND( dtmp / m_BIU_to_cfgunit );
223 
224  if( (itmp < m_Min) || (itmp > m_Max) )
225  itmp = m_Default;
226 
227  *m_Pt_param = itmp;
228 }
229 
230 
231 void PARAM_CFG_INT_WITH_SCALE::SaveParam( wxConfigBase* aConfig ) const
232 {
233  if( !m_Pt_param || !aConfig )
234  return;
235 
236  // We cannot use aConfig->Write for a double, because
237  // this function uses a format with very few digits in mantissa,
238  // and truncature issues are frequent.
239  // We uses our function.
241 }
242 
243 
244 PARAM_CFG_DOUBLE::PARAM_CFG_DOUBLE( const wxString& ident, double* ptparam,
245  double default_val, double min, double max,
246  const wxChar* group ) :
247  PARAM_CFG( ident, PARAM_DOUBLE, group )
248 {
249  m_Pt_param = ptparam;
250  m_Default = default_val;
251  m_Min = min;
252  m_Max = max;
253 }
254 
255 
257  const wxString& ident,
258  double* ptparam,
259  double default_val,
260  double min,
261  double max,
262  const wxChar* group ) :
263  PARAM_CFG( ident, PARAM_DOUBLE, group )
264 {
265  m_Pt_param = ptparam;
266  m_Default = default_val;
267  m_Min = min;
268  m_Max = max;
269  m_Setup = Insetup;
270 }
271 
272 
273 void PARAM_CFG_DOUBLE::ReadParam( wxConfigBase* aConfig ) const
274 {
275  if( !m_Pt_param || !aConfig )
276  return;
277 
278  double dtmp = m_Default;
279  aConfig->Read( m_Ident, &dtmp );
280 
281  if( (dtmp < m_Min) || (dtmp > m_Max) )
282  dtmp = m_Default;
283 
284  *m_Pt_param = dtmp;
285 }
286 
287 
288 void PARAM_CFG_DOUBLE::SaveParam( wxConfigBase* aConfig ) const
289 {
290  if( !m_Pt_param || !aConfig )
291  return;
292 
293  // We cannot use aConfig->Write for a double, because
294  // this function uses a format with very few digits in mantissa,
295  // and truncature issues are frequent.
296  // We uses our function.
298 }
299 
300 
301 PARAM_CFG_BOOL::PARAM_CFG_BOOL( const wxString& ident, bool* ptparam, int default_val,
302  const wxChar* group, const wxString& legacy ) :
303  PARAM_CFG( ident, PARAM_BOOL, group, legacy )
304 {
305  m_Pt_param = ptparam;
306  m_Default = default_val ? true : false;
307 }
308 
309 
310 PARAM_CFG_BOOL::PARAM_CFG_BOOL( bool Insetup, const wxString& ident, bool* ptparam,
311  int default_val, const wxChar* group, const wxString& legacy ) :
312  PARAM_CFG( ident, PARAM_BOOL, group, legacy )
313 {
314  m_Pt_param = ptparam;
315  m_Default = default_val ? true : false;
316  m_Setup = Insetup;
317 }
318 
319 
320 void PARAM_CFG_BOOL::ReadParam( wxConfigBase* aConfig ) const
321 {
322  if( !m_Pt_param || !aConfig )
323  return;
324 
325  int itmp = (int) m_Default;
326 
327  if( !aConfig->Read( m_Ident, &itmp ) && m_Ident_legacy != wxEmptyString )
328  aConfig->Read( m_Ident_legacy, &itmp );
329 
330  *m_Pt_param = itmp ? true : false;
331 }
332 
333 
334 void PARAM_CFG_BOOL::SaveParam( wxConfigBase* aConfig ) const
335 {
336  if( !m_Pt_param || !aConfig )
337  return;
338 
339  aConfig->Write( m_Ident, *m_Pt_param );
340 }
341 
342 
343 PARAM_CFG_WXSTRING::PARAM_CFG_WXSTRING( const wxString& ident, wxString* ptparam,
344  const wxChar* group ) :
345  PARAM_CFG( ident, PARAM_WXSTRING, group )
346 {
347  m_Pt_param = ptparam;
348 }
349 
350 
351 PARAM_CFG_WXSTRING::PARAM_CFG_WXSTRING( bool Insetup, const wxString& ident, wxString* ptparam,
352  const wxString& default_val, const wxChar* group ) :
353  PARAM_CFG( ident, PARAM_WXSTRING, group )
354 {
355  m_Pt_param = ptparam;
356  m_Setup = Insetup;
357  m_default = default_val;
358 }
359 
360 
361 void PARAM_CFG_WXSTRING::ReadParam( wxConfigBase* aConfig ) const
362 {
363  if( !m_Pt_param || !aConfig )
364  return;
365 
366  *m_Pt_param = aConfig->Read( m_Ident, m_default );
367 }
368 
369 
370 void PARAM_CFG_WXSTRING::SaveParam( wxConfigBase* aConfig ) const
371 {
372  if( !m_Pt_param || !aConfig )
373  return;
374 
375  aConfig->Write( m_Ident, *m_Pt_param );
376 }
377 
378 
379 PARAM_CFG_WXSTRING_SET::PARAM_CFG_WXSTRING_SET( const wxString& ident, std::set<wxString>* ptparam,
380  const wxChar* group ) :
382 {
383  m_Pt_param = ptparam;
384 }
385 
386 
387 PARAM_CFG_WXSTRING_SET::PARAM_CFG_WXSTRING_SET( bool Insetup, const wxString& ident,
388  std::set<wxString>* ptparam, const wxChar* group ) :
389  PARAM_CFG( ident, PARAM_WXSTRING, group )
390 {
391  m_Pt_param = ptparam;
392  m_Setup = Insetup;
393 }
394 
395 
396 void PARAM_CFG_WXSTRING_SET::ReadParam( wxConfigBase* aConfig ) const
397 {
398  if( !m_Pt_param || !aConfig )
399  return;
400 
401  for( int i = 1; true; ++i )
402  {
403  wxString key, data;
404 
405  key = m_Ident;
406  key << i;
407  data = aConfig->Read( key, wxT( "" ) );
408 
409  if( data.IsEmpty() )
410  break;
411 
412  m_Pt_param->insert( data );
413  }
414 }
415 
416 
417 void PARAM_CFG_WXSTRING_SET::SaveParam( wxConfigBase* aConfig ) const
418 {
419  if( !m_Pt_param || !aConfig )
420  return;
421 
422  int i = 1;
423 
424  for( const wxString& str : *m_Pt_param )
425  {
426  wxString key, data;
427 
428  key = m_Ident;
429  key << i++;
430 
431  aConfig->Write( key, str );
432  }
433 }
434 
435 
437  wxString* ptparam,
438  const wxChar* group ) :
439  PARAM_CFG( ident, PARAM_FILENAME, group )
440 {
441  m_Pt_param = ptparam;
442 }
443 
444 
445 void PARAM_CFG_FILENAME::ReadParam( wxConfigBase* aConfig ) const
446 {
447  if( !m_Pt_param || !aConfig )
448  return;
449 
450  wxString prm = aConfig->Read( m_Ident );
451  // file names are stored using Unix notation
452  // under Window we must use \ instead of /
453  // mainly if there is a server name in path (something like \\server\kicad)
454 #ifdef __WINDOWS__
455  prm.Replace(wxT("/"), wxT("\\"));
456 #endif
457  *m_Pt_param = prm;
458 }
459 
460 
461 void PARAM_CFG_FILENAME::SaveParam( wxConfigBase* aConfig ) const
462 {
463  if( !m_Pt_param || !aConfig )
464  return;
465 
466  wxString prm = *m_Pt_param;
467  // filenames are stored using Unix notation
468  prm.Replace(wxT("\\"), wxT("/") );
469  aConfig->Write( m_Ident, prm );
470 }
471 
472 
474  wxArrayString* ptparam,
475  const wxChar* group ) :
477 {
478  m_Pt_param = ptparam;
479 }
480 
481 
482 void PARAM_CFG_LIBNAME_LIST::ReadParam( wxConfigBase* aConfig ) const
483 {
484  if( !m_Pt_param || !aConfig )
485  return;
486 
487  int indexlib = 1; // We start indexlib to 1 because first
488  // lib name is LibName1
489  wxString libname, id_lib;
490  wxArrayString* libname_list = m_Pt_param;
491 
492  while( 1 )
493  {
494  id_lib = m_Ident;
495  id_lib << indexlib;
496  indexlib++;
497  libname = aConfig->Read( id_lib, wxT( "" ) );
498 
499  if( libname.IsEmpty() )
500  break;
501  // file names are stored using Unix notation
502  // under Window we must use \ instead of /
503  // mainly if there is a server name in path (something like \\server\kicad)
504 #ifdef __WINDOWS__
505  libname.Replace(wxT("/"), wxT("\\"));
506 #endif
507  libname_list->Add( libname );
508  }
509 }
510 
511 
512 void PARAM_CFG_LIBNAME_LIST::SaveParam( wxConfigBase* aConfig ) const
513 {
514  if( !m_Pt_param || !aConfig )
515  return;
516 
517  wxArrayString* libname_list = m_Pt_param;
518 
519  wxString configkey;
520  wxString libname;
521 
522  for( unsigned indexlib = 0; indexlib < libname_list->GetCount(); indexlib++ )
523  {
524  configkey = m_Ident;
525 
526  // We use indexlib+1 because first lib name is LibName1
527  configkey << (indexlib + 1);
528  libname = libname_list->Item( indexlib );
529 
530  // filenames are stored using Unix notation
531  libname.Replace(wxT("\\"), wxT("/") );
532  aConfig->Write( configkey, libname );
533  }
534 }
PARAM_CFG_DOUBLE(const wxString &ident, double *ptparam, double default_val=0.0, double min=0.0, double max=10000.0, const wxChar *group=nullptr)
bool m_Setup
Install or Project based parameter, true == install.
virtual void SaveParam(wxConfigBase *aConfig) const override
Save the value of the parameter stored in aConfig.
PARAM_CFG_WXSTRING_SET(const wxString &ident, std::set< wxString > *ptparam, const wxChar *group=nullptr)
wxString m_Group
Group name (this is like a path in the config data)
int m_Default
The default value of the parameter.
wxString * m_Pt_param
Pointer to the parameter value.
virtual void ReadParam(wxConfigBase *aConfig) const override
Read the value of the parameter stored in aConfig.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
wxString m_default
The default value of the parameter.
void wxConfigLoadParams(wxConfigBase *aCfg, const std::vector< PARAM_CFG * > &aList, const wxString &aGroup)
Use aList of PARAM_CFG objects to load configuration values from aCfg.
void wxConfigLoadSetups(wxConfigBase *aCfg, const std::vector< PARAM_CFG * > &aList)
Use aList of PARAM_CFG object to load configuration values from aCfg.
virtual void SaveParam(wxConfigBase *aConfig) const override
Save the value of the parameter stored in aConfig.
wxString m_Ident
Keyword in config data.
int m_Default
The default value of the parameter.
virtual void SaveParam(wxConfigBase *aConfig) const override
Save the value of the parameter stored in aConfig.
virtual void ReadParam(wxConfigBase *aConfig) const override
Read the value of the parameter stored in aConfig.
wxString m_Ident_legacy
double * m_Pt_param
Pointer to the parameter value.
int * m_Pt_param
Pointer to the parameter value.
PARAM_CFG(const wxString &ident, const paramcfg_id type, const wxChar *group=nullptr, const wxString &legacy_ident=wxEmptyString)
void wxConfigSaveSetups(wxConfigBase *aCfg, const std::vector< PARAM_CFG * > &aList)
Writes aList of PARAM_CFG objects to aCfg.
double m_BIU_to_cfgunit
the factor to convert the saved value in internal value
std::set< wxString > * m_Pt_param
Pointer to the parameter value.
PARAM_CFG_INT_WITH_SCALE(const wxString &ident, int *ptparam, int default_val=0, int min=std::numeric_limits< int >::min(), int max=std::numeric_limits< int >::max(), const wxChar *group=nullptr, double aBiu2cfgunit=1.0, const wxString &legacy_ident=wxEmptyString)
wxArrayString * m_Pt_param
Pointer to the parameter value.
virtual void ReadParam(wxConfigBase *aConfig) const override
Read the value of the parameter stored in aConfig.
virtual void SaveParam(wxConfigBase *aConfig) const override
Save the value of the parameter stored in aConfig.
Configuration object for integers.
int m_Max
Minimum and maximum values of the param type.
virtual void SaveParam(wxConfigBase *aConfig) const override
Save the value of the parameter stored in aConfig.
double m_Max
Minimum and maximum values of the param type.
paramcfg_id
Type of parameter in the configuration file.
Definition: config_params.h:54
virtual void SaveParam(wxConfigBase *aConfig) const override
Save the value of the parameter stored in aConfig.
double m_Default
The default value of the parameter.
PARAM_CFG_INT(const wxString &ident, int *ptparam, int default_val=0, int min=std::numeric_limits< int >::min(), int max=std::numeric_limits< int >::max(), const wxChar *group=nullptr, const wxString &legacy_ident=wxEmptyString)
bool * m_Pt_param
Pointer to the parameter value.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
virtual void SaveParam(wxConfigBase *aConfig) const override
Save the value of the parameter stored in aConfig.
void ConfigBaseWriteDouble(wxConfigBase *aConfig, const wxString &aKey, double aValue)
A helper function to write doubles in configuration file.
virtual void ReadParam(wxConfigBase *aConfig) const override
Read the value of the parameter stored in aConfig.
virtual void ReadParam(wxConfigBase *aConfig) const override
Read the value of the parameter stored in aConfig.
PARAM_CFG_BOOL(const wxString &ident, bool *ptparam, int default_val=false, const wxChar *group=nullptr, const wxString &legacy_ident=wxEmptyString)
A base class which establishes the interface functions ReadParam and SaveParam, which are implemented...
Definition: config_params.h:81
PARAM_CFG_LIBNAME_LIST(const wxChar *ident, wxArrayString *ptparam, const wxChar *group=nullptr)
paramcfg_id m_Type
Type of parameter.
void wxConfigSaveParams(wxConfigBase *aCfg, const std::vector< PARAM_CFG * > &aList, const wxString &aGroup)
Write aList of PARAM_CFG objects aCfg.
wxString * m_Pt_param
Pointer to the parameter value.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
virtual void ReadParam(wxConfigBase *aConfig) const override
Read the value of the parameter stored in aConfig.
virtual void ReadParam(wxConfigBase *aConfig) const override
Read the value of the parameter stored in aConfig.
PARAM_CFG_WXSTRING(const wxString &ident, wxString *ptparam, const wxChar *group=nullptr)
virtual void ReadParam(wxConfigBase *aConfig) const override
Read the value of the parameter stored in aConfig.
virtual void SaveParam(wxConfigBase *aConfig) const override
Save the value of the parameter stored in aConfig.
PARAM_CFG_FILENAME(const wxString &ident, wxString *ptparam, const wxChar *group=nullptr)