KiCad PCB EDA Suite
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-2022 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 <bitmaps.h>
25#include <confirm.h>
27#include <kiway.h>
28#include <symbol_edit_frame.h>
30#include <math/util.h> // for KiROUND
31#include <sch_symbol.h>
32#include <kiplatform/ui.h>
34#include <widgets/wx_grid.h>
36#include <string_utils.h>
37
38#ifdef KICAD_SPICE
39#include <dialog_sim_model.h>
40#endif /* KICAD_SPICE */
41
45
46
50
51
53 LIB_SYMBOL* aLibEntry ) :
55 m_Parent( aParent ),
56 m_libEntry( aLibEntry ),
57 m_pinNameOffset( aParent, m_nameOffsetLabel, m_nameOffsetCtrl, m_nameOffsetUnits, true ),
58 m_delayedFocusCtrl( nullptr ),
59 m_delayedFocusGrid( nullptr ),
60 m_delayedFocusRow( -1 ),
61 m_delayedFocusColumn( -1 ),
62 m_delayedFocusPage( -1 )
63{
64 // Give a bit more room for combobox editors
65 m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
68 m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this ) );
69 m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
70
71 // Show/hide columns according to the user's preference
74
75 wxGridCellAttr* attr = new wxGridCellAttr;
76 attr->SetEditor( new GRID_CELL_URL_EDITOR( this, Prj().SchSearchS() ) );
77 m_grid->SetAttr( DATASHEET_FIELD, FDC_VALUE, attr );
78
79 m_SymbolNameCtrl->SetValidator( SCH_FIELD_VALIDATOR( true, VALUE_FIELD ) );
80
81 // Configure button logos
89
91
92 if( aParent->IsSymbolFromLegacyLibrary() && !aParent->IsSymbolFromSchematic() )
93 {
94 m_stdSizerButtonCancel->SetDefault();
95 m_stdSizerButtonOK->SetLabel( _( "Read Only" ) );
96 m_stdSizerButtonOK->Enable( false );
97 }
98
99#ifndef KICAD_SPICE
100 m_excludeFromSim->Hide();
101 m_spiceFieldsButton->Hide();
102#endif
103
104 // wxFormBuilder doesn't include this event...
105 m_grid->Connect( wxEVT_GRID_CELL_CHANGING,
107 nullptr, this );
108
110 {
113 {
114 resetSize();
115 }
116 }
117
120
121 m_grid->GetParent()->Layout();
123 Layout();
124
126}
127
128
130{
131 m_lastOpenedPage = m_NoteBook->GetSelection( );
132
135
136 // Prevents crash bug in wxGrid's d'tor
138
139 m_grid->Disconnect( wxEVT_GRID_CELL_CHANGING,
141 nullptr, this );
142
143 // Delete the GRID_TRICKS.
144 m_grid->PopEventHandler( true );
145}
146
147
149{
150 if( !wxDialog::TransferDataToWindow() )
151 return false;
152
153 // Push a copy of each field into m_updateFields
155
156 // The Y axis for components in lib is from bottom to top while the screen axis is top
157 // to bottom: we must change the y coord sign for editing
158 for( size_t i = 0; i < m_fields->size(); ++i )
159 {
160 VECTOR2I pos = m_fields->at( i ).GetPosition();
161 pos.y = -pos.y;
162 m_fields->at( i ).SetPosition( pos );
163 }
164
165 // notify the grid
166 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->GetNumberRows() );
167 m_grid->ProcessTableMessage( msg );
169
171
172 m_DescCtrl->ChangeValue( m_libEntry->GetDescription() );
173 m_KeywordCtrl->ChangeValue( m_libEntry->GetKeyWords() );
176 m_libEntry->GetUnitCount() == 1 );
177
178 // If a symbol contains no conversion-specific pins or graphic items, symbol->HasConversion()
179 // will return false. But when editing a symbol with DeMorgan option set, we don't want to
180 // keep turning it off just because there aren't any conversion-specific items yet, so we force
181 // it to on if the parent frame has it enabled.
183
184 m_OptionPower->SetValue( m_libEntry->IsPower() );
185
186#ifdef KICAD_SPICE
187 LIB_FIELD* simEnableField = m_libEntry->FindField( SIM_ENABLE_FIELD );
188 m_excludeFromSim->SetValue( simEnableField && simEnableField->GetText() == wxT( "0" ) );
189#endif
190
193
198
199 wxArrayString tmp = m_libEntry->GetFPFilters();
200 m_FootprintFilterListBox->Append( tmp );
201
202 // Populate the list of root parts for inherited objects.
203 if( m_libEntry->IsAlias() )
204 {
205 wxArrayString rootSymbolNames;
206 wxString libName = m_Parent->GetCurLib();
207
208 // Someone forgot to set the current library in the editor frame window.
209 wxCHECK( !libName.empty(), false );
210
211 m_Parent->GetLibManager().GetRootSymbolNames( libName, rootSymbolNames );
212 m_inheritanceSelectCombo->Append( rootSymbolNames );
213
214 LIB_SYMBOL_SPTR rootSymbol = m_libEntry->GetParent().lock();
215
216 wxCHECK( rootSymbol, false );
217
218 wxString parentName = UnescapeString( rootSymbol->GetName() );
219 int selection = m_inheritanceSelectCombo->FindString( parentName );
220
221 wxCHECK( selection != wxNOT_FOUND, false );
222 m_inheritanceSelectCombo->SetSelection( selection );
223
225 }
226
227 m_NoteBook->SetSelection( (unsigned) m_lastOpenedPage );
228
229 return true;
230}
231
232
234{
235#ifdef KICAD_SPICE
236 int simEnableFieldRow = -1;
237
238 for( int ii = MANDATORY_FIELDS; ii < m_grid->GetNumberRows(); ++ii )
239 {
240 if( m_grid->GetCellValue( ii, FDC_NAME ) == SIM_ENABLE_FIELD )
241 simEnableFieldRow = ii;
242 }
243
244 if( event.IsChecked() )
245 {
246 if( simEnableFieldRow == -1 )
247 {
248 simEnableFieldRow = (int) m_fields->size();
249 m_fields->emplace_back( m_libEntry, simEnableFieldRow, SIM_ENABLE_FIELD );
250
251 // notify the grid
252 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
253 m_grid->ProcessTableMessage( msg );
254 }
255
256 m_grid->SetCellValue( simEnableFieldRow, FDC_VALUE, wxT( "0" ) );
257 m_grid->SetCellValue( simEnableFieldRow, FDC_SHOWN, wxT( "0" ) );
258 m_grid->SetCellValue( simEnableFieldRow, FDC_SHOW_NAME, wxT( "0" ) );
259 }
260 else if( simEnableFieldRow >= 0 )
261 {
262 m_fields->erase( m_fields->begin() + simEnableFieldRow );
263
264 // notify the grid
265 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, simEnableFieldRow, 1 );
266 m_grid->ProcessTableMessage( msg );
267 }
268
269 OnModify();
270#endif
271}
272
273
275{
277 return false;
278
279 // Alias symbol reference can be empty because it inherits from the parent symbol.
280 if( m_libEntry->IsRoot() &&
282 {
283 if( m_NoteBook->GetSelection() != 0 )
284 m_NoteBook->SetSelection( 0 );
285
286 m_delayedErrorMessage = _( "References must start with a letter." );
291
292 return false;
293 }
294
295 // Check for missing field names.
296 for( int ii = MANDATORY_FIELDS; ii < (int) m_fields->size(); ++ii )
297 {
298 LIB_FIELD& field = m_fields->at( ii );
299 wxString fieldName = field.GetName( false );
300
301 if( fieldName.IsEmpty() )
302 {
303 if( m_NoteBook->GetSelection() != 0 )
304 m_NoteBook->SetSelection( 0 );
305
306 m_delayedErrorMessage = _( "Fields must have a name." );
311
312 return false;
313 }
314 }
315
316 // Verify that the parent name is set if the symbol is inherited
317 if( m_libEntry->IsAlias() )
318 {
319 wxString parentName = m_inheritanceSelectCombo->GetValue();
320
321 if( parentName.IsEmpty() )
322 {
323 m_delayedErrorMessage = _( "Derived symbol must have a parent selected" );
324
325 return false;
326 }
327 }
328
329 /*
330 * Confirm destructive actions.
331 */
332
333 if( m_SelNumberOfUnits->GetValue() < m_libEntry->GetUnitCount() )
334 {
335 if( !IsOK( this, _( "Delete extra units from symbol?" ) ) )
336 return false;
337 }
338
339 if( !m_AsConvertButt->GetValue() && m_libEntry->HasConversion() )
340 {
341 if( !IsOK( this, _( "Delete alternate body style (De Morgan) from symbol?" ) ) )
342 return false;
343 }
344
345 return true;
346}
347
348
350{
351 if( !wxDialog::TransferDataFromWindow() )
352 return false;
353
355 return false;
356
357 wxString newName = EscapeString( m_SymbolNameCtrl->GetValue(), CTX_LIBID );
358 wxString oldName = m_libEntry->GetName();
359
360 if( oldName != newName )
361 {
362 wxString libName = m_Parent->GetCurLib();
363
364 if( m_Parent->GetLibManager().SymbolExists( newName, libName ) )
365 {
366 wxString msg;
367
368 msg.Printf( _( "Symbol name '%s' already in use in library '%s'." ),
369 UnescapeString( newName ),
370 libName );
371 DisplayErrorMessage( this, msg );
372 return false;
373 }
374
376 }
377 else
378 {
380 }
381
382 // The Y axis for components in lib is from bottom to top while the screen axis is top
383 // to bottom: we must change the y coord sign when writing back to the library
384 for( int ii = 0; ii < (int) m_fields->size(); ++ii )
385 {
386 VECTOR2I pos = m_fields->at( ii ).GetPosition();
387 pos.y = -pos.y;
388 m_fields->at( ii ).SetPosition( pos );
389 m_fields->at( ii ).SetId( ii );
390 }
391
393
394 // Update the parent for inherited symbols
395 if( m_libEntry->IsAlias() )
396 {
397 wxString parentName = EscapeString( m_inheritanceSelectCombo->GetValue(), CTX_LIBID );
398
399 // The parentName was verified to be non-empty in the Validator
400 wxString libName = m_Parent->GetCurLib();
401
402 // Get the parent from the libManager based on the name set in the inheritance combo box.
403 LIB_SYMBOL* newParent = m_Parent->GetLibManager().GetAlias( parentName, libName );
404
405 // Verify that the requested parent exists
406 wxCHECK( newParent, false );
407
408 // Verify that the new parent is not an alias.
409 wxCHECK( !newParent->IsAlias(), false );
410
411 m_libEntry->SetParent( newParent );
412 }
413
414 m_libEntry->SetName( newName );
415 m_libEntry->SetDescription( m_DescCtrl->GetValue() );
416 m_libEntry->SetKeyWords( m_KeywordCtrl->GetValue() );
419 !m_OptionPartsInterchangeable->GetValue() );
422
423 if( m_OptionPower->GetValue() )
424 {
426 // Power symbols must have value matching name for now
427 m_libEntry->GetValueField().SetText( newName );
428 }
429 else
430 {
432 }
433
436
439
440 if( m_PinsNameInsideButt->GetValue() )
441 {
442 int offset = KiROUND( (double) m_pinNameOffset.GetValue() );
443
444 // We interpret an offset of 0 as "outside", so make sure it's non-zero
445 m_libEntry->SetPinNameOffset( offset == 0 ? 20 : offset );
446 }
447 else
448 {
449 m_libEntry->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
450 }
451
453
455
456 // It's possible that the symbol being edited has no pins, in which case there may be no
457 // alternate body style objects causing #LIB_SYMBOL::HasCoversion() to always return false.
458 // This allows the user to edit the alternate body style just in case this condition occurs.
460
461 return true;
462}
463
464
466{
467 wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
468 wxControl* control = editor->GetControl();
469
470 if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
471 {
472 event.Veto();
473
475 m_delayedFocusRow = event.GetRow();
476 m_delayedFocusColumn = event.GetCol();
478 }
479 else if( event.GetCol() == FDC_NAME )
480 {
481 wxString newName = event.GetString();
482
483 for( int i = 0; i < m_grid->GetNumberRows(); ++i )
484 {
485 if( i == event.GetRow() )
486 continue;
487
488 if( newName.CmpNoCase( m_grid->GetCellValue( i, FDC_NAME ) ) == 0 )
489 {
490 DisplayError( this, wxString::Format( _( "The name '%s' is already in use." ),
491 newName ) );
492 event.Veto();
493 m_delayedFocusRow = event.GetRow();
494 m_delayedFocusColumn = event.GetCol();
495 }
496 }
497 }
498
499 editor->DecRef();
500}
501
502
504{
505 if( m_OptionPower->IsChecked() )
506 m_grid->SetCellValue( VALUE_FIELD, FDC_VALUE, m_SymbolNameCtrl->GetValue() );
507}
508
509
511{
512 if( !m_delayedFocusCtrl )
513 {
514 // If the validation fails and we throw up a dialog then GTK will give us another
515 // KillFocus event and we end up in infinite recursion. So we use m_delayedFocusCtrl
516 // as a re-entrancy block and then clear it again if validation passes.
519
520 if( m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
521 {
522 m_delayedFocusCtrl = nullptr;
524 }
525 }
526
527 event.Skip();
528}
529
530
531void DIALOG_LIB_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
532{
534 return;
535
537 int fieldID = (int) m_fields->size();
538 LIB_FIELD newField( m_libEntry, fieldID );
539
540 newField.SetTextSize( wxSize( schIUScale.MilsToIU( settings->m_Defaults.text_size ),
541 schIUScale.MilsToIU( settings->m_Defaults.text_size ) ) );
542
543 m_fields->push_back( newField );
544
545 // notify the grid
546 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
547 m_grid->ProcessTableMessage( msg );
548
549 m_grid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
550 m_grid->SetGridCursor( (int) m_fields->size() - 1, 0 );
551
552 m_grid->EnableCellEditControl();
553 m_grid->ShowCellEditControl();
554
555 OnModify();
556}
557
558
560{
561 wxArrayInt selectedRows = m_grid->GetSelectedRows();
562
563 if( selectedRows.empty() && m_grid->GetGridCursorRow() >= 0 )
564 selectedRows.push_back( m_grid->GetGridCursorRow() );
565
566 if( selectedRows.empty() )
567 return;
568
569 for( int row : selectedRows )
570 {
571 if( row < MANDATORY_FIELDS )
572 {
573 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
575 return;
576 }
577 }
578
579 m_grid->CommitPendingChanges( true /* quiet mode */ );
580
581 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
582 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
583
584 for( int row : selectedRows )
585 {
586 m_fields->erase( m_fields->begin() + row );
587
588 // notify the grid
589 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
590 m_grid->ProcessTableMessage( msg );
591
592 if( m_grid->GetNumberRows() > 0 )
593 {
594 m_grid->MakeCellVisible( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
595 m_grid->SetGridCursor( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
596 }
597 }
598
599 OnModify();
600}
601
602
603void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
604{
606 return;
607
608 int i = m_grid->GetGridCursorRow();
609
610 if( i > MANDATORY_FIELDS )
611 {
612 LIB_FIELD tmp = m_fields->at( (unsigned) i );
613 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
614 m_fields->insert( m_fields->begin() + i - 1, tmp );
615 m_grid->ForceRefresh();
616
617 m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
618 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
619
620 OnModify();
621 }
622 else
623 {
624 wxBell();
625 }
626}
627
628
629void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
630{
632 return;
633
634 int i = m_grid->GetGridCursorRow();
635
636 if( i >= MANDATORY_FIELDS && i + 1 < m_fields->GetNumberRows() )
637 {
638 LIB_FIELD tmp = m_fields->at( (unsigned) i );
639 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
640 m_fields->insert( m_fields->begin() + i + 1, tmp );
641 m_grid->ForceRefresh();
642
643 m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
644 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
645
646 OnModify();
647 }
648 else
649 {
650 wxBell();
651 }
652}
653
654
656{
657#ifdef KICAD_SPICE
659 return;
660
661 std::vector<LIB_FIELD> fields;
662
663 for( const LIB_FIELD& field : *m_fields )
664 fields.emplace_back( field );
665
666 DIALOG_SIM_MODEL dialog( this, *m_libEntry, fields );
667
668 if( dialog.ShowModal() != wxID_OK )
669 return;
670
671 // Add in any new fields
672 for( const LIB_FIELD& editedField : fields )
673 {
674 bool found = false;
675
676 for( LIB_FIELD& existingField : *m_fields )
677 {
678 if( existingField.GetName() == editedField.GetName() )
679 {
680 found = true;
681 existingField.SetText( editedField.GetText() );
682 break;
683 }
684 }
685
686 if( !found )
687 {
688 m_fields->emplace_back( editedField );
689 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
690 m_grid->ProcessTableMessage( msg );
691 }
692 }
693
694 // Remove any deleted fields
695 for( int ii = (int) m_fields->size() - 1; ii >= 0; /* advance in loop */ )
696 {
697 LIB_FIELD& existingField = m_fields->at( ii );
698 bool found = false;
699
700 for( LIB_FIELD& editedField : fields )
701 {
702 if( editedField.GetName() == existingField.GetName() )
703 {
704 found = true;
705 break;
706 }
707 }
708
709 if( found )
710 {
711 ii--;
712 }
713 else
714 {
715 m_fields->erase( m_fields->begin() + ii );
716 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, ii, 1 );
717 m_grid->ProcessTableMessage( msg );
718 }
719 }
720
721 OnModify();
722 m_grid->ForceRefresh();
723#endif /* KICAD_SPICE */
724}
725
726
728{
729 int idx = m_FootprintFilterListBox->HitTest( event.GetPosition() );
730 wxCommandEvent dummy;
731
732 if( idx >= 0 )
734 else
736}
737
738
740{
741 // Running the Footprint Browser gums up the works and causes the automatic cancel
742 // stuff to no longer work. So we do it here ourselves.
743 EndQuasiModal( wxID_CANCEL );
744}
745
746
748{
749 wxString filterLine;
750 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Add Footprint Filter" ), filterLine );
751
752 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue().IsEmpty() )
753 return;
754
755 filterLine = dlg.GetValue();
756 filterLine.Replace( wxT( " " ), wxT( "_" ) );
757
758 // duplicate filters do no harm, so don't be a nanny.
759
760 m_FootprintFilterListBox->Append( filterLine );
761 m_FootprintFilterListBox->SetSelection( (int) m_FootprintFilterListBox->GetCount() - 1 );
762
763 OnModify();
764}
765
766
768{
769 int ii = m_FootprintFilterListBox->GetSelection();
770
771 if( ii >= 0 )
772 {
773 m_FootprintFilterListBox->Delete( (unsigned) ii );
774
775 if( m_FootprintFilterListBox->GetCount() == 0 )
776 m_FootprintFilterListBox->SetSelection( wxNOT_FOUND );
777 else
778 m_FootprintFilterListBox->SetSelection( std::max( 0, ii - 1 ) );
779 }
780
781 OnModify();
782}
783
784
786{
787 int idx = m_FootprintFilterListBox->GetSelection();
788
789 if( idx >= 0 )
790 {
791 wxString filter = m_FootprintFilterListBox->GetStringSelection();
792
793 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Edit Footprint Filter" ), filter );
794
795 if( dlg.ShowModal() == wxID_OK && !dlg.GetValue().IsEmpty() )
796 {
797 m_FootprintFilterListBox->SetString( (unsigned) idx, dlg.GetValue() );
798 OnModify();
799 }
800 }
801}
802
803
805{
806 // Account for scroll bars
808
809 m_grid->AutoSizeColumn( FDC_NAME );
810 m_grid->SetColSize( FDC_NAME, std::max( 72, m_grid->GetColSize( FDC_NAME ) ) );
811
812 int fixedColsWidth = m_grid->GetColSize( FDC_NAME );
813
814 for( int i = 2; i < m_grid->GetNumberCols(); i++ )
815 fixedColsWidth += m_grid->GetColSize( i );
816
817 m_grid->SetColSize( FDC_VALUE, std::max( 120, width - fixedColsWidth ) );
818}
819
820
821void DIALOG_LIB_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
822{
823 m_OptionPartsInterchangeable->Enable( m_SelNumberOfUnits->GetValue() > 1 );
825
826 if( m_grid->IsCellEditControlShown() )
827 {
828 int row = m_grid->GetGridCursorRow();
829 int col = m_grid->GetGridCursorCol();
830
831 if( row == VALUE_FIELD && col == FDC_VALUE && m_OptionPower->IsChecked() )
832 {
833 wxGridCellEditor* editor = m_grid->GetCellEditor( row, col );
834 m_SymbolNameCtrl->ChangeValue( editor->GetValue() );
835 editor->DecRef();
836 }
837 }
838
839 // Handle shown columns changes
840 wxString shownColumns = m_grid->GetShownColumns();
841
842 if( shownColumns != m_shownColumns )
843 {
844 m_shownColumns = shownColumns;
845
846 if( !m_grid->IsCellEditControlShown() )
848 }
849
850 // Handle a delayed focus. The delay allows us to:
851 // a) change focus when the error was triggered from within a killFocus handler
852 // b) show the correct notebook page in the background before the error dialog comes up
853 // when triggered from an OK or a notebook page change
854
855 if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
856 {
857 m_NoteBook->ChangeSelection( (unsigned) m_delayedFocusPage );
859 }
860
861 if( !m_delayedErrorMessage.IsEmpty() )
862 {
863 // We will re-enter this routine when the error dialog is displayed, so make
864 // sure we don't keep putting up more dialogs.
865 wxString msg = m_delayedErrorMessage;
866 m_delayedErrorMessage = wxEmptyString;
867
868 // Do not use DisplayErrorMessage(); it screws up window order on Mac
869 DisplayError( nullptr, msg );
870 }
871
873 {
874 m_delayedFocusCtrl->SetFocus();
875
876 if( auto textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
877 textEntry->SelectAll();
878
879 m_delayedFocusCtrl = nullptr;
880 }
881 else if( m_delayedFocusGrid )
882 {
883 m_delayedFocusGrid->SetFocus();
886
887 m_delayedFocusGrid->EnableCellEditControl( true );
888 m_delayedFocusGrid->ShowCellEditControl();
889
890 m_delayedFocusGrid = nullptr;
893 }
894
895#ifdef KICAD_SPICE
896 wxString simEnable;
897
898 for( int ii = MANDATORY_FIELDS; ii < m_fields->GetNumberRows(); ++ii )
899 {
901 {
902 simEnable = m_fields->GetValue( ii, FDC_VALUE );
903 break;
904 }
905 }
906
907 m_excludeFromSim->SetValue( simEnable == wxS( "0" ) );
908#endif
909}
910
911
913{
914 auto new_size = event.GetSize();
915
916 if( new_size != m_size )
917 {
918 m_size = new_size;
919
921 }
922
923 // Always propagate a wxSizeEvent:
924 event.Skip();
925}
926
927
929{
930 bSizerLowerBasicPanel->Show( !aIsAlias );
931 m_inheritanceSelectCombo->Enable( aIsAlias );
932 m_inheritsStaticText->Enable( aIsAlias );
933 m_grid->ForceRefresh();
934}
935
936
938{
939 if( m_OptionPower->IsChecked() )
940 {
941 m_excludeFromBomCheckBox->SetValue( true );
942 m_excludeFromBoardCheckBox->SetValue( true );
943 m_excludeFromBomCheckBox->Enable( false );
944 m_excludeFromBoardCheckBox->Enable( false );
945 }
946 else
947 {
948 m_excludeFromBomCheckBox->Enable( true );
949 m_excludeFromBoardCheckBox->Enable( true );
950 }
951
952 OnModify();
953}
954
955
956void DIALOG_LIB_SYMBOL_PROPERTIES::OnText( wxCommandEvent& event )
957{
958 OnModify();
959}
960
961
962void DIALOG_LIB_SYMBOL_PROPERTIES::OnCombobox( wxCommandEvent& event )
963{
964 OnModify();
965}
966
967
968void DIALOG_LIB_SYMBOL_PROPERTIES::OnCheckBox( wxCommandEvent& event )
969{
970 OnModify();
971}
972
973
975{
976 OnModify();
977}
978
979
981{
982 OnModify();
983}
984
985
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:105
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
FIELDS_GRID_TABLE< LIB_FIELD > * m_fields
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 OnExcludeFromSimulation(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...
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:87
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:347
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:163
wxString GetValue(int aRow, int aCol) override
int GetNumberRows() override
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Field object used in symbol libraries.
Definition: lib_field.h:61
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: lib_field.cpp:470
Define a library symbol object.
Definition: lib_symbol.h:99
void SetIncludeOnBoard(bool aIncludeOnBoard)
Set or clear include in board netlist flag.
Definition: lib_symbol.h:648
void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: lib_symbol.h:624
int GetPinNameOffset() const
Definition: lib_symbol.h:617
wxString GetKeyWords() const
Definition: lib_symbol.h:164
void SetConversion(bool aSetConvert, bool aDuplicatePins=true)
Set or clear the alternate body style (DeMorgan) for the symbol.
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:258
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition: lib_symbol.h:187
void SetPinNameOffset(int aOffset)
Set the offset in mils of the pin name text from the pin symbol.
Definition: lib_symbol.h:616
bool IsAlias() const
Definition: lib_symbol.h:188
bool IsPower() const
Definition: lib_symbol.cpp:548
bool GetIncludeOnBoard() const
Definition: lib_symbol.h:649
void SetPower()
Definition: lib_symbol.cpp:557
bool ShowPinNames() const
Definition: lib_symbol.h:625
void LockUnits(bool aLockUnits)
Set interchangeable the property for symbol units.
Definition: lib_symbol.h:252
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: lib_symbol.h:632
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:447
wxString GetName() const override
Definition: lib_symbol.h:138
void SetDescription(const wxString &aDescription)
Definition: lib_symbol.h:149
void SetKeyWords(const wxString &aKeyWords)
Definition: lib_symbol.h:162
void GetFields(std::vector< LIB_FIELD * > &aList)
Return a list of fields within this symbol.
LIB_FIELD * FindField(const wxString &aFieldName)
Find a field within this symbol matching aFieldName and returns it or NULL if not found.
wxArrayString GetFPFilters() const
Definition: lib_symbol.h:199
LIB_FIELD & GetValueField()
Return reference to the value field.
void SetFPFilters(const wxArrayString &aFilters)
Definition: lib_symbol.h:197
bool GetIncludeInBom() const
Definition: lib_symbol.h:641
wxString GetDescription() override
Definition: lib_symbol.h:151
int GetUnitCount() const override
For items with units, return the number of units.
void SetIncludeInBom(bool aIncludeInBom)
Set or clear the include in schematic bill of materials flag.
Definition: lib_symbol.h:640
bool HasConversion() const
Test if symbol has more than one body conversion type (DeMorgan).
LIB_SYMBOL_REF & GetParent()
Definition: lib_symbol.h:127
void SetFields(const std::vector< LIB_FIELD > &aFieldsList)
Overwrite all the existing fields in this symbol with fields supplied in aFieldsList.
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:437
void SetNormal()
Definition: lib_symbol.cpp:575
bool ShowPinNumbers() const
Definition: lib_symbol.h:633
A text control validator used for validating the text allowed in library and schematic symbol fields.
static bool IsReferenceStringValid(const wxString &aReferenceString)
Test for an acceptable reference string.
Definition: sch_symbol.cpp:688
void SetBitmap(const wxBitmap &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
SYMBOL_EDITOR_SETTINGS * GetSettings() const
LIB_SYMBOL_LIBRARY_MANAGER & GetLibManager()
void SetShowDeMorgan(bool show)
void SaveCopyInUndoList(EDA_ITEM *aItem, UNDO_REDO aUndoType=UNDO_REDO::LIBEDIT, bool aAppend=false)
Create a copy of the current symbol, and save it in the undo list.
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...
void GetRootSymbolNames(const wxString &aLibName, wxArrayString &aRootSymbolNames)
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).
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:295
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:164
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:262
wxString GetShownColumns()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:276
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:423
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:380
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:300
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:325
This file is part of the common library.
#define _(s)
@ FDC_SHOW_NAME
@ FDC_NAME
@ FDC_SHOWN
@ 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: gtk/ui.cpp:126
must_if< error >::control< Rule > control
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
#define SIM_ENABLE_FIELD
Definition: sim_model.h:55
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:55
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
@ DATASHEET_FIELD
name of datasheet
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ MANDATORY_FIELDS
The first 4 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:85