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