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 <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#include <project_sch.h>
38
39#include <dialog_sim_model.h>
40
44
45
49
50
52 LIB_SYMBOL* aLibEntry ) :
54 m_Parent( aParent ),
55 m_libEntry( aLibEntry ),
56 m_pinNameOffset( aParent, m_nameOffsetLabel, m_nameOffsetCtrl, m_nameOffsetUnits, true ),
57 m_delayedFocusCtrl( nullptr ),
58 m_delayedFocusGrid( nullptr ),
59 m_delayedFocusRow( -1 ),
60 m_delayedFocusColumn( -1 ),
61 m_delayedFocusPage( -1 )
62{
63 // Give a bit more room for combobox editors
64 m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
67 m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this,
68 [&]( wxCommandEvent& aEvent )
69 {
70 OnAddField( aEvent );
71 } ) );
72 m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
73
74 // Show/hide columns according to the user's preference
77
78 wxGridCellAttr* attr = new wxGridCellAttr;
79 attr->SetEditor( new GRID_CELL_URL_EDITOR( this, PROJECT_SCH::SchSearchS( &Prj() ) ) );
80 m_grid->SetAttr( DATASHEET_FIELD, FDC_VALUE, attr );
81
83
84 // Configure button logos
85 m_bpAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
86 m_bpDelete->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
87 m_bpMoveUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
88 m_bpMoveDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
89 m_addFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
90 m_deleteFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
91 m_editFilterButton->SetBitmap( KiBitmapBundle( BITMAPS::small_edit ) );
92
94
95 if( aParent->IsSymbolFromLegacyLibrary() && !aParent->IsSymbolFromSchematic() )
96 {
97 m_stdSizerButtonCancel->SetDefault();
98 m_stdSizerButtonOK->SetLabel( _( "Read Only" ) );
99 m_stdSizerButtonOK->Enable( false );
100 }
101
102 // wxFormBuilder doesn't include this event...
103 m_grid->Connect( wxEVT_GRID_CELL_CHANGING,
105 nullptr, this );
106
108 {
110 && aLibEntry->IsRoot() )
112 && aLibEntry->IsAlias() ) )
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
134 cfg->m_EditSymbolVisibleColumns = m_grid->GetShownColumnsAsString();
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_KeywordCtrl->ChangeValue( m_libEntry->GetKeyWords() );
175 m_libEntry->GetUnitCount() == 1 );
176
177 // If a symbol contains no body-style-specific pins or graphic items,
178 // symbol->HasAlternateBodyStyle() will return false.
179 // But when editing a symbol with DeMorgan option set, we don't want to keep turning it off
180 // just because there aren't any body-style-specific items yet, so we force it to on if the
181 // parent frame has it enabled.
183
184 m_OptionPower->SetValue( m_libEntry->IsPower() );
185
186 if( m_libEntry->IsPower() )
187 m_spiceFieldsButton->Hide();
188
192
197
198 wxArrayString tmp = m_libEntry->GetFPFilters();
199 m_FootprintFilterListBox->Append( tmp );
200
201 // Populate the list of root parts for inherited objects.
202 if( m_libEntry->IsAlias() )
203 {
204 wxArrayString symbolNames;
205 wxString libName = m_Parent->GetCurLib();
206
207 // Someone forgot to set the current library in the editor frame window.
208 wxCHECK( !libName.empty(), false );
209
210 m_Parent->GetLibManager().GetSymbolNames( libName, symbolNames );
211
212 // Do allow an inherited symbol to be derived from itself.
213 symbolNames.Remove( m_libEntry->GetName() );
214 m_inheritanceSelectCombo->Append( symbolNames );
215
216 LIB_SYMBOL_SPTR rootSymbol = m_libEntry->GetParent().lock();
217
218 wxCHECK( rootSymbol, false );
219
220 wxString parentName = UnescapeString( rootSymbol->GetName() );
221 int selection = m_inheritanceSelectCombo->FindString( parentName );
222
223 wxCHECK( selection != wxNOT_FOUND, false );
224 m_inheritanceSelectCombo->SetSelection( selection );
225
227 }
228
229 m_NoteBook->SetSelection( (unsigned) m_lastOpenedPage );
230
231 return true;
232}
233
234
236{
238 return false;
239
240 // Alias symbol reference can be empty because it inherits from the parent symbol.
241 if( m_libEntry->IsRoot() &&
243 {
244 if( m_NoteBook->GetSelection() != 0 )
245 m_NoteBook->SetSelection( 0 );
246
247 m_delayedErrorMessage = _( "References must start with a letter." );
252
253 return false;
254 }
255
256 // Check for missing field names.
257 for( int ii = MANDATORY_FIELDS; ii < (int) m_fields->size(); ++ii )
258 {
259 LIB_FIELD& field = m_fields->at( ii );
260 wxString fieldName = field.GetName( false );
261
262 if( fieldName.IsEmpty() && !field.GetText().IsEmpty() )
263 {
264 if( m_NoteBook->GetSelection() != 0 )
265 m_NoteBook->SetSelection( 0 );
266
267 m_delayedErrorMessage = _( "Fields must have a name." );
272
273 return false;
274 }
275 }
276
277 // Verify that the parent name is set if the symbol is inherited
278 if( m_libEntry->IsAlias() )
279 {
280 wxString parentName = m_inheritanceSelectCombo->GetValue();
281
282 if( parentName.IsEmpty() )
283 {
284 m_delayedErrorMessage = _( "Derived symbol must have a parent selected" );
285
286 return false;
287 }
288 }
289
290 /*
291 * Confirm destructive actions.
292 */
293
294 if( m_SelNumberOfUnits->GetValue() < m_libEntry->GetUnitCount() )
295 {
296 if( !IsOK( this, _( "Delete extra units from symbol?" ) ) )
297 return false;
298 }
299
301 {
302 if( !IsOK( this, _( "Delete alternate body style (De Morgan) from symbol?" ) ) )
303 return false;
304 }
305
306 return true;
307}
308
309
311{
312 if( !wxDialog::TransferDataFromWindow() )
313 return false;
314
316 return false;
317
318 wxString newName = EscapeString( m_SymbolNameCtrl->GetValue(), CTX_LIBID );
319 wxString oldName = m_libEntry->GetName();
320
321 if( newName.IsEmpty() )
322 {
323 wxMessageBox( _( "Symbol must have a name." ) );
324 return false;
325 }
326
327 if( oldName != newName )
328 {
329 wxString libName = m_Parent->GetCurLib();
330
331 if( m_Parent->GetLibManager().SymbolExists( newName, libName ) )
332 {
333 wxString msg;
334
335 msg.Printf( _( "Symbol name '%s' already in use in library '%s'." ),
336 UnescapeString( newName ),
337 libName );
338 DisplayErrorMessage( this, msg );
339 return false;
340 }
341
342 m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry,
343 UNDO_REDO::LIB_RENAME );
344 }
345 else
346 {
347 m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry );
348 }
349
350 // The Y axis for components in lib is from bottom to top while the screen axis is top
351 // to bottom: we must change the y coord sign when writing back to the library
352 for( int ii = 0; ii < (int) m_fields->size(); ++ii )
353 {
354 VECTOR2I pos = m_fields->at( ii ).GetPosition();
355 pos.y = -pos.y;
356 m_fields->at( ii ).SetPosition( pos );
357 m_fields->at( ii ).SetId( ii );
358 }
359
360 for( int ii = m_fields->GetNumberRows() - 1; ii >= MANDATORY_FIELDS; ii-- )
361 {
362 LIB_FIELD& field = m_fields->at( ii );
363 const wxString& fieldName = field.GetCanonicalName();
364
365 if( fieldName.IsEmpty() && field.GetText().IsEmpty() )
366 m_fields->erase( m_fields->begin() + ii );
367 else if( fieldName.IsEmpty() )
368 field.SetName( _( "untitled" ) );
369 }
370
372
373 // Update the parent for inherited symbols
374 if( m_libEntry->IsAlias() )
375 {
376 wxString parentName = EscapeString( m_inheritanceSelectCombo->GetValue(), CTX_LIBID );
377
378 // The parentName was verified to be non-empty in the Validator
379 wxString libName = m_Parent->GetCurLib();
380
381 // Get the parent from the libManager based on the name set in the inheritance combo box.
382 LIB_SYMBOL* newParent = m_Parent->GetLibManager().GetAlias( parentName, libName );
383
384 // Verify that the requested parent exists
385 wxCHECK( newParent, false );
386
387 m_libEntry->SetParent( newParent );
388 }
389
390 m_libEntry->SetName( newName );
391 m_libEntry->SetKeyWords( m_KeywordCtrl->GetValue() );
394 !m_OptionPartsInterchangeable->GetValue() );
397
398 if( m_OptionPower->GetValue() )
399 {
401 // Power symbols must have value matching name for now
402 m_libEntry->GetValueField().SetText( newName );
403 }
404 else
405 {
407 }
408
412
415
416 if( m_PinsNameInsideButt->GetValue() )
417 {
418 int offset = KiROUND( (double) m_pinNameOffset.GetValue() );
419
420 // We interpret an offset of 0 as "outside", so make sure it's non-zero
421 m_libEntry->SetPinNameOffset( offset == 0 ? 20 : offset );
422 }
423 else
424 {
425 m_libEntry->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
426 }
427
429
431
432 // It's possible that the symbol being edited has no pins, in which case there may be no
433 // alternate body style objects causing #LIB_SYMBOL::HasAlternateBodyStyle() to always return
434 // false. This allows the user to edit the alternate body style just in case this condition
435 // occurs.
437
438 return true;
439}
440
441
443{
444 wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
445 wxControl* control = editor->GetControl();
446
447 if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
448 {
449 event.Veto();
450
452 m_delayedFocusRow = event.GetRow();
453 m_delayedFocusColumn = event.GetCol();
455 }
456 else if( event.GetCol() == FDC_NAME )
457 {
458 wxString newName = event.GetString();
459
460 for( int i = 0; i < m_grid->GetNumberRows(); ++i )
461 {
462 if( i == event.GetRow() )
463 continue;
464
465 if( newName.CmpNoCase( m_grid->GetCellValue( i, FDC_NAME ) ) == 0 )
466 {
467 DisplayError( this, wxString::Format( _( "The name '%s' is already in use." ),
468 newName ) );
469 event.Veto();
470 m_delayedFocusRow = event.GetRow();
471 m_delayedFocusColumn = event.GetCol();
472 }
473 }
474 }
475
476 editor->DecRef();
477}
478
479
481{
482 if( m_OptionPower->IsChecked() )
483 m_grid->SetCellValue( VALUE_FIELD, FDC_VALUE, m_SymbolNameCtrl->GetValue() );
484}
485
486
488{
489 if( !m_delayedFocusCtrl )
490 {
491 // If the validation fails and we throw up a dialog then GTK will give us another
492 // KillFocus event and we end up in infinite recursion. So we use m_delayedFocusCtrl
493 // as a re-entrancy block and then clear it again if validation passes.
496
497 if( m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
498 {
499 m_delayedFocusCtrl = nullptr;
501 }
502 }
503
504 event.Skip();
505}
506
507
508void DIALOG_LIB_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
509{
511 return;
512
514 int fieldID = (int) m_fields->size();
515 LIB_FIELD newField( m_libEntry, fieldID );
516
518 schIUScale.MilsToIU( settings->m_Defaults.text_size ) ) );
519
520 m_fields->push_back( newField );
521
522 // notify the grid
523 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
524 m_grid->ProcessTableMessage( msg );
525
526 m_grid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
527 m_grid->SetGridCursor( (int) m_fields->size() - 1, 0 );
528
529 m_grid->EnableCellEditControl();
530 m_grid->ShowCellEditControl();
531
532 OnModify();
533}
534
535
537{
538 wxArrayInt selectedRows = m_grid->GetSelectedRows();
539
540 if( selectedRows.empty() && m_grid->GetGridCursorRow() >= 0 )
541 selectedRows.push_back( m_grid->GetGridCursorRow() );
542
543 if( selectedRows.empty() )
544 return;
545
546 for( int row : selectedRows )
547 {
548 if( row < MANDATORY_FIELDS )
549 {
550 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
552 return;
553 }
554 }
555
556 m_grid->CommitPendingChanges( true /* quiet mode */ );
557 m_grid->ClearSelection();
558
559 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
560 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
561
562 for( int row : selectedRows )
563 {
564 m_fields->erase( m_fields->begin() + row );
565
566 // notify the grid
567 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
568 m_grid->ProcessTableMessage( msg );
569
570 if( m_grid->GetNumberRows() > 0 )
571 {
572 m_grid->MakeCellVisible( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
573 m_grid->SetGridCursor( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
574 }
575 }
576
577 OnModify();
578}
579
580
581void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
582{
584 return;
585
586 int i = m_grid->GetGridCursorRow();
587
588 if( i > MANDATORY_FIELDS )
589 {
590 LIB_FIELD tmp = m_fields->at( (unsigned) i );
591 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
592 m_fields->insert( m_fields->begin() + i - 1, tmp );
593 m_grid->ForceRefresh();
594
595 m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
596 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
597
598 OnModify();
599 }
600 else
601 {
602 wxBell();
603 }
604}
605
606
607void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
608{
610 return;
611
612 int i = m_grid->GetGridCursorRow();
613
614 if( i >= MANDATORY_FIELDS && i + 1 < m_fields->GetNumberRows() )
615 {
616 LIB_FIELD tmp = m_fields->at( (unsigned) i );
617 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
618 m_fields->insert( m_fields->begin() + i + 1, tmp );
619 m_grid->ForceRefresh();
620
621 m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
622 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
623
624 OnModify();
625 }
626 else
627 {
628 wxBell();
629 }
630}
631
632
634{
636 return;
637
638 std::vector<LIB_FIELD> fields;
639
640 for( const LIB_FIELD& field : *m_fields )
641 fields.emplace_back( field );
642
643 DIALOG_SIM_MODEL dialog( this, m_parentFrame, *m_libEntry, fields );
644
645 if( dialog.ShowModal() != wxID_OK )
646 return;
647
648 // Add in any new fields
649 for( const LIB_FIELD& editedField : fields )
650 {
651 bool found = false;
652
653 for( LIB_FIELD& existingField : *m_fields )
654 {
655 if( existingField.GetName() == editedField.GetName() )
656 {
657 found = true;
658 existingField.SetText( editedField.GetText() );
659 break;
660 }
661 }
662
663 if( !found )
664 {
665 m_fields->emplace_back( editedField );
666 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
667 m_grid->ProcessTableMessage( msg );
668 }
669 }
670
671 // Remove any deleted fields
672 for( int ii = (int) m_fields->size() - 1; ii >= 0; --ii )
673 {
674 LIB_FIELD& existingField = m_fields->at( ii );
675 bool found = false;
676
677 for( LIB_FIELD& editedField : fields )
678 {
679 if( editedField.GetName() == existingField.GetName() )
680 {
681 found = true;
682 break;
683 }
684 }
685
686 if( !found )
687 {
688 m_fields->erase( m_fields->begin() + ii );
689 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, ii, 1 );
690 m_grid->ProcessTableMessage( msg );
691 }
692 }
693
694 OnModify();
695 m_grid->ForceRefresh();
696}
697
698
700{
701 int idx = m_FootprintFilterListBox->HitTest( event.GetPosition() );
702 wxCommandEvent dummy;
703
704 if( idx >= 0 )
706 else
708}
709
710
712{
713 // Running the Footprint Browser gums up the works and causes the automatic cancel
714 // stuff to no longer work. So we do it here ourselves.
715 EndQuasiModal( wxID_CANCEL );
716}
717
718
720{
721 wxString filterLine;
722 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Add Footprint Filter" ), filterLine );
723
724 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue().IsEmpty() )
725 return;
726
727 filterLine = dlg.GetValue();
728 filterLine.Replace( wxT( " " ), wxT( "_" ) );
729
730 // duplicate filters do no harm, so don't be a nanny.
731
732 m_FootprintFilterListBox->Append( filterLine );
733 m_FootprintFilterListBox->SetSelection( (int) m_FootprintFilterListBox->GetCount() - 1 );
734
735 OnModify();
736}
737
738
740{
741 int ii = m_FootprintFilterListBox->GetSelection();
742
743 if( ii >= 0 )
744 {
745 m_FootprintFilterListBox->Delete( (unsigned) ii );
746
747 if( m_FootprintFilterListBox->GetCount() == 0 )
748 m_FootprintFilterListBox->SetSelection( wxNOT_FOUND );
749 else
750 m_FootprintFilterListBox->SetSelection( std::max( 0, ii - 1 ) );
751 }
752
753 OnModify();
754}
755
756
758{
759 int idx = m_FootprintFilterListBox->GetSelection();
760
761 if( idx >= 0 )
762 {
763 wxString filter = m_FootprintFilterListBox->GetStringSelection();
764
765 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Edit Footprint Filter" ), filter );
766
767 if( dlg.ShowModal() == wxID_OK && !dlg.GetValue().IsEmpty() )
768 {
769 m_FootprintFilterListBox->SetString( (unsigned) idx, dlg.GetValue() );
770 OnModify();
771 }
772 }
773}
774
775
777{
778 // Account for scroll bars
780
781 m_grid->AutoSizeColumn( FDC_NAME );
782 m_grid->SetColSize( FDC_NAME, std::max( 72, m_grid->GetColSize( FDC_NAME ) ) );
783
784 int fixedColsWidth = m_grid->GetColSize( FDC_NAME );
785
786 for( int i = 2; i < m_grid->GetNumberCols(); i++ )
787 fixedColsWidth += m_grid->GetColSize( i );
788
789 m_grid->SetColSize( FDC_VALUE, std::max( 120, width - fixedColsWidth ) );
790}
791
792
793void DIALOG_LIB_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
794{
795 m_OptionPartsInterchangeable->Enable( m_SelNumberOfUnits->GetValue() > 1 );
797
798 if( m_grid->IsCellEditControlShown() )
799 {
800 int row = m_grid->GetGridCursorRow();
801 int col = m_grid->GetGridCursorCol();
802
803 if( row == VALUE_FIELD && col == FDC_VALUE && m_OptionPower->IsChecked() )
804 {
805 wxGridCellEditor* editor = m_grid->GetCellEditor( row, col );
806 m_SymbolNameCtrl->ChangeValue( editor->GetValue() );
807 editor->DecRef();
808 }
809 }
810
811 // Handle shown columns changes
812 std::bitset<64> shownColumns = m_grid->GetShownColumns();
813
814 if( shownColumns != m_shownColumns )
815 {
816 m_shownColumns = shownColumns;
817
818 if( !m_grid->IsCellEditControlShown() )
820 }
821
822 // Handle a delayed focus. The delay allows us to:
823 // a) change focus when the error was triggered from within a killFocus handler
824 // b) show the correct notebook page in the background before the error dialog comes up
825 // when triggered from an OK or a notebook page change
826
827 if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
828 {
829 m_NoteBook->ChangeSelection( (unsigned) m_delayedFocusPage );
831 }
832
833 if( !m_delayedErrorMessage.IsEmpty() )
834 {
835 // We will re-enter this routine when the error dialog is displayed, so make
836 // sure we don't keep putting up more dialogs.
837 wxString msg = m_delayedErrorMessage;
838 m_delayedErrorMessage = wxEmptyString;
839
840 // Do not use DisplayErrorMessage(); it screws up window order on Mac
841 DisplayError( nullptr, msg );
842 }
843
845 {
846 m_delayedFocusCtrl->SetFocus();
847
848 if( auto textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
849 textEntry->SelectAll();
850
851 m_delayedFocusCtrl = nullptr;
852 }
853 else if( m_delayedFocusGrid )
854 {
855 m_delayedFocusGrid->SetFocus();
858
859 m_delayedFocusGrid->EnableCellEditControl( true );
860 m_delayedFocusGrid->ShowCellEditControl();
861
862 m_delayedFocusGrid = nullptr;
865 }
866}
867
868
870{
871 auto new_size = event.GetSize();
872
873 if( new_size != m_size )
874 {
875 m_size = new_size;
876
878 }
879
880 // Always propagate a wxSizeEvent:
881 event.Skip();
882}
883
884
886{
887 bSizerLowerBasicPanel->Show( !aIsAlias );
888 m_inheritanceSelectCombo->Enable( aIsAlias );
889 m_inheritsStaticText->Enable( aIsAlias );
890 m_grid->ForceRefresh();
891}
892
893
895{
896 if( m_OptionPower->IsChecked() )
897 {
898 m_excludeFromSimCheckBox->SetValue( true );
899 m_excludeFromBomCheckBox->SetValue( true );
900 m_excludeFromBoardCheckBox->SetValue( true );
901 m_excludeFromBomCheckBox->Enable( false );
902 m_excludeFromBoardCheckBox->Enable( false );
903 m_excludeFromSimCheckBox->Enable( false );
904 m_spiceFieldsButton->Show( false );
905 }
906 else
907 {
908 m_excludeFromBomCheckBox->Enable( true );
909 m_excludeFromBoardCheckBox->Enable( true );
910 m_excludeFromSimCheckBox->Enable( true );
911 m_spiceFieldsButton->Show( true );
912 }
913
914 OnModify();
915}
916
917
918void DIALOG_LIB_SYMBOL_PROPERTIES::OnText( wxCommandEvent& event )
919{
920 OnModify();
921}
922
923
924void DIALOG_LIB_SYMBOL_PROPERTIES::OnCombobox( wxCommandEvent& event )
925{
926 OnModify();
927}
928
929
930void DIALOG_LIB_SYMBOL_PROPERTIES::OnCheckBox( wxCommandEvent& event )
931{
932 OnModify();
933}
934
935
937{
938 OnModify();
939}
940
941
943{
944 OnModify();
945}
946
947
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
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
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 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:223
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:374
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:95
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:183
int GetNumberRows() override
A text control validator used for validating the text allowed in fields.
Definition: validators.h:238
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Field object used in symbol libraries.
Definition: lib_field.h:62
void SetName(const wxString &aName)
Set a user definable field name to aName.
Definition: lib_field.cpp:503
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: lib_field.cpp:485
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
Definition: lib_field.cpp:494
Define a library symbol object.
Definition: lib_symbol.h:99
bool HasAlternateBodyStyle() const
Test if symbol has more than one body conversion type (DeMorgan).
void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: lib_symbol.h:632
int GetPinNameOffset() const
Definition: lib_symbol.h:625
wxString GetKeyWords() const
Definition: lib_symbol.h:191
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:286
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition: lib_symbol.h:214
void SetPinNameOffset(int aOffset)
Set the offset in mils of the pin name text from the pin symbol.
Definition: lib_symbol.h:624
bool IsAlias() const
Definition: lib_symbol.h:215
bool IsPower() const
Definition: lib_symbol.cpp:704
void SetPower()
Definition: lib_symbol.cpp:718
bool ShowPinNames() const
Definition: lib_symbol.h:633
void LockUnits(bool aLockUnits)
Set interchangeable the property for symbol units.
Definition: lib_symbol.h:280
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: lib_symbol.h:640
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:596
wxString GetName() const override
Definition: lib_symbol.h:160
void SetKeyWords(const wxString &aKeyWords)
Definition: lib_symbol.h:189
void GetFields(std::vector< LIB_FIELD * > &aList)
Return a list of fields within this symbol.
wxArrayString GetFPFilters() const
Definition: lib_symbol.h:226
void SetExcludedFromBOM(bool aExcludeFromBOM)
Set or clear the exclude from schematic bill of materials flag.
Definition: lib_symbol.h:656
bool GetExcludedFromBOM() const
Definition: lib_symbol.h:657
void SetExcludedFromBoard(bool aExcludeFromBoard)
Set or clear exclude from board netlist flag.
Definition: lib_symbol.h:664
LIB_FIELD & GetValueField()
Return reference to the value field.
bool GetExcludedFromSim() const
Definition: lib_symbol.h:649
void SetFPFilters(const wxArrayString &aFilters)
Definition: lib_symbol.h:224
void SetHasAlternateBodyStyle(bool aHasAlternate, bool aDuplicatePins=true)
Set or clear the alternate body style (DeMorgan) for the symbol.
int GetUnitCount() const override
For items with units, return the number of units.
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:589
void SetNormal()
Definition: lib_symbol.cpp:746
bool ShowPinNumbers() const
Definition: lib_symbol.h:641
void SetExcludedFromSim(bool aExcludeFromSim)
Set or clear the exclude from simulation flag.
Definition: lib_symbol.h:648
bool GetExcludedFromBoard() const
Definition: lib_symbol.h:665
static SEARCH_STACK * SchSearchS(PROJECT *aProject)
Accessor for Eeschema search stack.
Definition: project_sch.cpp:41
static bool IsReferenceStringValid(const wxString &aReferenceString)
Test for an acceptable reference string.
Definition: sch_symbol.cpp:787
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)
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:312
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:156
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:268
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:282
std::bitset< 64 > GetShownColumns()
Definition: wx_grid.cpp:301
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:462
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:360
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:280
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:305
This file is part of the common library.
#define _(s)
@ FDC_NAME
@ FDC_VALUE
std::shared_ptr< LIB_SYMBOL > LIB_SYMBOL_SPTR
shared pointer to LIB_SYMBOL
Definition: lib_symbol.h:45
wxSize GetUnobscuredSize(const wxWindow *aWindow)
Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl,...
Definition: gtk/ui.cpp:195
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:94
@ 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:85
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588