KiCad PCB EDA Suite
dialog_edit_component_in_lib.cpp
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, you may find one here:
22  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23  * or you may search the http://www.gnu.org website for the version 2 license,
24  * or you may write to the Free Software Foundation, Inc.,
25  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27 
28 #include <fctsys.h>
29 #include <kiway.h>
30 #include <common.h>
31 #include <confirm.h>
32 #include <pgm_base.h>
33 #include <kiface_i.h>
34 #include <dialog_text_entry.h>
35 
36 #include <general.h>
37 #include <widgets/wx_grid.h>
39 #include <lib_edit_frame.h>
40 #include <class_library.h>
41 #include <symbol_lib_table.h>
42 #include <sch_component.h>
43 #include <dialog_helpers.h>
44 #include <bitmaps.h>
45 
47 
48 
49 #define LibEditFieldsShownColumnsKey wxT( "LibEditFieldsShownColumns" )
50 
52 
53 
55  LIB_PART* aLibEntry ) :
57  m_Parent( aParent ),
58  m_libEntry( aLibEntry ),
59  m_currentAlias( wxNOT_FOUND ),
60  m_pinNameOffset( aParent, m_nameOffsetLabel, m_nameOffsetCtrl, m_nameOffsetUnits, true ),
61  m_delayedFocusCtrl( nullptr ),
62  m_delayedFocusGrid( nullptr ),
63  m_delayedFocusPage( -1 )
64 {
66 
67  // Give a bit more room for combobox editors
68  m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
69  m_aliasGrid->SetDefaultRowSize( m_aliasGrid->GetDefaultRowSize() + 4 );
70 
71  // Work around a bug in wxWidgets where it fails to recalculate the grid height
72  // after changing the default row size
73  m_aliasGrid->AppendRows( 1 );
74  m_aliasGrid->DeleteRows( m_grid->GetNumberRows() - 1, 1 );
75 
76  m_fields = new FIELDS_GRID_TABLE<LIB_FIELD>( this, aParent, m_libEntry );
78 
79  m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this ) );
80  m_aliasGrid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this ) );
81 
82  // Show/hide columns according to the user's preference
83  m_config->Read( LibEditFieldsShownColumnsKey, &m_shownColumns, wxT( "0 1 2 3 4 5 6 7" ) );
85  // Hide non-overridden rows in aliases grid
86  m_aliasGrid->HideRow( REFERENCE );
87  m_aliasGrid->HideRow( FOOTPRINT );
88 
89  wxGridCellAttr* attr = new wxGridCellAttr;
90  attr->SetReadOnly();
91  m_aliasGrid->SetColAttr( FDC_NAME, attr );
94 
95  attr = new wxGridCellAttr;
96  attr->SetEditor( new GRID_CELL_URL_EDITOR( this ) );
97  m_aliasGrid->SetAttr( DATASHEET, FDC_VALUE, attr );
98 
99  m_SymbolNameCtrl->SetValidator( SCH_FIELD_VALIDATOR( true, VALUE ) );
100 
101  // Configure button logos
102  m_bpAdd->SetBitmap( KiBitmap( small_plus_xpm ) );
103  m_bpDelete->SetBitmap( KiBitmap( trash_xpm ) );
104  m_bpMoveUp->SetBitmap( KiBitmap( small_up_xpm ) );
105  m_bpMoveDown->SetBitmap( KiBitmap( small_down_xpm ) );
106  m_addAliasButton->SetBitmap( KiBitmap( small_plus_xpm ) );
107  m_deleteAliasButton->SetBitmap( KiBitmap( trash_xpm ) );
108  m_addFilterButton->SetBitmap( KiBitmap( small_plus_xpm ) );
109  m_deleteFilterButton->SetBitmap( KiBitmap( trash_xpm ) );
110  m_editFilterButton->SetBitmap( KiBitmap( small_edit_xpm ) );
111 
112  m_stdSizerButtonOK->SetDefault();
113 
114  // wxFormBuilder doesn't include this event...
115  m_grid->Connect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnGridCellChanging ), NULL, this );
116  m_aliasGrid->Connect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAliasGridCellChanging ), NULL, this );
117 
118  m_grid->GetParent()->Layout();
119  m_aliasGrid->GetParent()->Layout();
120  Layout();
121 
123 }
124 
125 
127 {
128  m_lastOpenedPage = m_NoteBook->GetSelection( );
129 
131 
132  // Prevents crash bug in wxGrid's d'tor
134 
135  m_grid->Disconnect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnGridCellChanging ), NULL, this );
136  m_aliasGrid->Disconnect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAliasGridCellChanging ), NULL, this );
137 
138  // Delete the GRID_TRICKS.
139  m_grid->PopEventHandler( true );
140  m_aliasGrid->PopEventHandler( true );
141 
142  // An OK will have transferred these and cleared the buffer, but we have to delete them
143  // on a Cancel.
144  for( LIB_ALIAS* alias : m_aliasesBuffer )
145  delete alias;
146 }
147 
148 
150 {
151  if( !wxDialog::TransferDataToWindow() )
152  return false;
153 
154  // Push a copy of each field into m_fields
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  wxPoint 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 );
169  adjustGridColumns( m_grid->GetRect().GetWidth());
170 
171  m_SymbolNameCtrl->SetValue( m_libEntry->GetName() );
172 
173  LIB_ALIAS* rootAlias = m_libEntry->GetAlias( m_libEntry->GetName() );
174  m_DescCtrl->SetValue( rootAlias->GetDescription() );
175  m_KeywordCtrl->SetValue( rootAlias->GetKeyWords() );
176 
179  m_AsConvertButt->SetValue( m_libEntry->HasConversion() );
180  m_OptionPower->SetValue( m_libEntry->IsPower() );
181 
183  m_ShowPinNameButt->SetValue( m_libEntry->ShowPinNames() );
184  m_PinsNameInsideButt->SetValue( m_libEntry->GetPinNameOffset() != 0 );
186 
187  const LIB_ALIASES aliases = m_libEntry->GetAliases();
188 
189  for( LIB_ALIAS* alias : aliases )
190  {
191  if( alias->IsRoot() )
192  continue;
193 
194  m_aliasesBuffer.push_back( new LIB_ALIAS( *alias, m_libEntry ) );
195  m_aliasListBox->Append( alias->GetName() );
196  }
197 
198  if( m_aliasListBox->GetCount() )
199  {
200  m_aliasListBox->SetSelection( 0 );
201 
202  wxCommandEvent dummy;
203  OnSelectAlias( dummy );
204  }
205 
206  adjustAliasGridColumns( m_aliasGrid->GetClientRect().GetWidth() - 4 );
207 
209 
210  m_NoteBook->SetSelection( (unsigned) m_lastOpenedPage );
211 
212  return true;
213 }
214 
215 
217 {
219  return false;
220 
221  if( !SCH_COMPONENT::IsReferenceStringValid( m_fields->at( REFERENCE ).GetText() ) )
222  {
223  if( m_NoteBook->GetSelection() != 0 )
224  m_NoteBook->SetSelection( 0 );
225 
226  m_delayedErrorMessage = _( "References must start with a letter." );
230  m_delayedFocusPage = 0;
231 
232  return false;
233  }
234 
235  // Check for missing field names.
236  for( size_t i = MANDATORY_FIELDS; i < m_fields->size(); ++i )
237  {
238  LIB_FIELD& field = m_fields->at( i );
239  wxString fieldName = field.GetName( false );
240 
241  if( fieldName.IsEmpty() )
242  {
243  if( m_NoteBook->GetSelection() != 0 )
244  m_NoteBook->SetSelection( 0 );
245 
246  m_delayedErrorMessage = _( "Fields must have a name." );
250  m_delayedFocusPage = 0;
251 
252  return false;
253  }
254  }
255 
256  if( m_SelNumberOfUnits->GetValue() < m_libEntry->GetUnitCount() )
257  {
258  if( !IsOK( this, _( "Delete extra units from symbol?" ) ) )
259  return false;
260  }
261 
262  if( m_AsConvertButt->GetValue() && !m_libEntry->HasConversion() )
263  {
264  if( !IsOK( this, _( "Add new pins for alternate body style (DeMorgan) to symbol?" ) ) )
265  return false;
266  }
267  else if( !m_AsConvertButt->GetValue() && m_libEntry->HasConversion() )
268  {
269  if( !IsOK( this, _( "Delete alternate body style (DeMorgan) draw items from symbol?" ) ) )
270  return false;
271  }
272 
273  return true;
274 }
275 
276 
278 {
279  if( !Validate() )
280  return false;
281 
283 
284  // The Y axis for components in lib is from bottom to top while the screen axis is top
285  // to bottom: we must change the y coord sign when writing back to the library
286  for( size_t i = 0; i < m_fields->size(); ++i )
287  {
288  wxPoint pos = m_fields->at( i ).GetPosition();
289  pos.y = -pos.y;
290  m_fields->at( i ).SetPosition( pos );
291  }
292 
294 
295  // We need to keep the name and the value the same at the moment!
296  SetName( m_libEntry->GetValueField().GetText() );
297 
298  LIB_ALIAS* rootAlias = m_libEntry->GetAlias( m_libEntry->GetName() );
299 
300  rootAlias->SetDescription( m_DescCtrl->GetValue() );
301  rootAlias->SetKeyWords( m_KeywordCtrl->GetValue() );
302 
305 
306  m_libEntry->SetConversion( m_AsConvertButt->GetValue() );
307 
308  if( m_OptionPower->GetValue() )
309  m_libEntry->SetPower();
310  else
312 
315 
316  if( m_PinsNameInsideButt->GetValue() )
317  {
318  int offset = KiROUND( (double) m_pinNameOffset.GetValue() / IU_PER_MILS );
319 
320  // We interpret an offset of 0 as "outside", so make sure it's non-zero
321  m_libEntry->SetPinNameOffset( offset == 0 ? 20 : offset );
322  }
323  else
324  {
325  m_libEntry->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
326  }
327 
330 
331  for( LIB_ALIAS* alias : m_aliasesBuffer )
332  m_libEntry->AddAlias( alias ); // Transfers ownership; no need to delete
333 
334  m_aliasesBuffer.clear();
335 
336  m_libEntry->GetFootprints().Clear();
338 
340  m_Parent->OnModify();
341 
342  return true;
343 }
344 
345 
347 {
348  wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
349  wxControl* control = editor->GetControl();
350 
351  if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
352  {
353  event.Veto();
354 
356  m_delayedFocusRow = event.GetRow();
357  m_delayedFocusColumn = event.GetCol();
358  m_delayedFocusPage = 0;
359  }
360  else if( event.GetRow() == VALUE && event.GetCol() == FDC_VALUE )
361  m_SymbolNameCtrl->ChangeValue( event.GetString() );
362 
363  editor->DecRef();
364 }
365 
366 
368 {
369  m_grid->SetCellValue( VALUE, FDC_VALUE, m_SymbolNameCtrl->GetValue() );
370 }
371 
372 
374 {
375  if( !m_delayedFocusCtrl && !m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
376  {
378  m_delayedFocusPage = 0;
379  }
380 
381  event.Skip();
382 }
383 
384 
385 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAddField( wxCommandEvent& event )
386 {
387  if( !m_grid->CommitPendingChanges() )
388  return;
389 
390  int fieldID = m_fields->size();
391  LIB_FIELD newField( m_libEntry, fieldID );
392 
393  m_fields->push_back( newField );
394 
395  // notify the grid
396  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
397  m_grid->ProcessTableMessage( msg );
398 
399  m_grid->MakeCellVisible( m_fields->size() - 1, 0 );
400  m_grid->SetGridCursor( m_fields->size() - 1, 0 );
401 
402  m_grid->EnableCellEditControl();
403  m_grid->ShowCellEditControl();
404 }
405 
406 
408 {
409  int curRow = m_grid->GetGridCursorRow();
410 
411  if( curRow < 0 )
412  return;
413  else if( curRow < MANDATORY_FIELDS )
414  {
415  DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
416  MANDATORY_FIELDS ) );
417  return;
418  }
419 
420  m_grid->CommitPendingChanges( true /* quiet mode */ );
421 
422  m_fields->erase( m_fields->begin() + curRow );
423 
424  // notify the grid
425  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 );
426  m_grid->ProcessTableMessage( msg );
427 
428  if( m_grid->GetNumberRows() > 0 )
429  {
430  m_grid->MakeCellVisible( std::max( 0, curRow-1 ), m_grid->GetGridCursorCol() );
431  m_grid->SetGridCursor( std::max( 0, curRow-1 ), m_grid->GetGridCursorCol() );
432  }
433 }
434 
435 
436 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnMoveUp( wxCommandEvent& event )
437 {
438  if( !m_grid->CommitPendingChanges() )
439  return;
440 
441  int i = m_grid->GetGridCursorRow();
442 
443  if( i > MANDATORY_FIELDS )
444  {
445  LIB_FIELD tmp = m_fields->at( (unsigned) i );
446  m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
447  m_fields->insert( m_fields->begin() + i - 1, tmp );
448  m_grid->ForceRefresh();
449 
450  m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
451  m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
452  }
453  else
454  wxBell();
455 }
456 
457 
458 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnMoveDown( wxCommandEvent& event )
459 {
460  if( !m_grid->CommitPendingChanges() )
461  return;
462 
463  int i = m_grid->GetGridCursorRow();
464 
465  if( i >= MANDATORY_FIELDS )
466  {
467  LIB_FIELD tmp = m_fields->at( (unsigned) i );
468  m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
469  m_fields->insert( m_fields->begin() + i + 1, tmp );
470  m_grid->ForceRefresh();
471 
472  m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
473  m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
474  }
475  else
476  wxBell();
477 }
478 
479 
480 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::updateAliasName( bool aFromGrid, const wxString& aName )
481 {
482  int idx = m_aliasListBox->GetSelection();
483 
484  if( idx >= 0 )
485  {
486  m_aliasListBox->SetString( (unsigned) idx, aName );
487  m_aliasesBuffer[ idx ]->SetName( aName );
488 
489  if( aFromGrid )
490  m_AliasNameCtrl->ChangeValue( aName );
491  else
492  m_aliasGrid->SetCellValue( VALUE, FDC_VALUE, aName );
493  }
494 }
495 
496 
498 {
499  if( event.GetRow() == VALUE )
500  {
501  int idx = m_aliasListBox->GetSelection();
502  wxString newName = event.GetString();
503 
504  if( idx < 0 || !checkAliasName( newName ) )
505  {
506  event.Veto();
507 
509  m_delayedFocusRow = event.GetRow();
510  m_delayedFocusColumn = event.GetCol();
511  m_delayedFocusPage = 1;
512  }
513  else
514  updateAliasName( true, newName );
515  }
516 }
517 
518 
520 {
521  updateAliasName( false, m_AliasNameCtrl->GetValue() );
522 }
523 
524 
526 {
527  if( !m_delayedFocusCtrl && !checkAliasName( m_AliasNameCtrl->GetValue() ) )
528  {
530  m_delayedFocusPage = 1;
531  }
532 
533  event.Skip();
534 }
535 
536 
538 {
539  if( m_currentAlias >= 0 )
540  {
542 
543  alias->SetName( m_aliasGrid->GetCellValue( VALUE, FDC_VALUE ) );
544  alias->SetDocFileName( m_aliasGrid->GetCellValue( DATASHEET, FDC_VALUE ) );
545  alias->SetDescription( m_AliasDescCtrl->GetValue() );
546  alias->SetKeyWords( m_AliasKeywordsCtrl->GetValue() );
547  }
548 }
549 
550 
552 {
554  {
555  m_aliasListBox->SetSelection( m_currentAlias ); // veto selection change
556  return;
557  }
558 
559  // Copy any pending changes back into the buffer
561 
562  LIB_ALIAS* alias = nullptr;
563  int newIdx = m_aliasListBox->GetSelection();
564 
565  if( newIdx >= 0 )
566  {
567  alias = m_aliasesBuffer[ newIdx ];
568 
569  m_aliasGrid->SetCellValue( VALUE, FDC_VALUE, alias->GetName() );
570  m_aliasGrid->SetCellValue( DATASHEET, FDC_VALUE, alias->GetDocFileName() );
571 
572  // Use ChangeValue() so we don't generate events
573  m_AliasNameCtrl->ChangeValue( alias->GetName() );
574  m_AliasDescCtrl->ChangeValue( alias->GetDescription() );
575  m_AliasKeywordsCtrl->ChangeValue( alias->GetKeyWords() );
576  }
577  else
578  {
579  m_aliasGrid->SetCellValue( VALUE, FDC_VALUE, wxEmptyString );
580  m_aliasGrid->SetCellValue( DATASHEET, FDC_VALUE, wxEmptyString );
581 
582  // Use ChangeValue() so we don't generate events
583  m_AliasNameCtrl->ChangeValue( wxEmptyString );
584  m_AliasDescCtrl->ChangeValue( wxEmptyString );
585  m_AliasKeywordsCtrl->ChangeValue( wxEmptyString );
586  }
587 
588  m_currentAlias = newIdx;
589 }
590 
591 
593 {
594  if( aName.IsEmpty() )
595  return false;
596 
597  for( int i = 0; i < (int)m_aliasListBox->GetCount(); ++i )
598  {
599  if( i == m_aliasListBox->GetSelection() )
600  continue;
601 
602  if( m_aliasListBox->GetString( i ).CmpNoCase( aName ) == 0 )
603  {
604  wxString msg;
605  msg.Printf( _( "Alias \"%s\" already exists." ), aName );
606  DisplayInfoMessage( this, msg );
607  return false;
608  }
609  }
610 
611  wxString library = m_Parent->GetCurLib();
612 
613  if( !library.empty() )
614  {
615  LIB_ALIAS* existing = Prj().SchSymbolLibTable()->LoadSymbol( library, aName );
616 
617  if( existing && existing->GetPart()->GetName() != m_libEntry->GetName() )
618  {
619  wxString msg;
620  msg.Printf( _( "Symbol name \"%s\" already exists in library \"%s\"." ), aName, library );
621  DisplayErrorMessage( this, msg );
622  return false;
623  }
624  }
625 
626  return true;
627 }
628 
629 
630 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAddAlias( wxCommandEvent& event )
631 {
633  return;
634 
635  wxCommandEvent dummy;
636  wxString aliasname = _( "untitled" );
637  int suffix = 1;
638 
639  while( m_libEntry->HasAlias( aliasname ) )
640  aliasname = wxString::Format( _( "untitled%i" ), suffix++ );
641 
642  LIB_ALIAS* alias = new LIB_ALIAS( aliasname, m_libEntry );
643 
644  // Initialize with parent's data
645  alias->SetDescription( m_DescCtrl->GetValue() );
646  alias->SetKeyWords( m_KeywordCtrl->GetValue() );
647  alias->SetDocFileName( m_grid->GetCellValue( DATASHEET, FDC_VALUE ) );
648 
649  m_aliasesBuffer.push_back( alias ); // transfers ownership of alias to aliasesBuffer
650 
651  m_aliasListBox->Append( aliasname );
652  m_aliasListBox->SetSelection( m_aliasListBox->GetCount() - 1 );
653  OnSelectAlias( dummy );
654 }
655 
656 
658 {
660  return;
661 
662  int sel = m_aliasListBox->GetSelection();
663 
664  if( sel == wxNOT_FOUND )
665  return;
666 
667  m_aliasListBox->Delete( (unsigned) sel );
668  m_aliasesBuffer.erase( m_aliasesBuffer.begin() + sel );
669 
670  if( m_aliasListBox->GetCount() == 0 )
671  m_aliasListBox->SetSelection( wxNOT_FOUND );
672  else
673  m_aliasListBox->SetSelection( std::max( 0, sel - 1 ) );
674 
675  wxCommandEvent dummy;
676  OnSelectAlias( dummy );
677 }
678 
679 
681 {
682  wxString filterLine;
683  LIB_PART* component = m_Parent->GetCurPart();
684 
685  if( component == NULL )
686  return;
687 
688  WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Add Footprint Filter" ), filterLine );
689 
690  if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue().IsEmpty() )
691  return;
692 
693  filterLine = dlg.GetValue();
694  filterLine.Replace( wxT( " " ), wxT( "_" ) );
695 
696  // duplicate filters do no harm, so don't be a nanny.
697 
698  m_FootprintFilterListBox->Append( filterLine );
699  m_FootprintFilterListBox->SetSelection( m_FootprintFilterListBox->GetCount() - 1 );
700 }
701 
702 
704 {
705  int ii = m_FootprintFilterListBox->GetSelection();
706 
707  if( ii >= 0 )
708  {
709  m_FootprintFilterListBox->Delete( (unsigned) ii );
710 
711  if( m_FootprintFilterListBox->GetCount() == 0 )
712  m_FootprintFilterListBox->SetSelection( wxNOT_FOUND );
713  else
714  m_FootprintFilterListBox->SetSelection( std::max( 0, ii - 1 ) );
715  }
716 }
717 
719 {
720  int idx = m_FootprintFilterListBox->GetSelection();
721 
722  if( idx >= 0 )
723  {
724  wxString filter = m_FootprintFilterListBox->GetStringSelection();
725 
726  WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Edit Footprint Filter" ), filter );
727 
728  if( dlg.ShowModal() == wxID_OK && !dlg.GetValue().IsEmpty() )
729  m_FootprintFilterListBox->SetString( (unsigned) idx, dlg.GetValue() );
730  }
731 }
732 
733 
735 {
736  // Account for scroll bars
737  aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x );
738 
739  m_grid->AutoSizeColumn( FDC_NAME );
740 
741  int fixedColsWidth = m_grid->GetColSize( FDC_NAME );
742 
743  for( int i = 2; i < m_grid->GetNumberCols(); i++ )
744  fixedColsWidth += m_grid->GetColSize( i );
745 
746  m_grid->SetColSize( FDC_VALUE, aWidth - fixedColsWidth );
747 }
748 
749 
751 {
752  m_aliasGrid->AutoSizeColumn( FDC_NAME );
753  m_aliasGrid->SetColSize( FDC_VALUE, aWidth - m_aliasGrid->GetColSize( FDC_NAME ) - 2 );
754 }
755 
756 
757 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnUpdateUI( wxUpdateUIEvent& event )
758 {
759  m_OptionPartsLocked->Enable( m_SelNumberOfUnits->GetValue() > 1 );
761 
762  if( m_grid->IsCellEditControlShown() )
763  {
764  int row = m_grid->GetGridCursorRow();
765  int col = m_grid->GetGridCursorCol();
766 
767  if( row == VALUE && col == FDC_VALUE )
768  {
769  wxGridCellEditor* editor = m_grid->GetCellEditor( row, col );
770  m_SymbolNameCtrl->ChangeValue( editor->GetValue() );
771  editor->DecRef();
772  }
773  }
774 
775  // Synthesize a Select event when the selection is cleared
776  if( m_aliasListBox->GetSelection() == wxNOT_FOUND && m_currentAlias != wxNOT_FOUND )
777  {
778  wxCommandEvent dummy;
779  OnSelectAlias( dummy );
780  }
781 
782  // Handle shown columns changes
783  wxString shownColumns = m_grid->GetShownColumns();
784 
785  if( shownColumns != m_shownColumns )
786  {
787  m_shownColumns = shownColumns;
788 
789  if( !m_grid->IsCellEditControlShown() )
790  adjustGridColumns( m_grid->GetRect().GetWidth() );
791  }
792 
793  // Handle a delayed focus. The delay allows us to:
794  // a) change focus when the error was triggered from within a killFocus handler
795  // b) show the correct notebook page in the background before the error dialog comes up
796  // when triggered from an OK or a notebook page change
797 
798  if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
799  {
800  m_NoteBook->SetSelection( (unsigned) m_delayedFocusPage );
801  m_delayedFocusPage = -1;
802  }
803 
804  if( !m_delayedErrorMessage.IsEmpty() )
805  {
806  // We will re-enter this routine when the error dialog is displayed, so make
807  // sure we don't keep putting up more dialogs.
808  wxString msg = m_delayedErrorMessage;
809  m_delayedErrorMessage = wxEmptyString;
810 
811  // Do not use DisplayErrorMessage(); it screws up window order on Mac
812  DisplayError( nullptr, msg );
813  }
814 
815  if( m_delayedFocusCtrl )
816  {
817  m_delayedFocusCtrl->SetFocus();
818 
819  if( dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
820  dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl )->SelectAll();
821 
822  m_delayedFocusCtrl = nullptr;
823  }
824  else if( m_delayedFocusGrid )
825  {
826  m_delayedFocusGrid->SetFocus();
829 
830  m_delayedFocusGrid->EnableCellEditControl( true );
831  m_delayedFocusGrid->ShowCellEditControl();
832 
833  m_delayedFocusGrid = nullptr;
834  m_delayedFocusRow = -1;
836  }
837 }
838 
839 
841 {
842  adjustGridColumns( event.GetSize().GetX() );
843 
844  event.Skip();
845 }
846 
847 
849 {
850  adjustAliasGridColumns( event.GetSize().GetX() );
851 
852  event.Skip();
853 }
void OnAddFootprintFilter(wxCommandEvent &event) override
bool UnitsLocked() const
Check whether part units are interchangeable.
Part library alias object definition.
void SetConversion(bool aSetConvert)
Set or clear the alternate body style (DeMorgan) for the part.
void SetPower()
name of datasheet
void OnUpdateUI(wxUpdateUIEvent &event) override
int GetPinNameOffset()
bool HasConversion() const
Test if part has more than one body conversion type (DeMorgan).
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Function DisplayErrorMessage displays an error message with aMessage.
Definition: confirm.cpp:259
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:120
void OnAliasNameText(wxCommandEvent &event) override
bool IsPower() const
int GetNumberRows() override
LIB_ALIAS * GetAlias(size_t aIndex)
void OnEditFootprintFilter(wxCommandEvent &event) override
void OnSizeGrid(wxSizeEvent &event) override
This file is part of the common library.
void updateAliasName(bool aFromGrid, const wxString &aName)
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:108
LIB_ALIASES GetAliases() const
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors...
Field object used in symbol libraries.
Definition: lib_field.h:59
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
bool HasAlias(const wxString &aName) const
Test if alias aName is in part alias list.
LIB_FIELD & GetValueField()
Return reference to the value field.
void OnModify()
Must be called after a schematic change in order to set the "modify" flag of the current screen...
static const wxString GetDefaultFieldName(int aFieldNdx)
Function GetDefaultFieldName returns a default symbol field name for field aFieldNdx for all componen...
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid&#39;s SetTable() method with one which doesn&#39;t mess up the grid column widths when setting th...
Definition: wx_grid.cpp:46
void OnSymbolNameText(wxCommandEvent &event) override
std::vector< LIB_ALIAS * > LIB_ALIASES
void AddAlias(const wxString &aName)
Add an alias aName to the part.
void SetDocFileName(const wxString &aDocFileName)
void OnDeleteFootprintFilter(wxCommandEvent &event) override
Field Name Module PCB, i.e. "16DIP300".
Field Reference of part, i.e. "IC21".
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
void OnAliasNameKillFocus(wxFocusEvent &event) override
void OnMoveUp(wxCommandEvent &event) override
virtual int GetValue()
Function GetValue Returns the current value in Internal Units.
DIALOG_EDIT_COMPONENT_IN_LIBRARY(LIB_EDIT_FRAME *parent, LIB_PART *aLibEntry)
Constructors.
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:77
bool ShowPinNames()
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Function KiBitmap constructs a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:78
void SetName(const wxString &aName)
bool ShowPinNumbers()
LIB_PART * GetCurPart() const
Return the current part being edited or NULL if none selected.
const wxString & GetKeyWords() const
void SetUnitCount(int count)
Set the units per part count.
void OnDeleteField(wxCommandEvent &event) override
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:143
Define a library symbol object.
Helper dialog and control classes.
void OnSelectAlias(wxCommandEvent &event) override
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
wxString GetCurLib() const
The nickname of the current library being edited and empty string if none.
void OnSizeAliasGrid(wxSizeEvent &event) override
void OnSymbolNameKillFocus(wxFocusEvent &event) override
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:156
void SetDescription(const wxString &aDescription)
void OnMoveDown(wxCommandEvent &event) override
wxArrayString & GetFootprints()
wxString GetName(bool aTranslate=true) const
Returns the field name.
Definition: lib_field.cpp:433
LIB_PART * GetPart() const
Get the shared LIB_PART.
void OnDeleteAlias(wxCommandEvent &event) override
int GetUnitCount() const
const wxString & GetDescription() override
const wxString & GetDocFileName() const
#define LibEditFieldsShownColumnsKey
wxString GetShownColumns()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:90
Definition the SCH_COMPONENT class for Eeschema.
wxString GetValue()
The symbol library editor main window.
see class PGM_BASE
const wxString & GetName() const override
void RemoveAllAliases()
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
#define max(a, b)
Definition: auxiliary.h:86
void SetKeyWords(const wxString &aKeyWords)
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
void SaveCopyInUndoList(EDA_ITEM *ItemToCopy, UNDO_REDO_T undoType=UR_LIBEDIT)
Create a copy of the current component, and save it in the undo list.
size_t i
Definition: json11.cpp:597
#define IU_PER_MILS
Definition: plotter.cpp:134
The common library.
Class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE.
const wxString & GetName() const
Definition of class LIB_EDIT_FRAME.
void OnAddAlias(wxCommandEvent &event) override
class SCH_FILED_VALIDATOR
Definition for part library class.
static bool IsReferenceStringValid(const wxString &aReferenceString)
Tests for an acceptable reference string.
void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
void SetPinNameOffset(int aOffset)
Set the offset in mils of the pin name text from the pin symbol.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:277
void SetFields(const std::vector< LIB_FIELD > &aFieldsList)
Overwrite all the existing fields in this symbol with fields supplied in aFieldsList.
#define VALUE
void OnAddField(wxCommandEvent &event) override
FIELDS_GRID_TABLE< LIB_FIELD > * m_fields
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:245
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Function IsOK displays a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:295
void Enable(bool aEnable)
Function Enable Enables/diasables the label, widget and units label.
void GetFields(LIB_FIELDS &aList)
Return a list of fields within this part.
void LockUnits(bool aLockUnits)
Set interchangeable the property for part units.
void SetNormal()