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 <[email protected]>
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 <eda_list_dialog.h>
43 #include <wx/clipbrd.h>
44 #include <wx/filedlg.h>
45 #include <wx/log.h>
46 #include <string_utils.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 += UnescapeString( GetCurSymbol()->GetLibId().Format() );
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. Save changes?" ),
263  [&]() -> bool
264  {
265  return saveCurrentSymbol();
266  } ) )
267  {
268  return false;
269  }
270  }
271 
273 
274  if( LoadSymbolFromCurrentLib( aLibId.GetLibItemName(), aUnit, aConvert ) )
275  {
276  m_treePane->GetLibTree()->SelectLibId( aLibId );
277  m_treePane->GetLibTree()->ExpandLibId( aLibId );
278 
279  m_centerItemOnIdle = aLibId;
280  Bind( wxEVT_IDLE, &SYMBOL_EDIT_FRAME::centerItemIdleHandler, this );
281 
282  return true;
283  }
284 
285  return false;
286 }
287 
288 
289 void SYMBOL_EDIT_FRAME::centerItemIdleHandler( wxIdleEvent& aEvent )
290 {
292  Unbind( wxEVT_IDLE, &SYMBOL_EDIT_FRAME::centerItemIdleHandler, this );
293 }
294 
295 
296 bool SYMBOL_EDIT_FRAME::LoadSymbolFromCurrentLib( const wxString& aAliasName, int aUnit,
297  int aConvert )
298 {
299  LIB_SYMBOL* alias = nullptr;
300 
301  try
302  {
303  alias = Prj().SchSymbolLibTable()->LoadSymbol( GetCurLib(), aAliasName );
304  }
305  catch( const IO_ERROR& ioe )
306  {
307  wxString msg;
308 
309  msg.Printf( _( "Error loading symbol %s from library '%s'." ),
310  aAliasName,
311  GetCurLib() );
312  DisplayErrorMessage( this, msg, ioe.What() );
313  return false;
314  }
315 
316  if( !alias || !LoadOneLibrarySymbolAux( alias, GetCurLib(), aUnit, aConvert ) )
317  return false;
318 
319  // Enable synchronized pin edit mode for symbols with interchangeable units
321 
324  SetShowDeMorgan( GetCurSymbol()->Flatten()->HasConversion() );
325 
326  if( aUnit > 0 )
328 
329  return true;
330 }
331 
332 
333 bool SYMBOL_EDIT_FRAME::LoadOneLibrarySymbolAux( LIB_SYMBOL* aEntry, const wxString& aLibrary,
334  int aUnit, int aConvert )
335 {
336  wxString msg, rootName;
337  bool rebuildMenuAndToolbar = false;
338 
339  if( !aEntry || aLibrary.empty() )
340  return false;
341 
342  if( aEntry->GetName().IsEmpty() )
343  {
344  wxLogWarning( "Symbol in library '%s' has empty name field.", aLibrary );
345  return false;
346  }
347 
349 
350  // Symbols from the schematic are edited in place and not managed by the library manager.
351  if( IsSymbolFromSchematic() )
352  {
353  delete m_symbol;
354  m_symbol = nullptr;
355 
356  SCH_SCREEN* screen = GetScreen();
357  delete screen;
359  m_isSymbolFromSchematic = false;
360  rebuildMenuAndToolbar = true;
361  }
362 
363  LIB_SYMBOL* lib_symbol = m_libMgr->GetBufferedSymbol( aEntry->GetName(), aLibrary );
364  wxCHECK( lib_symbol, false );
365 
366  m_unit = aUnit > 0 ? aUnit : 1;
367  m_convert = aConvert > 0 ? aConvert : 1;
368 
369  // The buffered screen for the symbol
370  SCH_SCREEN* symbol_screen = m_libMgr->GetScreen( lib_symbol->GetName(), aLibrary );
371 
372  SetScreen( symbol_screen );
373  SetCurSymbol( new LIB_SYMBOL( *lib_symbol ), true );
374  SetCurLib( aLibrary );
375 
376  if( rebuildMenuAndToolbar )
377  {
378  ReCreateMenuBar();
380  GetInfoBar()->Dismiss();
381  }
382 
383  updateTitle();
385  SetShowDeMorgan( GetCurSymbol()->HasConversion() );
386 
387  // Display the document information based on the entry selected just in
388  // case the entry is an alias.
389  UpdateMsgPanel();
390  Refresh();
391 
392  return true;
393 }
394 
395 
397 {
398  saveAllLibraries( false );
400 }
401 
402 
404 {
406 
407  wxArrayString rootSymbols;
408  wxString lib = getTargetLib();
409 
410  if( !m_libMgr->LibraryExists( lib ) )
411  {
412  lib = SelectLibraryFromList();
413 
414  if( !m_libMgr->LibraryExists( lib ) )
415  return;
416  }
417 
418  m_libMgr->GetRootSymbolNames( lib, rootSymbols );
419 
420  rootSymbols.Sort();
421 
422  DIALOG_LIB_NEW_SYMBOL dlg( this, &rootSymbols );
423  dlg.SetMinSize( dlg.GetSize() );
424 
425  if( dlg.ShowModal() == wxID_CANCEL )
426  return;
427 
428  if( dlg.GetName().IsEmpty() )
429  {
430  wxMessageBox( _( "This new symbol has no name and cannot be created." ) );
431  return;
432  }
433 
434  wxString name = dlg.GetName();
435 
436  // Currently, symbol names cannot include a space, that breaks libraries:
437  name.Replace( " ", "_" );
438 
439  // Test if there is a symbol with this name already.
440  if( !lib.empty() && m_libMgr->SymbolExists( name, lib ) )
441  {
442  wxString msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'." ),
443  name,
444  lib );
445 
446  KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
447  errorDlg.SetOKLabel( _( "Overwrite" ) );
448  errorDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
449 
450  if( errorDlg.ShowModal() == wxID_CANCEL )
451  return;
452  }
453 
454  LIB_SYMBOL new_symbol( name ); // do not create symbol on the heap, it will be buffered soon
455 
456  wxString parentSymbolName = dlg.GetParentSymbolName();
457 
458  if( parentSymbolName.IsEmpty() )
459  {
460  new_symbol.GetReferenceField().SetText( dlg.GetReference() );
461  new_symbol.SetUnitCount( dlg.GetUnitCount() );
462 
463  // Initialize new_symbol.m_TextInside member:
464  // if 0, pin text is outside the body (on the pin)
465  // if > 0, pin text is inside the body
466  if( dlg.GetPinNameInside() )
467  {
468  new_symbol.SetPinNameOffset( dlg.GetPinTextPosition() );
469 
470  if( new_symbol.GetPinNameOffset() == 0 )
471  new_symbol.SetPinNameOffset( 1 );
472  }
473  else
474  {
475  new_symbol.SetPinNameOffset( 0 );
476  }
477 
478  ( dlg.GetPowerSymbol() ) ? new_symbol.SetPower() : new_symbol.SetNormal();
479  new_symbol.SetShowPinNumbers( dlg.GetShowPinNumber() );
480  new_symbol.SetShowPinNames( dlg.GetShowPinName() );
481  new_symbol.LockUnits( dlg.GetLockItems() );
482  new_symbol.SetIncludeInBom( dlg.GetIncludeInBom() );
483  new_symbol.SetIncludeOnBoard( dlg.GetIncludeOnBoard() );
484 
485  if( dlg.GetUnitCount() < 2 )
486  new_symbol.LockUnits( false );
487 
488  new_symbol.SetConversion( dlg.GetAlternateBodyStyle() );
489 
490  // must be called after loadSymbol, that calls SetShowDeMorgan, but
491  // because the symbol is empty,it looks like it has no alternate body
493  }
494  else
495  {
496  LIB_SYMBOL* parent = m_libMgr->GetAlias( parentSymbolName, lib );
497  wxCHECK( parent, /* void */ );
498  new_symbol.SetParent( parent );
499 
500  // Inherit the parent mandatory field attributes.
501  for( int id = 0; id < MANDATORY_FIELDS; ++id )
502  {
503  LIB_FIELD* field = new_symbol.GetFieldById( id );
504 
505  // the MANDATORY_FIELDS are exactly that in RAM.
506  wxCHECK( field, /* void */ );
507 
508  LIB_FIELD* parentField = parent->GetFieldById( id );
509 
510  wxCHECK( parentField, /* void */ );
511 
512  *field = *parentField;
513 
514  switch( id )
515  {
516  case REFERENCE_FIELD:
517  // parent's reference already copied
518  break;
519 
520  case VALUE_FIELD:
521  field->SetText( name );
522  break;
523 
524  case FOOTPRINT_FIELD:
525  case DATASHEET_FIELD:
526  // - footprint might be the same as parent, but might not
527  // - datasheet is most likely different
528  // - probably best to play it safe and copy neither
529  field->SetText( wxEmptyString );
530  break;
531  }
532 
533  field->SetParent( &new_symbol );
534  }
535  }
536 
537  m_libMgr->UpdateSymbol( &new_symbol, lib );
538  SyncLibraries( false );
539  LoadSymbol( name, lib, 1 );
540 }
541 
542 
544 {
545  if( getTargetSymbol() == m_symbol )
546  {
547  if( IsSymbolFromSchematic() )
548  {
549  SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
550 
551  if( !schframe ) // happens when the schematic editor is not active (or closed)
552  {
553  DisplayErrorMessage( this, _( "No schematic currently open." ) );
554  }
555  else
556  {
557  schframe->SaveSymbolToSchematic( *m_symbol );
558  GetScreen()->SetContentModified( false );
559  }
560  }
561  else
562  {
564  }
565  }
566  else if( !GetTargetLibId().GetLibNickname().empty() )
567  {
568  LIB_ID libId = GetTargetLibId();
569  const wxString& libName = libId.GetLibNickname();
570 
571  if( m_libMgr->IsLibraryReadOnly( libName ) )
572  {
573  wxString msg = wxString::Format( _( "Symbol library '%s' is not writeable." ),
574  libName );
575  wxString msg2 = _( "You must save to a different location." );
576 
577  if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) == wxID_OK )
578  saveLibrary( libName, true );
579  }
580  else
581  {
582  saveLibrary( libName, false );
583  }
584  }
585 
587  updateTitle();
588 }
589 
590 
592 {
593  wxCHECK( !GetTargetLibId().GetLibNickname().empty(), /* void */ );
594 
595  const wxString& libName = GetTargetLibId().GetLibNickname();
596 
597  saveLibrary( libName, true );
599 }
600 
601 
603 {
604  wxCHECK( GetTargetLibId().IsValid(), /* void */ );
605 
606  saveSymbolAs();
607 
609 }
610 
611 
613 {
614  LIB_SYMBOL* symbol = getTargetSymbol();
615 
616  if( symbol )
617  {
618  LIB_ID old_lib_id = symbol->GetLibId();
619  wxString old_name = old_lib_id.GetLibItemName();
620  wxString old_lib = old_lib_id.GetLibNickname();
621 
622  SYMBOL_LIB_TABLE* tbl = Prj().SchSymbolLibTable();
623  wxArrayString headers;
624  std::vector< wxArrayString > itemsToDisplay;
625  std::vector< wxString > libNicknames = tbl->GetLogicalLibs();
626 
627  headers.Add( _( "Nickname" ) );
628  headers.Add( _( "Description" ) );
629 
630  for( const wxString& name : libNicknames )
631  {
632  wxArrayString item;
633  item.Add( name );
634  item.Add( tbl->GetDescription( name ) );
635  itemsToDisplay.push_back( item );
636  }
637 
638  EDA_LIST_DIALOG dlg( this, _( "Save Symbol As" ), headers, itemsToDisplay, old_lib );
639  dlg.SetListLabel( _( "Save in library:" ) );
640  dlg.SetOKLabel( _( "Save" ) );
641 
642  wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
643 
644  wxStaticText* label = new wxStaticText( &dlg, wxID_ANY, _( "Name:" ),
645  wxDefaultPosition, wxDefaultSize, 0 );
646  bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
647 
648  wxTextCtrl* nameTextCtrl = new wxTextCtrl( &dlg, wxID_ANY, old_name,
649  wxDefaultPosition, wxDefaultSize, 0 );
650  bNameSizer->Add( nameTextCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
651 
652  wxSizer* mainSizer = dlg.GetSizer();
653  mainSizer->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
654 
655  // Move nameTextCtrl to the head of the tab-order
656  if( dlg.GetChildren().DeleteObject( nameTextCtrl ) )
657  dlg.GetChildren().Insert( nameTextCtrl );
658 
659  dlg.SetInitialFocus( nameTextCtrl );
660 
661  dlg.Layout();
662  mainSizer->Fit( &dlg );
663 
664  if( dlg.ShowModal() != wxID_OK )
665  return; // canceled by user
666 
667  wxString new_lib = dlg.GetTextSelection();
668 
669  if( new_lib.IsEmpty() )
670  {
671  DisplayError( this, _( "No library specified. Symbol could not be saved." ) );
672  return;
673  }
674 
675  // @todo Either check the selecteced library to see if the parent symbol name is in
676  // the new library and/or copy the parent symbol as well. This is the lazy
677  // solution to ensure derived symbols do not get orphaned.
678  if( symbol->IsAlias() && new_lib != old_lib )
679  {
680  DisplayError( this, _( "Derived symbols must be saved in the same library as their "
681  "parent symbol." ) );
682  return;
683  }
684 
685  wxString new_name = nameTextCtrl->GetValue();
686  new_name.Trim( true );
687  new_name.Trim( false );
688  new_name.Replace( " ", "_" );
689 
690  if( new_name.IsEmpty() )
691  {
692  // This is effectively a cancel. No need to nag the user about it.
693  return;
694  }
695 
696  // Test if there is a symbol with this name already.
697  if( m_libMgr->SymbolExists( new_name, new_lib ) )
698  {
699  wxString msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'" ),
700  new_name,
701  new_lib );
702 
703  KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
704  errorDlg.SetOKLabel( _( "Overwrite" ) );
705  errorDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
706 
707  if( errorDlg.ShowModal() == wxID_CANCEL )
708  return;
709  }
710 
711  LIB_SYMBOL new_symbol( *symbol );
712  new_symbol.SetName( new_name );
713 
714  m_libMgr->UpdateSymbol( &new_symbol, new_lib );
715  SyncLibraries( false );
716  m_treePane->GetLibTree()->SelectLibId( LIB_ID( new_lib, new_symbol.GetName() ) );
717  LoadSymbol( new_name, new_lib, m_unit );
718  }
719 }
720 
721 
723 {
724  wxCHECK( m_symbol, /* void */ );
725 
726  wxString lib = GetCurLib();
727 
728  if( !lib.IsEmpty() && aOldName && *aOldName != m_symbol->GetName() )
729  {
730  // Test the current library for name conflicts
731  if( m_libMgr->SymbolExists( m_symbol->GetName(), lib ) )
732  {
733  wxString msg = wxString::Format( _( "Symbol name '%s' already in use." ),
735 
736  DisplayErrorMessage( this, msg );
737  m_symbol->SetName( *aOldName );
738  }
739  else
740  {
741  m_libMgr->UpdateSymbolAfterRename( m_symbol, *aOldName, lib );
742  }
743 
744  // Reselect the renamed symbol
746  }
747 
749  SetShowDeMorgan( GetCurSymbol()->Flatten()->HasConversion() );
750  updateTitle();
751  UpdateMsgPanel();
752 
753  RebuildView();
754  OnModify();
755 }
756 
757 
759 {
760  LIB_ID libId = GetTargetLibId();
761 
762  if( m_libMgr->IsSymbolModified( libId.GetLibItemName(), libId.GetLibNickname() )
763  && !IsOK( this, wxString::Format( _( "The symbol '%s' has been modified.\n"
764  "Do you want to remove it from the library?" ),
765  libId.GetUniStringLibItemName() ) ) )
766  {
767  return;
768  }
769 
770  if( m_libMgr->HasDerivedSymbols( libId.GetLibItemName(), libId.GetLibNickname() ) )
771  {
772  wxString msg;
773 
774  msg.Printf( _( "The symbol %s is used to derive other symbols.\n"
775  "Deleting this symbol will delete all of the symbols derived from it.\n\n"
776  "Do you wish to delete this symbol and all of its derivatives?" ),
777  libId.GetLibItemName().wx_str() );
778 
779  wxMessageDialog::ButtonLabel yesButtonLabel( _( "Delete Symbol" ) );
780  wxMessageDialog::ButtonLabel noButtonLabel( _( "Keep Symbol" ) );
781 
782  wxMessageDialog dlg( this, msg, _( "Warning" ),
783  wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTER );
784  dlg.SetYesNoLabels( yesButtonLabel, noButtonLabel );
785 
786  if( dlg.ShowModal() == wxID_NO )
787  return;
788  }
789 
790  if( isCurrentSymbol( libId ) )
791  emptyScreen();
792 
793  m_libMgr->RemoveSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
794 
796 }
797 
798 
800 {
801  int dummyUnit;
802  LIB_ID libId = m_treePane->GetLibTree()->GetSelectedLibId( &dummyUnit );
804  libId.GetLibNickname() );
805 
806  if( !symbol )
807  return;
808 
809  std::unique_ptr< LIB_SYMBOL> tmp = symbol->Flatten();
810  STRING_FORMATTER formatter;
811  SCH_SEXPR_PLUGIN::FormatLibSymbol( tmp.get(), formatter );
812 
813  wxLogNull doNotLog; // disable logging of failed clipboard actions
814 
815  auto clipboard = wxTheClipboard;
816  wxClipboardLocker clipboardLock( clipboard );
817 
818  if( !clipboardLock || !clipboard->IsOpened() )
819  return;
820 
821  auto data = new wxTextDataObject( wxString( formatter.GetString().c_str(), wxConvUTF8 ) );
822  clipboard->SetData( data );
823 
824  clipboard->Flush();
825 }
826 
827 
828 void SYMBOL_EDIT_FRAME::DuplicateSymbol( bool aFromClipboard )
829 {
830  int dummyUnit;
831  LIB_ID libId = m_treePane->GetLibTree()->GetSelectedLibId( &dummyUnit );
832  wxString lib = libId.GetLibNickname();
833 
834  if( !m_libMgr->LibraryExists( lib ) )
835  return;
836 
837  LIB_SYMBOL* srcSymbol = nullptr;
838  LIB_SYMBOL* newSymbol = nullptr;
839 
840  if( aFromClipboard )
841  {
842  wxLogNull doNotLog; // disable logging of failed clipboard actions
843 
844  auto clipboard = wxTheClipboard;
845  wxClipboardLocker clipboardLock( clipboard );
846 
847  if( !clipboardLock || ! clipboard->IsSupported( wxDF_TEXT ) )
848  return;
849 
850  wxTextDataObject data;
851  clipboard->GetData( data );
852  wxString symbolSource = data.GetText();
853 
854  STRING_LINE_READER reader( TO_UTF8( symbolSource ), "Clipboard" );
855 
856  try
857  {
858  newSymbol = SCH_SEXPR_PLUGIN::ParseLibSymbol( reader );
859  }
860  catch( IO_ERROR& e )
861  {
862  wxLogMessage( "Can not paste: %s", e.Problem() );
863  return;
864  }
865  }
866  else
867  {
868  srcSymbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(), lib );
869 
870  wxCHECK( srcSymbol, /* void */ );
871 
872  newSymbol = new LIB_SYMBOL( *srcSymbol );
873 
874  // Derive from same parent.
875  if( srcSymbol->IsAlias() )
876  {
877  std::shared_ptr< LIB_SYMBOL > srcParent = srcSymbol->GetParent().lock();
878 
879  wxCHECK( srcParent, /* void */ );
880 
881  newSymbol->SetParent( srcParent.get() );
882  }
883  }
884 
885  if( !newSymbol )
886  return;
887 
888  ensureUniqueName( newSymbol, lib );
889  m_libMgr->UpdateSymbol( newSymbol, lib );
890 
891  LoadOneLibrarySymbolAux( newSymbol, lib, GetUnit(), GetConvert() );
892 
893  SyncLibraries( false );
894  m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, newSymbol->GetName() ) );
895 
896  delete newSymbol;
897 }
898 
899 
900 void SYMBOL_EDIT_FRAME::ensureUniqueName( LIB_SYMBOL* aSymbol, const wxString& aLibrary )
901 {
902  wxCHECK( aSymbol, /* void */ );
903 
904  int i = 1;
905  wxString newName = aSymbol->GetName();
906 
907  // Append a number to the name until the name is unique in the library.
908  while( m_libMgr->SymbolExists( newName, aLibrary ) )
909  newName.Printf( "%s_%d", aSymbol->GetName(), i++ );
910 
911  aSymbol->SetName( newName );
912 }
913 
914 
915 void SYMBOL_EDIT_FRAME::Revert( bool aConfirm )
916 {
917  LIB_ID libId = GetTargetLibId();
918  const wxString& libName = libId.GetLibNickname();
919 
920  // Empty if this is the library itself that is selected.
921  const wxString& symbolName = libId.GetLibItemName();
922 
923  wxString msg = wxString::Format( _( "Revert '%s' to last version saved?" ),
924  symbolName.IsEmpty() ? libName : symbolName );
925 
926  if( aConfirm && !ConfirmRevertDialog( this, msg ) )
927  return;
928 
929  bool reload_currentSymbol = false;
930  wxString curr_symbolName = symbolName;
931 
932  if( GetCurSymbol() )
933  {
934  // the library itself is reverted: the current symbol will be reloaded only if it is
935  // owned by this library
936  if( symbolName.IsEmpty() )
937  {
938  LIB_ID curr_libId = GetCurSymbol()->GetLibId();
939  reload_currentSymbol = libName == curr_libId.GetLibNickname();
940 
941  if( reload_currentSymbol )
942  curr_symbolName = curr_libId.GetLibItemName();
943  }
944  else
945  {
946  reload_currentSymbol = isCurrentSymbol( libId );
947  }
948  }
949 
950  int unit = m_unit;
951 
952  if( reload_currentSymbol )
953  emptyScreen();
954 
955  if( symbolName.IsEmpty() )
956  {
957  m_libMgr->RevertLibrary( libName );
958  }
959  else
960  {
961  libId = m_libMgr->RevertSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
962 
963  m_treePane->GetLibTree()->SelectLibId( libId );
965  }
966 
967  if( reload_currentSymbol && m_libMgr->SymbolExists( curr_symbolName, libName ) )
968  LoadSymbol( curr_symbolName, libName, unit );
969 
970  m_treePane->Refresh();
971 }
972 
973 
975 {
976  wxCHECK_RET( m_libMgr, "Library manager object not created." );
977 
978  Revert( false );
979  m_libMgr->RevertAll();
980 }
981 
982 
983 void SYMBOL_EDIT_FRAME::LoadSymbol( const wxString& aAlias, const wxString& aLibrary, int aUnit )
984 {
985  LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aAlias, aLibrary );
986 
987  if( !symbol )
988  {
989  wxString msg;
990 
991  msg.Printf( _( "Symbol %s not found in library '%s'." ),
992  aAlias,
993  aLibrary );
994  DisplayError( this, msg );
995  return;
996  }
997 
998  // Optimize default edit options for this symbol
999  // Usually if units are locked, graphic items are specific to each unit
1000  // and if units are interchangeable, graphic items are common to units
1002  tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
1003 
1004  LoadOneLibrarySymbolAux( symbol, aLibrary, aUnit, 0 );
1005 }
1006 
1007 
1008 bool SYMBOL_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
1009 {
1010  wxFileName fn;
1011  wxString msg;
1012  SAVE_AS_HELPER::SAH_TYPE type = SAVE_AS_HELPER::SAH_TYPE::UNDEFINED;
1013  SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::SCH_FILE_T::SCH_KICAD;
1014  PROJECT& prj = Prj();
1015 
1017 
1018  if( !aNewFile && ( aLibrary.empty() || !prj.SchSymbolLibTable()->HasLibrary( aLibrary ) ) )
1019  {
1020  ShowInfoBarError( _( "No library specified." ) );
1021  return false;
1022  }
1023 
1024  if( aNewFile )
1025  {
1026  SEARCH_STACK* search = prj.SchSearchS();
1027 
1028  // Get a new name for the library
1029  wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
1030 
1031  if( !default_path )
1032  default_path = search->LastVisitedPath();
1033 
1034  fn.SetName( aLibrary );
1035  fn.SetExt( KiCadSymbolLibFileExtension );
1036 
1037  wxString wildcards = KiCadSymbolLibFileWildcard();
1038 
1039  wxFileDialog dlg( this, wxString::Format( _( "Save Library '%s' As..." ), aLibrary ),
1040  default_path, fn.GetFullName(), wildcards,
1041  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1042 
1043  dlg.SetExtraControlCreator( &SAVE_AS_HELPER::Create );
1044 
1045  if( dlg.ShowModal() == wxID_CANCEL )
1046  return false;
1047 
1048  fn = dlg.GetPath();
1049 
1050  prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
1051 
1052  if( fn.GetExt().IsEmpty() )
1053  fn.SetExt( KiCadSymbolLibFileExtension );
1054 
1055  const SAVE_AS_HELPER* sah = dynamic_cast<const SAVE_AS_HELPER*>( dlg.GetExtraControl() );
1056  wxCHECK( sah, false );
1057 
1058  type = sah->GetOption();
1059  }
1060  else
1061  {
1062  fn = prj.SchSymbolLibTable()->GetFullURI( aLibrary );
1063  fileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
1064  }
1065 
1066  // Verify the user has write privileges before attempting to save the library file.
1067  if( !aNewFile && m_libMgr->IsLibraryReadOnly( aLibrary ) )
1068  return false;
1069 
1070  ClearMsgPanel();
1071 
1072  // Copy .kicad_symb file to .bak.
1073  if( !backupFile( fn, "bak" ) )
1074  return false;
1075 
1076  if( !m_libMgr->SaveLibrary( aLibrary, fn.GetFullPath(), fileType ) )
1077  {
1078  msg.Printf( _( "Failed to save changes to symbol library file '%s'." ),
1079  fn.GetFullPath() );
1080  DisplayErrorMessage( this, _( "Error Saving Library" ), msg );
1081  return false;
1082  }
1083 
1084  if( !aNewFile )
1085  {
1086  m_libMgr->ClearLibraryModified( aLibrary );
1087  }
1088  else
1089  {
1090  bool resyncLibTree = false;
1091  wxString originalLibNickname = getTargetLib();
1092  wxString forceRefresh;
1093 
1094  switch( type )
1095  {
1096  case SAVE_AS_HELPER::SAH_TYPE::REPLACE_TABLE_ENTRY:
1097  resyncLibTree = replaceLibTableEntry( originalLibNickname, fn.GetFullPath() );
1098  forceRefresh = originalLibNickname;
1099  break;
1100 
1101  case SAVE_AS_HELPER::SAH_TYPE::ADD_GLOBAL_TABLE_ENTRY:
1102  resyncLibTree = addLibTableEntry( fn.GetFullPath() );
1103  break;
1104 
1105  case SAVE_AS_HELPER::SAH_TYPE::ADD_PROJECT_TABLE_ENTRY:
1106  resyncLibTree = addLibTableEntry( fn.GetFullPath(), PROJECT_LIB_TABLE );
1107  break;
1108 
1109  case SAVE_AS_HELPER::SAH_TYPE::NORMAL_SAVE_AS:
1110  default:
1111  break;
1112  }
1113 
1114  if( resyncLibTree )
1115  {
1117  SyncLibraries( true, forceRefresh );
1118  ThawLibraryTree();
1119  }
1120  }
1121 
1122  ClearMsgPanel();
1123  msg.Printf( _( "Symbol library file '%s' saved." ), fn.GetFullPath() );
1125 
1126  return true;
1127 }
1128 
1129 
1130 bool SYMBOL_EDIT_FRAME::saveAllLibraries( bool aRequireConfirmation )
1131 {
1132  wxString msg, msg2;
1133  bool doSave = true;
1134  int dirtyCount = 0;
1135  bool applyToAll = false;
1136  bool retv = true;
1137 
1138  for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1139  {
1140  if( m_libMgr->IsLibraryModified( libNickname ) )
1141  dirtyCount++;
1142  }
1143 
1144  for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1145  {
1146  if( m_libMgr->IsLibraryModified( libNickname ) )
1147  {
1148  if( aRequireConfirmation && !applyToAll )
1149  {
1150  msg.Printf( _( "Save changes to '%s' before closing?" ), libNickname );
1151 
1152  switch( UnsavedChangesDialog( this, msg, dirtyCount > 1 ? &applyToAll : nullptr ) )
1153  {
1154  case wxID_YES: doSave = true; break;
1155  case wxID_NO: doSave = false; break;
1156  default:
1157  case wxID_CANCEL: return false;
1158  }
1159  }
1160 
1161  if( doSave )
1162  {
1163  // If saving under existing name fails then do a Save As..., and if that
1164  // fails then cancel close action.
1165  if( !m_libMgr->IsLibraryReadOnly( libNickname ) )
1166  {
1167  if( saveLibrary( libNickname, false ) )
1168  continue;
1169  }
1170  else
1171  {
1172  msg.Printf( _( "Symbol library '%s' is not writeable." ), libNickname );
1173  msg2 = _( "You must save to a different location." );
1174 
1175  if( dirtyCount == 1 )
1176  {
1177  if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) != wxID_OK )
1178  {
1179  retv = false;
1180  continue;
1181  }
1182  }
1183  else
1184  {
1185  m_infoBar->Dismiss();
1186  m_infoBar->ShowMessageFor( msg + wxS( " " ) + msg2,
1187  2000, wxICON_EXCLAMATION );
1188 
1189  while( m_infoBar->IsShown() )
1190  wxSafeYield();
1191 
1192  retv = false;
1193  continue;
1194  }
1195  }
1196 
1197  if( !saveLibrary( libNickname, true ) )
1198  retv = false;
1199  }
1200  }
1201  }
1202 
1203  updateTitle();
1204  return retv;
1205 }
1206 
1207 
1209 {
1211 
1212  if( !m_symbol )
1213  return;
1214 
1215  wxString msg = m_symbol->GetName();
1216 
1217  AppendMsgPanel( _( "Name" ), UnescapeString( msg ), 8 );
1218 
1219  if( m_symbol->IsAlias() )
1220  {
1221  LIB_SYMBOL_SPTR parent = m_symbol->GetParent().lock();
1222 
1223  msg = parent ? parent->GetName() : _( "Undefined!" );
1224  AppendMsgPanel( _( "Parent" ), UnescapeString( msg ), 8 );
1225  }
1226 
1227  static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
1228  msg = UnitLetter[m_unit];
1229 
1230  AppendMsgPanel( _( "Unit" ), msg, 8 );
1231 
1232  if( m_convert > 1 )
1233  msg = _( "Convert" );
1234  else
1235  msg = _( "Normal" );
1236 
1237  AppendMsgPanel( _( "Body" ), msg, 8 );
1238 
1239  if( m_symbol->IsPower() )
1240  msg = _( "Power Symbol" );
1241  else
1242  msg = _( "Symbol" );
1243 
1244  AppendMsgPanel( _( "Type" ), msg, 8 );
1245  AppendMsgPanel( _( "Description" ), m_symbol->GetDescription(), 8 );
1246  AppendMsgPanel( _( "Keywords" ), m_symbol->GetKeyWords() );
1247  AppendMsgPanel( _( "Datasheet" ), m_symbol->GetDatasheetField().GetText() );
1248 }
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:279
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:239
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
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
Definition: confirm.cpp:55
bool ConfirmRevertDialog(wxWindow *parent, const wxString &aMessage)
Display a confirmation dialog for a revert action.
Definition: confirm.cpp:228
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.
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:292
void SetIncludeOnBoard(bool aIncludeOnBoard)
Set or clear include in board netlist flag.
Definition: lib_symbol.h:592
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:45
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:383
void SaveAll()
Save all modified symbols and libraries.
A dialog which shows:
Schematic editor (Eeschema) main window.
bool IsPower() const
Definition: lib_symbol.cpp:408
Look for files in a number of paths.
Definition: search_stack.h:41
void ShowMessageFor(const wxString &aMessage, int aTime, int aFlags=wxICON_INFORMATION, MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the infobar with the provided message and icon for a specific period of time.
Definition: infobar.cpp:128
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
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:331
LIB_FIELD & GetReferenceField()
Return reference to the reference designator field.
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 m_isSymbolFromSchematic
RefDes of the symbol (only valid if symbol was loaded from schematic)
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).
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false, WX_INFOBAR::MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
#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:175
static LIB_SYMBOL * ParseLibSymbol(LINE_READER &aReader, int aVersion=SEXPR_SCHEMATIC_FILE_VERSION)
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:124
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:313
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:165
int UnsavedChangesDialog(wxWindow *parent, const wxString &aMessage, bool *aApplyToAll)
A specialized version of HandleUnsavedChanges which handles an apply-to-all checkbox.
Definition: confirm.cpp:176
Definition of file extensions used in Kicad.
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:322
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:278
bool isCurrentSymbol(const LIB_ID &aLibId) const
Rename LIB_SYMBOL aliases to avoid conflicts before adding a symbol to a library.
int OKOrCancelDialog(wxWindow *aParent, const wxString &aWarning, const wxString &aMessage, const wxString &aDetailedMessage, const wxString &aOKLabel, const wxString &aCancelLabel, bool *aApplyToAll)
Display a warning dialog with aMessage and returns the user response.
Definition: confirm.cpp:252
void RefreshLibTree()
Refreshes the tree (mainly to update highlighting and asterisking)
Definition: lib_tree.cpp:231
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.
void centerItemIdleHandler(wxIdleEvent &aEvent)
void UpdateSymbolMsgPanelInfo()
Display the documentation of the selected symbol.
wxString UnescapeString(const wxString &aSource)
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.
void ExpandLibId(const LIB_ID &aLibId)
Expand and item i the tree widget.
Definition: lib_tree.cpp:207
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.
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:964
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:56
bool saveAllLibraries(bool aRequireConfirmation)
Save the current symbol.
WX_INFOBAR * m_infoBar
wxRadioButton * m_simpleSaveAs
void SetPower()
Definition: lib_symbol.cpp:417
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 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
int ShowModal() override
Definition: confirm.cpp:99
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:323
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:154
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
Definition: lib_id.h:114
void SetNormal()
Definition: lib_symbol.cpp:435
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.
void CenterLibId(const LIB_ID &aLibId)
Ensure that an item is visible (preferably centered).
Definition: lib_tree.cpp:196
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:190
virtual void UpdateMsgPanel()
Redraw the message panel.
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)