KiCad PCB EDA Suite
fp_text_grid_table.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) 2018-2022 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
24#include <kiway_player.h>
25#include <fp_text_grid_table.h>
28#include <trigo.h>
29#include <pcb_base_frame.h>
31
32enum
33{
34 MYID_SELECT_FOOTPRINT = 991, // must be within GRID_TRICKS' enum range
36};
37
38
39wxArrayString g_menuOrientations;
40
41
43 m_frame( aFrame )
44{
45 // Build the column attributes.
46
47 m_readOnlyAttr = new wxGridCellAttr;
48 m_readOnlyAttr->SetReadOnly( true );
49
50 m_boolColAttr = new wxGridCellAttr;
51 m_boolColAttr->SetRenderer( new wxGridCellBoolRenderer() );
52 m_boolColAttr->SetEditor( new wxGridCellBoolEditor() );
53 m_boolColAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
54
55 if( g_menuOrientations.IsEmpty() )
56 {
61 }
62
63 m_orientationColAttr = new wxGridCellAttr;
65
66 m_layerColAttr = new wxGridCellAttr;
67 m_layerColAttr->SetRenderer( new GRID_CELL_LAYER_RENDERER( m_frame ) );
68 m_layerColAttr->SetEditor( new GRID_CELL_LAYER_SELECTOR( m_frame, {} ) );
69
70 m_eval = std::make_unique<NUMERIC_EVALUATOR>( m_frame->GetUserUnits() );
71
72 m_frame->Bind( UNITS_CHANGED, &FP_TEXT_GRID_TABLE::onUnitsChanged, this );
73}
74
75
77{
78 m_readOnlyAttr->DecRef();
79 m_boolColAttr->DecRef();
80 m_orientationColAttr->DecRef();
81 m_layerColAttr->DecRef();
82
83 m_frame->Unbind( UNITS_CHANGED, &FP_TEXT_GRID_TABLE::onUnitsChanged, this );
84}
85
86
87void FP_TEXT_GRID_TABLE::onUnitsChanged( wxCommandEvent& aEvent )
88{
89 if( GetView() )
90 GetView()->ForceRefresh();
91
92 aEvent.Skip();
93}
94
95
97{
98 switch( aCol )
99 {
100 case FPT_TEXT: return _( "Text Items" );
101 case FPT_SHOWN: return _( "Show" );
102 case FPT_WIDTH: return _( "Width" );
103 case FPT_HEIGHT: return _( "Height" );
104 case FPT_THICKNESS: return _( "Thickness" );
105 case FPT_ITALIC: return _( "Italic" );
106 case FPT_LAYER: return _( "Layer" );
107 case FPT_ORIENTATION: return _( "Orientation" );
108 case FPT_UPRIGHT: return _( "Keep Upright" );
109 case FPT_XOFFSET: return _( "X Offset" );
110 case FPT_YOFFSET: return _( "Y Offset" );
111 default: wxFAIL; return wxEmptyString;
112 }
113}
114
115
117{
118 switch( aRow )
119 {
120 case 0: return _( "Reference designator" );
121 case 1: return _( "Value" );
122 default: return wxEmptyString;
123 }
124}
125
126
127bool FP_TEXT_GRID_TABLE::CanGetValueAs( int aRow, int aCol, const wxString& aTypeName )
128{
129 switch( aCol )
130 {
131 case FPT_TEXT:
132 case FPT_WIDTH:
133 case FPT_HEIGHT:
134 case FPT_THICKNESS:
135 case FPT_ORIENTATION:
136 case FPT_XOFFSET:
137 case FPT_YOFFSET:
138 return aTypeName == wxGRID_VALUE_STRING;
139
140 case FPT_SHOWN:
141 case FPT_ITALIC:
142 case FPT_UPRIGHT:
143 return aTypeName == wxGRID_VALUE_BOOL;
144
145 case FPT_LAYER:
146 return aTypeName == wxGRID_VALUE_NUMBER;
147
148 default:
149 wxFAIL;
150 return false;
151 }
152}
153
154
155bool FP_TEXT_GRID_TABLE::CanSetValueAs( int aRow, int aCol, const wxString& aTypeName )
156{
157 return CanGetValueAs( aRow, aCol, aTypeName );
158}
159
160
161wxGridCellAttr* FP_TEXT_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind )
162{
163 switch( aCol )
164 {
165 case FPT_TEXT:
166 case FPT_WIDTH:
167 case FPT_HEIGHT:
168 case FPT_THICKNESS:
169 case FPT_XOFFSET:
170 case FPT_YOFFSET:
171 return nullptr;
172
173 case FPT_SHOWN:
174 case FPT_ITALIC:
175 case FPT_UPRIGHT:
176 m_boolColAttr->IncRef();
177 return m_boolColAttr;
178
179 case FPT_LAYER:
180 m_layerColAttr->IncRef();
181 return m_layerColAttr;
182
183 case FPT_ORIENTATION:
184 m_orientationColAttr->IncRef();
186
187 default:
188 wxFAIL;
189 return nullptr;
190 }
191}
192
193
194wxString FP_TEXT_GRID_TABLE::GetValue( int aRow, int aCol )
195{
196 wxGrid* grid = GetView();
197 const FP_TEXT& text = this->at( (size_t) aRow );
198
199 if( grid->GetGridCursorRow() == aRow && grid->GetGridCursorCol() == aCol
200 && grid->IsCellEditControlShown() )
201 {
202 auto it = m_evalOriginal.find( { aRow, aCol } );
203
204 if( it != m_evalOriginal.end() )
205 return it->second;
206 }
207
208 switch( aCol )
209 {
210 case FPT_TEXT:
211 return text.GetText();
212
213 case FPT_WIDTH:
214 return m_frame->StringFromValue( text.GetTextWidth(), true );
215
216 case FPT_HEIGHT:
217 return m_frame->StringFromValue( text.GetTextHeight(), true );
218
219 case FPT_THICKNESS:
220 return m_frame->StringFromValue( text.GetTextThickness(), true );
221
222 case FPT_LAYER:
223 return text.GetLayerName();
224
225 case FPT_ORIENTATION:
226 return m_frame->StringFromValue( text.GetTextAngle(), true );
227
228 case FPT_XOFFSET:
229 return m_frame->StringFromValue( text.GetPos0().x, true );
230
231 case FPT_YOFFSET:
232 return m_frame->StringFromValue( text.GetPos0().y, true );
233
234 default:
235 // we can't assert here because wxWidgets sometimes calls this without checking
236 // the column type when trying to see if there's an overflow
237 return wxT( "bad wxWidgets!" );
238 }
239}
240
241
242bool FP_TEXT_GRID_TABLE::GetValueAsBool( int aRow, int aCol )
243{
244 FP_TEXT& text = this->at( (size_t) aRow );
245
246 switch( aCol )
247 {
248 case FPT_SHOWN: return text.IsVisible();
249 case FPT_ITALIC: return text.IsItalic();
250 case FPT_UPRIGHT: return text.IsKeepUpright();
251
252 default:
253 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
254 return false;
255 }
256}
257
258
259long FP_TEXT_GRID_TABLE::GetValueAsLong( int aRow, int aCol )
260{
261 FP_TEXT& text = this->at( (size_t) aRow );
262
263 switch( aCol )
264 {
265 case FPT_LAYER: return text.GetLayer();
266
267 default:
268 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a long value" ), aCol ) );
269 return 0;
270 }
271}
272
273
274void FP_TEXT_GRID_TABLE::SetValue( int aRow, int aCol, const wxString &aValue )
275{
276 FP_TEXT& text = this->at( (size_t) aRow );
277 VECTOR2I pos;
278 wxString value = aValue;
279
280 switch( aCol )
281 {
282 case FPT_WIDTH:
283 case FPT_HEIGHT:
284 case FPT_THICKNESS:
285 case FPT_XOFFSET:
286 case FPT_YOFFSET:
287 m_eval->SetDefaultUnits( m_frame->GetUserUnits() );
288
289 if( m_eval->Process( value ) )
290 {
291 m_evalOriginal[ { aRow, aCol } ] = value;
292 value = m_eval->Result();
293 }
294
295 break;
296
297 default:
298 break;
299 }
300
301 switch( aCol )
302 {
303 case FPT_TEXT:
304 text.SetText( value );
305 break;
306
307 case FPT_WIDTH:
308 text.SetTextWidth( m_frame->ValueFromString( value ) );
309 break;
310
311 case FPT_HEIGHT:
312 text.SetTextHeight( m_frame->ValueFromString( value ) );
313 break;
314
315 case FPT_THICKNESS:
316 text.SetTextThickness( m_frame->ValueFromString( value ) );
317 break;
318
319 case FPT_ORIENTATION:
320 text.SetTextAngle( m_frame->AngleValueFromString( value ) );
321 text.SetDrawCoord();
322 break;
323
324 case FPT_XOFFSET:
325 case FPT_YOFFSET:
326 pos = text.GetPos0();
327
328 if( aCol == FPT_XOFFSET )
329 pos.x = m_frame->ValueFromString( value );
330 else
331 pos.y = m_frame->ValueFromString( value );
332
333 text.SetPos0( pos );
334 text.SetDrawCoord();
335 break;
336
337 default:
338 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a string value" ), aCol ) );
339 break;
340 }
341
342 GetView()->Refresh();
343}
344
345
346void FP_TEXT_GRID_TABLE::SetValueAsBool( int aRow, int aCol, bool aValue )
347{
348 FP_TEXT& text = this->at( (size_t) aRow );
349
350 switch( aCol )
351 {
352 case FPT_SHOWN:
353 text.SetVisible( aValue );
354 break;
355
356 case FPT_ITALIC:
357 text.SetItalic( aValue );
358 break;
359
360 case FPT_UPRIGHT:text.SetKeepUpright( aValue );
361 break;
362
363 default:
364 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
365 break;
366 }
367}
368
369
370void FP_TEXT_GRID_TABLE::SetValueAsLong( int aRow, int aCol, long aValue )
371{
372 FP_TEXT& text = this->at( (size_t) aRow );
373
374 switch( aCol )
375 {
376 case FPT_LAYER:
377 text.SetLayer( ToLAYER_ID( (int) aValue ) );
378 text.SetMirrored( IsBackLayer( text.GetLayer() ) );
379 break;
380
381 default:
382 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a long value" ), aCol ) );
383 break;
384 }
385}
386
wxGridCellAttr * GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind) override
void SetValueAsLong(int aRow, int aCol, long aValue) override
wxGridCellAttr * m_boolColAttr
void SetValue(int aRow, int aCol, const wxString &aValue) override
wxString GetValue(int aRow, int aCol) override
wxString GetColLabelValue(int aCol) override
PCB_BASE_FRAME * m_frame
FP_TEXT_GRID_TABLE(PCB_BASE_FRAME *aFrame)
void onUnitsChanged(wxCommandEvent &aEvent)
wxGridCellAttr * m_readOnlyAttr
bool GetValueAsBool(int aRow, int aCol) override
long GetValueAsLong(int aRow, int aCol) override
void SetValueAsBool(int aRow, int aCol, bool aValue) override
wxGridCellAttr * m_orientationColAttr
wxGridCellAttr * m_layerColAttr
bool CanSetValueAs(int aRow, int aCol, const wxString &aTypeName) override
wxString GetRowLabelValue(int aRow) override
bool CanGetValueAs(int aRow, int aCol, const wxString &aTypeName) override
std::map< std::pair< int, int >, wxString > m_evalOriginal
std::unique_ptr< NUMERIC_EVALUATOR > m_eval
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
EDA_ANGLE AngleValueFromString(const wxString &aTextValue)
wxString StringFromValue(double aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Converts aValue in internal units into a united string.
int ValueFromString(const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Converts aTextValue in aUnits to internal units used by the frame.
EDA_UNITS GetUserUnits() const
#define _(s)
wxArrayString g_menuOrientations
@ MYID_SHOW_DATASHEET
@ MYID_SELECT_FOOTPRINT
@ FPT_ORIENTATION
@ FPT_YOFFSET
@ FPT_UPRIGHT
@ FPT_ITALIC
@ FPT_LAYER
@ FPT_WIDTH
@ FPT_SHOWN
@ FPT_HEIGHT
@ FPT_XOFFSET
@ FPT_TEXT
@ FPT_THICKNESS
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
Definition: layer_ids.h:922
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:932
wxString GetText(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
Definition: eda_units.cpp:98
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