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
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() ),
92 aLibEntry ) );
93 m_grid->SetAttr( DATASHEET_FIELD, FDC_VALUE, attr );
94
96
97 // Configure button logos
98 m_bpAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
99 m_bpDelete->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
100 m_bpMoveUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
101 m_bpMoveDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
102 m_addFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
103 m_deleteFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
104 m_editFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_edit ) );
105
107
108 if( aParent->IsSymbolFromLegacyLibrary() && !aParent->IsSymbolFromSchematic() )
109 {
110 m_stdSizerButtonCancel->SetDefault();
111 m_stdSizerButtonOK->SetLabel( _( "Read Only" ) );
112 m_stdSizerButtonOK->Enable( false );
113 }
114
115 // wxFormBuilder doesn't include this event...
116 m_grid->Connect( wxEVT_GRID_CELL_CHANGING,
118 nullptr, this );
119
120 // Forward the delete button to the tricks
121 m_deleteFilterButton->Bind( wxEVT_BUTTON,
122 [&]( wxCommandEvent& aEvent )
123 {
124 wxCommandEvent cmdEvent( EDA_EVT_LISTBOX_DELETE );
125 m_fpFilterTricks->ProcessEvent( cmdEvent );
126 } );
127
128 // When the filter tricks modifies something, update ourselves
129 m_FootprintFilterListBox->Bind( EDA_EVT_LISTBOX_CHANGED,
130 [&]( wxCommandEvent& aEvent )
131 {
132 OnModify();
133 } );
134
136 {
138 && aLibEntry->IsRoot() )
140 && aLibEntry->IsAlias() ) )
141 {
142 resetSize();
143 }
144 }
145
148
149 m_grid->GetParent()->Layout();
151 Layout();
152
154}
155
156
158{
159 m_lastOpenedPage = m_NoteBook->GetSelection( );
160
162 cfg->m_EditSymbolVisibleColumns = m_grid->GetShownColumnsAsString();
163
164 // Prevents crash bug in wxGrid's d'tor
166
167 m_grid->Disconnect( wxEVT_GRID_CELL_CHANGING,
169 nullptr, this );
170
171 // Delete the GRID_TRICKS.
172 m_grid->PopEventHandler( true );
173}
174
175
177{
178 if( !wxDialog::TransferDataToWindow() )
179 return false;
180
181 // Push a copy of each field into m_updateFields
183
184 std::set<wxString> defined;
185
186 for( SCH_FIELD& field : *m_fields )
187 defined.insert( field.GetName() );
188
189 // Add in any template fieldnames not yet defined:
190 // Read global fieldname templates
192 EESCHEMA_SETTINGS* cfg = mgr.GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
193
194 if( cfg )
195 {
196 TEMPLATES templateMgr;
197
198 if( !cfg->m_Drawing.field_names.IsEmpty() )
199 templateMgr.AddTemplateFieldNames( cfg->m_Drawing.field_names );
200
201 for( const TEMPLATE_FIELDNAME& templateFieldname : templateMgr.GetTemplateFieldNames() )
202 {
203 if( defined.count( templateFieldname.m_Name ) <= 0 )
204 {
205 SCH_FIELD field( VECTOR2I( 0, 0 ), -1, m_libEntry, templateFieldname.m_Name );
206 field.SetVisible( templateFieldname.m_Visible );
207 m_fields->push_back( field );
208 m_addedTemplateFields.insert( templateFieldname.m_Name );
209 }
210 }
211 }
212
213 // The Y axis for components in lib is from bottom to top while the screen axis is top
214 // to bottom: we must change the y coord sign for editing
215 for( size_t i = 0; i < m_fields->size(); ++i )
216 {
217 VECTOR2I pos = m_fields->at( i ).GetPosition();
218 pos.y = -pos.y;
219 m_fields->at( i ).SetPosition( pos );
220 }
221
222 // notify the grid
223 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->GetNumberRows() );
224 m_grid->ProcessTableMessage( msg );
226
228
229 m_KeywordCtrl->ChangeValue( m_libEntry->GetKeyWords() );
232 m_libEntry->GetUnitCount() == 1 );
233
234 // If a symbol contains no body-style-specific pins or graphic items,
235 // symbol->HasAlternateBodyStyle() will return false.
236 // But when editing a symbol with DeMorgan option set, we don't want to keep turning it off
237 // just because there aren't any body-style-specific items yet, so we force it to on if the
238 // parent frame has it enabled.
240
241 m_OptionPower->SetValue( m_libEntry->IsPower() );
242
243 if( m_libEntry->IsPower() )
244 m_spiceFieldsButton->Hide();
245
249
254
255 wxArrayString tmp = m_libEntry->GetFPFilters();
256 m_FootprintFilterListBox->Append( tmp );
257
258 // Populate the list of root parts for inherited objects.
259 if( m_libEntry->IsAlias() )
260 {
261 wxArrayString symbolNames;
262 wxString libName = m_Parent->GetCurLib();
263
264 // Someone forgot to set the current library in the editor frame window.
265 wxCHECK( !libName.empty(), false );
266
267 m_Parent->GetLibManager().GetSymbolNames( libName, symbolNames );
268
269 // Sort the list of symbols for easier search
270 symbolNames.Sort(
271 []( const wxString& a, const wxString& b ) -> int
272 {
273 return StrNumCmp( a, b, true );
274 } );
275
276 // Do allow an inherited symbol to be derived from itself.
277 symbolNames.Remove( m_libEntry->GetName() );
278 m_inheritanceSelectCombo->Append( symbolNames );
279
280 if( LIB_SYMBOL_SPTR rootSymbol = m_libEntry->GetParent().lock() )
281 {
282 wxString parentName = UnescapeString( rootSymbol->GetName() );
283 int selection = m_inheritanceSelectCombo->FindString( parentName );
284
285 if( selection == wxNOT_FOUND )
286 return false;
287
288 m_inheritanceSelectCombo->SetSelection( selection );
289 }
290
292 }
293
294 m_NoteBook->SetSelection( (unsigned) m_lastOpenedPage );
295
297
298 return true;
299}
300
301
303{
305 return false;
306
307 // Alias symbol reference can be empty because it inherits from the parent symbol.
308 if( m_libEntry->IsRoot()
309 && UTIL::GetRefDesPrefix( m_fields->at( REFERENCE_FIELD ).GetText() ).IsEmpty() )
310 {
311 if( m_NoteBook->GetSelection() != 0 )
312 m_NoteBook->SetSelection( 0 );
313
314 m_delayedErrorMessage = _( "References must start with a letter." );
319
320 return false;
321 }
322
323 // Check for missing field names.
324 for( int ii = MANDATORY_FIELDS; ii < (int) m_fields->size(); ++ii )
325 {
326 SCH_FIELD& field = m_fields->at( ii );
327 wxString fieldName = field.GetName( false );
328
329 if( fieldName.IsEmpty() && !field.GetText().IsEmpty() )
330 {
331 if( m_NoteBook->GetSelection() != 0 )
332 m_NoteBook->SetSelection( 0 );
333
334 m_delayedErrorMessage = _( "Fields must have a name." );
339
340 return false;
341 }
342 }
343
344 // Verify that the parent name is set if the symbol is inherited
345 if( m_libEntry->IsAlias() )
346 {
347 wxString parentName = m_inheritanceSelectCombo->GetValue();
348
349 if( parentName.IsEmpty() )
350 {
351 m_delayedErrorMessage = _( "Derived symbol must have a parent selected" );
352
353 return false;
354 }
355 }
356
357 /*
358 * Confirm destructive actions.
359 */
360
361 if( m_SelNumberOfUnits->GetValue() < m_libEntry->GetUnitCount() )
362 {
363 if( !IsOK( this, _( "Delete extra units from symbol?" ) ) )
364 return false;
365 }
366
368 {
369 if( !IsOK( this, _( "Delete alternate body style (De Morgan) from symbol?" ) ) )
370 return false;
371 }
372
373 return true;
374}
375
376
378{
379 if( !wxDialog::TransferDataFromWindow() )
380 return false;
381
383 return false;
384
385 wxString newName = EscapeString( m_SymbolNameCtrl->GetValue(), CTX_LIBID );
386 wxString oldName = m_libEntry->GetName();
387
388 if( newName.IsEmpty() )
389 {
390 wxMessageBox( _( "Symbol must have a name." ) );
391 return false;
392 }
393
394 if( oldName != newName )
395 {
396 wxString libName = m_Parent->GetCurLib();
397
398 if( m_Parent->GetLibManager().SymbolExists( newName, libName ) )
399 {
400 wxString msg;
401
402 msg.Printf( _( "Symbol name '%s' already in use in library '%s'." ),
403 UnescapeString( newName ),
404 libName );
405 DisplayErrorMessage( this, msg );
406 return false;
407 }
408
409 m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry,
410 UNDO_REDO::LIB_RENAME );
411 }
412 else
413 {
414 m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry );
415 }
416
417 // The Y axis for components in lib is from bottom to top while the screen axis is top
418 // to bottom: we must change the y coord sign when writing back to the library
419 for( int ii = 0; ii < (int) m_fields->size(); ++ii )
420 {
421 VECTOR2I pos = m_fields->at( ii ).GetPosition();
422 pos.y = -pos.y;
423 m_fields->at( ii ).SetPosition( pos );
424 m_fields->at( ii ).SetId( ii );
425 }
426
427 for( int ii = m_fields->GetNumberRows() - 1; ii >= MANDATORY_FIELDS; ii-- )
428 {
429 SCH_FIELD& field = m_fields->at( ii );
430 const wxString& fieldName = field.GetCanonicalName();
431
432 if( field.GetText().IsEmpty() )
433 {
434 if( fieldName.IsEmpty() || m_addedTemplateFields.contains( fieldName ) )
435 m_fields->erase( m_fields->begin() + ii );
436 }
437 else if( fieldName.IsEmpty() )
438 {
439 field.SetName( _( "untitled" ) );
440 }
441 }
442
444
445 // Update the parent for inherited symbols
446 if( m_libEntry->IsAlias() )
447 {
448 wxString parentName = EscapeString( m_inheritanceSelectCombo->GetValue(), CTX_LIBID );
449
450 // The parentName was verified to be non-empty in the Validator
451 wxString libName = m_Parent->GetCurLib();
452
453 // Get the parent from the libManager based on the name set in the inheritance combo box.
454 LIB_SYMBOL* newParent = m_Parent->GetLibManager().GetAlias( parentName, libName );
455
456 // Verify that the requested parent exists
457 wxCHECK( newParent, false );
458
459 m_libEntry->SetParent( newParent );
460 }
461
462 m_libEntry->SetName( newName );
463 m_libEntry->SetKeyWords( m_KeywordCtrl->GetValue() );
466 !m_OptionPartsInterchangeable->GetValue() );
469
470 if( m_OptionPower->GetValue() )
471 {
473 // Power symbols must have value matching name for now
474 m_libEntry->GetValueField().SetText( newName );
475 }
476 else
477 {
479 }
480
484
487
488 if( m_PinsNameInsideButt->GetValue() )
489 {
490 int offset = KiROUND( (double) m_pinNameOffset.GetValue() );
491
492 // We interpret an offset of 0 as "outside", so make sure it's non-zero
493 m_libEntry->SetPinNameOffset( offset == 0 ? 20 : offset );
494 }
495 else
496 {
497 m_libEntry->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
498 }
499
501
503
504 // It's possible that the symbol being edited has no pins, in which case there may be no
505 // alternate body style objects causing #LIB_SYMBOL::HasAlternateBodyStyle() to always return
506 // false. This allows the user to edit the alternate body style just in case this condition
507 // occurs.
509
511 return true;
512}
513
514
516{
517 wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
518 wxControl* control = editor->GetControl();
519
520 if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
521 {
522 event.Veto();
523
525 m_delayedFocusRow = event.GetRow();
526 m_delayedFocusColumn = event.GetCol();
528 }
529 else if( event.GetCol() == FDC_NAME )
530 {
531 wxString newName = event.GetString();
532
533 for( int i = 0; i < m_grid->GetNumberRows(); ++i )
534 {
535 if( i == event.GetRow() )
536 continue;
537
538 if( newName.CmpNoCase( m_grid->GetCellValue( i, FDC_NAME ) ) == 0 )
539 {
540 DisplayError( this, wxString::Format( _( "The name '%s' is already in use." ),
541 newName ) );
542 event.Veto();
543 m_delayedFocusRow = event.GetRow();
544 m_delayedFocusColumn = event.GetCol();
545 }
546 }
547 }
548
549 editor->DecRef();
550}
551
552
554{
555 if( m_OptionPower->IsChecked() )
556 m_grid->SetCellValue( VALUE_FIELD, FDC_VALUE, m_SymbolNameCtrl->GetValue() );
557
558 OnModify();
559}
560
561
563{
564 if( !m_delayedFocusCtrl )
565 {
566 // If the validation fails and we throw up a dialog then GTK will give us another
567 // KillFocus event and we end up in infinite recursion. So we use m_delayedFocusCtrl
568 // as a re-entrancy block and then clear it again if validation passes.
571
572 if( m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
573 {
574 m_delayedFocusCtrl = nullptr;
576 }
577 }
578
579 event.Skip();
580}
581
582
583void DIALOG_LIB_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
584{
586 return;
587
589 int fieldID = (int) m_fields->size();
590 SCH_FIELD newField( m_libEntry, fieldID );
591
593 schIUScale.MilsToIU( settings->m_Defaults.text_size ) ) );
594
595 m_fields->push_back( newField );
596
597 // notify the grid
598 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
599 m_grid->ProcessTableMessage( msg );
600
601 m_grid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
602 m_grid->SetGridCursor( (int) m_fields->size() - 1, 0 );
603
604 m_grid->EnableCellEditControl();
605 m_grid->ShowCellEditControl();
606
607 OnModify();
608}
609
610
612{
613 wxArrayInt selectedRows = m_grid->GetSelectedRows();
614
615 if( selectedRows.empty() && m_grid->GetGridCursorRow() >= 0 )
616 selectedRows.push_back( m_grid->GetGridCursorRow() );
617
618 if( selectedRows.empty() )
619 return;
620
621 for( int row : selectedRows )
622 {
623 if( row < MANDATORY_FIELDS )
624 {
625 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
627 return;
628 }
629 }
630
631 m_grid->CommitPendingChanges( true /* quiet mode */ );
632 m_grid->ClearSelection();
633
634 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
635 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
636
637 for( int row : selectedRows )
638 {
639 m_fields->erase( m_fields->begin() + row );
640
641 // notify the grid
642 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
643 m_grid->ProcessTableMessage( msg );
644
645 if( m_grid->GetNumberRows() > 0 )
646 {
647 m_grid->MakeCellVisible( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
648 m_grid->SetGridCursor( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
649 }
650 }
651
652 OnModify();
653}
654
655
656void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
657{
659 return;
660
661 int i = m_grid->GetGridCursorRow();
662
663 if( i > MANDATORY_FIELDS )
664 {
665 SCH_FIELD tmp = m_fields->at( (unsigned) i );
666 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
667 m_fields->insert( m_fields->begin() + i - 1, tmp );
668 m_grid->ForceRefresh();
669
670 m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
671 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
672
673 OnModify();
674 }
675 else
676 {
677 wxBell();
678 }
679}
680
681
682void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
683{
685 return;
686
687 int i = m_grid->GetGridCursorRow();
688
689 if( i >= MANDATORY_FIELDS && i + 1 < m_fields->GetNumberRows() )
690 {
691 SCH_FIELD tmp = m_fields->at( (unsigned) i );
692 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
693 m_fields->insert( m_fields->begin() + i + 1, tmp );
694 m_grid->ForceRefresh();
695
696 m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
697 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
698
699 OnModify();
700 }
701 else
702 {
703 wxBell();
704 }
705}
706
707
709{
711 return;
712
713 std::vector<SCH_FIELD> fields;
714
715 for( const SCH_FIELD& field : *m_fields )
716 fields.emplace_back( field );
717
718 DIALOG_SIM_MODEL dialog( this, m_parentFrame, *m_libEntry, fields );
719
720 if( dialog.ShowModal() != wxID_OK )
721 return;
722
723 // Add in any new fields
724 for( const SCH_FIELD& editedField : fields )
725 {
726 bool found = false;
727
728 for( SCH_FIELD& existingField : *m_fields )
729 {
730 if( existingField.GetName() == editedField.GetName() )
731 {
732 found = true;
733 existingField.SetText( editedField.GetText() );
734 break;
735 }
736 }
737
738 if( !found )
739 {
740 m_fields->emplace_back( editedField );
741 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
742 m_grid->ProcessTableMessage( msg );
743 }
744 }
745
746 // Remove any deleted fields
747 for( int ii = (int) m_fields->size() - 1; ii >= 0; --ii )
748 {
749 SCH_FIELD& existingField = m_fields->at( ii );
750 bool found = false;
751
752 for( SCH_FIELD& editedField : fields )
753 {
754 if( editedField.GetName() == existingField.GetName() )
755 {
756 found = true;
757 break;
758 }
759 }
760
761 if( !found )
762 {
763 m_fields->erase( m_fields->begin() + ii );
764 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, ii, 1 );
765 m_grid->ProcessTableMessage( msg );
766 }
767 }
768
769 OnModify();
770 m_grid->ForceRefresh();
771}
772
773
775{
776 int idx = m_FootprintFilterListBox->HitTest( event.GetPosition() );
777 wxCommandEvent dummy;
778
779 if( idx >= 0 )
781 else
783}
784
785
787{
788 // Running the Footprint Browser gums up the works and causes the automatic cancel
789 // stuff to no longer work. So we do it here ourselves.
790 EndQuasiModal( wxID_CANCEL );
791}
792
793
795{
796 wxString filterLine;
797 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Add Footprint Filter" ), filterLine );
798
799 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue().IsEmpty() )
800 return;
801
802 filterLine = dlg.GetValue();
803 filterLine.Replace( wxT( " " ), wxT( "_" ) );
804
805 // duplicate filters do no harm, so don't be a nanny.
806 m_FootprintFilterListBox->Append( filterLine );
807 m_FootprintFilterListBox->SetSelection( (int) m_FootprintFilterListBox->GetCount() - 1 );
808
809 OnModify();
810}
811
812
814{
815 wxArrayInt selections;
816 int n = m_FootprintFilterListBox->GetSelections( selections );
817
818 if( n > 0 )
819 {
820 // Just edit the first one
821 int idx = selections[0];
822 wxString filter = m_FootprintFilterListBox->GetString( idx );
823
824 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Edit Footprint Filter" ), filter );
825
826 if( dlg.ShowModal() == wxID_OK && !dlg.GetValue().IsEmpty() )
827 {
828 m_FootprintFilterListBox->SetString( (unsigned) idx, dlg.GetValue() );
829 OnModify();
830 }
831 }
832}
833
834
836{
837 // Account for scroll bars
839
840 m_grid->AutoSizeColumn( FDC_NAME );
841 m_grid->SetColSize( FDC_NAME, std::max( 72, m_grid->GetColSize( FDC_NAME ) ) );
842
843 int fixedColsWidth = m_grid->GetColSize( FDC_NAME );
844
845 for( int i = 2; i < m_grid->GetNumberCols(); i++ )
846 fixedColsWidth += m_grid->GetColSize( i );
847
848 m_grid->SetColSize( FDC_VALUE, std::max( 120, width - fixedColsWidth ) );
849}
850
851
852void DIALOG_LIB_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
853{
854 m_OptionPartsInterchangeable->Enable( m_SelNumberOfUnits->GetValue() > 1 );
856
857 if( m_grid->IsCellEditControlShown() )
858 {
859 int row = m_grid->GetGridCursorRow();
860 int col = m_grid->GetGridCursorCol();
861
862 if( row == VALUE_FIELD && col == FDC_VALUE && m_OptionPower->IsChecked() )
863 {
864 wxGridCellEditor* editor = m_grid->GetCellEditor( row, col );
865 m_SymbolNameCtrl->ChangeValue( editor->GetValue() );
866 editor->DecRef();
867 }
868 }
869
870 // Handle shown columns changes
871 std::bitset<64> shownColumns = m_grid->GetShownColumns();
872
873 if( shownColumns != m_shownColumns )
874 {
875 m_shownColumns = shownColumns;
876
877 if( !m_grid->IsCellEditControlShown() )
879 }
880
881 // Handle a delayed focus. The delay allows us to:
882 // a) change focus when the error was triggered from within a killFocus handler
883 // b) show the correct notebook page in the background before the error dialog comes up
884 // when triggered from an OK or a notebook page change
885
886 if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
887 {
888 m_NoteBook->ChangeSelection( (unsigned) m_delayedFocusPage );
890 }
891
892 if( !m_delayedErrorMessage.IsEmpty() )
893 {
894 // We will re-enter this routine when the error dialog is displayed, so make
895 // sure we don't keep putting up more dialogs.
896 wxString msg = m_delayedErrorMessage;
897 m_delayedErrorMessage = wxEmptyString;
898
899 // Do not use DisplayErrorMessage(); it screws up window order on Mac
900 DisplayError( nullptr, msg );
901 }
902
904 {
905 m_delayedFocusCtrl->SetFocus();
906
907 if( auto textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
908 textEntry->SelectAll();
909
910 m_delayedFocusCtrl = nullptr;
911 }
912 else if( m_delayedFocusGrid )
913 {
914 m_delayedFocusGrid->SetFocus();
917
918 m_delayedFocusGrid->EnableCellEditControl( true );
919 m_delayedFocusGrid->ShowCellEditControl();
920
921 m_delayedFocusGrid = nullptr;
924 }
925}
926
927
929{
930 auto new_size = event.GetSize();
931
932 if( new_size != m_size )
933 {
934 m_size = new_size;
935
937 }
938
939 // Always propagate a wxSizeEvent:
940 event.Skip();
941}
942
943
945{
946 bSizerLowerBasicPanel->Show( !aIsAlias );
947 m_inheritanceSelectCombo->Enable( aIsAlias );
948 m_inheritsStaticText->Enable( aIsAlias );
949 m_grid->ForceRefresh();
950}
951
952
954{
955 if( m_OptionPower->IsChecked() )
956 {
957 m_excludeFromSimCheckBox->SetValue( true );
958 m_excludeFromBomCheckBox->SetValue( true );
959 m_excludeFromBoardCheckBox->SetValue( true );
960 m_excludeFromBomCheckBox->Enable( false );
961 m_excludeFromBoardCheckBox->Enable( false );
962 m_excludeFromSimCheckBox->Enable( false );
963 m_spiceFieldsButton->Show( false );
964 }
965 else
966 {
967 m_excludeFromBomCheckBox->Enable( true );
968 m_excludeFromBoardCheckBox->Enable( true );
969 m_excludeFromSimCheckBox->Enable( true );
970 m_spiceFieldsButton->Show( true );
971 }
972
973 OnModify();
974}
975
976
977void DIALOG_LIB_SYMBOL_PROPERTIES::OnText( wxCommandEvent& event )
978{
979 OnModify();
980}
981
982
983void DIALOG_LIB_SYMBOL_PROPERTIES::OnCombobox( wxCommandEvent& event )
984{
985 OnModify();
986}
987
988
989void DIALOG_LIB_SYMBOL_PROPERTIES::OnCheckBox( wxCommandEvent& event )
990{
991 OnModify();
992}
993
994
996{
997 OnModify();
998}
999
1000
1002{
1003 OnModify();
1004}
1005
1006
1008{
1010 aEvent.Veto();
1011}
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:248
int ShowModal() override
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:524
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:224
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Define a library symbol object.
Definition: lib_symbol.h:84
wxString GetKeyWords() const override
Definition: lib_symbol.h:182
bool IsPower() const override
Definition: lib_symbol.cpp:418
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:285
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition: lib_symbol.h:205
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:206
void SetPower()
Definition: lib_symbol.cpp:434
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:279
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:324
wxString GetName() const override
Definition: lib_symbol.h:148
void SetKeyWords(const wxString &aKeyWords)
Definition: lib_symbol.h:180
wxArrayString GetFPFilters() const
Definition: lib_symbol.h:217
void SetFPFilters(const wxArrayString &aFilters)
Definition: lib_symbol.h:215
void CopyFields(std::vector< SCH_FIELD > &aList)
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:117
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:317
void SetNormal()
Definition: lib_symbol.cpp:462
bool TransferDataToWindow() override
bool TransferDataFromWindow() override
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:125
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:1252
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:1227
void SetName(const wxString &aName)
Definition: sch_field.cpp:1202
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1212
T * GetAppSettings(const wxString &aFilename)
Return a handle to the a given settings by type.
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:181
virtual void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: symbol.h:162
bool GetExcludedFromBOM() const
Definition: symbol.h:175
void SetExcludedFromSim(bool aExcludeFromSim) override
Set or clear the exclude from simulation flag.
Definition: symbol.h:168
int GetPinNameOffset() const
Definition: symbol.h:151
virtual void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: symbol.h:156
virtual bool GetShowPinNames() const
Definition: symbol.h:157
void SetExcludedFromBOM(bool aExcludeFromBOM)
Set or clear the exclude from schematic bill of materials flag.
Definition: symbol.h:174
void SetPinNameOffset(int aOffset)
Set the offset in mils of the pin name text from the pin symbol.
Definition: symbol.h:150
void SetExcludedFromBoard(bool aExcludeFromBoard)
Set or clear exclude from board netlist flag.
Definition: symbol.h:180
virtual bool GetShowPinNumbers() const
Definition: symbol.h:163
bool GetExcludedFromSim() const override
Definition: symbol.h:169
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:496
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:277
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:451
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:466
std::bitset< 64 > GetShownColumns()
Definition: wx_grid.cpp:485
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:646
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:52
wxSize GetUnobscuredSize(const wxWindow *aWindow)
Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl,...
Definition: wxgtk/ui.cpp:252
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:1073
see class PGM_BASE
Collection of utility functions for component reference designators (refdes)
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
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:695