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/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{
146 && GetCurSymbol()->GetLibId() == aLibId
147 && GetUnit() == aUnit
148 && GetConvert() == aConvert )
149 {
150 return true;
151 }
152
154 {
155 if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
156 [&]() -> bool
157 {
158 return saveCurrentSymbol();
159 } ) )
160 {
161 return false;
162 }
163 }
164
166
167 if( LoadSymbolFromCurrentLib( aLibId.GetLibItemName(), aUnit, aConvert ) )
168 {
169 m_treePane->GetLibTree()->SelectLibId( aLibId );
170 m_treePane->GetLibTree()->ExpandLibId( aLibId );
171
172 m_centerItemOnIdle = aLibId;
173 Bind( wxEVT_IDLE, &SYMBOL_EDIT_FRAME::centerItemIdleHandler, this );
174
175 return true;
176 }
177
178 return false;
179}
180
181
183{
185 Unbind( wxEVT_IDLE, &SYMBOL_EDIT_FRAME::centerItemIdleHandler, this );
186}
187
188
189bool SYMBOL_EDIT_FRAME::LoadSymbolFromCurrentLib( const wxString& aAliasName, int aUnit,
190 int aConvert )
191{
192 LIB_SYMBOL* alias = nullptr;
193
194 try
195 {
196 alias = Prj().SchSymbolLibTable()->LoadSymbol( GetCurLib(), aAliasName );
197 }
198 catch( const IO_ERROR& ioe )
199 {
200 wxString msg;
201
202 msg.Printf( _( "Error loading symbol %s from library '%s'." ),
203 aAliasName,
204 GetCurLib() );
205 DisplayErrorMessage( this, msg, ioe.What() );
206 return false;
207 }
208
209 if( !alias || !LoadOneLibrarySymbolAux( alias, GetCurLib(), aUnit, aConvert ) )
210 return false;
211
212 // Enable synchronized pin edit mode for symbols with interchangeable units
214
217 SetShowDeMorgan( GetCurSymbol()->Flatten()->HasConversion() );
218
219 if( aUnit > 0 )
221
222 return true;
223}
224
225
226bool SYMBOL_EDIT_FRAME::LoadOneLibrarySymbolAux( LIB_SYMBOL* aEntry, const wxString& aLibrary,
227 int aUnit, int aConvert )
228{
229 bool rebuildMenuAndToolbar = false;
230
231 if( !aEntry || aLibrary.empty() )
232 return false;
233
234 if( aEntry->GetName().IsEmpty() )
235 {
236 wxLogWarning( "Symbol in library '%s' has empty name field.", aLibrary );
237 return false;
238 }
239
241
242 // Symbols from the schematic are edited in place and not managed by the library manager.
244 {
245 delete m_symbol;
246 m_symbol = nullptr;
247
248 SCH_SCREEN* screen = GetScreen();
249 delete screen;
252 rebuildMenuAndToolbar = true;
253 }
254
255 LIB_SYMBOL* lib_symbol = m_libMgr->GetBufferedSymbol( aEntry->GetName(), aLibrary );
256 wxCHECK( lib_symbol, false );
257
258 m_unit = aUnit > 0 ? aUnit : 1;
259 m_convert = aConvert > 0 ? aConvert : 1;
260
261 // The buffered screen for the symbol
262 SCH_SCREEN* symbol_screen = m_libMgr->GetScreen( lib_symbol->GetName(), aLibrary );
263
264 SetScreen( symbol_screen );
265 SetCurSymbol( new LIB_SYMBOL( *lib_symbol ), true );
266 SetCurLib( aLibrary );
267
268 if( rebuildMenuAndToolbar )
269 {
272 GetInfoBar()->Dismiss();
273 }
274
275 updateTitle();
277 SetShowDeMorgan( GetCurSymbol()->HasConversion() );
278
280
281 // Display the document information based on the entry selected just in
282 // case the entry is an alias.
284 Refresh();
285
286 return true;
287}
288
289
291{
292 saveAllLibraries( false );
294}
295
296
298{
300
301 wxArrayString rootSymbols;
302 wxString lib = getTargetLib();
303
304 if( !m_libMgr->LibraryExists( lib ) )
305 {
306 lib = SelectLibraryFromList();
307
308 if( !m_libMgr->LibraryExists( lib ) )
309 return;
310 }
311
312 m_libMgr->GetRootSymbolNames( lib, rootSymbols );
313
314 rootSymbols.Sort();
315
316 DIALOG_LIB_NEW_SYMBOL dlg( this, &rootSymbols );
317 dlg.SetMinSize( dlg.GetSize() );
318
319 if( dlg.ShowModal() == wxID_CANCEL )
320 return;
321
322 if( dlg.GetName().IsEmpty() )
323 {
324 wxMessageBox( _( "This new symbol has no name and cannot be created." ) );
325 return;
326 }
327
328 wxString name = dlg.GetName();
329
330 // Currently, symbol names cannot include a space, that breaks libraries:
331 name.Replace( " ", "_" );
332
333 // Test if there is a symbol with this name already.
334 if( !lib.empty() && m_libMgr->SymbolExists( name, lib ) )
335 {
336 wxString msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'." ),
337 name,
338 lib );
339
340 KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
341 errorDlg.SetOKLabel( _( "Overwrite" ) );
342 errorDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
343
344 if( errorDlg.ShowModal() == wxID_CANCEL )
345 return;
346 }
347
348 LIB_SYMBOL new_symbol( name ); // do not create symbol on the heap, it will be buffered soon
349
350 wxString parentSymbolName = dlg.GetParentSymbolName();
351
352 if( parentSymbolName.IsEmpty() )
353 {
354 new_symbol.GetReferenceField().SetText( dlg.GetReference() );
355 new_symbol.SetUnitCount( dlg.GetUnitCount() );
356
357 // Initialize new_symbol.m_TextInside member:
358 // if 0, pin text is outside the body (on the pin)
359 // if > 0, pin text is inside the body
360 if( dlg.GetPinNameInside() )
361 {
362 new_symbol.SetPinNameOffset( dlg.GetPinTextPosition() );
363
364 if( new_symbol.GetPinNameOffset() == 0 )
365 new_symbol.SetPinNameOffset( 1 );
366 }
367 else
368 {
369 new_symbol.SetPinNameOffset( 0 );
370 }
371
372 ( dlg.GetPowerSymbol() ) ? new_symbol.SetPower() : new_symbol.SetNormal();
373 new_symbol.SetShowPinNumbers( dlg.GetShowPinNumber() );
374 new_symbol.SetShowPinNames( dlg.GetShowPinName() );
375 new_symbol.LockUnits( !dlg.GetUnitsInterchangeable() );
376 new_symbol.SetIncludeInBom( dlg.GetIncludeInBom() );
377 new_symbol.SetIncludeOnBoard( dlg.GetIncludeOnBoard() );
378
379 if( dlg.GetUnitCount() < 2 )
380 new_symbol.LockUnits( false );
381
382 new_symbol.SetConversion( dlg.GetAlternateBodyStyle() );
383 }
384 else
385 {
386 LIB_SYMBOL* parent = m_libMgr->GetAlias( parentSymbolName, lib );
387 wxCHECK( parent, /* void */ );
388 new_symbol.SetParent( parent );
389
390 // Inherit the parent mandatory field attributes.
391 for( int id = 0; id < MANDATORY_FIELDS; ++id )
392 {
393 LIB_FIELD* field = new_symbol.GetFieldById( id );
394
395 // the MANDATORY_FIELDS are exactly that in RAM.
396 wxCHECK( field, /* void */ );
397
398 LIB_FIELD* parentField = parent->GetFieldById( id );
399
400 wxCHECK( parentField, /* void */ );
401
402 *field = *parentField;
403
404 switch( id )
405 {
406 case REFERENCE_FIELD:
407 // parent's reference already copied
408 break;
409
410 case VALUE_FIELD:
411 if( parent->IsPower() )
412 field->SetText( name );
413 break;
414
415 case FOOTPRINT_FIELD:
416 case DATASHEET_FIELD:
417 // - footprint might be the same as parent, but might not
418 // - datasheet is most likely different
419 // - probably best to play it safe and copy neither
420 field->SetText( wxEmptyString );
421 break;
422 }
423
424 field->SetParent( &new_symbol );
425 }
426 }
427
428 m_libMgr->UpdateSymbol( &new_symbol, lib );
429 SyncLibraries( false );
430 LoadSymbol( name, lib, 1 );
431
432 // must be called after loadSymbol, that calls SetShowDeMorgan, but
433 // because the symbol is empty,it looks like it has no alternate body
435}
436
437
439{
440 if( getTargetSymbol() == m_symbol )
441 {
443 {
444 SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
445
446 if( !schframe ) // happens when the schematic editor is not active (or closed)
447 {
448 DisplayErrorMessage( this, _( "No schematic currently open." ) );
449 }
450 else
451 {
453 GetScreen()->SetContentModified( false );
454 }
455 }
456 else
457 {
459 }
460 }
461 else if( !GetTargetLibId().GetLibNickname().empty() )
462 {
463 LIB_ID libId = GetTargetLibId();
464 const wxString& libName = libId.GetLibNickname();
465
466 if( m_libMgr->IsLibraryReadOnly( libName ) )
467 {
468 wxString msg = wxString::Format( _( "Symbol library '%s' is not writable." ),
469 libName );
470 wxString msg2 = _( "You must save to a different location." );
471
472 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) == wxID_OK )
473 saveLibrary( libName, true );
474 }
475 else
476 {
477 saveLibrary( libName, false );
478 }
479 }
480
482 updateTitle();
483}
484
485
487{
488 wxCHECK( !GetTargetLibId().GetLibNickname().empty(), /* void */ );
489
490 const wxString& libName = GetTargetLibId().GetLibNickname();
491
492 saveLibrary( libName, true );
494}
495
496
498{
499 saveSymbolAs();
500
502}
503
504
505static int ID_SAVE_AS_NAME = 4172;
506static int ID_MAKE_NEW_LIBRARY = 4173;
507
508
510 const wxString& aLibraryPreselect )
511{
512 COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
514 SYMBOL_LIB_TABLE* tbl = Prj().SchSymbolLibTable();
515 std::vector<wxString> libNicknames = tbl->GetLogicalLibs();
516 wxArrayString headers;
517 std::vector<wxArrayString> itemsToDisplay;
518
519 headers.Add( _( "Nickname" ) );
520 headers.Add( _( "Description" ) );
521
522 for( const wxString& nickname : libNicknames )
523 {
524 if( alg::contains( project.m_PinnedSymbolLibs, nickname )
525 || alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
526 {
527 wxArrayString item;
528 item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
529 item.Add( tbl->GetDescription( nickname ) );
530 itemsToDisplay.push_back( item );
531 }
532 }
533
534 for( const wxString& nickname : libNicknames )
535 {
536 if( !alg::contains( project.m_PinnedSymbolLibs, nickname )
537 && !alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
538 {
539 wxArrayString item;
540 item.Add( nickname );
541 item.Add( tbl->GetDescription( nickname ) );
542 itemsToDisplay.push_back( item );
543 }
544 }
545
546 EDA_LIST_DIALOG* dlg = new EDA_LIST_DIALOG( this, _( "Save Symbol As" ), headers,
547 itemsToDisplay, aLibraryPreselect, false );
548
549 dlg->SetListLabel( _( "Save in library:" ) );
550 dlg->SetOKLabel( _( "Save" ) );
551
552 wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
553
554 wxStaticText* label = new wxStaticText( dlg, wxID_ANY, _( "Name:" ) );
555 bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
556
557 wxTextCtrl* nameTextCtrl = new wxTextCtrl( dlg, ID_SAVE_AS_NAME, aSymbolName );
558 bNameSizer->Add( nameTextCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
559
560 wxButton* newLibraryButton = new wxButton( dlg, ID_MAKE_NEW_LIBRARY, _( "New Library..." ) );
561 dlg->m_ButtonsSizer->Prepend( 80, 20 );
562 dlg->m_ButtonsSizer->Prepend( newLibraryButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
563
564 dlg->GetSizer()->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
565
566 dlg->Bind( wxEVT_BUTTON,
567 [dlg]( wxCommandEvent& )
568 {
569 dlg->EndModal( ID_MAKE_NEW_LIBRARY );
571
572 // Move nameTextCtrl to the head of the tab-order
573 if( dlg->GetChildren().DeleteObject( nameTextCtrl ) )
574 dlg->GetChildren().Insert( nameTextCtrl );
575
576 dlg->SetInitialFocus( nameTextCtrl );
577
578 dlg->Layout();
579 dlg->GetSizer()->Fit( dlg );
580
581 return dlg;
582}
583
584
586{
587 LIB_SYMBOL* symbol = getTargetSymbol();
588
589 if( symbol )
590 {
591 LIB_ID old_lib_id = symbol->GetLibId();
592 wxString symbolName = old_lib_id.GetLibItemName();
593 wxString libraryName = old_lib_id.GetLibNickname();
594 bool done = false;
595
596 std::unique_ptr<EDA_LIST_DIALOG> dlg;
597
598 while( !done )
599 {
600 dlg.reset( buildSaveAsDialog( symbolName, libraryName ) );
601
602 int ret = dlg->ShowModal();
603
604 if( ret == wxID_CANCEL )
605 {
606 return;
607 }
608 else if( ret == wxID_OK )
609 {
610 done = true;
611 }
612 else if( ret == ID_MAKE_NEW_LIBRARY )
613 {
614 wxFileName newLibrary( AddLibraryFile( true ) );
615 libraryName = newLibrary.GetName();
616 }
617 }
618
619 libraryName = dlg->GetTextSelection();
620
621 if( libraryName.IsEmpty() )
622 {
623 DisplayError( this, _( "No library specified. Symbol could not be saved." ) );
624 return;
625 }
626
627 // @todo Either check the selecteced library to see if the parent symbol name is in
628 // the new library and/or copy the parent symbol as well. This is the lazy
629 // solution to ensure derived symbols do not get orphaned.
630 if( symbol->IsAlias() && libraryName != old_lib_id.GetLibNickname() )
631 {
632 DisplayError( this, _( "Derived symbols must be saved in the same library as their "
633 "parent symbol." ) );
634 return;
635 }
636
637 symbolName = static_cast<wxTextCtrl*>( dlg->FindWindow( ID_SAVE_AS_NAME ) )->GetValue();
638 symbolName.Trim( true );
639 symbolName.Trim( false );
640 symbolName.Replace( " ", "_" );
641
642 if( symbolName.IsEmpty() )
643 {
644 // This is effectively a cancel. No need to nag the user about it.
645 return;
646 }
647
648 // Test if there is a symbol with this name already.
649 if( m_libMgr->SymbolExists( symbolName, libraryName ) )
650 {
651 wxString msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'" ),
652 symbolName,
653 libraryName );
654
655 KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
656 errorDlg.SetOKLabel( _( "Overwrite" ) );
657 errorDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
658
659 if( errorDlg.ShowModal() == wxID_CANCEL )
660 return;
661 }
662
663 LIB_SYMBOL new_symbol( *symbol );
664 new_symbol.SetName( symbolName );
665
666 m_libMgr->UpdateSymbol( &new_symbol, libraryName );
667 SyncLibraries( false );
668 m_treePane->GetLibTree()->SelectLibId( LIB_ID( libraryName, new_symbol.GetName() ) );
669 LoadSymbol( symbolName, libraryName, m_unit );
670 }
671}
672
673
675{
676 wxCHECK( m_symbol, /* void */ );
677
678 wxString lib = GetCurLib();
679
680 if( !lib.IsEmpty() && aOldName && *aOldName != m_symbol->GetName() )
681 {
682 // Test the current library for name conflicts
683 if( m_libMgr->SymbolExists( m_symbol->GetName(), lib ) )
684 {
685 wxString msg = wxString::Format( _( "Symbol name '%s' already in use." ),
687
688 DisplayErrorMessage( this, msg );
689 m_symbol->SetName( *aOldName );
690 }
691 else
692 {
693 m_libMgr->UpdateSymbolAfterRename( m_symbol, *aOldName, lib );
694 }
695
696 // Reselect the renamed symbol
698 }
699
701 SetShowDeMorgan( GetCurSymbol()->Flatten()->HasConversion() );
702 updateTitle();
703
704 // N.B. The view needs to be rebuilt first as the Symbol Properties change may invalidate
705 // the view pointers by rebuilting the field table
706 RebuildView();
708
709 OnModify();
710}
711
712
714{
715 std::vector<LIB_ID> toDelete = GetSelectedLibIds();
716
717 if( toDelete.empty() )
718 toDelete.emplace_back( GetTargetLibId() );
719
720 for( LIB_ID& libId : toDelete )
721 {
722 if( m_libMgr->IsSymbolModified( libId.GetLibItemName(), libId.GetLibNickname() )
723 && !IsOK( this, wxString::Format( _( "The symbol '%s' has been modified.\n"
724 "Do you want to remove it from the library?" ),
725 libId.GetUniStringLibItemName() ) ) )
726 {
727 continue;
728 }
729
730 if( m_libMgr->HasDerivedSymbols( libId.GetLibItemName(), libId.GetLibNickname() ) )
731 {
732 wxString msg;
733
734 msg.Printf(
735 _( "The symbol %s is used to derive other symbols.\n"
736 "Deleting this symbol will delete all of the symbols derived from it.\n\n"
737 "Do you wish to delete this symbol and all of its derivatives?" ),
738 libId.GetLibItemName().wx_str() );
739
740 wxMessageDialog::ButtonLabel yesButtonLabel( _( "Delete Symbol" ) );
741 wxMessageDialog::ButtonLabel noButtonLabel( _( "Keep Symbol" ) );
742
743 wxMessageDialog dlg( this, msg, _( "Warning" ),
744 wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTER );
745 dlg.SetYesNoLabels( yesButtonLabel, noButtonLabel );
746
747 if( dlg.ShowModal() == wxID_NO )
748 continue;
749 }
750
751 if( IsCurrentSymbol( libId ) )
752 emptyScreen();
753
754 m_libMgr->RemoveSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
755 }
756
758}
759
760
762{
763 std::vector<LIB_ID> symbols;
764
765 if( GetTreeLIBIDs( symbols ) == 0 )
766 return;
767
768 STRING_FORMATTER formatter;
769
770 for( LIB_ID& libId : symbols )
771 {
772 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(),
773 libId.GetLibNickname() );
774
775 if( !symbol )
776 continue;
777
778 std::unique_ptr<LIB_SYMBOL> tmp = symbol->Flatten();
779 SCH_SEXPR_PLUGIN::FormatLibSymbol( tmp.get(), formatter );
780 }
781
782 wxLogNull doNotLog; // disable logging of failed clipboard actions
783
784 auto clipboard = wxTheClipboard;
785 wxClipboardLocker clipboardLock( clipboard );
786
787 if( !clipboardLock || !clipboard->IsOpened() )
788 return;
789
790 auto data = new wxTextDataObject( wxString( formatter.GetString().c_str(), wxConvUTF8 ) );
791 clipboard->SetData( data );
792
793 clipboard->Flush();
794}
795
796
797void SYMBOL_EDIT_FRAME::DuplicateSymbol( bool aFromClipboard )
798{
799 LIB_ID libId = GetTargetLibId();
800 wxString lib = libId.GetLibNickname();
801
802 if( !m_libMgr->LibraryExists( lib ) )
803 return;
804
805 LIB_SYMBOL* srcSymbol = nullptr;
806 LIB_SYMBOL* newSymbol = nullptr;
807
808 std::vector<LIB_SYMBOL*> newSymbols;
809
810 if( aFromClipboard )
811 {
812 wxLogNull doNotLog; // disable logging of failed clipboard actions
813
814 auto clipboard = wxTheClipboard;
815 wxClipboardLocker clipboardLock( clipboard );
816
817 if( !clipboardLock
818 || !( clipboard->IsSupported( wxDF_TEXT )
819 || clipboard->IsSupported( wxDF_UNICODETEXT ) ) )
820 {
821 return;
822 }
823
824 wxTextDataObject data;
825 clipboard->GetData( data );
826 wxString symbolSource = data.GetText();
827
828 std::unique_ptr<STRING_LINE_READER> reader = std::make_unique<STRING_LINE_READER>( TO_UTF8( symbolSource ), "Clipboard" );
829
830 do
831 {
832 try
833 {
834 newSymbol = SCH_SEXPR_PLUGIN::ParseLibSymbol( *reader );
835 }
836 catch( IO_ERROR& e )
837 {
838 wxLogMessage( "Can not paste: %s", e.Problem() );
839 break;
840 }
841
842 if( newSymbol )
843 newSymbols.emplace_back( newSymbol );
844
845 reader.reset( new STRING_LINE_READER( *reader ) );
846 }
847 while( newSymbol );
848 }
849 else
850 {
851 srcSymbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(), lib );
852
853 wxCHECK( srcSymbol, /* void */ );
854
855 newSymbols.emplace_back( new LIB_SYMBOL( *srcSymbol ) );
856
857 // Derive from same parent.
858 if( srcSymbol->IsAlias() )
859 {
860 std::shared_ptr< LIB_SYMBOL > srcParent = srcSymbol->GetParent().lock();
861
862 wxCHECK( srcParent, /* void */ );
863
864 newSymbol->SetParent( srcParent.get() );
865 }
866 }
867
868 if( newSymbols.empty() )
869 return;
870
871 for( LIB_SYMBOL* symbol : newSymbols )
872 {
873 ensureUniqueName( symbol, lib );
874 m_libMgr->UpdateSymbol( symbol, lib );
875
876 LoadOneLibrarySymbolAux( symbol, lib, GetUnit(), GetConvert() );
877 }
878
879 SyncLibraries( false );
880 m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, newSymbols[0]->GetName() ) );
881
882 delete newSymbol;
883}
884
885
886void SYMBOL_EDIT_FRAME::ensureUniqueName( LIB_SYMBOL* aSymbol, const wxString& aLibrary )
887{
888 wxCHECK( aSymbol, /* void */ );
889
890 int i = 1;
891 wxString newName = aSymbol->GetName();
892
893 // Append a number to the name until the name is unique in the library.
894 while( m_libMgr->SymbolExists( newName, aLibrary ) )
895 newName.Printf( "%s_%d", aSymbol->GetName(), i++ );
896
897 aSymbol->SetName( newName );
898}
899
900
901void SYMBOL_EDIT_FRAME::Revert( bool aConfirm )
902{
903 LIB_ID libId = GetTargetLibId();
904 const wxString& libName = libId.GetLibNickname();
905
906 // Empty if this is the library itself that is selected.
907 const wxString& symbolName = libId.GetLibItemName();
908
909 wxString msg = wxString::Format( _( "Revert '%s' to last version saved?" ),
910 symbolName.IsEmpty() ? libName : symbolName );
911
912 if( aConfirm && !ConfirmRevertDialog( this, msg ) )
913 return;
914
915 bool reload_currentSymbol = false;
916 wxString curr_symbolName = symbolName;
917
918 if( GetCurSymbol() )
919 {
920 // the library itself is reverted: the current symbol will be reloaded only if it is
921 // owned by this library
922 if( symbolName.IsEmpty() )
923 {
924 LIB_ID curr_libId = GetCurSymbol()->GetLibId();
925 reload_currentSymbol = libName == curr_libId.GetLibNickname();
926
927 if( reload_currentSymbol )
928 curr_symbolName = curr_libId.GetLibItemName();
929 }
930 else
931 {
932 reload_currentSymbol = IsCurrentSymbol( libId );
933 }
934 }
935
936 int unit = m_unit;
937
938 if( reload_currentSymbol )
939 emptyScreen();
940
941 if( symbolName.IsEmpty() )
942 {
943 m_libMgr->RevertLibrary( libName );
944 }
945 else
946 {
947 libId = m_libMgr->RevertSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
948
949 m_treePane->GetLibTree()->SelectLibId( libId );
951 }
952
953 if( reload_currentSymbol && m_libMgr->SymbolExists( curr_symbolName, libName ) )
954 LoadSymbol( curr_symbolName, libName, unit );
955
956 m_treePane->Refresh();
957}
958
959
961{
962 wxCHECK_RET( m_libMgr, "Library manager object not created." );
963
964 Revert( false );
966}
967
968
969void SYMBOL_EDIT_FRAME::LoadSymbol( const wxString& aAlias, const wxString& aLibrary, int aUnit )
970{
972 {
973 if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
974 [&]() -> bool
975 {
976 return saveCurrentSymbol();
977 } ) )
978 {
979 return;
980 }
981 }
982
983 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aAlias, aLibrary );
984
985 if( !symbol )
986 {
987 DisplayError( this, wxString::Format( _( "Symbol %s not found in library '%s'." ),
988 aAlias,
989 aLibrary ) );
990 return;
991 }
992
993 // Optimize default edit options for this symbol
994 // Usually if units are locked, graphic items are specific to each unit
995 // and if units are interchangeable, graphic items are common to units
997 tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
998
999 LoadOneLibrarySymbolAux( symbol, aLibrary, aUnit, 0 );
1000}
1001
1002
1003bool SYMBOL_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
1004{
1005 wxFileName fn;
1006 wxString msg;
1008 SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::SCH_FILE_T::SCH_KICAD;
1009 PROJECT& prj = Prj();
1010
1012
1013 if( !aNewFile && ( aLibrary.empty() || !prj.SchSymbolLibTable()->HasLibrary( aLibrary ) ) )
1014 {
1015 ShowInfoBarError( _( "No library specified." ) );
1016 return false;
1017 }
1018
1019 if( aNewFile )
1020 {
1021 SEARCH_STACK* search = prj.SchSearchS();
1022
1023 // Get a new name for the library
1024 wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
1025
1026 if( !default_path )
1027 default_path = search->LastVisitedPath();
1028
1029 fn.SetName( aLibrary );
1030 fn.SetExt( KiCadSymbolLibFileExtension );
1031
1032 wxString wildcards = KiCadSymbolLibFileWildcard();
1033
1034 wxFileDialog dlg( this, wxString::Format( _( "Save Library '%s' As..." ), aLibrary ),
1035 default_path, fn.GetFullName(), wildcards,
1036 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1037
1038#if wxCHECK_VERSION( 3, 1, 7 )
1039 SYMBOL_FILEDLG_SAVE_AS saveAsHook( type );
1040 dlg.SetCustomizeHook( saveAsHook );
1041#else
1042 dlg.SetExtraControlCreator( &SYMBOL_LEGACYFILEDLG_SAVE_AS::Create );
1043#endif
1044
1045 if( dlg.ShowModal() == wxID_CANCEL )
1046 return false;
1047
1048 fn = dlg.GetPath();
1049
1050 prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
1051
1052 if( fn.GetExt().IsEmpty() )
1053 fn.SetExt( KiCadSymbolLibFileExtension );
1054
1055#if wxCHECK_VERSION( 3, 1, 7 )
1056 type = saveAsHook.GetOption();
1057#else
1058 const SYMBOL_LEGACYFILEDLG_SAVE_AS* sah =
1059 dynamic_cast<const SYMBOL_LEGACYFILEDLG_SAVE_AS*>( dlg.GetExtraControl() );
1060 wxCHECK( sah, false );
1061
1062 type = sah->GetOption();
1063#endif
1064 }
1065 else
1066 {
1067 fn = prj.SchSymbolLibTable()->GetFullURI( aLibrary );
1069 }
1070
1071 // Verify the user has write privileges before attempting to save the library file.
1072 if( !aNewFile && m_libMgr->IsLibraryReadOnly( aLibrary ) )
1073 return false;
1074
1075 ClearMsgPanel();
1076
1077 // Copy .kicad_symb file to .bak.
1078 if( !backupFile( fn, "bak" ) )
1079 return false;
1080
1081 if( !m_libMgr->SaveLibrary( aLibrary, fn.GetFullPath(), fileType ) )
1082 {
1083 msg.Printf( _( "Failed to save changes to symbol library file '%s'." ),
1084 fn.GetFullPath() );
1085 DisplayErrorMessage( this, _( "Error Saving Library" ), msg );
1086 return false;
1087 }
1088
1089 if( !aNewFile )
1090 {
1091 m_libMgr->ClearLibraryModified( aLibrary );
1092 }
1093 else
1094 {
1095 bool resyncLibTree = false;
1096 wxString originalLibNickname = getTargetLib();
1097 wxString forceRefresh;
1098
1099 switch( type )
1100 {
1102 resyncLibTree = replaceLibTableEntry( originalLibNickname, fn.GetFullPath() );
1103 forceRefresh = originalLibNickname;
1104 break;
1105
1107 resyncLibTree = addLibTableEntry( fn.GetFullPath() );
1108 break;
1109
1111 resyncLibTree = addLibTableEntry( fn.GetFullPath(), PROJECT_LIB_TABLE );
1112 break;
1113
1114 default:
1115 break;
1116 }
1117
1118 if( resyncLibTree )
1119 {
1121 SyncLibraries( true, false, forceRefresh );
1123 }
1124 }
1125
1126 ClearMsgPanel();
1127 msg.Printf( _( "Symbol library file '%s' saved." ), fn.GetFullPath() );
1129
1130 return true;
1131}
1132
1133
1134bool SYMBOL_EDIT_FRAME::saveAllLibraries( bool aRequireConfirmation )
1135{
1136 wxString msg, msg2;
1137 bool doSave = true;
1138 int dirtyCount = 0;
1139 bool applyToAll = false;
1140 bool retv = true;
1141
1142 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1143 {
1144 if( m_libMgr->IsLibraryModified( libNickname ) )
1145 dirtyCount++;
1146 }
1147
1148 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1149 {
1150 if( m_libMgr->IsLibraryModified( libNickname ) )
1151 {
1152 if( aRequireConfirmation && !applyToAll )
1153 {
1154 msg.Printf( _( "Save changes to '%s' before closing?" ), libNickname );
1155
1156 switch( UnsavedChangesDialog( this, msg, dirtyCount > 1 ? &applyToAll : nullptr ) )
1157 {
1158 case wxID_YES: doSave = true; break;
1159 case wxID_NO: doSave = false; break;
1160 default:
1161 case wxID_CANCEL: return false;
1162 }
1163 }
1164
1165 if( doSave )
1166 {
1167 // If saving under existing name fails then do a Save As..., and if that
1168 // fails then cancel close action.
1169 if( !m_libMgr->IsLibraryReadOnly( libNickname ) )
1170 {
1171 if( saveLibrary( libNickname, false ) )
1172 continue;
1173 }
1174 else
1175 {
1176 msg.Printf( _( "Symbol library '%s' is not writable." ), libNickname );
1177 msg2 = _( "You must save to a different location." );
1178
1179 if( dirtyCount == 1 )
1180 {
1181 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) != wxID_OK )
1182 {
1183 retv = false;
1184 continue;
1185 }
1186 }
1187 else
1188 {
1189 m_infoBar->Dismiss();
1190 m_infoBar->ShowMessageFor( msg + wxS( " " ) + msg2,
1191 2000, wxICON_EXCLAMATION );
1192
1193 while( m_infoBar->IsShown() )
1194 wxSafeYield();
1195
1196 retv = false;
1197 continue;
1198 }
1199 }
1200
1201 if( !saveLibrary( libNickname, true ) )
1202 retv = false;
1203 }
1204 }
1205 }
1206
1207 updateTitle();
1208 return retv;
1209}
1210
1211
1213{
1215
1216 if( !m_symbol )
1217 return;
1218
1219 wxString msg = m_symbol->GetName();
1220
1221 AppendMsgPanel( _( "Name" ), UnescapeString( msg ), 8 );
1222
1223 if( m_symbol->IsAlias() )
1224 {
1225 LIB_SYMBOL_SPTR parent = m_symbol->GetParent().lock();
1226
1227 msg = parent ? parent->GetName() : _( "Undefined!" );
1228 AppendMsgPanel( _( "Parent" ), UnescapeString( msg ), 8 );
1229 }
1230
1231 static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
1232 msg = UnitLetter[m_unit];
1233
1234 AppendMsgPanel( _( "Unit" ), msg, 8 );
1235
1236 if( m_convert > 1 )
1237 msg = _( "Convert" );
1238 else
1239 msg = _( "Normal" );
1240
1241 AppendMsgPanel( _( "Body" ), msg, 8 );
1242
1243 if( m_symbol->IsPower() )
1244 msg = _( "Power Symbol" );
1245 else
1246 msg = _( "Symbol" );
1247
1248 AppendMsgPanel( _( "Type" ), msg, 8 );
1249 AppendMsgPanel( _( "Description" ), m_symbol->GetDescription(), 8 );
1250 AppendMsgPanel( _( "Keywords" ), m_symbol->GetKeyWords() );
1251 AppendMsgPanel( _( "Datasheet" ), m_symbol->GetDatasheetField().GetText() );
1252}
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...
WX_INFOBAR * GetInfoBar()
virtual void ClearMsgPanel()
Clear all messages from the message panel.
virtual void UpdateMsgPanel()
Redraw 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:56
int ShowModal() override
Definition: confirm.cpp:100
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:60
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
const UTF8 & GetLibItemName() const
Definition: lib_id.h:101
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:98
void SetIncludeOnBoard(bool aIncludeOnBoard)
Set or clear include in board netlist flag.
Definition: lib_symbol.h:647
void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: lib_symbol.h:623
bool IsMulti() const
Definition: lib_symbol.h:556
int GetPinNameOffset() const
Definition: lib_symbol.h:616
wxString GetKeyWords() const
Definition: lib_symbol.h:159
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:253
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:615
bool IsAlias() const
Definition: lib_symbol.h:183
bool IsPower() const
Definition: lib_symbol.cpp:552
void SetPower()
Definition: lib_symbol.cpp:561
void LockUnits(bool aLockUnits)
Set interchangeable the property for symbol units.
Definition: lib_symbol.h:247
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: lib_symbol.h:631
LIB_ID GetLibId() const override
Definition: lib_symbol.h:139
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:451
wxString GetName() const override
Definition: lib_symbol.h:136
wxString GetDescription() override
Definition: lib_symbol.h:146
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:460
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:639
LIB_SYMBOL_REF & GetParent()
Definition: lib_symbol.h:125
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:441
void SetNormal()
Definition: lib_symbol.cpp:579
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:307
void CenterLibId(const LIB_ID &aLibId)
Ensure that an item is visible (preferably centered).
Definition: lib_tree.cpp:230
void SelectLibId(const LIB_ID &aLibId)
Select an item in the tree widget.
Definition: lib_tree.cpp:224
void ExpandLibId(const LIB_ID &aLibId)
Expand and item i the tree widget.
Definition: lib_tree.cpp:242
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:65
Container for project specific data.
Definition: project.h:63
@ SCH_LIB_PATH
Definition: project.h:164
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:148
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:253
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:264
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 ReCreateMenuBar() override
Recreates the menu bar.
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)
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.
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.
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: infobar.cpp:128
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: 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:253
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:342
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:280
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:240
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:299
int UnsavedChangesDialog(wxWindow *parent, const wxString &aMessage, bool *aApplyToAll)
A specialized version of HandleUnsavedChanges which handles an apply-to-all checkbox.
Definition: confirm.cpp:177
bool ConfirmRevertDialog(wxWindow *parent, const wxString &aMessage)
Display a confirmation dialog for a revert action.
Definition: confirm.cpp:229
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:44
FormatType fileType(const char *aFileName)
Definition: loadmodel.cpp:292
#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
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.