KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_fp_editor_field_defaults.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
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
26#include <pgm_base.h>
30#include <template_fieldnames.h>
32#include <grid_tricks.h>
33#include <eda_text.h>
35#include <bitmaps.h>
36#include <confirm.h>
37
38
39class TEXT_ITEMS_GRID_TABLE : public wxGridTableBase
40{
42 std::vector<TEXT_ITEM_INFO> m_items;
43
44public:
45 TEXT_ITEMS_GRID_TABLE( bool aForFieldProps ) :
46 m_forFieldProps( aForFieldProps )
47 {}
48
49 int GetNumberRows() override { return m_items.size(); }
50 int GetNumberCols() override { return m_forFieldProps ? 3 : 2; }
51
52 wxString GetColLabelValue( int aCol ) override
53 {
54 if( m_forFieldProps )
55 {
56 switch( aCol )
57 {
58 case 0: return _( "Value" );
59 case 1: return _( "Show" );
60 case 2: return _( "Layer" );
61 default: return wxEmptyString;
62 }
63 }
64 else
65 {
66 switch( aCol )
67 {
68 case 0: return _( "Text Items" );
69 case 1: return _( "Layer" );
70 default: return wxEmptyString;
71 }
72 }
73 }
74
75 wxString GetRowLabelValue( int aRow ) override
76 {
77 switch( aRow )
78 {
79 case 0: return _( "Reference designator" );
80 case 1: return _( "Value" );
81 default: return wxEmptyString;
82 }
83 }
84
85 bool CanGetValueAs( int aRow, int aCol, const wxString& aTypeName ) override
86 {
87 if( m_forFieldProps )
88 {
89 switch( aCol )
90 {
91 case 0: return aTypeName == wxGRID_VALUE_STRING;
92 case 1: return aTypeName == wxGRID_VALUE_BOOL;
93 case 2: return aTypeName == wxGRID_VALUE_NUMBER;
94 default: wxFAIL; return false;
95 }
96 }
97 else
98 {
99 switch( aCol )
100 {
101 case 0: return aTypeName == wxGRID_VALUE_STRING;
102 case 1: return aTypeName == wxGRID_VALUE_NUMBER;
103 default: wxFAIL; return false;
104 }
105 }
106 }
107
108 bool CanSetValueAs( int aRow, int aCol, const wxString& aTypeName ) override
109 {
110 return CanGetValueAs( aRow, aCol, aTypeName );
111 }
112
113 wxString GetValue( int row, int col ) override { return m_items[row].m_Text; }
114 void SetValue( int row, int col, const wxString& value ) override
115 {
116 if( col == 0 )
117 m_items[row].m_Text = value;
118 }
119
120 bool GetValueAsBool( int row, int col ) override { return m_items[row].m_Visible; }
121 void SetValueAsBool( int row, int col, bool value ) override
122 {
123 if( col == 1 )
124 m_items[row].m_Visible = value;
125 }
126
127 long GetValueAsLong( int row, int col ) override { return m_items[row].m_Layer; }
128 void SetValueAsLong( int row, int col, long value ) override
129 {
130 if( col == GetNumberCols() - 1 ) // only last column uses a long value
131 // (probably useless test)
132 m_items[row].m_Layer = static_cast<PCB_LAYER_ID>( value );
133 }
134
135 bool AppendRows( size_t aNumRows = 1 ) override
136 {
137 for( size_t i = 0; i < aNumRows; ++i )
138 m_items.emplace_back( wxT( "" ), true, F_SilkS );
139
140 if( GetView() )
141 {
142 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, aNumRows );
143 GetView()->ProcessTableMessage( msg );
144 }
145
146 return true;
147 }
148
149 bool DeleteRows( size_t aPos, size_t aNumRows ) override
150 {
151 // aPos may be a large positive, e.g. size_t(-1), and the sum of
152 // aPos+aNumRows may wrap here, so both ends of the range are tested.
153 if( aPos < m_items.size() && aPos + aNumRows <= m_items.size() )
154 {
155 m_items.erase( m_items.begin() + aPos, m_items.begin() + aPos + aNumRows );
156
157 if( GetView() )
158 {
159 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aPos, aNumRows );
160 GetView()->ProcessTableMessage( msg );
161 }
162 return true;
163 }
164
165 return false;
166 }
167};
168
169
171{
172 return *GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" );
173}
174
175
177 UNITS_PROVIDER* aUnitsProvider ) :
179 m_unitProvider( aUnitsProvider ),
180 m_designSettings( GetPgmSettings().m_DesignSettings )
181{
182 m_fieldPropsGrid->SetTable( new TEXT_ITEMS_GRID_TABLE( true ), true );
183 m_fieldPropsGrid->PushEventHandler( new GRID_TRICKS( m_fieldPropsGrid ) );
184 m_fieldPropsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
185
186 wxGridCellAttr* attr = new wxGridCellAttr;
187 attr->SetRenderer( new wxGridCellBoolRenderer() );
188 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
189 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
190 m_fieldPropsGrid->SetColAttr( 1, attr );
191
192 attr = new wxGridCellAttr;
193 attr->SetRenderer( new GRID_CELL_LAYER_RENDERER( nullptr ) );
194 attr->SetEditor( new GRID_CELL_LAYER_SELECTOR( nullptr, {} ) );
195 m_fieldPropsGrid->SetColAttr( 2, attr );
196
197 m_textItemsGrid->SetTable( new TEXT_ITEMS_GRID_TABLE( false ), true );
198 m_textItemsGrid->PushEventHandler( new GRID_TRICKS( m_textItemsGrid ) );
199 m_textItemsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
200
201 attr = new wxGridCellAttr;
202 attr->SetRenderer( new GRID_CELL_LAYER_RENDERER( nullptr ) );
203 attr->SetEditor( new GRID_CELL_LAYER_SELECTOR( nullptr, {} ) );
204 m_textItemsGrid->SetColAttr( 1, attr );
205}
206
207
209{
210 // destroy GRID_TRICKS before grids.
211 m_fieldPropsGrid->PopEventHandler( true );
212 m_textItemsGrid->PopEventHandler( true );
213}
214
215
217{
218 // Footprint defaults
219 wxGridTableBase* table = m_fieldPropsGrid->GetTable();
220 table->DeleteRows( 0, m_fieldPropsGrid->GetNumberRows() );
221 table->AppendRows( 2 );
222
223 for( int i = 0; i < std::min<int>( 2, (int) aCfg->m_DesignSettings.m_DefaultFPTextItems.size() ); ++i )
224 {
226
227 table->SetValue( i, 0, item.m_Text );
228 table->SetValueAsBool( i, 1, item.m_Visible );
229 table->SetValueAsLong( i, 2, item.m_Layer );
230 }
231
232 table = m_textItemsGrid->GetTable();
233 table->DeleteRows( 0, m_textItemsGrid->GetNumberRows() );
234
235 // if aCfg->m_DesignSettings.m_DefaultFPTextItems.size() is > 2 (first and second are ref and
236 // value), some extra texts must be added to the list of default texts
237 int extra_texts_cnt = (int) aCfg->m_DesignSettings.m_DefaultFPTextItems.size() - 2;
238
239 if( extra_texts_cnt > 0 )
240 table->AppendRows( extra_texts_cnt );
241
242 for( int i = 2; i < (int) aCfg->m_DesignSettings.m_DefaultFPTextItems.size(); ++i )
243 {
245
246 table->SetValue( i - 2, 0, item.m_Text );
247 table->SetValueAsLong( i - 2, 1, item.m_Layer );
248 }
249
250 Layout();
251}
252
253
255{
257
258 loadFPSettings( &cfg );
259
260 return true;
261}
262
263
265{
266 bool retVal = wxPanel::Show( aShow );
267
268 if( aShow )
269 {
270 // These *should* work in the constructor, and indeed they do if this panel is the
271 // first displayed. However, on OSX 3.0.5 (at least), if another panel is displayed
272 // first then the icons will be blank unless they're set here.
273 m_bpAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
274 m_bpDelete->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
275 }
276
277 return retVal;
278}
279
280
282{
284 return false;
285
287
288 // Footprint defaults
289 cfg.m_DefaultFPTextItems.clear();
290
291 wxGridTableBase* table = m_fieldPropsGrid->GetTable();
292
293 for( int i : { 0, 1 } )
294 {
295 wxString text = table->GetValue( i, 0 );
296 bool visible = table->GetValueAsBool( i, 1 );
297 PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( table->GetValueAsLong( i, 2 ) );
298
299 cfg.m_DefaultFPTextItems.emplace_back( text, visible, layer );
300 }
301
302 table = m_textItemsGrid->GetTable();
303
304 for( int i = 0; i < m_textItemsGrid->GetNumberRows(); ++i )
305 {
306 wxString text = table->GetValue( i, 0 );
307 PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( table->GetValueAsLong( i, 1 ) );
308
309 cfg.m_DefaultFPTextItems.emplace_back( text, true, layer );
310 }
311
312 return true;
313}
314
315
317{
319 return;
320
321 wxGridTableBase* table = m_textItemsGrid->GetTable();
322
323 int newRow = m_textItemsGrid->GetNumberRows();
324 table->AppendRows( 1 );
325
326 long defaultBoardLayer = F_SilkS;
327
328 if( newRow > 0 )
329 defaultBoardLayer = table->GetValueAsLong( newRow - 1, 1 );
330
331 table->SetValueAsLong( newRow, 1, defaultBoardLayer );
332
333 m_textItemsGrid->MakeCellVisible( newRow, 0 );
334 m_textItemsGrid->SetGridCursor( newRow, 0 );
335
336 m_textItemsGrid->EnableCellEditControl( true );
337 m_textItemsGrid->ShowCellEditControl();
338}
339
340
342{
343 wxArrayInt selectedRows = m_textItemsGrid->GetSelectedRows();
344
345 if( selectedRows.empty() && m_textItemsGrid->GetGridCursorRow() >= 0 )
346 selectedRows.push_back( m_textItemsGrid->GetGridCursorRow() );
347
348 if( selectedRows.empty() )
349 return;
350
352 return;
353
354 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
355 selectedRows.Sort(
356 []( int* first, int* second )
357 {
358 return *second - *first;
359 } );
360
361 for( int row : selectedRows )
362 {
363 m_textItemsGrid->GetTable()->DeleteRows( row, 1 );
364
365 if( m_textItemsGrid->GetNumberRows() > 0 )
366 {
367 m_textItemsGrid->MakeCellVisible( std::max( 0, row - 1 ),
368 m_textItemsGrid->GetGridCursorCol() );
369 m_textItemsGrid->SetGridCursor( std::max( 0, row - 1 ),
370 m_textItemsGrid->GetGridCursorCol() );
371 }
372 }
373}
374
375
377{
379 cfg.Load(); // Loading without a file will init to defaults
380
381 loadFPSettings( &cfg );
382}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition: bitmap.cpp:110
Container for design settings for a BOARD object.
std::vector< TEXT_ITEM_INFO > m_DefaultFPTextItems
BOARD_DESIGN_SETTINGS m_DesignSettings
Only some of these settings are actually used for footprint editing.
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
virtual void Load()
Updates the parameters of this object based on the current JSON document contents.
Class PANEL_FP_EDITOR_FIELD_DEFAULTS_BASE.
PANEL_FP_EDITOR_FIELD_DEFAULTS(wxWindow *aParent, UNITS_PROVIDER *aUnitsProvider)
void OnAddTextItem(wxCommandEvent &event) override
void OnDeleteTextItem(wxCommandEvent &event) override
void loadFPSettings(const FOOTPRINT_EDITOR_SETTINGS *aCfg)
void ResetPanel() override
Reset the contents of this panel.
void SetBitmap(const wxBitmapBundle &aBmp)
std::vector< TEXT_ITEM_INFO > m_items
bool DeleteRows(size_t aPos, size_t aNumRows) override
wxString GetRowLabelValue(int aRow) override
TEXT_ITEMS_GRID_TABLE(bool aForFieldProps)
void SetValueAsLong(int row, int col, long value) override
void SetValue(int row, int col, const wxString &value) override
wxString GetValue(int row, int col) override
void SetValueAsBool(int row, int col, bool value) override
wxString GetColLabelValue(int aCol) override
bool CanSetValueAs(int aRow, int aCol, const wxString &aTypeName) override
bool GetValueAsBool(int row, int col) override
bool AppendRows(size_t aNumRows=1) override
bool CanGetValueAs(int aRow, int aCol, const wxString &aTypeName) override
long GetValueAsLong(int row, int col) override
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid's SetTable() method with one which doesn't mess up the grid column widths when setting th...
Definition: wx_grid.cpp:273
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:645
This file is part of the common library.
#define _(s)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ F_SilkS
Definition: layer_ids.h:100
static FOOTPRINT_EDITOR_SETTINGS & GetPgmSettings()
see class PGM_BASE