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