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