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