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