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;
48 s = wxString::FromCDouble( *static_cast<const PARAM_CFG_DOUBLE&>( aParam ).m_Pt_param );
49 break;
51 s = *static_cast<const PARAM_CFG_WXSTRING&>( aParam ).m_Pt_param;
52 break;
54 s << ( *static_cast<const PARAM_CFG_BOOL&>( aParam ).m_Pt_param ? wxS( "true" ) : wxS( "false" ) );
55 break;
56 default:
57 wxLogError( wxS( "Unsupported PARAM_CFG variant: " ) + wxString::Format( wxS( "%d" ), aParam.m_Type ) );
58 }
59 }
60 catch( ... )
61 {
62 wxLogError( wxS( "Error converting parameter value to string." ) );
63 }
64 return s;
65}
66
67
68static wxString paramDefaultString( const PARAM_CFG& aParam )
69{
70 wxString s;
71
72 try
73 {
74 switch( aParam.m_Type )
75 {
77 s << static_cast<const PARAM_CFG_INT&>( aParam ).m_Default;
78 break;
80 s = wxString::FromCDouble( static_cast<const PARAM_CFG_DOUBLE&>( aParam ).m_Default );
81 break;
83 s << static_cast<const PARAM_CFG_WXSTRING&>( aParam ).m_default;
84 break;
86 s << ( static_cast<const PARAM_CFG_BOOL&>( aParam ).m_Default ? wxS( "true" ) : wxS( "false" ) );
87 break;
88 default:
89 break;
90 }
91 }
92 catch( ... )
93 {
94 wxLogError( wxS( "Error converting parameter default value to string." ) );
95 }
96
97 return s;
98}
99
100
101static void writeParam( PARAM_CFG& aParam, const wxString& aValue )
102{
103 switch( aParam.m_Type )
104 {
106 {
107 PARAM_CFG_INT& param = static_cast<PARAM_CFG_INT&>( aParam );
108 *param.m_Pt_param = wxAtoi( aValue );
109 break;
110 }
112 {
113 PARAM_CFG_BOOL& param = static_cast<PARAM_CFG_BOOL&>( aParam );
114
115 if( aValue.CmpNoCase( wxS( "true" ) ) == 0 || aValue.CmpNoCase( wxS( "yes" ) ) == 0
116 || aValue.CmpNoCase( wxS( "1" ) ) == 0 )
117 {
118 *param.m_Pt_param = true;
119 }
120 else
121 {
122 *param.m_Pt_param = false;
123 }
124 break;
125 }
127 {
128 PARAM_CFG_DOUBLE& param = static_cast<PARAM_CFG_DOUBLE&>( aParam );
129 aValue.ToCDouble( param.m_Pt_param );
130 break;
131 }
133 {
134 PARAM_CFG_WXSTRING& param = static_cast<PARAM_CFG_WXSTRING&>( aParam );
135 *param.m_Pt_param = aValue;
136 break;
137 }
138 default:
139 wxASSERT_MSG( false, wxS( "Unsupported PARAM_CFG variant: " )
140 + wxString::Format( wxS( "%d" ), aParam.m_Type ) );
141 }
142}
143
145 wxDialog( aParent, wxID_ANY, _( "Edit Advanced Configuration" ), wxDefaultPosition, wxDefaultSize,
146 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )
147{
148 m_cfgFile = wxFileName( PATHS::GetUserSettingsPath(), wxS( "kicad_advanced" ) );
149
150 m_grid = new WX_GRID( this, wxID_ANY );
151 m_grid->CreateGrid( 0, 3 );
152 m_grid->SetColSize( 0, 100 ); // SetColumnAutosizer() will use these for minimum size
153 m_grid->SetColSize( 1, 80 );
154 m_grid->SetColLabelValue( 0, _( "Key" ) );
155 m_grid->SetColLabelValue( 1, _( "Value" ) );
156 m_grid->SetColLabelValue( 2, _( "Extant" ) );
157 m_grid->HideCol( 2 );
158 m_grid->SetRowLabelSize( 0 );
159 m_grid->SetupColumnAutosizer( 1 );
160
161 loadSettings();
162
163 wxStdDialogButtonSizer* buttonSizer = new wxStdDialogButtonSizer();
164 wxButton* okButton = new wxButton( this, wxID_OK, _( "OK" ) );
165 okButton->SetDefault();
166 buttonSizer->AddButton( okButton );
167 buttonSizer->Realize();
168
169 wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
170 sizer->Add( m_grid, 1, wxEXPAND | wxALL, 5 );
171 sizer->Add( buttonSizer, 0, wxEXPAND | wxALL, 5 );
172 SetSizer( sizer );
173
174 wxDisplay display( wxDisplay::GetFromWindow( this ) );
175 wxRect displayRect = display.GetClientArea();
176
177 SetMinSize( wxSize( 500, 300 ) );
178 SetMaxSize( wxSize( displayRect.GetWidth() - 100, displayRect.GetHeight() - 100 ) );
179 SetSizeHints( wxSize( 700, 500 ) );
180
181 m_grid->Bind( wxEVT_GRID_CELL_CHANGED, &DIALOG_EDIT_CFG::OnCellChange, this );
182 m_grid->Bind( wxEVT_GRID_CELL_RIGHT_CLICK, &DIALOG_EDIT_CFG::OnCellRightClick, this );
183 Bind( wxEVT_SIZE, &DIALOG_EDIT_CFG::OnSize, this );
184
185 m_contextRow = -1;
186
187 Layout();
188 Centre();
189}
190
191
193{
194 const ADVANCED_CFG& adv = ADVANCED_CFG::GetCfg();
195 const std::vector<std::unique_ptr<PARAM_CFG>>& entries = adv.GetEntries();
196
197 for( const auto& entry : entries )
198 {
199 wxString value = paramValueString( *entry );
200 wxString def = paramDefaultString( *entry );
201 int row = m_grid->GetNumberRows();
202 m_grid->AppendRows( 1 );
203 m_grid->SetCellValue( row, 0, entry->m_Ident );
204 m_grid->SetCellValue( row, 1, value );
205 m_grid->SetCellValue( row, 2, def == value ? wxS( "0" ) : wxS( "1" ) );
206 m_grid->SetReadOnly( row, 2 );
207 updateRowAppearance( row );
208 }
209}
210
211
213{
214 int rows = m_grid->GetNumberRows();
215
216 for( int row = 0; row < rows; ++row )
217 {
218 wxString key = m_grid->GetCellValue( row, 0 );
219 wxString val = m_grid->GetCellValue( row, 1 );
220 wxString ext = m_grid->GetCellValue( row, 2 );
221
222 if( key.IsEmpty() || ext != wxS( "1" ) )
223 continue;
224
225 const std::vector<std::unique_ptr<PARAM_CFG>>& entries = ADVANCED_CFG::GetCfg().GetEntries();
226 for( auto& entry : entries )
227 {
228 if( entry->m_Ident == key )
229 {
230 writeParam( *entry, val );
231 break;
232 }
233 }
234 }
235
236 ADVANCED_CFG& adv = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() );
237 adv.Save();
238}
239
240
241void DIALOG_EDIT_CFG::OnCellChange( wxGridEvent& aEvent )
242{
243 int row = aEvent.GetRow();
244 int col = aEvent.GetCol();
245
246 if( col == 0 || col == 1 )
247 {
248 m_grid->SetCellValue( row, 2, wxS( "1" ) );
249 updateRowAppearance( row );
250 }
251
252 saveSettings();
253
254 int lastRow = m_grid->GetNumberRows() - 1;
255 if( !m_grid->GetCellValue( lastRow, 0 ).IsEmpty() || !m_grid->GetCellValue( lastRow, 1 ).IsEmpty() )
256 {
257 m_grid->AppendRows( 1 );
258 m_grid->SetCellValue( m_grid->GetNumberRows() - 1, 2, wxS( "0" ) );
259 m_grid->SetReadOnly( m_grid->GetNumberRows() - 1, 2 );
260 updateRowAppearance( m_grid->GetNumberRows() - 1 );
261 }
262
263 aEvent.Skip();
264}
265
266
267void DIALOG_EDIT_CFG::OnCellRightClick( wxGridEvent& aEvent )
268{
269 m_contextRow = aEvent.GetRow();
270 wxMenu menu;
271 menu.Append( wxID_ANY, _( "Reset to default" ) );
272 menu.Bind( wxEVT_MENU, &DIALOG_EDIT_CFG::OnResetDefault, this );
273 PopupMenu( &menu );
274 menu.Unbind( wxEVT_MENU, &DIALOG_EDIT_CFG::OnResetDefault, this );
275}
276
277
278void DIALOG_EDIT_CFG::OnResetDefault( wxCommandEvent& aEvent )
279{
280 if( m_contextRow < 0 )
281 return;
282
283 wxString key = m_grid->GetCellValue( m_contextRow, 0 );
284 wxString def;
285
286 const ADVANCED_CFG& adv = ADVANCED_CFG::GetCfg();
287 const std::vector<std::unique_ptr<PARAM_CFG>>& entries = adv.GetEntries();
288
289 for( const auto& entry : entries )
290 {
291 if( entry->m_Ident == key )
292 {
293 def = paramDefaultString( *entry );
294 break;
295 }
296 }
297
298 m_grid->SetCellValue( m_contextRow, 1, def );
299 m_grid->SetCellValue( m_contextRow, 2, wxS( "0" ) );
301 saveSettings();
302}
303
304
306{
307 bool ext = m_grid->GetCellValue( aRow, 2 ) == wxS( "1" );
308 wxFont font = m_grid->GetCellFont( aRow, 0 );
309 font.SetWeight( ext ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL );
310 m_grid->SetCellFont( aRow, 0, font );
311 m_grid->SetCellFont( aRow, 1, font );
312}
const std::vector< std::unique_ptr< PARAM_CFG > > & GetEntries() const
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)
void OnResetDefault(wxCommandEvent &aEvent)
wxFileName m_cfgFile
void updateRowAppearance(int aRow)
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:592
@ 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)