KiCad PCB EDA Suite
Loading...
Searching...
No Matches
symbol_editor_control.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 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
26
27#include <advanced_config.h>
29#include <confirm.h>
31#include <gestfich.h> // To open with a text editor
32#include <kidialog.h>
33#include <kiway.h>
34#include <launch_ext.h> // To default when file manager setting is empty
37#include <pgm_base.h>
38#include <sch_painter.h>
39#include <string_utils.h>
42#include <symbol_viewer_frame.h>
44#include <tool/tool_manager.h>
45#include <tools/sch_actions.h>
47
48#include <wx/filedlg.h>
49
50
52{
56
58 {
59 LIBRARY_EDITOR_CONTROL* libraryTreeTool = m_toolMgr->GetTool<LIBRARY_EDITOR_CONTROL>();
60 CONDITIONAL_MENU& ctxMenu = m_menu->GetMenu();
61
62 auto libSelectedCondition =
63 [this]( const SELECTION& aSel )
64 {
66 {
67 LIB_ID sel = editFrame->GetTreeLIBID();
68 return !sel.GetLibNickname().empty() && sel.GetLibItemName().empty();
69 }
70
71 return false;
72 };
73
74 // The libInferredCondition allows you to do things like New Symbol and Paste with a
75 // symbol selected (in other words, when we know the library context even if the library
76 // itself isn't selected.
77 auto libInferredCondition =
78 [this]( const SELECTION& aSel )
79 {
81 {
82 LIB_ID sel = editFrame->GetTreeLIBID();
83 return !sel.GetLibNickname().empty();
84 }
85
86 return false;
87 };
88
89 auto symbolSelectedCondition =
90 [this]( const SELECTION& aSel )
91 {
93 {
94 LIB_ID sel = editFrame->GetTargetLibId();
95 return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
96 }
97
98 return false;
99 };
100
101 auto derivedSymbolSelectedCondition =
102 [this]( const SELECTION& aSel )
103 {
105 {
106 LIB_ID sel = editFrame->GetTargetLibId();
107
108 if( sel.GetLibNickname().empty() || sel.GetLibItemName().empty() )
109 return false;
110
111 LIB_SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
112 const LIB_SYMBOL* sym = libMgr.GetSymbol( sel.GetLibItemName(), sel.GetLibNickname() );
113
114 return sym && sym->IsDerived();
115 }
116
117 return false;
118 };
119
120 auto relatedSymbolSelectedCondition =
121 [this]( const SELECTION& aSel )
122 {
124 {
125 LIB_ID sel = editFrame->GetTargetLibId();
126
127 if( sel.GetLibNickname().empty() || sel.GetLibItemName().empty() )
128 return false;
129
130 LIB_SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
131 const LIB_SYMBOL* sym = libMgr.GetSymbol( sel.GetLibItemName(), sel.GetLibNickname() );
132 wxArrayString derived;
133
134 libMgr.GetDerivedSymbolNames( sel.GetLibItemName(), sel.GetLibNickname(), derived );
135
136 return ( sym && sym->IsDerived() ) || !derived.IsEmpty();
137 }
138
139 return false;
140 };
141
142 auto multiSymbolSelectedCondition =
143 [this]( const SELECTION& aSel )
144 {
146
147 if( editFrame && editFrame->GetTreeSelectionCount() > 1 )
148 {
149 for( LIB_ID& sel : editFrame->GetSelectedLibIds() )
150 {
151 if( !sel.IsValid() )
152 return false;
153 }
154
155 return true;
156 }
157
158 return false;
159 };
160/* not used, yet
161 auto multiLibrarySelectedCondition =
162 [this]( const SELECTION& aSel )
163 {
164 SYMBOL_EDIT_FRAME* editFrame = getEditFrame<SYMBOL_EDIT_FRAME>();
165
166 if( editFrame && editFrame->GetTreeSelectionCount() > 1 )
167 {
168 for( LIB_ID& sel : editFrame->GetSelectedLibIds() )
169 {
170 if( sel.IsValid() )
171 return false;
172 }
173
174 return true;
175 }
176
177 return false;
178 };
179*/
180 auto canOpenExternally =
181 [this]( const SELECTION& aSel )
182 {
183 // The option is shown if the lib has no current edits
185 {
186 LIB_SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
187 wxString libName = editFrame->GetTargetLibId().GetLibNickname();
188 return !libMgr.IsLibraryModified( libName );
189 }
190
191 return false;
192 };
193
194
195// clang-format off
196 ctxMenu.AddItem( SCH_ACTIONS::newSymbol, libInferredCondition, 10 );
197 ctxMenu.AddItem( SCH_ACTIONS::deriveFromExistingSymbol, symbolSelectedCondition, 10 );
198
199 ctxMenu.AddSeparator( 10 );
200 ctxMenu.AddItem( ACTIONS::save, symbolSelectedCondition || libInferredCondition, 10 );
201 ctxMenu.AddItem( SCH_ACTIONS::saveLibraryAs, libSelectedCondition, 10 );
202 ctxMenu.AddItem( SCH_ACTIONS::saveSymbolAs, symbolSelectedCondition, 10 );
203 ctxMenu.AddItem( SCH_ACTIONS::saveSymbolCopyAs, symbolSelectedCondition, 10 );
204 ctxMenu.AddItem( ACTIONS::revert, symbolSelectedCondition || libInferredCondition, 10 );
205
206 ctxMenu.AddSeparator( 20 );
207 ctxMenu.AddItem( SCH_ACTIONS::importSymbol, libInferredCondition, 20 );
208 ctxMenu.AddItem( SCH_ACTIONS::exportSymbol, symbolSelectedCondition, 20 );
209
210 ctxMenu.AddSeparator( 100 );
211 ctxMenu.AddItem( SCH_ACTIONS::cutSymbol, symbolSelectedCondition || multiSymbolSelectedCondition, 100 );
212 ctxMenu.AddItem( SCH_ACTIONS::copySymbol, symbolSelectedCondition || multiSymbolSelectedCondition, 100 );
213 ctxMenu.AddItem( SCH_ACTIONS::pasteSymbol, libInferredCondition, 100 );
214 ctxMenu.AddItem( SCH_ACTIONS::duplicateSymbol, symbolSelectedCondition, 100 );
215 ctxMenu.AddItem( SCH_ACTIONS::deleteSymbol, symbolSelectedCondition || multiSymbolSelectedCondition, 100 );
216
217 ctxMenu.AddSeparator( 120 );
218 ctxMenu.AddItem( SCH_ACTIONS::renameSymbol, symbolSelectedCondition, 120 );
219 ctxMenu.AddItem( SCH_ACTIONS::symbolProperties, symbolSelectedCondition, 120 );
220 ctxMenu.AddItem( SCH_ACTIONS::flattenSymbol, derivedSymbolSelectedCondition, 120 );
221
222 if( ADVANCED_CFG::GetCfg().m_EnableLibWithText || ADVANCED_CFG::GetCfg().m_EnableLibDir )
223 ctxMenu.AddSeparator( 200 );
224
225 if( ADVANCED_CFG::GetCfg().m_EnableLibWithText )
226 ctxMenu.AddItem( ACTIONS::openWithTextEditor, canOpenExternally && ( symbolSelectedCondition || libSelectedCondition ), 200 );
227
228 if( ADVANCED_CFG::GetCfg().m_EnableLibDir )
229 ctxMenu.AddItem( ACTIONS::openDirectory, canOpenExternally && ( symbolSelectedCondition || libSelectedCondition ), 200 );
230
231 ctxMenu.AddSeparator( 300 );
232 ctxMenu.AddItem( SCH_ACTIONS::showLibFieldsTable, libInferredCondition, 300 );
233 ctxMenu.AddItem( SCH_ACTIONS::showRelatedLibFieldsTable, relatedSymbolSelectedCondition, 300 );
234
235 libraryTreeTool->AddContextMenuItems( &ctxMenu );
236 }
237// clang-format on
238
239 return true;
240}
241
242
244{
245 bool createNew = aEvent.IsAction( &ACTIONS::newLibrary );
246
247 if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
248 static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->AddLibraryFile( createNew );
249
250 return 0;
251}
252
253
255{
256 wxString libFile = *aEvent.Parameter<wxString*>();
257
258 if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
259 static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->DdAddLibrary( libFile );
260
261 return 0;
262}
263
264
266{
267 if( !m_isSymbolEditor )
268 return 0;
269
271 int unit = 0;
272 LIB_ID partId = editFrame->GetTreeLIBID( &unit );
273
274 editFrame->LoadSymbol( partId.GetLibItemName(), partId.GetLibNickname(), unit );
275 return 0;
276}
277
278
280{
282 const LIB_SYMBOL* symbol = editFrame->GetCurSymbol();
283
284 if( !symbol || !editFrame->IsSymbolFromSchematic() )
285 {
286 wxBell();
287 return 0;
288 }
289
290 const LIB_ID& libId = symbol->GetLibId();
291
292 if( editFrame->LoadSymbol( libId, editFrame->GetUnit(), editFrame->GetBodyStyle() ) )
293 {
294 if( !editFrame->IsLibraryTreeShown() )
295 editFrame->ToggleLibraryTree();
296 }
297 else
298 {
299 const wxString libName = libId.GetLibNickname();
300 const wxString symbolName = libId.GetLibItemName();
301
302 DisplayError( editFrame,
303 wxString::Format( _( "Failed to load symbol %s from "
304 "library %s." ),
305 UnescapeString( symbolName ), UnescapeString( libName ) ) );
306 }
307 return 0;
308}
309
310
312{
313 if( !m_isSymbolEditor )
314 return 0;
315
317 LIB_ID target = editFrame->GetTargetLibId();
318 const wxString& libName = target.GetLibNickname();
319 wxString msg;
320
321 if( libName.IsEmpty() )
322 {
323 msg.Printf( _( "No symbol library selected." ) );
324 m_frame->ShowInfoBarError( msg );
325 return 0;
326 }
327
328 if( !editFrame->GetLibManager().LibraryExists( libName ) )
329 {
330 msg.Printf( _( "Symbol library '%s' not found." ), libName );
331 m_frame->ShowInfoBarError( msg );
332 return 0;
333 }
334
335 if( editFrame->GetLibManager().IsLibraryReadOnly( libName ) )
336 {
337 msg.Printf( _( "Symbol library '%s' is not writable." ), libName );
338 m_frame->ShowInfoBarError( msg );
339 return 0;
340 }
341
342 if( aEvent.IsAction( &SCH_ACTIONS::newSymbol ) )
343 editFrame->CreateNewSymbol();
345 editFrame->CreateNewSymbol( target.GetLibItemName() );
346 else if( aEvent.IsAction( &SCH_ACTIONS::importSymbol ) )
347 editFrame->ImportSymbol();
348
349 return 0;
350}
351
352
354{
355 if( !m_isSymbolEditor )
356 return 0;
357
359
360 if( aEvt.IsAction( &SCH_ACTIONS::save ) )
361 editFrame->Save();
362 else if( aEvt.IsAction( &SCH_ACTIONS::saveLibraryAs ) )
363 editFrame->SaveLibraryAs();
364 else if( aEvt.IsAction( &SCH_ACTIONS::saveSymbolAs ) )
365 editFrame->SaveSymbolCopyAs( true );
366 else if( aEvt.IsAction( &SCH_ACTIONS::saveSymbolCopyAs ) )
367 editFrame->SaveSymbolCopyAs( false );
368 else if( aEvt.IsAction( &SCH_ACTIONS::saveAll ) )
369 editFrame->SaveAll();
370
371 return 0;
372}
373
374
376{
377 if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
378 static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->Revert();
379
380 return 0;
381}
382
383
385{
386 if( !m_isSymbolEditor )
387 return 0;
388
391
392 LIB_ID libId = editFrame->GetTreeLIBID();
393
394 wxString libName = libId.GetLibNickname();
395 std::optional<wxString> libItemName =
396 manager.GetFullURI( LIBRARY_TABLE_TYPE::SYMBOL, libName, true );
397
398 wxCHECK( libItemName, 0 );
399
400 wxFileName fileName( *libItemName );
401
402 wxString filePath = wxEmptyString;
403 wxString explorerCommand;
404
405 if( COMMON_SETTINGS* cfg = Pgm().GetCommonSettings() )
406 explorerCommand = cfg->m_System.file_explorer;
407
408 if( explorerCommand.IsEmpty() )
409 {
410 filePath = fileName.GetFullPath().BeforeLast( wxFileName::GetPathSeparator() );
411
412 if( !filePath.IsEmpty() && wxDirExists( filePath ) )
413 LaunchExternal( filePath );
414
415 return 0;
416 }
417
418 if( !explorerCommand.EndsWith( "%F" ) )
419 {
420 wxMessageBox( _( "Missing/malformed file explorer argument '%F' in common settings." ) );
421 return 0;
422 }
423
424 filePath = fileName.GetFullPath();
425 filePath.Replace( wxS( "\"" ), wxS( "_" ) );
426
427 wxString fileArg = '"' + filePath + '"';
428
429 explorerCommand.Replace( wxT( "%F" ), fileArg );
430
431 if( !explorerCommand.IsEmpty() )
432 wxExecute( explorerCommand );
433
434 return 0;
435}
436
437
439{
440 if( !m_isSymbolEditor )
441 return 0;
442
444 wxString textEditorName = Pgm().GetTextEditor();
445
446 if( textEditorName.IsEmpty() )
447 {
448 wxMessageBox( _( "No text editor selected in KiCad. Please choose one." ) );
449 return 0;
450 }
451
453
454 LIB_ID libId = editFrame->GetTreeLIBID();
455 wxString libName = libId.GetLibNickname();
456
457 std::optional<wxString> optUri =
458 manager.GetFullURI( LIBRARY_TABLE_TYPE::SYMBOL, libName, true );
459
460 wxCHECK( optUri, 0 );
461
462 wxString tempFName = ( *optUri ).wc_str();
463
464 if( !tempFName.IsEmpty() )
465 ExecuteFile( textEditorName, tempFName, nullptr, false );
466
467 return 0;
468}
469
470
472{
473 if( !m_isSymbolEditor )
474 return 0;
475
477
479 editFrame->CopySymbolToClipboard();
480
482 {
483 bool hasWritableLibs = false;
484 wxString msg;
485
486 for( LIB_ID& sel : editFrame->GetSelectedLibIds() )
487 {
488 const wxString& libName = sel.GetLibNickname();
489
490 if( !editFrame->GetLibManager().LibraryExists( libName ) )
491 msg.Printf( _( "Symbol library '%s' not found." ), libName );
492 else if( editFrame->GetLibManager().IsLibraryReadOnly( libName ) )
493 msg.Printf( _( "Symbol library '%s' is not writable." ), libName );
494 else
495 hasWritableLibs = true;
496 }
497
498 if( !msg.IsEmpty() )
499 m_frame->ShowInfoBarError( msg );
500
501 if( !hasWritableLibs )
502 return 0;
503
504 editFrame->DeleteSymbolFromLibrary();
505 }
506
507 return 0;
508}
509
510
512{
513 if( !m_isSymbolEditor )
514 return 0;
515
517 LIB_ID sel = editFrame->GetTargetLibId();
518 // DuplicateSymbol() is called to duplicate a symbol, or to paste a previously
519 // saved symbol in clipboard
520 bool isPasteAction = aEvent.IsAction( &SCH_ACTIONS::pasteSymbol );
521 wxString msg;
522
523 if( !sel.IsValid() && !isPasteAction )
524 {
525 // When duplicating a symbol, a source symbol must exists.
526 msg.Printf( _( "No symbol selected" ) );
527 m_frame->ShowInfoBarError( msg );
528 return 0;
529 }
530
531 const wxString& libName = sel.GetLibNickname();
532
533 if( !editFrame->GetLibManager().LibraryExists( libName ) )
534 {
535 msg.Printf( _( "Symbol library '%s' not found." ), libName );
536 m_frame->ShowInfoBarError( msg );
537 return 0;
538 }
539
540 if( editFrame->GetLibManager().IsLibraryReadOnly( libName ) )
541 {
542 msg.Printf( _( "Symbol library '%s' is not writable." ), libName );
543 m_frame->ShowInfoBarError( msg );
544 return 0;
545 }
546
547 editFrame->DuplicateSymbol( isPasteAction );
548 return 0;
549}
550
551
553{
554 if( !m_isSymbolEditor )
555 return 0;
556
558 LIB_SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
560
561 LIB_ID libId = editFrame->GetTreeLIBID();
562 wxString libName = libId.GetLibNickname();
563 wxString oldName = libId.GetLibItemName();
564 wxString newName;
565 wxString msg;
566
567 if( !libMgr.LibraryExists( libName ) )
568 return 0;
569
570 if( !libTool->RenameLibrary( _( "Change Symbol Name" ), oldName,
571 [&]( const wxString& aNewName )
572 {
573 newName = EscapeString( aNewName, CTX_LIBID );
574
575 if( newName.IsEmpty() )
576 {
577 wxMessageBox( _( "Symbol must have a name." ) );
578 return false;
579 }
580
581 // If no change, accept it without prompting
582 if( newName != oldName && libMgr.SymbolNameInUse( newName, libName ) )
583 {
584 msg.Printf( _( "Symbol '%s' already exists in library '%s'." ),
585 UnescapeString( newName ),
586 libName );
587
588 KIDIALOG errorDlg( m_frame, msg, _( "Confirmation" ),
589 wxOK | wxCANCEL | wxICON_WARNING );
590
591 errorDlg.SetOKLabel( _( "Overwrite" ) );
592
593 return errorDlg.ShowModal() == wxID_OK;
594 }
595
596 return true;
597 } ) )
598 {
599 return 0; // cancelled by user
600 }
601
602 if( newName == oldName )
603 return 0;
604
605 LIB_SYMBOL* libSymbol = libMgr.GetBufferedSymbol( oldName, libName );
606
607 if( !libSymbol )
608 return 0;
609
610 // Renaming the current symbol
611 const bool isCurrentSymbol = editFrame->IsCurrentSymbol( libId );
612 bool overwritingCurrentSymbol = false;
613
614 if( libMgr.SymbolExists( newName, libName ) )
615 {
616 // Overwriting the current symbol also need to update the open symbol
617 LIB_SYMBOL* const overwrittenSymbol = libMgr.GetBufferedSymbol( newName, libName );
618 overwritingCurrentSymbol = editFrame->IsCurrentSymbol( overwrittenSymbol->GetLibId() );
619 libMgr.RemoveSymbol( newName, libName );
620 }
621
622 libSymbol->SetName( newName );
623
624 if( libSymbol->GetValueField().GetText() == oldName )
625 libSymbol->GetValueField().SetText( newName );
626
627 libMgr.UpdateSymbolAfterRename( libSymbol, newName, libName );
628 libMgr.SetSymbolModified( newName, libName );
629
630 if( overwritingCurrentSymbol )
631 {
632 // We overwrite the old current symbol with the renamed one, so show
633 // the renamed one now
634 editFrame->SetCurSymbol( new LIB_SYMBOL( *libSymbol ), false );
635 }
636 else if( isCurrentSymbol && editFrame->GetCurSymbol() )
637 {
638 // Renamed the current symbol - follow it
639 libSymbol = editFrame->GetCurSymbol();
640
641 libSymbol->SetName( newName );
642
643 if( libSymbol->GetValueField().GetText() == oldName )
644 libSymbol->GetValueField().SetText( newName );
645
646 editFrame->RebuildView();
647 editFrame->OnModify();
648 editFrame->UpdateTitle();
649
650 // N.B. The view needs to be rebuilt first as the Symbol Properties change may
651 // invalidate the view pointers by rebuilting the field table
652 editFrame->UpdateMsgPanel();
653 }
654
655 wxDataViewItem treeItem = libMgr.GetAdapter()->FindItem( libId );
656 editFrame->UpdateLibraryTree( treeItem, libSymbol );
657 editFrame->FocusOnLibId( LIB_ID( libName, newName ) );
658 return 0;
659}
660
661
669
670
672{
673 SCH_RENDER_SETTINGS* renderSettings = m_frame->GetRenderSettings();
674 renderSettings->m_ShowPinsElectricalType = !renderSettings->m_ShowPinsElectricalType;
675
676 // Update canvas
677 m_frame->GetCanvas()->GetView()->UpdateAllItems( KIGFX::REPAINT );
678 m_frame->GetCanvas()->Refresh();
679
680 return 0;
681}
682
683
685{
686 SCH_RENDER_SETTINGS* renderSettings = m_frame->GetRenderSettings();
687 renderSettings->m_ShowPinNumbers = !renderSettings->m_ShowPinNumbers;
688
689 // Update canvas
690 m_frame->GetCanvas()->GetView()->UpdateAllItems( KIGFX::REPAINT );
691 m_frame->GetCanvas()->Refresh();
692
693 return 0;
694}
695
696
698{
699 if( !m_isSymbolEditor )
700 return 0;
701
703 editFrame->m_SyncPinEdit = !editFrame->m_SyncPinEdit;
704
705 return 0;
706}
707
708
710{
711 if( !m_isSymbolEditor )
712 return 0;
713
714 SYMBOL_EDITOR_SETTINGS* cfg = m_frame->libeditconfig();
716
718 cfg->m_ShowHiddenPins;
719
721 m_frame->GetCanvas()->Refresh();
722 return 0;
723}
724
725
727{
728 if( !m_isSymbolEditor )
729 return 0;
730
731 SYMBOL_EDITOR_SETTINGS* cfg = m_frame->libeditconfig();
733
734 // TODO: Why is this needed in symbol edit and not in schematic edit?
737
739 m_frame->GetCanvas()->Refresh();
740 return 0;
741}
742
743
745{
746 if( !m_isSymbolEditor )
747 return 0;
748
749 SYMBOL_EDITOR_SETTINGS& cfg = *m_frame->libeditconfig();
751
752 m_frame->GetRenderSettings()->m_ShowPinAltIcons = cfg.m_ShowPinAltIcons;
753
755 m_frame->GetCanvas()->Refresh();
756 return 0;
757}
758
759
761{
762 if( !m_isSymbolEditor )
763 return 0;
764
766 LIB_SYMBOL* symbol = editFrame->GetCurSymbol();
767
768 if( !symbol )
769 {
770 wxMessageBox( _( "No symbol to export" ) );
771 return 0;
772 }
773
774 wxFileName fn( symbol->GetName() );
775 fn.SetExt( "png" );
776
777 wxString projectPath = wxPathOnly( m_frame->Prj().GetProjectFullName() );
778
779 wxFileDialog dlg( editFrame, _( "Export View as PNG" ), projectPath, fn.GetFullName(),
780 FILEEXT::PngFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
781
782 if( dlg.ShowModal() == wxID_OK && !dlg.GetPath().IsEmpty() )
783 {
784 // calling wxYield is mandatory under Linux, after closing the file selector dialog
785 // to refresh the screen before creating the PNG or JPEG image from screen
786 wxYield();
787
788 if( !editFrame->SaveCanvasImageToFile( dlg.GetPath(), BITMAP_TYPE::PNG ) )
789 {
790 wxMessageBox( wxString::Format( _( "Can't save file '%s'." ), dlg.GetPath() ) );
791 }
792 }
793
794 return 0;
795}
796
797
799{
800 if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
801 static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->ExportSymbol();
802
803 return 0;
804}
805
806
808{
809 if( !m_isSymbolEditor )
810 return 0;
811
813 LIB_SYMBOL* symbol = editFrame->GetCurSymbol();
814
815 if( !symbol )
816 {
817 wxMessageBox( _( "No symbol to export" ) );
818 return 0;
819 }
820
821 wxFileName fn( symbol->GetName() );
822 fn.SetExt( FILEEXT::SVGFileExtension );
823
824 wxString pro_dir = wxPathOnly( m_frame->Prj().GetProjectFullName() );
825
826 wxString fullFileName = wxFileSelector( _( "SVG File Name" ), pro_dir, fn.GetFullName(),
828 wxFD_SAVE,
829 m_frame );
830
831 if( !fullFileName.IsEmpty() )
832 {
833 PAGE_INFO pageSave = editFrame->GetScreen()->GetPageSettings();
834 PAGE_INFO pageTemp = pageSave;
835
836 BOX2I symbolBBox = symbol->GetUnitBoundingBox( editFrame->GetUnit(),
837 editFrame->GetBodyStyle(), false );
838
839 // Add a small margin (10% of size)to the plot bounding box
840 symbolBBox.Inflate( symbolBBox.GetSize().x * 0.1, symbolBBox.GetSize().y * 0.1 );
841
842 pageTemp.SetWidthMils( schIUScale.IUToMils( symbolBBox.GetSize().x ) );
843 pageTemp.SetHeightMils( schIUScale.IUToMils( symbolBBox.GetSize().y ) );
844
845 // Add an offet to plot the symbol centered on the page.
846 VECTOR2I plot_offset = symbolBBox.GetOrigin();
847
848 editFrame->GetScreen()->SetPageSettings( pageTemp );
849 editFrame->SVGPlotSymbol( fullFileName, -plot_offset );
850 editFrame->GetScreen()->SetPageSettings( pageSave );
851 }
852
853 return 0;
854}
855
856
858{
859 if( !m_isSymbolEditor )
860 return 0;
861
863 LIB_SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
864 LIB_ID symId = editFrame->GetTargetLibId();
865
866 if( !symId.IsValid() )
867 {
868 wxMessageBox( _( "No symbol to flatten" ) );
869 return 0;
870 }
871
872 const LIB_SYMBOL* symbol = libMgr.GetBufferedSymbol( symId.GetLibItemName(), symId.GetLibNickname() );
873 std::unique_ptr<LIB_SYMBOL> flatSymbol = symbol->Flatten();
874 wxCHECK_MSG( flatSymbol, 0, _( "Failed to flatten symbol" ) );
875
876 if( !libMgr.UpdateSymbol( flatSymbol.get(), symId.GetLibNickname() ) )
877 {
878 wxMessageBox( _( "Failed to update library with flattened symbol" ) );
879 return 0;
880 }
881
882 wxDataViewItem treeItem = libMgr.GetAdapter()->FindItem( symId );
883 editFrame->UpdateLibraryTree( treeItem, flatSymbol.get() );
884
885 return 0;
886}
887
888
890{
891 LIB_SYMBOL* libSymbol = nullptr;
892 LIB_ID libId;
893 int unit, bodyStyle;
894
895 if( m_isSymbolEditor )
896 {
898
899 libSymbol = editFrame->GetCurSymbol();
900 unit = editFrame->GetUnit();
901 bodyStyle = editFrame->GetBodyStyle();
902
903 if( libSymbol )
904 libId = libSymbol->GetLibId();
905 }
906 else
907 {
909
910 libSymbol = viewerFrame->GetSelectedSymbol();
911 unit = viewerFrame->GetUnit();
912 bodyStyle = viewerFrame->GetBodyStyle();
913
914 if( libSymbol )
915 libId = libSymbol->GetLibId();
916 }
917
918 if( libSymbol )
919 {
920 SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH, false );
921
922 if( !schframe ) // happens when the schematic editor is not active (or closed)
923 {
924 DisplayErrorMessage( m_frame, _( "No schematic currently open." ) );
925 return 0;
926 }
927
928 wxWindow* blocking_dialog = schframe->Kiway().GetBlockingDialog();
929
930 if( blocking_dialog )
931 {
932 blocking_dialog->Raise();
933 wxBell();
934 return 0;
935 }
936
937 SCH_SYMBOL* symbol = new SCH_SYMBOL( *libSymbol, libId, &schframe->GetCurrentSheet(),
938 unit, bodyStyle );
939
940 symbol->SetParent( schframe->GetScreen() );
941
942 if( schframe->eeconfig()->m_AutoplaceFields.enable )
943 {
944 // Not placed yet, so pass a nullptr screen reference
945 symbol->AutoplaceFields( nullptr, AUTOPLACE_AUTO );
946 }
947
948 schframe->Raise();
950 SCH_ACTIONS::PLACE_SYMBOL_PARAMS{ symbol, true } );
951 }
952
953 return 0;
954}
955
956
958{
959 if( !m_isSymbolEditor )
960 return 0;
961
963 const int deltaUnit = aEvent.Parameter<int>();
964
965 const int nUnits = editFrame->GetCurSymbol()->GetUnitCount();
966 const int newUnit = ( ( editFrame->GetUnit() - 1 + deltaUnit + nUnits ) % nUnits ) + 1;
967
968 editFrame->SetUnit( newUnit );
969
970 return 0;
971}
972
973
986
987
989{
990 // clang-format off
998
1000
1007
1015
1017
1020
1024
1028
1033
1036
1039 // clang-format on
1040}
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:114
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
static TOOL_ACTION openWithTextEditor
Definition actions.h:68
static TOOL_ACTION revert
Definition actions.h:62
static TOOL_ACTION addLibrary
Definition actions.h:56
static TOOL_ACTION openDirectory
Definition actions.h:69
static TOOL_ACTION saveAll
Definition actions.h:61
static TOOL_ACTION save
Definition actions.h:58
static TOOL_ACTION showProperties
Definition actions.h:266
static TOOL_ACTION newLibrary
Definition actions.h:55
static TOOL_ACTION ddAddLibrary
Definition actions.h:67
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:558
constexpr const Vec & GetOrigin() const
Definition box2.h:210
constexpr const SizeVec & GetSize() const
Definition box2.h:206
int ShowModal() override
bool SaveCanvasImageToFile(const wxString &aFileName, BITMAP_TYPE aBitmapType)
Save the current view as an image file.
virtual void ToggleProperties()
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.h:113
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:98
AUTOPLACE_FIELDS m_AutoplaceFields
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition kidialog.h:42
int ShowModal() override
Definition kidialog.cpp:93
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition view.cpp:1561
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
wxWindow * GetBlockingDialog()
Gets the window pointer to the blocking dialog (to send it signals)
Definition kiway.cpp:680
Module editor specific tools.
bool RenameLibrary(const wxString &aTitle, const wxString &aName, std::function< bool(const wxString &aNewName)> aValidator)
void AddContextMenuItems(CONDITIONAL_MENU *aMenu)
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
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
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
Symbol library management helper that is specific to the symbol library editor frame.
wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > & GetAdapter()
Return the adapter object that provides the stored data.
Define a library symbol object.
Definition lib_symbol.h:83
const LIB_ID & GetLibId() const override
Definition lib_symbol.h:153
const BOX2I GetUnitBoundingBox(int aUnit, int aBodyStyle, bool aIgnoreHiddenFields=true, bool aIgnoreLabelsOnInvisiblePins=true) const
Get the bounding box for the symbol.
bool IsDerived() const
Definition lib_symbol.h:204
wxString GetName() const override
Definition lib_symbol.h:146
SCH_FIELD & GetValueField()
Return reference to the value field.
Definition lib_symbol.h:333
int GetUnitCount() const override
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
virtual void SetName(const wxString &aName)
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition page_info.h:79
void SetHeightMils(double aHeightInMils)
void SetWidthMils(double aWidthInMils)
virtual const wxString & GetTextEditor(bool aCanShowFileChooser=true)
Return the path to the preferred text editor application.
Definition pgm_base.cpp:206
virtual LIBRARY_MANAGER & GetLibraryManager() const
Definition pgm_base.h:131
static TOOL_ACTION editSymbol
static TOOL_ACTION importSymbol
static TOOL_ACTION newSymbol
static TOOL_ACTION saveLibraryAs
static TOOL_ACTION showRelatedLibFieldsTable
static TOOL_ACTION editLibSymbolWithLibEdit
static TOOL_ACTION pasteSymbol
static TOOL_ACTION exportSymbolAsSVG
static TOOL_ACTION renameSymbol
static TOOL_ACTION duplicateSymbol
static TOOL_ACTION cutSymbol
static TOOL_ACTION saveSymbolCopyAs
static TOOL_ACTION nextUnit
static TOOL_ACTION showElectricalTypes
static TOOL_ACTION flattenSymbol
static TOOL_ACTION placeSymbol
Definition sch_actions.h:66
static TOOL_ACTION showHiddenFields
static TOOL_ACTION showHiddenPins
static TOOL_ACTION showPinNumbers
static TOOL_ACTION exportSymbolView
static TOOL_ACTION showLibFieldsTable
static TOOL_ACTION copySymbol
static TOOL_ACTION symbolProperties
static TOOL_ACTION toggleSyncedPinsMode
static TOOL_ACTION deleteSymbol
static TOOL_ACTION togglePinAltIcons
static TOOL_ACTION exportSymbol
static TOOL_ACTION previousUnit
static TOOL_ACTION deriveFromExistingSymbol
static TOOL_ACTION addSymbolToSchematic
static TOOL_ACTION saveSymbolAs
SCH_RENDER_SETTINGS * GetRenderSettings()
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
EESCHEMA_SETTINGS * eeconfig() const
Schematic editor (Eeschema) main window.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SCH_SHEET_PATH & GetCurrentSheet() const
void SetText(const wxString &aText) override
const PAGE_INFO & GetPageSettings() const
Definition sch_screen.h:139
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition sch_screen.h:140
Schematic symbol object.
Definition sch_symbol.h:76
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
Automatically orient all the fields in the symbol.
SCH_SELECTION_TOOL * m_selectionTool
int ToggleSyncedPinsMode(const TOOL_EVENT &aEvent)
int Save(const TOOL_EVENT &aEvt)
int EditSymbol(const TOOL_EVENT &aEvent)
int ExportView(const TOOL_EVENT &aEvent)
int ShowElectricalTypes(const TOOL_EVENT &aEvent)
int FlattenSymbol(const TOOL_EVENT &aEvent)
int OpenDirectory(const TOOL_EVENT &aEvent)
int RenameSymbol(const TOOL_EVENT &newName)
int DuplicateSymbol(const TOOL_EVENT &aEvent)
int ToggleHiddenPins(const TOOL_EVENT &aEvent)
int ShowLibraryTable(const TOOL_EVENT &aEvent)
int AddLibrary(const TOOL_EVENT &aEvent)
int AddSymbol(const TOOL_EVENT &aEvent)
int TogglePinAltIcons(const TOOL_EVENT &aEvent)
int ChangeUnit(const TOOL_EVENT &aEvent)
int Revert(const TOOL_EVENT &aEvent)
int ToggleHiddenFields(const TOOL_EVENT &aEvent)
int OpenWithTextEditor(const TOOL_EVENT &aEvent)
int ExportSymbol(const TOOL_EVENT &aEvent)
void setTransitions() override
< Set up handlers for various events.
int ToggleProperties(const TOOL_EVENT &aEvent)
bool Init() override
Init() is called once upon a registration of the tool.
int EditLibrarySymbol(const TOOL_EVENT &aEvent)
int ExportSymbolAsSVG(const TOOL_EVENT &aEvent)
int ShowPinNumbers(const TOOL_EVENT &aEvent)
int DdAddLibrary(const TOOL_EVENT &aEvent)
int AddSymbolToSchematic(const TOOL_EVENT &aEvent)
int CutCopyDelete(const TOOL_EVENT &aEvent)
bool m_ShowPinAltIcons
When true, dragging an outline edge will drag pins rooted on it.
The symbol library editor main window.
void SaveAll()
Save all modified symbols and libraries.
bool IsLibraryTreeShown() const override
bool IsCurrentSymbol(const LIB_ID &aLibId) const
Restore the empty editor screen, without any symbol or library selected.
LIB_ID GetTreeLIBID(int *aUnit=nullptr) const
Return the LIB_ID of the library or symbol selected in the symbol tree.
void FocusOnLibId(const LIB_ID &aLibID)
void SVGPlotSymbol(const wxString &aFullFileName, const VECTOR2I &aOffset)
Create the SVG print file for the current edited symbol.
void Save()
Save the selected symbol or library.
void LoadSymbol(const wxString &aLibrary, const wxString &aSymbol, int Unit)
bool m_SyncPinEdit
Set to true to synchronize pins at the same position when editing symbols with multiple units or mult...
int GetTreeSelectionCount() const
bool IsSymbolFromSchematic() const
void DuplicateSymbol(bool aFromClipboard)
Insert a duplicate symbol.
void SetCurSymbol(LIB_SYMBOL *aSymbol, bool aUpdateZoom)
Take ownership of aSymbol and notes that it is the one currently being edited.
std::vector< LIB_ID > GetSelectedLibIds() const
LIB_SYMBOL * GetCurSymbol() const
Return the current symbol being edited or NULL if none selected.
LIB_ID GetTargetLibId() const override
Return either the symbol selected in the symbol tree (if context menu is active) or the symbol on the...
void UpdateMsgPanel() override
Redraw the message panel.
void CreateNewSymbol(const wxString &newName=wxEmptyString)
Create a new symbol in the selected library.
void UpdateTitle()
Update the main window title bar with the current library name and read only status of the library.
LIB_SYMBOL_LIBRARY_MANAGER & GetLibManager()
void SaveSymbolCopyAs(bool aOpenCopy)
Save the currently selected symbol to a new name and/or location.
void UpdateLibraryTree(const wxDataViewItem &aTreeItem, LIB_SYMBOL *aSymbol)
Update a symbol node in the library tree.
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current symbol.
void SaveLibraryAs()
Save the currently selected library to a new file.
void ToggleLibraryTree() override
bool IsLibraryReadOnly(const wxString &aLibrary) const
Return true if the library is stored in a read-only file.
bool LibraryExists(const wxString &aLibrary, bool aCheckEnabled=false) const
Return true if library exists.
LIB_SYMBOL * GetBufferedSymbol(const wxString &aSymbolName, const wxString &aLibrary)
Return the symbol copy from the buffer.
bool SymbolNameInUse(const wxString &aName, const wxString &aLibrary)
Return true if the symbol name is already in use in the specified library.
bool IsLibraryModified(const wxString &aLibrary) const
Return true if library has unsaved modifications.
LIB_SYMBOL * GetSymbol(const wxString &aSymbolName, 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...
bool RemoveSymbol(const wxString &aSymbolName, const wxString &aLibrary)
Remove the symbol from the symbol buffer.
bool UpdateSymbolAfterRename(LIB_SYMBOL *aSymbol, const wxString &aOldSymbolName, const wxString &aLibrary)
Update the symbol buffer with a new version of the symbol when the name has changed.
void SetSymbolModified(const wxString &aSymbolName, const wxString &aLibrary)
size_t GetDerivedSymbolNames(const wxString &aSymbolName, const wxString &aLibraryName, wxArrayString &aList)
Fetch all of the symbols derived from a aSymbolName into aList.
bool SymbolExists(const wxString &aSymbolName, const wxString &aLibrary) const
Return true if symbol with a specific alias exists in library (either original one or buffered).
bool UpdateSymbol(LIB_SYMBOL *aSymbol, const wxString &aLibrary)
Update the symbol buffer with a new version of the symbol.
Symbol library viewer main window.
LIB_SYMBOL * GetSelectedSymbol() const
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
SCH_BASE_FRAME * getEditFrame() const
Definition tool_base.h:186
KIGFX::VIEW * getView() const
Definition tool_base.cpp:38
Generic, UI-independent tool event.
Definition tool_event.h:171
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
T Parameter() const
Return a parameter assigned to the event.
Definition tool_event.h:473
void Go(int(SCH_BASE_FRAME::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
std::unique_ptr< TOOL_MENU > m_menu
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
bool empty() const
Definition utf8.h:109
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:202
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:177
This file is part of the common library.
#define _(s)
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:35
@ FRAME_SCH
Definition frame_type.h:34
int ExecuteFile(const wxString &aEditorName, const wxString &aFileName, wxProcess *aCallback, bool aFileForKicad)
Call the executable file aEditorName with the parameter aFileName.
Definition gestfich.cpp:145
static const std::string SVGFileExtension
static wxString PngFileWildcard()
static wxString SVGFileWildcard()
bool LaunchExternal(const wxString &aPath)
Launches the given file or folder in the host OS.
@ REPAINT
Item needs to be redrawn.
Definition view_item.h:58
PGM_BASE & Pgm()
The global program "get" accessor.
Definition pgm_base.cpp:946
see class PGM_BASE
@ AUTOPLACE_AUTO
Definition sch_item.h:70
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_LIBID
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
Definition of file extensions used in Kicad.