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-2017 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 <colors.h> // for ColorByName, EDA_COLOR_T, UNSPECIFIE...
28 #include <common.h> // for LOCALE_IO
29 #include <config_params.h> // for PARAM_CFG_INT_WITH_SCALE, PARAM_CFG_...
30 #include <gal/color4d.h> // for COLOR4D
31 #include <math/util.h> // for KiROUND
32 #include <wx/config.h> // for wxConfigBase
33 #include <wx/debug.h> // for wxASSERT
34 #include <wx/wx.h> // for wxString, operator!=, operator==
35 
36 
37 void wxConfigLoadParams( wxConfigBase* aCfg, const std::vector<PARAM_CFG*>& aList,
38  const wxString& aGroup )
39 {
40  wxASSERT( aCfg );
41 
42  for( PARAM_CFG* param : aList )
43  {
44  if( !!param->m_Group )
45  aCfg->SetPath( param->m_Group );
46  else
47  aCfg->SetPath( aGroup );
48 
49  if( param->m_Setup )
50  continue;
51 
52  param->ReadParam( aCfg );
53  }
54 }
55 
56 
57 void wxConfigLoadSetups( wxConfigBase* aCfg, const std::vector<PARAM_CFG*>& aList )
58 {
59  wxASSERT( aCfg );
60 
61  for( PARAM_CFG* param : aList )
62  {
63  if( !param->m_Setup )
64  continue;
65 
66  param->ReadParam( aCfg );
67  }
68 }
69 
70 
71 void wxConfigSaveParams( wxConfigBase* aCfg, const std::vector<PARAM_CFG*>& aList,
72  const wxString& aGroup )
73 {
74  wxASSERT( aCfg );
75 
76  for( PARAM_CFG* param : aList )
77  {
78  if( !!param->m_Group )
79  aCfg->SetPath( param->m_Group );
80  else
81  aCfg->SetPath( aGroup );
82 
83  if( param->m_Setup )
84  continue;
85 
86  if( param->m_Type == PARAM_COMMAND_ERASE ) // Erase all data
87  {
88  if( !!param->m_Ident )
89  aCfg->DeleteGroup( param->m_Ident );
90  }
91  else
92  {
93  param->SaveParam( aCfg );
94  }
95  }
96 }
97 
98 
99 void wxConfigSaveSetups( wxConfigBase* aCfg, const std::vector<PARAM_CFG*>& aList )
100 {
101  wxASSERT( aCfg );
102 
103  for( PARAM_CFG* param : aList )
104  {
105  if( !param->m_Setup )
106  continue;
107 
108  if( param->m_Type == PARAM_COMMAND_ERASE ) // Erase all data
109  {
110  if( !!param->m_Ident )
111  aCfg->DeleteGroup( param->m_Ident );
112  }
113  else
114  {
115  param->SaveParam( aCfg );
116  }
117  }
118 }
119 
120 
121 void ConfigBaseWriteDouble( wxConfigBase* aConfig, const wxString& aKey, double aValue )
122 {
123  // Use a single strategy, regardless of wx version.
124  // Want C locale float string.
125 
126  LOCALE_IO toggle;
127  wxString tnumber = wxString::Format( wxT( "%.16g" ), aValue );
128 
129  aConfig->Write( aKey, tnumber );
130 }
131 
132 
133 PARAM_CFG::PARAM_CFG( const wxString& ident, const paramcfg_id type,
134  const wxChar* group, const wxString& legacy )
135 {
136  m_Ident = ident;
137  m_Type = type;
138  m_Group = group;
139  m_Setup = false;
140 
141  m_Ident_legacy = legacy;
142 }
143 
144 
145 PARAM_CFG_INT::PARAM_CFG_INT( const wxString& ident, int* ptparam, int default_val,
146  int min, int max, const wxChar* group, const wxString& legacy ) :
147  PARAM_CFG( ident, PARAM_INT, group, legacy )
148 {
149  m_Pt_param = ptparam;
150  m_Default = default_val;
151  m_Min = min;
152  m_Max = max;
153 }
154 
155 
156 PARAM_CFG_INT::PARAM_CFG_INT( bool setup, const wxString& ident, int* ptparam, int default_val,
157  int min, int max, const wxChar* group, const wxString& legacy ) :
158  PARAM_CFG( ident, PARAM_INT, group, legacy )
159 {
160  m_Pt_param = ptparam;
161  m_Default = default_val;
162  m_Min = min;
163  m_Max = max;
164  m_Setup = setup;
165 }
166 
167 
168 void PARAM_CFG_INT::ReadParam( wxConfigBase* aConfig ) const
169 {
170  if( !m_Pt_param || !aConfig )
171  return;
172 
173  int itmp = m_Default;
174 
175  if( !aConfig->Read( m_Ident, &itmp ) && m_Ident_legacy != wxEmptyString )
176  aConfig->Read( m_Ident_legacy, &itmp );
177 
178  if( (itmp < m_Min) || (itmp > m_Max) )
179  itmp = m_Default;
180 
181  *m_Pt_param = itmp;
182 }
183 
184 
185 void PARAM_CFG_INT::SaveParam( wxConfigBase* aConfig ) const
186 {
187  if( !m_Pt_param || !aConfig )
188  return;
189 
190  aConfig->Write( m_Ident, *m_Pt_param );
191 }
192 
193 
194 PARAM_CFG_INT_WITH_SCALE::PARAM_CFG_INT_WITH_SCALE( const wxString& ident, int* ptparam,
195  int default_val, int min, int max,
196  const wxChar* group, double aBiu2cfgunit,
197  const wxString& legacy_ident ) :
198  PARAM_CFG_INT( ident, ptparam, default_val, min, max, group, legacy_ident )
199 {
201  m_BIU_to_cfgunit = aBiu2cfgunit;
202 }
203 
204 
205 PARAM_CFG_INT_WITH_SCALE::PARAM_CFG_INT_WITH_SCALE( bool setup, const wxString& ident, int* ptparam,
206  int default_val, int min, int max,
207  const wxChar* group, double aBiu2cfgunit,
208  const wxString& legacy_ident ) :
209  PARAM_CFG_INT( setup, ident, ptparam, default_val, min, max, group, legacy_ident )
210 {
212  m_BIU_to_cfgunit = aBiu2cfgunit;
213 }
214 
215 
216 void PARAM_CFG_INT_WITH_SCALE::ReadParam( wxConfigBase* aConfig ) const
217 {
218  if( !m_Pt_param || !aConfig )
219  return;
220 
221  double dtmp = (double) m_Default * m_BIU_to_cfgunit;
222  if( !aConfig->Read( m_Ident, &dtmp ) && m_Ident_legacy != wxEmptyString )
223  aConfig->Read( m_Ident_legacy, &dtmp );
224 
225  int itmp = KiROUND( dtmp / m_BIU_to_cfgunit );
226 
227  if( (itmp < m_Min) || (itmp > m_Max) )
228  itmp = m_Default;
229 
230  *m_Pt_param = itmp;
231 }
232 
233 
234 void PARAM_CFG_INT_WITH_SCALE::SaveParam( wxConfigBase* aConfig ) const
235 {
236  if( !m_Pt_param || !aConfig )
237  return;
238 
239  // We cannot use aConfig->Write for a double, because
240  // this function uses a format with very few digits in mantissa,
241  // and truncature issues are frequent.
242  // We uses our function.
244 }
245 
246 
247 PARAM_CFG_SETCOLOR::PARAM_CFG_SETCOLOR( const wxString& ident, COLOR4D* ptparam,
248  COLOR4D default_val,
249  const wxChar* group ) :
250  PARAM_CFG( ident, PARAM_SETCOLOR, group )
251 {
252  m_Pt_param = ptparam;
253  m_Default = default_val;
254 }
255 
256 
258  const wxString& ident,
259  COLOR4D* ptparam,
260  COLOR4D default_val,
261  const wxChar* group ) :
262  PARAM_CFG( ident, PARAM_SETCOLOR, group )
263 {
264  m_Pt_param = ptparam;
265  m_Default = default_val;
266  m_Setup = Insetup;
267 }
268 
269 
270 void PARAM_CFG_SETCOLOR::ReadParam( wxConfigBase* aConfig ) const
271 {
272  if( !m_Pt_param || !aConfig )
273  return;
274 
275  COLOR4D temp;
276 
277  if( aConfig->HasEntry( m_Ident ) )
278  {
279  if( temp.SetFromWxString( aConfig->Read( m_Ident, wxT( "NONE" ) ) ) )
280  {
281  *m_Pt_param = temp;
282  return;
283  }
284  }
285 
286  // If no luck, try reading legacy format
287  wxString legacy_Ident = m_Ident;
288  legacy_Ident.Replace( wxT( "4D" ), wxEmptyString );
289 
290  EDA_COLOR_T old = ColorByName( aConfig->Read( legacy_Ident, wxT( "NONE" ) ) );
291 
292  if( old != UNSPECIFIED_COLOR )
293  {
294  if( m_Ident == wxT( "Color4DErcWEx" ) || m_Ident == wxT( "Color4DErcEEx" ) )
295  *m_Pt_param = COLOR4D( old ).WithAlpha( 0.8 );
296  else
297  *m_Pt_param = COLOR4D( old );
298  return;
299  }
300 
302 }
303 
304 
305 void PARAM_CFG_SETCOLOR::SaveParam( wxConfigBase* aConfig ) const
306 {
307  if( !m_Pt_param || !aConfig )
308  return;
309 
310  aConfig->Write( m_Ident, m_Pt_param->ToColour().GetAsString( wxC2S_CSS_SYNTAX ) );
311 }
312 
313 
314 PARAM_CFG_DOUBLE::PARAM_CFG_DOUBLE( const wxString& ident, double* ptparam,
315  double default_val, double min, double max,
316  const wxChar* group ) :
317  PARAM_CFG( ident, PARAM_DOUBLE, group )
318 {
319  m_Pt_param = ptparam;
320  m_Default = default_val;
321  m_Min = min;
322  m_Max = max;
323 }
324 
325 
327  const wxString& ident,
328  double* ptparam,
329  double default_val,
330  double min,
331  double max,
332  const wxChar* group ) :
333  PARAM_CFG( ident, PARAM_DOUBLE, group )
334 {
335  m_Pt_param = ptparam;
336  m_Default = default_val;
337  m_Min = min;
338  m_Max = max;
339  m_Setup = Insetup;
340 }
341 
342 
343 void PARAM_CFG_DOUBLE::ReadParam( wxConfigBase* aConfig ) const
344 {
345  if( !m_Pt_param || !aConfig )
346  return;
347 
348  double dtmp = m_Default;
349  aConfig->Read( m_Ident, &dtmp );
350 
351  if( (dtmp < m_Min) || (dtmp > m_Max) )
352  dtmp = m_Default;
353 
354  *m_Pt_param = dtmp;
355 }
356 
357 
358 void PARAM_CFG_DOUBLE::SaveParam( wxConfigBase* aConfig ) const
359 {
360  if( !m_Pt_param || !aConfig )
361  return;
362 
363  // We cannot use aConfig->Write for a double, because
364  // this function uses a format with very few digits in mantissa,
365  // and truncature issues are frequent.
366  // We uses our function.
368 }
369 
370 
371 PARAM_CFG_BOOL::PARAM_CFG_BOOL( const wxString& ident, bool* ptparam, int default_val,
372  const wxChar* group, const wxString& legacy ) :
373  PARAM_CFG( ident, PARAM_BOOL, group, legacy )
374 {
375  m_Pt_param = ptparam;
376  m_Default = default_val ? true : false;
377 }
378 
379 
380 PARAM_CFG_BOOL::PARAM_CFG_BOOL( bool Insetup, const wxString& ident, bool* ptparam,
381  int default_val, const wxChar* group, const wxString& legacy ) :
382  PARAM_CFG( ident, PARAM_BOOL, group, legacy )
383 {
384  m_Pt_param = ptparam;
385  m_Default = default_val ? true : false;
386  m_Setup = Insetup;
387 }
388 
389 
390 void PARAM_CFG_BOOL::ReadParam( wxConfigBase* aConfig ) const
391 {
392  if( !m_Pt_param || !aConfig )
393  return;
394 
395  int itmp = (int) m_Default;
396 
397  if( !aConfig->Read( m_Ident, &itmp ) && m_Ident_legacy != wxEmptyString )
398  aConfig->Read( m_Ident_legacy, &itmp );
399 
400  *m_Pt_param = itmp ? true : false;
401 }
402 
403 
404 void PARAM_CFG_BOOL::SaveParam( wxConfigBase* aConfig ) const
405 {
406  if( !m_Pt_param || !aConfig )
407  return;
408 
409  aConfig->Write( m_Ident, *m_Pt_param );
410 }
411 
412 
413 PARAM_CFG_WXSTRING::PARAM_CFG_WXSTRING( const wxString& ident, wxString* ptparam,
414  const wxChar* group ) :
415  PARAM_CFG( ident, PARAM_WXSTRING, group )
416 {
417  m_Pt_param = ptparam;
418 }
419 
420 
421 PARAM_CFG_WXSTRING::PARAM_CFG_WXSTRING( bool Insetup, const wxString& ident, wxString* ptparam,
422  const wxString& default_val, const wxChar* group ) :
423  PARAM_CFG( ident, PARAM_WXSTRING, group )
424 {
425  m_Pt_param = ptparam;
426  m_Setup = Insetup;
427  m_default = default_val;
428 }
429 
430 
431 void PARAM_CFG_WXSTRING::ReadParam( wxConfigBase* aConfig ) const
432 {
433  if( !m_Pt_param || !aConfig )
434  return;
435 
436  *m_Pt_param = aConfig->Read( m_Ident, m_default );
437 }
438 
439 
440 void PARAM_CFG_WXSTRING::SaveParam( wxConfigBase* aConfig ) const
441 {
442  if( !m_Pt_param || !aConfig )
443  return;
444 
445  aConfig->Write( m_Ident, *m_Pt_param );
446 }
447 
448 
450  wxString* ptparam,
451  const wxChar* group ) :
452  PARAM_CFG( ident, PARAM_FILENAME, group )
453 {
454  m_Pt_param = ptparam;
455 }
456 
457 
458 void PARAM_CFG_FILENAME::ReadParam( wxConfigBase* aConfig ) const
459 {
460  if( !m_Pt_param || !aConfig )
461  return;
462 
463  wxString prm = aConfig->Read( m_Ident );
464  // file names are stored using Unix notation
465  // under Window we must use \ instead of /
466  // mainly if there is a server name in path (something like \\server\kicad)
467 #ifdef __WINDOWS__
468  prm.Replace(wxT("/"), wxT("\\"));
469 #endif
470  *m_Pt_param = prm;
471 }
472 
473 
474 void PARAM_CFG_FILENAME::SaveParam( wxConfigBase* aConfig ) const
475 {
476  if( !m_Pt_param || !aConfig )
477  return;
478 
479  wxString prm = *m_Pt_param;
480  // filenames are stored using Unix notation
481  prm.Replace(wxT("\\"), wxT("/") );
482  aConfig->Write( m_Ident, prm );
483 }
484 
485 
487  wxArrayString* ptparam,
488  const wxChar* group ) :
489  PARAM_CFG( ident, PARAM_LIBNAME_LIST, group )
490 {
491  m_Pt_param = ptparam;
492 }
493 
494 
495 void PARAM_CFG_LIBNAME_LIST::ReadParam( wxConfigBase* aConfig ) const
496 {
497  if( !m_Pt_param || !aConfig )
498  return;
499 
500  int indexlib = 1; // We start indexlib to 1 because first
501  // lib name is LibName1
502  wxString libname, id_lib;
503  wxArrayString* libname_list = m_Pt_param;
504 
505  while( 1 )
506  {
507  id_lib = m_Ident;
508  id_lib << indexlib;
509  indexlib++;
510  libname = aConfig->Read( id_lib, wxT( "" ) );
511 
512  if( libname.IsEmpty() )
513  break;
514  // file names are stored using Unix notation
515  // under Window we must use \ instead of /
516  // mainly if there is a server name in path (something like \\server\kicad)
517 #ifdef __WINDOWS__
518  libname.Replace(wxT("/"), wxT("\\"));
519 #endif
520  libname_list->Add( libname );
521  }
522 }
523 
524 
525 void PARAM_CFG_LIBNAME_LIST::SaveParam( wxConfigBase* aConfig ) const
526 {
527  if( !m_Pt_param || !aConfig )
528  return;
529 
530  wxArrayString* libname_list = m_Pt_param;
531 
532  wxString configkey;
533  wxString libname;
534 
535  for( unsigned indexlib = 0; indexlib < libname_list->GetCount(); indexlib++ )
536  {
537  configkey = m_Ident;
538 
539  // We use indexlib+1 because first lib name is LibName1
540  configkey << (indexlib + 1);
541  libname = libname_list->Item( indexlib );
542 
543  // filenames are stored using Unix notation
544  libname.Replace(wxT("\\"), wxT("/") );
545  aConfig->Write( configkey, libname );
546  }
547 }
bool m_Setup
Install or Project based parameter, true == install.
virtual void SaveParam(wxConfigBase *aConfig) const override
Function SaveParam saves the value of the parameter stored in aConfig.
wxString m_Group
Group name (this is like a path in the config data)
int m_Default
The default value of the parameter.
EDA_COLOR_T
NOTE: EDA_COLOR_T is deprecated and is kept around for compatibility with legacy canvas.
Definition: colors.h:42
wxString * m_Pt_param
Pointer to the parameter value.
EDA_COLOR_T ColorByName(const wxString &aName)
Find a color by name.
Definition: colors.cpp:72
virtual void ReadParam(wxConfigBase *aConfig) const override
Function ReadParam reads the value of the parameter stored in aConfig.
COLOR4D * m_Pt_param
Pointer to the parameter value.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: common.h:90
wxString m_default
The default value of the parameter.
void wxConfigLoadParams(wxConfigBase *aCfg, const std::vector< PARAM_CFG * > &aList, const wxString &aGroup)
Function wxConfigLoadParams uses aList of PARAM_CFG to load configuration values from aCfg.
virtual void ReadParam(wxConfigBase *aConfig) const override
Function ReadParam reads the value of the parameter stored in aConfig.
void wxConfigLoadSetups(wxConfigBase *aCfg, const std::vector< PARAM_CFG * > &aList)
Function wxConfigLoadSetups uses aList of PARAM_CFG to load configuration values from aCfg.
virtual void SaveParam(wxConfigBase *aConfig) const override
Function SaveParam saves the value of the parameter stored in aConfig.
wxString m_Ident
Keyword in config data.
int m_Default
The default value of the parameter.
COLOR4D WithAlpha(double aAlpha) const
Function WithAlpha Returns a colour with the same colour, but the given alpha.
Definition: color4d.h:247
The common library.
wxString m_Ident_legacy
double * m_Pt_param
Pointer to the parameter value.
int * m_Pt_param
Pointer to the parameter value.
void wxConfigSaveSetups(wxConfigBase *aCfg, const std::vector< PARAM_CFG * > &aList)
Function wxConfigSaveSetups writes aList of PARAM_CFG to save configuration values to aCfg.
PARAM_CFG_BOOL(const wxString &ident, bool *ptparam, int default_val=false, const wxChar *group=NULL, const wxString &legacy_ident=wxEmptyString)
double m_BIU_to_cfgunit
the factor to convert the saved value in internal value
PARAM_CFG_LIBNAME_LIST(const wxChar *ident, wxArrayString *ptparam, const wxChar *group=NULL)
wxArrayString * m_Pt_param
Pointer to the parameter value.
virtual void ReadParam(wxConfigBase *aConfig) const override
Function ReadParam reads the value of the parameter stored in aConfig.
PARAM_CFG(const wxString &ident, const paramcfg_id type, const wxChar *group=NULL, const wxString &legacy_ident=wxEmptyString)
virtual void SaveParam(wxConfigBase *aConfig) const override
Function SaveParam saves the value of the parameter stored in aConfig.
Configuration parameter - Integer Class.
int m_Max
Minimum and maximum values of the param type.
virtual void SaveParam(wxConfigBase *aConfig) const override
Function SaveParam saves 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:71
virtual void SaveParam(wxConfigBase *aConfig) const override
Function SaveParam saves 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)
PARAM_CFG_WXSTRING(const wxString &ident, wxString *ptparam, const wxChar *group=NULL)
bool * m_Pt_param
Pointer to the parameter value.
virtual void SaveParam(wxConfigBase *aConfig) const override
Function SaveParam saves the value of the parameter stored in aConfig.
void ConfigBaseWriteDouble(wxConfigBase *aConfig, const wxString &aKey, double aValue)
Function ConfigBaseWriteDouble This is a helper function to write doubles in config We cannot use wxC...
virtual void ReadParam(wxConfigBase *aConfig) const override
Function ReadParam reads the value of the parameter stored in aConfig.
COLOR4D m_Default
The default value of the parameter.
virtual void ReadParam(wxConfigBase *aConfig) const override
Function ReadParam reads the value of the parameter stored in aConfig.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
PARAM_CFG is a base class which establishes the interface functions ReadParam and SaveParam,...
Definition: config_params.h:99
virtual void SaveParam(wxConfigBase *aConfig) const override
Function SaveParam saves the value of the parameter stored in aConfig.
paramcfg_id m_Type
Type of parameter.
void wxConfigSaveParams(wxConfigBase *aCfg, const std::vector< PARAM_CFG * > &aList, const wxString &aGroup)
Function wxConfigSaveParams writes aList of PARAM_CFG to save configuration values to 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:61
The common library.
PARAM_CFG_SETCOLOR(const wxString &ident, COLOR4D *ptparam, COLOR4D default_val, const wxChar *group=NULL)
virtual void ReadParam(wxConfigBase *aConfig) const override
Function ReadParam reads the value of the parameter stored in aConfig.
PARAM_CFG_DOUBLE(const wxString &ident, double *ptparam, double default_val=0.0, double min=0.0, double max=10000.0, const wxChar *group=NULL)
virtual void ReadParam(wxConfigBase *aConfig) const override
Function ReadParam reads the value of the parameter stored in aConfig.
virtual void ReadParam(wxConfigBase *aConfig) const override
Function ReadParam reads the value of the parameter stored in aConfig.
PARAM_CFG_FILENAME(const wxString &ident, wxString *ptparam, const wxChar *group=NULL)
virtual void SaveParam(wxConfigBase *aConfig) const override
Function SaveParam saves the value of the parameter stored in aConfig.
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=NULL, double aBiu2cfgunit=1.0, const wxString &legacy_ident=wxEmptyString)
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39