KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_lib_symbol_properties.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 The 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
25
26#include <pgm_base.h>
27#include <eeschema_settings.h>
28#include <bitmaps.h>
29#include <confirm.h>
31#include <kiway.h>
32#include <symbol_edit_frame.h>
34#include <math/util.h> // for KiROUND
35#include <sch_symbol.h>
36#include <kiplatform/ui.h>
38#include <widgets/wx_grid.h>
40#include <string_utils.h>
41#include <project_sch.h>
42#include <refdes_utils.h>
43#include <dialog_sim_model.h>
44#include <vector>
45
50
51#include <wx/clipbrd.h>
52#include <wx/msgdlg.h>
53
54
58
59
61 LIB_SYMBOL* aLibEntry ) :
63 m_Parent( aParent ),
64 m_libEntry( aLibEntry ),
66 m_delayedFocusCtrl( nullptr ),
67 m_delayedFocusGrid( nullptr ),
72{
73 std::vector<const EMBEDDED_FILES*> inheritedEmbeddedFiles;
74
75 if( std::shared_ptr<LIB_SYMBOL> parent = m_libEntry->GetParent().lock() )
76 {
77 while( parent )
78 {
79 inheritedEmbeddedFiles.push_back( parent->GetEmbeddedFiles() );
80 parent = parent->GetParent().lock();
81 }
82 }
83
84 m_embeddedFiles = new PANEL_EMBEDDED_FILES( m_NoteBook, m_libEntry, 0, std::move( inheritedEmbeddedFiles ) );
85 m_NoteBook->AddPage( m_embeddedFiles, _( "Embedded Files" ) );
86
87 m_fields = new FIELDS_GRID_TABLE( this, aParent, m_grid, m_libEntry, { m_embeddedFiles->GetLocalFiles() } );
88 m_grid->SetTable( m_fields );
89 m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this, { m_embeddedFiles->GetLocalFiles() },
90 [&]( wxCommandEvent& aEvent )
91 {
92 OnAddField( aEvent );
93 } ) );
94 m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
95
96 // Load the FIELDS_GRID_TABLE -- ensure we are calling the overloaded push_back method
97 std::vector<SCH_FIELD> fields;
98 m_libEntry->CopyFields( fields );
99
100 for( const SCH_FIELD& f : fields )
101 m_fields->push_back( f );
102
103 if( std::shared_ptr<LIB_SYMBOL> parent = m_libEntry->GetParent().lock() )
104 addInheritedFields( parent );
105
106 m_grid->ShowHideColumns( "0 1 2 3 4 5 6 7" );
107
108 m_SymbolNameCtrl->SetValidator( FIELD_VALIDATOR( FIELD_T::VALUE ) );
109
110 m_unitNamesGrid->PushEventHandler( new GRID_TRICKS( m_unitNamesGrid ) );
111 m_unitNamesGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
112
113 m_bodyStyleNamesGrid->PushEventHandler( new GRID_TRICKS( m_bodyStyleNamesGrid,
114 [this]( wxCommandEvent& aEvent )
115 {
116 OnAddBodyStyle( aEvent );
117 } ) );
118 m_bodyStyleNamesGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
119
120 m_jumperGroupsGrid->SetupColumnAutosizer( 0 );
121 m_jumperGroupsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
122
123 m_jumperGroupsGrid->PushEventHandler( new GRID_TRICKS( m_jumperGroupsGrid,
124 [this]( wxCommandEvent& aEvent )
125 {
126 OnAddJumperGroup( aEvent );
127 } ) );
128
129 // Configure button logos
130 m_bpAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
131 m_bpMoveUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
132 m_bpMoveDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
133 m_bpDelete->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
134
135 m_bpAddBodyStyle->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
136 m_bpMoveUpBodyStyle->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
137 m_bpMoveDownBodyStyle->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
138 m_bpDeleteBodyStyle->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
139
140 m_addFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
141 m_editFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_edit ) );
142 m_deleteFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
143
144 m_bpAddJumperGroup->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
145 m_bpRemoveJumperGroup->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
146
147 SetupStandardButtons();
148
149 if( aParent->IsSymbolFromLegacyLibrary() && !aParent->IsSymbolFromSchematic() )
150 {
151 m_stdSizerButtonCancel->SetDefault();
152 m_stdSizerButtonOK->SetLabel( _( "Read Only" ) );
153 m_stdSizerButtonOK->Enable( false );
154 }
155
156 // wxFormBuilder doesn't include this event...
157 m_grid->Bind( wxEVT_GRID_CELL_CHANGING, &DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging, this );
158 m_grid->Bind( wxEVT_GRID_CELL_CHANGED, &DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanged, this );
159 m_grid->GetGridWindow()->Bind( wxEVT_MOTION, &DIALOG_LIB_SYMBOL_PROPERTIES::OnGridMotion, this );
160
161
162 // Forward the delete button to the tricks
163 m_deleteFilterButton->Bind( wxEVT_BUTTON,
164 [&]( wxCommandEvent& aEvent )
165 {
166 wxCommandEvent cmdEvent( EDA_EVT_LISTBOX_DELETE );
167 m_fpFilterTricks->ProcessEvent( cmdEvent );
168 } );
169
170 // When the filter tricks modifies something, update ourselves
171 m_FootprintFilterListBox->Bind( EDA_EVT_LISTBOX_CHANGED,
172 [&]( wxCommandEvent& aEvent )
173 {
174 OnModify();
175 } );
176
178 {
179 if( ( m_lastLayout == DIALOG_LIB_SYMBOL_PROPERTIES::LAST_LAYOUT::ALIAS && aLibEntry->IsRoot() )
180 || ( m_lastLayout == DIALOG_LIB_SYMBOL_PROPERTIES::LAST_LAYOUT::PARENT && aLibEntry->IsDerived() ) )
181 {
182 resetSize();
183 }
184 }
185
186 m_lastLayout = ( aLibEntry->IsDerived() ) ? DIALOG_LIB_SYMBOL_PROPERTIES::LAST_LAYOUT::ALIAS
188
189 m_grid->GetParent()->Layout();
190 syncControlStates( m_libEntry->IsDerived() );
191 Layout();
192
193 finishDialogSettings();
194}
195
196
198{
199 m_lastOpenedPage = m_NoteBook->GetSelection( );
200
201 // Prevents crash bug in wxGrid's d'tor
202 m_grid->DestroyTable( m_fields );
203
204 m_grid->Unbind( wxEVT_GRID_CELL_CHANGING, &DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging, this );
205 m_grid->Unbind( wxEVT_GRID_CELL_CHANGED, &DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanged, this );
206 m_grid->GetGridWindow()->Unbind( wxEVT_MOTION, &DIALOG_LIB_SYMBOL_PROPERTIES::OnGridMotion, this );
207
208 // Delete the GRID_TRICKS.
209 m_grid->PopEventHandler( true );
210 m_unitNamesGrid->PopEventHandler( true );
211 m_bodyStyleNamesGrid->PopEventHandler( true );
212 m_jumperGroupsGrid->PopEventHandler( true );
213}
214
215
216void DIALOG_LIB_SYMBOL_PROPERTIES::addInheritedFields( const std::shared_ptr<LIB_SYMBOL>& aParent )
217{
218 if( std::shared_ptr<LIB_SYMBOL> ancestor = aParent->GetParent().lock() )
219 addInheritedFields( ancestor );
220
221 std::vector<SCH_FIELD*> parentFields;
222 aParent->GetFields( parentFields );
223
224 for( SCH_FIELD* parentField : parentFields )
225 {
226 bool found = false;
227
228 if( parentField->IsMandatory() )
229 continue; // Don't inherit mandatory fields
230
231 for( size_t ii = 0; ii < m_fields->size(); ++ii )
232 {
233 SCH_FIELD& field = m_fields->at( ii );
234
235 if( field.IsMandatory() )
236 continue; // Don't inherit mandatory fields
237
238 if( field.GetCanonicalName() == parentField->GetCanonicalName() )
239 {
240 m_fields->SetFieldInherited( ii, *parentField );
241 found = true;
242 break;
243 }
244 }
245
246 if( !found )
247 m_fields->AddInheritedField( *parentField );
248 }
249}
250
251
253{
254 if( !wxDialog::TransferDataToWindow() )
255 return false;
256
257 std::set<wxString> defined;
258
259 for( SCH_FIELD& field : *m_fields )
260 defined.insert( field.GetName() );
261
262 // Add in any template fieldnames not yet defined:
263 // Read global fieldname templates
265 {
266 TEMPLATES templateMgr;
267
268 if( !cfg->m_Drawing.field_names.IsEmpty() )
269 templateMgr.AddTemplateFieldNames( cfg->m_Drawing.field_names );
270
271 for( const TEMPLATE_FIELDNAME& templateFieldname : templateMgr.GetTemplateFieldNames() )
272 {
273 if( defined.count( templateFieldname.m_Name ) <= 0 )
274 {
275 SCH_FIELD field( m_libEntry, FIELD_T::USER, templateFieldname.m_Name );
276 field.SetVisible( templateFieldname.m_Visible );
277 m_fields->push_back( field );
278 m_addedTemplateFields.insert( templateFieldname.m_Name );
279 }
280 }
281 }
282
283 // The Y axis for components in library file is from bottom to top while the screen axis is top
284 // to bottom.However it is nowhandled by the lib file parser/writer.
285
286 // notify the grid
287 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->GetNumberRows() );
288 m_grid->ProcessTableMessage( msg );
289
290 m_SymbolNameCtrl->ChangeValue( UnescapeString( m_libEntry->GetName() ) );
291
292 m_KeywordCtrl->ChangeValue( m_libEntry->GetKeyWords() );
293 m_unitSpinCtrl->SetValue( m_libEntry->GetUnitCount() );
294 m_OptionPartsInterchangeable->SetValue( !m_libEntry->UnitsLocked() || m_libEntry->GetUnitCount() == 1 );
295
297
298 for( int unit = 0; unit < m_libEntry->GetUnitCount(); unit++ )
299 {
300 if( m_libEntry->GetUnitDisplayNames().contains( unit + 1 ) )
301 m_unitNamesGrid->SetCellValue( unit, 1, m_libEntry->GetUnitDisplayNames().at( unit + 1 ) );
302 }
303
304 if( m_libEntry->HasDeMorganBodyStyles() )
305 {
306 m_radioDeMorgan->SetValue( true );
307 }
308 else if( m_libEntry->IsMultiBodyStyle() )
309 {
310 m_radioCustom->SetValue( true );
311
312 for( const wxString& name : m_libEntry->GetBodyStyleNames() )
313 {
314 int row = m_bodyStyleNamesGrid->GetNumberRows();
315 m_bodyStyleNamesGrid->AppendRows( 1 );
316 m_bodyStyleNamesGrid->SetCellValue( row, 0, name );
317 }
318 }
319 else
320 {
321 m_radioSingle->SetValue( true );
322 }
323
324 m_OptionPower->SetValue( m_libEntry->IsPower() );
325 m_OptionLocalPower->SetValue( m_libEntry->IsLocalPower() );
326
327 if( m_libEntry->IsPower() )
328 {
329 m_spiceFieldsButton->Hide();
330 m_OptionLocalPower->Enable();
331 }
332 else
333 {
334 m_OptionLocalPower->Enable( false );
335 }
336
337 m_excludeFromSimCheckBox->SetValue( m_libEntry->GetExcludedFromSim() );
338 m_excludeFromBomCheckBox->SetValue( m_libEntry->GetExcludedFromBOM() );
339 m_excludeFromBoardCheckBox->SetValue( m_libEntry->GetExcludedFromBoard() );
340 m_excludeFromPosFilesCheckBox->SetValue( m_libEntry->GetExcludedFromPosFiles() );
341
342 m_ShowPinNumButt->SetValue( m_libEntry->GetShowPinNumbers() );
343 m_ShowPinNameButt->SetValue( m_libEntry->GetShowPinNames() );
344 m_PinsNameInsideButt->SetValue( m_libEntry->GetPinNameOffset() != 0 );
345 m_pinNameOffset.ChangeValue( m_libEntry->GetPinNameOffset() );
346
347 wxArrayString tmp = m_libEntry->GetFPFilters();
348 m_FootprintFilterListBox->Append( tmp );
349
350 m_cbDuplicatePinsAreJumpers->SetValue( m_libEntry->GetDuplicatePinNumbersAreJumpers() );
351
352 std::set<wxString> availablePins;
353
354 for( const SCH_PIN* pin : m_libEntry->GetGraphicalPins( 0, 0 ) )
355 availablePins.insert( pin->GetNumber() );
356
357 for( const std::set<wxString>& group : m_libEntry->JumperPinGroups() )
358 {
359 wxString groupTxt;
360
361 for( const wxString& pinNumber : group )
362 {
363 if( !groupTxt.IsEmpty() )
364 groupTxt << ", ";
365
366 groupTxt << pinNumber;
367 }
368
369 m_jumperGroupsGrid->AppendRows( 1 );
370 m_jumperGroupsGrid->SetCellValue( m_jumperGroupsGrid->GetNumberRows() - 1, 0, groupTxt );
371 }
372
373 // Populate the list of root parts for inherited objects.
374 if( m_libEntry->IsDerived() )
375 {
376 wxArrayString symbolNames;
377 wxString libName = m_Parent->GetCurLib();
378
379 // Someone forgot to set the current library in the editor frame window.
380 wxCHECK( !libName.empty(), false );
381
382 m_Parent->GetLibManager().GetSymbolNames( libName, symbolNames );
383
384 // Sort the list of symbols for easier search
385 symbolNames.Sort(
386 []( const wxString& a, const wxString& b ) -> int
387 {
388 return StrNumCmp( a, b, true );
389 } );
390
391 // Don't allow a symbol to be derived from itself
392 if( symbolNames.Index( m_libEntry->GetName() ) != wxNOT_FOUND )
393 symbolNames.Remove( m_libEntry->GetName() );
394
395 // Don't allow a symbol to be derived from any of its descendants (would create
396 // circular inheritance)
397 wxArrayString descendants;
398 m_Parent->GetLibManager().GetDerivedSymbolNames( m_libEntry->GetName(), libName, descendants );
399
400 for( const wxString& descendant : descendants )
401 {
402 if( symbolNames.Index( descendant ) != wxNOT_FOUND )
403 symbolNames.Remove( descendant );
404 }
405
406 m_inheritanceSelectCombo->Append( symbolNames );
407
408 if( std::shared_ptr<LIB_SYMBOL> rootSymbol = m_libEntry->GetParent().lock() )
409 {
410 wxString parentName = UnescapeString( rootSymbol->GetName() );
411 int selection = m_inheritanceSelectCombo->FindString( parentName );
412
413 if( selection == wxNOT_FOUND )
414 return false;
415
416 m_inheritanceSelectCombo->SetSelection( selection );
417 }
418
420 }
421
422 m_NoteBook->SetSelection( (unsigned) m_lastOpenedPage );
423
424 m_embeddedFiles->TransferDataToWindow();
425
426 return true;
427}
428
429
431{
432 if( !m_grid->CommitPendingChanges() )
433 return false;
434
435 // Symbol reference can be empty because it inherits from the parent symbol.
436 if( m_libEntry->IsRoot() )
437 {
438 SCH_FIELD* field = m_fields->GetField( FIELD_T::REFERENCE );
439
440 if( UTIL::GetRefDesPrefix( field->GetText() ).IsEmpty() )
441 {
442 if( m_NoteBook->GetSelection() != 0 )
443 m_NoteBook->SetSelection( 0 );
444
445 m_delayedErrorMessage = _( "References must start with a letter." );
450
451 return false;
452 }
453 }
454
455 // Check for missing field names.
456 for( int ii = 0; ii < (int) m_fields->size(); ++ii )
457 {
458 SCH_FIELD& field = m_fields->at( ii );
459
460 if( field.IsMandatory() )
461 continue;
462
463 wxString fieldName = field.GetName( false );
464
465 if( fieldName.IsEmpty() && !field.GetText().IsEmpty() )
466 {
467 if( m_NoteBook->GetSelection() != 0 )
468 m_NoteBook->SetSelection( 0 );
469
470 m_delayedErrorMessage = _( "Fields must have a name." );
475
476 return false;
477 }
478 }
479
480 // Verify that the parent name is set if the symbol is inherited
481 if( m_libEntry->IsDerived() )
482 {
483 wxString parentName = m_inheritanceSelectCombo->GetValue();
484
485 if( parentName.IsEmpty() )
486 {
487 m_delayedErrorMessage = _( "Derived symbol must have a parent selected" );
488 return false;
489 }
490 }
491
492 /*
493 * Confirm destructive actions.
494 */
495
496 if( m_unitSpinCtrl->GetValue() < m_libEntry->GetUnitCount() )
497 {
498 if( !IsOK( this, _( "Delete extra units from symbol?" ) ) )
499 return false;
500 }
501
502 int bodyStyleCount = 0;
503
504 if( m_radioSingle->GetValue() )
505 {
506 bodyStyleCount = 1;
507 }
508 if( m_radioDeMorgan->GetValue() )
509 {
510 bodyStyleCount = 2;
511 }
512 else if( m_radioCustom->GetValue() )
513 {
514 for( int ii = 0; ii < m_bodyStyleNamesGrid->GetNumberRows(); ++ii )
515 {
516 if( !m_bodyStyleNamesGrid->GetCellValue( ii, 0 ).IsEmpty() )
517 bodyStyleCount++;
518 }
519 }
520
521 if( bodyStyleCount == 0 )
522 {
523 m_delayedErrorMessage = _( "Symbol must have at least 1 body style" );
524 return false;
525 }
526
527 if( bodyStyleCount < m_libEntry->GetBodyStyleCount() )
528 {
529 if( !IsOK( this, _( "Delete extra body styles from symbol?" ) ) )
530 return false;
531 }
532
533 return true;
534}
535
536
538{
539 if( !m_grid->CommitPendingChanges()
540 || !m_unitNamesGrid->CommitPendingChanges()
541 || !m_bodyStyleNamesGrid->CommitPendingChanges()
542 || !m_jumperGroupsGrid->CommitPendingChanges()
543 || !m_embeddedFiles->TransferDataFromWindow() )
544 {
545 return false;
546 }
547
548 wxString newName = EscapeString( m_SymbolNameCtrl->GetValue(), CTX_LIBID );
549 wxString oldName = m_libEntry->GetName();
550
551 if( newName.IsEmpty() )
552 {
553 wxMessageBox( _( "Symbol must have a name." ) );
554 return false;
555 }
556
558
559 if( oldName != newName )
560 {
561 wxString libName = m_Parent->GetCurLib();
562
563 if( m_Parent->GetLibManager().SymbolNameInUse( newName, libName ) )
564 {
565 wxString msg;
566
567 msg.Printf( _( "Symbol name '%s' already in use in library '%s'." ),
568 UnescapeString( newName ),
569 libName );
570 DisplayErrorMessage( this, msg );
571 return false;
572 }
573
574 opType = UNDO_REDO::LIB_RENAME;
575 }
576
577 m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry, opType );
578
579 // The Y axis for components in lib is from bottom to top while the screen axis is top
580 // to bottom: we must change the y coord sign when writing back to the library
581 std::vector<SCH_FIELD> fieldsToSave;
582 int ordinal = 42; // Arbitrarily larger than any mandatory FIELD_T ids.
583
584 for( size_t ii = 0; ii < m_fields->size(); ++ii )
585 {
586 SCH_FIELD& field = m_fields->at( ii );
587
588 if( !field.IsMandatory() )
589 field.SetOrdinal( ordinal++ );
590
591 wxString fieldName = field.GetCanonicalName();
592
593 if( m_fields->IsInherited( ii ) && field == m_fields->ParentField( ii ) )
594 continue; // Skip inherited fields
595
596 if( field.GetText().IsEmpty() )
597 {
598 if( fieldName.IsEmpty() || m_addedTemplateFields.contains( fieldName ) )
599 continue; // Skip empty fields that are not mandatory or template fields
600 }
601 else if( fieldName.IsEmpty() )
602 {
603 field.SetName( _( "untitled" ) ); // Set a default name for unnamed fields
604 }
605
606 fieldsToSave.push_back( field );
607 }
608
609 m_libEntry->SetFields( fieldsToSave );
610
611 // Update the parent for inherited symbols
612 if( m_libEntry->IsDerived() )
613 {
614 wxString parentName = EscapeString( m_inheritanceSelectCombo->GetValue(), CTX_LIBID );
615
616 // The parentName was verified to be non-empty in the Validator
617 wxString libName = m_Parent->GetCurLib();
618
619 // Get the parent from the libManager based on the name set in the inheritance combo box.
620 LIB_SYMBOL* newParent = m_Parent->GetLibManager().GetSymbol( parentName, libName );
621
622 // Verify that the requested parent exists
623 wxCHECK( newParent, false );
624
625 m_libEntry->SetParent( newParent );
626 }
627
628 m_libEntry->SetName( newName );
629 m_libEntry->SetKeyWords( m_KeywordCtrl->GetValue() );
630 m_libEntry->SetUnitCount( m_unitSpinCtrl->GetValue(), true );
631 m_libEntry->LockUnits( m_libEntry->GetUnitCount() > 1 && !m_OptionPartsInterchangeable->GetValue() );
632
633 m_libEntry->GetUnitDisplayNames().clear();
634
635 for( int row = 0; row < m_unitNamesGrid->GetNumberRows(); row++ )
636 {
637 if( !m_unitNamesGrid->GetCellValue( row, 1 ).IsEmpty() )
638 m_libEntry->GetUnitDisplayNames()[row+1] = m_unitNamesGrid->GetCellValue( row, 1 );
639 }
640
641 if( m_radioSingle->GetValue() )
642 {
643 m_libEntry->SetHasDeMorganBodyStyles( false );
644 m_libEntry->SetBodyStyleCount( 1, false, false );
645 m_libEntry->SetBodyStyleNames( {} );
646 }
647 else if( m_radioDeMorgan->GetValue() )
648 {
649 m_libEntry->SetHasDeMorganBodyStyles( true );
650 m_libEntry->SetBodyStyleCount( 2, false, true );
651 m_libEntry->SetBodyStyleNames( {} );
652 }
653 else
654 {
655 std::vector<wxString> bodyStyleNames;
656
657 for( int row = 0; row < m_bodyStyleNamesGrid->GetNumberRows(); ++row )
658 {
659 if( !m_bodyStyleNamesGrid->GetCellValue( row, 0 ).IsEmpty() )
660 bodyStyleNames.push_back( m_bodyStyleNamesGrid->GetCellValue( row, 0 ) );
661 }
662
663 m_libEntry->SetHasDeMorganBodyStyles( false );
664 m_libEntry->SetBodyStyleCount( bodyStyleNames.size(), true, true );
665 m_libEntry->SetBodyStyleNames( bodyStyleNames );
666 }
667
668 if( m_OptionPower->GetValue() )
669 {
670 if( m_OptionLocalPower->GetValue() )
671 m_libEntry->SetLocalPower();
672 else
673 m_libEntry->SetGlobalPower();
674
675 // Power symbols must have value matching name for now
676 m_libEntry->GetValueField().SetText( newName );
677 }
678 else
679 {
680 m_libEntry->SetNormal();
681 }
682
683 m_libEntry->SetExcludedFromSim( m_excludeFromSimCheckBox->GetValue() );
684 m_libEntry->SetExcludedFromBOM( m_excludeFromBomCheckBox->GetValue() );
685 m_libEntry->SetExcludedFromBoard( m_excludeFromBoardCheckBox->GetValue() );
686 m_libEntry->SetExcludedFromPosFiles( m_excludeFromPosFilesCheckBox->GetValue() );
687
688 m_libEntry->SetShowPinNumbers( m_ShowPinNumButt->GetValue() );
689 m_libEntry->SetShowPinNames( m_ShowPinNameButt->GetValue() );
690
691 if( m_PinsNameInsideButt->GetValue() )
692 {
693 int offset = KiROUND( (double) m_pinNameOffset.GetValue() );
694
695 // We interpret an offset of 0 as "outside", so make sure it's non-zero
696 m_libEntry->SetPinNameOffset( offset == 0 ? 20 : offset );
697 }
698 else
699 {
700 m_libEntry->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
701 }
702
703 m_libEntry->SetFPFilters( m_FootprintFilterListBox->GetStrings());
704
705 m_libEntry->SetDuplicatePinNumbersAreJumpers( m_cbDuplicatePinsAreJumpers->GetValue() );
706
707 std::set<wxString> availablePins;
708
709 for( const SCH_PIN* pin : m_libEntry->GetGraphicalPins( 0, 0 ) )
710 availablePins.insert( pin->GetNumber() );
711
712 std::vector<std::set<wxString>>& jumpers = m_libEntry->JumperPinGroups();
713 jumpers.clear();
714
715 for( int ii = 0; ii < m_jumperGroupsGrid->GetNumberRows(); ++ii )
716 {
717 wxStringTokenizer tokenizer( m_jumperGroupsGrid->GetCellValue( ii, 0 ), ", \t\r\n", wxTOKEN_STRTOK );
718 std::set<wxString>& group = jumpers.emplace_back();
719
720 while( tokenizer.HasMoreTokens() )
721 {
722 wxString token = tokenizer.GetNextToken();
723
724 if( token.IsEmpty() )
725 continue;
726
727 if( !availablePins.count( token ) )
728 {
729 wxString msg;
730 msg.Printf( _( "Pin '%s' in jumper pin group %d does not exist in this symbol." ),
731 token, ii + 1 );
732 DisplayErrorMessage( this, msg );
733 return false;
734 }
735
736 group.insert( token );
737 }
738 }
739
740 m_Parent->UpdateAfterSymbolProperties( &oldName );
741
742 return true;
743}
744
745
746void DIALOG_LIB_SYMBOL_PROPERTIES::OnBodyStyle( wxCommandEvent& event )
747{
748 m_bodyStyleNamesGrid->Enable( m_radioCustom->GetValue() );
749
750 m_bpAddBodyStyle->Enable( m_radioCustom->GetValue() );
751 m_bpMoveUpBodyStyle->Enable( m_radioCustom->GetValue() );
752 m_bpMoveDownBodyStyle->Enable( m_radioCustom->GetValue() );
753 m_bpDeleteBodyStyle->Enable( m_radioCustom->GetValue() );
754}
755
756
758{
759 aEvent.Skip();
760
761 wxPoint pos = aEvent.GetPosition();
762 wxPoint unscolled_pos = m_grid->CalcUnscrolledPosition( pos );
763 int row = m_grid->YToRow( unscolled_pos.y );
764 int col = m_grid->XToCol( unscolled_pos.x );
765
766 if( row == wxNOT_FOUND || col == wxNOT_FOUND || !m_fields->IsInherited( row ) )
767 {
768 m_grid->SetToolTip( "" );
769 return;
770 }
771
772 m_grid->SetToolTip( wxString::Format( _( "This field is inherited from '%s'." ),
773 m_fields->ParentField( row ).GetName() ) );
774}
775
776
778{
779 wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
780 wxControl* control = editor->GetControl();
781
782 if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
783 {
784 event.Veto();
785
787 m_delayedFocusRow = event.GetRow();
788 m_delayedFocusColumn = event.GetCol();
790 }
791 else if( event.GetCol() == FDC_NAME )
792 {
793 wxString newName = event.GetString();
794
795 for( int i = 0; i < m_grid->GetNumberRows(); ++i )
796 {
797 if( i == event.GetRow() )
798 continue;
799
800 if( newName.CmpNoCase( m_grid->GetCellValue( i, FDC_NAME ) ) == 0 )
801 {
802 DisplayError( this, wxString::Format( _( "The name '%s' is already in use." ), newName ) );
803 event.Veto();
804 m_delayedFocusRow = event.GetRow();
805 m_delayedFocusColumn = event.GetCol();
806 }
807 }
808 }
809
810 editor->DecRef();
811}
812
813
815{
816 m_grid->ForceRefresh();
817 OnModify();
818}
819
820
822{
823 if( m_OptionPower->IsChecked() )
824 m_grid->SetCellValue( m_fields->GetFieldRow( FIELD_T::VALUE ), FDC_VALUE, m_SymbolNameCtrl->GetValue() );
825
826 OnModify();
827}
828
829
831{
832 if( !m_delayedFocusCtrl )
833 {
834 // If the validation fails and we throw up a dialog then GTK will give us another
835 // KillFocus event and we end up in infinite recursion. So we use m_delayedFocusCtrl
836 // as a re-entrancy block and then clear it again if validation passes.
839
840 if( m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
841 {
842 m_delayedFocusCtrl = nullptr;
844 }
845 }
846
847 event.Skip();
848}
849
850
851void DIALOG_LIB_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
852{
853 m_grid->OnAddRow(
854 [&]() -> std::pair<int, int>
855 {
856 SYMBOL_EDITOR_SETTINGS* settings = m_Parent->GetSettings();
858
859 newField.SetTextSize( VECTOR2I( schIUScale.MilsToIU( settings->m_Defaults.text_size ),
860 schIUScale.MilsToIU( settings->m_Defaults.text_size ) ) );
861 newField.SetVisible( false );
862
863 m_fields->push_back( newField );
864
865 // notify the grid
866 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
867 m_grid->ProcessTableMessage( msg );
868 OnModify();
869
870 return { m_fields->size() - 1, FDC_NAME };
871 } );
872}
873
874
876{
877 m_grid->OnDeleteRows(
878 [&]( int row )
879 {
880 if( row < m_fields->GetMandatoryRowCount() )
881 {
882 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
883 m_fields->GetMandatoryRowCount() ) );
884 return false;
885 }
886
887 return true;
888 },
889 [&]( int row )
890 {
891 if( !m_fields->EraseRow( row ) )
892 return;
893
894 // notify the grid
895 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
896 m_grid->ProcessTableMessage( msg );
897 } );
898
899 OnModify();
900}
901
902
903void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
904{
905 m_grid->OnMoveRowUp(
906 [&]( int row )
907 {
908 return row > m_fields->GetMandatoryRowCount();
909 },
910 [&]( int row )
911 {
912 m_fields->SwapRows( row, row - 1 );
913 m_grid->ForceRefresh();
914 OnModify();
915 } );
916}
917
918
919void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
920{
921 m_grid->OnMoveRowDown(
922 [&]( int row )
923 {
924 return row >= m_fields->GetMandatoryRowCount();
925 },
926 [&]( int row )
927 {
928 m_fields->SwapRows( row, row + 1 );
929 m_grid->ForceRefresh();
930 OnModify();
931 } );
932}
933
934
936{
937 m_bodyStyleNamesGrid->OnAddRow(
938 [&]() -> std::pair<int, int>
939 {
940 m_bodyStyleNamesGrid->AppendRows( 1 );
941 OnModify();
942
943 return { m_bodyStyleNamesGrid->GetNumberRows() - 1, 0 };
944 } );
945}
946
947
949{
950 m_bodyStyleNamesGrid->OnDeleteRows(
951 [&]( int row )
952 {
953 m_bodyStyleNamesGrid->DeleteRows( row );
954 } );
955
956 OnModify();
957}
958
959
961{
962 m_bodyStyleNamesGrid->OnMoveRowUp(
963 [&]( int row )
964 {
965 m_bodyStyleNamesGrid->SwapRows( row, row - 1 );
966 OnModify();
967 } );
968}
969
970
972{
973 m_bodyStyleNamesGrid->OnMoveRowDown(
974 [&]( int row )
975 {
976 m_bodyStyleNamesGrid->SwapRows( row, row + 1 );
977 OnModify();
978 } );
979}
980
981
983{
984 if( !m_grid->CommitPendingChanges() )
985 return;
986
987 m_grid->ClearSelection();
988
989 std::vector<SCH_FIELD> fields;
990
991 for( const SCH_FIELD& field : *m_fields )
992 fields.emplace_back( field );
993
994 DIALOG_SIM_MODEL dialog( this, m_parentFrame, *m_libEntry, fields );
995
996 if( dialog.ShowModal() != wxID_OK )
997 return;
998
999 // Add in any new fields
1000 for( const SCH_FIELD& editedField : fields )
1001 {
1002 bool found = false;
1003
1004 for( SCH_FIELD& existingField : *m_fields )
1005 {
1006 if( existingField.GetName() == editedField.GetName() )
1007 {
1008 found = true;
1009 existingField.SetText( editedField.GetText() );
1010 break;
1011 }
1012 }
1013
1014 if( !found )
1015 {
1016 m_fields->emplace_back( editedField );
1017 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
1018 m_grid->ProcessTableMessage( msg );
1019 }
1020 }
1021
1022 // Remove any deleted fields
1023 for( int ii = (int) m_fields->size() - 1; ii >= 0; --ii )
1024 {
1025 SCH_FIELD& existingField = m_fields->at( ii );
1026 bool found = false;
1027
1028 for( SCH_FIELD& editedField : fields )
1029 {
1030 if( editedField.GetName() == existingField.GetName() )
1031 {
1032 found = true;
1033 break;
1034 }
1035 }
1036
1037 if( !found )
1038 {
1039 m_grid->ClearSelection();
1040 m_fields->erase( m_fields->begin() + ii );
1041
1042 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, ii, 1 );
1043 m_grid->ProcessTableMessage( msg );
1044 }
1045 }
1046
1047 OnModify();
1048 m_grid->ForceRefresh();
1049}
1050
1051
1053{
1054 int idx = m_FootprintFilterListBox->HitTest( event.GetPosition() );
1055 wxCommandEvent dummy;
1056
1057 if( idx >= 0 )
1059 else
1061}
1062
1063
1065{
1066 // Running the Footprint Browser gums up the works and causes the automatic cancel
1067 // stuff to no longer work. So we do it here ourselves.
1068 EndQuasiModal( wxID_CANCEL );
1069}
1070
1071
1073{
1074 wxString filterLine;
1075 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Add Footprint Filter" ), filterLine );
1076
1077 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue().IsEmpty() )
1078 return;
1079
1080 filterLine = dlg.GetValue();
1081 filterLine.Replace( wxT( " " ), wxT( "_" ) );
1082
1083 // duplicate filters do no harm, so don't be a nanny.
1084 m_FootprintFilterListBox->Append( filterLine );
1085 m_FootprintFilterListBox->SetSelection( (int) m_FootprintFilterListBox->GetCount() - 1 );
1086
1087 OnModify();
1088}
1089
1090
1092{
1093 wxArrayInt selections;
1094 int n = m_FootprintFilterListBox->GetSelections( selections );
1095
1096 if( n > 0 )
1097 {
1098 // Just edit the first one
1099 int idx = selections[0];
1100 wxString filter = m_FootprintFilterListBox->GetString( idx );
1101
1102 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Edit Footprint Filter" ), filter );
1103
1104 if( dlg.ShowModal() == wxID_OK && !dlg.GetValue().IsEmpty() )
1105 {
1106 m_FootprintFilterListBox->SetString( (unsigned) idx, dlg.GetValue() );
1107 OnModify();
1108 }
1109 }
1110}
1111
1112
1113void DIALOG_LIB_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
1114{
1115 m_OptionPartsInterchangeable->Enable( m_unitSpinCtrl->GetValue() > 1 );
1116 m_pinNameOffset.Enable( m_PinsNameInsideButt->GetValue() );
1117
1118 if( m_grid->IsCellEditControlShown() )
1119 {
1120 int row = m_grid->GetGridCursorRow();
1121 int col = m_grid->GetGridCursorCol();
1122
1123 if( row == m_fields->GetFieldRow( FIELD_T::VALUE ) && col == FDC_VALUE && m_OptionPower->IsChecked() )
1124 {
1125 wxGridCellEditor* editor = m_grid->GetCellEditor( row, col );
1126 m_SymbolNameCtrl->ChangeValue( editor->GetValue() );
1127 editor->DecRef();
1128 }
1129 }
1130
1131 // Handle shown columns changes
1132 std::bitset<64> shownColumns = m_grid->GetShownColumns();
1133
1134 if( shownColumns != m_shownColumns )
1135 {
1136 m_shownColumns = shownColumns;
1137
1138 if( !m_grid->IsCellEditControlShown() )
1139 m_grid->SetGridWidthsDirty();
1140 }
1141
1142 // Handle a delayed focus. The delay allows us to:
1143 // a) change focus when the error was triggered from within a killFocus handler
1144 // b) show the correct notebook page in the background before the error dialog comes up
1145 // when triggered from an OK or a notebook page change
1146
1147 if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
1148 {
1149 m_NoteBook->ChangeSelection( (unsigned) m_delayedFocusPage );
1150 m_delayedFocusPage = -1;
1151 }
1152
1153 if( !m_delayedErrorMessage.IsEmpty() )
1154 {
1155 // We will re-enter this routine when the error dialog is displayed, so make
1156 // sure we don't keep putting up more dialogs.
1157 wxString msg = m_delayedErrorMessage;
1158 m_delayedErrorMessage = wxEmptyString;
1159
1160 // Do not use DisplayErrorMessage(); it screws up window order on Mac
1161 DisplayError( nullptr, msg );
1162 }
1163
1164 if( m_delayedFocusCtrl )
1165 {
1166 m_delayedFocusCtrl->SetFocus();
1167
1168 if( wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
1169 textEntry->SelectAll();
1170
1171 m_delayedFocusCtrl = nullptr;
1172 }
1173 else if( m_delayedFocusGrid )
1174 {
1175 m_delayedFocusGrid->SetFocus();
1178
1179 m_delayedFocusGrid->EnableCellEditControl( true );
1180 m_delayedFocusGrid->ShowCellEditControl();
1181
1182 m_delayedFocusGrid = nullptr;
1183 m_delayedFocusRow = -1;
1185 }
1186}
1187
1188
1190{
1191 bSizerLowerBasicPanel->Show( !aIsAlias );
1192 m_inheritanceSelectCombo->Enable( aIsAlias );
1193 m_inheritsStaticText->Enable( aIsAlias );
1194 m_grid->ForceRefresh();
1195}
1196
1197
1199{
1200 if( m_OptionPower->IsChecked() )
1201 {
1202 m_excludeFromSimCheckBox->SetValue( true );
1203 m_excludeFromBomCheckBox->SetValue( true );
1204 m_excludeFromBoardCheckBox->SetValue( true );
1205 m_excludeFromPosFilesCheckBox->SetValue( true );
1206 m_excludeFromBomCheckBox->Enable( false );
1207 m_excludeFromBoardCheckBox->Enable( false );
1208 m_excludeFromSimCheckBox->Enable( false );
1209 m_excludeFromPosFilesCheckBox->Enable( false );
1210 m_spiceFieldsButton->Show( false );
1211 m_OptionLocalPower->Enable( true );
1212 }
1213 else
1214 {
1215 m_excludeFromBomCheckBox->Enable( true );
1216 m_excludeFromBoardCheckBox->Enable( true );
1217 m_excludeFromSimCheckBox->Enable( true );
1218 m_excludeFromPosFilesCheckBox->Enable( true );
1219 m_spiceFieldsButton->Show( true );
1220 m_OptionLocalPower->Enable( false );
1221 }
1222
1223 OnModify();
1224}
1225
1226
1227void DIALOG_LIB_SYMBOL_PROPERTIES::OnText( wxCommandEvent& event )
1228{
1229 OnModify();
1230}
1231
1232
1233void DIALOG_LIB_SYMBOL_PROPERTIES::OnCombobox( wxCommandEvent& event )
1234{
1235 OnModify();
1236}
1237
1238
1239void DIALOG_LIB_SYMBOL_PROPERTIES::OnCheckBox( wxCommandEvent& event )
1240{
1241 OnModify();
1242}
1243
1244
1246{
1247 m_unitNamesGrid->CommitPendingChanges( true /* aQuietMode */ );
1248
1249 int extra = m_unitNamesGrid->GetNumberRows() - m_unitSpinCtrl->GetValue();
1250 int needed = m_unitSpinCtrl->GetValue() - m_unitNamesGrid->GetNumberRows();
1251
1252 if( extra > 0 )
1253 {
1254 m_unitNamesGrid->DeleteRows( m_unitNamesGrid->GetNumberRows() - extra, extra );
1255 return true;
1256 }
1257
1258 if( needed > 0 )
1259 {
1260 m_unitNamesGrid->AppendRows( needed );
1261
1262 for( int row = m_unitNamesGrid->GetNumberRows() - needed; row < m_unitNamesGrid->GetNumberRows(); ++row )
1263 m_unitNamesGrid->SetCellValue( row, 0, LIB_SYMBOL::LetterSubReference( row + 1, 'A' ) );
1264
1265 return true;
1266 }
1267
1268 return false;
1269}
1270
1271
1273{
1274 if( updateUnitCount() )
1275 OnModify();
1276}
1277
1278
1280{
1281 // wait for kill focus to update unit count
1282}
1283
1284
1286{
1287 if( updateUnitCount() )
1288 OnModify();
1289}
1290
1291
1293{
1294 if( updateUnitCount() )
1295 OnModify();
1296}
1297
1298
1300{
1301 if( !m_grid->CommitPendingChanges() )
1302 aEvent.Veto();
1303}
1304
1305
1307{
1308 m_jumperGroupsGrid->OnAddRow(
1309 [&]() -> std::pair<int, int>
1310 {
1311 m_jumperGroupsGrid->AppendRows( 1 );
1312 OnModify();
1313
1314 return { m_jumperGroupsGrid->GetNumberRows() - 1, 0 };
1315 } );
1316}
1317
1318
1320{
1321 m_jumperGroupsGrid->OnDeleteRows(
1322 [&]( int row )
1323 {
1324 m_jumperGroupsGrid->DeleteRows( row, 1 );
1325 } );
1326
1327 OnModify();
1328}
1329
1330
const char * name
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:114
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:110
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:990
DIALOG_LIB_SYMBOL_PROPERTIES_BASE(wxWindow *parent, wxWindowID id=ID_LIBEDIT_NOTEBOOK, const wxString &title=_("Library Symbol Properties"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
void OnSymbolNameKillFocus(wxFocusEvent &event) override
void OnUnitSpinCtrlText(wxCommandEvent &event) override
std::unique_ptr< LISTBOX_TRICKS > m_fpFilterTricks
void OnPageChanging(wxNotebookEvent &event) override
void OnBodyStyle(wxCommandEvent &event) override
DIALOG_LIB_SYMBOL_PROPERTIES(SYMBOL_EDIT_FRAME *parent, LIB_SYMBOL *aLibEntry)
void OnUpdateUI(wxUpdateUIEvent &event) override
void OnBodyStyleMoveUp(wxCommandEvent &event) override
void OnCancelButtonClick(wxCommandEvent &event) override
void OnEditFootprintFilter(wxCommandEvent &event) override
void OnDeleteField(wxCommandEvent &event) override
void OnCombobox(wxCommandEvent &event) override
void OnFpFilterDClick(wxMouseEvent &event) override
void OnUnitSpinCtrlEnter(wxCommandEvent &event) override
void OnAddBodyStyle(wxCommandEvent &event) override
void OnMoveUp(wxCommandEvent &event) override
void OnDeleteBodyStyle(wxCommandEvent &event) override
void OnAddJumperGroup(wxCommandEvent &event) override
void OnText(wxCommandEvent &event) override
void OnUnitSpinCtrlKillFocus(wxFocusEvent &event) override
void OnMoveDown(wxCommandEvent &event) override
void OnAddFootprintFilter(wxCommandEvent &event) override
void OnCheckBox(wxCommandEvent &event) override
void OnSymbolNameText(wxCommandEvent &event) override
void OnBodyStyleMoveDown(wxCommandEvent &event) override
void OnRemoveJumperGroup(wxCommandEvent &event) override
void onPowerCheckBox(wxCommandEvent &aEvent) override
void OnAddField(wxCommandEvent &event) override
void OnEditSpiceModel(wxCommandEvent &event) override
void addInheritedFields(const std::shared_ptr< LIB_SYMBOL > &aParent)
void OnUnitSpinCtrl(wxSpinEvent &event) override
void EndQuasiModal(int retCode)
EDA_BASE_FRAME * m_parentFrame
int ShowModal() override
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition eda_text.cpp:546
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:400
void push_back(const SCH_FIELD &field)
A text control validator used for validating the text allowed in fields.
Definition validators.h:142
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition grid_tricks.h:61
Define a library symbol object.
Definition lib_symbol.h:83
static wxString LetterSubReference(int aUnit, wxChar aInitialLetter)
void SetOrdinal(int aOrdinal)
Definition sch_field.h:126
bool IsMandatory() const
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:116
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
void SetName(const wxString &aName)
The symbol library editor main window.
void AddTemplateFieldNames(const wxString &aSerializedFieldNames)
Add a serialized list of template field names.
const std::vector< TEMPLATE_FIELDNAME > & GetTemplateFieldNames()
Return a template field name list for read only access.
A KICAD version of wxTextEntryDialog which supports the various improvements/work-arounds from DIALOG...
wxString GetValue() const
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition confirm.cpp:259
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:202
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:177
This file is part of the common library.
#define _(s)
@ FDC_NAME
@ FDC_VALUE
wxString GetRefDesPrefix(const wxString &aRefDes)
Get the (non-numeric) prefix from a refdes - e.g.
STL namespace.
see class PGM_BASE
Collection of utility functions for component reference designators (refdes)
T * GetAppSettings(const char *aFilename)
std::vector< FAB_LAYER_COLOR > dummy
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
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_LIBID
Hold a name of a symbol's field, field value, and default visibility.
wxString GetUserFieldName(int aFieldNdx, bool aTranslateForHI)
#define DO_TRANSLATE
@ USER
The field ID hasn't been set yet; field is invalid.
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
KIBIS_PIN * pin
UNDO_REDO
Undo Redo considerations: Basically we have 3 cases New item Deleted item Modified item there is also...
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695