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-2023 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
24#include <pgm_base.h>
25#include <eeschema_settings.h>
26#include <bitmaps.h>
27#include <confirm.h>
29#include <kiway.h>
30#include <symbol_edit_frame.h>
32#include <math/util.h> // for KiROUND
33#include <sch_symbol.h>
34#include <kiplatform/ui.h>
36#include <widgets/wx_grid.h>
38#include <string_utils.h>
39#include <project_sch.h>
40
41#include <dialog_sim_model.h>
42
47#include <wx/msgdlg.h>
48
49
53
54
56 LIB_SYMBOL* aLibEntry ) :
58 m_Parent( aParent ),
59 m_libEntry( aLibEntry ),
60 m_pinNameOffset( aParent, m_nameOffsetLabel, m_nameOffsetCtrl, m_nameOffsetUnits, true ),
61 m_delayedFocusCtrl( nullptr ),
62 m_delayedFocusGrid( nullptr ),
63 m_delayedFocusRow( -1 ),
64 m_delayedFocusColumn( -1 ),
65 m_delayedFocusPage( -1 )
66{
68 m_NoteBook->AddPage( m_embeddedFiles, _( "Embedded Files" ) );
69
70 // Give a bit more room for combobox editors
71 m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
72 m_fields = new FIELDS_GRID_TABLE( this, aParent, m_grid, m_libEntry );
74 m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this, aLibEntry,
75 [&]( wxCommandEvent& aEvent )
76 {
77 OnAddField( aEvent );
78 } ) );
79 m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
80
81 // Show/hide columns according to the user's preference
84
85 wxGridCellAttr* attr = new wxGridCellAttr;
86 attr->SetEditor( new GRID_CELL_URL_EDITOR( this, PROJECT_SCH::SchSearchS( &Prj() ), aLibEntry ) );
87 m_grid->SetAttr( DATASHEET_FIELD, FDC_VALUE, attr );
88
90
91 // Configure button logos
92 m_bpAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
93 m_bpDelete->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
94 m_bpMoveUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
95 m_bpMoveDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
96 m_addFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
97 m_deleteFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
98 m_editFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_edit ) );
99
101
102 if( aParent->IsSymbolFromLegacyLibrary() && !aParent->IsSymbolFromSchematic() )
103 {
104 m_stdSizerButtonCancel->SetDefault();
105 m_stdSizerButtonOK->SetLabel( _( "Read Only" ) );
106 m_stdSizerButtonOK->Enable( false );
107 }
108
109 // wxFormBuilder doesn't include this event...
110 m_grid->Connect( wxEVT_GRID_CELL_CHANGING,
112 nullptr, this );
113
115 {
117 && aLibEntry->IsRoot() )
119 && aLibEntry->IsAlias() ) )
120 {
121 resetSize();
122 }
123 }
124
127
128 m_grid->GetParent()->Layout();
130 Layout();
131
133}
134
135
137{
138 m_lastOpenedPage = m_NoteBook->GetSelection( );
139
141 cfg->m_EditSymbolVisibleColumns = m_grid->GetShownColumnsAsString();
142
143 // Prevents crash bug in wxGrid's d'tor
145
146 m_grid->Disconnect( wxEVT_GRID_CELL_CHANGING,
148 nullptr, this );
149
150 // Delete the GRID_TRICKS.
151 m_grid->PopEventHandler( true );
152}
153
154
156{
157 if( !wxDialog::TransferDataToWindow() )
158 return false;
159
160 // Push a copy of each field into m_updateFields
162
163 std::set<wxString> defined;
164
165 for( SCH_FIELD& field : *m_fields )
166 defined.insert( field.GetName() );
167
168 // Add in any template fieldnames not yet defined:
169 // Read global fieldname templates
170 if( EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>() )
171 {
172 TEMPLATES templateMgr;
173
174 if( !cfg->m_Drawing.field_names.IsEmpty() )
175 templateMgr.AddTemplateFieldNames( cfg->m_Drawing.field_names );
176
177 for( const TEMPLATE_FIELDNAME& templateFieldname : templateMgr.GetTemplateFieldNames() )
178 {
179 if( defined.count( templateFieldname.m_Name ) <= 0 )
180 {
181 SCH_FIELD field( VECTOR2I( 0, 0 ), -1, m_libEntry, templateFieldname.m_Name );
182 field.SetVisible( templateFieldname.m_Visible );
183 m_fields->push_back( field );
184 m_addedTemplateFields.insert( templateFieldname.m_Name );
185 }
186 }
187 }
188
189 // The Y axis for components in lib is from bottom to top while the screen axis is top
190 // to bottom: we must change the y coord sign for editing
191 for( size_t i = 0; i < m_fields->size(); ++i )
192 {
193 VECTOR2I pos = m_fields->at( i ).GetPosition();
194 pos.y = -pos.y;
195 m_fields->at( i ).SetPosition( pos );
196 }
197
198 // notify the grid
199 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->GetNumberRows() );
200 m_grid->ProcessTableMessage( msg );
202
204
205 m_KeywordCtrl->ChangeValue( m_libEntry->GetKeyWords() );
208 m_libEntry->GetUnitCount() == 1 );
209
210 // If a symbol contains no body-style-specific pins or graphic items,
211 // symbol->HasAlternateBodyStyle() will return false.
212 // But when editing a symbol with DeMorgan option set, we don't want to keep turning it off
213 // just because there aren't any body-style-specific items yet, so we force it to on if the
214 // parent frame has it enabled.
216
217 m_OptionPower->SetValue( m_libEntry->IsPower() );
218
219 if( m_libEntry->IsPower() )
220 m_spiceFieldsButton->Hide();
221
225
230
231 wxArrayString tmp = m_libEntry->GetFPFilters();
232 m_FootprintFilterListBox->Append( tmp );
233
234 // Populate the list of root parts for inherited objects.
235 if( m_libEntry->IsAlias() )
236 {
237 wxArrayString symbolNames;
238 wxString libName = m_Parent->GetCurLib();
239
240 // Someone forgot to set the current library in the editor frame window.
241 wxCHECK( !libName.empty(), false );
242
243 m_Parent->GetLibManager().GetSymbolNames( libName, symbolNames );
244
245 // Do allow an inherited symbol to be derived from itself.
246 symbolNames.Remove( m_libEntry->GetName() );
247 m_inheritanceSelectCombo->Append( symbolNames );
248
249 if( LIB_SYMBOL_SPTR rootSymbol = m_libEntry->GetParent().lock() )
250 {
251 wxString parentName = UnescapeString( rootSymbol->GetName() );
252 int selection = m_inheritanceSelectCombo->FindString( parentName );
253
254 if( selection == wxNOT_FOUND )
255 return false;
256
257 m_inheritanceSelectCombo->SetSelection( selection );
258 }
259
261 }
262
263 m_NoteBook->SetSelection( (unsigned) m_lastOpenedPage );
264
266
267 return true;
268}
269
270
272{
274 return false;
275
276 // Alias symbol reference can be empty because it inherits from the parent symbol.
277 if( m_libEntry->IsRoot() &&
279 {
280 if( m_NoteBook->GetSelection() != 0 )
281 m_NoteBook->SetSelection( 0 );
282
283 m_delayedErrorMessage = _( "References must start with a letter." );
288
289 return false;
290 }
291
292 // Check for missing field names.
293 for( int ii = MANDATORY_FIELDS; ii < (int) m_fields->size(); ++ii )
294 {
295 SCH_FIELD& field = m_fields->at( ii );
296 wxString fieldName = field.GetName( false );
297
298 if( fieldName.IsEmpty() && !field.GetText().IsEmpty() )
299 {
300 if( m_NoteBook->GetSelection() != 0 )
301 m_NoteBook->SetSelection( 0 );
302
303 m_delayedErrorMessage = _( "Fields must have a name." );
308
309 return false;
310 }
311 }
312
313 // Verify that the parent name is set if the symbol is inherited
314 if( m_libEntry->IsAlias() )
315 {
316 wxString parentName = m_inheritanceSelectCombo->GetValue();
317
318 if( parentName.IsEmpty() )
319 {
320 m_delayedErrorMessage = _( "Derived symbol must have a parent selected" );
321
322 return false;
323 }
324 }
325
326 /*
327 * Confirm destructive actions.
328 */
329
330 if( m_SelNumberOfUnits->GetValue() < m_libEntry->GetUnitCount() )
331 {
332 if( !IsOK( this, _( "Delete extra units from symbol?" ) ) )
333 return false;
334 }
335
337 {
338 if( !IsOK( this, _( "Delete alternate body style (De Morgan) from symbol?" ) ) )
339 return false;
340 }
341
342 return true;
343}
344
345
347{
348 if( !wxDialog::TransferDataFromWindow() )
349 return false;
350
352 return false;
353
354 wxString newName = EscapeString( m_SymbolNameCtrl->GetValue(), CTX_LIBID );
355 wxString oldName = m_libEntry->GetName();
356
357 if( newName.IsEmpty() )
358 {
359 wxMessageBox( _( "Symbol must have a name." ) );
360 return false;
361 }
362
363 if( oldName != newName )
364 {
365 wxString libName = m_Parent->GetCurLib();
366
367 if( m_Parent->GetLibManager().SymbolExists( newName, libName ) )
368 {
369 wxString msg;
370
371 msg.Printf( _( "Symbol name '%s' already in use in library '%s'." ),
372 UnescapeString( newName ),
373 libName );
374 DisplayErrorMessage( this, msg );
375 return false;
376 }
377
378 m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry,
379 UNDO_REDO::LIB_RENAME );
380 }
381 else
382 {
383 m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry );
384 }
385
386 // The Y axis for components in lib is from bottom to top while the screen axis is top
387 // to bottom: we must change the y coord sign when writing back to the library
388 for( int ii = 0; ii < (int) m_fields->size(); ++ii )
389 {
390 VECTOR2I pos = m_fields->at( ii ).GetPosition();
391 pos.y = -pos.y;
392 m_fields->at( ii ).SetPosition( pos );
393 m_fields->at( ii ).SetId( ii );
394 }
395
396 for( int ii = m_fields->GetNumberRows() - 1; ii >= MANDATORY_FIELDS; ii-- )
397 {
398 SCH_FIELD& field = m_fields->at( ii );
399 const wxString& fieldName = field.GetCanonicalName();
400
401 if( field.GetText().IsEmpty() )
402 {
403 if( fieldName.IsEmpty() || m_addedTemplateFields.contains( fieldName ) )
404 m_fields->erase( m_fields->begin() + ii );
405 }
406 else if( fieldName.IsEmpty() )
407 {
408 field.SetName( _( "untitled" ) );
409 }
410 }
411
413
414 // Update the parent for inherited symbols
415 if( m_libEntry->IsAlias() )
416 {
417 wxString parentName = EscapeString( m_inheritanceSelectCombo->GetValue(), CTX_LIBID );
418
419 // The parentName was verified to be non-empty in the Validator
420 wxString libName = m_Parent->GetCurLib();
421
422 // Get the parent from the libManager based on the name set in the inheritance combo box.
423 LIB_SYMBOL* newParent = m_Parent->GetLibManager().GetAlias( parentName, libName );
424
425 // Verify that the requested parent exists
426 wxCHECK( newParent, false );
427
428 m_libEntry->SetParent( newParent );
429 }
430
431 m_libEntry->SetName( newName );
432 m_libEntry->SetKeyWords( m_KeywordCtrl->GetValue() );
435 !m_OptionPartsInterchangeable->GetValue() );
438
439 if( m_OptionPower->GetValue() )
440 {
442 // Power symbols must have value matching name for now
443 m_libEntry->GetValueField().SetText( newName );
444 }
445 else
446 {
448 }
449
453
456
457 if( m_PinsNameInsideButt->GetValue() )
458 {
459 int offset = KiROUND( (double) m_pinNameOffset.GetValue() );
460
461 // We interpret an offset of 0 as "outside", so make sure it's non-zero
462 m_libEntry->SetPinNameOffset( offset == 0 ? 20 : offset );
463 }
464 else
465 {
466 m_libEntry->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
467 }
468
470
472
473 // It's possible that the symbol being edited has no pins, in which case there may be no
474 // alternate body style objects causing #LIB_SYMBOL::HasAlternateBodyStyle() to always return
475 // false. This allows the user to edit the alternate body style just in case this condition
476 // occurs.
478
480 return true;
481}
482
483
485{
486 wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
487 wxControl* control = editor->GetControl();
488
489 if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
490 {
491 event.Veto();
492
494 m_delayedFocusRow = event.GetRow();
495 m_delayedFocusColumn = event.GetCol();
497 }
498 else if( event.GetCol() == FDC_NAME )
499 {
500 wxString newName = event.GetString();
501
502 for( int i = 0; i < m_grid->GetNumberRows(); ++i )
503 {
504 if( i == event.GetRow() )
505 continue;
506
507 if( newName.CmpNoCase( m_grid->GetCellValue( i, FDC_NAME ) ) == 0 )
508 {
509 DisplayError( this, wxString::Format( _( "The name '%s' is already in use." ),
510 newName ) );
511 event.Veto();
512 m_delayedFocusRow = event.GetRow();
513 m_delayedFocusColumn = event.GetCol();
514 }
515 }
516 }
517
518 editor->DecRef();
519}
520
521
523{
524 if( m_OptionPower->IsChecked() )
525 m_grid->SetCellValue( VALUE_FIELD, FDC_VALUE, m_SymbolNameCtrl->GetValue() );
526}
527
528
530{
531 if( !m_delayedFocusCtrl )
532 {
533 // If the validation fails and we throw up a dialog then GTK will give us another
534 // KillFocus event and we end up in infinite recursion. So we use m_delayedFocusCtrl
535 // as a re-entrancy block and then clear it again if validation passes.
538
539 if( m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
540 {
541 m_delayedFocusCtrl = nullptr;
543 }
544 }
545
546 event.Skip();
547}
548
549
550void DIALOG_LIB_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
551{
553 return;
554
556 int fieldID = (int) m_fields->size();
557 SCH_FIELD newField( m_libEntry, fieldID );
558
560 schIUScale.MilsToIU( settings->m_Defaults.text_size ) ) );
561
562 m_fields->push_back( newField );
563
564 // notify the grid
565 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
566 m_grid->ProcessTableMessage( msg );
567
568 m_grid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
569 m_grid->SetGridCursor( (int) m_fields->size() - 1, 0 );
570
571 m_grid->EnableCellEditControl();
572 m_grid->ShowCellEditControl();
573
574 OnModify();
575}
576
577
579{
580 wxArrayInt selectedRows = m_grid->GetSelectedRows();
581
582 if( selectedRows.empty() && m_grid->GetGridCursorRow() >= 0 )
583 selectedRows.push_back( m_grid->GetGridCursorRow() );
584
585 if( selectedRows.empty() )
586 return;
587
588 for( int row : selectedRows )
589 {
590 if( row < MANDATORY_FIELDS )
591 {
592 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
594 return;
595 }
596 }
597
598 m_grid->CommitPendingChanges( true /* quiet mode */ );
599 m_grid->ClearSelection();
600
601 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
602 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
603
604 for( int row : selectedRows )
605 {
606 m_fields->erase( m_fields->begin() + row );
607
608 // notify the grid
609 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
610 m_grid->ProcessTableMessage( msg );
611
612 if( m_grid->GetNumberRows() > 0 )
613 {
614 m_grid->MakeCellVisible( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
615 m_grid->SetGridCursor( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
616 }
617 }
618
619 OnModify();
620}
621
622
623void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
624{
626 return;
627
628 int i = m_grid->GetGridCursorRow();
629
630 if( i > MANDATORY_FIELDS )
631 {
632 SCH_FIELD tmp = m_fields->at( (unsigned) i );
633 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
634 m_fields->insert( m_fields->begin() + i - 1, tmp );
635 m_grid->ForceRefresh();
636
637 m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
638 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
639
640 OnModify();
641 }
642 else
643 {
644 wxBell();
645 }
646}
647
648
649void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
650{
652 return;
653
654 int i = m_grid->GetGridCursorRow();
655
656 if( i >= MANDATORY_FIELDS && i + 1 < m_fields->GetNumberRows() )
657 {
658 SCH_FIELD tmp = m_fields->at( (unsigned) i );
659 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
660 m_fields->insert( m_fields->begin() + i + 1, tmp );
661 m_grid->ForceRefresh();
662
663 m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
664 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
665
666 OnModify();
667 }
668 else
669 {
670 wxBell();
671 }
672}
673
674
676{
678 return;
679
680 std::vector<SCH_FIELD> fields;
681
682 for( const SCH_FIELD& field : *m_fields )
683 fields.emplace_back( field );
684
685 DIALOG_SIM_MODEL dialog( this, m_parentFrame, *m_libEntry, fields );
686
687 if( dialog.ShowModal() != wxID_OK )
688 return;
689
690 // Add in any new fields
691 for( const SCH_FIELD& editedField : fields )
692 {
693 bool found = false;
694
695 for( SCH_FIELD& existingField : *m_fields )
696 {
697 if( existingField.GetName() == editedField.GetName() )
698 {
699 found = true;
700 existingField.SetText( editedField.GetText() );
701 break;
702 }
703 }
704
705 if( !found )
706 {
707 m_fields->emplace_back( editedField );
708 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
709 m_grid->ProcessTableMessage( msg );
710 }
711 }
712
713 // Remove any deleted fields
714 for( int ii = (int) m_fields->size() - 1; ii >= 0; --ii )
715 {
716 SCH_FIELD& existingField = m_fields->at( ii );
717 bool found = false;
718
719 for( SCH_FIELD& editedField : fields )
720 {
721 if( editedField.GetName() == existingField.GetName() )
722 {
723 found = true;
724 break;
725 }
726 }
727
728 if( !found )
729 {
730 m_fields->erase( m_fields->begin() + ii );
731 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, ii, 1 );
732 m_grid->ProcessTableMessage( msg );
733 }
734 }
735
736 OnModify();
737 m_grid->ForceRefresh();
738}
739
740
742{
743 int idx = m_FootprintFilterListBox->HitTest( event.GetPosition() );
744 wxCommandEvent dummy;
745
746 if( idx >= 0 )
748 else
750}
751
752
754{
755 // Running the Footprint Browser gums up the works and causes the automatic cancel
756 // stuff to no longer work. So we do it here ourselves.
757 EndQuasiModal( wxID_CANCEL );
758}
759
760
762{
763 wxString filterLine;
764 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Add Footprint Filter" ), filterLine );
765
766 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue().IsEmpty() )
767 return;
768
769 filterLine = dlg.GetValue();
770 filterLine.Replace( wxT( " " ), wxT( "_" ) );
771
772 // duplicate filters do no harm, so don't be a nanny.
773
774 m_FootprintFilterListBox->Append( filterLine );
775 m_FootprintFilterListBox->SetSelection( (int) m_FootprintFilterListBox->GetCount() - 1 );
776
777 OnModify();
778}
779
780
782{
783 int ii = m_FootprintFilterListBox->GetSelection();
784
785 if( ii >= 0 )
786 {
787 m_FootprintFilterListBox->Delete( (unsigned) ii );
788
789 if( m_FootprintFilterListBox->GetCount() == 0 )
790 m_FootprintFilterListBox->SetSelection( wxNOT_FOUND );
791 else
792 m_FootprintFilterListBox->SetSelection( std::max( 0, ii - 1 ) );
793 }
794
795 OnModify();
796}
797
798
800{
801 int idx = m_FootprintFilterListBox->GetSelection();
802
803 if( idx >= 0 )
804 {
805 wxString filter = m_FootprintFilterListBox->GetStringSelection();
806
807 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Edit Footprint Filter" ), filter );
808
809 if( dlg.ShowModal() == wxID_OK && !dlg.GetValue().IsEmpty() )
810 {
811 m_FootprintFilterListBox->SetString( (unsigned) idx, dlg.GetValue() );
812 OnModify();
813 }
814 }
815}
816
817
819{
820 // Account for scroll bars
822
823 m_grid->AutoSizeColumn( FDC_NAME );
824 m_grid->SetColSize( FDC_NAME, std::max( 72, m_grid->GetColSize( FDC_NAME ) ) );
825
826 int fixedColsWidth = m_grid->GetColSize( FDC_NAME );
827
828 for( int i = 2; i < m_grid->GetNumberCols(); i++ )
829 fixedColsWidth += m_grid->GetColSize( i );
830
831 m_grid->SetColSize( FDC_VALUE, std::max( 120, width - fixedColsWidth ) );
832}
833
834
835void DIALOG_LIB_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
836{
837 m_OptionPartsInterchangeable->Enable( m_SelNumberOfUnits->GetValue() > 1 );
839
840 if( m_grid->IsCellEditControlShown() )
841 {
842 int row = m_grid->GetGridCursorRow();
843 int col = m_grid->GetGridCursorCol();
844
845 if( row == VALUE_FIELD && col == FDC_VALUE && m_OptionPower->IsChecked() )
846 {
847 wxGridCellEditor* editor = m_grid->GetCellEditor( row, col );
848 m_SymbolNameCtrl->ChangeValue( editor->GetValue() );
849 editor->DecRef();
850 }
851 }
852
853 // Handle shown columns changes
854 std::bitset<64> shownColumns = m_grid->GetShownColumns();
855
856 if( shownColumns != m_shownColumns )
857 {
858 m_shownColumns = shownColumns;
859
860 if( !m_grid->IsCellEditControlShown() )
862 }
863
864 // Handle a delayed focus. The delay allows us to:
865 // a) change focus when the error was triggered from within a killFocus handler
866 // b) show the correct notebook page in the background before the error dialog comes up
867 // when triggered from an OK or a notebook page change
868
869 if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
870 {
871 m_NoteBook->ChangeSelection( (unsigned) m_delayedFocusPage );
873 }
874
875 if( !m_delayedErrorMessage.IsEmpty() )
876 {
877 // We will re-enter this routine when the error dialog is displayed, so make
878 // sure we don't keep putting up more dialogs.
879 wxString msg = m_delayedErrorMessage;
880 m_delayedErrorMessage = wxEmptyString;
881
882 // Do not use DisplayErrorMessage(); it screws up window order on Mac
883 DisplayError( nullptr, msg );
884 }
885
887 {
888 m_delayedFocusCtrl->SetFocus();
889
890 if( auto textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
891 textEntry->SelectAll();
892
893 m_delayedFocusCtrl = nullptr;
894 }
895 else if( m_delayedFocusGrid )
896 {
897 m_delayedFocusGrid->SetFocus();
900
901 m_delayedFocusGrid->EnableCellEditControl( true );
902 m_delayedFocusGrid->ShowCellEditControl();
903
904 m_delayedFocusGrid = nullptr;
907 }
908}
909
910
912{
913 auto new_size = event.GetSize();
914
915 if( new_size != m_size )
916 {
917 m_size = new_size;
918
920 }
921
922 // Always propagate a wxSizeEvent:
923 event.Skip();
924}
925
926
928{
929 bSizerLowerBasicPanel->Show( !aIsAlias );
930 m_inheritanceSelectCombo->Enable( aIsAlias );
931 m_inheritsStaticText->Enable( aIsAlias );
932 m_grid->ForceRefresh();
933}
934
935
937{
938 if( m_OptionPower->IsChecked() )
939 {
940 m_excludeFromSimCheckBox->SetValue( true );
941 m_excludeFromBomCheckBox->SetValue( true );
942 m_excludeFromBoardCheckBox->SetValue( true );
943 m_excludeFromBomCheckBox->Enable( false );
944 m_excludeFromBoardCheckBox->Enable( false );
945 m_excludeFromSimCheckBox->Enable( false );
946 m_spiceFieldsButton->Show( false );
947 }
948 else
949 {
950 m_excludeFromBomCheckBox->Enable( true );
951 m_excludeFromBoardCheckBox->Enable( true );
952 m_excludeFromSimCheckBox->Enable( true );
953 m_spiceFieldsButton->Show( true );
954 }
955
956 OnModify();
957}
958
959
960void DIALOG_LIB_SYMBOL_PROPERTIES::OnText( wxCommandEvent& event )
961{
962 OnModify();
963}
964
965
966void DIALOG_LIB_SYMBOL_PROPERTIES::OnCombobox( wxCommandEvent& event )
967{
968 OnModify();
969}
970
971
972void DIALOG_LIB_SYMBOL_PROPERTIES::OnCheckBox( wxCommandEvent& event )
973{
974 OnModify();
975}
976
977
979{
980 OnModify();
981}
982
983
985{
986 OnModify();
987}
988
989
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
Class DIALOG_LIB_SYMBOL_PROPERTIES_BASE.
void OnSymbolNameKillFocus(wxFocusEvent &event) override
void OnFilterDClick(wxMouseEvent &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 OnDeleteFootprintFilter(wxCommandEvent &event) override
void OnEditFootprintFilter(wxCommandEvent &event) override
void OnDeleteField(wxCommandEvent &event) override
void OnCombobox(wxCommandEvent &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:228
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:373
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:94
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:244
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
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:1245
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:1220
void SetName(const wxString &aName)
Definition: sch_field.cpp:1195
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1205
static bool IsReferenceStringValid(const wxString &aReferenceString)
Test for an acceptable reference string.
Definition: sch_symbol.cpp:768
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:444
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:267
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:400
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:414
std::bitset< 64 > GetShownColumns()
Definition: wx_grid.cpp:433
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:594
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
SETTINGS_MANAGER * GetSettingsManager()
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1059
see class PGM_BASE
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".
constexpr ret_type KiROUND(fp_type v, bool aQuiet=false)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:100
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:676