KiCad PCB EDA Suite
fields_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.h>
25#include <kiway_player.h>
26#include <dialog_shim.h>
27#include <fields_grid_table.h>
28#include <sch_base_frame.h>
29#include <sch_field.h>
30#include <sch_label.h>
31#include <sch_validators.h>
32#include <validators.h>
33#include <sch_edit_frame.h>
34#include <netclass.h>
35#include <symbol_library.h>
36#include <schematic.h>
37#include <template_fieldnames.h>
42#include "eda_doc.h"
44#include "font/fontconfig.h"
46#include <wx/settings.h>
47#include <string_utils.h>
49
50
51enum
52{
55};
56
57
58#define DEFAULT_FONT_NAME _( "Default Font" )
59
60
61static wxString netList( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH& aSheetPath )
62{
63 /*
64 * Symbol netlist format:
65 * library:footprint
66 * reference
67 * value
68 * pinName,netName,pinFunction,pinType
69 * pinName,netName,pinFunction,pinType
70 * ...
71 */
72 wxString netlist;
73
74 netlist << EscapeString( aSymbol->GetFootprint( &aSheetPath, true ), CTX_LINE ) << wxS( "\r" );
75 netlist << EscapeString( aSymbol->GetRef( &aSheetPath ), CTX_LINE ) << wxS( "\r" );
76 netlist << EscapeString( aSymbol->GetValue( &aSheetPath, true ), CTX_LINE );
78 for( SCH_PIN* pin : aSymbol->GetPins( &aSheetPath ) )
79 {
80 netlist << wxS( "\r" );
81 netlist << EscapeString( pin->GetNumber(), CTX_CSV ) << wxS( "," );
82 netlist << EscapeString( pin->GetDefaultNetName( aSheetPath ), CTX_CSV ) << wxS( "," );
83 netlist << EscapeString( pin->GetName(), CTX_CSV ) << wxS( "," );
84 netlist << EscapeString( pin->GetCanonicalElectricalTypeName(), CTX_CSV );
85 }
86
87 return netlist;
88}
89
91template <class T>
93 WX_GRID* aGrid, LIB_SYMBOL* aSymbol ) :
94 m_frame( aFrame ),
95 m_dialog( aDialog ),
96 m_grid( aGrid ),
97 m_parentType( SCH_SYMBOL_T ),
98 m_mandatoryFieldCount( MANDATORY_FIELDS ),
99 m_part( aSymbol ),
100 m_fieldNameValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), FIELD_NAME ),
101 m_referenceValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), REFERENCE_FIELD ),
102 m_valueValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), VALUE_FIELD ),
103 m_libIdValidator(),
104 m_urlValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), FIELD_VALUE ),
105 m_nonUrlValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), FIELD_VALUE ),
106 m_filepathValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), SHEETFILENAME )
108 initGrid( aGrid );
109}
110
112template <class T>
114 WX_GRID* aGrid, SCH_SYMBOL* aSymbol ) :
115 m_frame( aFrame ),
116 m_dialog( aDialog ),
117 m_grid( aGrid ),
118 m_parentType( SCH_SYMBOL_T ),
119 m_mandatoryFieldCount( MANDATORY_FIELDS ),
120 m_part( aSymbol->GetLibSymbolRef().get() ),
121 m_symbolNetlist( netList( aSymbol, aFrame->GetCurrentSheet() ) ),
122 m_fieldNameValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), FIELD_NAME ),
123 m_referenceValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), REFERENCE_FIELD ),
124 m_valueValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), VALUE_FIELD ),
125 m_libIdValidator(),
126 m_urlValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), FIELD_VALUE ),
127 m_nonUrlValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), FIELD_VALUE ),
128 m_filepathValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), SHEETFILENAME )
129{
130 initGrid( aGrid );
131}
132
133
134template <class T>
136 WX_GRID* aGrid, SCH_SHEET* aSheet ) :
137 m_frame( aFrame ),
138 m_dialog( aDialog ),
139 m_grid( aGrid ),
140 m_parentType( SCH_SHEET_T ),
141 m_mandatoryFieldCount( SHEET_MANDATORY_FIELDS ),
142 m_part( nullptr ),
143 m_fieldNameValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), FIELD_NAME ),
144 m_referenceValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), SHEETNAME_V ),
145 m_valueValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), VALUE_FIELD ),
146 m_libIdValidator(),
147 m_urlValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), FIELD_VALUE ),
148 m_nonUrlValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), FIELD_VALUE ),
149 m_filepathValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), SHEETFILENAME_V )
150{
151 initGrid( aGrid );
152}
153
154
155template <class T>
157 WX_GRID* aGrid, SCH_LABEL_BASE* aLabel ) :
158 m_frame( aFrame ),
159 m_dialog( aDialog ),
160 m_grid( aGrid ),
161 m_parentType( SCH_LABEL_LOCATE_ANY_T ),
162 m_mandatoryFieldCount( aLabel->GetMandatoryFieldCount() ),
163 m_part( nullptr ),
164 m_fieldNameValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), FIELD_NAME ),
165 m_referenceValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), 0 ),
166 m_valueValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), 0 ),
167 m_libIdValidator(),
168 m_urlValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), FIELD_VALUE ),
169 m_nonUrlValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), FIELD_VALUE ),
170 m_filepathValidator( aFrame->IsType( FRAME_SCH_SYMBOL_EDITOR ), 0 )
171{
172 initGrid( aGrid );
173}
174
175
176template <class T>
178{
179 // Build the various grid cell attributes.
180 // NOTE: validators and cellAttrs are member variables to get the destruction order
181 // right. wxGrid is VERY cranky about this.
182
183 m_readOnlyAttr = new wxGridCellAttr;
184 m_readOnlyAttr->SetReadOnly( true );
185
186 m_fieldNameAttr = new wxGridCellAttr;
188 nameEditor->SetValidator( m_fieldNameValidator );
189 m_fieldNameAttr->SetEditor( nameEditor );
190
191 m_referenceAttr = new wxGridCellAttr;
192 GRID_CELL_TEXT_EDITOR* referenceEditor = new GRID_CELL_TEXT_EDITOR();
193 referenceEditor->SetValidator( m_referenceValidator );
194 m_referenceAttr->SetEditor( referenceEditor );
195
196 m_valueAttr = new wxGridCellAttr;
197 GRID_CELL_TEXT_EDITOR* valueEditor = new GRID_CELL_TEXT_EDITOR();
198 valueEditor->SetValidator( m_valueValidator );
199 m_valueAttr->SetEditor( valueEditor );
200
201 m_footprintAttr = new wxGridCellAttr;
202 GRID_CELL_FPID_EDITOR* fpIdEditor = new GRID_CELL_FPID_EDITOR( m_dialog, m_symbolNetlist );
203 fpIdEditor->SetValidator( m_libIdValidator );
204 m_footprintAttr->SetEditor( fpIdEditor );
205
206 m_urlAttr = new wxGridCellAttr;
207 GRID_CELL_URL_EDITOR* urlEditor = new GRID_CELL_URL_EDITOR( m_dialog,
208 m_frame->Prj().SchSearchS() );
209 urlEditor->SetValidator( m_urlValidator );
210 m_urlAttr->SetEditor( urlEditor );
211
212 m_nonUrlAttr = new wxGridCellAttr;
213 GRID_CELL_TEXT_EDITOR* nonUrlEditor = new GRID_CELL_TEXT_EDITOR();
214 nonUrlEditor->SetValidator( m_nonUrlValidator );
215 m_nonUrlAttr->SetEditor( nonUrlEditor );
216
217 m_curdir = m_frame->Prj().GetProjectPath();
218 m_filepathAttr = new wxGridCellAttr;
219
220 // Create a wild card using wxFileDialog syntax.
221 wxString wildCard( _( "Schematic Files" ) );
222 std::vector<std::string> exts;
223 exts.push_back( KiCadSchematicFileExtension );
224 wildCard += AddFileExtListToFilter( exts );
225
226 auto filepathEditor = new GRID_CELL_PATH_EDITOR( m_dialog, aGrid, &m_curdir, wildCard );
227 filepathEditor->SetValidator( m_filepathValidator );
228 m_filepathAttr->SetEditor( filepathEditor );
229
230 m_boolAttr = new wxGridCellAttr;
231 m_boolAttr->SetRenderer( new wxGridCellBoolRenderer() );
232 m_boolAttr->SetEditor( new wxGridCellBoolEditor() );
233 m_boolAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
234
235 wxArrayString vAlignNames;
236 vAlignNames.Add( _( "Top" ) );
237 vAlignNames.Add( _( "Center" ) );
238 vAlignNames.Add( _( "Bottom" ) );
239 m_vAlignAttr = new wxGridCellAttr;
240 m_vAlignAttr->SetEditor( new wxGridCellChoiceEditor( vAlignNames ) );
241 m_vAlignAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_BOTTOM );
242
243 wxArrayString hAlignNames;
244 hAlignNames.Add( _( "Left" ) );
245 hAlignNames.Add(_( "Center" ) );
246 hAlignNames.Add(_( "Right" ) );
247 m_hAlignAttr = new wxGridCellAttr;
248 m_hAlignAttr->SetEditor( new wxGridCellChoiceEditor( hAlignNames ) );
249 m_hAlignAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_BOTTOM );
250
251 wxArrayString orientationNames;
252 orientationNames.Add( _( "Horizontal" ) );
253 orientationNames.Add(_( "Vertical" ) );
254 m_orientationAttr = new wxGridCellAttr;
255 m_orientationAttr->SetEditor( new wxGridCellChoiceEditor( orientationNames ) );
256 m_orientationAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_BOTTOM );
257
258 SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
259 wxArrayString existingNetclasses;
260
261 if( editFrame )
262 {
263 // Load the combobox with existing existingNetclassNames
264 PROJECT_FILE& projectFile = editFrame->Prj().GetProjectFile();
265 const std::shared_ptr<NET_SETTINGS>& settings = projectFile.NetSettings();
266
267 existingNetclasses.push_back( settings->m_DefaultNetClass->GetName() );
268
269 for( const auto& [ name, netclass ] : settings->m_NetClasses )
270 existingNetclasses.push_back( name );
271 }
272
273 m_netclassAttr = new wxGridCellAttr;
274 m_netclassAttr->SetEditor( new GRID_CELL_COMBOBOX( existingNetclasses ) );
275
276 wxArrayString fonts;
277 std::vector<std::string> fontNames;
278 Fontconfig()->ListFonts( fontNames );
279
280 for( const std::string& name : fontNames )
281 fonts.Add( wxString( name ) );
282
283 fonts.Sort();
284 fonts.Insert( KICAD_FONT_NAME, 0 );
285 fonts.Insert( DEFAULT_FONT_NAME, 0 );
286
287 m_fontAttr = new wxGridCellAttr;
288 m_fontAttr->SetEditor( new GRID_CELL_COMBOBOX( fonts ) );
289
290 m_colorAttr = new wxGridCellAttr;
291 m_colorAttr->SetRenderer( new GRID_CELL_COLOR_RENDERER( m_dialog ) );
292 m_colorAttr->SetEditor( new GRID_CELL_COLOR_SELECTOR( m_dialog, aGrid ) );
293
294 m_frame->Bind( UNITS_CHANGED, &FIELDS_GRID_TABLE<T>::onUnitsChanged, this );
295}
296
297
298template <class T>
300{
301 m_readOnlyAttr->DecRef();
302 m_fieldNameAttr->DecRef();
303 m_boolAttr->DecRef();
304 m_referenceAttr->DecRef();
305 m_valueAttr->DecRef();
306 m_footprintAttr->DecRef();
307 m_urlAttr->DecRef();
308 m_nonUrlAttr->DecRef();
309 m_filepathAttr->DecRef();
310 m_vAlignAttr->DecRef();
311 m_hAlignAttr->DecRef();
312 m_orientationAttr->DecRef();
313 m_netclassAttr->DecRef();
314 m_fontAttr->DecRef();
315 m_colorAttr->DecRef();
316
317 m_frame->Unbind( UNITS_CHANGED, &FIELDS_GRID_TABLE<T>::onUnitsChanged, this );
318}
319
320
321template <class T>
322void FIELDS_GRID_TABLE<T>::onUnitsChanged( wxCommandEvent& aEvent )
323{
324 if( GetView() )
325 GetView()->ForceRefresh();
326
327 aEvent.Skip();
328}
329
330
331template <class T>
333{
334 switch( aCol )
335 {
336 case FDC_NAME: return _( "Name" );
337 case FDC_VALUE: return _( "Value" );
338 case FDC_SHOWN: return _( "Show" );
339 case FDC_H_ALIGN: return _( "H Align" );
340 case FDC_V_ALIGN: return _( "V Align" );
341 case FDC_ITALIC: return _( "Italic" );
342 case FDC_BOLD: return _( "Bold" );
343 case FDC_TEXT_SIZE: return _( "Text Size" );
344 case FDC_ORIENTATION: return _( "Orientation" );
345 case FDC_POSX: return _( "X Position" );
346 case FDC_POSY: return _( "Y Position" );
347 case FDC_FONT: return _( "Font" );
348 case FDC_COLOR: return _( "Color" );
349 default: wxFAIL; return wxEmptyString;
350 }
351}
352
353
354template <class T>
355bool FIELDS_GRID_TABLE<T>::CanGetValueAs( int aRow, int aCol, const wxString& aTypeName )
356{
357 switch( aCol )
358 {
359 case FDC_NAME:
360 case FDC_VALUE:
361 case FDC_H_ALIGN:
362 case FDC_V_ALIGN:
363 case FDC_TEXT_SIZE:
364 case FDC_ORIENTATION:
365 case FDC_POSX:
366 case FDC_POSY:
367 case FDC_FONT:
368 case FDC_COLOR:
369 return aTypeName == wxGRID_VALUE_STRING;
370
371 case FDC_SHOWN:
372 case FDC_ITALIC:
373 case FDC_BOLD:
374 return aTypeName == wxGRID_VALUE_BOOL;
375
376 default:
377 wxFAIL;
378 return false;
379 }
380}
381
382
383template <class T>
384bool FIELDS_GRID_TABLE<T>::CanSetValueAs( int aRow, int aCol, const wxString& aTypeName )
385{
386 return CanGetValueAs( aRow, aCol, aTypeName );
387}
388
389
390template <class T>
391wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind )
392{
393 wxGridCellAttr* tmp;
394
395 switch( aCol )
396 {
397 case FDC_NAME:
398 if( aRow < m_mandatoryFieldCount )
399 {
400 tmp = m_fieldNameAttr->Clone();
401 tmp->SetReadOnly( true );
402 return tmp;
403 }
404 else
405 {
406 m_fieldNameAttr->IncRef();
407 return m_fieldNameAttr;
408 }
409
410 case FDC_VALUE:
411 if( m_parentType == SCH_SYMBOL_T && aRow == REFERENCE_FIELD )
412 {
413 m_referenceAttr->IncRef();
414 return m_referenceAttr;
415 }
416 else if( m_parentType == SCH_SYMBOL_T && aRow == VALUE_FIELD )
417 {
418 // For power symbols, the value is not editable, because value and pin name must
419 // be the same and can be edited only in library editor.
420 if( ( m_part && m_part->IsPower() && !m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) ) )
421 {
422 tmp = m_readOnlyAttr->Clone();
423 tmp->SetReadOnly( true );
424 tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
425 return tmp;
426 }
427 else
428 {
429 m_valueAttr->IncRef();
430 return m_valueAttr;
431 }
432 }
433 else if( m_parentType == SCH_SYMBOL_T && aRow == FOOTPRINT_FIELD )
434 {
435 m_footprintAttr->IncRef();
436 return m_footprintAttr;
437 }
438 else if( m_parentType == SCH_SYMBOL_T && aRow == DATASHEET_FIELD )
439 {
440 m_urlAttr->IncRef();
441 return m_urlAttr;
442 }
443 else if( m_parentType == SCH_SHEET_T && aRow == SHEETNAME )
444 {
445 m_referenceAttr->IncRef();
446 return m_referenceAttr;
447 }
448 else if( m_parentType == SCH_SHEET_T && aRow == SHEETFILENAME )
449 {
450 m_filepathAttr->IncRef();
451 return m_filepathAttr;
452 }
453 else if( ( m_parentType == SCH_LABEL_LOCATE_ANY_T )
454 && this->at( (size_t) aRow ).GetCanonicalName() == wxT( "Netclass" ) )
455 {
456 m_netclassAttr->IncRef();
457 return m_netclassAttr;
458 }
459 else
460 {
461 wxString fn = GetValue( aRow, FDC_NAME );
462
463 SCHEMATIC_SETTINGS* settings = m_frame->Prj().GetProjectFile().m_SchematicSettings;
464
465 const TEMPLATE_FIELDNAME* templateFn =
466 settings ? settings->m_TemplateFieldNames.GetFieldName( fn ) : nullptr;
467
468 if( templateFn && templateFn->m_URL )
469 {
470 m_urlAttr->IncRef();
471 return m_urlAttr;
472 }
473 else
474 {
475 m_nonUrlAttr->IncRef();
476 return m_nonUrlAttr;
477 }
478 }
479
480 case FDC_TEXT_SIZE:
481 case FDC_POSX:
482 case FDC_POSY:
483 return nullptr;
484
485 case FDC_H_ALIGN:
486 m_hAlignAttr->IncRef();
487 return m_hAlignAttr;
488
489 case FDC_V_ALIGN:
490 m_vAlignAttr->IncRef();
491 return m_vAlignAttr;
492
493 case FDC_ORIENTATION:
494 m_orientationAttr->IncRef();
495 return m_orientationAttr;
496
497 case FDC_SHOWN:
498 case FDC_ITALIC:
499 case FDC_BOLD:
500 m_boolAttr->IncRef();
501 return m_boolAttr;
502
503 case FDC_FONT:
504 m_fontAttr->IncRef();
505 return m_fontAttr;
506
507 case FDC_COLOR:
508 m_colorAttr->IncRef();
509 return m_colorAttr;
510
511 default:
512 wxFAIL;
513 return nullptr;
514 }
515}
516
517
518template <class T>
519wxString FIELDS_GRID_TABLE<T>::GetValue( int aRow, int aCol )
520{
521 wxCHECK( aRow < GetNumberRows(), wxEmptyString );
522 const T& field = this->at( (size_t) aRow );
523
524 switch( aCol )
525 {
526 case FDC_NAME:
527 // Use default field names for mandatory and system fields because they are translated
528 // according to the current locale
529 if( m_parentType == SCH_SYMBOL_T )
530 {
531 if( aRow < m_mandatoryFieldCount )
533 else
534 return field.GetName( false );
535 }
536 else if( m_parentType == SCH_SHEET_T )
537 {
538 if( aRow < m_mandatoryFieldCount )
539 return SCH_SHEET::GetDefaultFieldName( aRow );
540 else
541 return field.GetName( false );
542 }
543 else if( m_parentType == SCH_LABEL_LOCATE_ANY_T )
544 {
545 return SCH_LABEL_BASE::GetDefaultFieldName( field.GetCanonicalName(), false );
546 }
547 else
548 {
549 wxFAIL_MSG( "Unhandled field owner type." );
550 return field.GetName( false );
551 }
552
553 case FDC_VALUE:
554 return UnescapeString( field.GetText() );
555
556 case FDC_SHOWN:
557 return StringFromBool( field.IsVisible() );
558
559 case FDC_H_ALIGN:
560 switch ( field.GetHorizJustify() )
561 {
562 case GR_TEXT_H_ALIGN_LEFT: return _( "Left" );
563 case GR_TEXT_H_ALIGN_CENTER: return _( "Center" );
564 case GR_TEXT_H_ALIGN_RIGHT: return _( "Right" );
565 }
566
567 break;
568
569 case FDC_V_ALIGN:
570 switch ( field.GetVertJustify() )
571 {
572 case GR_TEXT_V_ALIGN_TOP: return _( "Top" );
573 case GR_TEXT_V_ALIGN_CENTER: return _( "Center" );
574 case GR_TEXT_V_ALIGN_BOTTOM: return _( "Bottom" );
575 }
576
577 break;
578
579 case FDC_ITALIC:
580 return StringFromBool( field.IsItalic() );
581
582 case FDC_BOLD:
583 return StringFromBool( field.IsBold() );
584
585 case FDC_TEXT_SIZE:
586 return m_frame->StringFromValue( field.GetTextHeight(), true );
587
588 case FDC_ORIENTATION:
589 if( field.GetTextAngle().IsHorizontal() )
590 return _( "Horizontal" );
591 else
592 return _( "Vertical" );
593
594 case FDC_POSX:
595 return m_frame->StringFromValue( field.GetTextPos().x, true );
596
597 case FDC_POSY:
598 return m_frame->StringFromValue( field.GetTextPos().y, true );
599
600 case FDC_FONT:
601 if( field.GetFont() )
602 return field.GetFont()->GetName();
603 else
604 return DEFAULT_FONT_NAME;
605
606 case FDC_COLOR:
607 return field.GetTextColor().ToCSSString();
608
609 default:
610 // we can't assert here because wxWidgets sometimes calls this without checking
611 // the column type when trying to see if there's an overflow
612 break;
613 }
614
615 return wxT( "bad wxWidgets!" );
616}
617
618
619template <class T>
620bool FIELDS_GRID_TABLE<T>::GetValueAsBool( int aRow, int aCol )
621{
622 wxCHECK( aRow < GetNumberRows(), false );
623 const T& field = this->at( (size_t) aRow );
624
625 switch( aCol )
626 {
627 case FDC_SHOWN: return field.IsVisible();
628 case FDC_ITALIC: return field.IsItalic();
629 case FDC_BOLD: return field.IsBold();
630 default:
631 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
632 return false;
633 }
634}
635
636
637template <class T>
638void FIELDS_GRID_TABLE<T>::SetValue( int aRow, int aCol, const wxString &aValue )
639{
640 wxCHECK( aRow < GetNumberRows(), /*void*/ );
641 T& field = this->at( (size_t) aRow );
642 VECTOR2I pos;
643
644 switch( aCol )
645 {
646 case FDC_NAME:
647 field.SetName( aValue );
648 break;
649
650 case FDC_VALUE:
651 {
652 wxString value( aValue );
653
654 if( m_parentType == SCH_SHEET_T && aRow == SHEETFILENAME )
655 {
656 wxFileName fn( value );
657
658 // It's annoying to throw up nag dialogs when the extension isn't right. Just
659 // fix it.
660 if( fn.GetExt().CmpNoCase( KiCadSchematicFileExtension ) != 0 )
661 {
662 fn.SetExt( KiCadSchematicFileExtension );
663 value = fn.GetFullPath();
664 }
665 }
666 else if( m_parentType == LIB_SYMBOL_T && aRow == VALUE_FIELD )
667 {
668 value = EscapeString( value, CTX_LIBID );
669 }
670
671 field.SetText( value );
672 break;
673 }
674
675 case FDC_SHOWN:
676 field.SetVisible( BoolFromString( aValue ) );
677 break;
678
679 case FDC_H_ALIGN:
680 if( aValue == _( "Left" ) )
681 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
682 else if( aValue == _( "Center" ) )
683 field.SetHorizJustify( GR_TEXT_H_ALIGN_CENTER );
684 else if( aValue == _( "Right" ) )
685 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
686 else
687 wxFAIL_MSG( wxT( "unknown horizontal alignment: " ) + aValue );
688
689 break;
690
691 case FDC_V_ALIGN:
692 if( aValue == _( "Top" ) )
693 field.SetVertJustify( GR_TEXT_V_ALIGN_TOP );
694 else if( aValue == _( "Center" ) )
695 field.SetVertJustify( GR_TEXT_V_ALIGN_CENTER );
696 else if( aValue == _( "Bottom" ) )
697 field.SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
698 else
699 wxFAIL_MSG( wxT( "unknown vertical alignment: " ) + aValue);
700
701 break;
702
703 case FDC_ITALIC:
704 field.SetItalic( BoolFromString( aValue ) );
705 break;
706
707 case FDC_BOLD:
708 field.SetBold( BoolFromString( aValue ) );
709 break;
710
711 case FDC_TEXT_SIZE:
712 field.SetTextSize(
713 wxSize( EDA_UNIT_UTILS::UI::ValueFromString( schIUScale, m_frame->GetUserUnits(), aValue ),
714 EDA_UNIT_UTILS::UI::ValueFromString( schIUScale, m_frame->GetUserUnits(), aValue ) ) );
715 break;
716
717 case FDC_ORIENTATION:
718 if( aValue == _( "Horizontal" ) )
719 field.SetTextAngle( ANGLE_HORIZONTAL );
720 else if( aValue == _( "Vertical" ) )
721 field.SetTextAngle( ANGLE_VERTICAL );
722 else
723 wxFAIL_MSG( wxT( "unknown orientation: " ) + aValue );
724
725 break;
726
727 case FDC_POSX:
728 case FDC_POSY:
729 pos = field.GetTextPos();
730
731 if( aCol == FDC_POSX )
732 pos.x = EDA_UNIT_UTILS::UI::ValueFromString( schIUScale, m_frame->GetUserUnits(), aValue );
733 else
734 pos.y = EDA_UNIT_UTILS::UI::ValueFromString( schIUScale, m_frame->GetUserUnits(),
735 aValue );
736
737 field.SetTextPos( pos );
738 break;
739
740 case FDC_FONT:
741 if( aValue == DEFAULT_FONT_NAME )
742 field.SetFont( nullptr );
743 else if( aValue == KICAD_FONT_NAME )
744 field.SetFont( KIFONT::FONT::GetFont( wxEmptyString, field.IsBold(), field.IsItalic() ) );
745 else
746 field.SetFont( KIFONT::FONT::GetFont( aValue, field.IsBold(), field.IsItalic() ) );
747
748 break;
749
750 case FDC_COLOR:
751 field.SetTextColor( wxColor( aValue ) );
752 break;
753
754 default:
755 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a string value" ), aCol ) );
756 break;
757 }
758
759 m_dialog->OnModify();
760
761 GetView()->Refresh();
762}
763
764
765template <class T>
766void FIELDS_GRID_TABLE<T>::SetValueAsBool( int aRow, int aCol, bool aValue )
767{
768 wxCHECK( aRow < GetNumberRows(), /*void*/ );
769 T& field = this->at( (size_t) aRow );
770
771 switch( aCol )
772 {
773 case FDC_SHOWN:
774 field.SetVisible( aValue );
775 break;
776
777 case FDC_ITALIC:
778 field.SetItalic( aValue );
779 break;
780
781 case FDC_BOLD:
782 field.SetBold( aValue );
783 break;
784
785 default:
786 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
787 break;
788 }
789
790 m_dialog->OnModify();
791}
792
793
794// Explicit Instantiations
795
796template class FIELDS_GRID_TABLE<SCH_FIELD>;
797template class FIELDS_GRID_TABLE<LIB_FIELD>;
798
799
801{
802 if( m_grid->GetGridCursorRow() == FOOTPRINT_FIELD && m_grid->GetGridCursorCol() == FDC_VALUE )
803 {
804 menu.Append( MYID_SELECT_FOOTPRINT, _( "Select Footprint..." ),
805 _( "Browse for footprint" ) );
806 menu.AppendSeparator();
807 }
808 else if( m_grid->GetGridCursorRow() == DATASHEET_FIELD && m_grid->GetGridCursorCol() == FDC_VALUE )
809 {
810 menu.Append( MYID_SHOW_DATASHEET, _( "Show Datasheet" ),
811 _( "Show datasheet in browser" ) );
812 menu.AppendSeparator();
813 }
814
816}
817
818
819void FIELDS_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
820{
821 if( event.GetId() == MYID_SELECT_FOOTPRINT )
822 {
823 // pick a footprint using the footprint picker.
824 wxString fpid = m_grid->GetCellValue( FOOTPRINT_FIELD, FDC_VALUE );
826
827 if( frame->ShowModal( &fpid, m_dlg ) )
828 m_grid->SetCellValue( FOOTPRINT_FIELD, FDC_VALUE, fpid );
829
830 frame->Destroy();
831 }
832 else if (event.GetId() == MYID_SHOW_DATASHEET )
833 {
834 wxString datasheet_uri = m_grid->GetCellValue( DATASHEET_FIELD, FDC_VALUE );
835 GetAssociatedDocument( m_dlg, datasheet_uri, &m_dlg->Prj(), m_dlg->Prj().SchSearchS() );
836 }
837 else
838 {
840 }
841}
842
843
844template <class T>
845wxString FIELDS_GRID_TABLE<T>::StringFromBool( bool aValue ) const
846{
847 if( aValue )
848 return wxT( "1" );
849 else
850 return wxT( "0" );
851}
852
853
854template <class T>
855bool FIELDS_GRID_TABLE<T>::BoolFromString( wxString aValue ) const
856{
857 if( aValue == "1" )
858 {
859 return true;
860 }
861 else if( aValue == "0" )
862 {
863 return false;
864 }
865 else
866 {
867 wxFAIL_MSG( wxString::Format( "string '%s' can't be converted to boolean correctly and "
868 "will be perceived as FALSE", aValue ) );
869 return false;
870 }
871}
const char * name
Definition: DXF_plotter.cpp:56
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition: dialog_shim.h:83
wxString GetValue(int aRow, int aCol) override
bool CanSetValueAs(int aRow, int aCol, const wxString &aTypeName) override
bool GetValueAsBool(int aRow, int aCol) override
void onUnitsChanged(wxCommandEvent &aEvent)
wxString GetColLabelValue(int aCol) override
void SetValue(int aRow, int aCol, const wxString &aValue) override
bool CanGetValueAs(int aRow, int aCol, const wxString &aTypeName) override
FIELDS_GRID_TABLE(DIALOG_SHIM *aDialog, SCH_BASE_FRAME *aFrame, WX_GRID *aGrid, LIB_SYMBOL *aSymbol)
wxGridCellAttr * GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind) override
wxString StringFromBool(bool aValue) const
void SetValueAsBool(int aRow, int aCol, bool aValue) override
bool BoolFromString(wxString aValue) const
void initGrid(WX_GRID *aGrid)
virtual void showPopupMenu(wxMenu &menu) override
virtual void doPopupSelection(wxCommandEvent &event) override
Editor for wxGrid cells that adds a file/folder browser to the grid input field.
This class works around a bug in wxGrid where the first keystroke doesn't get sent through the valida...
Definition: validators.h:45
virtual void SetValidator(const wxValidator &validator) override
Definition: validators.cpp:46
virtual void doPopupSelection(wxCommandEvent &event)
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:121
virtual void showPopupMenu(wxMenu &menu)
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
Definition: font.cpp:65
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:53
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:66
virtual bool ShowModal(wxString *aResult=nullptr, wxWindow *aResultantFocusWindow=nullptr)
Show this wxFrame as if it were a modal dialog, with all other instantiated wxFrames disabled until t...
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:394
Define a library symbol object.
Definition: lib_symbol.h:98
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:65
std::shared_ptr< NET_SETTINGS > & NetSettings()
Definition: project_file.h:96
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:148
These settings were stored in SCH_BASE_FRAME previously.
TEMPLATES m_TemplateFieldNames
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
Schematic editor (Eeschema) main window.
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
Definition: sch_label.cpp:183
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:55
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslated=true)
Definition: sch_sheet.cpp:55
Schematic symbol object.
Definition: sch_symbol.h:80
const wxString GetFootprint(const SCH_SHEET_PATH *sheet, bool aResolve) const
Return the instance-specific footprint assignment for the given sheet path.
Definition: sch_symbol.cpp:833
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:632
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve a list of the SCH_PINs for the given sheet path.
const wxString GetValue(const SCH_SHEET_PATH *sheet, bool aResolve) const
Return the instance-specific value for the given sheet path.
Definition: sch_symbol.cpp:767
const TEMPLATE_FIELDNAME * GetFieldName(const wxString &aName)
Search for aName in the template field name list.
#define _(s)
static constexpr EDA_ANGLE & ANGLE_HORIZONTAL
Definition: eda_angle.h:408
static constexpr EDA_ANGLE & ANGLE_VERTICAL
Definition: eda_angle.h:409
bool GetAssociatedDocument(wxWindow *aParent, const wxString &aDocName, PROJECT *aProject, SEARCH_STACK *aPaths)
Open a document (file) with the suitable browser.
Definition: eda_doc.cpp:74
This file is part of the common library.
#define DEFAULT_FONT_NAME
static wxString netList(SCH_SYMBOL *aSymbol, SCH_SHEET_PATH &aSheetPath)
@ MYID_SHOW_DATASHEET
@ MYID_SELECT_FOOTPRINT
@ FDC_TEXT_SIZE
@ FDC_BOLD
@ FDC_POSY
@ FDC_ITALIC
@ FDC_NAME
@ FDC_H_ALIGN
@ FDC_COLOR
@ FDC_SHOWN
@ FDC_VALUE
@ FDC_POSX
@ FDC_ORIENTATION
@ FDC_V_ALIGN
@ FDC_FONT
FONTCONFIG * Fontconfig()
Definition: fontconfig.cpp:52
@ FRAME_FOOTPRINT_VIEWER_MODAL
Definition: frame_type.h:43
@ FRAME_SCH_SYMBOL_EDITOR
Definition: frame_type.h:35
@ GRIDTRICKS_FIRST_CLIENT_ID
Definition: grid_tricks.h:48
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
const std::string KiCadSchematicFileExtension
#define KICAD_FONT_NAME
long long int ValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Function ValueFromString converts aTextValue in aUnits to internal units used by the application.
Definition: eda_units.cpp:530
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
@ SHEET_MANDATORY_FIELDS
The first 2 are mandatory, and must be instantiated in SCH_SHEET.
Definition: sch_sheet.h:47
@ SHEETNAME
Definition: sch_sheet.h:43
@ SHEETFILENAME
Definition: sch_sheet.h:44
Definitions of control validators for schematic dialogs.
#define SHEETFILENAME_V
#define FIELD_NAME
#define SHEETNAME_V
#define FIELD_VALUE
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_LINE
Definition: string_utils.h:59
@ CTX_LIBID
Definition: string_utils.h:55
@ CTX_CSV
Definition: string_utils.h:60
Hold a name of a symbol's field, field value, and default visibility.
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslateForHI=false)
Return a default symbol field name for field aFieldNdx for all components.
Definition for symbol library class.
#define DO_TRANSLATE
@ DATASHEET_FIELD
name of datasheet
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ MANDATORY_FIELDS
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
@ LIB_SYMBOL_T
Definition: typeinfo.h:197
@ SCH_SYMBOL_T
Definition: typeinfo.h:155
@ SCH_SHEET_T
Definition: typeinfo.h:157
@ SCH_LABEL_LOCATE_ANY_T
Definition: typeinfo.h:174
Custom text control validator definitions.
Definition of file extensions used in Kicad.