KiCad PCB EDA Suite
dialog_edit_components_libid.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 2017 Jean-Pierre Charras, jp.charras@wanadoo.fr
5  * Copyright 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
31 #include <fctsys.h>
33 #include <sch_edit_frame.h>
34 #include <class_drawpanel.h>
35 #include <sch_component.h>
36 #include <sch_reference_list.h>
37 #include <pgm_base.h>
38 #include <symbol_lib_table.h>
39 
40 #include <wx/choicdlg.h>
41 
42 #define COL_REFS 0
43 #define COL_CURR_LIBID 1
44 #define COL_NEW_LIBID 2
45 
46 // a helper class to handle components to edit
48 {
49 public:
50  SCH_COMPONENT* m_Component; // the schematic component
51  int m_Row; // the row index in m_grid
52  SCH_SCREEN* m_Screen; // the screen where m_Component lives
53  wxString m_Reference; // the schematic reference, only to display it in list
54  wxString m_InitialLibId; // the Lib Id of the component before any change
55  bool m_IsOrphan; // true if a component has no corresponding symbol found in libs
56 
58  {
59  m_Component = aComponent;
60  m_InitialLibId = m_Component->GetLibId().Format();
61  m_Row = -1;
62  m_IsOrphan = false;
63  m_Screen = nullptr;
64  }
65 
66  // Returns a string like mylib:symbol_name from the LIB_ID of the component
67  wxString GetStringLibId()
68  {
69  return m_Component->GetLibId().GetUniStringLibId();
70  }
71 
72  // Returns a string containing the reference of the component
74  {
75  return m_Reference;
76  }
77 };
78 
79 
89 {
90 public:
92 
93  bool IsSchematicModified() { return m_isModified; }
94 
95 private:
97  bool m_isModified; // set to true if the schematic is modified
98  std::vector<int> m_OrphansRowIndexes; // list of rows containing orphan lib_id
99 
100  std::vector<CMP_CANDIDATE> m_components;
101 
102  void initDlg();
103 
111  void AddRowToGrid( int aRowId, bool aMarkRow,
112  const wxString& aReferences, const wxString& aStrLibId );
113 
115  bool validateLibIds();
116 
118  void revertChanges();
119 
124  bool setLibIdByBrowser( int aRow );
125 
126  // Events handlers
127 
128  // called on a right click or a left double click:
129  void onCellBrowseLib( wxGridEvent& event ) override;
130 
131  // Apply changes, but do not close the dialog
132  void onApplyButton( wxCommandEvent& event ) override;
133 
134  // Cancel all changes, and close the dialog
135  void onCancel( wxCommandEvent& event ) override
136  {
137  if( m_isModified )
138  revertChanges();
139  event.Skip();
140  }
141 
142  void onButtonBrowseLibraries( wxCommandEvent& event ) override;
143 
144  // Undo all changes, and clear the list of new lib_ids
145  void onUndoChangesButton( wxCommandEvent& event ) override;
146 
147  // Try to find a candidate for non existing symbols
148  void onClickOrphansButton( wxCommandEvent& event ) override;
149 
150  // UI event, to enable/disable buttons
151  void updateUIChangesButton( wxUpdateUIEvent& event ) override
152  {
153  m_buttonUndo->Enable( m_isModified );
154  }
155 
156  void updateUIBrowseButton( wxUpdateUIEvent& event ) override
157  {
158  wxArrayInt rows = m_grid->GetSelectedRows();
159  m_buttonBrowseLibs->Enable( rows.GetCount() == 1 );
160  }
161 
162  // Automatically called when click on OK button
163  bool TransferDataFromWindow() override;
164 };
165 
166 
169 {
170  m_parent = aParent;
171  initDlg();
172 
173  // Gives a min size to display m_grid, now it is populated:
174  int minwidth = 30 // a margin
175  + m_grid->GetRowLabelSize() + m_grid->GetColSize( COL_REFS )
176  + m_grid->GetColSize( COL_CURR_LIBID ) + m_grid->GetColSize( COL_NEW_LIBID );
177 
178  SetMinClientSize( wxSize( minwidth, VertPixelsFromDU( 250 ) ) );
179 
180  SetSizeInDU( 500, 400 );
181  Center();
182 }
183 
184 
185 // A sort compare function to sort components list by LIB_ID
186 // inside the group of same LIB_ID, sort by reference
187 static bool sort_by_libid( const CMP_CANDIDATE& cmp1, const CMP_CANDIDATE& cmp2 )
188 {
189  if( cmp1.m_Component->GetLibId() == cmp2.m_Component->GetLibId() )
190  return cmp1.m_Reference.Cmp( cmp2.m_Reference ) < 0;
191 
192  return cmp1.m_Component->GetLibId() < cmp2.m_Component->GetLibId();
193 }
194 
195 
197 {
198  m_isModified = false;
199 
200  // Build the component list:
201 #if 0
202  // This option build a component list that works fine to edit LIB_ID fields, but does not display
203  // all components in a complex hierarchy.
204  // the list is shorter, but can be look like there are missing components in list
205  SCH_SCREENS screens;
206 
207  for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
208  {
209  for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
210  {
211  if( item->Type() == SCH_COMPONENT_T )
212  {
213  CMP_CANDIDATE candidate( static_cast< SCH_COMPONENT* >( item ) );
214  candidate.m_Screen = screen;
215  candidate.m_Reference = candidate.m_Component->GetField( REFERENCE )->GetFullyQualifiedText();
216  m_components.push_back( candidate );
217  }
218  }
219  }
220 #else
221  // This option build the full component list
222  // In complex hierarchies, the same component is in fact duplicated, but
223  // it is listed with different references (one by sheet instance)
224  // the list is larger and looks like it contains all components
225  SCH_SHEET_LIST sheets( g_RootSheet );
226  SCH_REFERENCE_LIST references;
227  // build the full list of components including component having no symbol in loaded libs
228  // (orphan components)
229  sheets.GetComponents( references, /* include power symbols */true,
230  /* include orphan components */true );
231 
232  for( unsigned ii = 0; ii < references.GetCount(); ii++ )
233  {
234  SCH_REFERENCE& item = references[ii];
235  CMP_CANDIDATE candidate( item.GetComp() );
236  candidate.m_Screen = item.GetSheetPath().LastScreen();
237  SCH_SHEET_PATH sheetpath = item.GetSheetPath();
238  candidate.m_Reference = candidate.m_Component->GetRef( &sheetpath );
239  // For multi units per package , add unit id.
240  // however, there is a problem: the unit id stored is always >= 1
241  // and 1 for no multi units.
242  // so add unit id only if unit > 1 if the unit count is > 1
243  // (can be 0 if the symbol is not found)
244  int unit = candidate.m_Component->GetUnitSelection( &sheetpath );
245  int unitcount = candidate.m_Component->GetUnitCount();
246  candidate.m_IsOrphan = ( unitcount == 0 );
247 
248  if( unitcount > 1 || unit > 1 )
249  {
250  candidate.m_Reference << wxChar( ('A' + unit -1) );
251  }
252 
253  m_components.push_back( candidate );
254  }
255 #endif
256 
257  if( m_components.size() == 0 )
258  return;
259 
260  // now sort by lib id to create groups of items having the same lib id
261  std::sort( m_components.begin(), m_components.end(), sort_by_libid );
262 
263  // Now, fill m_grid
264  wxString last_str_libid = m_components.front().GetStringLibId();
265  int row = 0;
266  wxString refs;
267  bool mark_cell = m_components.front().m_IsOrphan;
268  CMP_CANDIDATE* cmp = nullptr;
269 
270  for( unsigned ii = 0; ii < m_components.size(); ii++ )
271  {
272  cmp = &m_components[ii];
273 
274  wxString str_libid = cmp->GetStringLibId();
275 
276  if( last_str_libid != str_libid )
277  {
278  // Add last group to grid
279  AddRowToGrid( row, mark_cell, refs, last_str_libid );
280 
281  // prepare next entry
282  mark_cell = cmp->m_IsOrphan;
283  last_str_libid = str_libid;
284  refs.Empty();
285  row++;
286  }
287 
288  if( !refs.IsEmpty() )
289  refs += " ";
290 
291  refs += cmp->GetSchematicReference();
292  cmp->m_Row = row;
293  }
294 
295  // Add last component group:
296  AddRowToGrid( row, mark_cell, refs, last_str_libid );
297 
298  m_grid->AutoSizeColumn( COL_CURR_LIBID );
299  // ensure the column title is correctly displayed
300  // (the min size is already fixed by AutoSizeColumn() )
301  m_grid->AutoSizeColLabelSize( COL_CURR_LIBID );
302 
303  // Gives a similar width to COL_NEW_LIBID because it can contains similar strings
304  if( m_grid->GetColSize( COL_CURR_LIBID ) > m_grid->GetColSize( COL_NEW_LIBID ) )
305  m_grid->SetColSize( COL_NEW_LIBID, m_grid->GetColSize( COL_CURR_LIBID ) );
306  // ensure the column title is correctly displayed
307  m_grid->SetColMinimalWidth( COL_NEW_LIBID, m_grid->GetColSize( COL_NEW_LIBID ) );
308  m_grid->AutoSizeColLabelSize( COL_NEW_LIBID );
309 
310  // Allows only the selection by row
311  m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
312 
313  m_buttonOrphanItems->Enable( m_OrphansRowIndexes.size() > 0 );
314  Layout();
315 }
316 
317 
318 void DIALOG_EDIT_COMPONENTS_LIBID::AddRowToGrid( int aRowId, bool aMarkRow,
319  const wxString& aReferences, const wxString& aStrLibId )
320 {
321  if( aMarkRow ) // a orphan component exists, set m_AsOrphanCmp as true
322  m_OrphansRowIndexes.push_back( aRowId );
323 
324  int row = aRowId;
325 
326  if( m_grid->GetNumberRows() <= row )
327  m_grid->AppendRows();
328 
329  m_grid->SetCellValue( row, COL_REFS, aReferences );
330  m_grid->SetReadOnly( row, COL_REFS );
331 
332  m_grid->SetCellValue( row, COL_CURR_LIBID, aStrLibId );
333  m_grid->SetReadOnly( row, COL_CURR_LIBID );
334 
335  if( aMarkRow ) // A symbol is not existing in libraries: mark the cell
336  {
337  wxFont font = m_grid->GetDefaultCellFont();
338  font.MakeBold();
339  font.MakeItalic();
340  m_grid->SetCellFont( row, COL_CURR_LIBID, font );
341  }
342 
343  m_grid->SetCellRenderer( row, COL_REFS, new wxGridCellAutoWrapStringRenderer);
344  m_grid->AutoSizeRow( row, false );
345 }
346 
347 
349 {
350  int row_max = m_grid->GetNumberRows() - 1;
351 
352  for( int row = 0; row <= row_max; row++ )
353  {
354  wxString new_libid = m_grid->GetCellValue( row, COL_NEW_LIBID );
355 
356  if( new_libid.IsEmpty() )
357  continue;
358 
359  // a new lib id is found. validate this new value
360  LIB_ID id;
361  id.Parse( new_libid );
362 
363  if( !id.IsValid() )
364  {
365  wxString msg;
366  msg.Printf( _( "Symbol library identifier \"%s\" is not valid at row %d!" ), new_libid, row+1 );
367  wxMessageBox( msg );
368  return false;
369  }
370  }
371 
372  return true;
373 }
374 
375 
376 void DIALOG_EDIT_COMPONENTS_LIBID::onApplyButton( wxCommandEvent& event )
377 {
378  if( TransferDataFromWindow() )
379  m_parent->GetCanvas()->Refresh();
380 }
381 
382 
384 {
385  revertChanges();
386 
387  int row_max = m_grid->GetNumberRows() - 1;
388 
389  for( int row = 0; row <= row_max; row++ )
390  {
391  m_grid->SetCellValue( row, COL_NEW_LIBID, wxEmptyString );
392  }
393 
394  m_isModified = false;
395 }
396 
397 
399 {
400  int row = event.GetRow();
401  m_grid->SelectRow( row ); // only for user, to show the selected line
402 
403  setLibIdByBrowser( row );
404 
405 }
406 
407 
409 {
410  wxArrayInt rows = m_grid->GetSelectedRows();
411 
412  if( rows.GetCount() != 1 ) // Should not occur, because the button is disabled
413  return;
414 
415  setLibIdByBrowser( rows[0] );
416 }
417 
418 
420 {
421  std::vector< wxString > libs = Prj().SchSymbolLibTable()->GetLogicalLibs();
422  wxArrayString aliasNames;
423  wxArrayString candidateSymbNames;
424 
425  unsigned fixesCount = 0;
426 
427  // Try to find a candidate for non existing symbols in any loaded library
428  for( unsigned ii = 0; ii < m_OrphansRowIndexes.size(); ii++ )
429  {
430  wxString orphanLibid = m_grid->GetCellValue( m_OrphansRowIndexes[ii], COL_CURR_LIBID );
431  int grid_row_idx = m_OrphansRowIndexes[ii]; //row index in m_grid for the current item
432 
433  LIB_ID curr_libid( orphanLibid );
434  wxString symbName = curr_libid.GetLibItemName();
435  // number of full LIB_ID candidates (because we search for a symbol name
436  // inside all avaiable libraries, perhaps the same symbol name can be found
437  // in more than one library, giving ambiguity
438  int libIdCandidateCount = 0;
439  candidateSymbNames.Clear();
440 
441  // now try to fin a candidate
442  for( auto &lib : libs )
443  {
444  aliasNames.Clear();
445 
446  try
447  {
448  Prj().SchSymbolLibTable()->EnumerateSymbolLib( lib, aliasNames );
449  }
450  catch( const IO_ERROR& ) {} // ignore, it is handled below
451 
452  if( aliasNames.IsEmpty() )
453  continue;
454 
455  // Find a symbol name in symbols inside this library:
456  int index = aliasNames.Index( symbName );
457 
458  if( index != wxNOT_FOUND )
459  {
460  // a candidate is found!
461  libIdCandidateCount++;
462  wxString newLibid = lib + ':' + symbName;
463 
464  // Uses the first found. Most of time, it is alone.
465  // Others will be stored in a candidate list
466  if( libIdCandidateCount <= 1 )
467  {
468  m_grid->SetCellValue( grid_row_idx, COL_NEW_LIBID, newLibid );
469  candidateSymbNames.Add( m_grid->GetCellValue( grid_row_idx, COL_NEW_LIBID ) );
470  fixesCount++;
471  }
472  else // Store other candidates for later selection
473  {
474  candidateSymbNames.Add( newLibid );
475  }
476  }
477  }
478 
479  // If more than one LIB_ID candidate, ask for selection between candidates:
480  if( libIdCandidateCount > 1 )
481  {
482  // Mainly for user: select the row being edited
483  m_grid->SelectRow( grid_row_idx );
484 
485  wxString msg;
486  msg.Printf( _( "Available Candidates for %s " ),
487  m_grid->GetCellValue( grid_row_idx, COL_CURR_LIBID ) );
488 
489  wxSingleChoiceDialog dlg ( this, msg,
490  wxString::Format( _( "Candidates count %d " ), libIdCandidateCount ),
491  candidateSymbNames );
492 
493  if( dlg.ShowModal() == wxID_OK )
494  m_grid->SetCellValue( grid_row_idx, COL_NEW_LIBID, dlg.GetStringSelection() );
495  }
496  }
497 
498  if( fixesCount < m_OrphansRowIndexes.size() ) // Not all orphan components are fixed
499  {
500  wxMessageBox( wxString::Format( _( "%u link(s) mapped, %d not found" ),
501  fixesCount, m_OrphansRowIndexes.size() - fixesCount ) );
502  }
503  else
504  wxMessageBox( wxString::Format( _( "All %u link(s) resolved" ), fixesCount ) );
505 }
506 
507 
509 {
510 #if 0
511  // Use dialog symbol selector to choose a symbol
514  m_parent->SelectComponentFromLibrary( NULL, dummy, true, 0, 0, false );
515 #else
516  // Use library viewer to choose a symbol
517  LIB_ID aPreselectedLibid;
519  m_parent->SelectComponentFromLibBrowser( this, NULL, aPreselectedLibid, 0, 0 );
520 #endif
521 
522  if( sel.LibId.empty() ) // command aborted
523  return false;
524 
525  if( !sel.LibId.IsValid() ) // Should not occur
526  {
527  wxMessageBox( _( "Invalid symbol library identifier" ) );
528  return false;
529  }
530 
531  wxString new_libid;
532  new_libid = sel.LibId.Format();
533 
534  m_grid->SetCellValue( aRow, COL_NEW_LIBID, new_libid );
535 
536  return true;
537 }
538 
539 
541 {
542  if( !validateLibIds() )
543  return false;
544 
545  bool change = false;
546  int row_max = m_grid->GetNumberRows() - 1;
547 
548  for( int row = 0; row <= row_max; row++ )
549  {
550  wxString new_libid = m_grid->GetCellValue( row, COL_NEW_LIBID );
551 
552  if( new_libid.IsEmpty() || new_libid == m_grid->GetCellValue( row, COL_CURR_LIBID ) )
553  continue;
554 
555  // a new lib id is found and was already validated.
556  // set this new value
557  LIB_ID id;
558  id.Parse( new_libid );
559 
560  for( CMP_CANDIDATE& cmp : m_components )
561  {
562  if( cmp.m_Row != row )
563  continue;
564 
565  cmp.m_Component->SetLibId( id );
566  change = true;
567  cmp.m_Screen->SetModify();
568  }
569  }
570 
571  if( change )
572  {
573  m_isModified = true;
574  SCH_SCREENS schematic;
575  schematic.UpdateSymbolLinks( true );
576  }
577 
578  return true;
579 }
580 
581 
583 {
584  bool change = false;
585  int row_max = m_grid->GetNumberRows() - 1;
586 
587  for( int row = 0; row <= row_max; row++ )
588  {
589  for( CMP_CANDIDATE& cmp : m_components )
590  {
591  if( cmp.m_Row != row )
592  continue;
593 
594  LIB_ID id;
595  id.Parse( cmp.m_InitialLibId );
596 
597  if( cmp.m_Component->GetLibId() != id )
598  {
599  cmp.m_Component->SetLibId( id );
600  change = true;
601  }
602  }
603  }
604 
605  if( change )
606  {
607  SCH_SCREENS schematic;
608  schematic.UpdateSymbolLinks( true );
609  m_parent->GetCanvas()->Refresh();
610  }
611 }
612 
613 
615 {
616  // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
617  // frame. Therefore this dialog as a modal frame parent, MUST be run under
618  // quasimodal mode for the quasimodal frame support to work. So don't use
619  // the QUASIMODAL macros here.
620  DIALOG_EDIT_COMPONENTS_LIBID dlg( aCaller );
621  // DO NOT use ShowModal() here, otherwise the library browser will not work
622  // properly.
623  dlg.ShowQuasiModal();
624 
625  return dlg.IsSchematicModified();
626 }
DIALOG_EDIT_COMPONENTS_LIBID(SCH_EDIT_FRAME *aParent)
bool IsValid() const
Definition: lib_id.h:175
Class SCH_SHEET_LIST.
void revertChanges()
Reverts all changes already made.
bool empty() const
Definition: lib_id.h:190
SCH_SCREEN * GetNext()
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
Definition: draw_panel.cpp:338
std::vector< CMP_CANDIDATE > m_components
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:359
COMPONENT_SELECTION SelectComponentFromLibBrowser(wxTopLevelWindow *aParent, const SCHLIB_FILTER *aFilter, const LIB_ID &aPreselectedLibid, int aUnit, int aConvert)
Function SelectComponentFromLibBrowser Calls the library viewer to select component to import into sc...
Definition: getpart.cpp:54
const wxString GetFullyQualifiedText() const
Function GetFullyQualifiedText returns the fully qualified field text by allowing for the part suffix...
Definition: sch_field.cpp:80
bool setLibIdByBrowser(int aRow)
run the lib browser and set the selected LIB_ID for row aRow
std::vector< COMPONENT_SELECTION > HISTORY_LIST
int Parse(const UTF8 &aId)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:122
Schematic editor (Eeschema) main window.
SCH_SCREEN * LastScreen() const
Function LastScreen.
#define COL_CURR_LIBID
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
SCH_ITEM * Next() const
Field Reference of part, i.e. "IC21".
wxString GetUniStringLibId() const
Definition: lib_id.h:152
Class SCH_REFERENCE_LIST is used to create a flattened list of components because in a complex hierar...
CMP_CANDIDATE(SCH_COMPONENT *aComponent)
DIALOG_EDIT_COMPONENTS_LIBID is a dialog to globally edit the LIB_ID of groups if components having t...
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:55
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
const UTF8 & GetLibItemName() const
Definition: lib_id.h:118
int ShowQuasiModal()
static bool sort_by_libid(const CMP_CANDIDATE &cmp1, const CMP_CANDIDATE &cmp2)
void onCancel(wxCommandEvent &event) override
void SetSizeInDU(int x, int y)
Set the dialog to the given dimensions in "dialog units".
bool InvokeDialogEditComponentsLibId(SCH_EDIT_FRAME *aCaller)
Run a dialog to modify the LIB_ID of components for instance when a symbol has moved from a symbol li...
void onButtonBrowseLibraries(wxCommandEvent &event) override
Class SCH_SHEET_PATH.
int VertPixelsFromDU(int y)
Convert an integer number of dialog units to pixels, vertically.
void onCellBrowseLib(wxGridEvent &event) override
Definition the SCH_COMPONENT class for Eeschema.
void updateUIBrowseButton(wxUpdateUIEvent &event) override
void onApplyButton(wxCommandEvent &event) override
see class PGM_BASE
void UpdateSymbolLinks(bool aForce=false)
Initialize or reinitialize the weak reference to the LIB_PART for each SCH_COMPONENT found in the ful...
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...
SCH_SHEET_PATH GetSheetPath() const
void AddRowToGrid(int aRowId, bool aMarkRow, const wxString &aReferences, const wxString &aStrLibId)
Add a new row (new entry) in m_grid.
#define COL_NEW_LIBID
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
const LIB_ID & GetLibId() const
UTF8 Format() const
Definition: lib_id.cpp:263
Class DIALOG_EDIT_COMPONENTS_LIBID_BASE.
COMPONENT_SELECTION SelectComponentFromLibrary(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
SCH_SCREEN * GetFirst()
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 list of...
unsigned GetCount()
Function GetCount.
SCH_COMPONENT * GetComp() const
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:76
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
void onUndoChangesButton(wxCommandEvent &event) override
void onClickOrphansButton(wxCommandEvent &event) override
Class SCH_REFERENCE is used as a helper to define a component&#39;s reference designator in a schematic...
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:503
void updateUIChangesButton(wxUpdateUIEvent &event) override
bool validateLibIds()
returns true if all new lib id are valid