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-2023 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 /*
66 * Symbol netlist format:
67 * pinCount
68 * fpFilters
69 */
70 wxString netlist;
71
72 netlist << wxString::Format( wxS( "%zu\r" ), aSymbol->GetFullPinCount() );
73
74 wxArrayString fpFilters = aSymbol->GetLibSymbolRef()->GetFPFilters();
75
76 if( !fpFilters.IsEmpty() )
77 netlist << EscapeString( wxJoin( fpFilters, ' ' ), CTX_LINE );
78
79 netlist << wxS( "\r" );
81 return netlist;
83
85template <class T>
87 WX_GRID* aGrid, LIB_SYMBOL* aSymbol ) :
88 m_frame( aFrame ),
89 m_dialog( aDialog ),
90 m_grid( aGrid ),
91 m_parentType( SCH_SYMBOL_T ),
92 m_mandatoryFieldCount( MANDATORY_FIELDS ),
93 m_part( aSymbol ),
94 m_fieldNameValidator( FIELD_NAME ),
95 m_referenceValidator( REFERENCE_FIELD ),
96 m_valueValidator( VALUE_FIELD ),
97 m_urlValidator( FIELD_VALUE ),
98 m_nonUrlValidator( FIELD_VALUE ),
99 m_filepathValidator( SHEETFILENAME )
101 initGrid( aGrid );
103
105template <class T>
107 WX_GRID* aGrid, SCH_SYMBOL* aSymbol ) :
108 m_frame( aFrame ),
109 m_dialog( aDialog ),
110 m_grid( aGrid ),
111 m_parentType( SCH_SYMBOL_T ),
112 m_mandatoryFieldCount( MANDATORY_FIELDS ),
113 m_part( aSymbol->GetLibSymbolRef().get() ),
114 m_symbolNetlist( netList( aSymbol, aFrame->GetCurrentSheet() ) ),
115 m_fieldNameValidator( FIELD_NAME ),
116 m_referenceValidator( REFERENCE_FIELD ),
117 m_valueValidator( VALUE_FIELD ),
118 m_urlValidator( FIELD_VALUE ),
119 m_nonUrlValidator( FIELD_VALUE ),
120 m_filepathValidator( SHEETFILENAME )
121{
122 initGrid( aGrid );
123}
124
125
126template <class T>
128 WX_GRID* aGrid, SCH_SHEET* aSheet ) :
129 m_frame( aFrame ),
130 m_dialog( aDialog ),
131 m_grid( aGrid ),
132 m_parentType( SCH_SHEET_T ),
133 m_mandatoryFieldCount( SHEET_MANDATORY_FIELDS ),
134 m_part( nullptr ),
135 m_fieldNameValidator( FIELD_NAME ),
136 m_referenceValidator( SHEETNAME_V ),
137 m_valueValidator( VALUE_FIELD ),
138 m_urlValidator( FIELD_VALUE ),
139 m_nonUrlValidator( FIELD_VALUE ),
140 m_filepathValidator( SHEETFILENAME_V )
141{
142 initGrid( aGrid );
143}
144
145
146template <class T>
148 WX_GRID* aGrid, SCH_LABEL_BASE* aLabel ) :
149 m_frame( aFrame ),
150 m_dialog( aDialog ),
151 m_grid( aGrid ),
152 m_parentType( SCH_LABEL_LOCATE_ANY_T ),
153 m_mandatoryFieldCount( aLabel->GetMandatoryFieldCount() ),
154 m_part( nullptr ),
155 m_fieldNameValidator( FIELD_NAME ),
156 m_referenceValidator( 0 ),
157 m_valueValidator( 0 ),
158 m_urlValidator( FIELD_VALUE ),
159 m_nonUrlValidator( FIELD_VALUE ),
160 m_filepathValidator( 0 )
161{
162 initGrid( aGrid );
163}
164
165
166template <class T>
168{
169 // Build the various grid cell attributes.
170 // NOTE: validators and cellAttrs are member variables to get the destruction order
171 // right. wxGrid is VERY cranky about this.
172
173 m_readOnlyAttr = new wxGridCellAttr;
174 m_readOnlyAttr->SetReadOnly( true );
175
176 m_fieldNameAttr = new wxGridCellAttr;
178 nameEditor->SetValidator( m_fieldNameValidator );
179 m_fieldNameAttr->SetEditor( nameEditor );
180
181 m_referenceAttr = new wxGridCellAttr;
182 GRID_CELL_TEXT_EDITOR* referenceEditor = new GRID_CELL_TEXT_EDITOR();
183 referenceEditor->SetValidator( m_referenceValidator );
184 m_referenceAttr->SetEditor( referenceEditor );
185
186 m_valueAttr = new wxGridCellAttr;
187
188 if constexpr ( std::is_same_v<T, SCH_FIELD> )
189 {
190 GRID_CELL_STC_EDITOR* valueEditor = new GRID_CELL_STC_EDITOR( true,
191 [this]( wxStyledTextEvent& aEvent, SCINTILLA_TRICKS* aScintillaTricks )
192 {
193 SCH_FIELD& valueField = static_cast<SCH_FIELD&>( this->at( VALUE_FIELD ) );
194 valueField.OnScintillaCharAdded( aScintillaTricks, aEvent );
195 } );
196 m_valueAttr->SetEditor( valueEditor );
197 }
198 else
199 {
200 GRID_CELL_TEXT_EDITOR* valueEditor = new GRID_CELL_TEXT_EDITOR();
201 valueEditor->SetValidator( m_valueValidator );
202 m_valueAttr->SetEditor( valueEditor );
203 }
204
205 m_footprintAttr = new wxGridCellAttr;
206 GRID_CELL_FPID_EDITOR* fpIdEditor = new GRID_CELL_FPID_EDITOR( m_dialog, m_symbolNetlist );
207 fpIdEditor->SetValidator( m_nonUrlValidator );
208 m_footprintAttr->SetEditor( fpIdEditor );
209
210 m_urlAttr = new wxGridCellAttr;
211 GRID_CELL_URL_EDITOR* urlEditor = new GRID_CELL_URL_EDITOR( m_dialog, PROJECT_SCH::SchSearchS( &m_frame->Prj() ) );
212 urlEditor->SetValidator( m_urlValidator );
213 m_urlAttr->SetEditor( urlEditor );
214
215 m_nonUrlAttr = new wxGridCellAttr;
216 GRID_CELL_TEXT_EDITOR* nonUrlEditor = new GRID_CELL_TEXT_EDITOR();
217 nonUrlEditor->SetValidator( m_nonUrlValidator );
218 m_nonUrlAttr->SetEditor( nonUrlEditor );
219
220 m_curdir = m_frame->Prj().GetProjectPath();
221 m_filepathAttr = new wxGridCellAttr;
222
223 // Create a wild card using wxFileDialog syntax.
224 wxString wildCard( _( "Schematic Files" ) );
225 std::vector<std::string> exts;
226 exts.push_back( KiCadSchematicFileExtension );
227 wildCard += AddFileExtListToFilter( exts );
228
229 auto filepathEditor = new GRID_CELL_PATH_EDITOR( m_dialog, aGrid, &m_curdir, wildCard );
230 filepathEditor->SetValidator( m_filepathValidator );
231 m_filepathAttr->SetEditor( filepathEditor );
232
233 m_boolAttr = new wxGridCellAttr;
234 m_boolAttr->SetRenderer( new wxGridCellBoolRenderer() );
235 m_boolAttr->SetEditor( new wxGridCellBoolEditor() );
236 m_boolAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
237
238 wxArrayString vAlignNames;
239 vAlignNames.Add( _( "Top" ) );
240 vAlignNames.Add( _( "Center" ) );
241 vAlignNames.Add( _( "Bottom" ) );
242 m_vAlignAttr = new wxGridCellAttr;
243 m_vAlignAttr->SetEditor( new wxGridCellChoiceEditor( vAlignNames ) );
244 m_vAlignAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
245
246 wxArrayString hAlignNames;
247 hAlignNames.Add( _( "Left" ) );
248 hAlignNames.Add(_( "Center" ) );
249 hAlignNames.Add(_( "Right" ) );
250 m_hAlignAttr = new wxGridCellAttr;
251 m_hAlignAttr->SetEditor( new wxGridCellChoiceEditor( hAlignNames ) );
252 m_hAlignAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
253
254 wxArrayString orientationNames;
255 orientationNames.Add( _( "Horizontal" ) );
256 orientationNames.Add(_( "Vertical" ) );
257 m_orientationAttr = new wxGridCellAttr;
258 m_orientationAttr->SetEditor( new wxGridCellChoiceEditor( orientationNames ) );
259 m_orientationAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
260
261 SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
262 wxArrayString existingNetclasses;
263
264 if( editFrame )
265 {
266 // Load the combobox with existing existingNetclassNames
267 PROJECT_FILE& projectFile = editFrame->Prj().GetProjectFile();
268 const std::shared_ptr<NET_SETTINGS>& settings = projectFile.NetSettings();
269
270 existingNetclasses.push_back( settings->m_DefaultNetClass->GetName() );
271
272 for( const auto& [ name, netclass ] : settings->m_NetClasses )
273 existingNetclasses.push_back( name );
274 }
275
276 m_netclassAttr = new wxGridCellAttr;
277 m_netclassAttr->SetEditor( new GRID_CELL_COMBOBOX( existingNetclasses ) );
278
279 wxArrayString fonts;
280 std::vector<std::string> fontNames;
281 Fontconfig()->ListFonts( fontNames, std::string( Pgm().GetLanguageTag().utf8_str() ) );
282
283 for( const std::string& name : fontNames )
284 fonts.Add( wxString( name ) );
285
286 fonts.Sort();
287 fonts.Insert( KICAD_FONT_NAME, 0 );
288 fonts.Insert( DEFAULT_FONT_NAME, 0 );
289
290 m_fontAttr = new wxGridCellAttr;
291 m_fontAttr->SetEditor( new GRID_CELL_COMBOBOX( fonts ) );
292
293 m_colorAttr = new wxGridCellAttr;
294 m_colorAttr->SetRenderer( new GRID_CELL_COLOR_RENDERER( m_dialog ) );
295 m_colorAttr->SetEditor( new GRID_CELL_COLOR_SELECTOR( m_dialog, aGrid ) );
296
297 m_eval = std::make_unique<NUMERIC_EVALUATOR>( m_frame->GetUserUnits() );
298
299 m_frame->Bind( EDA_EVT_UNITS_CHANGED, &FIELDS_GRID_TABLE<T>::onUnitsChanged, this );
300}
301
302
303template <class T>
305{
306 m_readOnlyAttr->DecRef();
307 m_fieldNameAttr->DecRef();
308 m_boolAttr->DecRef();
309 m_referenceAttr->DecRef();
310 m_valueAttr->DecRef();
311 m_footprintAttr->DecRef();
312 m_urlAttr->DecRef();
313 m_nonUrlAttr->DecRef();
314 m_filepathAttr->DecRef();
315 m_vAlignAttr->DecRef();
316 m_hAlignAttr->DecRef();
317 m_orientationAttr->DecRef();
318 m_netclassAttr->DecRef();
319 m_fontAttr->DecRef();
320 m_colorAttr->DecRef();
321
322 m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &FIELDS_GRID_TABLE<T>::onUnitsChanged, this );
323}
324
325
326template <class T>
327void FIELDS_GRID_TABLE<T>::onUnitsChanged( wxCommandEvent& aEvent )
328{
329 if( GetView() )
330 GetView()->ForceRefresh();
331
332 aEvent.Skip();
333}
334
335
336template <class T>
338{
339 switch( aCol )
340 {
341 case FDC_NAME: return _( "Name" );
342 case FDC_VALUE: return _( "Value" );
343 case FDC_SHOWN: return _( "Show" );
344 case FDC_SHOW_NAME: return _( "Show Name" );
345 case FDC_H_ALIGN: return _( "H Align" );
346 case FDC_V_ALIGN: return _( "V Align" );
347 case FDC_ITALIC: return _( "Italic" );
348 case FDC_BOLD: return _( "Bold" );
349 case FDC_TEXT_SIZE: return _( "Text Size" );
350 case FDC_ORIENTATION: return _( "Orientation" );
351 case FDC_POSX: return _( "X Position" );
352 case FDC_POSY: return _( "Y Position" );
353 case FDC_FONT: return _( "Font" );
354 case FDC_COLOR: return _( "Color" );
355 case FDC_ALLOW_AUTOPLACE: return _( "Allow Autoplacement" );
356 default: wxFAIL; return wxEmptyString;
357 }
358}
359
360
361template <class T>
362bool FIELDS_GRID_TABLE<T>::CanGetValueAs( int aRow, int aCol, const wxString& aTypeName )
363{
364 switch( aCol )
365 {
366 case FDC_NAME:
367 case FDC_VALUE:
368 case FDC_H_ALIGN:
369 case FDC_V_ALIGN:
370 case FDC_TEXT_SIZE:
371 case FDC_ORIENTATION:
372 case FDC_POSX:
373 case FDC_POSY:
374 case FDC_FONT:
375 case FDC_COLOR:
376 return aTypeName == wxGRID_VALUE_STRING;
377
378 case FDC_SHOWN:
379 case FDC_SHOW_NAME:
380 case FDC_ITALIC:
381 case FDC_BOLD:
383 return aTypeName == wxGRID_VALUE_BOOL;
384
385 default:
386 wxFAIL;
387 return false;
388 }
389}
390
391
392template <class T>
393bool FIELDS_GRID_TABLE<T>::CanSetValueAs( int aRow, int aCol, const wxString& aTypeName )
394{
395 return CanGetValueAs( aRow, aCol, aTypeName );
396}
397
398
399template <class T>
400wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind )
401{
402 wxGridCellAttr* tmp;
403
404 switch( aCol )
405 {
406 case FDC_NAME:
407 if( aRow < m_mandatoryFieldCount )
408 {
409 tmp = m_fieldNameAttr->Clone();
410 tmp->SetReadOnly( true );
411 return tmp;
412 }
413 else
414 {
415 m_fieldNameAttr->IncRef();
416 return m_fieldNameAttr;
417 }
418
419 case FDC_VALUE:
420 if( m_parentType == SCH_SYMBOL_T && aRow == REFERENCE_FIELD )
421 {
422 m_referenceAttr->IncRef();
423 return m_referenceAttr;
424 }
425 else if( m_parentType == SCH_SYMBOL_T && aRow == VALUE_FIELD )
426 {
427 m_valueAttr->IncRef();
428 return m_valueAttr;
429 }
430 else if( m_parentType == SCH_SYMBOL_T && aRow == FOOTPRINT_FIELD )
431 {
432 m_footprintAttr->IncRef();
433 return m_footprintAttr;
434 }
435 else if( m_parentType == SCH_SYMBOL_T && aRow == DATASHEET_FIELD )
436 {
437 m_urlAttr->IncRef();
438 return m_urlAttr;
439 }
440 else if( m_parentType == SCH_SHEET_T && aRow == SHEETNAME )
441 {
442 m_referenceAttr->IncRef();
443 return m_referenceAttr;
444 }
445 else if( m_parentType == SCH_SHEET_T && aRow == SHEETFILENAME )
446 {
447 m_filepathAttr->IncRef();
448 return m_filepathAttr;
449 }
450 else if( ( m_parentType == SCH_LABEL_LOCATE_ANY_T )
451 && this->at( (size_t) aRow ).GetCanonicalName() == wxT( "Netclass" ) )
452 {
453 m_netclassAttr->IncRef();
454 return m_netclassAttr;
455 }
456 else
457 {
458 wxString fn = GetValue( aRow, FDC_NAME );
459
460 SCHEMATIC_SETTINGS* settings = m_frame->Prj().GetProjectFile().m_SchematicSettings;
461
462 const TEMPLATE_FIELDNAME* templateFn =
463 settings ? settings->m_TemplateFieldNames.GetFieldName( fn ) : nullptr;
464
465 if( templateFn && templateFn->m_URL )
466 {
467 m_urlAttr->IncRef();
468 return m_urlAttr;
469 }
470 else
471 {
472 m_nonUrlAttr->IncRef();
473 return m_nonUrlAttr;
474 }
475 }
476
477 case FDC_TEXT_SIZE:
478 case FDC_POSX:
479 case FDC_POSY:
480 return nullptr;
481
482 case FDC_H_ALIGN:
483 m_hAlignAttr->IncRef();
484 return m_hAlignAttr;
485
486 case FDC_V_ALIGN:
487 m_vAlignAttr->IncRef();
488 return m_vAlignAttr;
489
490 case FDC_ORIENTATION:
491 m_orientationAttr->IncRef();
492 return m_orientationAttr;
493
494 case FDC_SHOWN:
495 case FDC_SHOW_NAME:
496 case FDC_ITALIC:
497 case FDC_BOLD:
499 m_boolAttr->IncRef();
500 return m_boolAttr;
501
502 case FDC_FONT:
503 m_fontAttr->IncRef();
504 return m_fontAttr;
505
506 case FDC_COLOR:
507 m_colorAttr->IncRef();
508 return m_colorAttr;
509
510 default:
511 wxFAIL;
512 return nullptr;
513 }
514}
515
516
517template <class T>
518wxString FIELDS_GRID_TABLE<T>::GetValue( int aRow, int aCol )
519{
520 wxCHECK( aRow < GetNumberRows(), wxEmptyString );
521
522 wxGrid* grid = GetView();
523 const T& field = this->at( (size_t) aRow );
524
525 if( grid->GetGridCursorRow() == aRow && grid->GetGridCursorCol() == aCol
526 && grid->IsCellEditControlShown() )
527 {
528 auto it = m_evalOriginal.find( { aRow, aCol } );
529
530 if( it != m_evalOriginal.end() )
531 return it->second;
532 }
533
534 switch( aCol )
535 {
536 case FDC_NAME:
537 // Use default field names for mandatory and system fields because they are translated
538 // according to the current locale
539 if( m_parentType == SCH_SYMBOL_T )
540 {
541 if( aRow < m_mandatoryFieldCount )
543 else
544 return field.GetName( false );
545 }
546 else if( m_parentType == SCH_SHEET_T )
547 {
548 if( aRow < m_mandatoryFieldCount )
549 return SCH_SHEET::GetDefaultFieldName( aRow );
550 else
551 return field.GetName( false );
552 }
553 else if( m_parentType == SCH_LABEL_LOCATE_ANY_T )
554 {
555 return SCH_LABEL_BASE::GetDefaultFieldName( field.GetCanonicalName(), false );
556 }
557 else
558 {
559 wxFAIL_MSG( wxS( "Unhandled field owner type." ) );
560 return field.GetName( false );
561 }
562
563 case FDC_VALUE:
564 return EscapeString( UnescapeString( field.GetText() ), CTX_LINE );
565
566 case FDC_SHOWN:
567 return StringFromBool( field.IsVisible() );
568
569 case FDC_SHOW_NAME:
570 return StringFromBool( field.IsNameShown() );
571
572 case FDC_H_ALIGN:
573 switch ( field.GetEffectiveHorizJustify() )
574 {
575 case GR_TEXT_H_ALIGN_LEFT: return _( "Left" );
576 case GR_TEXT_H_ALIGN_CENTER: return _( "Center" );
577 case GR_TEXT_H_ALIGN_RIGHT: return _( "Right" );
578 }
579
580 break;
581
582 case FDC_V_ALIGN:
583 switch ( field.GetEffectiveVertJustify() )
584 {
585 case GR_TEXT_V_ALIGN_TOP: return _( "Top" );
586 case GR_TEXT_V_ALIGN_CENTER: return _( "Center" );
587 case GR_TEXT_V_ALIGN_BOTTOM: return _( "Bottom" );
588 }
589
590 break;
591
592 case FDC_ITALIC:
593 return StringFromBool( field.IsItalic() );
594
595 case FDC_BOLD:
596 return StringFromBool( field.IsBold() );
597
598 case FDC_TEXT_SIZE:
599 return m_frame->StringFromValue( field.GetTextHeight(), true );
600
601 case FDC_ORIENTATION:
602 if( field.GetTextAngle().IsHorizontal() )
603 return _( "Horizontal" );
604 else
605 return _( "Vertical" );
606
607 case FDC_POSX:
608 return m_frame->StringFromValue( field.GetTextPos().x, true );
609
610 case FDC_POSY:
611 return m_frame->StringFromValue( field.GetTextPos().y, true );
612
613 case FDC_FONT:
614 if( field.GetFont() )
615 return field.GetFont()->GetName();
616 else
617 return DEFAULT_FONT_NAME;
618
619 case FDC_COLOR:
620 return field.GetTextColor().ToCSSString();
621
623 return StringFromBool( field.CanAutoplace() );
624
625 default:
626 // we can't assert here because wxWidgets sometimes calls this without checking
627 // the column type when trying to see if there's an overflow
628 break;
629 }
630
631 return wxT( "bad wxWidgets!" );
632}
633
634
635template <class T>
636bool FIELDS_GRID_TABLE<T>::GetValueAsBool( int aRow, int aCol )
637{
638 wxCHECK( aRow < GetNumberRows(), false );
639 const T& field = this->at( (size_t) aRow );
640
641 switch( aCol )
642 {
643 case FDC_SHOWN: return field.IsVisible();
644 case FDC_SHOW_NAME: return field.IsNameShown();
645 case FDC_ITALIC: return field.IsItalic();
646 case FDC_BOLD: return field.IsBold();
647 case FDC_ALLOW_AUTOPLACE: return field.CanAutoplace();
648 default:
649 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
650 return false;
651 }
652}
653
654
655template <class T>
656void FIELDS_GRID_TABLE<T>::SetValue( int aRow, int aCol, const wxString &aValue )
657{
658 wxCHECK( aRow < GetNumberRows(), /*void*/ );
659 T& field = this->at( (size_t) aRow );
660 VECTOR2I pos;
661 wxString value = aValue;
662
663 switch( aCol )
664 {
665 case FDC_TEXT_SIZE:
666 case FDC_POSX:
667 case FDC_POSY:
668 m_eval->SetDefaultUnits( m_frame->GetUserUnits() );
669
670 if( m_eval->Process( value ) )
671 {
672 m_evalOriginal[ { aRow, aCol } ] = value;
673 value = m_eval->Result();
674 }
675
676 break;
677
678 default:
679 break;
680 }
681
682 switch( aCol )
683 {
684 case FDC_NAME:
685 field.SetName( value );
686 break;
687
688 case FDC_VALUE:
689 {
690 if( m_parentType == SCH_SHEET_T && aRow == SHEETFILENAME )
691 {
693 }
694 else if( m_parentType == LIB_SYMBOL_T && aRow == VALUE_FIELD )
695 {
696 value = EscapeString( value, CTX_LIBID );
697 }
698
699 field.SetText( UnescapeString( value ) );
700 break;
701 }
702
703 case FDC_SHOWN:
704 field.SetVisible( BoolFromString( value ) );
705 break;
706
707 case FDC_SHOW_NAME:
708 field.SetNameShown( BoolFromString( value ) );
709 break;
710
711 case FDC_H_ALIGN:
712 {
713 GR_TEXT_H_ALIGN_T horizontalJustification = GR_TEXT_H_ALIGN_CENTER;
714
715 if( value == _( "Left" ) )
716 horizontalJustification = GR_TEXT_H_ALIGN_LEFT;
717 else if( value == _( "Center" ) )
718 horizontalJustification = GR_TEXT_H_ALIGN_CENTER;
719 else if( value == _( "Right" ) )
720 horizontalJustification = GR_TEXT_H_ALIGN_RIGHT;
721 else
722 wxFAIL_MSG( wxT( "unknown horizontal alignment: " ) + value );
723
724 // Note that we must set justifications before we can ask if they're flipped. If the old
725 // justification is center then it won't know (whereas if the new justification is center
726 // the we don't care).
727 field.SetHorizJustify( horizontalJustification );
728
729 if( field.IsHorizJustifyFlipped() )
730 field.SetHorizJustify( EDA_TEXT::MapHorizJustify( - horizontalJustification ) );
731
732 break;
733 }
734
735 case FDC_V_ALIGN:
736 {
737 GR_TEXT_V_ALIGN_T verticalJustification = GR_TEXT_V_ALIGN_BOTTOM;
738
739 if( value == _( "Top" ) )
740 verticalJustification = GR_TEXT_V_ALIGN_TOP;
741 else if( value == _( "Center" ) )
742 verticalJustification = GR_TEXT_V_ALIGN_CENTER;
743 else if( value == _( "Bottom" ) )
744 verticalJustification = GR_TEXT_V_ALIGN_BOTTOM;
745 else
746 wxFAIL_MSG( wxT( "unknown vertical alignment: " ) + value);
747
748 // Note that we must set justifications before we can ask if they're flipped. If the old
749 // justification is center then it won't know (whereas if the new justification is center
750 // the we don't care).
751 field.SetVertJustify( verticalJustification );
752
753 if( field.IsVertJustifyFlipped() )
754 field.SetVertJustify( EDA_TEXT::MapVertJustify( -verticalJustification ) );
755
756 break;
757 }
758
759 case FDC_ITALIC:
760 field.SetItalic( BoolFromString( value ) );
761 break;
762
763 case FDC_BOLD:
764 field.SetBold( BoolFromString( value ) );
765 break;
766
767 case FDC_TEXT_SIZE:
768 field.SetTextSize( VECTOR2I( m_frame->ValueFromString( value ),
769 m_frame->ValueFromString( value ) ) );
770 break;
771
772 case FDC_ORIENTATION:
773 if( value == _( "Horizontal" ) )
774 field.SetTextAngle( ANGLE_HORIZONTAL );
775 else if( value == _( "Vertical" ) )
776 field.SetTextAngle( ANGLE_VERTICAL );
777 else
778 wxFAIL_MSG( wxT( "unknown orientation: " ) + value );
779
780 break;
781
782 case FDC_POSX:
783 case FDC_POSY:
784 pos = field.GetTextPos();
785
786 if( aCol == FDC_POSX )
787 pos.x = m_frame->ValueFromString( value );
788 else
789 pos.y = m_frame->ValueFromString( value );
790
791 field.SetTextPos( pos );
792 break;
793
794 case FDC_FONT:
795 if( value == DEFAULT_FONT_NAME )
796 field.SetFont( nullptr );
797 else if( value == KICAD_FONT_NAME )
798 field.SetFont( KIFONT::FONT::GetFont( wxEmptyString, field.IsBold(),
799 field.IsItalic() ) );
800 else
801 field.SetFont( KIFONT::FONT::GetFont( aValue, field.IsBold(), field.IsItalic() ) );
802
803 break;
804
805 case FDC_COLOR:
806 field.SetTextColor( wxColor( value ) );
807 break;
808
810 field.SetCanAutoplace( BoolFromString( value ) );
811 break;
812
813 default:
814 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a string value" ), aCol ) );
815 break;
816 }
817
818 m_dialog->OnModify();
819
820 GetView()->Refresh();
821}
822
823
824template <class T>
825void FIELDS_GRID_TABLE<T>::SetValueAsBool( int aRow, int aCol, bool aValue )
826{
827 wxCHECK( aRow < GetNumberRows(), /*void*/ );
828 T& field = this->at( (size_t) aRow );
829
830 switch( aCol )
831 {
832 case FDC_SHOWN:
833 field.SetVisible( aValue );
834 break;
835
836 case FDC_SHOW_NAME:
837 field.SetNameShown( aValue );
838 break;
839
840 case FDC_ITALIC:
841 field.SetItalic( aValue );
842 break;
843
844 case FDC_BOLD:
845 field.SetBold( aValue );
846 break;
847
849 field.SetCanAutoplace( aValue );
850 break;
851
852 default:
853 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
854 break;
855 }
856
857 m_dialog->OnModify();
858}
859
860
861// Explicit Instantiations
862
863template class FIELDS_GRID_TABLE<SCH_FIELD>;
864template class FIELDS_GRID_TABLE<LIB_FIELD>;
865
866
867void FIELDS_GRID_TRICKS::showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
868{
869 if( m_grid->GetGridCursorRow() == FOOTPRINT_FIELD && m_grid->GetGridCursorCol() == FDC_VALUE )
870 {
871 menu.Append( MYID_SELECT_FOOTPRINT, _( "Select Footprint..." ),
872 _( "Browse for footprint" ) );
873 menu.AppendSeparator();
874 }
875 else if( m_grid->GetGridCursorRow() == DATASHEET_FIELD
876 && m_grid->GetGridCursorCol() == FDC_VALUE )
877 {
878 menu.Append( MYID_SHOW_DATASHEET, _( "Show Datasheet" ),
879 _( "Show datasheet in browser" ) );
880 menu.AppendSeparator();
881 }
882
883 GRID_TRICKS::showPopupMenu( menu, aEvent );
884}
885
886
887void FIELDS_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
888{
889 if( event.GetId() == MYID_SELECT_FOOTPRINT )
890 {
891 // pick a footprint using the footprint picker.
892 wxString fpid = m_grid->GetCellValue( FOOTPRINT_FIELD, FDC_VALUE );
894
895 if( frame->ShowModal( &fpid, m_dlg ) )
896 m_grid->SetCellValue( FOOTPRINT_FIELD, FDC_VALUE, fpid );
897
898 frame->Destroy();
899 }
900 else if (event.GetId() == MYID_SHOW_DATASHEET )
901 {
902 wxString datasheet_uri = m_grid->GetCellValue( DATASHEET_FIELD, FDC_VALUE );
903 GetAssociatedDocument( m_dlg, datasheet_uri, &m_dlg->Prj(),
905 }
906 else
907 {
909 }
910}
911
912
913template <class T>
914wxString FIELDS_GRID_TABLE<T>::StringFromBool( bool aValue ) const
915{
916 if( aValue )
917 return wxT( "1" );
918 else
919 return wxT( "0" );
920}
921
922
923template <class T>
924bool FIELDS_GRID_TABLE<T>::BoolFromString( wxString aValue ) const
925{
926 if( aValue == wxS( "1" ) )
927 {
928 return true;
929 }
930 else if( aValue == wxS( "0" ) )
931 {
932 return false;
933 }
934 else
935 {
936 wxFAIL_MSG( wxString::Format( "string '%s' can't be converted to boolean correctly and "
937 "will be perceived as FALSE", aValue ) );
938 return false;
939 }
940}
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
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:81
size_t GetFullPinCount()
Definition: sch_symbol.h:519
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:192
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:398
#define _(s)
static constexpr EDA_ANGLE & ANGLE_HORIZONTAL
Definition: eda_angle.h:433
static constexpr EDA_ANGLE & ANGLE_VERTICAL
Definition: eda_angle.h:434
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_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:54
@ FRAME_FOOTPRINT_CHOOSER
Definition: frame_type.h:44
@ 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
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_V_ALIGN_T
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
@ LIB_SYMBOL_T
Definition: typeinfo.h:198
@ SCH_SYMBOL_T
Definition: typeinfo.h:156
@ SCH_SHEET_T
Definition: typeinfo.h:158
@ SCH_LABEL_LOCATE_ANY_T
Definition: typeinfo.h:175
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
Definition of file extensions used in Kicad.