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