KiCad PCB EDA Suite
symbol_editor.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) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <pgm_base.h>
27 #include <confirm.h>
28 #include <kiway.h>
29 #include <widgets/infobar.h>
30 #include <tools/ee_actions.h>
32 #include <symbol_edit_frame.h>
33 #include <class_library.h>
34 #include <template_fieldnames.h>
36 #include <symbol_lib_table.h>
37 #include <symbol_library_manager.h>
38 #include <symbol_tree_pane.h>
39 #include <widgets/lib_tree.h>
43 #include <dialog_helpers.h>
44 #include <wx/clipbrd.h>
45 
46 
50 class SAVE_AS_HELPER : public wxPanel
51 {
52 public:
53  SAVE_AS_HELPER( wxWindow* aParent ) :
54  wxPanel( aParent )
55  {
56  m_simpleSaveAs = new wxRadioButton( this, wxID_ANY, _( "Normal save as operation" ),
57  wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
58  m_simpleSaveAs->SetToolTip( _( "Do not perform any additional operations after saving "
59  "library." ) );
60  m_replaceTableEntry = new wxRadioButton( this, wxID_ANY,
61  _( "Replace library table entry" ) );
62  m_replaceTableEntry->SetToolTip( _( "Replace symbol library table entry with new library."
63  "\n\nThe original library will no longer be available "
64  "for use." ) );
65  m_addGlobalTableEntry = new wxRadioButton( this, wxID_ANY,
66  _( "Add new global library table entry" ) );
67  m_addGlobalTableEntry->SetToolTip( _( "Add new entry to the global symbol library table."
68  "\n\nThe symbol library table nickname is suffixed "
69  "with\nan integer to ensure no duplicate table "
70  "entries." ) );
71  m_addProjectTableEntry = new wxRadioButton( this, wxID_ANY,
72  _( "Add new project library table entry" ) );
73  m_addProjectTableEntry->SetToolTip( _( "Add new entry to the project symbol library table."
74  "\n\nThe symbol library table nickname is suffixed "
75  "with\nan integer to ensure no duplicate table "
76  "entries." ) );
77 
78  wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
79  sizer->Add( m_simpleSaveAs, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5 );
80  sizer->Add( m_replaceTableEntry, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5 );
81  sizer->Add( m_addGlobalTableEntry, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5 );
82  sizer->Add( m_addProjectTableEntry, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5 );
83 
84  SetSizerAndFit( sizer );
85  }
86 
87  enum SAH_TYPE
88  {
89  UNDEFINED = -1,
94  };
95 
97  {
98  if( m_simpleSaveAs->GetValue() )
99  return SAH_TYPE::NORMAL_SAVE_AS;
100  else if( m_replaceTableEntry->GetValue() )
101  return SAH_TYPE::REPLACE_TABLE_ENTRY;
102  else if( m_addGlobalTableEntry->GetValue() )
103  return ADD_GLOBAL_TABLE_ENTRY;
104  else if( m_addProjectTableEntry->GetValue() )
106  else
107  return UNDEFINED;
108  }
109 
118  static wxWindow* Create( wxWindow* aParent )
119  {
120  wxCHECK( aParent, nullptr );
121 
122  return new SAVE_AS_HELPER( aParent );
123  }
124 
125 private:
126  wxRadioButton* m_simpleSaveAs;
127  wxRadioButton* m_replaceTableEntry;
128  wxRadioButton* m_addGlobalTableEntry;
129  wxRadioButton* m_addProjectTableEntry;
130 };
131 
132 
134 {
135  wxString lib = GetCurLib();
136  wxString title;
137 
138  if( IsSymbolFromSchematic() )
139  {
140  title = wxString::Format( _( "%s%s [from schematic]" ) + wxT( " \u2014 " ),
141  GetScreen() && GetScreen()->IsModify() ? "*" : "",
142  m_reference );
143  }
144  else
145  {
146  if( GetCurPart() )
147  {
148  bool readOnly = m_libMgr && m_libMgr->IsLibraryReadOnly( GetCurLib() );
149 
150  title = wxString::Format( wxT( "%s%s %s\u2014 " ),
151  GetScreen() && GetScreen()->IsModify() ? "*" : "",
152  GetCurPart()->GetLibId().Format().c_str(),
153  readOnly ? _( "[Read Only Library]" ) + wxT( " " ) : "" );
154  }
155  }
156 
157  title += _( "Symbol Editor" );
158  SetTitle( title );
159 }
160 
161 
162 void SYMBOL_EDIT_FRAME::SelectActiveLibrary( const wxString& aLibrary )
163 {
164  wxString selectedLib = aLibrary;
165 
166  if( selectedLib.empty() )
167  selectedLib = SelectLibraryFromList();
168 
169  if( !selectedLib.empty() )
170  SetCurLib( selectedLib );
171 
172  updateTitle();
173 }
174 
175 
177 {
178  PROJECT& prj = Prj();
179 
180  if( prj.SchSymbolLibTable()->IsEmpty() )
181  {
182  ShowInfoBarError( _( "No symbol libraries are loaded." ) );
183  return wxEmptyString;
184  }
185 
186  wxArrayString headers;
187 
188  headers.Add( _( "Library" ) );
189 
190  std::vector< wxArrayString > itemsToDisplay;
191  std::vector< wxString > libNicknames = prj.SchSymbolLibTable()->GetLogicalLibs();
192 
193  // Conversion from wxArrayString to vector of ArrayString
194  for( const wxString& name : libNicknames )
195  {
196  wxArrayString item;
197 
198  // Exclude read only libraries.
200  continue;
201 
202  item.Add( name );
203  itemsToDisplay.push_back( item );
204  }
205 
206  wxString oldLibName = prj.GetRString( PROJECT::SCH_LIB_SELECT );
207 
208  EDA_LIST_DIALOG dlg( this, _( "Select Symbol Library" ), headers, itemsToDisplay, oldLibName );
209 
210  if( dlg.ShowModal() != wxID_OK )
211  return wxEmptyString;
212 
213  wxString libName = dlg.GetTextSelection();
214 
215  if( !libName.empty() )
216  {
217  if( prj.SchSymbolLibTable()->HasLibrary( libName ) )
218  prj.SetRString( PROJECT::SCH_LIB_SELECT, libName );
219  else
220  libName = wxEmptyString;
221  }
222 
223  return libName;
224 }
225 
226 
228 {
229  if( GetCurPart() )
230  {
231  LIB_ID libId = GetCurPart()->GetLibId();
232  const wxString& libName = libId.GetLibNickname();
233  const wxString& partName = libId.GetLibItemName();
234 
235  if( m_libMgr->FlushPart( partName, libName ) )
236  {
237  m_libMgr->ClearPartModified( partName, libName );
238  return true;
239  }
240  }
241 
242  return false;
243 }
244 
245 
246 bool SYMBOL_EDIT_FRAME::LoadSymbolAndSelectLib( const LIB_ID& aLibId, int aUnit, int aConvert )
247 {
248  if( GetCurPart() && GetCurPart()->GetLibId() == aLibId
249  && GetUnit() == aUnit && GetConvert() == aConvert )
250  {
251  return true;
252  }
253 
254  if( GetScreen()->IsModify() && GetCurPart() )
255  {
256  if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. "
257  "Save changes?" ),
258  [&]()->bool { return saveCurrentPart(); } ) )
259  {
260  return false;
261  }
262  }
263 
265  return LoadSymbolFromCurrentLib( aLibId.GetLibItemName(), aUnit, aConvert );
266 }
267 
268 
269 bool SYMBOL_EDIT_FRAME::LoadSymbolFromCurrentLib( const wxString& aAliasName, int aUnit,
270  int aConvert )
271 {
272  LIB_PART* alias = nullptr;
273 
274  try
275  {
276  alias = Prj().SchSymbolLibTable()->LoadSymbol( GetCurLib(), aAliasName );
277  }
278  catch( const IO_ERROR& ioe )
279  {
280  wxString msg;
281 
282  msg.Printf( _( "Error occurred loading symbol \"%s\" from library \"%s\"." ),
283  aAliasName, GetCurLib() );
284  DisplayErrorMessage( this, msg, ioe.What() );
285  return false;
286  }
287 
288  if( !alias || !LoadOneLibraryPartAux( alias, GetCurLib(), aUnit, aConvert ) )
289  return false;
290 
291  // Enable synchronized pin edit mode for symbols with interchangeable units
293 
296  SetShowDeMorgan( GetCurPart()->Flatten()->HasConversion() );
297 
298  if( aUnit > 0 )
300 
301  return true;
302 }
303 
304 
305 bool SYMBOL_EDIT_FRAME::LoadOneLibraryPartAux( LIB_PART* aEntry, const wxString& aLibrary,
306  int aUnit, int aConvert )
307 {
308  wxString msg, rootName;
309  bool rebuildMenuAndToolbar = false;
310 
311  if( !aEntry || aLibrary.empty() )
312  return false;
313 
314  if( aEntry->GetName().IsEmpty() )
315  {
316  wxLogWarning( "Symbol in library \"%s\" has empty name field.", aLibrary );
317  return false;
318  }
319 
321 
322  // Symbols from the schematic are edited in place and not managed by the library manager.
323  if( IsSymbolFromSchematic() )
324  {
325  delete m_my_part;
326  m_my_part = nullptr;
327 
328  SCH_SCREEN* screen = GetScreen();
329  delete screen;
331  m_isSymbolFromSchematic = false;
332  rebuildMenuAndToolbar = true;
333  }
334 
335  LIB_PART* lib_part = m_libMgr->GetBufferedPart( aEntry->GetName(), aLibrary );
336  wxCHECK( lib_part, false );
337 
338  m_unit = aUnit > 0 ? aUnit : 1;
339  m_convert = aConvert > 0 ? aConvert : 1;
340 
341  // The buffered screen for the part
342  SCH_SCREEN* part_screen = m_libMgr->GetScreen( lib_part->GetName(), aLibrary );
343 
344  SetScreen( part_screen );
345  SetCurPart( new LIB_PART( *lib_part ), true );
346  SetCurLib( aLibrary );
347 
348  if( rebuildMenuAndToolbar )
349  {
350  ReCreateMenuBar();
352  GetInfoBar()->Dismiss();
353  }
354 
355  updateTitle();
357  SetShowDeMorgan( GetCurPart()->HasConversion() );
358 
359  // Display the document information based on the entry selected just in
360  // case the entry is an alias.
362  Refresh();
363 
364  return true;
365 }
366 
367 
369 {
370  saveAllLibraries( false );
372 }
373 
374 
376 {
378 
379  wxArrayString rootSymbols;
380  wxString lib = getTargetLib();
381 
382  if( !m_libMgr->LibraryExists( lib ) )
383  {
384  lib = SelectLibraryFromList();
385 
386  if( !m_libMgr->LibraryExists( lib ) )
387  return;
388  }
389 
390  m_libMgr->GetRootSymbolNames( lib, rootSymbols );
391 
392  rootSymbols.Sort();
393 
394  DIALOG_LIB_NEW_COMPONENT dlg( this, &rootSymbols );
395  dlg.SetMinSize( dlg.GetSize() );
396 
397  if( dlg.ShowModal() == wxID_CANCEL )
398  return;
399 
400  if( dlg.GetName().IsEmpty() )
401  {
402  wxMessageBox( _( "This new symbol has no name and cannot be created." ) );
403  return;
404  }
405 
406  wxString name = dlg.GetName();
407  // Currently, symbol names cannot include a space, that breaks libraries:
408  name.Replace( " ", "_" );
409 
410  // Test if there is a component with this name already.
411  if( !lib.empty() && m_libMgr->PartExists( name, lib ) )
412  {
413  wxString msg = wxString::Format( _( "Symbol \"%s\" already exists in library \"%s\"" ),
414  name, lib );
415  DisplayError( this, msg );
416  return;
417  }
418 
419  LIB_PART new_part( name ); // do not create part on the heap, it will be buffered soon
420 
421  wxString parentSymbolName = dlg.GetParentSymbolName();
422 
423  if( parentSymbolName.IsEmpty() )
424  {
425  new_part.GetReferenceField().SetText( dlg.GetReference() );
426  new_part.SetUnitCount( dlg.GetUnitCount() );
427 
428  // Initialize new_part.m_TextInside member:
429  // if 0, pin text is outside the body (on the pin)
430  // if > 0, pin text is inside the body
431 
432  if( dlg.GetPinNameInside() )
433  {
434  new_part.SetPinNameOffset( dlg.GetPinTextPosition() );
435 
436  if( new_part.GetPinNameOffset() == 0 )
437  new_part.SetPinNameOffset( 1 );
438  }
439  else
440  {
441  new_part.SetPinNameOffset( 0 );
442  }
443 
444  ( dlg.GetPowerSymbol() ) ? new_part.SetPower() : new_part.SetNormal();
445  new_part.SetShowPinNumbers( dlg.GetShowPinNumber() );
446  new_part.SetShowPinNames( dlg.GetShowPinName() );
447  new_part.LockUnits( dlg.GetLockItems() );
448  new_part.SetIncludeInBom( dlg.GetIncludeInBom() );
449  new_part.SetIncludeOnBoard( dlg.GetIncludeOnBoard() );
450 
451  if( dlg.GetUnitCount() < 2 )
452  new_part.LockUnits( false );
453 
454  new_part.SetConversion( dlg.GetAlternateBodyStyle() );
455  // must be called after loadPart, that calls SetShowDeMorgan, but
456  // because the symbol is empty,it looks like it has no alternate body
458  }
459  else
460  {
461  LIB_PART* parent = m_libMgr->GetAlias( parentSymbolName, lib );
462  wxCHECK( parent, /* void */ );
463  new_part.SetParent( parent );
464 
465  // Inherit the parent mandatory field attributes.
466  for( int id=0; id<MANDATORY_FIELDS; ++id )
467  {
468  LIB_FIELD* field = new_part.GetField( id );
469 
470  // the MANDATORY_FIELDS are exactly that in RAM.
471  wxCHECK( field, /* void */ );
472 
473  LIB_FIELD* parentField = parent->GetField( id );
474 
475  wxCHECK( parentField, /* void */ );
476 
477  *field = *parentField;
478 
479  switch( id )
480  {
481  case REFERENCE_FIELD:
482  // parent's reference already copied
483  break;
484 
485  case VALUE_FIELD:
486  field->SetText( name );
487  break;
488 
489  case FOOTPRINT_FIELD:
490  case DATASHEET_FIELD:
491  // - footprint might be the same as parent, but might not
492  // - datasheet is most likely different
493  // - probably best to play it safe and copy neither
494  field->SetText( wxEmptyString );
495  break;
496  }
497 
498  field->SetParent( &new_part );
499  }
500  }
501 
502  m_libMgr->UpdatePart( &new_part, lib );
503  SyncLibraries( false );
504  LoadPart( name, lib, 1 );
505 }
506 
507 
509 {
510  if( getTargetPart() == m_my_part )
511  {
512  if( IsSymbolFromSchematic() )
513  {
514  SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
515 
516  if( !schframe ) // happens when the schematic editor is not active (or closed)
517  {
518  DisplayErrorMessage( this, _( "No schematic currently open." ) );
519  }
520  else
521  {
522  schframe->UpdateSymbolFromEditor( *m_my_part );
523  GetScreen()->ClrModify();
524  }
525  }
526  else
527  {
528  saveCurrentPart();
529  }
530  }
531  else if( !GetTargetLibId().GetLibNickname().empty() )
532  {
533  LIB_ID libId = GetTargetLibId();
534  const wxString& libName = libId.GetLibNickname();
535 
536  if( m_libMgr->IsLibraryReadOnly( libName ) )
537  {
538  wxString msg = wxString::Format( _( "Symbol library '%s' is not writeable." ),
539  libName );
540  wxString msg2 = _( "You must save to a different location." );
541 
542  if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) == wxID_OK )
543  saveLibrary( libName, true );
544  }
545  else
546  {
547  saveLibrary( libName, false );
548  }
549  }
550 
552  updateTitle();
553 }
554 
555 
557 {
558  wxCHECK( !GetTargetLibId().GetLibNickname().empty(), /* void */ );
559 
560  const wxString& libName = GetTargetLibId().GetLibNickname();
561 
562  saveLibrary( libName, true );
564 }
565 
566 
568 {
569  wxCHECK( GetTargetLibId().IsValid(), /* void */ );
570 
571  savePartAs();
572 
574 }
575 
576 
578 {
579  LIB_PART* part = getTargetPart();
580 
581  if( part )
582  {
583  LIB_ID old_lib_id = part->GetLibId();
584  wxString old_name = old_lib_id.GetLibItemName();
585  wxString old_lib = old_lib_id.GetLibNickname();
586 
587  SYMBOL_LIB_TABLE* tbl = Prj().SchSymbolLibTable();
588  wxArrayString headers;
589  std::vector< wxArrayString > itemsToDisplay;
590  std::vector< wxString > libNicknames = tbl->GetLogicalLibs();
591 
592  headers.Add( _( "Nickname" ) );
593  headers.Add( _( "Description" ) );
594 
595  for( const wxString& name : libNicknames )
596  {
597  wxArrayString item;
598  item.Add( name );
599  item.Add( tbl->GetDescription( name ) );
600  itemsToDisplay.push_back( item );
601  }
602 
603  EDA_LIST_DIALOG dlg( this, _( "Save Symbol As" ), headers, itemsToDisplay, old_lib );
604  dlg.SetListLabel( _( "Save in library:" ) );
605  dlg.SetOKLabel( _( "Save" ) );
606 
607  wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
608 
609  wxStaticText* label = new wxStaticText( &dlg, wxID_ANY, _( "Name:" ),
610  wxDefaultPosition, wxDefaultSize, 0 );
611  bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
612 
613  wxTextCtrl* nameTextCtrl = new wxTextCtrl( &dlg, wxID_ANY, old_name,
614  wxDefaultPosition, wxDefaultSize, 0 );
615  bNameSizer->Add( nameTextCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
616 
617  wxSizer* mainSizer = dlg.GetSizer();
618  mainSizer->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
619 
620  // Move nameTextCtrl to the head of the tab-order
621  if( dlg.GetChildren().DeleteObject( nameTextCtrl ) )
622  dlg.GetChildren().Insert( nameTextCtrl );
623 
624  dlg.SetInitialFocus( nameTextCtrl );
625 
626  dlg.Layout();
627  mainSizer->Fit( &dlg );
628 
629  if( dlg.ShowModal() != wxID_OK )
630  return; // canceled by user
631 
632  wxString new_lib = dlg.GetTextSelection();
633 
634  if( new_lib.IsEmpty() )
635  {
636  DisplayError( this, _( "No library specified. Symbol could not be saved." ) );
637  return;
638  }
639 
640  // @todo Either check the selecteced library to see if the parent symbol name is in
641  // the new library and/or copy the parent symbol as well. This is the lazy
642  // solution to ensure derived parts do not get orphaned.
643  if( part->IsAlias() && new_lib != old_lib )
644  {
645  DisplayError( this, _( "Derived symbols must be saved in the same library as their "
646  "parent symbol." ) );
647  return;
648  }
649 
650  wxString new_name = nameTextCtrl->GetValue();
651  new_name.Trim( true );
652  new_name.Trim( false );
653  new_name.Replace( " ", "_" );
654 
655  if( new_name.IsEmpty() )
656  {
657  // This is effectively a cancel. No need to nag the user about it.
658  return;
659  }
660 
661  // Test if there is a component with this name already.
662  if( m_libMgr->PartExists( new_name, new_lib ) )
663  {
664  wxString msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'" ),
665  new_name,
666  new_lib );
667  DisplayError( this, msg );
668  return;
669  }
670 
671  LIB_PART new_part( *part );
672  new_part.SetName( new_name );
673 
674  m_libMgr->UpdatePart( &new_part, new_lib );
675  SyncLibraries( false );
676  m_treePane->GetLibTree()->SelectLibId( LIB_ID( new_lib, new_part.GetName() ) );
677  LoadPart( new_name, new_lib, m_unit );
678  }
679 }
680 
681 
683 {
684  wxCHECK( m_my_part, /* void */ );
685 
686  wxString msg;
687  wxString lib = GetCurLib();
688 
689  if( !lib.IsEmpty() && aOldName && *aOldName != m_my_part->GetName() )
690  {
691  // Test the current library for name conflicts
692  if( m_libMgr->PartExists( m_my_part->GetName(), lib ) )
693  {
694  msg.Printf( _( "The name '%s' conflicts with an existing entry in the library '%s'." ),
695  m_my_part->GetName(),
696  lib );
697 
698  DisplayErrorMessage( this, msg );
699  m_my_part->SetName( *aOldName );
700  }
701  else
702  {
703  m_libMgr->UpdatePartAfterRename( m_my_part, *aOldName, lib );
704  }
705 
706  // Reselect the renamed part
708  }
709 
711  SetShowDeMorgan( GetCurPart()->Flatten()->HasConversion() );
712  updateTitle();
714 
715  RebuildView();
716  OnModify();
717 }
718 
719 
721 {
722  LIB_ID libId = GetTargetLibId();
723 
724  if( m_libMgr->IsPartModified( libId.GetLibItemName(), libId.GetLibNickname() )
725  && !IsOK( this, _( wxString::Format( "The symbol \"%s\" has been modified\n"
726  "Do you want to remove it from the library?",
727  libId.GetUniStringLibItemName() ) ) ) )
728  {
729  return;
730  }
731 
732  if( m_libMgr->HasDerivedSymbols( libId.GetLibItemName(), libId.GetLibNickname() ) )
733  {
734  wxString msg;
735 
736  msg.Printf( _( "The symbol \"%s\" is used to derive other symbols.\n"
737  "Deleting this symbol will delete all of the symbols derived from it.\n\n"
738  "Do you wish to delete this symbol and all of it's derivatives?" ),
739  libId.GetLibItemName().wx_str() );
740 
741  wxMessageDialog::ButtonLabel yesButtonLabel( _( "Delete Symbol" ) );
742  wxMessageDialog::ButtonLabel noButtonLabel( _( "Keep Symbol" ) );
743 
744  wxMessageDialog dlg( this, msg, _( "Warning" ),
745  wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTER );
746  dlg.SetYesNoLabels( yesButtonLabel, noButtonLabel );
747 
748  if( dlg.ShowModal() == wxID_NO )
749  return;
750  }
751 
752  if( isCurrentPart( libId ) )
753  emptyScreen();
754 
755  m_libMgr->RemovePart( libId.GetLibItemName(), libId.GetLibNickname() );
756 
758 }
759 
760 
762 {
763  int dummyUnit;
764  LIB_ID libId = m_treePane->GetLibTree()->GetSelectedLibId( &dummyUnit );
765  LIB_PART* part = m_libMgr->GetBufferedPart( libId.GetLibItemName(), libId.GetLibNickname() );
766 
767  if( !part )
768  return;
769 
770  std::unique_ptr< LIB_PART> tmp = part->Flatten();
771  STRING_FORMATTER formatter;
772  SCH_SEXPR_PLUGIN::FormatPart( tmp.get(), formatter );
773 
774  wxLogNull doNotLog; // disable logging of failed clipboard actions
775 
776  auto clipboard = wxTheClipboard;
777  wxClipboardLocker clipboardLock( clipboard );
778 
779  if( !clipboardLock || !clipboard->IsOpened() )
780  return;
781 
782  auto data = new wxTextDataObject( wxString( formatter.GetString().c_str(), wxConvUTF8 ) );
783  clipboard->SetData( data );
784 
785  clipboard->Flush();
786 }
787 
788 
789 void SYMBOL_EDIT_FRAME::DuplicatePart( bool aFromClipboard )
790 {
791  int dummyUnit;
792  LIB_ID libId = m_treePane->GetLibTree()->GetSelectedLibId( &dummyUnit );
793  wxString lib = libId.GetLibNickname();
794 
795  if( !m_libMgr->LibraryExists( lib ) )
796  return;
797 
798  LIB_PART* srcPart = nullptr;
799  LIB_PART* newPart = nullptr;
800 
801  if( aFromClipboard )
802  {
803  wxLogNull doNotLog; // disable logging of failed clipboard actions
804 
805  auto clipboard = wxTheClipboard;
806  wxClipboardLocker clipboardLock( clipboard );
807 
808  if( !clipboardLock || ! clipboard->IsSupported( wxDF_TEXT ) )
809  return;
810 
811  wxTextDataObject data;
812  clipboard->GetData( data );
813  wxString partSource = data.GetText();
814 
815  STRING_LINE_READER reader( TO_UTF8( partSource ), "Clipboard" );
816 
817  try
818  {
819  newPart = SCH_SEXPR_PLUGIN::ParsePart( reader );
820  }
821  catch( IO_ERROR& e )
822  {
823  wxLogMessage( "Can not paste: %s", e.Problem() );
824  return;
825  }
826  }
827  else
828  {
829  srcPart = m_libMgr->GetBufferedPart( libId.GetLibItemName(), lib );
830 
831  wxCHECK( srcPart, /* void */ );
832 
833  newPart = new LIB_PART( *srcPart );
834 
835  // Derive from same parent.
836  if( srcPart->IsAlias() )
837  {
838  std::shared_ptr< LIB_PART > srcParent = srcPart->GetParent().lock();
839 
840  wxCHECK( srcParent, /* void */ );
841 
842  newPart->SetParent( srcParent.get() );
843  }
844  }
845 
846  if( !newPart )
847  return;
848 
849  ensureUniqueName( newPart, lib );
850  m_libMgr->UpdatePart( newPart, lib );
851 
852  LoadOneLibraryPartAux( newPart, lib, GetUnit(), GetConvert() );
853 
854  SyncLibraries( false );
855  m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, newPart->GetName() ) );
856 
857  delete newPart;
858 }
859 
860 
861 void SYMBOL_EDIT_FRAME::ensureUniqueName( LIB_PART* aPart, const wxString& aLibrary )
862 {
863  wxCHECK( aPart, /* void */ );
864 
865  int i = 1;
866  wxString newName = aPart->GetName();
867 
868  // Append a number to the name until the name is unique in the library.
869  while( m_libMgr->PartExists( newName, aLibrary ) )
870  newName.Printf( "%s_%d", aPart->GetName(), i++ );
871 
872  aPart->SetName( newName );
873 }
874 
875 
876 void SYMBOL_EDIT_FRAME::Revert( bool aConfirm )
877 {
878  LIB_ID libId = GetTargetLibId();
879  const wxString& libName = libId.GetLibNickname();
880 
881  // Empty if this is the library itself that is selected.
882  const wxString& partName = libId.GetLibItemName();
883 
884  wxString msg = wxString::Format( _( "Revert \"%s\" to last version saved?" ),
885  partName.IsEmpty() ? libName : partName );
886 
887  if( aConfirm && !ConfirmRevertDialog( this, msg ) )
888  return;
889 
890  bool reload_currentPart = false;
891  wxString curr_partName = partName;
892 
893  if( GetCurPart() )
894  {
895  // the library itself is reverted: the current part will be reloaded only if it is
896  // owned by this library
897  if( partName.IsEmpty() )
898  {
899  LIB_ID curr_libId = GetCurPart()->GetLibId();
900  reload_currentPart = libName == curr_libId.GetLibNickname();
901 
902  if( reload_currentPart )
903  curr_partName = curr_libId.GetLibItemName();
904  }
905  else
906  {
907  reload_currentPart = isCurrentPart( libId );
908  }
909  }
910 
911  int unit = m_unit;
912 
913  if( reload_currentPart )
914  emptyScreen();
915 
916  if( partName.IsEmpty() )
917  {
918  m_libMgr->RevertLibrary( libName );
919  }
920  else
921  {
922  libId = m_libMgr->RevertPart( libId.GetLibItemName(), libId.GetLibNickname() );
923 
924  m_treePane->GetLibTree()->SelectLibId( libId );
926  }
927 
928  if( reload_currentPart && m_libMgr->PartExists( curr_partName, libName ) )
929  LoadPart( curr_partName, libName, unit );
930 
931  m_treePane->Refresh();
932 }
933 
934 
936 {
937  wxCHECK_RET( m_libMgr, "Library manager object not created." );
938 
939  Revert( false );
940  m_libMgr->RevertAll();
941 }
942 
943 
944 void SYMBOL_EDIT_FRAME::LoadPart( const wxString& aAlias, const wxString& aLibrary, int aUnit )
945 {
946  LIB_PART* part = m_libMgr->GetBufferedPart( aAlias, aLibrary );
947 
948  if( !part )
949  {
950  wxString msg;
951 
952  msg.Printf( _( "Symbol name \"%s\" not found in library \"%s\"" ), aAlias, aLibrary );
953  DisplayError( this, msg );
954  return;
955  }
956 
957  // Optimize default edit options for this symbol
958  // Usually if units are locked, graphic items are specific to each unit
959  // and if units are interchangeable, graphic items are common to units
961  tools->SetDrawSpecificUnit( part->UnitsLocked() );
962 
963  LoadOneLibraryPartAux( part, aLibrary, aUnit, 0 );
964 }
965 
966 
967 bool SYMBOL_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
968 {
969  wxFileName fn;
970  wxString msg;
971  SAVE_AS_HELPER::SAH_TYPE type = SAVE_AS_HELPER::SAH_TYPE::UNDEFINED;
972  SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::SCH_FILE_T::SCH_KICAD;
973  PROJECT& prj = Prj();
974 
976 
977  if( !aNewFile && ( aLibrary.empty() || !prj.SchSymbolLibTable()->HasLibrary( aLibrary ) ) )
978  {
979  ShowInfoBarError( _( "No library specified." ) );
980  return false;
981  }
982 
983  if( aNewFile )
984  {
985  SEARCH_STACK* search = prj.SchSearchS();
986 
987  // Get a new name for the library
988  wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
989 
990  if( !default_path )
991  default_path = search->LastVisitedPath();
992 
993  fn.SetName( aLibrary );
994  fn.SetExt( KiCadSymbolLibFileExtension );
995 
996  wxString wildcards = KiCadSymbolLibFileWildcard();
997 
998  wxFileDialog dlg( this, wxString::Format( _( "Save Library \"%s\" As..." ), aLibrary ),
999  default_path, fn.GetFullName(), wildcards,
1000  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1001 
1002  dlg.SetExtraControlCreator( &SAVE_AS_HELPER::Create );
1003 
1004  if( dlg.ShowModal() == wxID_CANCEL )
1005  return false;
1006 
1007  fn = dlg.GetPath();
1008 
1009  prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
1010 
1011  if( fn.GetExt().IsEmpty() )
1012  fn.SetExt( KiCadSymbolLibFileExtension );
1013 
1014  const SAVE_AS_HELPER* sah = dynamic_cast<const SAVE_AS_HELPER*>( dlg.GetExtraControl() );
1015  wxCHECK( sah, false );
1016 
1017  type = sah->GetOption();
1018  }
1019  else
1020  {
1021  fn = prj.SchSymbolLibTable()->GetFullURI( aLibrary );
1022  fileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
1023  }
1024 
1025  // Verify the user has write privileges before attempting to save the library file.
1026  if( !aNewFile && m_libMgr->IsLibraryReadOnly( aLibrary ) )
1027  return false;
1028 
1029  ClearMsgPanel();
1030 
1031  // Copy .kicad_symb file to .bak.
1032  if( !backupFile( fn, "bak" ) )
1033  return false;
1034 
1035  if( !m_libMgr->SaveLibrary( aLibrary, fn.GetFullPath(), fileType ) )
1036  {
1037  msg.Printf( _( "Failed to save changes to symbol library file \"%s\"" ),
1038  fn.GetFullPath() );
1039  DisplayErrorMessage( this, _( "Error saving library" ), msg );
1040  return false;
1041  }
1042 
1043  if( !aNewFile )
1044  {
1045  m_libMgr->ClearLibraryModified( aLibrary );
1046  }
1047  else
1048  {
1049  bool resyncLibTree = false;
1050  wxString originalLibNickname = getTargetLib();
1051  wxString forceRefresh;
1052 
1053  switch( type )
1054  {
1055  case SAVE_AS_HELPER::SAH_TYPE::REPLACE_TABLE_ENTRY:
1056  resyncLibTree = replaceLibTableEntry( originalLibNickname, fn.GetFullPath() );
1057  forceRefresh = originalLibNickname;
1058  break;
1059 
1060  case SAVE_AS_HELPER::SAH_TYPE::ADD_GLOBAL_TABLE_ENTRY:
1061  resyncLibTree = addLibTableEntry( fn.GetFullPath() );
1062  break;
1063 
1064  case SAVE_AS_HELPER::SAH_TYPE::ADD_PROJECT_TABLE_ENTRY:
1065  resyncLibTree = addLibTableEntry( fn.GetFullPath(), PROJECT_LIB_TABLE );
1066  break;
1067 
1068  case SAVE_AS_HELPER::SAH_TYPE::NORMAL_SAVE_AS:
1069  default:
1070  break;
1071  }
1072 
1073  if( resyncLibTree )
1074  {
1075  FreezeSearchTree();
1076  SyncLibraries( true, forceRefresh );
1077  ThawSearchTree();
1078  }
1079  }
1080 
1081  ClearMsgPanel();
1082  msg.Printf( _( "Symbol library file \"%s\" saved" ), fn.GetFullPath() );
1084 
1085  return true;
1086 }
1087 
1088 
1089 bool SYMBOL_EDIT_FRAME::saveAllLibraries( bool aRequireConfirmation )
1090 {
1091  wxString msg, msg2;
1092  bool doSave = true;
1093  int dirtyCount = 0;
1094  bool applyToAll = false;
1095  bool retv = true;
1096 
1097  for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1098  {
1099  if( m_libMgr->IsLibraryModified( libNickname ) )
1100  dirtyCount++;
1101  }
1102 
1103  for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1104  {
1105  if( m_libMgr->IsLibraryModified( libNickname ) )
1106  {
1107  if( aRequireConfirmation && !applyToAll )
1108  {
1109  msg.Printf( _( "Save changes to \"%s\" before closing?" ), libNickname );
1110 
1111  switch( UnsavedChangesDialog( this, msg, dirtyCount > 1 ? &applyToAll : nullptr ) )
1112  {
1113  case wxID_YES: doSave = true; break;
1114  case wxID_NO: doSave = false; break;
1115  default:
1116  case wxID_CANCEL: return false;
1117  }
1118  }
1119 
1120  if( doSave )
1121  {
1122  // If saving under existing name fails then do a Save As..., and if that
1123  // fails then cancel close action.
1124 
1125  if( !m_libMgr->IsLibraryReadOnly( libNickname ) )
1126  {
1127  if( saveLibrary( libNickname, false ) )
1128  continue;
1129  }
1130  else
1131  {
1132  msg.Printf( _( "Symbol library '%s' is not writeable." ), libNickname );
1133  msg2 = _( "You must save to a different location." );
1134 
1135  if( dirtyCount == 1 )
1136  {
1137  if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) != wxID_OK )
1138  {
1139  retv = false;
1140  continue;
1141  }
1142  }
1143  else
1144  {
1145  m_infoBar->Dismiss();
1146  m_infoBar->ShowMessageFor( msg + wxS( " " ) + msg2,
1147  2000, wxICON_EXCLAMATION );
1148 
1149  while( m_infoBar->IsShown() )
1150  wxSafeYield();
1151 
1152  retv = false;
1153  continue;
1154  }
1155  }
1156 
1157  if( !saveLibrary( libNickname, true ) )
1158  retv = false;
1159  }
1160  }
1161  }
1162 
1163  return retv;
1164 }
1165 
1166 
1168 {
1170 
1171  if( !m_my_part )
1172  return;
1173 
1174  wxString msg = m_my_part->GetName();
1175 
1176  AppendMsgPanel( _( "Name" ), msg, 8 );
1177 
1178  if( m_my_part->IsAlias() )
1179  {
1180  PART_SPTR parent = m_my_part->GetParent().lock();
1181 
1182  msg = parent ? parent->GetName() : _( "Undefined!" );
1183  AppendMsgPanel( _( "Parent" ), msg, 8 );
1184  }
1185 
1186  static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
1187  msg = UnitLetter[m_unit];
1188 
1189  AppendMsgPanel( _( "Unit" ), msg, 8 );
1190 
1191  if( m_convert > 1 )
1192  msg = _( "Convert" );
1193  else
1194  msg = _( "Normal" );
1195 
1196  AppendMsgPanel( _( "Body" ), msg, 8 );
1197 
1198  if( m_my_part->IsPower() )
1199  msg = _( "Power Symbol" );
1200  else
1201  msg = _( "Symbol" );
1202 
1203  AppendMsgPanel( _( "Type" ), msg, 8 );
1204  AppendMsgPanel( _( "Description" ), m_my_part->GetDescription(), 8 );
1205  AppendMsgPanel( _( "Keywords" ), m_my_part->GetKeyWords() );
1206  AppendMsgPanel( _( "Datasheet" ), m_my_part->GetDatasheetField().GetText() );
1207 }
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current symbol.
static SCH_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath)
Return a plugin type given a symbol library using the file extension of aLibPath.
Definition: sch_io_mgr.cpp:169
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:253
void ShowMessageFor(const wxString &aMessage, int aTime, int aFlags=wxICON_INFORMATION)
Show the infobar with the provided message and icon for a specific period of time.
Definition: infobar.cpp:113
bool ClearPartModified(const wxString &aAlias, const wxString &aLibrary) const
Clear the modified flag for a part.
bool UpdatePartAfterRename(LIB_PART *aPart, const wxString &oldAlias, const wxString &aLibrary)
Update the part buffer with a new version of the part when the name has changed.
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
Definition: confirm.cpp:208
int m_convert
Flag if the symbol being edited was loaded directly from a schematic.
void Revert(bool aConfirm=true)
Revert unsaved changes in a part, restoring to the last saved state.
const UTF8 & GetLibItemName() const
Definition: lib_id.h:106
LIB_PART * GetAlias(const wxString &aAlias, const wxString &aLibrary) const
Return either an alias of a working LIB_PART copy, or alias of the original part if there is no worki...
bool ConfirmRevertDialog(wxWindow *parent, const wxString &aMessage)
Display a confirmation dialog for a revert action.
Definition: confirm.cpp:197
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:56
void SetPower()
Definition: lib_symbol.cpp:413
wxString GetTextSelection(int aColumn=0)
Return the selected text from aColumn in the wxListCtrl in the dialog.
LIB_ID GetLibId() const override
Definition: lib_symbol.h:131
Container for project specific data.
Definition: project.h:62
void SelectActiveLibrary(const wxString &aLibrary=wxEmptyString)
Set the current active library to aLibrary.
LIB_FIELD & GetDatasheetField()
Return reference to the datasheet field.
Definition: lib_symbol.cpp:990
SCH_SCREEN * m_dummyScreen
< Helper screen used when no part is loaded
int GetPinNameOffset()
Definition: lib_symbol.h:554
void GetRootSymbolNames(const wxString &aLibName, wxArrayString &aRootSymbolNames)
bool RemovePart(const wxString &aName, const wxString &aLibrary)
Remove the part from the part buffer.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:266
wxString GetName() const override
Definition: lib_symbol.h:129
static LIB_PART * ParsePart(LINE_READER &aReader, int aVersion=SEXPR_SCHEMATIC_FILE_VERSION)
bool LoadOneLibraryPartAux(LIB_PART *aLibEntry, const wxString &aLibrary, int aUnit, int aConvert)
Create a copy of aLibEntry into memory.
This file is part of the common library.
bool ClearLibraryModified(const wxString &aLibrary) const
Clear the modified flag for all parts in a library.
bool backupFile(const wxFileName &aOriginalFile, const wxString &aBackupExt)
Return currently edited part.
void SetOKLabel(const wxString &aLabel)
void SetScreen(BASE_SCREEN *aScreen) override
void SetShowDeMorgan(bool show)
bool PartExists(const wxString &aAlias, const wxString &aLibrary) const
Return true if part with a specific alias exists in library (either original one or buffered).
bool LoadSymbolAndSelectLib(const LIB_ID &aLibId, int aUnit, int aConvert)
Select the currently active library and loads the symbol from aLibId.
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 SetUnitCount(int aCount, bool aDuplicateDrawItems=true)
Set the units per part count.
bool SaveLibrary(const wxString &aLibrary, const wxString &aFileName, SCH_IO_MGR::SCH_FILE_T aFileType=SCH_IO_MGR::SCH_FILE_T::SCH_LEGACY)
Save library to a file, including unsaved changes.
LIB_PART * getTargetPart() const
Return either the library selected in the symbol tree, if context menu is active or the library that ...
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
bool m_SyncPinEdit
Set to true to synchronize pins at the same position when editing symbols with multiple units or mult...
SYMBOL_TREE_PANE * m_treePane
static TOOL_ACTION zoomFitScreen
Definition: actions.h:99
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
void Save()
Save the selected part or library.
static wxWindow * Create(wxWindow *aParent)
Create a new panel to add to a wxFileDialog object.
bool saveCurrentPart()
Store the currently modified part in the library manager buffer.
wxRadioButton * m_addGlobalTableEntry
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:345
void SaveAll()
Save all modified parts and libraries.
A dialog which shows:
Schematic editor (Eeschema) main window.
std::shared_ptr< LIB_PART > PART_SPTR
shared pointer to LIB_PART
Definition: lib_symbol.h:42
Look for files in a number of paths.
Definition: search_stack.h:41
static void FormatPart(LIB_PART *aPart, OUTPUTFORMATTER &aFormatter)
wxString GetKeyWords() const
Definition: lib_symbol.h:151
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
void SetIncludeInBom(bool aIncludeInBom)
Set or clear the include in schematic bill of materials flag.
Definition: lib_symbol.h:577
wxString m_reference
The reference of the symbol.
bool UpdatePart(LIB_PART *aPart, const wxString &aLibrary)
Update the part buffer with a new version of the part.
wxString GetCurLib() const
The nickname of the current library being edited and empty string if none.
bool RevertLibrary(const wxString &aLibrary)
Revert unsaved changes for a particular library.
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:45
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:98
bool IsSymbolFromSchematic() const
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:165
name of datasheet
Field Value of part, i.e. "3.3K".
void UpdateAfterSymbolProperties(wxString *aOldName=nullptr)
void LoadPart(const wxString &aLibrary, const wxString &aPart, int Unit)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
bool FlushPart(const wxString &aAlias, const wxString &aLibrary)
Save part changes to the library copy used by the schematic editor.
LIB_PART * GetBufferedPart(const wxString &aAlias, const wxString &aLibrary)
Return the part copy from the buffer.
Subclass of DIALOG_LIB_NEW_COMPONENT, which is generated by wxFormBuilder.
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: infobar.cpp:166
void DisplaySymbolDatasheet()
Display the documentation of the selected symbol.
void SetConversion(bool aSetConvert, bool aDuplicatePins=true)
Set or clear the alternate body style (DeMorgan) for the part.
LIB_FIELD & GetReferenceField()
Return reference to the reference designator field.
Definition: lib_symbol.cpp:974
void UpdateSymbolFromEditor(const LIB_PART &aSymbol)
Update the LIB_PART of the currently selected symbol.
void updateTitle()
Update the main window title bar with the current library name and read only status of the library.
bool RevertAll()
Revert all pending changes.
void SaveSymbolAs()
Save the currently selected symbol to a new name and/or location.
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:121
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:29
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
const wxString GetDescription(const wxString &aNickname)
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
bool IsLibraryReadOnly(const wxString &aLibrary) const
Return true if the library is stored in a read-only file.
void DuplicatePart(bool aFromClipboard)
Insert a duplicate part.
wxString getTargetLib() const
LIB_ID GetSelectedLibId(int *aUnit=nullptr) const
For multi-unit components, if the user selects the component itself rather than picking an individual...
Definition: lib_tree.cpp:148
void SetParent(LIB_PART *aParent=nullptr)
Definition: lib_symbol.cpp:318
PART_REF & GetParent()
Definition: lib_symbol.h:120
Define a library symbol object.
Definition: lib_symbol.h:93
void ensureUniqueName(LIB_PART *aPart, const wxString &aLibrary)
Definition of file extensions used in Kicad.
Helper dialog and control classes.
void ReCreateHToolbar() override
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:92
wxString SelectLibraryFromList()
Display a list of loaded libraries in the symbol library and allows the user to select a library.
bool replaceLibTableEntry(const wxString &aLibNickname, const wxString &aLibFile)
Replace the file path of the symbol library table entry aLibNickname with aLibFile.
wxString KiCadSymbolLibFileWildcard()
wxString GetName(void) const override
wxString GetDescription() override
Definition: lib_symbol.h:138
const std::string & GetString()
Definition: richio.h:435
void ClearMsgPanel() override
Clear all messages from the message panel.
void SetCurPart(LIB_PART *aPart, bool aUpdateZoom)
Take ownership of aPart and notes that it is the one currently being edited.
bool HasDerivedSymbols(const wxString &aSymbolName, const wxString &aLibraryName)
Check if symbol aSymbolName in library aLibraryName is a root symbol that has derived symbols.
std::unique_ptr< LIB_PART > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:327
FormatType fileType(const char *aFileName)
Definition: loadmodel.cpp:271
int UnsavedChangesDialog(wxWindow *parent, wxString aMessage, bool *aApplyToAll)
A specialized version of HandleUnsavedChanges which handles an apply-to-all checkbox.
Definition: confirm.cpp:155
void RefreshLibTree()
Refreshes the tree (mainly to update highlighting and asterisking)
Definition: lib_tree.cpp:218
virtual void ClearMsgPanel()
Clear all messages from the message panel.
void ReCreateMenuBar() override
Recreates the menu bar.
LIB_PART * GetCurPart()
Return the current part being edited or NULL if none selected.
bool addLibTableEntry(const wxString &aLibFile, TABLE_SCOPE aScope=GLOBAL_LIB_TABLE)
Add aLibFile to the symbol library table defined by aScope.
bool saveLibrary(const wxString &aLibrary, bool aNewFile)
Save the changes to the current library.
Helper control to inquire user what to do on library save as operation.
virtual void SetRString(RSTRING_T aStringId, const wxString &aString)
Store a "retained string", which is any session and project specific string identified in enum RSTRIN...
Field Name Module PCB, i.e. "16DIP300".
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
wxArrayString GetLibraryNames() const
Return the array of library names.
bool LoadSymbolFromCurrentLib(const wxString &aAliasName, int aUnit=0, int aConvert=0)
Load a symbol from the current active library, optionally setting the selected unit and convert.
int OKOrCancelDialog(wxWindow *aParent, const wxString &aWarning, const wxString &aMessage, wxString aDetailedMessage, wxString aOKLabel, wxString aCancelLabel, bool *aApplyToAll)
Display a warning dialog with aMessage and returns the user response.
Definition: confirm.cpp:221
LIB_ID GetTargetLibId() const
virtual const wxString & GetRString(RSTRING_T aStringId)
Return a "retained string", which is any session and project specific string identified in enum RSTRI...
LIB_ID RevertPart(const wxString &aAlias, const wxString &aLibrary)
Revert unsaved changes for a particular part.
bool IsLibraryModified(const wxString &aLibrary) const
Return true if library has unsaved modifications.
bool LibraryExists(const wxString &aLibrary, bool aCheckEnabled=false) const
Return true if library exists.
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:157
bool IsPower() const
Definition: lib_symbol.cpp:404
see class PGM_BASE
const char * name
Definition: DXF_plotter.cpp:59
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: lib_symbol.h:569
bool saveAllLibraries(bool aRequireConfirmation)
Save the current part.
WX_INFOBAR * m_infoBar
#define _(s)
Definition: 3d_actions.cpp:33
wxRadioButton * m_simpleSaveAs
const wxString LastVisitedPath(const wxString &aSubPathToSearch=wxEmptyString)
A quirky function inherited from old code that seems to serve particular needs in the UI.
void CreateNewPart()
Create a new part in the selected library.
bool IsAlias() const
Definition: lib_symbol.h:168
wxString wx_str() const
Definition: utf8.cpp:51
void ClrModify()
Definition: base_screen.h:60
static bool empty(const wxTextEntryBase *aCtrl)
bool isCurrentPart(const LIB_ID &aLibId) const
Rename LIB_PART aliases to avoid conflicts before adding a symbol to a library.
wxRadioButton * m_addProjectTableEntry
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
wxRadioButton * m_replaceTableEntry
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:307
WX_INFOBAR * GetInfoBar()
Implementing DIALOG_LIB_NEW_COMPONENT.
SYMBOL_LIBRARY_MANAGER * m_libMgr
SCH_SCREEN * GetScreen(const wxString &aAlias, const wxString &aLibrary)
Return the screen used to edit a specific part.
void SetIncludeOnBoard(bool aIncludeOnBoard)
Set or clear include in board netlist flag.
Definition: lib_symbol.h:585
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
Definition for part library class.
void SaveLibraryAs()
Save the currently selected library to a new file.
void emptyScreen()
Return either the part selected in the symbol tree, if context menu is active or the currently modifi...
LIB_TREE * GetLibTree() const
void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: lib_symbol.h:561
LIB_FIELD * GetField(int aId) const
Return pointer to the requested field.
Definition: lib_symbol.cpp:928
void SetPinNameOffset(int aOffset)
Set the offset in mils of the pin name text from the pin symbol.
Definition: lib_symbol.h:553
void SyncLibraries(bool aShowProgress, const wxString &aForceRefresh=wxEmptyString)
Synchronize the library manager to the symbol library table, and then the symbol tree to the library ...
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:237
Field Reference of part, i.e. "IC21".
Implement an OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:411
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
wxString SetCurLib(const wxString &aLibNickname)
Set the current library nickname and returns the old library nickname.
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:297
virtual void ClearUndoRedoList()
Clear the undo and redo list using ClearUndoORRedoList()
SAH_TYPE GetOption() const
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
bool UnitsLocked() const
Check whether part units are interchangeable.
Definition: lib_symbol.h:237
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
Definition: lib_id.h:116
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.
SAVE_AS_HELPER(wxWindow *aParent)
SYMBOL_EDITOR_DRAWING_TOOLS.
void LockUnits(bool aLockUnits)
Set interchangeable the property for part units.
Definition: lib_symbol.h:231
void SelectLibId(const LIB_ID &aLibId)
Select an item in the tree widget.
Definition: lib_tree.cpp:177
const std::string KiCadSymbolLibFileExtension
void SetNormal()
Definition: lib_symbol.cpp:431
void AppendMsgPanel(const wxString &aTextUpper, const wxString &aTextLower, int aPadding=6)
Append a message to the message panel.
void SetListLabel(const wxString &aLabel)
bool IsPartModified(const wxString &aAlias, const wxString &aLibrary) const
Return true if part has unsaved modifications.