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