KiCad PCB EDA Suite
dialog_edit_component_in_schematic.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) 2004-2018 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 
25 #include <wx/tooltip.h>
26 #include <pgm_base.h>
27 #include <kiface_i.h>
28 #include <sch_draw_panel.h>
29 #include <confirm.h>
30 #include <sch_edit_frame.h>
31 #include <grid_tricks.h>
32 #include <menus_helpers.h>
33 #include <widgets/wx_grid.h>
34 #include <sch_reference_list.h>
35 #include <class_library.h>
36 #include <symbol_lib_table.h>
37 #include <fields_grid_table.h>
38 
40 #include <invoke_sch_dialog.h>
41 
42 #ifdef KICAD_SPICE
43 #include <dialog_spice_model.h>
45 #endif /* KICAD_SPICE */
46 
47 
48 
49 #define SymbolFieldsShownColumnsKey wxT( "SymbolFieldsShownColumns" )
50 
51 
59 {
60 public:
63 
64  SCH_EDIT_FRAME* GetParent() { return dynamic_cast<SCH_EDIT_FRAME*>( wxDialog::GetParent() ); }
65 
66 private:
67  wxConfigBase* m_config;
68 
71 
74  wxString m_shownColumns;
75 
77 
78  bool TransferDataToWindow() override;
79  bool TransferDataFromWindow() override;
80 
81  bool Validate() override;
82 
83  // event handlers
84  void UpdateFieldsFromLibrary( wxCommandEvent& event ) override;
85  void OnAddField( wxCommandEvent& event ) override;
86  void OnDeleteField( wxCommandEvent& event ) override;
87  void OnMoveUp( wxCommandEvent& event ) override;
88  void OnMoveDown( wxCommandEvent& event ) override;
89  void OnBrowseLibrary( wxCommandEvent& event ) override;
90  void OnEditSpiceModel( wxCommandEvent& event ) override;
91  void OnSizeGrid( wxSizeEvent& event ) override;
92  void OnGridCellChanging( wxGridEvent& event );
93  void OnUpdateUI( wxUpdateUIEvent& event ) override;
94  void OnCancelButtonClick( wxCommandEvent& event ) override;
95 
96  void OnInitDlg( wxInitDialogEvent& event ) override
97  {
99 
100  // Now all widgets have the size fixed, call FinishDialogSettings
102  }
103 
104  void AdjustGridColumns( int aWidth );
105 };
106 
107 
109 {
110  wxCHECK_RET( aComponent != nullptr && aComponent->Type() == SCH_COMPONENT_T,
111  wxT( "Invalid component object pointer. Bad Programmer!" ) );
112 
114 
115  DIALOG_EDIT_COMPONENT_IN_SCHEMATIC dlg( this, aComponent );
116 
117  // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
118  // frame. Therefore this dialog as a modal frame parent, MUST be run under
119  // quasimodal mode for the quasimodal frame support to work. So don't use
120  // the QUASIMODAL macros here.
121  int ret = dlg.ShowQuasiModal();
122 
123  m_canvas->SetIgnoreMouseEvents( false );
125 
126  if( ret == wxID_OK )
127  {
128  if( m_autoplaceFields )
129  aComponent->AutoAutoplaceFields( GetScreen() );
130 
131  GetCanvas()->Refresh();
132  }
133 }
134 
135 
137  SCH_COMPONENT* aComponent ) :
139 {
141 
142  m_cmp = aComponent;
143  m_part = GetParent()->GetLibPart( m_cmp->GetLibId(), true );
144  m_fields = new FIELDS_GRID_TABLE<SCH_FIELD>( this, aParent, m_part );
145 
148 
149 #ifndef KICAD_SPICE
150  m_spiceFieldsButton->Hide();
151 #endif /* not KICAD_SPICE */
152 
153  // disable some options inside the edit dialog which can cause problems while dragging
154  if( m_cmp->IsDragging() )
155  {
156  m_rbOrientation->Disable();
157  m_rbMirror->Disable();
158  m_libraryNameTextCtrl->Disable();
159  }
160 
161  // Give a bit more room for combobox editors
162  m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
163 
165  m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this ) );
166 
167  // Show/hide columns according to user's preference
168  m_config->Read( SymbolFieldsShownColumnsKey, &m_shownColumns, wxT( "0 1 2 3 4 5 6 7" ) );
170 
171  wxToolTip::Enable( true );
172  m_stdDialogButtonSizerOK->SetDefault();
173 
174  // Configure button logos
175  m_buttonBrowseLibrary->SetBitmap( KiBitmap( small_library_xpm ) );
176  m_bpAdd->SetBitmap( KiBitmap( small_plus_xpm ) );
177  m_bpDelete->SetBitmap( KiBitmap( trash_xpm ) );
178  m_bpMoveUp->SetBitmap( KiBitmap( small_up_xpm ) );
179  m_bpMoveDown->SetBitmap( KiBitmap( small_down_xpm ) );
180 
181  // wxFormBuilder doesn't include this event...
182  m_grid->Connect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnGridCellChanging ), NULL, this );
183 
185 }
186 
187 
189 {
191 
192  // Prevents crash bug in wxGrid's d'tor
194 
195  m_grid->Disconnect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnGridCellChanging ), NULL, this );
196 
197  // Delete the GRID_TRICKS.
198  m_grid->PopEventHandler( true );
199 }
200 
201 
203 {
204  if( !wxDialog::TransferDataToWindow() )
205  return false;
206 
207  std::set<wxString> defined;
208 
209  // Push a copy of each field into m_fields
210  for( int i = 0; i < m_cmp->GetFieldCount(); ++i )
211  {
212  SCH_FIELD field( *m_cmp->GetField( i ) );
213 
214  // change offset to be symbol-relative
215  field.Offset( -m_cmp->GetPosition() );
216 
217  defined.insert( field.GetName() );
218  m_fields->push_back( field );
219  }
220 
221  // Add in any template fieldnames not yet defined:
222  for( TEMPLATE_FIELDNAME templateFieldname : GetParent()->GetTemplateFieldNames() )
223  {
224  if( defined.count( templateFieldname.m_Name ) <= 0 )
225  {
226  SCH_FIELD field( wxPoint( 0, 0 ), -1, m_cmp, templateFieldname.m_Name );
227  field.SetVisible( templateFieldname.m_Visible );
228  m_fields->push_back( field );
229  }
230  }
231 
232  // notify the grid
233  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->size() );
234  m_grid->ProcessTableMessage( msg );
235  AdjustGridColumns( m_grid->GetRect().GetWidth() );
236 
237  // If a multi-unit component, set up the unit selector and interchangeable checkbox.
238  if( m_cmp->GetUnitCount() > 1 )
239  {
240  for( int ii = 1; ii <= m_cmp->GetUnitCount(); ii++ )
241  m_unitChoice->Append( LIB_PART::SubReference( ii, false ) );
242 
243  if( m_cmp->GetUnit() <= ( int )m_unitChoice->GetCount() )
244  m_unitChoice->SetSelection( m_cmp->GetUnit() - 1 );
245  }
246  else
247  {
248  m_unitLabel->Enable( false );
249  m_unitChoice->Enable( false );
250  }
251 
252  if( m_part != nullptr && m_part->HasConversion() )
253  {
254  if( m_cmp->GetConvert() > 1 )
255  m_cbAlternateSymbol->SetValue( true );
256  }
257  else
258  m_cbAlternateSymbol->Enable( false );
259 
260  // Set the symbol orientation and mirroring.
261  int orientation = m_cmp->GetOrientation() & ~( CMP_MIRROR_X | CMP_MIRROR_Y );
262 
263  if( orientation == CMP_ORIENT_90 )
264  m_rbOrientation->SetSelection( 1 );
265  else if( orientation == CMP_ORIENT_180 )
266  m_rbOrientation->SetSelection( 2 );
267  else if( orientation == CMP_ORIENT_270 )
268  m_rbOrientation->SetSelection( 3 );
269  else
270  m_rbOrientation->SetSelection( 0 );
271 
272  int mirror = m_cmp->GetOrientation() & ( CMP_MIRROR_X | CMP_MIRROR_Y );
273 
274  if( mirror == CMP_MIRROR_X )
275  {
276  m_rbMirror->SetSelection( 1 );
277  DBG( printf( "mirror=X,1\n" ); )
278  }
279  else if( mirror == CMP_MIRROR_Y )
280  {
281  m_rbMirror->SetSelection( 2 );
282  DBG( printf( "mirror=Y,2\n" ); )
283  }
284  else
285  m_rbMirror->SetSelection( 0 );
286 
287  // Set the component's unique ID time stamp.
288  m_textCtrlTimeStamp->SetValue( wxString::Format( wxT( "%8.8lX" ),
289  (unsigned long) m_cmp->GetTimeStamp() ) );
290 
291  // Set the component's library name.
292  m_libraryNameTextCtrl->SetValue( m_cmp->GetLibId().Format() );
293 
294  Layout();
295 
296  return true;
297 }
298 
299 
301 {
303 
304  LIB_ID id;
305  id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH );
306 
307  auto sel = GetParent()->SelectComponentFromLibTree( nullptr, dummy, true, 0, 0, false, &id );
308 
309  if( !sel.LibId.IsValid() )
310  return;
311 
312  m_libraryNameTextCtrl->SetValue( sel.LibId.Format() );
313 
314  // Update the value field for Power symbols
315  LIB_PART* entry = GetParent()->GetLibPart( sel.LibId );
316 
317  if( entry && entry->IsPower() )
318  m_grid->SetCellValue( VALUE, FDC_VALUE, sel.LibId.GetLibItemName() );
319 }
320 
321 
323 {
324 #ifdef KICAD_SPICE
325  int diff = m_fields->size();
326 
327  DIALOG_SPICE_MODEL dialog( this, *m_cmp, m_fields );
328 
329  if( dialog.ShowModal() != wxID_OK )
330  return;
331 
332  diff = m_fields->size() - diff;
333 
334  if( diff > 0 )
335  {
336  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, diff );
337  m_grid->ProcessTableMessage( msg );
338  }
339  else if( diff < 0 )
340  {
341  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, diff );
342  m_grid->ProcessTableMessage( msg );
343  }
344 
345  m_grid->ForceRefresh();
346 #endif /* KICAD_SPICE */
347 }
348 
349 
351 {
352  // Running the Footprint Browser gums up the works and causes the automatic cancel
353  // stuff to no longer work. So we do it here ourselves.
354  EndQuasiModal( wxID_CANCEL );
355 }
356 
357 
359 {
360  wxString msg;
361  LIB_ID id;
362 
363  if( !m_grid->CommitPendingChanges() )
364  return false;
365 
366  if( !SCH_COMPONENT::IsReferenceStringValid( m_fields->at( REFERENCE ).GetText() ) )
367  {
368  DisplayErrorMessage( this, _( "References must start with a letter." ) );
369 
372 
373  return false;
374  }
375 
376  id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH );
377 
378  if( !id.IsValid() )
379  {
380  DisplayErrorMessage( this, _( "Library reference is not valid." ) );
381 
382  m_libraryNameTextCtrl->SetFocus();
383 
384  return false;
385  }
386  else if( id != m_cmp->GetLibId() )
387  {
388  LIB_ALIAS* alias = nullptr;
389 
390  try
391  {
392  alias = Prj().SchSymbolLibTable()->LoadSymbol( id );
393  }
394  catch( ... )
395  {
396  }
397 
398  if( !alias )
399  {
400  msg.Printf( _( "Symbol \"%s\" not found in library \"%s\"." ),
401  id.GetLibItemName().wx_str(),
402  id.GetLibNickname().wx_str() );
403  DisplayErrorMessage( this, msg );
404 
405  m_libraryNameTextCtrl->SetFocus();
406 
407  return false;
408  }
409  }
410  m_libraryNameTextCtrl->SetValue( id.Format() );
411 
412  // Check for missing field names.
413  for( size_t i = MANDATORY_FIELDS; i < m_fields->size(); ++i )
414  {
415  SCH_FIELD& field = m_fields->at( i );
416  wxString fieldName = field.GetName( false );
417 
418  if( fieldName.IsEmpty() )
419  {
420  DisplayErrorMessage( this, _( "Fields must have a name." ) );
421 
424 
425  return false;
426  }
427  }
428 
429  return true;
430 }
431 
432 
434 {
435  if( !Validate() )
436  return false;
437 
438  // save old cmp in undo list if not already in edit, or moving ...
439  // or the component to be edited is part of a block
442 
443  // Save current flags which could be modified by next change settings
444  STATUS_FLAGS flags = m_cmp->GetFlags();
445 
446  // Library symbol identifier
447  LIB_ID id;
448  id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH, true );
449  m_cmp->SetLibId( id, Prj().SchSymbolLibTable(), Prj().SchLibs()->GetCacheLibrary() );
450 
451  // For symbols with multiple shapes (De Morgan representation) Set the selected shape:
452  if( m_cbAlternateSymbol->IsEnabled() )
453  m_cmp->SetConvert( m_cbAlternateSymbol->GetValue() ? 2 : 1 );
454 
455  //Set the part selection in multiple part per package
456  if( m_cmp->GetUnitCount() > 1 )
457  {
458  int unit_selection = m_unitChoice->GetCurrentSelection() + 1;
459 
460  m_cmp->SetUnitSelection( &GetParent()->GetCurrentSheet(), unit_selection );
461  m_cmp->SetUnit( unit_selection );
462  }
463 
464  switch( m_rbOrientation->GetSelection() )
465  {
466  case 0: m_cmp->SetOrientation( CMP_ORIENT_0 ); break;
467  case 1: m_cmp->SetOrientation( CMP_ORIENT_90 ); break;
468  case 2: m_cmp->SetOrientation( CMP_ORIENT_180 ); break;
469  case 3: m_cmp->SetOrientation( CMP_ORIENT_270 ); break;
470  }
471 
472  switch( m_rbMirror->GetSelection() )
473  {
474  case 0: break;
475  case 1: m_cmp->SetOrientation( CMP_MIRROR_X ); break;
476  case 2: m_cmp->SetOrientation( CMP_MIRROR_Y ); break;
477  }
478 
479  // Restore m_Flag modified by SetUnit() and other change settings
480  m_cmp->ClearFlags();
481  m_cmp->SetFlags( flags );
482 
483  // change all field positions from relative to absolute
484  for( unsigned i = 0; i < m_fields->size(); ++i )
485  m_fields->at( i ).Offset( m_cmp->GetPosition() );
486 
487  LIB_PART* entry = GetParent()->GetLibPart( m_cmp->GetLibId() );
488 
489  if( entry && entry->IsPower() )
490  m_fields->at( VALUE ).SetText( m_cmp->GetLibId().GetLibItemName() );
491 
492  // Remove any TEMPLATE_FIELDNAMES which were not set (given values).
493  TEMPLATE_FIELDNAMES templateFieldnames = GetParent()->GetTemplateFieldNames();
494 
495  for( size_t i = MANDATORY_FIELDS; i < m_fields->size(); ++i )
496  {
497  SCH_FIELD& field = m_fields->at( i );
498 
499  for( auto fieldname : templateFieldnames )
500  {
501  if( field.GetName() == fieldname.m_Name && field.GetText().IsEmpty() )
502  {
503  m_fields->erase( m_fields->begin() + i );
504 
505  // grid needs to be notified about the size change,
506  // as it still accesses the data on close (size event)
507  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, i, 1 );
508  m_grid->ProcessTableMessage( msg );
509  i--;
510  break;
511  }
512  }
513  }
514 
515  m_cmp->SetFields( *m_fields );
516 
517  // Reference has a specific initialization, depending on the current active sheet
518  // because for a given component, in a complex hierarchy, there are more than one
519  // reference.
520  m_cmp->SetRef( &GetParent()->GetCurrentSheet(), m_fields->at( REFERENCE ).GetText() );
521 
522  // The value, footprint and datasheet fields should be kept in sync in multi-unit
523  // parts.
524  if( m_cmp->GetUnitCount() > 1 )
525  {
526  const LIB_ID thisLibId = m_cmp->GetLibId();
527  const wxString thisRef = m_cmp->GetRef( &( GetParent()->GetCurrentSheet() ) );
528  int thisUnit = m_cmp->GetUnit();
529 
530  SCH_REFERENCE_LIST components;
531  GetParent()->GetCurrentSheet().GetComponents( components );
532  for( unsigned i = 0; i < components.GetCount(); i++ )
533  {
534  SCH_REFERENCE component = components[i];
535  if( component.GetLibPart()->GetLibId() == thisLibId
536  && component.GetRef() == thisRef
537  && component.GetUnit() != thisUnit )
538  {
539  SCH_COMPONENT* otherUnit = component.GetComp();
540  GetParent()->SaveCopyInUndoList( otherUnit, UR_CHANGED, true /* append */);
541  otherUnit->GetField( VALUE )->SetText( m_fields->at( VALUE ).GetText() );
542  otherUnit->GetField( FOOTPRINT )->SetText( m_fields->at( FOOTPRINT ).GetText() );
543  otherUnit->GetField( DATASHEET )->SetText( m_fields->at( DATASHEET ).GetText() );
544  }
545  }
546  }
547 
549 
552  GetParent()->OnModify();
553 
554  return true;
555 }
556 
557 
559 {
560  wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
561  wxControl* control = editor->GetControl();
562 
563  if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
564  {
565  event.Veto();
566  m_delayedFocusRow = event.GetRow();
567  m_delayedFocusColumn = event.GetCol();
568  }
569 
570  editor->DecRef();
571 }
572 
573 
575 {
576  if( !m_grid->CommitPendingChanges() )
577  return;
578 
579  int fieldID = m_fields->size();
580  SCH_FIELD newField( wxPoint( 0, 0 ), fieldID, m_cmp );
581 
582  newField.SetName( TEMPLATE_FIELDNAME::GetDefaultFieldName( fieldID ) );
583  newField.SetTextAngle( m_fields->at( REFERENCE ).GetTextAngle() );
584 
585  m_fields->push_back( newField );
586 
587  // notify the grid
588  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
589  m_grid->ProcessTableMessage( msg );
590 
591  m_grid->MakeCellVisible( m_fields->size() - 1, 0 );
592  m_grid->SetGridCursor( m_fields->size() - 1, 0 );
593 
594  m_grid->EnableCellEditControl();
595  m_grid->ShowCellEditControl();
596 }
597 
598 
600 {
601  int curRow = m_grid->GetGridCursorRow();
602 
603  if( curRow < 0 )
604  return;
605  else if( curRow < MANDATORY_FIELDS )
606  {
607  DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
608  MANDATORY_FIELDS ) );
609  return;
610  }
611 
612  m_grid->CommitPendingChanges( true /* quiet mode */ );
613 
614  m_fields->erase( m_fields->begin() + curRow );
615 
616  // notify the grid
617  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 );
618  m_grid->ProcessTableMessage( msg );
619 
620  if( m_grid->GetNumberRows() > 0 )
621  {
622  m_grid->MakeCellVisible( std::max( 0, curRow-1 ), m_grid->GetGridCursorCol() );
623  m_grid->SetGridCursor( std::max( 0, curRow-1 ), m_grid->GetGridCursorCol() );
624  }
625 }
626 
627 
628 void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnMoveUp( wxCommandEvent& event )
629 {
630  if( !m_grid->CommitPendingChanges() )
631  return;
632 
633  int i = m_grid->GetGridCursorRow();
634 
635  if( i > MANDATORY_FIELDS )
636  {
637  SCH_FIELD tmp = m_fields->at( (unsigned) i );
638  m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
639  m_fields->insert( m_fields->begin() + i - 1, tmp );
640  m_grid->ForceRefresh();
641 
642  m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
643  m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
644  }
645  else
646  wxBell();
647 }
648 
649 
651 {
652  if( !m_grid->CommitPendingChanges() )
653  return;
654 
655  int i = m_grid->GetGridCursorRow();
656 
657  if( i >= MANDATORY_FIELDS && i < m_grid->GetNumberRows() - 1 )
658  {
659  SCH_FIELD tmp = m_fields->at( (unsigned) i );
660  m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
661  m_fields->insert( m_fields->begin() + i + 1, tmp );
662  m_grid->ForceRefresh();
663 
664  m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
665  m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
666  }
667  else
668  wxBell();
669 }
670 
671 
673 {
674  if( !m_grid->CommitPendingChanges() )
675  return;
676 
677  SCH_COMPONENT copy( *m_cmp );
678  copy.SetFields( *m_fields );
679 
680  // Update the requested fields in the component copy
681  std::list<SCH_COMPONENT*> components;
682  components.push_back( &copy );
683  InvokeDialogUpdateFields( GetParent(), components, false );
684 
685  // Copy fields from the component copy to the dialog buffer
686  m_fields->clear();
687  std::set<wxString> defined;
688 
689  for( int i = 0; i < copy.GetFieldCount(); ++i )
690  {
691  copy.GetField( i )->SetParent( m_cmp );
692 
693  defined.insert( copy.GetField( i )->GetName() );
694  m_fields->push_back( *copy.GetField( i ) );
695  }
696 
697  // Add in any template fieldnames not yet defined:
698  for( TEMPLATE_FIELDNAME templateFieldname : GetParent()->GetTemplateFieldNames() )
699  {
700  if( defined.count( templateFieldname.m_Name ) <= 0 )
701  {
702  SCH_FIELD field( wxPoint( 0, 0 ), -1, m_cmp, templateFieldname.m_Name );
703  field.SetVisible( templateFieldname.m_Visible );
704  m_fields->push_back( field );
705  }
706  }
707 
708  m_grid->ForceRefresh();
709 }
710 
711 
713 {
714  // Account for scroll bars
715  aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x );
716 
717  m_grid->AutoSizeColumn( 0 );
718 
719  int fixedColsWidth = m_grid->GetColSize( 0 );
720 
721  for( int i = 2; i < m_grid->GetNumberCols(); i++ )
722  fixedColsWidth += m_grid->GetColSize( i );
723 
724  m_grid->SetColSize( 1, aWidth - fixedColsWidth );
725 }
726 
727 
729 {
730  wxString shownColumns = m_grid->GetShownColumns();
731 
732  if( shownColumns != m_shownColumns )
733  {
734  m_shownColumns = shownColumns;
735 
736  if( !m_grid->IsCellEditControlShown() )
737  AdjustGridColumns( m_grid->GetRect().GetWidth() );
738  }
739 
740  // Handle a delayed focus
741  if( m_delayedFocusRow >= 0 )
742  {
743  m_grid->SetFocus();
744  m_grid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn );
745  m_grid->SetGridCursor( m_delayedFocusRow, m_delayedFocusColumn );
746 
747 
748  m_grid->EnableCellEditControl( true );
749  m_grid->ShowCellEditControl();
750 
751  m_delayedFocusRow = -1;
753  }
754 }
755 
756 
758 {
759  AdjustGridColumns( event.GetSize().GetX() );
760 
761  event.Skip();
762 }
void GetComponents(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanComponents=false)
Function GetComponents adds a SCH_REFERENCE() object to aReferences for each component in the sheet.
void SetTextAngle(double aAngle)
Definition: eda_text.h:169
DIALOG_EDIT_COMPONENT_IN_SCHEMATIC(SCH_EDIT_FRAME *aParent, SCH_COMPONENT *aComponent)
Class SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:56
void Offset(const wxPoint &aOffset)
Definition: eda_text.h:242
void EditComponent(SCH_COMPONENT *aComponent)
Display the edit component dialog to edit the parameters of aComponent.
void UpdateFieldsFromLibrary(wxCommandEvent &event) override
void AutoAutoplaceFields(SCH_SCREEN *aScreen)
Autoplace fields only if correct to do so automatically.
Part library alias object definition.
BLOCK_STATE_T GetState() const
const UTF8 & GetLibItemName() const
Definition: lib_id.h:114
BLOCK_SELECTOR m_BlockLocate
Block description for block commands.
Definition: base_screen.h:214
name of datasheet
int GetOrientation()
Get the display symbol orientation.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Function DisplayErrorMessage displays an error message with aMessage.
Definition: confirm.cpp:257
void OnMoveDown(wxCommandEvent &event) override
This file is part of the common library.
bool HasConversion() const
Test if part has more than one body conversion type (DeMorgan).
void OnModify()
Must be called after a schematic change in order to set the "modify" flag of the current screen* and ...
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:119
void OnAddField(wxCommandEvent &event) override
SCH_COMPONENT * GetComp() const
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
void OnEditSpiceModel(wxCommandEvent &event) override
void OnInitDlg(wxInitDialogEvent &event) override
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
int GetUnitCount() const
Return the number of units per package of the symbol.
void SetVisible(bool aVisible)
Definition: eda_text.h:188
void OnCancelButtonClick(wxCommandEvent &event) override
std::vector< COMPONENT_SELECTION > HISTORY_LIST
static const wxString GetDefaultFieldName(int aFieldNdx)
Function GetDefaultFieldName returns a default symbol field name for field aFieldNdx for all componen...
Schematic editor (Eeschema) main window.
LIB_PART * GetLibPart(const LIB_ID &aLibId, bool aUseCacheLib=false, bool aShowErrorMsg=false)
bool TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
void SetUnitSelection(SCH_SHEET_PATH *aSheet, int aUnitSelection)
int GetUnit() const
void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
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:57
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
virtual void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
Field Name Module PCB, i.e. "16DIP300".
Field Reference of part, i.e. "IC21".
bool IsDragging() const
Definition: base_struct.h:222
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
Class SCH_REFERENCE_LIST is used to create a flattened list of components because in a complex hierar...
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
void SetConvert(int aConvert)
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:88
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
wxString GetRef() const
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:79
#define VALUE
void SetLibId(const LIB_ID &aName, PART_LIBS *aLibs=NULL)
int GetUnit() const
void OnBrowseLibrary(wxCommandEvent &event) override
void UpdatePinCache()
Updates the local cache of pin positions.
std::vector< TEMPLATE_FIELDNAME > TEMPLATE_FIELDNAMES
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:256
void SetFields(const SCH_FIELDS &aFields)
Set multiple schematic fields.
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:216
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:143
int ShowQuasiModal()
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
SCH_DRAW_PANEL * GetCanvas() const override
SCH_SHEET_PATH & GetCurrentSheet()
const LIB_ID & GetLibId() const
#define SymbolFieldsShownColumnsKey
void SaveCopyInUndoList(SCH_ITEM *aItemToCopy, UNDO_REDO_T aTypeCommand, bool aAppend=false, const wxPoint &aTransformPoint=wxPoint(0, 0))
Create a copy of the current schematic item, and put it in the undo list.
Define a library symbol object.
void OnDeleteField(wxCommandEvent &event) override
timestamp_t GetTimeStamp() const
Definition: base_struct.h:207
unsigned STATUS_FLAGS
Definition: base_struct.h:147
void SetUnit(int aUnit)
Change the unit number to aUnit.
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:167
const wxString GetRef(const SCH_SHEET_PATH *aSheet)
Return the reference for the given sheet path.
int GetFieldCount() const
Return the number of fields in this symbol.
int InvokeDialogUpdateFields(SCH_EDIT_FRAME *aCaller, const list< SCH_COMPONENT * > aComponents, bool aCreateUndoEntry)
UTF8 Format() const
Definition: lib_id.cpp:237
Class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE.
bool m_autoplaceFields
automatically place component fields
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:126
wxString GetShownColumns()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:101
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void EndQuasiModal(int retCode)
bool IsPower() const
see class PGM_BASE
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
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 RefreshItem(SCH_ITEM *aItem, bool isAddOrDelete=false)
Mark an item for refresh.
LIB_PART * GetLibPart() const
Dialog used to edit SCH_COMPONENT objects in a schematic.
wxString GetName(bool aUseDefaultName=true) const
Function GetName returns the field name.
Definition: sch_field.cpp:435
size_t i
Definition: json11.cpp:597
void SetIgnoreMouseEvents(bool aIgnore)
void SetName(const wxString &aName)
Definition: sch_field.h:85
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:70
wxPoint GetPosition() const override
Function GetPosition.
Struct TEMPLATE_FIELDNAME holds a name of a component's field, field value, and default visibility.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:257
int GetConvert() const
#define DBG(x)
Definition: fctsys.h:33
const TEMPLATE_FIELDNAMES & GetTemplateFieldNames() const
Return a template field names list for read only access.
Definition for part library class.
COMPONENT_SELECTION SelectComponentFromLibTree(const SCHLIB_FILTER *aFilter, std::vector< COMPONENT_SELECTION > &aHistoryList, bool aUseLibBrowser, int aUnit, int aConvert, bool aShowFootprints, const LIB_ID *aHighlight=nullptr, bool aAllowFields=true)
Function SelectComponentFromLib Calls the library viewer to select component to import into schematic...
Definition: getpart.cpp:101
static bool IsReferenceStringValid(const wxString &aReferenceString)
Tests for an acceptable reference string.
int Parse(const UTF8 &aId, LIB_ID_TYPE aType, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:122
unsigned GetCount()
Function GetCount.
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:258
const LIB_ID & GetLibId() const
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:243
void OnUpdateUI(wxUpdateUIEvent &event) override
Class SCH_REFERENCE is used as a helper to define a component's reference designator in a schematic.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
virtual void SetText(const wxString &aText)
Definition: eda_text.h:154
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...