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 The 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 );
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
91
92 // Configure button logos
93 m_bpAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
94 m_bpDelete->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
95 m_bpMoveUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
96 m_bpMoveDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
97 m_addFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
98 m_deleteFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
99 m_editFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_edit ) );
100
102
103 if( aParent->IsSymbolFromLegacyLibrary() && !aParent->IsSymbolFromSchematic() )
104 {
105 m_stdSizerButtonCancel->SetDefault();
106 m_stdSizerButtonOK->SetLabel( _( "Read Only" ) );
107 m_stdSizerButtonOK->Enable( false );
108 }
109
110 // wxFormBuilder doesn't include this event...
111 m_grid->Connect( wxEVT_GRID_CELL_CHANGING,
113 nullptr, this );
114
115 // Forward the delete button to the tricks
116 m_deleteFilterButton->Bind( wxEVT_BUTTON,
117 [&]( wxCommandEvent& aEvent )
118 {
119 wxCommandEvent cmdEvent( EDA_EVT_LISTBOX_DELETE );
120 m_fpFilterTricks->ProcessEvent( cmdEvent );
121 } );
122
123 // When the filter tricks modifies something, update ourselves
124 m_FootprintFilterListBox->Bind( EDA_EVT_LISTBOX_CHANGED,
125 [&]( wxCommandEvent& aEvent )
126 {
127 OnModify();
128 } );
129
131 {
133 && aLibEntry->IsRoot() )
135 && aLibEntry->IsAlias() ) )
136 {
137 resetSize();
138 }
139 }
140
143
144 m_grid->GetParent()->Layout();
146 Layout();
147
149}
150
151
153{
154 m_lastOpenedPage = m_NoteBook->GetSelection( );
155
157 cfg->m_EditSymbolVisibleColumns = m_grid->GetShownColumnsAsString();
158
159 // Prevents crash bug in wxGrid's d'tor
161
162 m_grid->Disconnect( wxEVT_GRID_CELL_CHANGING,
164 nullptr, this );
165
166 // Delete the GRID_TRICKS.
167 m_grid->PopEventHandler( true );
168}
169
170
172{
173 if( !wxDialog::TransferDataToWindow() )
174 return false;
175
176 // Push a copy of each field into m_updateFields
178
179 std::set<wxString> defined;
180
181 for( SCH_FIELD& field : *m_fields )
182 defined.insert( field.GetName() );
183
184 // Add in any template fieldnames not yet defined:
185 // Read global fieldname templates
187 EESCHEMA_SETTINGS* cfg = mgr.GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
188
189 if( cfg )
190 {
191 TEMPLATES templateMgr;
192
193 if( !cfg->m_Drawing.field_names.IsEmpty() )
194 templateMgr.AddTemplateFieldNames( cfg->m_Drawing.field_names );
195
196 for( const TEMPLATE_FIELDNAME& templateFieldname : templateMgr.GetTemplateFieldNames() )
197 {
198 if( defined.count( templateFieldname.m_Name ) <= 0 )
199 {
200 SCH_FIELD field( VECTOR2I( 0, 0 ), -1, m_libEntry, templateFieldname.m_Name );
201 field.SetVisible( templateFieldname.m_Visible );
202 m_fields->push_back( field );
203 m_addedTemplateFields.insert( templateFieldname.m_Name );
204 }
205 }
206 }
207
208 // The Y axis for components in lib is from bottom to top while the screen axis is top
209 // to bottom: we must change the y coord sign for editing
210 for( size_t i = 0; i < m_fields->size(); ++i )
211 {
212 VECTOR2I pos = m_fields->at( i ).GetPosition();
213 pos.y = -pos.y;
214 m_fields->at( i ).SetPosition( pos );
215 }
216
217 // notify the grid
218 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->GetNumberRows() );
219 m_grid->ProcessTableMessage( msg );
221
223
224 m_KeywordCtrl->ChangeValue( m_libEntry->GetKeyWords() );
227 m_libEntry->GetUnitCount() == 1 );
228
229 // If a symbol contains no body-style-specific pins or graphic items,
230 // symbol->HasAlternateBodyStyle() will return false.
231 // But when editing a symbol with DeMorgan option set, we don't want to keep turning it off
232 // just because there aren't any body-style-specific items yet, so we force it to on if the
233 // parent frame has it enabled.
235
236 m_OptionPower->SetValue( m_libEntry->IsPower() );
237
238 if( m_libEntry->IsPower() )
239 m_spiceFieldsButton->Hide();
240
244
249
250 wxArrayString tmp = m_libEntry->GetFPFilters();
251 m_FootprintFilterListBox->Append( tmp );
252
253 // Populate the list of root parts for inherited objects.
254 if( m_libEntry->IsAlias() )
255 {
256 wxArrayString symbolNames;
257 wxString libName = m_Parent->GetCurLib();
258
259 // Someone forgot to set the current library in the editor frame window.
260 wxCHECK( !libName.empty(), false );
261
262 m_Parent->GetLibManager().GetSymbolNames( libName, symbolNames );
263
264 // Sort the list of symbols for easier search
265 symbolNames.Sort(
266 []( const wxString& a, const wxString& b ) -> int
267 {
268 return StrNumCmp( a, b, true );
269 } );
270
271 // Do allow an inherited symbol to be derived from itself.
272 symbolNames.Remove( m_libEntry->GetName() );
273 m_inheritanceSelectCombo->Append( symbolNames );
274
275 if( LIB_SYMBOL_SPTR rootSymbol = m_libEntry->GetParent().lock() )
276 {
277 wxString parentName = UnescapeString( rootSymbol->GetName() );
278 int selection = m_inheritanceSelectCombo->FindString( parentName );
279
280 if( selection == wxNOT_FOUND )
281 return false;
282
283 m_inheritanceSelectCombo->SetSelection( selection );
284 }
285
287 }
288
289 m_NoteBook->SetSelection( (unsigned) m_lastOpenedPage );
290
292
293 return true;
294}
295
296
298{
300 return false;
301
302 // Alias symbol reference can be empty because it inherits from the parent symbol.
303 if( m_libEntry->IsRoot()
304 && UTIL::GetRefDesPrefix( m_fields->at( REFERENCE_FIELD ).GetText() ).IsEmpty() )
305 {
306 if( m_NoteBook->GetSelection() != 0 )
307 m_NoteBook->SetSelection( 0 );
308
309 m_delayedErrorMessage = _( "References must start with a letter." );
314
315 return false;
316 }
317
318 // Check for missing field names.
319 for( int ii = 0; ii < (int) m_fields->size(); ++ii )
320 {
321 SCH_FIELD& field = m_fields->at( ii );
322
323 if( field.IsMandatory() )
324 continue;
325
326 wxString fieldName = field.GetName( false );
327
328 if( fieldName.IsEmpty() && !field.GetText().IsEmpty() )
329 {
330 if( m_NoteBook->GetSelection() != 0 )
331 m_NoteBook->SetSelection( 0 );
332
333 m_delayedErrorMessage = _( "Fields must have a name." );
338
339 return false;
340 }
341 }
342
343 // Verify that the parent name is set if the symbol is inherited
344 if( m_libEntry->IsAlias() )
345 {
346 wxString parentName = m_inheritanceSelectCombo->GetValue();
347
348 if( parentName.IsEmpty() )
349 {
350 m_delayedErrorMessage = _( "Derived symbol must have a parent selected" );
351
352 return false;
353 }
354 }
355
356 /*
357 * Confirm destructive actions.
358 */
359
360 if( m_SelNumberOfUnits->GetValue() < m_libEntry->GetUnitCount() )
361 {
362 if( !IsOK( this, _( "Delete extra units from symbol?" ) ) )
363 return false;
364 }
365
367 {
368 if( !IsOK( this, _( "Delete alternate body style (De Morgan) from symbol?" ) ) )
369 return false;
370 }
371
372 return true;
373}
374
375
377{
378 if( !wxDialog::TransferDataFromWindow() )
379 return false;
380
382 return false;
383
384 wxString newName = EscapeString( m_SymbolNameCtrl->GetValue(), CTX_LIBID );
385 wxString oldName = m_libEntry->GetName();
386
387 if( newName.IsEmpty() )
388 {
389 wxMessageBox( _( "Symbol must have a name." ) );
390 return false;
391 }
392
393 if( oldName != newName )
394 {
395 wxString libName = m_Parent->GetCurLib();
396
397 if( m_Parent->GetLibManager().SymbolExists( newName, libName ) )
398 {
399 wxString msg;
400
401 msg.Printf( _( "Symbol name '%s' already in use in library '%s'." ),
402 UnescapeString( newName ),
403 libName );
404 DisplayErrorMessage( this, msg );
405 return false;
406 }
407
408 m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry,
409 UNDO_REDO::LIB_RENAME );
410 }
411 else
412 {
413 m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry );
414 }
415
416 // The Y axis for components in lib is from bottom to top while the screen axis is top
417 // to bottom: we must change the y coord sign when writing back to the library
418 for( int ii = 0; ii < (int) m_fields->size(); ++ii )
419 {
420 VECTOR2I pos = m_fields->at( ii ).GetPosition();
421 pos.y = -pos.y;
422 m_fields->at( ii ).SetPosition( pos );
423 m_fields->at( ii ).SetId( ii );
424 }
425
426 for( int ii = m_fields->GetNumberRows() - 1; ii >= 0; ii-- )
427 {
428 SCH_FIELD& field = m_fields->at( ii );
429
430 if( field.IsMandatory() )
431 continue;
432
433 const wxString& fieldName = field.GetCanonicalName();
434
435 if( field.GetText().IsEmpty() )
436 {
437 if( fieldName.IsEmpty() || m_addedTemplateFields.contains( fieldName ) )
438 m_fields->erase( m_fields->begin() + ii );
439 }
440 else if( fieldName.IsEmpty() )
441 {
442 field.SetName( _( "untitled" ) );
443 }
444 }
445
447
448 // Update the parent for inherited symbols
449 if( m_libEntry->IsAlias() )
450 {
451 wxString parentName = EscapeString( m_inheritanceSelectCombo->GetValue(), CTX_LIBID );
452
453 // The parentName was verified to be non-empty in the Validator
454 wxString libName = m_Parent->GetCurLib();
455
456 // Get the parent from the libManager based on the name set in the inheritance combo box.
457 LIB_SYMBOL* newParent = m_Parent->GetLibManager().GetAlias( parentName, libName );
458
459 // Verify that the requested parent exists
460 wxCHECK( newParent, false );
461
462 m_libEntry->SetParent( newParent );
463 }
464
465 m_libEntry->SetName( newName );
466 m_libEntry->SetKeyWords( m_KeywordCtrl->GetValue() );
469 !m_OptionPartsInterchangeable->GetValue() );
472
473 if( m_OptionPower->GetValue() )
474 {
476 // Power symbols must have value matching name for now
477 m_libEntry->GetValueField().SetText( newName );
478 }
479 else
480 {
482 }
483
487
490
491 if( m_PinsNameInsideButt->GetValue() )
492 {
493 int offset = KiROUND( (double) m_pinNameOffset.GetValue() );
494
495 // We interpret an offset of 0 as "outside", so make sure it's non-zero
496 m_libEntry->SetPinNameOffset( offset == 0 ? 20 : offset );
497 }
498 else
499 {
500 m_libEntry->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
501 }
502
504
506
507 // It's possible that the symbol being edited has no pins, in which case there may be no
508 // alternate body style objects causing #LIB_SYMBOL::HasAlternateBodyStyle() to always return
509 // false. This allows the user to edit the alternate body style just in case this condition
510 // occurs.
512
513 return true;
514}
515
516
518{
519 wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
520 wxControl* control = editor->GetControl();
521
522 if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
523 {
524 event.Veto();
525
527 m_delayedFocusRow = event.GetRow();
528 m_delayedFocusColumn = event.GetCol();
530 }
531 else if( event.GetCol() == FDC_NAME )
532 {
533 wxString newName = event.GetString();
534
535 for( int i = 0; i < m_grid->GetNumberRows(); ++i )
536 {
537 if( i == event.GetRow() )
538 continue;
539
540 if( newName.CmpNoCase( m_grid->GetCellValue( i, FDC_NAME ) ) == 0 )
541 {
542 DisplayError( this, wxString::Format( _( "The name '%s' is already in use." ),
543 newName ) );
544 event.Veto();
545 m_delayedFocusRow = event.GetRow();
546 m_delayedFocusColumn = event.GetCol();
547 }
548 }
549 }
550
551 editor->DecRef();
552}
553
554
556{
557 if( m_OptionPower->IsChecked() )
558 m_grid->SetCellValue( VALUE_FIELD, FDC_VALUE, m_SymbolNameCtrl->GetValue() );
559
560 OnModify();
561}
562
563
565{
566 if( !m_delayedFocusCtrl )
567 {
568 // If the validation fails and we throw up a dialog then GTK will give us another
569 // KillFocus event and we end up in infinite recursion. So we use m_delayedFocusCtrl
570 // as a re-entrancy block and then clear it again if validation passes.
573
574 if( m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
575 {
576 m_delayedFocusCtrl = nullptr;
578 }
579 }
580
581 event.Skip();
582}
583
584
585void DIALOG_LIB_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
586{
588 return;
589
591 int fieldID = (int) m_fields->size();
592 SCH_FIELD newField( m_libEntry, fieldID );
593
595 schIUScale.MilsToIU( settings->m_Defaults.text_size ) ) );
596 newField.SetVisible( false );
597
598 m_fields->push_back( newField );
599
600 // notify the grid
601 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
602 m_grid->ProcessTableMessage( msg );
603
604 m_grid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
605 m_grid->SetGridCursor( (int) m_fields->size() - 1, 0 );
606
607 m_grid->EnableCellEditControl();
608 m_grid->ShowCellEditControl();
609
610 OnModify();
611}
612
613
615{
616 wxArrayInt selectedRows = m_grid->GetSelectedRows();
617
618 if( selectedRows.empty() && m_grid->GetGridCursorRow() >= 0 )
619 selectedRows.push_back( m_grid->GetGridCursorRow() );
620
621 if( selectedRows.empty() )
622 return;
623
624 for( int row : selectedRows )
625 {
626 if( row < m_fields->GetMandatoryRowCount() )
627 {
628 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
630 return;
631 }
632 }
633
634 m_grid->CommitPendingChanges( true /* quiet mode */ );
635 m_grid->ClearSelection();
636
637 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
638 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
639
640 for( int row : selectedRows )
641 {
642 m_fields->erase( m_fields->begin() + row );
643
644 // notify the grid
645 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
646 m_grid->ProcessTableMessage( msg );
647
648 if( m_grid->GetNumberRows() > 0 )
649 {
650 m_grid->MakeCellVisible( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
651 m_grid->SetGridCursor( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
652 }
653 }
654
655 OnModify();
656}
657
658
659void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
660{
662 return;
663
664 int i = m_grid->GetGridCursorRow();
665
666 if( i > m_fields->GetMandatoryRowCount() )
667 {
668 SCH_FIELD tmp = m_fields->at( (unsigned) i );
669 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
670 m_fields->insert( m_fields->begin() + i - 1, tmp );
671 m_grid->ForceRefresh();
672
673 m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
674 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
675
676 OnModify();
677 }
678 else
679 {
680 wxBell();
681 }
682}
683
684
685void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
686{
688 return;
689
690 int i = m_grid->GetGridCursorRow();
691
692 if( i >= m_fields->GetMandatoryRowCount() && i + 1 < m_fields->GetNumberRows() )
693 {
694 SCH_FIELD tmp = m_fields->at( (unsigned) i );
695 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
696 m_fields->insert( m_fields->begin() + i + 1, tmp );
697 m_grid->ForceRefresh();
698
699 m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
700 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
701
702 OnModify();
703 }
704 else
705 {
706 wxBell();
707 }
708}
709
710
712{
714 return;
715
716 std::vector<SCH_FIELD> fields;
717
718 for( const SCH_FIELD& field : *m_fields )
719 fields.emplace_back( field );
720
721 DIALOG_SIM_MODEL dialog( this, m_parentFrame, *m_libEntry, fields );
722
723 if( dialog.ShowModal() != wxID_OK )
724 return;
725
726 // Add in any new fields
727 for( const SCH_FIELD& editedField : fields )
728 {
729 bool found = false;
730
731 for( SCH_FIELD& existingField : *m_fields )
732 {
733 if( existingField.GetName() == editedField.GetName() )
734 {
735 found = true;
736 existingField.SetText( editedField.GetText() );
737 break;
738 }
739 }
740
741 if( !found )
742 {
743 m_fields->emplace_back( editedField );
744 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
745 m_grid->ProcessTableMessage( msg );
746 }
747 }
748
749 // Remove any deleted fields
750 for( int ii = (int) m_fields->size() - 1; ii >= 0; --ii )
751 {
752 SCH_FIELD& existingField = m_fields->at( ii );
753 bool found = false;
754
755 for( SCH_FIELD& editedField : fields )
756 {
757 if( editedField.GetName() == existingField.GetName() )
758 {
759 found = true;
760 break;
761 }
762 }
763
764 if( !found )
765 {
766 m_fields->erase( m_fields->begin() + ii );
767 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, ii, 1 );
768 m_grid->ProcessTableMessage( msg );
769 }
770 }
771
772 OnModify();
773 m_grid->ForceRefresh();
774}
775
776
778{
779 int idx = m_FootprintFilterListBox->HitTest( event.GetPosition() );
780 wxCommandEvent dummy;
781
782 if( idx >= 0 )
784 else
786}
787
788
790{
791 // Running the Footprint Browser gums up the works and causes the automatic cancel
792 // stuff to no longer work. So we do it here ourselves.
793 EndQuasiModal( wxID_CANCEL );
794}
795
796
798{
799 wxString filterLine;
800 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Add Footprint Filter" ), filterLine );
801
802 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue().IsEmpty() )
803 return;
804
805 filterLine = dlg.GetValue();
806 filterLine.Replace( wxT( " " ), wxT( "_" ) );
807
808 // duplicate filters do no harm, so don't be a nanny.
809 m_FootprintFilterListBox->Append( filterLine );
810 m_FootprintFilterListBox->SetSelection( (int) m_FootprintFilterListBox->GetCount() - 1 );
811
812 OnModify();
813}
814
815
817{
818 wxArrayInt selections;
819 int n = m_FootprintFilterListBox->GetSelections( selections );
820
821 if( n > 0 )
822 {
823 // Just edit the first one
824 int idx = selections[0];
825 wxString filter = m_FootprintFilterListBox->GetString( idx );
826
827 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Edit Footprint Filter" ), filter );
828
829 if( dlg.ShowModal() == wxID_OK && !dlg.GetValue().IsEmpty() )
830 {
831 m_FootprintFilterListBox->SetString( (unsigned) idx, dlg.GetValue() );
832 OnModify();
833 }
834 }
835}
836
837
839{
840 // Account for scroll bars
842
843 m_grid->AutoSizeColumn( FDC_NAME );
844 m_grid->SetColSize( FDC_NAME, std::max( 72, m_grid->GetColSize( FDC_NAME ) ) );
845
846 int fixedColsWidth = m_grid->GetColSize( FDC_NAME );
847
848 for( int i = 2; i < m_grid->GetNumberCols(); i++ )
849 fixedColsWidth += m_grid->GetColSize( i );
850
851 m_grid->SetColSize( FDC_VALUE, std::max( 120, width - fixedColsWidth ) );
852}
853
854
855void DIALOG_LIB_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
856{
857 m_OptionPartsInterchangeable->Enable( m_SelNumberOfUnits->GetValue() > 1 );
859
860 if( m_grid->IsCellEditControlShown() )
861 {
862 int row = m_grid->GetGridCursorRow();
863 int col = m_grid->GetGridCursorCol();
864
865 if( row == VALUE_FIELD && col == FDC_VALUE && m_OptionPower->IsChecked() )
866 {
867 wxGridCellEditor* editor = m_grid->GetCellEditor( row, col );
868 m_SymbolNameCtrl->ChangeValue( editor->GetValue() );
869 editor->DecRef();
870 }
871 }
872
873 // Handle shown columns changes
874 std::bitset<64> shownColumns = m_grid->GetShownColumns();
875
876 if( shownColumns != m_shownColumns )
877 {
878 m_shownColumns = shownColumns;
879
880 if( !m_grid->IsCellEditControlShown() )
882 }
883
884 // Handle a delayed focus. The delay allows us to:
885 // a) change focus when the error was triggered from within a killFocus handler
886 // b) show the correct notebook page in the background before the error dialog comes up
887 // when triggered from an OK or a notebook page change
888
889 if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
890 {
891 m_NoteBook->ChangeSelection( (unsigned) m_delayedFocusPage );
893 }
894
895 if( !m_delayedErrorMessage.IsEmpty() )
896 {
897 // We will re-enter this routine when the error dialog is displayed, so make
898 // sure we don't keep putting up more dialogs.
899 wxString msg = m_delayedErrorMessage;
900 m_delayedErrorMessage = wxEmptyString;
901
902 // Do not use DisplayErrorMessage(); it screws up window order on Mac
903 DisplayError( nullptr, msg );
904 }
905
907 {
908 m_delayedFocusCtrl->SetFocus();
909
910 if( auto textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
911 textEntry->SelectAll();
912
913 m_delayedFocusCtrl = nullptr;
914 }
915 else if( m_delayedFocusGrid )
916 {
917 m_delayedFocusGrid->SetFocus();
920
921 m_delayedFocusGrid->EnableCellEditControl( true );
922 m_delayedFocusGrid->ShowCellEditControl();
923
924 m_delayedFocusGrid = nullptr;
927 }
928}
929
930
932{
933 auto new_size = event.GetSize();
934
935 if( new_size != m_size )
936 {
937 m_size = new_size;
938
940 }
941
942 // Always propagate a wxSizeEvent:
943 event.Skip();
944}
945
946
948{
949 bSizerLowerBasicPanel->Show( !aIsAlias );
950 m_inheritanceSelectCombo->Enable( aIsAlias );
951 m_inheritsStaticText->Enable( aIsAlias );
952 m_grid->ForceRefresh();
953}
954
955
957{
958 if( m_OptionPower->IsChecked() )
959 {
960 m_excludeFromSimCheckBox->SetValue( true );
961 m_excludeFromBomCheckBox->SetValue( true );
962 m_excludeFromBoardCheckBox->SetValue( true );
963 m_excludeFromBomCheckBox->Enable( false );
964 m_excludeFromBoardCheckBox->Enable( false );
965 m_excludeFromSimCheckBox->Enable( false );
966 m_spiceFieldsButton->Show( false );
967 }
968 else
969 {
970 m_excludeFromBomCheckBox->Enable( true );
971 m_excludeFromBoardCheckBox->Enable( true );
972 m_excludeFromSimCheckBox->Enable( true );
973 m_spiceFieldsButton->Show( true );
974 }
975
976 OnModify();
977}
978
979
980void DIALOG_LIB_SYMBOL_PROPERTIES::OnText( wxCommandEvent& event )
981{
982 OnModify();
983}
984
985
986void DIALOG_LIB_SYMBOL_PROPERTIES::OnCombobox( wxCommandEvent& event )
987{
988 OnModify();
989}
990
991
992void DIALOG_LIB_SYMBOL_PROPERTIES::OnCheckBox( wxCommandEvent& event )
993{
994 OnModify();
995}
996
997
999{
1000 OnModify();
1001}
1002
1003
1005{
1006 OnModify();
1007}
1008
1009
1011{
1013 aEvent.Veto();
1014}
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
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:248
int ShowModal() override
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:526
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:379
int GetNumberRows() override
int GetMandatoryRowCount() const
A text control validator used for validating the text allowed in fields.
Definition: validators.h:224
Define a library symbol object.
Definition: lib_symbol.h:84
wxString GetKeyWords() const override
Definition: lib_symbol.h:182
bool IsPower() const override
Definition: lib_symbol.cpp:423
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:285
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition: lib_symbol.h:205
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:206
void SetPower()
Definition: lib_symbol.cpp:439
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:279
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:329
wxString GetName() const override
Definition: lib_symbol.h:148
void SetKeyWords(const wxString &aKeyWords)
Definition: lib_symbol.h:180
wxArrayString GetFPFilters() const
Definition: lib_symbol.h:217
void SetFPFilters(const wxArrayString &aFilters)
Definition: lib_symbol.h:215
void CopyFields(std::vector< SCH_FIELD > &aList)
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:117
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:322
void SetNormal()
Definition: lib_symbol.cpp:467
EMBEDDED_FILES * GetLocalFiles()
bool TransferDataToWindow() override
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:125
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:53
bool IsMandatory() const
Definition: sch_field.cpp:1507
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:1254
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:1229
void SetName(const wxString &aName)
Definition: sch_field.cpp:1204
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1214
T * GetAppSettings(const wxString &aFilename)
Return a handle to the a given settings by type.
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:185
virtual void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: symbol.h:162
bool GetExcludedFromBOM() const
Definition: symbol.h:179
void SetExcludedFromSim(bool aExcludeFromSim) override
Set or clear the exclude from simulation flag.
Definition: symbol.h:168
int GetPinNameOffset() const
Definition: symbol.h:151
virtual void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: symbol.h:156
virtual bool GetShowPinNames() const
Definition: symbol.h:157
void SetExcludedFromBOM(bool aExcludeFromBOM)
Set or clear the exclude from schematic bill of materials flag.
Definition: symbol.h:178
void SetPinNameOffset(int aOffset)
Set the offset in mils of the pin name text from the pin symbol.
Definition: symbol.h:150
void SetExcludedFromBoard(bool aExcludeFromBoard)
Set or clear exclude from board netlist flag.
Definition: symbol.h:184
virtual bool GetShowPinNumbers() const
Definition: symbol.h:163
bool GetExcludedFromSim() const override
Definition: symbol.h:173
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:494
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:275
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:449
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:464
std::bitset< 64 > GetShownColumns()
Definition: wx_grid.cpp:483
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:644
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:52
wxSize GetUnobscuredSize(const wxWindow *aWindow)
Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl,...
Definition: wxgtk/ui.cpp:252
wxString GetRefDesPrefix(const wxString &aRefDes)
Get the (non-numeric) prefix from a refdes - e.g.
STL namespace.
PGM_BASE & Pgm()
The global program "get" accessor.
Definition: pgm_base.cpp:1073
see class PGM_BASE
Collection of utility functions for component reference designators (refdes)
std::vector< FAB_LAYER_COLOR > dummy
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
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.
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695