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