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