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