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
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 OnModify();
528}
529
530
532{
533 if( !m_delayedFocusCtrl )
534 {
535 // If the validation fails and we throw up a dialog then GTK will give us another
536 // KillFocus event and we end up in infinite recursion. So we use m_delayedFocusCtrl
537 // as a re-entrancy block and then clear it again if validation passes.
540
541 if( m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
542 {
543 m_delayedFocusCtrl = nullptr;
545 }
546 }
547
548 event.Skip();
549}
550
551
552void DIALOG_LIB_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
553{
555 return;
556
558 int fieldID = (int) m_fields->size();
559 SCH_FIELD newField( m_libEntry, fieldID );
560
562 schIUScale.MilsToIU( settings->m_Defaults.text_size ) ) );
563
564 m_fields->push_back( newField );
565
566 // notify the grid
567 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
568 m_grid->ProcessTableMessage( msg );
569
570 m_grid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
571 m_grid->SetGridCursor( (int) m_fields->size() - 1, 0 );
572
573 m_grid->EnableCellEditControl();
574 m_grid->ShowCellEditControl();
575
576 OnModify();
577}
578
579
581{
582 wxArrayInt selectedRows = m_grid->GetSelectedRows();
583
584 if( selectedRows.empty() && m_grid->GetGridCursorRow() >= 0 )
585 selectedRows.push_back( m_grid->GetGridCursorRow() );
586
587 if( selectedRows.empty() )
588 return;
589
590 for( int row : selectedRows )
591 {
592 if( row < MANDATORY_FIELDS )
593 {
594 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
596 return;
597 }
598 }
599
600 m_grid->CommitPendingChanges( true /* quiet mode */ );
601 m_grid->ClearSelection();
602
603 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
604 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
605
606 for( int row : selectedRows )
607 {
608 m_fields->erase( m_fields->begin() + row );
609
610 // notify the grid
611 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
612 m_grid->ProcessTableMessage( msg );
613
614 if( m_grid->GetNumberRows() > 0 )
615 {
616 m_grid->MakeCellVisible( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
617 m_grid->SetGridCursor( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
618 }
619 }
620
621 OnModify();
622}
623
624
625void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
626{
628 return;
629
630 int i = m_grid->GetGridCursorRow();
631
632 if( i > MANDATORY_FIELDS )
633 {
634 SCH_FIELD tmp = m_fields->at( (unsigned) i );
635 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
636 m_fields->insert( m_fields->begin() + i - 1, tmp );
637 m_grid->ForceRefresh();
638
639 m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
640 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
641
642 OnModify();
643 }
644 else
645 {
646 wxBell();
647 }
648}
649
650
651void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
652{
654 return;
655
656 int i = m_grid->GetGridCursorRow();
657
658 if( i >= MANDATORY_FIELDS && i + 1 < m_fields->GetNumberRows() )
659 {
660 SCH_FIELD tmp = m_fields->at( (unsigned) i );
661 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
662 m_fields->insert( m_fields->begin() + i + 1, tmp );
663 m_grid->ForceRefresh();
664
665 m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
666 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
667
668 OnModify();
669 }
670 else
671 {
672 wxBell();
673 }
674}
675
676
678{
680 return;
681
682 std::vector<SCH_FIELD> fields;
683
684 for( const SCH_FIELD& field : *m_fields )
685 fields.emplace_back( field );
686
687 DIALOG_SIM_MODEL dialog( this, m_parentFrame, *m_libEntry, fields );
688
689 if( dialog.ShowModal() != wxID_OK )
690 return;
691
692 // Add in any new fields
693 for( const SCH_FIELD& editedField : fields )
694 {
695 bool found = false;
696
697 for( SCH_FIELD& existingField : *m_fields )
698 {
699 if( existingField.GetName() == editedField.GetName() )
700 {
701 found = true;
702 existingField.SetText( editedField.GetText() );
703 break;
704 }
705 }
706
707 if( !found )
708 {
709 m_fields->emplace_back( editedField );
710 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
711 m_grid->ProcessTableMessage( msg );
712 }
713 }
714
715 // Remove any deleted fields
716 for( int ii = (int) m_fields->size() - 1; ii >= 0; --ii )
717 {
718 SCH_FIELD& existingField = m_fields->at( ii );
719 bool found = false;
720
721 for( SCH_FIELD& editedField : fields )
722 {
723 if( editedField.GetName() == existingField.GetName() )
724 {
725 found = true;
726 break;
727 }
728 }
729
730 if( !found )
731 {
732 m_fields->erase( m_fields->begin() + ii );
733 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, ii, 1 );
734 m_grid->ProcessTableMessage( msg );
735 }
736 }
737
738 OnModify();
739 m_grid->ForceRefresh();
740}
741
742
744{
745 int idx = m_FootprintFilterListBox->HitTest( event.GetPosition() );
746 wxCommandEvent dummy;
747
748 if( idx >= 0 )
750 else
752}
753
754
756{
757 // Running the Footprint Browser gums up the works and causes the automatic cancel
758 // stuff to no longer work. So we do it here ourselves.
759 EndQuasiModal( wxID_CANCEL );
760}
761
762
764{
765 wxString filterLine;
766 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Add Footprint Filter" ), filterLine );
767
768 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue().IsEmpty() )
769 return;
770
771 filterLine = dlg.GetValue();
772 filterLine.Replace( wxT( " " ), wxT( "_" ) );
773
774 // duplicate filters do no harm, so don't be a nanny.
775
776 m_FootprintFilterListBox->Append( filterLine );
777 m_FootprintFilterListBox->SetSelection( (int) m_FootprintFilterListBox->GetCount() - 1 );
778
779 OnModify();
780}
781
782
784{
785 int ii = m_FootprintFilterListBox->GetSelection();
786
787 if( ii >= 0 )
788 {
789 m_FootprintFilterListBox->Delete( (unsigned) ii );
790
791 if( m_FootprintFilterListBox->GetCount() == 0 )
792 m_FootprintFilterListBox->SetSelection( wxNOT_FOUND );
793 else
794 m_FootprintFilterListBox->SetSelection( std::max( 0, ii - 1 ) );
795 }
796
797 OnModify();
798}
799
800
802{
803 int idx = m_FootprintFilterListBox->GetSelection();
804
805 if( idx >= 0 )
806 {
807 wxString filter = m_FootprintFilterListBox->GetStringSelection();
808
809 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Edit Footprint Filter" ), filter );
810
811 if( dlg.ShowModal() == wxID_OK && !dlg.GetValue().IsEmpty() )
812 {
813 m_FootprintFilterListBox->SetString( (unsigned) idx, dlg.GetValue() );
814 OnModify();
815 }
816 }
817}
818
819
821{
822 // Account for scroll bars
824
825 m_grid->AutoSizeColumn( FDC_NAME );
826 m_grid->SetColSize( FDC_NAME, std::max( 72, m_grid->GetColSize( FDC_NAME ) ) );
827
828 int fixedColsWidth = m_grid->GetColSize( FDC_NAME );
829
830 for( int i = 2; i < m_grid->GetNumberCols(); i++ )
831 fixedColsWidth += m_grid->GetColSize( i );
832
833 m_grid->SetColSize( FDC_VALUE, std::max( 120, width - fixedColsWidth ) );
834}
835
836
837void DIALOG_LIB_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
838{
839 m_OptionPartsInterchangeable->Enable( m_SelNumberOfUnits->GetValue() > 1 );
841
842 if( m_grid->IsCellEditControlShown() )
843 {
844 int row = m_grid->GetGridCursorRow();
845 int col = m_grid->GetGridCursorCol();
846
847 if( row == VALUE_FIELD && col == FDC_VALUE && m_OptionPower->IsChecked() )
848 {
849 wxGridCellEditor* editor = m_grid->GetCellEditor( row, col );
850 m_SymbolNameCtrl->ChangeValue( editor->GetValue() );
851 editor->DecRef();
852 }
853 }
854
855 // Handle shown columns changes
856 std::bitset<64> shownColumns = m_grid->GetShownColumns();
857
858 if( shownColumns != m_shownColumns )
859 {
860 m_shownColumns = shownColumns;
861
862 if( !m_grid->IsCellEditControlShown() )
864 }
865
866 // Handle a delayed focus. The delay allows us to:
867 // a) change focus when the error was triggered from within a killFocus handler
868 // b) show the correct notebook page in the background before the error dialog comes up
869 // when triggered from an OK or a notebook page change
870
871 if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
872 {
873 m_NoteBook->ChangeSelection( (unsigned) m_delayedFocusPage );
875 }
876
877 if( !m_delayedErrorMessage.IsEmpty() )
878 {
879 // We will re-enter this routine when the error dialog is displayed, so make
880 // sure we don't keep putting up more dialogs.
881 wxString msg = m_delayedErrorMessage;
882 m_delayedErrorMessage = wxEmptyString;
883
884 // Do not use DisplayErrorMessage(); it screws up window order on Mac
885 DisplayError( nullptr, msg );
886 }
887
889 {
890 m_delayedFocusCtrl->SetFocus();
891
892 if( auto textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
893 textEntry->SelectAll();
894
895 m_delayedFocusCtrl = nullptr;
896 }
897 else if( m_delayedFocusGrid )
898 {
899 m_delayedFocusGrid->SetFocus();
902
903 m_delayedFocusGrid->EnableCellEditControl( true );
904 m_delayedFocusGrid->ShowCellEditControl();
905
906 m_delayedFocusGrid = nullptr;
909 }
910}
911
912
914{
915 auto new_size = event.GetSize();
916
917 if( new_size != m_size )
918 {
919 m_size = new_size;
920
922 }
923
924 // Always propagate a wxSizeEvent:
925 event.Skip();
926}
927
928
930{
931 bSizerLowerBasicPanel->Show( !aIsAlias );
932 m_inheritanceSelectCombo->Enable( aIsAlias );
933 m_inheritsStaticText->Enable( aIsAlias );
934 m_grid->ForceRefresh();
935}
936
937
939{
940 if( m_OptionPower->IsChecked() )
941 {
942 m_excludeFromSimCheckBox->SetValue( true );
943 m_excludeFromBomCheckBox->SetValue( true );
944 m_excludeFromBoardCheckBox->SetValue( true );
945 m_excludeFromBomCheckBox->Enable( false );
946 m_excludeFromBoardCheckBox->Enable( false );
947 m_excludeFromSimCheckBox->Enable( false );
948 m_spiceFieldsButton->Show( false );
949 }
950 else
951 {
952 m_excludeFromBomCheckBox->Enable( true );
953 m_excludeFromBoardCheckBox->Enable( true );
954 m_excludeFromSimCheckBox->Enable( true );
955 m_spiceFieldsButton->Show( true );
956 }
957
958 OnModify();
959}
960
961
962void DIALOG_LIB_SYMBOL_PROPERTIES::OnText( wxCommandEvent& event )
963{
964 OnModify();
965}
966
967
968void DIALOG_LIB_SYMBOL_PROPERTIES::OnCombobox( wxCommandEvent& event )
969{
970 OnModify();
971}
972
973
974void DIALOG_LIB_SYMBOL_PROPERTIES::OnCheckBox( wxCommandEvent& event )
975{
976 OnModify();
977}
978
979
981{
982 OnModify();
983}
984
985
987{
988 OnModify();
989}
990
991
992void DIALOG_LIB_SYMBOL_PROPERTIES::OnPageChanging( wxBookCtrlEvent& aEvent )
993{
995 aEvent.Veto();
996}
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
void OnFilterDClick(wxMouseEvent &event) override
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 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:229
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:404
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:275
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: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
static bool IsReferenceStringValid(const wxString &aReferenceString)
Test for an acceptable reference string.
Definition: sch_symbol.cpp:769
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
SETTINGS_MANAGER * GetSettingsManager()
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
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".
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691