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