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 (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
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
49
50#include <wx/clipbrd.h>
51#include <wx/msgdlg.h>
52
53
57
58
60 LIB_SYMBOL* aLibEntry ) :
62 m_Parent( aParent ),
63 m_libEntry( aLibEntry ),
64 m_pinNameOffset( aParent, m_nameOffsetLabel, m_nameOffsetCtrl, m_nameOffsetUnits, true ),
65 m_delayedFocusCtrl( nullptr ),
66 m_delayedFocusGrid( nullptr ),
67 m_delayedFocusRow( -1 ),
68 m_delayedFocusColumn( -1 ),
69 m_delayedFocusPage( -1 ),
70 m_fpFilterTricks( std::make_unique<LISTBOX_TRICKS>( *this, *m_FootprintFilterListBox ) )
71{
73 m_NoteBook->AddPage( m_embeddedFiles, _( "Embedded Files" ) );
74
75 // Give a bit more room for combobox editors
76 m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
77 m_fields = new FIELDS_GRID_TABLE( this, aParent, m_grid, m_libEntry );
79 m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this, aLibEntry,
80 [&]( wxCommandEvent& aEvent )
81 {
82 OnAddField( aEvent );
83 } ) );
84 m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
85
86 // Show/hide columns according to the user's preference
89
90 wxGridCellAttr* attr = new wxGridCellAttr;
91 attr->SetEditor( new GRID_CELL_URL_EDITOR( this, PROJECT_SCH::SchSearchS( &Prj() ), aLibEntry ) );
92 m_grid->SetAttr( DATASHEET_FIELD, FDC_VALUE, attr );
93
95
96 // Configure button logos
97 m_bpAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
98 m_bpDelete->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
99 m_bpMoveUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
100 m_bpMoveDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
101 m_addFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
102 m_deleteFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
103 m_editFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_edit ) );
104
106
107 if( aParent->IsSymbolFromLegacyLibrary() && !aParent->IsSymbolFromSchematic() )
108 {
109 m_stdSizerButtonCancel->SetDefault();
110 m_stdSizerButtonOK->SetLabel( _( "Read Only" ) );
111 m_stdSizerButtonOK->Enable( false );
112 }
113
114 // wxFormBuilder doesn't include this event...
115 m_grid->Connect( wxEVT_GRID_CELL_CHANGING,
117 nullptr, this );
118
119 // Forward the delete button to the tricks
120 m_deleteFilterButton->Bind( wxEVT_BUTTON,
121 [&]( wxCommandEvent& aEvent )
122 {
123 wxCommandEvent cmdEvent( EDA_EVT_LISTBOX_DELETE );
124 m_fpFilterTricks->ProcessEvent( cmdEvent );
125 } );
126
127 // When the filter tricks modifies something, update outselves
128 m_FootprintFilterListBox->Bind( EDA_EVT_LISTBOX_CHANGED,
129 [&]( wxCommandEvent& aEvent )
130 {
131 OnModify();
132 } );
133
135 {
137 && aLibEntry->IsRoot() )
139 && aLibEntry->IsAlias() ) )
140 {
141 resetSize();
142 }
143 }
144
147
148 m_grid->GetParent()->Layout();
150 Layout();
151
153}
154
155
157{
158 m_lastOpenedPage = m_NoteBook->GetSelection( );
159
161 cfg->m_EditSymbolVisibleColumns = m_grid->GetShownColumnsAsString();
162
163 // Prevents crash bug in wxGrid's d'tor
165
166 m_grid->Disconnect( wxEVT_GRID_CELL_CHANGING,
168 nullptr, this );
169
170 // Delete the GRID_TRICKS.
171 m_grid->PopEventHandler( true );
172}
173
174
176{
177 if( !wxDialog::TransferDataToWindow() )
178 return false;
179
180 // Push a copy of each field into m_updateFields
182
183 std::set<wxString> defined;
184
185 for( SCH_FIELD& field : *m_fields )
186 defined.insert( field.GetName() );
187
188 // Add in any template fieldnames not yet defined:
189 // Read global fieldname templates
191 EESCHEMA_SETTINGS* cfg = mgr.GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
192
193 if( cfg )
194 {
195 TEMPLATES templateMgr;
196
197 if( !cfg->m_Drawing.field_names.IsEmpty() )
198 templateMgr.AddTemplateFieldNames( cfg->m_Drawing.field_names );
199
200 for( const TEMPLATE_FIELDNAME& templateFieldname : templateMgr.GetTemplateFieldNames() )
201 {
202 if( defined.count( templateFieldname.m_Name ) <= 0 )
203 {
204 SCH_FIELD field( VECTOR2I( 0, 0 ), -1, m_libEntry, templateFieldname.m_Name );
205 field.SetVisible( templateFieldname.m_Visible );
206 m_fields->push_back( field );
207 m_addedTemplateFields.insert( templateFieldname.m_Name );
208 }
209 }
210 }
211
212 // The Y axis for components in lib is from bottom to top while the screen axis is top
213 // to bottom: we must change the y coord sign for editing
214 for( size_t i = 0; i < m_fields->size(); ++i )
215 {
216 VECTOR2I pos = m_fields->at( i ).GetPosition();
217 pos.y = -pos.y;
218 m_fields->at( i ).SetPosition( pos );
219 }
220
221 // notify the grid
222 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->GetNumberRows() );
223 m_grid->ProcessTableMessage( msg );
225
227
228 m_KeywordCtrl->ChangeValue( m_libEntry->GetKeyWords() );
231 m_libEntry->GetUnitCount() == 1 );
232
233 // If a symbol contains no body-style-specific pins or graphic items,
234 // symbol->HasAlternateBodyStyle() will return false.
235 // But when editing a symbol with DeMorgan option set, we don't want to keep turning it off
236 // just because there aren't any body-style-specific items yet, so we force it to on if the
237 // parent frame has it enabled.
239
240 m_OptionPower->SetValue( m_libEntry->IsPower() );
241
242 if( m_libEntry->IsPower() )
243 m_spiceFieldsButton->Hide();
244
248
253
254 wxArrayString tmp = m_libEntry->GetFPFilters();
255 m_FootprintFilterListBox->Append( tmp );
256
257 // Populate the list of root parts for inherited objects.
258 if( m_libEntry->IsAlias() )
259 {
260 wxArrayString symbolNames;
261 wxString libName = m_Parent->GetCurLib();
262
263 // Someone forgot to set the current library in the editor frame window.
264 wxCHECK( !libName.empty(), false );
265
266 m_Parent->GetLibManager().GetSymbolNames( libName, symbolNames );
267
268 // Do allow an inherited symbol to be derived from itself.
269 symbolNames.Remove( m_libEntry->GetName() );
270 m_inheritanceSelectCombo->Append( symbolNames );
271
272 if( LIB_SYMBOL_SPTR rootSymbol = m_libEntry->GetParent().lock() )
273 {
274 wxString parentName = UnescapeString( rootSymbol->GetName() );
275 int selection = m_inheritanceSelectCombo->FindString( parentName );
276
277 if( selection == wxNOT_FOUND )
278 return false;
279
280 m_inheritanceSelectCombo->SetSelection( selection );
281 }
282
284 }
285
286 m_NoteBook->SetSelection( (unsigned) m_lastOpenedPage );
287
289
290 return true;
291}
292
293
295{
297 return false;
298
299 // Alias symbol reference can be empty because it inherits from the parent symbol.
300 if( m_libEntry->IsRoot()
301 && UTIL::GetRefDesPrefix( m_fields->at( REFERENCE_FIELD ).GetText() ).IsEmpty() )
302 {
303 if( m_NoteBook->GetSelection() != 0 )
304 m_NoteBook->SetSelection( 0 );
305
306 m_delayedErrorMessage = _( "References must start with a letter." );
311
312 return false;
313 }
314
315 // Check for missing field names.
316 for( int ii = MANDATORY_FIELDS; ii < (int) m_fields->size(); ++ii )
317 {
318 SCH_FIELD& field = m_fields->at( ii );
319 wxString fieldName = field.GetName( false );
320
321 if( fieldName.IsEmpty() && !field.GetText().IsEmpty() )
322 {
323 if( m_NoteBook->GetSelection() != 0 )
324 m_NoteBook->SetSelection( 0 );
325
326 m_delayedErrorMessage = _( "Fields must have a name." );
331
332 return false;
333 }
334 }
335
336 // Verify that the parent name is set if the symbol is inherited
337 if( m_libEntry->IsAlias() )
338 {
339 wxString parentName = m_inheritanceSelectCombo->GetValue();
340
341 if( parentName.IsEmpty() )
342 {
343 m_delayedErrorMessage = _( "Derived symbol must have a parent selected" );
344
345 return false;
346 }
347 }
348
349 /*
350 * Confirm destructive actions.
351 */
352
353 if( m_SelNumberOfUnits->GetValue() < m_libEntry->GetUnitCount() )
354 {
355 if( !IsOK( this, _( "Delete extra units from symbol?" ) ) )
356 return false;
357 }
358
360 {
361 if( !IsOK( this, _( "Delete alternate body style (De Morgan) from symbol?" ) ) )
362 return false;
363 }
364
365 return true;
366}
367
368
370{
371 if( !wxDialog::TransferDataFromWindow() )
372 return false;
373
375 return false;
376
377 wxString newName = EscapeString( m_SymbolNameCtrl->GetValue(), CTX_LIBID );
378 wxString oldName = m_libEntry->GetName();
379
380 if( newName.IsEmpty() )
381 {
382 wxMessageBox( _( "Symbol must have a name." ) );
383 return false;
384 }
385
386 if( oldName != newName )
387 {
388 wxString libName = m_Parent->GetCurLib();
389
390 if( m_Parent->GetLibManager().SymbolExists( newName, libName ) )
391 {
392 wxString msg;
393
394 msg.Printf( _( "Symbol name '%s' already in use in library '%s'." ),
395 UnescapeString( newName ),
396 libName );
397 DisplayErrorMessage( this, msg );
398 return false;
399 }
400
401 m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry,
402 UNDO_REDO::LIB_RENAME );
403 }
404 else
405 {
406 m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry );
407 }
408
409 // The Y axis for components in lib is from bottom to top while the screen axis is top
410 // to bottom: we must change the y coord sign when writing back to the library
411 for( int ii = 0; ii < (int) m_fields->size(); ++ii )
412 {
413 VECTOR2I pos = m_fields->at( ii ).GetPosition();
414 pos.y = -pos.y;
415 m_fields->at( ii ).SetPosition( pos );
416 m_fields->at( ii ).SetId( ii );
417 }
418
419 for( int ii = m_fields->GetNumberRows() - 1; ii >= MANDATORY_FIELDS; ii-- )
420 {
421 SCH_FIELD& field = m_fields->at( ii );
422 const wxString& fieldName = field.GetCanonicalName();
423
424 if( field.GetText().IsEmpty() )
425 {
426 if( fieldName.IsEmpty() || m_addedTemplateFields.contains( fieldName ) )
427 m_fields->erase( m_fields->begin() + ii );
428 }
429 else if( fieldName.IsEmpty() )
430 {
431 field.SetName( _( "untitled" ) );
432 }
433 }
434
436
437 // Update the parent for inherited symbols
438 if( m_libEntry->IsAlias() )
439 {
440 wxString parentName = EscapeString( m_inheritanceSelectCombo->GetValue(), CTX_LIBID );
441
442 // The parentName was verified to be non-empty in the Validator
443 wxString libName = m_Parent->GetCurLib();
444
445 // Get the parent from the libManager based on the name set in the inheritance combo box.
446 LIB_SYMBOL* newParent = m_Parent->GetLibManager().GetAlias( parentName, libName );
447
448 // Verify that the requested parent exists
449 wxCHECK( newParent, false );
450
451 m_libEntry->SetParent( newParent );
452 }
453
454 m_libEntry->SetName( newName );
455 m_libEntry->SetKeyWords( m_KeywordCtrl->GetValue() );
458 !m_OptionPartsInterchangeable->GetValue() );
461
462 if( m_OptionPower->GetValue() )
463 {
465 // Power symbols must have value matching name for now
466 m_libEntry->GetValueField().SetText( newName );
467 }
468 else
469 {
471 }
472
476
479
480 if( m_PinsNameInsideButt->GetValue() )
481 {
482 int offset = KiROUND( (double) m_pinNameOffset.GetValue() );
483
484 // We interpret an offset of 0 as "outside", so make sure it's non-zero
485 m_libEntry->SetPinNameOffset( offset == 0 ? 20 : offset );
486 }
487 else
488 {
489 m_libEntry->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
490 }
491
493
495
496 // It's possible that the symbol being edited has no pins, in which case there may be no
497 // alternate body style objects causing #LIB_SYMBOL::HasAlternateBodyStyle() to always return
498 // false. This allows the user to edit the alternate body style just in case this condition
499 // occurs.
501
503 return true;
504}
505
506
508{
509 wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
510 wxControl* control = editor->GetControl();
511
512 if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
513 {
514 event.Veto();
515
517 m_delayedFocusRow = event.GetRow();
518 m_delayedFocusColumn = event.GetCol();
520 }
521 else if( event.GetCol() == FDC_NAME )
522 {
523 wxString newName = event.GetString();
524
525 for( int i = 0; i < m_grid->GetNumberRows(); ++i )
526 {
527 if( i == event.GetRow() )
528 continue;
529
530 if( newName.CmpNoCase( m_grid->GetCellValue( i, FDC_NAME ) ) == 0 )
531 {
532 DisplayError( this, wxString::Format( _( "The name '%s' is already in use." ),
533 newName ) );
534 event.Veto();
535 m_delayedFocusRow = event.GetRow();
536 m_delayedFocusColumn = event.GetCol();
537 }
538 }
539 }
540
541 editor->DecRef();
542}
543
544
546{
547 if( m_OptionPower->IsChecked() )
548 m_grid->SetCellValue( VALUE_FIELD, FDC_VALUE, m_SymbolNameCtrl->GetValue() );
549
550 OnModify();
551}
552
553
555{
556 if( !m_delayedFocusCtrl )
557 {
558 // If the validation fails and we throw up a dialog then GTK will give us another
559 // KillFocus event and we end up in infinite recursion. So we use m_delayedFocusCtrl
560 // as a re-entrancy block and then clear it again if validation passes.
563
564 if( m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
565 {
566 m_delayedFocusCtrl = nullptr;
568 }
569 }
570
571 event.Skip();
572}
573
574
575void DIALOG_LIB_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
576{
578 return;
579
581 int fieldID = (int) m_fields->size();
582 SCH_FIELD newField( m_libEntry, fieldID );
583
585 schIUScale.MilsToIU( settings->m_Defaults.text_size ) ) );
586
587 m_fields->push_back( newField );
588
589 // notify the grid
590 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
591 m_grid->ProcessTableMessage( msg );
592
593 m_grid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
594 m_grid->SetGridCursor( (int) m_fields->size() - 1, 0 );
595
596 m_grid->EnableCellEditControl();
597 m_grid->ShowCellEditControl();
598
599 OnModify();
600}
601
602
604{
605 wxArrayInt selectedRows = m_grid->GetSelectedRows();
606
607 if( selectedRows.empty() && m_grid->GetGridCursorRow() >= 0 )
608 selectedRows.push_back( m_grid->GetGridCursorRow() );
609
610 if( selectedRows.empty() )
611 return;
612
613 for( int row : selectedRows )
614 {
615 if( row < MANDATORY_FIELDS )
616 {
617 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
619 return;
620 }
621 }
622
623 m_grid->CommitPendingChanges( true /* quiet mode */ );
624 m_grid->ClearSelection();
625
626 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
627 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
628
629 for( int row : selectedRows )
630 {
631 m_fields->erase( m_fields->begin() + row );
632
633 // notify the grid
634 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
635 m_grid->ProcessTableMessage( msg );
636
637 if( m_grid->GetNumberRows() > 0 )
638 {
639 m_grid->MakeCellVisible( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
640 m_grid->SetGridCursor( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
641 }
642 }
643
644 OnModify();
645}
646
647
648void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
649{
651 return;
652
653 int i = m_grid->GetGridCursorRow();
654
655 if( i > MANDATORY_FIELDS )
656 {
657 SCH_FIELD tmp = m_fields->at( (unsigned) i );
658 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
659 m_fields->insert( m_fields->begin() + i - 1, tmp );
660 m_grid->ForceRefresh();
661
662 m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
663 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
664
665 OnModify();
666 }
667 else
668 {
669 wxBell();
670 }
671}
672
673
674void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
675{
677 return;
678
679 int i = m_grid->GetGridCursorRow();
680
681 if( i >= MANDATORY_FIELDS && i + 1 < m_fields->GetNumberRows() )
682 {
683 SCH_FIELD tmp = m_fields->at( (unsigned) i );
684 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
685 m_fields->insert( m_fields->begin() + i + 1, tmp );
686 m_grid->ForceRefresh();
687
688 m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
689 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
690
691 OnModify();
692 }
693 else
694 {
695 wxBell();
696 }
697}
698
699
701{
703 return;
704
705 std::vector<SCH_FIELD> fields;
706
707 for( const SCH_FIELD& field : *m_fields )
708 fields.emplace_back( field );
709
710 DIALOG_SIM_MODEL dialog( this, m_parentFrame, *m_libEntry, fields );
711
712 if( dialog.ShowModal() != wxID_OK )
713 return;
714
715 // Add in any new fields
716 for( const SCH_FIELD& editedField : fields )
717 {
718 bool found = false;
719
720 for( SCH_FIELD& existingField : *m_fields )
721 {
722 if( existingField.GetName() == editedField.GetName() )
723 {
724 found = true;
725 existingField.SetText( editedField.GetText() );
726 break;
727 }
728 }
729
730 if( !found )
731 {
732 m_fields->emplace_back( editedField );
733 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
734 m_grid->ProcessTableMessage( msg );
735 }
736 }
737
738 // Remove any deleted fields
739 for( int ii = (int) m_fields->size() - 1; ii >= 0; --ii )
740 {
741 SCH_FIELD& existingField = m_fields->at( ii );
742 bool found = false;
743
744 for( SCH_FIELD& editedField : fields )
745 {
746 if( editedField.GetName() == existingField.GetName() )
747 {
748 found = true;
749 break;
750 }
751 }
752
753 if( !found )
754 {
755 m_fields->erase( m_fields->begin() + ii );
756 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, ii, 1 );
757 m_grid->ProcessTableMessage( msg );
758 }
759 }
760
761 OnModify();
762 m_grid->ForceRefresh();
763}
764
765
767{
768 int idx = m_FootprintFilterListBox->HitTest( event.GetPosition() );
769 wxCommandEvent dummy;
770
771 if( idx >= 0 )
773 else
775}
776
777
779{
780 // Running the Footprint Browser gums up the works and causes the automatic cancel
781 // stuff to no longer work. So we do it here ourselves.
782 EndQuasiModal( wxID_CANCEL );
783}
784
785
787{
788 wxString filterLine;
789 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Add Footprint Filter" ), filterLine );
790
791 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue().IsEmpty() )
792 return;
793
794 filterLine = dlg.GetValue();
795 filterLine.Replace( wxT( " " ), wxT( "_" ) );
796
797 // duplicate filters do no harm, so don't be a nanny.
798
799 m_FootprintFilterListBox->Append( filterLine );
800 m_FootprintFilterListBox->SetSelection( (int) m_FootprintFilterListBox->GetCount() - 1 );
801
802 OnModify();
803}
804
805
807{
808 wxArrayInt selections;
809 int n = m_FootprintFilterListBox->GetSelections( selections );
810
811 if( n > 0 )
812 {
813 // Just edit the first one
814 int idx = selections[0];
815 wxString filter = m_FootprintFilterListBox->GetString( idx );
816
817 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Edit Footprint Filter" ), filter );
818
819 if( dlg.ShowModal() == wxID_OK && !dlg.GetValue().IsEmpty() )
820 {
821 m_FootprintFilterListBox->SetString( (unsigned) idx, dlg.GetValue() );
822 OnModify();
823 }
824 }
825}
826
827
829{
830 // Account for scroll bars
832
833 m_grid->AutoSizeColumn( FDC_NAME );
834 m_grid->SetColSize( FDC_NAME, std::max( 72, m_grid->GetColSize( FDC_NAME ) ) );
835
836 int fixedColsWidth = m_grid->GetColSize( FDC_NAME );
837
838 for( int i = 2; i < m_grid->GetNumberCols(); i++ )
839 fixedColsWidth += m_grid->GetColSize( i );
840
841 m_grid->SetColSize( FDC_VALUE, std::max( 120, width - fixedColsWidth ) );
842}
843
844
845void DIALOG_LIB_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
846{
847 m_OptionPartsInterchangeable->Enable( m_SelNumberOfUnits->GetValue() > 1 );
849
850 if( m_grid->IsCellEditControlShown() )
851 {
852 int row = m_grid->GetGridCursorRow();
853 int col = m_grid->GetGridCursorCol();
854
855 if( row == VALUE_FIELD && col == FDC_VALUE && m_OptionPower->IsChecked() )
856 {
857 wxGridCellEditor* editor = m_grid->GetCellEditor( row, col );
858 m_SymbolNameCtrl->ChangeValue( editor->GetValue() );
859 editor->DecRef();
860 }
861 }
862
863 // Handle shown columns changes
864 std::bitset<64> shownColumns = m_grid->GetShownColumns();
865
866 if( shownColumns != m_shownColumns )
867 {
868 m_shownColumns = shownColumns;
869
870 if( !m_grid->IsCellEditControlShown() )
872 }
873
874 // Handle a delayed focus. The delay allows us to:
875 // a) change focus when the error was triggered from within a killFocus handler
876 // b) show the correct notebook page in the background before the error dialog comes up
877 // when triggered from an OK or a notebook page change
878
879 if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
880 {
881 m_NoteBook->ChangeSelection( (unsigned) m_delayedFocusPage );
883 }
884
885 if( !m_delayedErrorMessage.IsEmpty() )
886 {
887 // We will re-enter this routine when the error dialog is displayed, so make
888 // sure we don't keep putting up more dialogs.
889 wxString msg = m_delayedErrorMessage;
890 m_delayedErrorMessage = wxEmptyString;
891
892 // Do not use DisplayErrorMessage(); it screws up window order on Mac
893 DisplayError( nullptr, msg );
894 }
895
897 {
898 m_delayedFocusCtrl->SetFocus();
899
900 if( auto textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
901 textEntry->SelectAll();
902
903 m_delayedFocusCtrl = nullptr;
904 }
905 else if( m_delayedFocusGrid )
906 {
907 m_delayedFocusGrid->SetFocus();
910
911 m_delayedFocusGrid->EnableCellEditControl( true );
912 m_delayedFocusGrid->ShowCellEditControl();
913
914 m_delayedFocusGrid = nullptr;
917 }
918}
919
920
922{
923 auto new_size = event.GetSize();
924
925 if( new_size != m_size )
926 {
927 m_size = new_size;
928
930 }
931
932 // Always propagate a wxSizeEvent:
933 event.Skip();
934}
935
936
938{
939 bSizerLowerBasicPanel->Show( !aIsAlias );
940 m_inheritanceSelectCombo->Enable( aIsAlias );
941 m_inheritsStaticText->Enable( aIsAlias );
942 m_grid->ForceRefresh();
943}
944
945
947{
948 if( m_OptionPower->IsChecked() )
949 {
950 m_excludeFromSimCheckBox->SetValue( true );
951 m_excludeFromBomCheckBox->SetValue( true );
952 m_excludeFromBoardCheckBox->SetValue( true );
953 m_excludeFromBomCheckBox->Enable( false );
954 m_excludeFromBoardCheckBox->Enable( false );
955 m_excludeFromSimCheckBox->Enable( false );
956 m_spiceFieldsButton->Show( false );
957 }
958 else
959 {
960 m_excludeFromBomCheckBox->Enable( true );
961 m_excludeFromBoardCheckBox->Enable( true );
962 m_excludeFromSimCheckBox->Enable( true );
963 m_spiceFieldsButton->Show( true );
964 }
965
966 OnModify();
967}
968
969
970void DIALOG_LIB_SYMBOL_PROPERTIES::OnText( wxCommandEvent& event )
971{
972 OnModify();
973}
974
975
976void DIALOG_LIB_SYMBOL_PROPERTIES::OnCombobox( wxCommandEvent& event )
977{
978 OnModify();
979}
980
981
982void DIALOG_LIB_SYMBOL_PROPERTIES::OnCheckBox( wxCommandEvent& event )
983{
984 OnModify();
985}
986
987
989{
990 OnModify();
991}
992
993
995{
996 OnModify();
997}
998
999
1001{
1003 aEvent.Veto();
1004}
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
Class DIALOG_LIB_SYMBOL_PROPERTIES_BASE.
void OnSymbolNameKillFocus(wxFocusEvent &event) override
std::unique_ptr< LISTBOX_TRICKS > m_fpFilterTricks
void OnPageChanging(wxNotebookEvent &event) override
void OnSpinCtrlText(wxCommandEvent &event) override
void OnSizeGrid(wxSizeEvent &event) override
DIALOG_LIB_SYMBOL_PROPERTIES(SYMBOL_EDIT_FRAME *parent, LIB_SYMBOL *aLibEntry)
void OnUpdateUI(wxUpdateUIEvent &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 OnMoveUp(wxCommandEvent &event) override
void OnText(wxCommandEvent &event) override
void OnMoveDown(wxCommandEvent &event) override
void OnAddFootprintFilter(wxCommandEvent &event) override
void OnCheckBox(wxCommandEvent &event) override
void OnSymbolNameText(wxCommandEvent &event) override
void onPowerCheckBox(wxCommandEvent &aEvent) override
void OnAddField(wxCommandEvent &event) override
void OnEditSpiceModel(wxCommandEvent &event) override
void OnSpinCtrl(wxSpinEvent &event) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void resetSize()
Clear the existing dialog size and position.
void EndQuasiModal(int retCode)
void OnModify()
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
EDA_BASE_FRAME * m_parentFrame
Definition: dialog_shim.h:240
int ShowModal() override
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:506
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:98
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:377
int GetNumberRows() override
A text control validator used for validating the text allowed in fields.
Definition: validators.h:221
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Define a library symbol object.
Definition: lib_symbol.h:78
wxString GetKeyWords() const override
Definition: lib_symbol.h:171
bool IsPower() const override
Definition: lib_symbol.cpp:389
void SetUnitCount(int aCount, bool aDuplicateDrawItems=true)
Set the units per symbol count.
bool UnitsLocked() const
Check whether symbol units are interchangeable.
Definition: lib_symbol.h:264
void GetFields(std::vector< SCH_FIELD * > &aList)
Return a list of fields within this symbol.
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition: lib_symbol.h:194
void SetFields(const std::vector< SCH_FIELD > &aFieldsList)
Overwrite all the existing fields in this symbol with fields supplied in aFieldsList.
SCH_FIELD & GetValueField() const
Return reference to the value field.
bool IsAlias() const
Definition: lib_symbol.h:195
void SetPower()
Definition: lib_symbol.cpp:405
bool HasAlternateBodyStyle() const override
Test if symbol has more than one body conversion type (DeMorgan).
void LockUnits(bool aLockUnits)
Set interchangeable the property for symbol units.
Definition: lib_symbol.h:258
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:295
wxString GetName() const override
Definition: lib_symbol.h:137
void SetKeyWords(const wxString &aKeyWords)
Definition: lib_symbol.h:169
wxArrayString GetFPFilters() const
Definition: lib_symbol.h:206
void SetFPFilters(const wxArrayString &aFilters)
Definition: lib_symbol.h:204
void SetHasAlternateBodyStyle(bool aHasAlternate, bool aDuplicatePins=true)
Set or clear the alternate body style (DeMorgan) for the symbol.
int GetUnitCount() const override
LIB_SYMBOL_REF & GetParent()
Definition: lib_symbol.h:106
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:288
void SetNormal()
Definition: lib_symbol.cpp:433
bool TransferDataToWindow() override
bool TransferDataFromWindow() override
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
static SEARCH_STACK * SchSearchS(PROJECT *aProject)
Accessor for Eeschema search stack.
Definition: project_sch.cpp:41
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:51
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
Definition: sch_field.cpp:1253
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:1228
void SetName(const wxString &aName)
Definition: sch_field.cpp:1203
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1213
T * GetAppSettings(const wxString &aFilename)
Returns a handle to the a given settings by type If the settings have already been loaded,...
void SetBitmap(const wxBitmapBundle &aBmp)
The symbol library editor main window.
void UpdateAfterSymbolProperties(wxString *aOldName=nullptr)
wxString GetCurLib() const
The nickname of the current library being edited and empty string if none.
bool GetShowDeMorgan() const
bool IsSymbolFromLegacyLibrary() const
bool IsSymbolFromSchematic() const
void SaveCopyInUndoList(const wxString &aDescription, LIB_SYMBOL *aSymbol, UNDO_REDO aUndoType=UNDO_REDO::LIBEDIT)
Create a copy of the current symbol, and save it in the undo list.
SYMBOL_EDITOR_SETTINGS * GetSettings() const
LIB_SYMBOL_LIBRARY_MANAGER & GetLibManager()
void SetShowDeMorgan(bool show)
LIB_SYMBOL * GetAlias(const wxString &aAlias, const wxString &aLibrary) const
Return either an alias of a working LIB_SYMBOL copy, or alias of the original symbol if there is no w...
bool SymbolExists(const wxString &aAlias, const wxString &aLibrary) const
Return true if symbol with a specific alias exists in library (either original one or buffered).
void GetSymbolNames(const wxString &aLibName, wxArrayString &aSymbolNames, SYMBOL_NAME_FILTER aFilter=SYMBOL_NAME_FILTER::ALL)
bool GetExcludedFromBoard() const
Definition: symbol.h:148
virtual void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: symbol.h:129
bool GetExcludedFromBOM() const
Definition: symbol.h:142
void SetExcludedFromSim(bool aExcludeFromSim) override
Set or clear the exclude from simulation flag.
Definition: symbol.h:135
int GetPinNameOffset() const
Definition: symbol.h:118
virtual void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: symbol.h:123
virtual bool GetShowPinNames() const
Definition: symbol.h:124
void SetExcludedFromBOM(bool aExcludeFromBOM)
Set or clear the exclude from schematic bill of materials flag.
Definition: symbol.h:141
void SetPinNameOffset(int aOffset)
Set the offset in mils of the pin name text from the pin symbol.
Definition: symbol.h:117
void SetExcludedFromBoard(bool aExcludeFromBoard)
Set or clear exclude from board netlist flag.
Definition: symbol.h:147
virtual bool GetShowPinNumbers() const
Definition: symbol.h:130
bool GetExcludedFromSim() const override
Definition: symbol.h:136
void AddTemplateFieldNames(const wxString &aSerializedFieldNames)
Add a serialized list of template field names.
const TEMPLATE_FIELDNAMES & GetTemplateFieldNames()
Return a template field name list for read only access.
virtual long long int GetValue()
Return the current value in Internal Units.
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
virtual void ChangeValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion WITHOUT trigger...
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:487
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid's SetTable() method with one which doesn't mess up the grid column widths when setting th...
Definition: wx_grid.cpp:270
void DestroyTable(wxGridTableBase *aTable)
Work-around for a bug in wxGrid which crashes when deleting the table if the cell edit control was no...
Definition: wx_grid.cpp:443
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:457
std::bitset< 64 > GetShownColumns()
Definition: wx_grid.cpp:476
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:637
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:250
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:170
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:195
This file is part of the common library.
#define _(s)
@ FDC_NAME
@ FDC_VALUE
std::shared_ptr< LIB_SYMBOL > LIB_SYMBOL_SPTR
shared pointer to LIB_SYMBOL
Definition: lib_symbol.h:46
wxSize GetUnobscuredSize(const wxWindow *aWindow)
Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl,...
Definition: wxgtk/ui.cpp:195
wxString GetRefDesPrefix(const wxString &aRefDes)
Get the (non-numeric) prefix from a refdes - e.g.
STL namespace.
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
Collection of utility functions for component reference designators (refdes)
std::vector< FAB_LAYER_COLOR > dummy
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
Definition: string_utils.h:54
constexpr int MilsToIU(int mils) const
Definition: base_units.h:93
Hold a name of a symbol's field, field value, and default visibility.
@ DATASHEET_FIELD
name of datasheet
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ MANDATORY_FIELDS
The first 5 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691