KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2023 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 <project_sch.h>
49#include <string_utils.h>
50#include "symbol_saveas_type.h"
51
53
54
56{
57 wxString title;
58
60 {
62 title = wxT( "*" );
63
64 title += m_reference;
65 title += wxS( " " ) + _( "[from schematic]" );
66 }
67 else if( GetCurSymbol() )
68 {
70 title = wxT( "*" );
71
72 title += UnescapeString( GetCurSymbol()->GetLibId().Format() );
73
75 title += wxS( " " ) + _( "[Read Only Library]" );
76 }
77 else
78 {
79 title = _( "[no symbol loaded]" );
80 }
81
82 title += wxT( " \u2014 " ) + _( "Symbol Editor" );
83 SetTitle( title );
84}
85
86
87void SYMBOL_EDIT_FRAME::SelectActiveLibrary( const wxString& aLibrary )
88{
89 wxString selectedLib = aLibrary;
90
91 if( selectedLib.empty() )
92 selectedLib = SelectLibraryFromList();
93
94 if( !selectedLib.empty() )
95 SetCurLib( selectedLib );
96
98}
99
100
102{
103 if( GetCurSymbol() )
104 {
106 {
107 SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
108
109 if( !schframe ) // happens when the schematic editor has been closed
110 {
111 DisplayErrorMessage( this, _( "No schematic currently open." ) );
112 return false;
113 }
114 else
115 {
117 GetScreen()->SetContentModified( false );
118 return true;
119 }
120 }
121 else
122 {
123 const wxString& libName = GetCurSymbol()->GetLibId().GetLibNickname();
124
125 if( m_libMgr->IsLibraryReadOnly( libName ) )
126 {
127 wxString msg = wxString::Format( _( "Symbol library '%s' is not writable." ),
128 libName );
129 wxString msg2 = _( "You must save to a different location." );
130
131 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) == wxID_OK )
132 return saveLibrary( libName, true );
133 }
134 else
135 {
136 return saveLibrary( libName, false );
137 }
138 }
139 }
140
141 return false;
142}
143
144
145bool SYMBOL_EDIT_FRAME::LoadSymbol( const LIB_ID& aLibId, int aUnit, int aBodyStyle )
146{
147 LIB_ID libId = aLibId;
148
149 // Some libraries can't be edited, so load the underlying chosen symbol
151 {
152 if( lib->SchLibType() == SCH_IO_MGR::SCH_DATABASE
153 || lib->SchLibType() == SCH_IO_MGR::SCH_CADSTAR_ARCHIVE
154 || lib->SchLibType() == SCH_IO_MGR::SCH_HTTP )
155
156 {
157 try
158 {
159 LIB_SYMBOL* readOnlySym = PROJECT_SCH::SchSymbolLibTable( &Prj() )->LoadSymbol( aLibId );
160
161 if( readOnlySym && readOnlySym->GetSourceLibId().IsValid() )
162 libId = readOnlySym->GetSourceLibId();
163 }
164 catch( const IO_ERROR& ioe )
165 {
166 wxString msg;
167
168 msg.Printf( _( "Error loading symbol %s from library '%s'." ),
169 aLibId.GetUniStringLibId(), aLibId.GetUniStringLibItemName() );
170 DisplayErrorMessage( this, msg, ioe.What() );
171 return false;
172 }
173 }
174 }
175
177 && GetCurSymbol()->GetLibId() == libId
178 && GetUnit() == aUnit
179 && GetBodyStyle() == aBodyStyle )
180 {
181 return true;
182 }
183
185 {
186 if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
187 [&]() -> bool
188 {
189 return saveCurrentSymbol();
190 } ) )
191 {
192 return false;
193 }
194 }
195
197
198 if( LoadSymbolFromCurrentLib( libId.GetLibItemName(), aUnit, aBodyStyle ) )
199 {
200 m_treePane->GetLibTree()->SelectLibId( libId );
201 m_treePane->GetLibTree()->ExpandLibId( libId );
202
203 m_centerItemOnIdle = libId;
204 Bind( wxEVT_IDLE, &SYMBOL_EDIT_FRAME::centerItemIdleHandler, this );
205 setSymWatcher( &libId );
206
207 return true;
208 }
209
210 return false;
211}
212
213
215{
217 Unbind( wxEVT_IDLE, &SYMBOL_EDIT_FRAME::centerItemIdleHandler, this );
218}
219
220
221bool SYMBOL_EDIT_FRAME::LoadSymbolFromCurrentLib( const wxString& aAliasName, int aUnit,
222 int aBodyStyle )
223{
224 LIB_SYMBOL* alias = nullptr;
225
226 try
227 {
228 alias = PROJECT_SCH::SchSymbolLibTable( &Prj() )->LoadSymbol( GetCurLib(), aAliasName );
229 }
230 catch( const IO_ERROR& ioe )
231 {
232 wxString msg;
233
234 msg.Printf( _( "Error loading symbol %s from library '%s'." ),
235 aAliasName,
236 GetCurLib() );
237 DisplayErrorMessage( this, msg, ioe.What() );
238 return false;
239 }
240
241 if( !alias || !LoadOneLibrarySymbolAux( alias, GetCurLib(), aUnit, aBodyStyle ) )
242 return false;
243
244 // Enable synchronized pin edit mode for symbols with interchangeable units
246
249 SetShowDeMorgan( GetCurSymbol()->Flatten()->HasAlternateBodyStyle() );
250
251 if( aUnit > 0 )
253
254 return true;
255}
256
257
258bool SYMBOL_EDIT_FRAME::LoadOneLibrarySymbolAux( LIB_SYMBOL* aEntry, const wxString& aLibrary,
259 int aUnit, int aBodyStyle )
260{
261 bool rebuildMenuAndToolbar = false;
262
263 if( !aEntry || aLibrary.empty() )
264 return false;
265
266 if( aEntry->GetName().IsEmpty() )
267 {
268 wxLogWarning( "Symbol in library '%s' has empty name field.", aLibrary );
269 return false;
270 }
271
273
274 // Symbols from the schematic are edited in place and not managed by the library manager.
276 {
277 delete m_symbol;
278 m_symbol = nullptr;
279
280 SCH_SCREEN* screen = GetScreen();
281 delete screen;
284 rebuildMenuAndToolbar = true;
285 }
286
287 LIB_SYMBOL* lib_symbol = m_libMgr->GetBufferedSymbol( aEntry->GetName(), aLibrary );
288 wxCHECK( lib_symbol, false );
289
290 m_unit = aUnit > 0 ? aUnit : 1;
291 m_bodyStyle = aBodyStyle > 0 ? aBodyStyle : 1;
292
293 // The buffered screen for the symbol
294 SCH_SCREEN* symbol_screen = m_libMgr->GetScreen( lib_symbol->GetName(), aLibrary );
295
296 SetScreen( symbol_screen );
297 SetCurSymbol( new LIB_SYMBOL( *lib_symbol ), true );
298 SetCurLib( aLibrary );
299
300 if( rebuildMenuAndToolbar )
301 {
304 GetInfoBar()->Dismiss();
305 }
306
307 UpdateTitle();
309 SetShowDeMorgan( GetCurSymbol()->HasAlternateBodyStyle() );
310
312
313 if( !IsSymbolFromSchematic() )
314 {
315 LIB_ID libId = GetCurSymbol()->GetLibId();
316 setSymWatcher( &libId );
317 }
318
319 // Let tools add things to the view if necessary
320 if( m_toolManager )
322
324
325 // Display the document information based on the entry selected just in
326 // case the entry is an alias.
328 Refresh();
329
330 return true;
331}
332
333
335{
336 saveAllLibraries( false );
338}
339
340
341void SYMBOL_EDIT_FRAME::CreateNewSymbol( const wxString& aInheritFrom )
342{
344
345 wxArrayString symbolNames;
346 wxString lib = getTargetLib();
347
348 if( !m_libMgr->LibraryExists( lib ) )
349 {
350 lib = SelectLibraryFromList();
351
352 if( !m_libMgr->LibraryExists( lib ) )
353 return;
354 }
355
356 m_libMgr->GetSymbolNames( lib, symbolNames );
357
358 symbolNames.Sort();
359
360 wxString _inheritSymbolName;
361 wxString _infoMessage;
362 wxString msg;
363
364 // if the symbol being inherited from isn't a root symbol, find its root symbol
365 // and use that symbol instead
366 if( !aInheritFrom.IsEmpty() )
367 {
368 LIB_SYMBOL* inheritFromSymbol = m_libMgr->GetBufferedSymbol( aInheritFrom, lib );
369
370 if( inheritFromSymbol )
371 {
372 _inheritSymbolName = aInheritFrom;
373 _infoMessage = wxString::Format( _( "Deriving from symbol '%s'." ),
374 _inheritSymbolName );
375 }
376 else
377 {
378 _inheritSymbolName = aInheritFrom;
379 }
380 }
381
382 DIALOG_LIB_NEW_SYMBOL dlg( this, _infoMessage, &symbolNames, _inheritSymbolName,
383 [&]( wxString newName )
384 {
385 if( newName.IsEmpty() )
386 {
387 wxMessageBox( _( "Symbol must have a name." ) );
388 return false;
389 }
390
391 if( !lib.empty() && m_libMgr->SymbolExists( newName, lib ) )
392 {
393 msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'." ),
394 newName,
395 lib );
396
397 KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
398 wxOK | wxCANCEL | wxICON_WARNING );
399 errorDlg.SetOKLabel( _( "Overwrite" ) );
400
401 return errorDlg.ShowModal() == wxID_OK;
402 }
403
404 return true;
405 } );
406
407 dlg.SetMinSize( dlg.GetSize() );
408
409 if( dlg.ShowModal() == wxID_CANCEL )
410 return;
411
412 wxString name = dlg.GetName();
413
414 LIB_SYMBOL new_symbol( name ); // do not create symbol on the heap, it will be buffered soon
415
416 wxString parentSymbolName = dlg.GetParentSymbolName();
417
418 if( parentSymbolName.IsEmpty() )
419 {
420 new_symbol.GetReferenceField().SetText( dlg.GetReference() );
421 new_symbol.SetUnitCount( dlg.GetUnitCount() );
422
423 // Initialize new_symbol.m_TextInside member:
424 // if 0, pin text is outside the body (on the pin)
425 // if > 0, pin text is inside the body
426 if( dlg.GetPinNameInside() )
427 {
428 new_symbol.SetPinNameOffset( dlg.GetPinTextPosition() );
429
430 if( new_symbol.GetPinNameOffset() == 0 )
431 new_symbol.SetPinNameOffset( 1 );
432 }
433 else
434 {
435 new_symbol.SetPinNameOffset( 0 );
436 }
437
438 ( dlg.GetPowerSymbol() ) ? new_symbol.SetPower() : new_symbol.SetNormal();
439 new_symbol.SetShowPinNumbers( dlg.GetShowPinNumber() );
440 new_symbol.SetShowPinNames( dlg.GetShowPinName() );
441 new_symbol.LockUnits( !dlg.GetUnitsInterchangeable() );
442 new_symbol.SetExcludedFromBOM( !dlg.GetIncludeInBom() );
443 new_symbol.SetExcludedFromBoard( !dlg.GetIncludeOnBoard() );
444
445 if( dlg.GetUnitCount() < 2 )
446 new_symbol.LockUnits( false );
447
448 new_symbol.SetHasAlternateBodyStyle( dlg.GetAlternateBodyStyle() );
449 }
450 else
451 {
452 LIB_SYMBOL* parent = m_libMgr->GetAlias( parentSymbolName, lib );
453 wxCHECK( parent, /* void */ );
454 new_symbol.SetParent( parent );
455
456 // Inherit the parent mandatory field attributes.
457 for( int id = 0; id < MANDATORY_FIELDS; ++id )
458 {
459 LIB_FIELD* field = new_symbol.GetFieldById( id );
460
461 // the MANDATORY_FIELDS are exactly that in RAM.
462 wxCHECK( field, /* void */ );
463
464 LIB_FIELD* parentField = parent->GetFieldById( id );
465
466 wxCHECK( parentField, /* void */ );
467
468 *field = *parentField;
469
470 switch( id )
471 {
472 case REFERENCE_FIELD:
473 // parent's reference already copied
474 break;
475
476 case VALUE_FIELD:
477 if( parent->IsPower() )
478 field->SetText( name );
479 break;
480
481 case FOOTPRINT_FIELD:
482 case DATASHEET_FIELD:
483 // - footprint might be the same as parent, but might not
484 // - datasheet is most likely different
485 // - probably best to play it safe and copy neither
486 field->SetText( wxEmptyString );
487 break;
488 }
489
490 field->SetParent( &new_symbol );
491 }
492 }
493
494 m_libMgr->UpdateSymbol( &new_symbol, lib );
495 SyncLibraries( false );
496 LoadSymbol( name, lib, 1 );
497
498 // must be called after loadSymbol, that calls SetShowDeMorgan, but
499 // because the symbol is empty,it looks like it has no alternate body
500 // and a derived symbol inherits its parent body.
501 if( !new_symbol.GetParent().lock() )
502 SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
503 else
505}
506
507
509{
510 wxString libName;
511
512 if( IsSymbolTreeShown() )
514
515 if( libName.empty() )
516 {
518 }
519 else if( m_libMgr->IsLibraryReadOnly( libName ) )
520 {
521 wxString msg = wxString::Format( _( "Symbol library '%s' is not writable." ),
522 libName );
523 wxString msg2 = _( "You must save to a different location." );
524
525 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) == wxID_OK )
526 saveLibrary( libName, true );
527 }
528 else
529 {
530 saveLibrary( libName, false );
531 }
532
533 if( IsSymbolTreeShown() )
535
536 UpdateTitle();
537}
538
539
541{
542 wxCHECK( !GetTargetLibId().GetLibNickname().empty(), /* void */ );
543
544 const wxString& libName = GetTargetLibId().GetLibNickname();
545
546 saveLibrary( libName, true );
548}
549
550
552{
554
556}
557
558
559static int ID_MAKE_NEW_LIBRARY = 4173;
560
561
563{
564public:
565 SAVE_AS_DIALOG( SYMBOL_EDIT_FRAME* aParent, const wxString& aSymbolName,
566 const wxString& aLibraryPreselect,
567 std::function<bool( wxString libName, wxString symbolName )> aValidator ) :
568 EDA_LIST_DIALOG( aParent, _( "Save Symbol As" ), false ),
569 m_validator( std::move( aValidator ) )
570 {
571 COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
572 PROJECT_FILE& project = aParent->Prj().GetProjectFile();
574 std::vector<wxString> libNicknames = tbl->GetLogicalLibs();
575 wxArrayString headers;
576 std::vector<wxArrayString> itemsToDisplay;
577
578 headers.Add( _( "Nickname" ) );
579 headers.Add( _( "Description" ) );
580
581 for( const wxString& nickname : libNicknames )
582 {
583 if( alg::contains( project.m_PinnedSymbolLibs, nickname )
584 || alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
585 {
586 wxArrayString item;
587 item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
588 item.Add( tbl->GetDescription( nickname ) );
589 itemsToDisplay.push_back( item );
590 }
591 }
592
593 for( const wxString& nickname : libNicknames )
594 {
595 if( !alg::contains( project.m_PinnedSymbolLibs, nickname )
596 && !alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
597 {
598 wxArrayString item;
599 item.Add( nickname );
600 item.Add( tbl->GetDescription( nickname ) );
601 itemsToDisplay.push_back( item );
602 }
603 }
604
605 initDialog( headers, itemsToDisplay, aLibraryPreselect );
606
607 SetListLabel( _( "Save in library:" ) );
608 SetOKLabel( _( "Save" ) );
609
610 wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
611
612 wxStaticText* label = new wxStaticText( this, wxID_ANY, _( "Name:" ) );
613 bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
614
615 m_symbolNameCtrl = new wxTextCtrl( this, wxID_ANY, aSymbolName );
616 bNameSizer->Add( m_symbolNameCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
617
618 wxButton* newLibraryButton = new wxButton( this, ID_MAKE_NEW_LIBRARY, _( "New Library..." ) );
619 m_ButtonsSizer->Prepend( 80, 20 );
620 m_ButtonsSizer->Prepend( newLibraryButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
621
622 GetSizer()->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
623
624 Bind( wxEVT_BUTTON,
625 [this]( wxCommandEvent& )
626 {
627 EndModal( ID_MAKE_NEW_LIBRARY );
629
630 // Move nameTextCtrl to the head of the tab-order
631 if( GetChildren().DeleteObject( m_symbolNameCtrl ) )
632 GetChildren().Insert( m_symbolNameCtrl );
633
635
637
638 Layout();
639 GetSizer()->Fit( this );
640
641 Centre();
642 }
643
644 wxString GetSymbolName()
645 {
646 wxString symbolName = m_symbolNameCtrl->GetValue();
647 symbolName.Trim( true );
648 symbolName.Trim( false );
649 symbolName.Replace( " ", "_" );
650 return symbolName;
651 }
652
653protected:
655 {
657 }
658
659private:
660 wxTextCtrl* m_symbolNameCtrl;
661 std::function<bool( wxString libName, wxString symbolName )> m_validator;
662};
663
664
666{
667 LIB_SYMBOL* symbol = getTargetSymbol();
668
669 if( !symbol )
670 return;
671
672 LIB_ID old_lib_id = symbol->GetLibId();
673 wxString symbolName = old_lib_id.GetLibItemName();
674 wxString libraryName = old_lib_id.GetLibNickname();
675 bool valueFollowsName = symbol->GetValueField().GetText() == symbolName;
676 wxString msg;
677 bool done = false;
678
679 while( !done )
680 {
681 SAVE_AS_DIALOG dlg( this, symbolName, libraryName,
682 [&]( const wxString& newLib, const wxString& newName )
683 {
684 if( newLib.IsEmpty() )
685 {
686 wxMessageBox( _( "A library must be specified." ) );
687 return false;
688 }
689
690 if( newName.IsEmpty() )
691 {
692 wxMessageBox( _( "Symbol must have a name." ) );
693 return false;
694 }
695
696 if( m_libMgr->SymbolExists( newName, newLib ) )
697 {
698 msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'." ),
699 newName, newLib );
700
701 KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
702 wxOK | wxCANCEL | wxICON_WARNING );
703 errorDlg.SetOKLabel( _( "Overwrite" ) );
704
705 return errorDlg.ShowModal() == wxID_OK;
706 }
707
708 // @todo Either check the selecteced library to see if the parent symbol name
709 // is in the new library and/or copy the parent symbol as well. This is
710 // the lazy solution to ensure derived symbols do not get orphaned.
711 if( symbol->IsAlias() && newLib != old_lib_id.GetLibNickname() )
712 {
713 DisplayError( this, _( "Derived symbols must be saved in the same library "
714 "as their parent symbol." ) );
715 return false;
716 }
717
718 return true;
719 } );
720
721 int ret = dlg.ShowModal();
722
723 if( ret == wxID_CANCEL )
724 {
725 return;
726 }
727 else if( ret == wxID_OK )
728 {
729 symbolName = dlg.GetSymbolName();
730 libraryName = dlg.GetTextSelection();
731 done = true;
732 }
733 else if( ret == ID_MAKE_NEW_LIBRARY )
734 {
735 wxFileName newLibrary( AddLibraryFile( true ) );
736 libraryName = newLibrary.GetName();
737 }
738 }
739
740 LIB_SYMBOL new_symbol( *symbol );
741 new_symbol.SetName( symbolName );
742
743 if( valueFollowsName )
744 new_symbol.GetValueField().SetText( symbolName );
745
746 m_libMgr->UpdateSymbol( &new_symbol, libraryName );
747 SyncLibraries( false );
748}
749
750
752{
753 wxCHECK( m_symbol, /* void */ );
754
755 wxString lib = GetCurLib();
756
757 if( !lib.IsEmpty() && aOldName && *aOldName != m_symbol->GetName() )
758 {
759 // Test the current library for name conflicts
760 if( m_libMgr->SymbolExists( m_symbol->GetName(), lib ) )
761 {
762 wxString msg = wxString::Format( _( "Symbol name '%s' already in use." ),
764
765 DisplayErrorMessage( this, msg );
766 m_symbol->SetName( *aOldName );
767 }
768 else
769 {
770 m_libMgr->UpdateSymbolAfterRename( m_symbol, *aOldName, lib );
771 }
772
773 // Reselect the renamed symbol
775 }
776
778 SetShowDeMorgan( GetCurSymbol()->Flatten()->HasAlternateBodyStyle() );
779 UpdateTitle();
780
781 // N.B. The view needs to be rebuilt first as the Symbol Properties change may invalidate
782 // the view pointers by rebuilting the field table
783 RebuildView();
785
786 OnModify();
787}
788
789
791{
792 std::vector<LIB_ID> toDelete = GetSelectedLibIds();
793
794 if( toDelete.empty() )
795 toDelete.emplace_back( GetTargetLibId() );
796
797 for( LIB_ID& libId : toDelete )
798 {
799 if( m_libMgr->IsSymbolModified( libId.GetLibItemName(), libId.GetLibNickname() )
800 && !IsOK( this, wxString::Format( _( "The symbol '%s' has been modified.\n"
801 "Do you want to remove it from the library?" ),
802 libId.GetUniStringLibItemName() ) ) )
803 {
804 continue;
805 }
806
807 if( m_libMgr->HasDerivedSymbols( libId.GetLibItemName(), libId.GetLibNickname() ) )
808 {
809 wxString msg;
810
811 msg.Printf(
812 _( "The symbol %s is used to derive other symbols.\n"
813 "Deleting this symbol will delete all of the symbols derived from it.\n\n"
814 "Do you wish to delete this symbol and all of its derivatives?" ),
815 libId.GetLibItemName().wx_str() );
816
817 wxMessageDialog::ButtonLabel yesButtonLabel( _( "Delete Symbol" ) );
818 wxMessageDialog::ButtonLabel noButtonLabel( _( "Keep Symbol" ) );
819
820 wxMessageDialog dlg( this, msg, _( "Warning" ),
821 wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTER );
822 dlg.SetYesNoLabels( yesButtonLabel, noButtonLabel );
823
824 if( dlg.ShowModal() == wxID_NO )
825 continue;
826 }
827
828 if( IsCurrentSymbol( libId ) )
829 emptyScreen();
830
831 m_libMgr->RemoveSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
832 }
833
835}
836
837
839{
840 std::vector<LIB_ID> symbols;
841
842 if( GetTreeLIBIDs( symbols ) == 0 )
843 return;
844
845 STRING_FORMATTER formatter;
846
847 for( LIB_ID& libId : symbols )
848 {
849 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(),
850 libId.GetLibNickname() );
851
852 if( !symbol )
853 continue;
854
855 std::unique_ptr<LIB_SYMBOL> tmp = symbol->Flatten();
856 SCH_IO_KICAD_SEXPR::FormatLibSymbol( tmp.get(), formatter );
857 }
858
859 wxLogNull doNotLog; // disable logging of failed clipboard actions
860
861 auto clipboard = wxTheClipboard;
862 wxClipboardLocker clipboardLock( clipboard );
863
864 if( !clipboardLock || !clipboard->IsOpened() )
865 return;
866
867 auto data = new wxTextDataObject( wxString( formatter.GetString().c_str(), wxConvUTF8 ) );
868 clipboard->SetData( data );
869
870 clipboard->Flush();
871}
872
873
874void SYMBOL_EDIT_FRAME::DuplicateSymbol( bool aFromClipboard )
875{
876 LIB_ID libId = GetTargetLibId();
877 wxString lib = libId.GetLibNickname();
878
879 if( !m_libMgr->LibraryExists( lib ) )
880 return;
881
882 std::vector<LIB_SYMBOL*> newSymbols;
883
884 if( aFromClipboard )
885 {
886 std::string clipboardData = m_toolManager->GetClipboardUTF8();
887
888 try
889 {
890 newSymbols = SCH_IO_KICAD_SEXPR::ParseLibSymbols( clipboardData, "Clipboard" );
891 }
892 catch( IO_ERROR& e )
893 {
894 wxLogMessage( wxS( "Can not paste: %s" ), e.Problem() );
895 }
896 }
897 else
898 {
899 LIB_SYMBOL* srcSymbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(), lib );
900
901 wxCHECK( srcSymbol, /* void */ );
902
903 newSymbols.emplace_back( new LIB_SYMBOL( *srcSymbol ) );
904
905 // Derive from same parent.
906 if( srcSymbol->IsAlias() )
907 {
908 std::shared_ptr< LIB_SYMBOL > srcParent = srcSymbol->GetParent().lock();
909
910 wxCHECK( srcParent, /* void */ );
911
912 newSymbols.back()->SetParent( srcParent.get() );
913 }
914 }
915
916 if( newSymbols.empty() )
917 return;
918
919 for( LIB_SYMBOL* symbol : newSymbols )
920 {
921 ensureUniqueName( symbol, lib );
922 m_libMgr->UpdateSymbol( symbol, lib );
923
924 LoadOneLibrarySymbolAux( symbol, lib, GetUnit(), GetBodyStyle() );
925 }
926
927 SyncLibraries( false );
928 m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, newSymbols[0]->GetName() ) );
929
930 for( LIB_SYMBOL* symbol : newSymbols )
931 delete symbol;
932}
933
934
935void SYMBOL_EDIT_FRAME::ensureUniqueName( LIB_SYMBOL* aSymbol, const wxString& aLibrary )
936{
937 wxCHECK( aSymbol, /* void */ );
938
939 int i = 1;
940 wxString newName = aSymbol->GetName();
941
942 // Append a number to the name until the name is unique in the library.
943 while( m_libMgr->SymbolExists( newName, aLibrary ) )
944 newName.Printf( "%s_%d", aSymbol->GetName(), i++ );
945
946 aSymbol->SetName( newName );
947}
948
949
950void SYMBOL_EDIT_FRAME::Revert( bool aConfirm )
951{
952 LIB_ID libId = GetTargetLibId();
953 const wxString& libName = libId.GetLibNickname();
954
955 // Empty if this is the library itself that is selected.
956 const wxString& symbolName = libId.GetLibItemName();
957
958 wxString msg = wxString::Format( _( "Revert '%s' to last version saved?" ),
959 symbolName.IsEmpty() ? libName : symbolName );
960
961 if( aConfirm && !ConfirmRevertDialog( this, msg ) )
962 return;
963
964 bool reload_currentSymbol = false;
965 wxString curr_symbolName = symbolName;
966
967 if( GetCurSymbol() )
968 {
969 // the library itself is reverted: the current symbol will be reloaded only if it is
970 // owned by this library
971 if( symbolName.IsEmpty() )
972 {
973 LIB_ID curr_libId = GetCurSymbol()->GetLibId();
974 reload_currentSymbol = libName == curr_libId.GetLibNickname();
975
976 if( reload_currentSymbol )
977 curr_symbolName = curr_libId.GetUniStringLibItemName();
978 }
979 else
980 {
981 reload_currentSymbol = IsCurrentSymbol( libId );
982 }
983 }
984
985 int unit = m_unit;
986
987 if( reload_currentSymbol )
988 emptyScreen();
989
990 if( symbolName.IsEmpty() )
991 {
992 m_libMgr->RevertLibrary( libName );
993 }
994 else
995 {
996 libId = m_libMgr->RevertSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
997
998 m_treePane->GetLibTree()->SelectLibId( libId );
1000 }
1001
1002 if( reload_currentSymbol && m_libMgr->SymbolExists( curr_symbolName, libName ) )
1003 LoadSymbol( curr_symbolName, libName, unit );
1004
1005 m_treePane->Refresh();
1006}
1007
1008
1010{
1011 wxCHECK_RET( m_libMgr, "Library manager object not created." );
1012
1013 Revert( false );
1015}
1016
1017
1018void SYMBOL_EDIT_FRAME::LoadSymbol( const wxString& aAlias, const wxString& aLibrary, int aUnit )
1019{
1021 {
1022 if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
1023 [&]() -> bool
1024 {
1025 return saveCurrentSymbol();
1026 } ) )
1027 {
1028 return;
1029 }
1030 }
1031
1032 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aAlias, aLibrary );
1033
1034 if( !symbol )
1035 {
1036 DisplayError( this, wxString::Format( _( "Symbol %s not found in library '%s'." ),
1037 aAlias,
1038 aLibrary ) );
1040 return;
1041 }
1042
1043 // Optimize default edit options for this symbol
1044 // Usually if units are locked, graphic items are specific to each unit
1045 // and if units are interchangeable, graphic items are common to units
1047 tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
1048
1049 LoadOneLibrarySymbolAux( symbol, aLibrary, aUnit, 0 );
1050}
1051
1052
1053bool SYMBOL_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
1054{
1055 wxFileName fn;
1056 wxString msg;
1057 SYMBOL_SAVEAS_TYPE type = SYMBOL_SAVEAS_TYPE::NORMAL_SAVE_AS;
1058 SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::SCH_FILE_T::SCH_KICAD;
1059 PROJECT& prj = Prj();
1060
1062
1063 if( !aNewFile && ( aLibrary.empty() || !PROJECT_SCH::SchSymbolLibTable( &prj )->HasLibrary( aLibrary ) ) )
1064 {
1065 ShowInfoBarError( _( "No library specified." ) );
1066 return false;
1067 }
1068
1069 if( aNewFile )
1070 {
1071 SEARCH_STACK* search = PROJECT_SCH::SchSearchS( &prj );
1072
1073 // Get a new name for the library
1074 wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
1075
1076 if( !default_path )
1077 default_path = search->LastVisitedPath();
1078
1079 fn.SetName( aLibrary );
1081
1082 wxString wildcards = FILEEXT::KiCadSymbolLibFileWildcard();
1083
1084 wxFileDialog dlg( this, wxString::Format( _( "Save Library '%s' As..." ), aLibrary ),
1085 default_path, fn.GetFullName(), wildcards,
1086 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1087
1088 SYMBOL_FILEDLG_SAVE_AS saveAsHook( type );
1089 dlg.SetCustomizeHook( saveAsHook );
1090
1091 if( dlg.ShowModal() == wxID_CANCEL )
1092 return false;
1093
1094 fn = dlg.GetPath();
1095
1096 prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
1097
1098 if( fn.GetExt().IsEmpty() )
1100
1101 type = saveAsHook.GetOption();
1102 }
1103 else
1104 {
1105 fn = PROJECT_SCH::SchSymbolLibTable( &prj )->GetFullURI( aLibrary );
1107
1108 if( fileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
1109 fileType = SCH_IO_MGR::SCH_KICAD;
1110 }
1111
1112 // Verify the user has write privileges before attempting to save the library file.
1113 if( !aNewFile && m_libMgr->IsLibraryReadOnly( aLibrary ) )
1114 return false;
1115
1116 ClearMsgPanel();
1117
1118 // Copy .kicad_symb file to .bak.
1119 if( !backupFile( fn, "bak" ) )
1120 return false;
1121
1122 if( !m_libMgr->SaveLibrary( aLibrary, fn.GetFullPath(), fileType ) )
1123 {
1124 msg.Printf( _( "Failed to save changes to symbol library file '%s'." ),
1125 fn.GetFullPath() );
1126 DisplayErrorMessage( this, _( "Error Saving Library" ), msg );
1127 return false;
1128 }
1129
1130 if( !aNewFile )
1131 {
1132 m_libMgr->ClearLibraryModified( aLibrary );
1133
1134 // Update the library modification time so that we don't reload based on the watcher
1135 if( aLibrary == getTargetLib() )
1136 SetSymModificationTime( fn.GetModificationTime() );
1137 }
1138 else
1139 {
1140 bool resyncLibTree = false;
1141 wxString originalLibNickname = getTargetLib();
1142 wxString forceRefresh;
1143
1144 switch( type )
1145 {
1146 case SYMBOL_SAVEAS_TYPE::REPLACE_TABLE_ENTRY:
1147 resyncLibTree = replaceLibTableEntry( originalLibNickname, fn.GetFullPath() );
1148 forceRefresh = originalLibNickname;
1149 break;
1150
1151 case SYMBOL_SAVEAS_TYPE::ADD_GLOBAL_TABLE_ENTRY:
1152 resyncLibTree = addLibTableEntry( fn.GetFullPath() );
1153 break;
1154
1155 case SYMBOL_SAVEAS_TYPE::ADD_PROJECT_TABLE_ENTRY:
1156 resyncLibTree = addLibTableEntry( fn.GetFullPath(), PROJECT_LIB_TABLE );
1157 break;
1158
1159 default:
1160 break;
1161 }
1162
1163 if( resyncLibTree )
1164 {
1166 SyncLibraries( true, false, forceRefresh );
1168 }
1169 }
1170
1171 ClearMsgPanel();
1172 msg.Printf( _( "Symbol library file '%s' saved." ), fn.GetFullPath() );
1174
1175 return true;
1176}
1177
1178
1179bool SYMBOL_EDIT_FRAME::saveAllLibraries( bool aRequireConfirmation )
1180{
1181 wxString msg, msg2;
1182 bool doSave = true;
1183 int dirtyCount = 0;
1184 bool applyToAll = false;
1185 bool retv = true;
1186
1187 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1188 {
1189 if( m_libMgr->IsLibraryModified( libNickname ) )
1190 dirtyCount++;
1191 }
1192
1193 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1194 {
1195 if( m_libMgr->IsLibraryModified( libNickname ) )
1196 {
1197 if( aRequireConfirmation && !applyToAll )
1198 {
1199 msg.Printf( _( "Save changes to '%s' before closing?" ), libNickname );
1200
1201 switch( UnsavedChangesDialog( this, msg, dirtyCount > 1 ? &applyToAll : nullptr ) )
1202 {
1203 case wxID_YES: doSave = true; break;
1204 case wxID_NO: doSave = false; break;
1205 default:
1206 case wxID_CANCEL: return false;
1207 }
1208 }
1209
1210 if( doSave )
1211 {
1212 // If saving under existing name fails then do a Save As..., and if that
1213 // fails then cancel close action.
1214 if( m_libMgr->IsLibraryReadOnly( libNickname ) )
1215 {
1216 msg.Printf( _( "Symbol library '%s' is not writable." ), libNickname );
1217 msg2 = _( "You must save to a different location." );
1218
1219 if( dirtyCount == 1 )
1220 {
1221 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) != wxID_OK )
1222 {
1223 retv = false;
1224 continue;
1225 }
1226 }
1227 else
1228 {
1229 m_infoBar->Dismiss();
1230 m_infoBar->ShowMessageFor( msg + wxS( " " ) + msg2,
1231 2000, wxICON_EXCLAMATION );
1232
1233 while( m_infoBar->IsShownOnScreen() )
1234 wxSafeYield();
1235
1236 retv = false;
1237 continue;
1238 }
1239 }
1240 else if( saveLibrary( libNickname, false ) )
1241 {
1242 continue;
1243 }
1244
1245 if( !saveLibrary( libNickname, true ) )
1246 retv = false;
1247 }
1248 }
1249 }
1250
1251 UpdateTitle();
1252 return retv;
1253}
1254
1255
1257{
1259
1260 if( !m_symbol )
1261 return;
1262
1263 wxString msg = m_symbol->GetName();
1264
1265 AppendMsgPanel( _( "Name" ), UnescapeString( msg ), 8 );
1266
1267 if( m_symbol->IsAlias() )
1268 {
1269 LIB_SYMBOL_SPTR parent = m_symbol->GetParent().lock();
1270
1271 msg = parent ? parent->GetName() : _( "Undefined!" );
1272 AppendMsgPanel( _( "Parent" ), UnescapeString( msg ), 8 );
1273 }
1274
1275 static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
1276 msg = UnitLetter[m_unit];
1277
1278 AppendMsgPanel( _( "Unit" ), msg, 8 );
1279
1281 msg = _( "Alternate" );
1283 msg = _( "Standard" );
1284 else
1285 wxT( "?" );
1286
1287 AppendMsgPanel( _( "Body" ), msg, 8 );
1288
1289 if( m_symbol->IsPower() )
1290 msg = _( "Power Symbol" );
1291 else
1292 msg = _( "Symbol" );
1293
1294 AppendMsgPanel( _( "Type" ), msg, 8 );
1295 AppendMsgPanel( _( "Description" ), m_symbol->GetDescription(), 8 );
1296 AppendMsgPanel( _( "Keywords" ), m_symbol->GetKeyWords() );
1297 AppendMsgPanel( _( "Datasheet" ), m_symbol->GetDatasheetField().GetText() );
1298}
const char * name
Definition: DXF_plotter.cpp:57
static TOOL_ACTION cancelInteractive
Definition: actions.h:63
static TOOL_ACTION zoomFitScreen
Definition: actions.h:101
void SetContentModified(bool aModified=true)
Definition: base_screen.h:59
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:97
void SetupStandardButtons(std::map< int, wxString > aLabels={})
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 initDialog(const wxArrayString &aItemHeaders, const std::vector< wxArrayString > &aItemList, const wxString &aPreselectText)
wxString GetTextSelection(int aColumn=0)
Return the selected text from aColumn in the wxListCtrl in the dialog.
void SetListLabel(const wxString &aLabel)
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:95
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:183
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
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
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition: view.cpp:1501
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:432
Field object used in symbol libraries.
Definition: lib_field.h:62
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 wxString GetUniStringLibNickname() const
Definition: lib_id.h:88
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
@ BASE
Definition: lib_item.h:79
@ DEMORGAN
Definition: lib_item.h:80
Define a library symbol object.
Definition: lib_symbol.h:99
bool HasAlternateBodyStyle() const
Test if symbol has more than one body conversion type (DeMorgan).
void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: lib_symbol.h:632
bool IsMulti() const
Definition: lib_symbol.h:600
int GetPinNameOffset() const
Definition: lib_symbol.h:625
wxString GetKeyWords() const
Definition: lib_symbol.h:191
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:286
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:624
LIB_ID GetSourceLibId() const
Definition: lib_symbol.h:166
bool IsAlias() const
Definition: lib_symbol.h:215
bool IsPower() const
Definition: lib_symbol.cpp:704
void SetPower()
Definition: lib_symbol.cpp:718
void LockUnits(bool aLockUnits)
Set interchangeable the property for symbol units.
Definition: lib_symbol.h:280
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: lib_symbol.h:640
LIB_ID GetLibId() const override
Definition: lib_symbol.h:163
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:596
wxString GetName() const override
Definition: lib_symbol.h:160
void SetExcludedFromBOM(bool aExcludeFromBOM)
Set or clear the exclude from schematic bill of materials flag.
Definition: lib_symbol.h:656
void SetExcludedFromBoard(bool aExcludeFromBoard)
Set or clear exclude from board netlist flag.
Definition: lib_symbol.h:664
LIB_FIELD & GetValueField()
Return reference to the value field.
wxString GetDescription() override
Definition: lib_symbol.h:178
void SetHasAlternateBodyStyle(bool aHasAlternate, bool aDuplicatePins=true)
Set or clear the alternate body style (DeMorgan) for the symbol.
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:605
LIB_FIELD & GetDatasheetField()
Return reference to the datasheet field.
LIB_SYMBOL_REF & GetParent()
Definition: lib_symbol.h:127
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:589
void SetNormal()
Definition: lib_symbol.cpp:746
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.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
wxString GetFullURI(const wxString &aLibNickname, bool aExpandEnvVars=true) const
Return the full URI of the library mapped to aLibNickname.
static const wxString GetPinningSymbol()
void RefreshLibTree()
Refreshes the tree (mainly to update highlighting and asterisking)
Definition: lib_tree.cpp:397
void CenterLibId(const LIB_ID &aLibId)
Ensure that an item is visible (preferably centered).
Definition: lib_tree.cpp:320
void SelectLibId(const LIB_ID &aLibId)
Select an item in the tree widget.
Definition: lib_tree.cpp:314
void ExpandLibId(const LIB_ID &aLibId)
Expand and item i the tree widget.
Definition: lib_tree.cpp:332
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:70
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
static SEARCH_STACK * SchSearchS(PROJECT *aProject)
Accessor for Eeschema search stack.
Definition: project_sch.cpp:41
Container for project specific data.
Definition: project.h:62
@ SCH_LIB_PATH
Definition: project.h:182
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:166
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:269
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:280
wxString GetSymbolName()
bool TransferDataFromWindow() override
wxTextCtrl * m_symbolNameCtrl
SAVE_AS_DIALOG(SYMBOL_EDIT_FRAME *aParent, const wxString &aSymbolName, const wxString &aLibraryPreselect, std::function< bool(wxString libName, wxString symbolName)> aValidator)
std::function< bool(wxString libName, wxString symbolName)> m_validator
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
wxString SelectLibraryFromList()
Display a list of loaded libraries and allows the user to select a library.
void SetSymModificationTime(const wxDateTime &aTime)
Set the modification time of the symbol library table file.
void setSymWatcher(const LIB_ID *aSymbol)
Creates (or removes) a watcher on the specified symbol library.
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
Schematic editor (Eeschema) main window.
void SaveSymbolToSchematic(const LIB_SYMBOL &aSymbol, const KIID &aSchematicSymbolUUID)
Update a schematic symbol from a LIB_SYMBOL.
static void FormatLibSymbol(LIB_SYMBOL *aPart, OUTPUTFORMATTER &aFormatter)
static std::vector< LIB_SYMBOL * > ParseLibSymbols(std::string &aSymbolText, std::string aSource, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
static SCH_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
Return a plugin type given a symbol library using the file extension of aLibPath.
Definition: sch_io_mgr.cpp:139
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:433
const std::string & GetString()
Definition: richio.h:456
SYMBOL_EDITOR_DRAWING_TOOLS.
The symbol library editor main window.
void ClearMsgPanel() override
Clear all messages from the message panel.
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.
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_ID GetTreeLIBID(int *aUnit=nullptr) const
Return the LIB_ID of the library or symbol selected in the symbol tree.
LIB_SYMBOL_LIBRARY_MANAGER * m_libMgr
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)
int GetBodyStyle() const
bool IsSymbolTreeShown() const
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 SaveSymbolCopyAs()
Save the currently selected symbol to a new name and/or location.
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.
int m_bodyStyle
Flag if the symbol being edited was loaded directly from a schematic.
bool saveAllLibraries(bool aRequireConfirmation)
Save the current symbol.
void UpdateMsgPanel() override
Redraw the message panel.
void CreateNewSymbol(const wxString &newName=wxEmptyString)
Create a new symbol in the selected library.
wxString SetCurLib(const wxString &aLibNickname)
Set the current library nickname and returns the old library nickname.
void UpdateTitle()
Update the main window title bar with the current library name and read only status of the library.
void ReCreateHToolbar() override
SYMBOL_TREE_PANE * m_treePane
bool LoadOneLibrarySymbolAux(LIB_SYMBOL *aLibEntry, const wxString &aLibrary, int aUnit, int aBodyStyle)
Create a copy of aLibEntry into memory.
bool LoadSymbolFromCurrentLib(const wxString &aAliasName, int aUnit=0, int aBodyStyle=0)
Load a symbol from the current active library, optionally setting the selected unit and convert.
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
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.
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.
void GetSymbolNames(const wxString &aLibName, wxArrayString &aSymbolNames, SYMBOL_NAME_FILTER aFilter=SYMBOL_NAME_FILTER::ALL)
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.
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_IO object i...
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
LIB_TREE * GetLibTree() const
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:167
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition: tool_base.h:80
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:145
std::string GetClipboardUTF8() const
Return the information currently stored in the system clipboard.
void ResetTools(TOOL_BASE::RESET_REASON aReason)
Reset all tools (i.e.
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:140
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: wx_infobar.cpp:187
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:360
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:305
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)
static int ID_MAKE_NEW_LIBRARY
@ FRAME_SCH
Definition: frame_type.h:34
static const std::string KiCadSymbolLibFileExtension
static wxString KiCadSymbolLibFileWildcard()
PROJECT & Prj()
Definition: kicad.cpp:591
KIWAY Kiway
std::shared_ptr< LIB_SYMBOL > LIB_SYMBOL_SPTR
shared pointer to LIB_SYMBOL
Definition: lib_symbol.h:45
@ ALL
All except INITIAL_ADD.
Definition: view_item.h:58
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
STL namespace.
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:119
MODEL3D_FORMAT_TYPE fileType(const char *aFileName)
wxString UnescapeString(const wxString &aSource)
std::vector< wxString > pinned_symbol_libs
static int ID_MAKE_NEW_LIBRARY
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 5 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.