KiCad PCB EDA Suite
dialog_lib_symbol_properties.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 1992-2021 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>
29 #include <symbol_library_manager.h>
30 #include <math/util.h> // for KiROUND
31 #include <pgm_base.h>
32 #include <sch_symbol.h>
34 #include <widgets/wx_grid.h>
35 
36 #ifdef KICAD_SPICE
37 #include <dialog_spice_model.h>
38 #endif /* KICAD_SPICE */
39 
42 #include <symbol_editor_settings.h>
43 
44 
48 
49 
51  LIB_PART* aLibEntry ) :
53  m_Parent( aParent ),
54  m_libEntry( aLibEntry ),
55  m_pinNameOffset( aParent, m_nameOffsetLabel, m_nameOffsetCtrl, m_nameOffsetUnits, true ),
56  m_delayedFocusCtrl( nullptr ),
57  m_delayedFocusGrid( nullptr ),
58  m_delayedFocusRow( -1 ),
59  m_delayedFocusColumn( -1 ),
60  m_delayedFocusPage( -1 ),
61  m_width( 0 )
62 {
63  // Give a bit more room for combobox editors
64  m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
65  m_fields = new FIELDS_GRID_TABLE<LIB_FIELD>( this, aParent, m_grid, m_libEntry );
67  m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this ) );
68 
69  // Show/hide columns according to the user's preference
70  auto cfg = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
71  m_grid->ShowHideColumns( cfg->m_EditComponentVisibleColumns );
72 
73  wxGridCellAttr* attr = new wxGridCellAttr;
74  attr->SetEditor( new GRID_CELL_URL_EDITOR( this ) );
75  m_grid->SetAttr( DATASHEET_FIELD, FDC_VALUE, attr );
76 
77  m_SymbolNameCtrl->SetValidator( SCH_FIELD_VALIDATOR( true, VALUE_FIELD ) );
78 
79  // Configure button logos
80  m_bpAdd->SetBitmap( KiBitmap( BITMAPS::small_plus ) );
81  m_bpDelete->SetBitmap( KiBitmap( BITMAPS::small_trash ) );
82  m_bpMoveUp->SetBitmap( KiBitmap( BITMAPS::small_up ) );
83  m_bpMoveDown->SetBitmap( KiBitmap( BITMAPS::small_down ) );
87 
88  if( aParent->IsSymbolFromLegacyLibrary() )
89  {
90  m_stdSizerButtonCancel->SetDefault();
91  m_stdSizerButtonOK->SetLabel( _( "Read Only" ) );
92  m_stdSizerButtonOK->Enable( false );
93  }
94  else
95  {
96  m_stdSizerButtonOK->SetDefault();
97  }
98 
99 #ifndef KICAD_SPICE
100  m_spiceFieldsButton->Hide();
101 #endif
102 
103  // wxFormBuilder doesn't include this event...
104  m_grid->Connect( wxEVT_GRID_CELL_CHANGING,
106  NULL, this );
107 
109  {
110  if( ( m_lastLayout == DIALOG_LIB_SYMBOL_PROPERTIES::ALIAS && aLibEntry->IsRoot() )
111  || ( m_lastLayout == DIALOG_LIB_SYMBOL_PROPERTIES::PARENT && aLibEntry->IsAlias() ) )
112  {
113  resetSize();
114  }
115  }
116 
119 
120  m_grid->GetParent()->Layout();
122  Layout();
123 
125 }
126 
127 
129 {
130  m_lastOpenedPage = m_NoteBook->GetSelection( );
131 
132  auto cfg = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
134 
135  // Prevents crash bug in wxGrid's d'tor
137 
138  m_grid->Disconnect( wxEVT_GRID_CELL_CHANGING,
140  NULL, this );
141 
142  // Delete the GRID_TRICKS.
143  m_grid->PopEventHandler( true );
144 }
145 
146 
148 {
149  if( !wxDialog::TransferDataToWindow() )
150  return false;
151 
152  // Push a copy of each field into m_updateFields
154 
155  // The Y axis for components in lib is from bottom to top while the screen axis is top
156  // to bottom: we must change the y coord sign for editing
157  for( size_t i = 0; i < m_fields->size(); ++i )
158  {
159  wxPoint pos = m_fields->at( i ).GetPosition();
160  pos.y = -pos.y;
161  m_fields->at( i ).SetPosition( pos );
162  }
163 
164  // notify the grid
165  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->GetNumberRows() );
166  m_grid->ProcessTableMessage( msg );
167  adjustGridColumns( m_grid->GetRect().GetWidth() );
168 
169  m_SymbolNameCtrl->ChangeValue( m_libEntry->GetName() );
170 
171  m_DescCtrl->ChangeValue( m_libEntry->GetDescription() );
172  m_KeywordCtrl->ChangeValue( m_libEntry->GetKeyWords() );
175  m_AsConvertButt->SetValue( m_libEntry->HasConversion() );
176  m_OptionPower->SetValue( m_libEntry->IsPower() );
179 
181  m_ShowPinNameButt->SetValue( m_libEntry->ShowPinNames() );
182  m_PinsNameInsideButt->SetValue( m_libEntry->GetPinNameOffset() != 0 );
184 
185  wxArrayString tmp = m_libEntry->GetFPFilters();
186  m_FootprintFilterListBox->Append( tmp );
187 
188  // Populate the list of root parts for inherited objects.
189  if( m_libEntry->IsAlias() )
190  {
191  wxArrayString rootSymbolNames;
192  wxString libName = m_Parent->GetCurLib();
193 
194  // Someone forgot to set the current library in the editor frame window.
195  wxCHECK( !libName.empty(), false );
196 
197  m_Parent->GetLibManager().GetRootSymbolNames( libName, rootSymbolNames );
198  m_inheritanceSelectCombo->Append( rootSymbolNames );
199 
200  PART_SPTR rootPart = m_libEntry->GetParent().lock();
201 
202  wxCHECK( rootPart, false );
203 
204  wxString parentName = rootPart->GetName();
205  int selection = m_inheritanceSelectCombo->FindString( parentName );
206 
207  wxCHECK( selection != wxNOT_FOUND, false );
208  m_inheritanceSelectCombo->SetSelection( selection );
209 
210  m_lastOpenedPage = 0;
211  }
212 
213  m_NoteBook->SetSelection( (unsigned) m_lastOpenedPage );
214 
215  return true;
216 }
217 
218 
220 {
221  if( !m_grid->CommitPendingChanges() )
222  return false;
223 
224  // Alias symbol reference can be empty because it inherits from the parent symbol.
225  if( m_libEntry->IsRoot() &&
227  {
228  if( m_NoteBook->GetSelection() != 0 )
229  m_NoteBook->SetSelection( 0 );
230 
231  m_delayedErrorMessage = _( "References must start with a letter." );
235  m_delayedFocusPage = 0;
236 
237  return false;
238  }
239 
240  // Check for missing field names.
241  for( size_t i = MANDATORY_FIELDS; i < m_fields->size(); ++i )
242  {
243  LIB_FIELD& field = m_fields->at( i );
244  wxString fieldName = field.GetName( false );
245 
246  if( fieldName.IsEmpty() )
247  {
248  if( m_NoteBook->GetSelection() != 0 )
249  m_NoteBook->SetSelection( 0 );
250 
251  m_delayedErrorMessage = _( "Fields must have a name." );
254  m_delayedFocusRow = i;
255  m_delayedFocusPage = 0;
256 
257  return false;
258  }
259  }
260 
261  // Verify that the parent name is set if the symbol is inherited
262  if( m_libEntry->IsAlias() )
263  {
264  wxString parentName = m_inheritanceSelectCombo->GetValue();
265 
266  if( parentName.IsEmpty() )
267  {
268  m_delayedErrorMessage = _( "Aliased symbol must have a parent selected" );
269 
270  return false;
271  }
272  }
273 
274  if( m_SelNumberOfUnits->GetValue() < m_libEntry->GetUnitCount() )
275  {
276  if( !IsOK( this, _( "Delete extra units from symbol?" ) ) )
277  return false;
278  }
279 
280  if( m_AsConvertButt->GetValue() && !m_libEntry->HasConversion() )
281  {
282  if( !IsOK( this, _( "Add new pins for alternate body style (DeMorgan) to symbol?" ) ) )
283  return false;
284  }
285  else if( !m_AsConvertButt->GetValue() && m_libEntry->HasConversion() )
286  {
287  if( !IsOK( this, _( "Delete alternate body style (DeMorgan) draw items from symbol?" ) ) )
288  return false;
289  }
290 
291  return true;
292 }
293 
294 
296 {
297  if( !wxDialog::TransferDataFromWindow() )
298  return false;
299 
300  if( !m_grid->CommitPendingChanges() )
301  return false;
302 
303  // We need to keep the name and the value the same at the moment!
304  wxString newName = m_fields->at( VALUE_FIELD ).GetText();
305  wxString oldName = m_libEntry->GetName();
306 
307  if( oldName != newName )
308  {
309  wxString libName = m_Parent->GetCurLib();
310 
311  if( m_Parent->GetLibManager().PartExists( newName, libName ) )
312  {
313  wxString msg;
314 
315  msg.Printf( _( "The name '%s' conflicts with an existing entry in the library '%s'." ),
316  newName, libName );
317  DisplayErrorMessage( this, msg );
318  return false;
319  }
320 
322  }
323  else
324  {
326  }
327 
328  // The Y axis for components in lib is from bottom to top while the screen axis is top
329  // to bottom: we must change the y coord sign when writing back to the library
330  for( size_t i = 0; i < m_fields->size(); ++i )
331  {
332  wxPoint pos = m_fields->at( i ).GetPosition();
333  pos.y = -pos.y;
334  m_fields->at( i ).SetPosition( pos );
335  m_fields->at( i ).SetId( i );
336  }
337 
339 
340  // Update the parent for inherited symbols
341  if( m_libEntry->IsAlias() )
342  {
343  wxString parentName = m_inheritanceSelectCombo->GetValue();
344 
345  // The parentName was verified to be non-empty in the Validator
346  wxString libName = m_Parent->GetCurLib();
347 
348  // Get the parent from the libManager based on the name set in the inheritance combo box.
349  LIB_PART* newParent = m_Parent->GetLibManager().GetAlias( parentName, libName );
350 
351  // Verify that the requested parent exists
352  wxCHECK( newParent, false );
353 
354  // Verify that the new parent is not an alias.
355  wxCHECK( !newParent->IsAlias(), false );
356 
357  m_libEntry->SetParent( newParent );
358  }
359 
360  // We need to keep the name and the value the same at the moment!
361  m_libEntry->SetName( newName );
362  m_libEntry->SetDescription( m_DescCtrl->GetValue() );
363  m_libEntry->SetKeyWords( m_KeywordCtrl->GetValue() );
366  m_libEntry->SetConversion( m_AsConvertButt->GetValue() );
367 
368  if( m_OptionPower->GetValue() )
369  m_libEntry->SetPower();
370  else
372 
375 
378 
379  if( m_PinsNameInsideButt->GetValue() )
380  {
381  int offset = KiROUND( (double) m_pinNameOffset.GetValue() );
382 
383  // We interpret an offset of 0 as "outside", so make sure it's non-zero
384  m_libEntry->SetPinNameOffset( offset == 0 ? 20 : offset );
385  }
386  else
387  {
388  m_libEntry->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
389  }
390 
392 
394 
395  // It's possible that the symbol being edited has no pins, in which case there may be no
396  // alternate body style objects causing #LIB_PART::HasCoversion() to always return false.
397  // This allows the user to edit the alternate body style just in case this condition occurs.
398  m_Parent->SetShowDeMorgan( m_AsConvertButt->GetValue() );
399 
400  return true;
401 }
402 
403 
405 {
406  wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
407  wxControl* control = editor->GetControl();
408 
409  if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
410  {
411  event.Veto();
412 
414  m_delayedFocusRow = event.GetRow();
415  m_delayedFocusColumn = event.GetCol();
416  m_delayedFocusPage = 0;
417  }
418  else if( event.GetCol() == FDC_NAME )
419  {
420  wxString newName = event.GetString();
421 
422  for( int i = 0; i < m_grid->GetNumberRows(); ++i )
423  {
424  if( i == event.GetRow() )
425  continue;
426 
427  if( newName.CmpNoCase( m_grid->GetCellValue( i, FDC_NAME ) ) == 0 )
428  {
429  DisplayError( this, wxString::Format( _( "The name '%s' is already in use." ),
430  newName ) );
431  event.Veto();
432  m_delayedFocusRow = event.GetRow();
433  m_delayedFocusColumn = event.GetCol();
434  }
435  }
436  }
437  else if( event.GetRow() == VALUE_FIELD && event.GetCol() == FDC_VALUE )
438  m_SymbolNameCtrl->ChangeValue( event.GetString() );
439 
440  editor->DecRef();
441 }
442 
443 
445 {
447  m_grid->SetCellValue( VALUE_FIELD, FDC_VALUE, m_SymbolNameCtrl->GetValue() );
448 }
449 
450 
452 {
453  if( !m_delayedFocusCtrl && !m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
454  {
456  m_delayedFocusPage = 0;
457  }
458 
459  event.Skip();
460 }
461 
462 
463 void DIALOG_LIB_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
464 {
465  if( !m_grid->CommitPendingChanges() )
466  return;
467 
468  auto* settings = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
469  int fieldID = m_fields->size();
470  LIB_FIELD newField( m_libEntry, fieldID );
471 
472  newField.SetTextSize( wxSize( Mils2iu( settings->m_Defaults.text_size ),
473  Mils2iu( settings->m_Defaults.text_size ) ) );
474 
475  m_fields->push_back( newField );
476 
477  // notify the grid
478  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
479  m_grid->ProcessTableMessage( msg );
480 
481  m_grid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
482  m_grid->SetGridCursor( (int) m_fields->size() - 1, 0 );
483 
484  m_grid->EnableCellEditControl();
485  m_grid->ShowCellEditControl();
486 }
487 
488 
489 void DIALOG_LIB_SYMBOL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
490 {
491  int curRow = m_grid->GetGridCursorRow();
492 
493  if( curRow < 0 )
494  {
495  return;
496  }
497  else if( curRow < MANDATORY_FIELDS )
498  {
499  DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
500  MANDATORY_FIELDS ) );
501  return;
502  }
503 
504  m_grid->CommitPendingChanges( true /* quiet mode */ );
505 
506  m_fields->erase( m_fields->begin() + curRow );
507 
508  // notify the grid
509  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 );
510  m_grid->ProcessTableMessage( msg );
511 
512  if( m_grid->GetNumberRows() > 0 )
513  {
514  m_grid->MakeCellVisible( std::max( 0, curRow-1 ), m_grid->GetGridCursorCol() );
515  m_grid->SetGridCursor( std::max( 0, curRow-1 ), m_grid->GetGridCursorCol() );
516  }
517 }
518 
519 
520 void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
521 {
522  if( !m_grid->CommitPendingChanges() )
523  return;
524 
525  int i = m_grid->GetGridCursorRow();
526 
527  if( i > MANDATORY_FIELDS )
528  {
529  LIB_FIELD tmp = m_fields->at( (unsigned) i );
530  m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
531  m_fields->insert( m_fields->begin() + i - 1, tmp );
532  m_grid->ForceRefresh();
533 
534  m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
535  m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
536  }
537  else
538  wxBell();
539 }
540 
541 
542 void DIALOG_LIB_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
543 {
544  if( !m_grid->CommitPendingChanges() )
545  return;
546 
547  int i = m_grid->GetGridCursorRow();
548 
549  if( i >= MANDATORY_FIELDS && i + 1 < m_fields->GetNumberRows() )
550  {
551  LIB_FIELD tmp = m_fields->at( (unsigned) i );
552  m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
553  m_fields->insert( m_fields->begin() + i + 1, tmp );
554  m_grid->ForceRefresh();
555 
556  m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
557  m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
558  }
559  else
560  wxBell();
561 }
562 
563 
565 {
566 #ifdef KICAD_SPICE
567  int diff = m_fields->size();
568  auto cmp = SCH_COMPONENT( *m_libEntry, m_libEntry->GetLibId(), nullptr );
569 
570  DIALOG_SPICE_MODEL dialog( this, cmp, m_fields );
571 
572  if( dialog.ShowModal() != wxID_OK )
573  return;
574 
575  diff = (int) m_fields->size() - diff;
576 
577  if( diff > 0 )
578  {
579  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, diff );
580  m_grid->ProcessTableMessage( msg );
581  }
582  else if( diff < 0 )
583  {
584  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, -diff );
585  m_grid->ProcessTableMessage( msg );
586  }
587 
588  m_grid->ForceRefresh();
589 #endif /* KICAD_SPICE */
590 }
591 
592 
594 {
595  int idx = m_FootprintFilterListBox->HitTest( event.GetPosition() );
596  wxCommandEvent dummy;
597 
598  if( idx >= 0 )
600  else
602 }
603 
604 
606 {
607  // Running the Footprint Browser gums up the works and causes the automatic cancel
608  // stuff to no longer work. So we do it here ourselves.
609  EndQuasiModal( wxID_CANCEL );
610 }
611 
612 
614 {
615  wxString filterLine;
616  WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Add Footprint Filter" ), filterLine );
617 
618  if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue().IsEmpty() )
619  return;
620 
621  filterLine = dlg.GetValue();
622  filterLine.Replace( wxT( " " ), wxT( "_" ) );
623 
624  // duplicate filters do no harm, so don't be a nanny.
625 
626  m_FootprintFilterListBox->Append( filterLine );
627  m_FootprintFilterListBox->SetSelection( (int) m_FootprintFilterListBox->GetCount() - 1 );
628 }
629 
630 
632 {
633  int ii = m_FootprintFilterListBox->GetSelection();
634 
635  if( ii >= 0 )
636  {
637  m_FootprintFilterListBox->Delete( (unsigned) ii );
638 
639  if( m_FootprintFilterListBox->GetCount() == 0 )
640  m_FootprintFilterListBox->SetSelection( wxNOT_FOUND );
641  else
642  m_FootprintFilterListBox->SetSelection( std::max( 0, ii - 1 ) );
643  }
644 }
645 
646 
648 {
649  int idx = m_FootprintFilterListBox->GetSelection();
650 
651  if( idx >= 0 )
652  {
653  wxString filter = m_FootprintFilterListBox->GetStringSelection();
654 
655  WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Edit Footprint Filter" ), filter );
656 
657  if( dlg.ShowModal() == wxID_OK && !dlg.GetValue().IsEmpty() )
658  m_FootprintFilterListBox->SetString( (unsigned) idx, dlg.GetValue() );
659  }
660 }
661 
662 
664 {
665  m_width = aWidth;
666 
667  // Account for scroll bars
668  aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x );
669 
670  m_grid->AutoSizeColumn( FDC_NAME );
671 
672  int fixedColsWidth = m_grid->GetColSize( FDC_NAME );
673 
674  for( int i = 2; i < m_grid->GetNumberCols(); i++ )
675  fixedColsWidth += m_grid->GetColSize( i );
676 
677  m_grid->SetColSize( FDC_VALUE, aWidth - fixedColsWidth );
678 }
679 
680 
681 void DIALOG_LIB_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
682 {
683  m_OptionPartsInterchangeable->Enable( m_SelNumberOfUnits->GetValue() > 1 );
685 
686  if( m_grid->IsCellEditControlShown() )
687  {
688  int row = m_grid->GetGridCursorRow();
689  int col = m_grid->GetGridCursorCol();
690 
691  if( row == VALUE_FIELD && col == FDC_VALUE )
692  {
693  wxGridCellEditor* editor = m_grid->GetCellEditor( row, col );
694  m_SymbolNameCtrl->ChangeValue( editor->GetValue() );
695  editor->DecRef();
696  }
697  }
698 
699  // Handle shown columns changes
700  wxString shownColumns = m_grid->GetShownColumns();
701 
702  if( shownColumns != m_shownColumns )
703  {
704  m_shownColumns = shownColumns;
705 
706  if( !m_grid->IsCellEditControlShown() )
707  adjustGridColumns( m_grid->GetRect().GetWidth() );
708  }
709 
710  // Handle a delayed focus. The delay allows us to:
711  // a) change focus when the error was triggered from within a killFocus handler
712  // b) show the correct notebook page in the background before the error dialog comes up
713  // when triggered from an OK or a notebook page change
714 
715  if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
716  {
717  m_NoteBook->SetSelection( (unsigned) m_delayedFocusPage );
718  m_delayedFocusPage = -1;
719  }
720 
721  if( !m_delayedErrorMessage.IsEmpty() )
722  {
723  // We will re-enter this routine when the error dialog is displayed, so make
724  // sure we don't keep putting up more dialogs.
725  wxString msg = m_delayedErrorMessage;
726  m_delayedErrorMessage = wxEmptyString;
727 
728  // Do not use DisplayErrorMessage(); it screws up window order on Mac
729  DisplayError( nullptr, msg );
730  }
731 
732  if( m_delayedFocusCtrl )
733  {
734  m_delayedFocusCtrl->SetFocus();
735 
736  if( auto textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
737  textEntry->SelectAll();
738 
739  m_delayedFocusCtrl = nullptr;
740  }
741  else if( m_delayedFocusGrid )
742  {
743  m_delayedFocusGrid->SetFocus();
746 
747  m_delayedFocusGrid->EnableCellEditControl( true );
748  m_delayedFocusGrid->ShowCellEditControl();
749 
750  m_delayedFocusGrid = nullptr;
751  m_delayedFocusRow = -1;
753  }
754 }
755 
756 
758 {
759  auto new_size = event.GetSize().GetX();
760 
761  if( new_size != m_width )
762  {
763  adjustGridColumns( event.GetSize().GetX() );
764  }
765 
766  // Always propagate a wxSizeEvent:
767  event.Skip();
768 }
769 
770 
772 {
773  bSizerLowerBasicPanel->Show( !aIsAlias );
774 
775 #ifdef KICAD_SPICE
776  m_spiceFieldsButton->Show( !aIsAlias );
777 #endif
778 
779  m_inheritanceSelectCombo->Enable( aIsAlias );
780  m_inheritsStaticText->Enable( aIsAlias );
781  m_grid->ForceRefresh();
782 }
783 
784 
785 void DIALOG_LIB_SYMBOL_PROPERTIES::onPowerCheckBox( wxCommandEvent& aEvent )
786 {
787  if( m_OptionPower->IsChecked() )
788  {
789  m_excludeFromBomCheckBox->SetValue( true );
790  m_excludeFromBoardCheckBox->SetValue( true );
791  m_excludeFromBomCheckBox->Enable( false );
792  m_excludeFromBoardCheckBox->Enable( false );
793  }
794  else
795  {
796  m_excludeFromBomCheckBox->Enable( true );
797  m_excludeFromBoardCheckBox->Enable( true );
798  }
799 }
virtual void onPowerCheckBox(wxCommandEvent &aEvent) override
Field Reference of part, i.e. "IC21".
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:252
wxString GetValue() const
void OnEditSpiceModel(wxCommandEvent &event) override
void SetFPFilters(const wxArrayString &aFilters)
Definition: lib_symbol.h:177
LIB_PART * GetAlias(const wxString &aAlias, const wxString &aLibrary) const
Return either an alias of a working LIB_PART copy, or alias of the original part if there is no worki...
void SetPower()
Definition: lib_symbol.cpp:420
LIB_ID GetLibId() const override
Definition: lib_symbol.h:131
void GetRootSymbolNames(const wxString &aLibName, wxArrayString &aRootSymbolNames)
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:265
int GetNumberRows() override
wxString GetName() const override
Definition: lib_symbol.h:129
This file is part of the common library.
bool HasConversion() const
Test if part has more than one body conversion type (DeMorgan).
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:129
void SetShowDeMorgan(bool show)
bool PartExists(const wxString &aAlias, const wxString &aLibrary) const
Return true if part with a specific alias exists in library (either original one or buffered).
A KICAD version of wxTextEntryDialog which supports the various improvments/work-arounds from DIALOG_...
Field object used in symbol libraries.
Definition: lib_field.h:59
void SetUnitCount(int aCount, bool aDuplicateDrawItems=true)
Set the units per part count.
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Definition: sch_symbol.cpp:69
wxArrayString GetFPFilters() const
Definition: lib_symbol.h:179
std::shared_ptr< LIB_PART > PART_SPTR
shared pointer to LIB_PART
Definition: lib_symbol.h:42
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:244
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:65
wxString GetKeyWords() const
Definition: lib_symbol.h:151
void SetIncludeInBom(bool aIncludeInBom)
Set or clear the include in schematic bill of materials flag.
Definition: lib_symbol.h:580
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
wxString GetCurLib() const
The nickname of the current library being edited and empty string if none.
bool IsSymbolFromSchematic() const
wxString GetName(bool aUseDefaultName=true) const
Returns the field name.
Definition: lib_field.cpp:364
name of datasheet
void UpdateAfterSymbolProperties(wxString *aOldName=nullptr)
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:97
void OnMoveUp(wxCommandEvent &event) override
void OnCancelButtonClick(wxCommandEvent &event) override
void OnEditFootprintFilter(wxCommandEvent &event) override
void OnAddField(wxCommandEvent &event) override
DIALOG_LIB_SYMBOL_PROPERTIES(SYMBOL_EDIT_FRAME *parent, LIB_PART *aLibEntry)
void SetConversion(bool aSetConvert, bool aDuplicatePins=true)
Set or clear the alternate body style (DeMorgan) for the part.
Field Value of part, i.e. "3.3K".
#define NULL
int GetUnitCount() const override
For items with units, return the number of units.
void SaveCopyInUndoList(EDA_ITEM *aItem, UNDO_REDO aUndoType=UNDO_REDO::LIBEDIT, bool aAppend=false)
Create a copy of the current symbol, and save it in the undo list.
void SetDescription(const wxString &aDescription)
Definition: lib_symbol.h:136
SYMBOL_LIBRARY_MANAGER & GetLibManager()
void SetParent(LIB_PART *aParent=nullptr)
Definition: lib_symbol.cpp:325
PART_REF & GetParent()
Definition: lib_symbol.h:120
Define a library symbol object.
Definition: lib_symbol.h:93
void GetFields(std::vector< LIB_FIELD * > &aList)
Return a list of fields within this part.
Definition: lib_symbol.cpp:907
wxString GetDescription() override
Definition: lib_symbol.h:138
void OnDeleteFootprintFilter(wxCommandEvent &event) override
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:182
void OnSizeGrid(wxSizeEvent &event) override
void OnUpdateUI(wxUpdateUIEvent &event) override
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104
void OnSymbolNameText(wxCommandEvent &event) override
void OnMoveDown(wxCommandEvent &event) override
void OnDeleteField(wxCommandEvent &event) override
int GetPinNameOffset() const
Definition: lib_symbol.h:557
FIELDS_GRID_TABLE< LIB_FIELD > * m_fields
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
Class DIALOG_LIB_SYMBOL_PROPERTIES_BASE.
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
wxString GetShownColumns()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:110
void EndQuasiModal(int retCode)
bool IsPower() const
Definition: lib_symbol.cpp:411
see class PGM_BASE
void OnAddFootprintFilter(wxCommandEvent &event) override
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: lib_symbol.h:572
#define _(s)
Definition: 3d_actions.cpp:33
bool ShowPinNumbers() const
Definition: lib_symbol.h:573
void SetKeyWords(const wxString &aKeyWords)
Definition: lib_symbol.h:149
bool IsAlias() const
Definition: lib_symbol.h:168
Schematic symbol object.
Definition: sch_symbol.h:78
void resetSize()
Clear the existing dialog size and position.
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:68
bool GetIncludeOnBoard() const
Definition: lib_symbol.h:589
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition: lib_symbol.h:167
virtual long long int GetValue()
Return the current value in Internal Units.
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:314
void SetIncludeOnBoard(bool aIncludeOnBoard)
Set or clear include in board netlist flag.
Definition: lib_symbol.h:588
A text control validator used for validating the text allowed in library and schematic symbol fields.
static bool IsReferenceStringValid(const wxString &aReferenceString)
Test for an acceptable reference string.
Definition: sch_symbol.cpp:465
void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: lib_symbol.h:564
bool GetIncludeInBom() const
Definition: lib_symbol.h:581
void SetPinNameOffset(int aOffset)
Set the offset in mils of the pin name text from the pin symbol.
Definition: lib_symbol.h:556
void SetFields(const std::vector< LIB_FIELD > &aFieldsList)
Overwrite all the existing fields in this symbol with fields supplied in aFieldsList.
Definition: lib_symbol.cpp:890
bool IsSymbolFromLegacyLibrary() const
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:296
bool ShowPinNames() const
Definition: lib_symbol.h:565
void OnSymbolNameKillFocus(wxFocusEvent &event) override
bool UnitsLocked() const
Check whether part units are interchangeable.
Definition: lib_symbol.h:237
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
void LockUnits(bool aLockUnits)
Set interchangeable the property for part units.
Definition: lib_symbol.h:231
void SetNormal()
Definition: lib_symbol.cpp:438
virtual void ChangeValue(int aValue)
Change the value (in Internal Units) for the text field, taking care of units conversion but does not...
The symbol library editor main window.
void OnFilterDClick(wxMouseEvent &event) override