KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_edit_cfg.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "dialog_edit_cfg.h"
21
22#include <advanced_config.h>
23#include <config_params.h>
24#include <paths.h>
25#include <wx/button.h>
26#include <wx/display.h>
27#include <wx/log.h>
28#include <wx/menu.h>
29#include <wx/sizer.h>
30#include <wx/settings.h>
31#include <widgets/wx_grid.h>
32#include <functional>
33#include <memory>
34
35
36static wxString paramValueString( const PARAM_CFG& aParam )
37{
38 wxString s;
39
40 try
41 {
42 switch( aParam.m_Type )
43 {
45 s << *static_cast<const PARAM_CFG_INT&>( aParam ).m_Pt_param;
46 break;
47
49 s = wxString::FromCDouble( *static_cast<const PARAM_CFG_DOUBLE&>( aParam ).m_Pt_param );
50 break;
51
53 s = *static_cast<const PARAM_CFG_WXSTRING&>( aParam ).m_Pt_param;
54 break;
55
57 s << ( *static_cast<const PARAM_CFG_BOOL&>( aParam ).m_Pt_param ? wxS( "true" ) : wxS( "false" ) );
58 break;
59
60 default:
61 wxLogError( wxS( "Unsupported PARAM_CFG variant: " ) + wxString::Format( wxS( "%d" ), aParam.m_Type ) );
62 }
63 }
64 catch( ... )
65 {
66 wxLogError( wxS( "Error converting parameter value to string." ) );
67 }
68 return s;
69}
70
71
72static wxString paramDefaultString( const PARAM_CFG& aParam )
73{
74 wxString s;
75
76 try
77 {
78 switch( aParam.m_Type )
79 {
81 s << static_cast<const PARAM_CFG_INT&>( aParam ).m_Default;
82 break;
83
85 s = wxString::FromCDouble( static_cast<const PARAM_CFG_DOUBLE&>( aParam ).m_Default );
86 break;
87
89 s << static_cast<const PARAM_CFG_WXSTRING&>( aParam ).m_default;
90 break;
91
93 s << ( static_cast<const PARAM_CFG_BOOL&>( aParam ).m_Default ? wxS( "true" ) : wxS( "false" ) );
94 break;
95
96 default:
97 break;
98 }
99 }
100 catch( ... )
101 {
102 wxLogError( wxS( "Error converting parameter default value to string." ) );
103 }
104
105 return s;
106}
107
108
109static void writeParam( PARAM_CFG& aParam, const wxString& aValue )
110{
111 switch( aParam.m_Type )
112 {
114 {
115 PARAM_CFG_INT& param = static_cast<PARAM_CFG_INT&>( aParam );
116 *param.m_Pt_param = wxAtoi( aValue );
117 break;
118 }
119
121 {
122 PARAM_CFG_BOOL& param = static_cast<PARAM_CFG_BOOL&>( aParam );
123
124 if( aValue.CmpNoCase( wxS( "true" ) ) == 0 || aValue.CmpNoCase( wxS( "yes" ) ) == 0
125 || aValue.CmpNoCase( wxS( "1" ) ) == 0 )
126 {
127 *param.m_Pt_param = true;
128 }
129 else
130 {
131 *param.m_Pt_param = false;
132 }
133 break;
134 }
135
137 {
138 PARAM_CFG_DOUBLE& param = static_cast<PARAM_CFG_DOUBLE&>( aParam );
139 aValue.ToCDouble( param.m_Pt_param );
140 break;
141 }
142
144 {
145 PARAM_CFG_WXSTRING& param = static_cast<PARAM_CFG_WXSTRING&>( aParam );
146 *param.m_Pt_param = aValue;
147 break;
148 }
149
150 default:
151 wxASSERT_MSG( false, wxS( "Unsupported PARAM_CFG variant: " )
152 + wxString::Format( wxS( "%d" ), aParam.m_Type ) );
153 }
154}
155
156
158 wxDialog( aParent, wxID_ANY, _( "Edit Advanced Configuration" ), wxDefaultPosition, wxDefaultSize,
159 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )
160{
161 m_cfgFile = wxFileName( PATHS::GetUserSettingsPath(), wxS( "kicad_advanced" ) );
162
163 m_grid = new WX_GRID( this, wxID_ANY );
164 m_grid->CreateGrid( 0, 3 );
165 m_grid->SetColSize( 0, 100 ); // SetColumnAutosizer() will use these for minimum size
166 m_grid->SetColSize( 1, 80 );
167 m_grid->SetColLabelValue( 0, _( "Key" ) );
168 m_grid->SetColLabelValue( 1, _( "Value" ) );
169 m_grid->SetColLabelValue( 2, _( "Extant" ) );
170 m_grid->HideCol( 2 );
171 m_grid->SetRowLabelSize( 0 );
172 m_grid->SetupColumnAutosizer( 1 );
173
174 wxStdDialogButtonSizer* buttonSizer = new wxStdDialogButtonSizer();
175 wxButton* okButton = new wxButton( this, wxID_OK, _( "OK" ) );
176 okButton->SetDefault();
177 buttonSizer->AddButton( okButton );
178 buttonSizer->Realize();
179
180 wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
181 sizer->Add( m_grid, 1, wxEXPAND | wxALL, 5 );
182 sizer->Add( buttonSizer, 0, wxEXPAND | wxALL, 5 );
183 SetSizer( sizer );
184
185 wxDisplay display( wxDisplay::GetFromWindow( this ) );
186 wxRect displayRect = display.GetClientArea();
187
188 SetMinSize( wxSize( 500, 300 ) );
189 SetMaxSize( wxSize( displayRect.GetWidth() - 100, displayRect.GetHeight() - 100 ) );
190 SetSizeHints( wxSize( 700, 500 ) );
191
192 m_grid->Bind( wxEVT_GRID_CELL_CHANGED, &DIALOG_EDIT_CFG::OnCellChange, this );
193 m_grid->Bind( wxEVT_GRID_CELL_RIGHT_CLICK, &DIALOG_EDIT_CFG::OnCellRightClick, this );
194 Bind( wxEVT_SIZE, &DIALOG_EDIT_CFG::OnSize, this );
195
196 m_contextRow = -1;
197
198 Layout();
199 Centre();
200}
201
202
204{
205 for( const std::unique_ptr<PARAM_CFG>& entry : ADVANCED_CFG::GetCfg().GetEntries() )
206 {
207 wxString value = paramValueString( *entry );
208 wxString def = paramDefaultString( *entry );
209 int row = m_grid->GetNumberRows();
210 m_grid->AppendRows( 1 );
211 m_grid->SetCellValue( row, 0, entry->m_Ident );
212 m_grid->SetCellValue( row, 1, value );
213 m_grid->SetCellValue( row, 2, def == value ? wxS( "0" ) : wxS( "1" ) );
214 m_grid->SetReadOnly( row, 2 );
215 updateRowAppearance( row );
216 }
217
218 return true;
219}
220
221
223{
224 if( !m_grid->CommitPendingChanges() )
225 return false;
226
227 saveSettings();
228 return true;
229}
230
231
233{
234 int rows = m_grid->GetNumberRows();
235
236 for( int row = 0; row < rows; ++row )
237 {
238 wxString key = m_grid->GetCellValue( row, 0 );
239 wxString val = m_grid->GetCellValue( row, 1 );
240 wxString ext = m_grid->GetCellValue( row, 2 );
241
242 if( key.IsEmpty() || ext != wxS( "1" ) )
243 continue;
244
245 for( const std::unique_ptr<PARAM_CFG>& entry : ADVANCED_CFG::GetCfg().GetEntries() )
246 {
247 if( entry->m_Ident == key )
248 {
249 writeParam( *entry, val );
250 break;
251 }
252 }
253 }
254
255 ADVANCED_CFG& adv = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() );
256 adv.Save();
257}
258
259
260void DIALOG_EDIT_CFG::OnCellChange( wxGridEvent& aEvent )
261{
262 int row = aEvent.GetRow();
263 int col = aEvent.GetCol();
264
265 if( col == 0 || col == 1 )
266 {
267 m_grid->SetCellValue( row, 2, wxS( "1" ) );
268 updateRowAppearance( row );
269 }
270
271 saveSettings();
272
273 int lastRow = m_grid->GetNumberRows() - 1;
274
275 if( !m_grid->GetCellValue( lastRow, 0 ).IsEmpty() || !m_grid->GetCellValue( lastRow, 1 ).IsEmpty() )
276 {
277 m_grid->AppendRows( 1 );
278 m_grid->SetCellValue( m_grid->GetNumberRows() - 1, 2, wxS( "0" ) );
279 m_grid->SetReadOnly( m_grid->GetNumberRows() - 1, 2 );
280 updateRowAppearance( m_grid->GetNumberRows() - 1 );
281 }
282
283 aEvent.Skip();
284}
285
286
287void DIALOG_EDIT_CFG::OnCellRightClick( wxGridEvent& aEvent )
288{
289 m_contextRow = aEvent.GetRow();
290 wxMenu menu;
291 menu.Append( wxID_ANY, _( "Reset to default" ) );
292 menu.Bind( wxEVT_MENU, &DIALOG_EDIT_CFG::OnResetDefault, this );
293 PopupMenu( &menu );
294 menu.Unbind( wxEVT_MENU, &DIALOG_EDIT_CFG::OnResetDefault, this );
295}
296
297
298void DIALOG_EDIT_CFG::OnResetDefault( wxCommandEvent& aEvent )
299{
300 if( m_contextRow < 0 )
301 return;
302
303 wxString key = m_grid->GetCellValue( m_contextRow, 0 );
304 wxString def;
305
306 for( const std::unique_ptr<PARAM_CFG>& entry : ADVANCED_CFG::GetCfg().GetEntries() )
307 {
308 if( entry->m_Ident == key )
309 {
310 def = paramDefaultString( *entry );
311 break;
312 }
313 }
314
315 m_grid->SetCellValue( m_contextRow, 1, def );
316 m_grid->SetCellValue( m_contextRow, 2, wxS( "0" ) );
318 saveSettings();
319}
320
321
323{
324 bool ext = m_grid->GetCellValue( aRow, 2 ) == wxS( "1" );
325 wxFont font = m_grid->GetCellFont( aRow, 0 );
326 font.SetWeight( ext ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL );
327 m_grid->SetCellFont( aRow, 0, font );
328 m_grid->SetCellFont( aRow, 1, font );
329}
void Save()
Save the configuration to the configuration file.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
DIALOG_EDIT_CFG(wxWindow *aParent)
void OnCellChange(wxGridEvent &aEvent)
void OnCellRightClick(wxGridEvent &aEvent)
bool TransferDataToWindow() override
void OnResetDefault(wxCommandEvent &aEvent)
wxFileName m_cfgFile
void updateRowAppearance(int aRow)
bool TransferDataFromWindow() override
Configuration object for booleans.
bool * m_Pt_param
Pointer to the parameter value.
Configuration object for double precision floating point numbers.
double * m_Pt_param
Pointer to the parameter value.
Configuration object for integers.
int * m_Pt_param
Pointer to the parameter value.
Configuration object for wxString objects.
wxString * m_Pt_param
Pointer to the parameter value.
A base class which establishes the interface functions ReadParam and SaveParam, which are implemented...
paramcfg_id m_Type
Type of parameter.
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
Definition paths.cpp:612
@ PARAM_WXSTRING
@ PARAM_INT
@ PARAM_DOUBLE
@ PARAM_BOOL
static wxString paramValueString(const PARAM_CFG &aParam)
static void writeParam(PARAM_CFG &aParam, const wxString &aValue)
static wxString paramDefaultString(const PARAM_CFG &aParam)
#define _(s)