KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2024 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 <symbol_library.h>
35#include <schematic.h>
36#include <template_fieldnames.h>
41#include "eda_doc.h"
43#include "font/fontconfig.h"
46#include <wx/settings.h>
47#include <string_utils.h>
49#include <pgm_base.h>
50#include <project_sch.h>
51
52
53enum
54{
57};
58
59
60#define DEFAULT_FONT_NAME _( "Default Font" )
61
62
63static wxString netList( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH& aSheetPath )
64{
65 wxCHECK( aSymbol && aSymbol->GetLibSymbolRef(), wxEmptyString );
66
67 /*
68 * Symbol netlist format:
69 * pinNumber pinName <tab> pinNumber pinName...
70 * fpFilter fpFilter...
71 */
72 wxString netlist;
73
74 wxArrayString pins;
75
76 for( SCH_PIN* pin : aSymbol->GetPins( &aSheetPath ) )
77 pins.push_back( pin->GetNumber() + ' ' + pin->GetShownName() );
78
79 if( !pins.IsEmpty() )
80 netlist << EscapeString( wxJoin( pins, '\t' ), CTX_LINE );
81
82 netlist << wxS( "\r" );
83
84 wxArrayString fpFilters = aSymbol->GetLibSymbolRef()->GetFPFilters();
85
86 if( !fpFilters.IsEmpty() )
87 netlist << EscapeString( wxJoin( fpFilters, ' ' ), CTX_LINE );
89 netlist << wxS( "\r" );
90
91 return netlist;
92}
94
95static wxString netList( LIB_SYMBOL* aSymbol )
96{
97 /*
98 * Symbol netlist format:
99 * pinNumber pinName <tab> pinNumber pinName...
100 * fpFilter fpFilter...
101 */
102 wxString netlist;
103
104 std::vector<LIB_PIN*> pinList;
106 aSymbol->GetPins( pinList, 0, 1 ); // All units, but a single convert
108 wxArrayString pins;
109
110 for( LIB_PIN* pin : pinList )
111 pins.push_back( pin->GetNumber() + ' ' + pin->GetShownName() );
112
113 if( !pins.IsEmpty() )
114 netlist << EscapeString( wxJoin( pins, '\t' ), CTX_LINE );
115
116 netlist << wxS( "\r" );
117
118 wxArrayString fpFilters = aSymbol->GetFPFilters();
119
120 if( !fpFilters.IsEmpty() )
121 netlist << EscapeString( wxJoin( fpFilters, ' ' ), CTX_LINE );
122
123 netlist << wxS( "\r" );
124
125 return netlist;
126}
127
128
129template <class T>
131 WX_GRID* aGrid, LIB_SYMBOL* aSymbol ) :
132 m_frame( aFrame ),
133 m_dialog( aDialog ),
134 m_grid( aGrid ),
135 m_parentType( SCH_SYMBOL_T ),
136 m_mandatoryFieldCount( MANDATORY_FIELDS ),
137 m_part( aSymbol ),
138 m_symbolNetlist( netList( aSymbol ) ),
139 m_fieldNameValidator( FIELD_NAME ),
140 m_referenceValidator( REFERENCE_FIELD ),
141 m_valueValidator( VALUE_FIELD ),
142 m_urlValidator( FIELD_VALUE ),
143 m_nonUrlValidator( FIELD_VALUE ),
144 m_filepathValidator( SHEETFILENAME )
145{
146 initGrid( aGrid );
147}
148
149
150template <class T>
152 WX_GRID* aGrid, SCH_SYMBOL* aSymbol ) :
153 m_frame( aFrame ),
154 m_dialog( aDialog ),
155 m_grid( aGrid ),
156 m_parentType( SCH_SYMBOL_T ),
157 m_mandatoryFieldCount( MANDATORY_FIELDS ),
158 m_part( aSymbol->GetLibSymbolRef().get() ),
159 m_symbolNetlist( netList( aSymbol, aFrame->GetCurrentSheet() ) ),
160 m_fieldNameValidator( FIELD_NAME ),
161 m_referenceValidator( REFERENCE_FIELD ),
162 m_valueValidator( VALUE_FIELD ),
163 m_urlValidator( FIELD_VALUE ),
164 m_nonUrlValidator( FIELD_VALUE ),
165 m_filepathValidator( SHEETFILENAME )
166{
167 initGrid( aGrid );
168}
169
170
171template <class T>
173 WX_GRID* aGrid, SCH_SHEET* aSheet ) :
174 m_frame( aFrame ),
175 m_dialog( aDialog ),
176 m_grid( aGrid ),
177 m_parentType( SCH_SHEET_T ),
178 m_mandatoryFieldCount( SHEET_MANDATORY_FIELDS ),
179 m_part( nullptr ),
180 m_fieldNameValidator( FIELD_NAME ),
181 m_referenceValidator( SHEETNAME_V ),
182 m_valueValidator( VALUE_FIELD ),
183 m_urlValidator( FIELD_VALUE ),
184 m_nonUrlValidator( FIELD_VALUE ),
185 m_filepathValidator( SHEETFILENAME_V )
186{
187 initGrid( aGrid );
188}
189
190
191template <class T>
193 WX_GRID* aGrid, SCH_LABEL_BASE* aLabel ) :
194 m_frame( aFrame ),
195 m_dialog( aDialog ),
196 m_grid( aGrid ),
197 m_parentType( SCH_LABEL_LOCATE_ANY_T ),
198 m_mandatoryFieldCount( aLabel->GetMandatoryFieldCount() ),
199 m_part( nullptr ),
200 m_fieldNameValidator( FIELD_NAME ),
201 m_referenceValidator( 0 ),
202 m_valueValidator( 0 ),
203 m_urlValidator( FIELD_VALUE ),
204 m_nonUrlValidator( FIELD_VALUE ),
205 m_filepathValidator( 0 )
206{
207 initGrid( aGrid );
208}
209
210
211template <class T>
213{
214 // Build the various grid cell attributes.
215 // NOTE: validators and cellAttrs are member variables to get the destruction order
216 // right. wxGrid is VERY cranky about this.
217
218 m_readOnlyAttr = new wxGridCellAttr;
219 m_readOnlyAttr->SetReadOnly( true );
220
221 m_fieldNameAttr = new wxGridCellAttr;
223 nameEditor->SetValidator( m_fieldNameValidator );
224 m_fieldNameAttr->SetEditor( nameEditor );
225
226 m_referenceAttr = new wxGridCellAttr;
227 GRID_CELL_TEXT_EDITOR* referenceEditor = new GRID_CELL_TEXT_EDITOR();
228 referenceEditor->SetValidator( m_referenceValidator );
229 m_referenceAttr->SetEditor( referenceEditor );
230
231 m_valueAttr = new wxGridCellAttr;
232
233 if constexpr ( std::is_same_v<T, SCH_FIELD> )
234 {
235 GRID_CELL_STC_EDITOR* valueEditor = new GRID_CELL_STC_EDITOR( true,
236 [this]( wxStyledTextEvent& aEvent, SCINTILLA_TRICKS* aScintillaTricks )
237 {
238 SCH_FIELD& valueField = static_cast<SCH_FIELD&>( this->at( VALUE_FIELD ) );
239 valueField.OnScintillaCharAdded( aScintillaTricks, aEvent );
240 } );
241 m_valueAttr->SetEditor( valueEditor );
242 }
243 else
244 {
245 GRID_CELL_TEXT_EDITOR* valueEditor = new GRID_CELL_TEXT_EDITOR();
246 valueEditor->SetValidator( m_valueValidator );
247 m_valueAttr->SetEditor( valueEditor );
248 }
249
250 m_footprintAttr = new wxGridCellAttr;
251 GRID_CELL_FPID_EDITOR* fpIdEditor = new GRID_CELL_FPID_EDITOR( m_dialog, m_symbolNetlist );
252 fpIdEditor->SetValidator( m_nonUrlValidator );
253 m_footprintAttr->SetEditor( fpIdEditor );
254
255 m_urlAttr = new wxGridCellAttr;
256 GRID_CELL_URL_EDITOR* urlEditor = new GRID_CELL_URL_EDITOR( m_dialog, PROJECT_SCH::SchSearchS( &m_frame->Prj() ) );
257 urlEditor->SetValidator( m_urlValidator );
258 m_urlAttr->SetEditor( urlEditor );
259
260 m_nonUrlAttr = new wxGridCellAttr;
261 GRID_CELL_TEXT_EDITOR* nonUrlEditor = new GRID_CELL_TEXT_EDITOR();
262 nonUrlEditor->SetValidator( m_nonUrlValidator );
263 m_nonUrlAttr->SetEditor( nonUrlEditor );
264
265 m_curdir = m_frame->Prj().GetProjectPath();
266 m_filepathAttr = new wxGridCellAttr;
267
268 // Create a wild card using wxFileDialog syntax.
269 wxString wildCard( _( "Schematic Files" ) );
270 std::vector<std::string> exts;
271 exts.push_back( FILEEXT::KiCadSchematicFileExtension );
272 wildCard += AddFileExtListToFilter( exts );
273
274 auto filepathEditor = new GRID_CELL_PATH_EDITOR( m_dialog, aGrid, &m_curdir, wildCard );
275 filepathEditor->SetValidator( m_filepathValidator );
276 m_filepathAttr->SetEditor( filepathEditor );
277
278 m_boolAttr = new wxGridCellAttr;
279 m_boolAttr->SetRenderer( new wxGridCellBoolRenderer() );
280 m_boolAttr->SetEditor( new wxGridCellBoolEditor() );
281 m_boolAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
282
283 wxArrayString vAlignNames;
284 vAlignNames.Add( _( "Top" ) );
285 vAlignNames.Add( _( "Center" ) );
286 vAlignNames.Add( _( "Bottom" ) );
287 m_vAlignAttr = new wxGridCellAttr;
288 m_vAlignAttr->SetEditor( new wxGridCellChoiceEditor( vAlignNames ) );
289 m_vAlignAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
290
291 wxArrayString hAlignNames;
292 hAlignNames.Add( _( "Left" ) );
293 hAlignNames.Add(_( "Center" ) );
294 hAlignNames.Add(_( "Right" ) );
295 m_hAlignAttr = new wxGridCellAttr;
296 m_hAlignAttr->SetEditor( new wxGridCellChoiceEditor( hAlignNames ) );
297 m_hAlignAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
298
299 wxArrayString orientationNames;
300 orientationNames.Add( _( "Horizontal" ) );
301 orientationNames.Add(_( "Vertical" ) );
302 m_orientationAttr = new wxGridCellAttr;
303 m_orientationAttr->SetEditor( new wxGridCellChoiceEditor( orientationNames ) );
304 m_orientationAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
305
306 SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
307 wxArrayString existingNetclasses;
308
309 if( editFrame )
310 {
311 // Load the combobox with existing existingNetclassNames
312 PROJECT_FILE& projectFile = editFrame->Prj().GetProjectFile();
313 const std::shared_ptr<NET_SETTINGS>& settings = projectFile.NetSettings();
314
315 existingNetclasses.push_back( settings->m_DefaultNetClass->GetName() );
316
317 for( const auto& [ name, netclass ] : settings->m_NetClasses )
318 existingNetclasses.push_back( name );
319 }
320
321 m_netclassAttr = new wxGridCellAttr;
322 m_netclassAttr->SetEditor( new GRID_CELL_COMBOBOX( existingNetclasses ) );
323
324 wxArrayString fonts;
325 std::vector<std::string> fontNames;
326 Fontconfig()->ListFonts( fontNames, std::string( Pgm().GetLanguageTag().utf8_str() ) );
327
328 for( const std::string& name : fontNames )
329 fonts.Add( wxString( name ) );
330
331 fonts.Sort();
332 fonts.Insert( KICAD_FONT_NAME, 0 );
333 fonts.Insert( DEFAULT_FONT_NAME, 0 );
334
335 m_fontAttr = new wxGridCellAttr;
336 m_fontAttr->SetEditor( new GRID_CELL_COMBOBOX( fonts ) );
337
338 m_colorAttr = new wxGridCellAttr;
339 m_colorAttr->SetRenderer( new GRID_CELL_COLOR_RENDERER( m_dialog ) );
340 m_colorAttr->SetEditor( new GRID_CELL_COLOR_SELECTOR( m_dialog, aGrid ) );
341
342 m_eval = std::make_unique<NUMERIC_EVALUATOR>( m_frame->GetUserUnits() );
343
344 m_frame->Bind( EDA_EVT_UNITS_CHANGED, &FIELDS_GRID_TABLE<T>::onUnitsChanged, this );
345}
346
347
348template <class T>
350{
351 m_readOnlyAttr->DecRef();
352 m_fieldNameAttr->DecRef();
353 m_boolAttr->DecRef();
354 m_referenceAttr->DecRef();
355 m_valueAttr->DecRef();
356 m_footprintAttr->DecRef();
357 m_urlAttr->DecRef();
358 m_nonUrlAttr->DecRef();
359 m_filepathAttr->DecRef();
360 m_vAlignAttr->DecRef();
361 m_hAlignAttr->DecRef();
362 m_orientationAttr->DecRef();
363 m_netclassAttr->DecRef();
364 m_fontAttr->DecRef();
365 m_colorAttr->DecRef();
366
367 m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &FIELDS_GRID_TABLE<T>::onUnitsChanged, this );
368}
369
370
371template <class T>
372void FIELDS_GRID_TABLE<T>::onUnitsChanged( wxCommandEvent& aEvent )
373{
374 if( GetView() )
375 GetView()->ForceRefresh();
376
377 aEvent.Skip();
378}
379
380
381template <class T>
383{
384 switch( aCol )
385 {
386 case FDC_NAME: return _( "Name" );
387 case FDC_VALUE: return _( "Value" );
388 case FDC_SHOWN: return _( "Show" );
389 case FDC_SHOW_NAME: return _( "Show Name" );
390 case FDC_H_ALIGN: return _( "H Align" );
391 case FDC_V_ALIGN: return _( "V Align" );
392 case FDC_ITALIC: return _( "Italic" );
393 case FDC_BOLD: return _( "Bold" );
394 case FDC_TEXT_SIZE: return _( "Text Size" );
395 case FDC_ORIENTATION: return _( "Orientation" );
396 case FDC_POSX: return _( "X Position" );
397 case FDC_POSY: return _( "Y Position" );
398 case FDC_FONT: return _( "Font" );
399 case FDC_COLOR: return _( "Color" );
400 case FDC_ALLOW_AUTOPLACE: return _( "Allow Autoplacement" );
401 default: wxFAIL; return wxEmptyString;
402 }
403}
404
405
406template <class T>
407bool FIELDS_GRID_TABLE<T>::CanGetValueAs( int aRow, int aCol, const wxString& aTypeName )
408{
409 switch( aCol )
410 {
411 case FDC_NAME:
412 case FDC_VALUE:
413 case FDC_H_ALIGN:
414 case FDC_V_ALIGN:
415 case FDC_TEXT_SIZE:
416 case FDC_ORIENTATION:
417 case FDC_POSX:
418 case FDC_POSY:
419 case FDC_FONT:
420 case FDC_COLOR:
421 return aTypeName == wxGRID_VALUE_STRING;
422
423 case FDC_SHOWN:
424 case FDC_SHOW_NAME:
425 case FDC_ITALIC:
426 case FDC_BOLD:
428 return aTypeName == wxGRID_VALUE_BOOL;
429
430 default:
431 wxFAIL;
432 return false;
433 }
434}
435
436
437template <class T>
438bool FIELDS_GRID_TABLE<T>::CanSetValueAs( int aRow, int aCol, const wxString& aTypeName )
439{
440 return CanGetValueAs( aRow, aCol, aTypeName );
441}
442
443
444template <class T>
445wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind )
446{
447 wxGridCellAttr* tmp;
448
449 switch( aCol )
450 {
451 case FDC_NAME:
452 if( aRow < m_mandatoryFieldCount )
453 {
454 tmp = m_fieldNameAttr->Clone();
455 tmp->SetReadOnly( true );
456 return tmp;
457 }
458 else
459 {
460 m_fieldNameAttr->IncRef();
461 return m_fieldNameAttr;
462 }
463
464 case FDC_VALUE:
465 if( m_parentType == SCH_SYMBOL_T && aRow == REFERENCE_FIELD )
466 {
467 m_referenceAttr->IncRef();
468 return m_referenceAttr;
469 }
470 else if( m_parentType == SCH_SYMBOL_T && aRow == VALUE_FIELD )
471 {
472 m_valueAttr->IncRef();
473 return m_valueAttr;
474 }
475 else if( m_parentType == SCH_SYMBOL_T && aRow == FOOTPRINT_FIELD )
476 {
477 // Power symbols have do not appear in the board, so don't allow
478 // a footprint (m_part can be nullptr when loading a old schematic
479 // (for instance Kicad 4) with libraries missing)
480 if( m_part && m_part->IsPower() )
481 {
482 m_readOnlyAttr->IncRef();
483 return m_readOnlyAttr;
484 }
485 else
486 {
487 m_footprintAttr->IncRef();
488 return m_footprintAttr;
489 }
490 }
491 else if( m_parentType == SCH_SYMBOL_T && aRow == DATASHEET_FIELD )
492 {
493 m_urlAttr->IncRef();
494 return m_urlAttr;
495 }
496 else if( m_parentType == SCH_SHEET_T && aRow == SHEETNAME )
497 {
498 m_referenceAttr->IncRef();
499 return m_referenceAttr;
500 }
501 else if( m_parentType == SCH_SHEET_T && aRow == SHEETFILENAME )
502 {
503 m_filepathAttr->IncRef();
504 return m_filepathAttr;
505 }
506 else if( ( m_parentType == SCH_LABEL_LOCATE_ANY_T )
507 && this->at( (size_t) aRow ).GetCanonicalName() == wxT( "Netclass" ) )
508 {
509 m_netclassAttr->IncRef();
510 return m_netclassAttr;
511 }
512 else
513 {
514 wxString fn = GetValue( aRow, FDC_NAME );
515
516 SCHEMATIC_SETTINGS* settings = m_frame->Prj().GetProjectFile().m_SchematicSettings;
517
518 const TEMPLATE_FIELDNAME* templateFn =
519 settings ? settings->m_TemplateFieldNames.GetFieldName( fn ) : nullptr;
520
521 if( templateFn && templateFn->m_URL )
522 {
523 m_urlAttr->IncRef();
524 return m_urlAttr;
525 }
526 else
527 {
528 m_nonUrlAttr->IncRef();
529 return m_nonUrlAttr;
530 }
531 }
532
533 case FDC_TEXT_SIZE:
534 case FDC_POSX:
535 case FDC_POSY:
536 return nullptr;
537
538 case FDC_H_ALIGN:
539 m_hAlignAttr->IncRef();
540 return m_hAlignAttr;
541
542 case FDC_V_ALIGN:
543 m_vAlignAttr->IncRef();
544 return m_vAlignAttr;
545
546 case FDC_ORIENTATION:
547 m_orientationAttr->IncRef();
548 return m_orientationAttr;
549
550 case FDC_SHOWN:
551 case FDC_SHOW_NAME:
552 case FDC_ITALIC:
553 case FDC_BOLD:
555 m_boolAttr->IncRef();
556 return m_boolAttr;
557
558 case FDC_FONT:
559 m_fontAttr->IncRef();
560 return m_fontAttr;
561
562 case FDC_COLOR:
563 m_colorAttr->IncRef();
564 return m_colorAttr;
565
566 default:
567 wxFAIL;
568 return nullptr;
569 }
570}
571
572
573template <class T>
574wxString FIELDS_GRID_TABLE<T>::GetValue( int aRow, int aCol )
575{
576 wxCHECK( aRow < GetNumberRows(), wxEmptyString );
577
578 wxGrid* grid = GetView();
579 const T& field = this->at( (size_t) aRow );
580
581 if( grid->GetGridCursorRow() == aRow && grid->GetGridCursorCol() == aCol
582 && grid->IsCellEditControlShown() )
583 {
584 auto it = m_evalOriginal.find( { aRow, aCol } );
585
586 if( it != m_evalOriginal.end() )
587 return it->second;
588 }
589
590 switch( aCol )
591 {
592 case FDC_NAME:
593 // Use default field names for mandatory and system fields because they are translated
594 // according to the current locale
595 if( m_parentType == SCH_SYMBOL_T )
596 {
597 if( aRow < m_mandatoryFieldCount )
599 else
600 return field.GetName( false );
601 }
602 else if( m_parentType == SCH_SHEET_T )
603 {
604 if( aRow < m_mandatoryFieldCount )
605 return SCH_SHEET::GetDefaultFieldName( aRow );
606 else
607 return field.GetName( false );
608 }
609 else if( m_parentType == SCH_LABEL_LOCATE_ANY_T )
610 {
611 return SCH_LABEL_BASE::GetDefaultFieldName( field.GetCanonicalName(), false );
612 }
613 else
614 {
615 wxFAIL_MSG( wxS( "Unhandled field owner type." ) );
616 return field.GetName( false );
617 }
618
619 case FDC_VALUE:
620 return EscapeString( UnescapeString( field.GetText() ), CTX_LINE );
621
622 case FDC_SHOWN:
623 return StringFromBool( field.IsVisible() );
624
625 case FDC_SHOW_NAME:
626 return StringFromBool( field.IsNameShown() );
627
628 case FDC_H_ALIGN:
629 switch ( field.GetEffectiveHorizJustify() )
630 {
631 case GR_TEXT_H_ALIGN_LEFT: return _( "Left" );
632 case GR_TEXT_H_ALIGN_CENTER: return _( "Center" );
633 case GR_TEXT_H_ALIGN_RIGHT: return _( "Right" );
635 }
636
637 break;
638
639 case FDC_V_ALIGN:
640 switch ( field.GetEffectiveVertJustify() )
641 {
642 case GR_TEXT_V_ALIGN_TOP: return _( "Top" );
643 case GR_TEXT_V_ALIGN_CENTER: return _( "Center" );
644 case GR_TEXT_V_ALIGN_BOTTOM: return _( "Bottom" );
646 }
647
648 break;
649
650 case FDC_ITALIC:
651 return StringFromBool( field.IsItalic() );
652
653 case FDC_BOLD:
654 return StringFromBool( field.IsBold() );
655
656 case FDC_TEXT_SIZE:
657 return m_frame->StringFromValue( field.GetTextHeight(), true );
658
659 case FDC_ORIENTATION:
660 if( field.GetTextAngle().IsHorizontal() )
661 return _( "Horizontal" );
662 else
663 return _( "Vertical" );
664
665 case FDC_POSX:
666 return m_frame->StringFromValue( field.GetTextPos().x, true );
667
668 case FDC_POSY:
669 return m_frame->StringFromValue( field.GetTextPos().y, true );
670
671 case FDC_FONT:
672 if( field.GetFont() )
673 return field.GetFont()->GetName();
674 else
675 return DEFAULT_FONT_NAME;
676
677 case FDC_COLOR:
678 return field.GetTextColor().ToCSSString();
679
681 return StringFromBool( field.CanAutoplace() );
682
683 default:
684 // we can't assert here because wxWidgets sometimes calls this without checking
685 // the column type when trying to see if there's an overflow
686 break;
687 }
688
689 return wxT( "bad wxWidgets!" );
690}
691
692
693template <class T>
694bool FIELDS_GRID_TABLE<T>::GetValueAsBool( int aRow, int aCol )
695{
696 wxCHECK( aRow < GetNumberRows(), false );
697 const T& field = this->at( (size_t) aRow );
698
699 switch( aCol )
700 {
701 case FDC_SHOWN: return field.IsVisible();
702 case FDC_SHOW_NAME: return field.IsNameShown();
703 case FDC_ITALIC: return field.IsItalic();
704 case FDC_BOLD: return field.IsBold();
705 case FDC_ALLOW_AUTOPLACE: return field.CanAutoplace();
706 default:
707 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
708 return false;
709 }
710}
711
712
713template <class T>
714void FIELDS_GRID_TABLE<T>::SetValue( int aRow, int aCol, const wxString &aValue )
715{
716 wxCHECK( aRow < GetNumberRows(), /*void*/ );
717 T& field = this->at( (size_t) aRow );
718 VECTOR2I pos;
719 wxString value = aValue;
720
721 switch( aCol )
722 {
723 case FDC_TEXT_SIZE:
724 case FDC_POSX:
725 case FDC_POSY:
726 m_eval->SetDefaultUnits( m_frame->GetUserUnits() );
727
728 if( m_eval->Process( value ) )
729 {
730 m_evalOriginal[ { aRow, aCol } ] = value;
731 value = m_eval->Result();
732 }
733
734 break;
735
736 default:
737 break;
738 }
739
740 switch( aCol )
741 {
742 case FDC_NAME:
743 field.SetName( value );
744 break;
745
746 case FDC_VALUE:
747 {
748 if( m_parentType == SCH_SHEET_T && aRow == SHEETFILENAME )
749 {
751 }
752 else if( m_parentType == LIB_SYMBOL_T && aRow == VALUE_FIELD )
753 {
754 value = EscapeString( value, CTX_LIBID );
755 }
756
757 field.SetText( UnescapeString( value ) );
758 break;
759 }
760
761 case FDC_SHOWN:
762 field.SetVisible( BoolFromString( value ) );
763 break;
764
765 case FDC_SHOW_NAME:
766 field.SetNameShown( BoolFromString( value ) );
767 break;
768
769 case FDC_H_ALIGN:
770 {
771 GR_TEXT_H_ALIGN_T horizontalJustification = GR_TEXT_H_ALIGN_CENTER;
772
773 if( value == _( "Left" ) )
774 horizontalJustification = GR_TEXT_H_ALIGN_LEFT;
775 else if( value == _( "Center" ) )
776 horizontalJustification = GR_TEXT_H_ALIGN_CENTER;
777 else if( value == _( "Right" ) )
778 horizontalJustification = GR_TEXT_H_ALIGN_RIGHT;
779 else
780 wxFAIL_MSG( wxT( "unknown horizontal alignment: " ) + value );
781
782 // Note that we must set justifications before we can ask if they're flipped. If the old
783 // justification is center then it won't know (whereas if the new justification is center
784 // the we don't care).
785 field.SetHorizJustify( horizontalJustification );
786
787 if( field.IsHorizJustifyFlipped() )
788 field.SetHorizJustify( EDA_TEXT::MapHorizJustify( - horizontalJustification ) );
789
790 break;
791 }
792
793 case FDC_V_ALIGN:
794 {
795 GR_TEXT_V_ALIGN_T verticalJustification = GR_TEXT_V_ALIGN_BOTTOM;
796
797 if( value == _( "Top" ) )
798 verticalJustification = GR_TEXT_V_ALIGN_TOP;
799 else if( value == _( "Center" ) )
800 verticalJustification = GR_TEXT_V_ALIGN_CENTER;
801 else if( value == _( "Bottom" ) )
802 verticalJustification = GR_TEXT_V_ALIGN_BOTTOM;
803 else
804 wxFAIL_MSG( wxT( "unknown vertical alignment: " ) + value);
805
806 // Note that we must set justifications before we can ask if they're flipped. If the old
807 // justification is center then it won't know (whereas if the new justification is center
808 // the we don't care).
809 field.SetVertJustify( verticalJustification );
810
811 if( field.IsVertJustifyFlipped() )
812 field.SetVertJustify( EDA_TEXT::MapVertJustify( -verticalJustification ) );
813
814 break;
815 }
816
817 case FDC_ITALIC:
818 field.SetItalic( BoolFromString( value ) );
819 break;
820
821 case FDC_BOLD:
822 field.SetBold( BoolFromString( value ) );
823 break;
824
825 case FDC_TEXT_SIZE:
826 field.SetTextSize( VECTOR2I( m_frame->ValueFromString( value ),
827 m_frame->ValueFromString( value ) ) );
828 break;
829
830 case FDC_ORIENTATION:
831 if( value == _( "Horizontal" ) )
832 field.SetTextAngle( ANGLE_HORIZONTAL );
833 else if( value == _( "Vertical" ) )
834 field.SetTextAngle( ANGLE_VERTICAL );
835 else
836 wxFAIL_MSG( wxT( "unknown orientation: " ) + value );
837
838 break;
839
840 case FDC_POSX:
841 case FDC_POSY:
842 pos = field.GetTextPos();
843
844 if( aCol == FDC_POSX )
845 pos.x = m_frame->ValueFromString( value );
846 else
847 pos.y = m_frame->ValueFromString( value );
848
849 field.SetTextPos( pos );
850 break;
851
852 case FDC_FONT:
853 if( value == DEFAULT_FONT_NAME )
854 field.SetFont( nullptr );
855 else if( value == KICAD_FONT_NAME )
856 field.SetFont( KIFONT::FONT::GetFont( wxEmptyString, field.IsBold(),
857 field.IsItalic() ) );
858 else
859 field.SetFont( KIFONT::FONT::GetFont( aValue, field.IsBold(), field.IsItalic() ) );
860
861 break;
862
863 case FDC_COLOR:
864 field.SetTextColor( wxColor( value ) );
865 break;
866
868 field.SetCanAutoplace( BoolFromString( value ) );
869 break;
870
871 default:
872 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a string value" ), aCol ) );
873 break;
874 }
875
876 m_dialog->OnModify();
877
878 GetView()->Refresh();
879}
880
881
882template <class T>
883void FIELDS_GRID_TABLE<T>::SetValueAsBool( int aRow, int aCol, bool aValue )
884{
885 wxCHECK( aRow < GetNumberRows(), /*void*/ );
886 T& field = this->at( (size_t) aRow );
887
888 switch( aCol )
889 {
890 case FDC_SHOWN:
891 field.SetVisible( aValue );
892 break;
893
894 case FDC_SHOW_NAME:
895 field.SetNameShown( aValue );
896 break;
897
898 case FDC_ITALIC:
899 field.SetItalic( aValue );
900 break;
901
902 case FDC_BOLD:
903 field.SetBold( aValue );
904 break;
905
907 field.SetCanAutoplace( aValue );
908 break;
909
910 default:
911 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
912 break;
913 }
914
915 m_dialog->OnModify();
916}
917
918
919// Explicit Instantiations
920
921template class FIELDS_GRID_TABLE<SCH_FIELD>;
922template class FIELDS_GRID_TABLE<LIB_FIELD>;
923
924
925void FIELDS_GRID_TRICKS::showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
926{
927 if( m_grid->GetGridCursorRow() == FOOTPRINT_FIELD && m_grid->GetGridCursorCol() == FDC_VALUE
928 && !m_grid->IsReadOnly( FOOTPRINT_FIELD, FDC_VALUE ) )
929 {
930 menu.Append( MYID_SELECT_FOOTPRINT, _( "Select Footprint..." ),
931 _( "Browse for footprint" ) );
932 menu.AppendSeparator();
933 }
934 else if( m_grid->GetGridCursorRow() == DATASHEET_FIELD
935 && m_grid->GetGridCursorCol() == FDC_VALUE )
936 {
937 menu.Append( MYID_SHOW_DATASHEET, _( "Show Datasheet" ),
938 _( "Show datasheet in browser" ) );
939 menu.AppendSeparator();
940 }
941
942 GRID_TRICKS::showPopupMenu( menu, aEvent );
943}
944
945
946void FIELDS_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
947{
948 if( event.GetId() == MYID_SELECT_FOOTPRINT )
949 {
950 // pick a footprint using the footprint picker.
951 wxString fpid = m_grid->GetCellValue( FOOTPRINT_FIELD, FDC_VALUE );
953
954 if( frame->ShowModal( &fpid, m_dlg ) )
955 m_grid->SetCellValue( FOOTPRINT_FIELD, FDC_VALUE, fpid );
956
957 frame->Destroy();
958 }
959 else if (event.GetId() == MYID_SHOW_DATASHEET )
960 {
961 wxString datasheet_uri = m_grid->GetCellValue( DATASHEET_FIELD, FDC_VALUE );
962 GetAssociatedDocument( m_dlg, datasheet_uri, &m_dlg->Prj(),
964 }
965 else
966 {
968 }
969}
970
971
972template <class T>
973wxString FIELDS_GRID_TABLE<T>::StringFromBool( bool aValue ) const
974{
975 if( aValue )
976 return wxT( "1" );
977 else
978 return wxT( "0" );
979}
980
981
982template <class T>
983bool FIELDS_GRID_TABLE<T>::BoolFromString( wxString aValue ) const
984{
985 if( aValue == wxS( "1" ) )
986 {
987 return true;
988 }
989 else if( aValue == wxS( "0" ) )
990 {
991 return false;
992 }
993 else
994 {
995 wxFAIL_MSG( wxString::Format( "string '%s' can't be converted to boolean correctly and "
996 "will be perceived as FALSE", aValue ) );
997 return false;
998 }
999}
const char * name
Definition: DXF_plotter.cpp:57
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition: dialog_shim.h:83
static GR_TEXT_H_ALIGN_T MapHorizJustify(int aHorizJustify)
Definition: eda_text.cpp:63
static GR_TEXT_V_ALIGN_T MapVertJustify(int aVertJustify)
Definition: eda_text.cpp:77
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, wxGridEvent &aEvent) 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:58
virtual void SetValidator(const wxValidator &validator) override
Definition: validators.cpp:47
virtual void doPopupSelection(wxCommandEvent &event)
virtual void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent)
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:125
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
Definition: font.cpp:146
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:67
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:432
Define a library symbol object.
Definition: lib_symbol.h:99
void GetPins(LIB_PINS &aList, int aUnit=0, int aBodyStyle=0) const
Return a list of pin object pointers from the draw item list.
wxArrayString GetFPFilters() const
Definition: lib_symbol.h:226
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:70
std::shared_ptr< NET_SETTINGS > & NetSettings()
Definition: project_file.h:101
static SEARCH_STACK * SchSearchS(PROJECT *aProject)
Accessor for Eeschema search stack.
Definition: project_sch.cpp:41
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:166
These settings were stored in SCH_BASE_FRAME previously.
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
Schematic editor (Eeschema) main window.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:52
void OnScintillaCharAdded(SCINTILLA_TRICKS *aScintillaTricks, wxStyledTextEvent &aEvent) const
Definition: sch_field.cpp:670
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
Definition: sch_label.cpp:246
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:57
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslated=true)
Definition: sch_sheet.cpp:55
Schematic symbol object.
Definition: sch_symbol.h:109
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve a list of the SCH_PINs for the given sheet path.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:222
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
const TEMPLATE_FIELDNAME * GetFieldName(const wxString &aName)
Search for aName in the template field name list.
wxString EnsureFileExtension(const wxString &aFilename, const wxString &aExtension)
It's annoying to throw up nag dialogs when the extension isn't right.
Definition: common.cpp:415
#define _(s)
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition: eda_angle.h:432
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition: eda_angle.h:431
bool GetAssociatedDocument(wxWindow *aParent, const wxString &aDocName, PROJECT *aProject, SEARCH_STACK *aPaths)
Open a document (file) with the suitable browser.
Definition: eda_doc.cpp:60
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_SHOW_NAME
@ FDC_NAME
@ FDC_H_ALIGN
@ FDC_COLOR
@ FDC_SHOWN
@ FDC_ALLOW_AUTOPLACE
@ FDC_VALUE
@ FDC_POSX
@ FDC_ORIENTATION
@ FDC_V_ALIGN
@ FDC_FONT
FONTCONFIG * Fontconfig()
Definition: fontconfig.cpp:90
@ FRAME_FOOTPRINT_CHOOSER
Definition: frame_type.h:44
@ GRIDTRICKS_FIRST_CLIENT_ID
Definition: grid_tricks.h:48
static const std::string KiCadSchematicFileExtension
#define KICAD_FONT_NAME
see class PGM_BASE
@ SHEET_MANDATORY_FIELDS
The first 2 are mandatory, and must be instantiated in SCH_SHEET.
Definition: sch_sheet.h:49
@ SHEETNAME
Definition: sch_sheet.h:45
@ SHEETFILENAME
Definition: sch_sheet.h:46
Definitions of control validators for schematic dialogs.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:119
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:54
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 5 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_T
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_H_ALIGN_INDETERMINATE
GR_TEXT_V_ALIGN_T
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_INDETERMINATE
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
@ LIB_SYMBOL_T
Definition: typeinfo.h:202
@ SCH_SYMBOL_T
Definition: typeinfo.h:160
@ SCH_SHEET_T
Definition: typeinfo.h:162
@ SCH_LABEL_LOCATE_ANY_T
Definition: typeinfo.h:179
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
Definition: ui_common.h:44
Custom text control validator definitions.
#define SHEETFILENAME_V
Definition: validators.h:47
#define FIELD_NAME
Definition: validators.h:43
#define SHEETNAME_V
Definition: validators.h:46
#define FIELD_VALUE
Definition: validators.h:44
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
Definition of file extensions used in Kicad.