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