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  LIB_ALIAS* rootAlias = m_libEntry->GetAlias( m_libEntry->GetName() );
155 
156  // Push a copy of each field into m_fields
158 
159  // Datasheet field is special; grab its value from the docfilename
160  m_fields->at( DATASHEET ).SetText( rootAlias->GetDocFileName() );
161 
162  // The Y axis for components in lib is from bottom to top while the screen axis is top
163  // to bottom: we must change the y coord sign for editing
164  for( size_t i = 0; i < m_fields->size(); ++i )
165  {
166  wxPoint pos = m_fields->at( i ).GetPosition();
167  pos.y = -pos.y;
168  m_fields->at( i ).SetPosition( pos );
169  }
170 
171  // notify the grid
172  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->GetNumberRows() );
173  m_grid->ProcessTableMessage( msg );
174  adjustGridColumns( m_grid->GetRect().GetWidth());
175 
176  m_SymbolNameCtrl->SetValue( m_libEntry->GetName() );
177 
178  m_DescCtrl->SetValue( rootAlias->GetDescription() );
179  m_KeywordCtrl->SetValue( rootAlias->GetKeyWords() );
180 
183  m_AsConvertButt->SetValue( m_libEntry->HasConversion() );
184  m_OptionPower->SetValue( m_libEntry->IsPower() );
185 
187  m_ShowPinNameButt->SetValue( m_libEntry->ShowPinNames() );
188  m_PinsNameInsideButt->SetValue( m_libEntry->GetPinNameOffset() != 0 );
190 
191  const LIB_ALIASES aliases = m_libEntry->GetAliases();
192 
193  for( LIB_ALIAS* alias : aliases )
194  {
195  if( alias->IsRoot() )
196  continue;
197 
198  m_aliasesBuffer.push_back( new LIB_ALIAS( *alias, m_libEntry ) );
199  m_aliasListBox->Append( alias->GetName() );
200  }
201 
202  if( m_aliasListBox->GetCount() )
203  {
204  m_aliasListBox->SetSelection( 0 );
205 
206  wxCommandEvent dummy;
207  OnSelectAlias( dummy );
208  }
209 
210  adjustAliasGridColumns( m_aliasGrid->GetClientRect().GetWidth() - 4 );
211 
213 
214  m_NoteBook->SetSelection( (unsigned) m_lastOpenedPage );
215 
216  return true;
217 }
218 
219 
221 {
223  return false;
224 
225  if( !SCH_COMPONENT::IsReferenceStringValid( m_fields->at( REFERENCE ).GetText() ) )
226  {
227  if( m_NoteBook->GetSelection() != 0 )
228  m_NoteBook->SetSelection( 0 );
229 
230  m_delayedErrorMessage = _( "References must start with a letter." );
234  m_delayedFocusPage = 0;
235 
236  return false;
237  }
238 
239  // Check for missing field names.
240  for( size_t i = MANDATORY_FIELDS; i < m_fields->size(); ++i )
241  {
242  LIB_FIELD& field = m_fields->at( i );
243  wxString fieldName = field.GetName( false );
244 
245  if( fieldName.IsEmpty() )
246  {
247  if( m_NoteBook->GetSelection() != 0 )
248  m_NoteBook->SetSelection( 0 );
249 
250  m_delayedErrorMessage = _( "Fields must have a name." );
254  m_delayedFocusPage = 0;
255 
256  return false;
257  }
258  }
259 
260  if( m_SelNumberOfUnits->GetValue() < m_libEntry->GetUnitCount() )
261  {
262  if( !IsOK( this, _( "Delete extra units from symbol?" ) ) )
263  return false;
264  }
265 
266  if( m_AsConvertButt->GetValue() && !m_libEntry->HasConversion() )
267  {
268  if( !IsOK( this, _( "Add new pins for alternate body style (DeMorgan) to symbol?" ) ) )
269  return false;
270  }
271  else if( !m_AsConvertButt->GetValue() && m_libEntry->HasConversion() )
272  {
273  if( !IsOK( this, _( "Delete alternate body style (DeMorgan) draw items from symbol?" ) ) )
274  return false;
275  }
276 
277  return true;
278 }
279 
280 
282 {
283  if( !Validate() )
284  return false;
285 
286  LIB_ALIAS* rootAlias = m_libEntry->GetAlias( m_libEntry->GetName() );
287 
289 
290  // The Y axis for components in lib is from bottom to top while the screen axis is top
291  // to bottom: we must change the y coord sign when writing back to the library
292  for( size_t i = 0; i < m_fields->size(); ++i )
293  {
294  wxPoint pos = m_fields->at( i ).GetPosition();
295  pos.y = -pos.y;
296  m_fields->at( i ).SetPosition( pos );
297  }
298 
299  // Datasheet field is special; copy it to the root alias docfilename
300  rootAlias->SetDocFileName( m_fields->at( DATASHEET ).GetText() );
301  m_fields->at( DATASHEET ).SetText( wxEmptyString );
302 
304 
305  // We need to keep the name and the value the same at the moment!
307 
308  rootAlias->SetDescription( m_DescCtrl->GetValue() );
309  rootAlias->SetKeyWords( m_KeywordCtrl->GetValue() );
310 
313 
314  m_libEntry->SetConversion( m_AsConvertButt->GetValue() );
315 
316  if( m_OptionPower->GetValue() )
317  m_libEntry->SetPower();
318  else
320 
323 
324  if( m_PinsNameInsideButt->GetValue() )
325  {
326  int offset = KiROUND( (double) m_pinNameOffset.GetValue() / IU_PER_MILS );
327 
328  // We interpret an offset of 0 as "outside", so make sure it's non-zero
329  m_libEntry->SetPinNameOffset( offset == 0 ? 20 : offset );
330  }
331  else
332  {
333  m_libEntry->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
334  }
335 
338 
339  for( LIB_ALIAS* alias : m_aliasesBuffer )
340  m_libEntry->AddAlias( alias ); // Transfers ownership; no need to delete
341 
342  m_aliasesBuffer.clear();
343 
344  m_libEntry->GetFootprints().Clear();
346 
348  m_Parent->OnModify();
349 
350  return true;
351 }
352 
353 
355 {
356  wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
357  wxControl* control = editor->GetControl();
358 
359  if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
360  {
361  event.Veto();
362 
364  m_delayedFocusRow = event.GetRow();
365  m_delayedFocusColumn = event.GetCol();
366  m_delayedFocusPage = 0;
367  }
368  else if( event.GetRow() == VALUE && event.GetCol() == FDC_VALUE )
369  m_SymbolNameCtrl->ChangeValue( event.GetString() );
370 
371  editor->DecRef();
372 }
373 
374 
376 {
377  m_grid->SetCellValue( VALUE, FDC_VALUE, m_SymbolNameCtrl->GetValue() );
378 }
379 
380 
382 {
383  if( !m_delayedFocusCtrl && !m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
384  {
386  m_delayedFocusPage = 0;
387  }
388 
389  event.Skip();
390 }
391 
392 
393 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAddField( wxCommandEvent& event )
394 {
395  if( !m_grid->CommitPendingChanges() )
396  return;
397 
398  int fieldID = m_fields->size();
399  LIB_FIELD newField( m_libEntry, fieldID );
400 
401  m_fields->push_back( newField );
402 
403  // notify the grid
404  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
405  m_grid->ProcessTableMessage( msg );
406 
407  m_grid->MakeCellVisible( m_fields->size() - 1, 0 );
408  m_grid->SetGridCursor( m_fields->size() - 1, 0 );
409 
410  m_grid->EnableCellEditControl();
411  m_grid->ShowCellEditControl();
412 }
413 
414 
416 {
417  int curRow = m_grid->GetGridCursorRow();
418 
419  if( curRow < 0 )
420  return;
421  else if( curRow < MANDATORY_FIELDS )
422  {
423  DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
424  MANDATORY_FIELDS ) );
425  return;
426  }
427 
428  m_grid->CommitPendingChanges( true /* quiet mode */ );
429 
430  m_fields->erase( m_fields->begin() + curRow );
431 
432  // notify the grid
433  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 );
434  m_grid->ProcessTableMessage( msg );
435 
436  if( m_grid->GetNumberRows() > 0 )
437  {
438  m_grid->MakeCellVisible( std::max( 0, curRow-1 ), m_grid->GetGridCursorCol() );
439  m_grid->SetGridCursor( std::max( 0, curRow-1 ), m_grid->GetGridCursorCol() );
440  }
441 }
442 
443 
444 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnMoveUp( wxCommandEvent& event )
445 {
446  if( !m_grid->CommitPendingChanges() )
447  return;
448 
449  int i = m_grid->GetGridCursorRow();
450 
451  if( i > MANDATORY_FIELDS )
452  {
453  LIB_FIELD tmp = m_fields->at( (unsigned) i );
454  m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
455  m_fields->insert( m_fields->begin() + i - 1, tmp );
456  m_grid->ForceRefresh();
457 
458  m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
459  m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
460  }
461  else
462  wxBell();
463 }
464 
465 
466 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnMoveDown( wxCommandEvent& event )
467 {
468  if( !m_grid->CommitPendingChanges() )
469  return;
470 
471  int i = m_grid->GetGridCursorRow();
472 
473  if( i >= MANDATORY_FIELDS )
474  {
475  LIB_FIELD tmp = m_fields->at( (unsigned) i );
476  m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
477  m_fields->insert( m_fields->begin() + i + 1, tmp );
478  m_grid->ForceRefresh();
479 
480  m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
481  m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
482  }
483  else
484  wxBell();
485 }
486 
487 
488 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::updateAliasName( bool aFromGrid, const wxString& aName )
489 {
490  int idx = m_aliasListBox->GetSelection();
491 
492  if( idx >= 0 )
493  {
494  m_aliasListBox->SetString( (unsigned) idx, aName );
495  m_aliasesBuffer[ idx ]->SetName( aName );
496 
497  if( aFromGrid )
498  m_AliasNameCtrl->ChangeValue( aName );
499  else
500  m_aliasGrid->SetCellValue( VALUE, FDC_VALUE, aName );
501  }
502 }
503 
504 
506 {
507  if( event.GetRow() == VALUE )
508  {
509  int idx = m_aliasListBox->GetSelection();
510  wxString newName = event.GetString();
511 
512  if( idx < 0 || !checkAliasName( newName ) )
513  {
514  event.Veto();
515 
517  m_delayedFocusRow = event.GetRow();
518  m_delayedFocusColumn = event.GetCol();
519  m_delayedFocusPage = 1;
520  }
521  else
522  updateAliasName( true, newName );
523  }
524 }
525 
526 
528 {
529  updateAliasName( false, m_AliasNameCtrl->GetValue() );
530 }
531 
532 
534 {
535  if( !m_delayedFocusCtrl && !checkAliasName( m_AliasNameCtrl->GetValue() ) )
536  {
538  m_delayedFocusPage = 1;
539  }
540 
541  event.Skip();
542 }
543 
544 
546 {
547  if( m_currentAlias >= 0 )
548  {
550 
551  alias->SetName( m_aliasGrid->GetCellValue( VALUE, FDC_VALUE ) );
552  alias->SetDocFileName( m_aliasGrid->GetCellValue( DATASHEET, FDC_VALUE ) );
553  alias->SetDescription( m_AliasDescCtrl->GetValue() );
554  alias->SetKeyWords( m_AliasKeywordsCtrl->GetValue() );
555  }
556 }
557 
558 
560 {
562  {
563  m_aliasListBox->SetSelection( m_currentAlias ); // veto selection change
564  return;
565  }
566 
567  // Copy any pending changes back into the buffer
569 
570  LIB_ALIAS* alias = nullptr;
571  int newIdx = m_aliasListBox->GetSelection();
572 
573  if( newIdx >= 0 )
574  {
575  alias = m_aliasesBuffer[ newIdx ];
576 
577  m_aliasGrid->SetCellValue( VALUE, FDC_VALUE, alias->GetName() );
578  m_aliasGrid->SetCellValue( DATASHEET, FDC_VALUE, alias->GetDocFileName() );
579 
580  // Use ChangeValue() so we don't generate events
581  m_AliasNameCtrl->ChangeValue( alias->GetName() );
582  m_AliasDescCtrl->ChangeValue( alias->GetDescription() );
583  m_AliasKeywordsCtrl->ChangeValue( alias->GetKeyWords() );
584  }
585  else
586  {
587  m_aliasGrid->SetCellValue( VALUE, FDC_VALUE, wxEmptyString );
588  m_aliasGrid->SetCellValue( DATASHEET, FDC_VALUE, wxEmptyString );
589 
590  // Use ChangeValue() so we don't generate events
591  m_AliasNameCtrl->ChangeValue( wxEmptyString );
592  m_AliasDescCtrl->ChangeValue( wxEmptyString );
593  m_AliasKeywordsCtrl->ChangeValue( wxEmptyString );
594  }
595 
596  m_currentAlias = newIdx;
597 }
598 
599 
601 {
602  if( aName.IsEmpty() )
603  return false;
604 
605  for( int i = 0; i < (int)m_aliasListBox->GetCount(); ++i )
606  {
607  if( i == m_aliasListBox->GetSelection() )
608  continue;
609 
610  if( m_aliasListBox->GetString( i ).CmpNoCase( aName ) == 0 )
611  {
612  wxString msg;
613  msg.Printf( _( "Alias \"%s\" already exists." ), aName );
614  DisplayInfoMessage( this, msg );
615  return false;
616  }
617  }
618 
619  wxString library = m_Parent->GetCurLib();
620 
621  if( !library.empty() )
622  {
623  LIB_ALIAS* existing = Prj().SchSymbolLibTable()->LoadSymbol( library, aName );
624 
625  if( existing && existing->GetPart()->GetName() != m_libEntry->GetName() )
626  {
627  wxString msg;
628  msg.Printf( _( "Symbol name \"%s\" already exists in library \"%s\"." ), aName, library );
629  DisplayErrorMessage( this, msg );
630  return false;
631  }
632  }
633 
634  return true;
635 }
636 
637 
638 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAddAlias( wxCommandEvent& event )
639 {
641  return;
642 
643  wxCommandEvent dummy;
644  wxString aliasname = _( "untitled" );
645  int suffix = 1;
646 
647  while( m_libEntry->HasAlias( aliasname ) )
648  aliasname = wxString::Format( _( "untitled%i" ), suffix++ );
649 
650  LIB_ALIAS* alias = new LIB_ALIAS( aliasname, m_libEntry );
651 
652  // Initialize with parent's data
653  alias->SetDescription( m_DescCtrl->GetValue() );
654  alias->SetKeyWords( m_KeywordCtrl->GetValue() );
655  alias->SetDocFileName( m_grid->GetCellValue( DATASHEET, FDC_VALUE ) );
656 
657  m_aliasesBuffer.push_back( alias ); // transfers ownership of alias to aliasesBuffer
658 
659  m_aliasListBox->Append( aliasname );
660  m_aliasListBox->SetSelection( m_aliasListBox->GetCount() - 1 );
661  OnSelectAlias( dummy );
662 }
663 
664 
666 {
668  return;
669 
670  int sel = m_aliasListBox->GetSelection();
671 
672  if( sel == wxNOT_FOUND )
673  return;
674 
675  m_aliasListBox->Delete( (unsigned) sel );
676  m_aliasesBuffer.erase( m_aliasesBuffer.begin() + sel );
677 
678  if( m_aliasListBox->GetCount() == 0 )
679  m_aliasListBox->SetSelection( wxNOT_FOUND );
680  else
681  m_aliasListBox->SetSelection( std::max( 0, sel - 1 ) );
682 
683  wxCommandEvent dummy;
684  OnSelectAlias( dummy );
685 }
686 
687 
689 {
690  wxString filterLine;
691  LIB_PART* component = m_Parent->GetCurPart();
692 
693  if( component == NULL )
694  return;
695 
696  WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Add Footprint Filter" ), filterLine );
697 
698  if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue().IsEmpty() )
699  return;
700 
701  filterLine = dlg.GetValue();
702  filterLine.Replace( wxT( " " ), wxT( "_" ) );
703 
704  // duplicate filters do no harm, so don't be a nanny.
705 
706  m_FootprintFilterListBox->Append( filterLine );
707  m_FootprintFilterListBox->SetSelection( m_FootprintFilterListBox->GetCount() - 1 );
708 }
709 
710 
712 {
713  int ii = m_FootprintFilterListBox->GetSelection();
714 
715  if( ii >= 0 )
716  {
717  m_FootprintFilterListBox->Delete( (unsigned) ii );
718 
719  if( m_FootprintFilterListBox->GetCount() == 0 )
720  m_FootprintFilterListBox->SetSelection( wxNOT_FOUND );
721  else
722  m_FootprintFilterListBox->SetSelection( std::max( 0, ii - 1 ) );
723  }
724 }
725 
727 {
728  int idx = m_FootprintFilterListBox->GetSelection();
729 
730  if( idx >= 0 )
731  {
732  wxString filter = m_FootprintFilterListBox->GetStringSelection();
733 
734  WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Edit Footprint Filter" ), filter );
735 
736  if( dlg.ShowModal() == wxID_OK && !dlg.GetValue().IsEmpty() )
737  m_FootprintFilterListBox->SetString( (unsigned) idx, dlg.GetValue() );
738  }
739 }
740 
741 
743 {
744  // Account for scroll bars
745  aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x );
746 
747  m_grid->AutoSizeColumn( FDC_NAME );
748 
749  int fixedColsWidth = m_grid->GetColSize( FDC_NAME );
750 
751  for( int i = 2; i < m_grid->GetNumberCols(); i++ )
752  fixedColsWidth += m_grid->GetColSize( i );
753 
754  m_grid->SetColSize( FDC_VALUE, aWidth - fixedColsWidth );
755 }
756 
757 
759 {
760  m_aliasGrid->AutoSizeColumn( FDC_NAME );
761  m_aliasGrid->SetColSize( FDC_VALUE, aWidth - m_aliasGrid->GetColSize( FDC_NAME ) - 2 );
762 }
763 
764 
765 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnUpdateUI( wxUpdateUIEvent& event )
766 {
767  m_OptionPartsLocked->Enable( m_SelNumberOfUnits->GetValue() > 1 );
769 
770  if( m_grid->IsCellEditControlShown() )
771  {
772  int row = m_grid->GetGridCursorRow();
773  int col = m_grid->GetGridCursorCol();
774 
775  if( row == VALUE && col == FDC_VALUE )
776  {
777  wxGridCellEditor* editor = m_grid->GetCellEditor( row, col );
778  m_SymbolNameCtrl->ChangeValue( editor->GetValue() );
779  editor->DecRef();
780  }
781  }
782 
783  // Synthesize a Select event when the selection is cleared
784  if( m_aliasListBox->GetSelection() == wxNOT_FOUND && m_currentAlias != wxNOT_FOUND )
785  {
786  wxCommandEvent dummy;
787  OnSelectAlias( dummy );
788  }
789 
790  // Handle shown columns changes
791  wxString shownColumns = m_grid->GetShownColumns();
792 
793  if( shownColumns != m_shownColumns )
794  {
795  m_shownColumns = shownColumns;
796 
797  if( !m_grid->IsCellEditControlShown() )
798  adjustGridColumns( m_grid->GetRect().GetWidth() );
799  }
800 
801  // Handle a delayed focus. The delay allows us to:
802  // a) change focus when the error was triggered from within a killFocus handler
803  // b) show the correct notebook page in the background before the error dialog comes up
804  // when triggered from an OK or a notebook page change
805 
806  if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
807  {
808  m_NoteBook->SetSelection( (unsigned) m_delayedFocusPage );
809  m_delayedFocusPage = -1;
810  }
811 
812  if( !m_delayedErrorMessage.IsEmpty() )
813  {
814  // We will re-enter this routine when the error dialog is displayed, so make
815  // sure we don't keep putting up more dialogs.
816  wxString msg = m_delayedErrorMessage;
817  m_delayedErrorMessage = wxEmptyString;
818 
819  // Do not use DisplayErrorMessage(); it screws up window order on Mac
820  DisplayError( nullptr, msg );
821  }
822 
823  if( m_delayedFocusCtrl )
824  {
825  m_delayedFocusCtrl->SetFocus();
826 
827  if( dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
828  dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl )->SelectAll();
829 
830  m_delayedFocusCtrl = nullptr;
831  }
832  else if( m_delayedFocusGrid )
833  {
834  m_delayedFocusGrid->SetFocus();
837 
838  m_delayedFocusGrid->EnableCellEditControl( true );
839  m_delayedFocusGrid->ShowCellEditControl();
840 
841  m_delayedFocusGrid = nullptr;
842  m_delayedFocusRow = -1;
844  }
845 }
846 
847 
849 {
850  adjustGridColumns( event.GetSize().GetX() );
851 
852  event.Skip();
853 }
854 
855 
857 {
858  adjustAliasGridColumns( event.GetSize().GetX() );
859 
860  event.Skip();
861 }
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)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:79
void SetName(const wxString &aName)
#define VALUE
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:440
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
virtual void SetName(const wxString &aName)
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.
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()