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#include <kiplatform/ui.h>
50
51
53{
57
59 {
60 LIBRARY_EDITOR_CONTROL* libraryTreeTool = m_toolMgr->GetTool<LIBRARY_EDITOR_CONTROL>();
61 CONDITIONAL_MENU& ctxMenu = m_menu->GetMenu();
62
63 auto libSelectedCondition =
64 [this]( const SELECTION& aSel )
65 {
67 {
68 LIB_ID sel = editFrame->GetTreeLIBID();
69 return !sel.GetLibNickname().empty() && sel.GetLibItemName().empty();
70 }
71
72 return false;
73 };
74
75 // The libInferredCondition allows you to do things like New Symbol and Paste with a
76 // symbol selected (in other words, when we know the library context even if the library
77 // itself isn't selected.
78 auto libInferredCondition =
79 [this]( const SELECTION& aSel )
80 {
82 {
83 LIB_ID sel = editFrame->GetTreeLIBID();
84 return !sel.GetLibNickname().empty();
85 }
86
87 return false;
88 };
89
90 auto symbolSelectedCondition =
91 [this]( const SELECTION& aSel )
92 {
94 {
95 LIB_ID sel = editFrame->GetTargetLibId();
96 return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
97 }
98
99 return false;
100 };
101
102 auto derivedSymbolSelectedCondition =
103 [this]( const SELECTION& aSel )
104 {
106 {
107 LIB_ID sel = editFrame->GetTargetLibId();
108
109 if( sel.GetLibNickname().empty() || sel.GetLibItemName().empty() )
110 return false;
111
112 LIB_SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
113 const LIB_SYMBOL* sym = libMgr.GetSymbol( sel.GetLibItemName(), sel.GetLibNickname() );
114
115 return sym && sym->IsDerived();
116 }
117
118 return false;
119 };
120
121 auto relatedSymbolSelectedCondition =
122 [this]( const SELECTION& aSel )
123 {
125 {
126 LIB_ID sel = editFrame->GetTargetLibId();
127
128 if( sel.GetLibNickname().empty() || sel.GetLibItemName().empty() )
129 return false;
130
131 LIB_SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
132 const LIB_SYMBOL* sym = libMgr.GetSymbol( sel.GetLibItemName(), sel.GetLibNickname() );
133 wxArrayString derived;
134
135 libMgr.GetDerivedSymbolNames( sel.GetLibItemName(), sel.GetLibNickname(), derived );
136
137 return ( sym && sym->IsDerived() ) || !derived.IsEmpty();
138 }
139
140 return false;
141 };
142
143 auto multiSymbolSelectedCondition =
144 [this]( const SELECTION& aSel )
145 {
147
148 if( editFrame && editFrame->GetTreeSelectionCount() > 1 )
149 {
150 for( LIB_ID& sel : editFrame->GetSelectedLibIds() )
151 {
152 if( !sel.IsValid() )
153 return false;
154 }
155
156 return true;
157 }
158
159 return false;
160 };
161/* not used, yet
162 auto multiLibrarySelectedCondition =
163 [this]( const SELECTION& aSel )
164 {
165 SYMBOL_EDIT_FRAME* editFrame = getEditFrame<SYMBOL_EDIT_FRAME>();
166
167 if( editFrame && editFrame->GetTreeSelectionCount() > 1 )
168 {
169 for( LIB_ID& sel : editFrame->GetSelectedLibIds() )
170 {
171 if( sel.IsValid() )
172 return false;
173 }
174
175 return true;
176 }
177
178 return false;
179 };
180*/
181 auto canOpenExternally =
182 [this]( const SELECTION& aSel )
183 {
184 // The option is shown if the lib has no current edits
186 {
187 LIB_SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
188 wxString libName = editFrame->GetTargetLibId().GetLibNickname();
189 return !libMgr.IsLibraryModified( libName );
190 }
191
192 return false;
193 };
194
195
196// clang-format off
197 ctxMenu.AddItem( SCH_ACTIONS::newSymbol, libInferredCondition, 10 );
198 ctxMenu.AddItem( SCH_ACTIONS::deriveFromExistingSymbol, symbolSelectedCondition, 10 );
199
200 ctxMenu.AddSeparator( 10 );
201 ctxMenu.AddItem( ACTIONS::save, symbolSelectedCondition || libInferredCondition, 10 );
202 ctxMenu.AddItem( SCH_ACTIONS::saveLibraryAs, libSelectedCondition, 10 );
203 ctxMenu.AddItem( SCH_ACTIONS::saveSymbolAs, symbolSelectedCondition, 10 );
204 ctxMenu.AddItem( SCH_ACTIONS::saveSymbolCopyAs, symbolSelectedCondition, 10 );
205 ctxMenu.AddItem( ACTIONS::revert, symbolSelectedCondition || libInferredCondition, 10 );
206
207 ctxMenu.AddSeparator( 20 );
208 ctxMenu.AddItem( SCH_ACTIONS::importSymbol, libInferredCondition, 20 );
209 ctxMenu.AddItem( SCH_ACTIONS::exportSymbol, symbolSelectedCondition, 20 );
210
211 ctxMenu.AddSeparator( 100 );
212 ctxMenu.AddItem( SCH_ACTIONS::cutSymbol, symbolSelectedCondition || multiSymbolSelectedCondition, 100 );
213 ctxMenu.AddItem( SCH_ACTIONS::copySymbol, symbolSelectedCondition || multiSymbolSelectedCondition, 100 );
214 ctxMenu.AddItem( SCH_ACTIONS::pasteSymbol, libInferredCondition, 100 );
215 ctxMenu.AddItem( SCH_ACTIONS::duplicateSymbol, symbolSelectedCondition, 100 );
216 ctxMenu.AddItem( SCH_ACTIONS::deleteSymbol, symbolSelectedCondition || multiSymbolSelectedCondition, 100 );
217
218 ctxMenu.AddSeparator( 120 );
219 ctxMenu.AddItem( SCH_ACTIONS::renameSymbol, symbolSelectedCondition, 120 );
220 ctxMenu.AddItem( SCH_ACTIONS::symbolProperties, symbolSelectedCondition, 120 );
221 ctxMenu.AddItem( SCH_ACTIONS::flattenSymbol, derivedSymbolSelectedCondition, 120 );
222
223 if( ADVANCED_CFG::GetCfg().m_EnableLibWithText || ADVANCED_CFG::GetCfg().m_EnableLibDir )
224 ctxMenu.AddSeparator( 200 );
225
226 if( ADVANCED_CFG::GetCfg().m_EnableLibWithText )
227 ctxMenu.AddItem( ACTIONS::openWithTextEditor, canOpenExternally && ( symbolSelectedCondition || libSelectedCondition ), 200 );
228
229 if( ADVANCED_CFG::GetCfg().m_EnableLibDir )
230 ctxMenu.AddItem( ACTIONS::openDirectory, canOpenExternally && ( symbolSelectedCondition || libSelectedCondition ), 200 );
231
232 ctxMenu.AddSeparator( 300 );
233 ctxMenu.AddItem( SCH_ACTIONS::showLibFieldsTable, libInferredCondition, 300 );
234 ctxMenu.AddItem( SCH_ACTIONS::showRelatedLibFieldsTable, relatedSymbolSelectedCondition, 300 );
235
236 libraryTreeTool->AddContextMenuItems( &ctxMenu );
237 }
238// clang-format on
239
240 return true;
241}
242
243
245{
246 bool createNew = aEvent.IsAction( &ACTIONS::newLibrary );
247
248 if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
249 static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->AddLibraryFile( createNew );
250
251 return 0;
252}
253
254
256{
257 wxString libFile = *aEvent.Parameter<wxString*>();
258
259 if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
260 static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->DdAddLibrary( libFile );
261
262 return 0;
263}
264
265
267{
268 if( !m_isSymbolEditor )
269 return 0;
270
272 int unit = 0;
273 LIB_ID partId = editFrame->GetTreeLIBID( &unit );
274
275 editFrame->LoadSymbol( partId.GetLibItemName(), partId.GetLibNickname(), unit );
276 return 0;
277}
278
279
281{
283 const LIB_SYMBOL* symbol = editFrame->GetCurSymbol();
284
285 if( !symbol || !editFrame->IsSymbolFromSchematic() )
286 {
287 wxBell();
288 return 0;
289 }
290
291 const LIB_ID& libId = symbol->GetLibId();
292
293 if( editFrame->LoadSymbol( libId, editFrame->GetUnit(), editFrame->GetBodyStyle() ) )
294 {
295 if( !editFrame->IsLibraryTreeShown() )
296 editFrame->ToggleLibraryTree();
297 }
298 else
299 {
300 const wxString libName = libId.GetLibNickname();
301 const wxString symbolName = libId.GetLibItemName();
302
303 DisplayError( editFrame,
304 wxString::Format( _( "Failed to load symbol %s from "
305 "library %s." ),
306 UnescapeString( symbolName ), UnescapeString( libName ) ) );
307 }
308 return 0;
309}
310
311
313{
314 if( !m_isSymbolEditor )
315 return 0;
316
318 LIB_ID target = editFrame->GetTargetLibId();
319 const wxString& libName = target.GetLibNickname();
320 wxString msg;
321
322 if( libName.IsEmpty() )
323 {
324 msg.Printf( _( "No symbol library selected." ) );
325 m_frame->ShowInfoBarError( msg );
326 return 0;
327 }
328
329 if( !editFrame->GetLibManager().LibraryExists( libName ) )
330 {
331 msg.Printf( _( "Symbol library '%s' not found." ), libName );
332 m_frame->ShowInfoBarError( msg );
333 return 0;
334 }
335
336 if( editFrame->GetLibManager().IsLibraryReadOnly( libName ) )
337 {
338 msg.Printf( _( "Symbol library '%s' is not writable." ), libName );
339 m_frame->ShowInfoBarError( msg );
340 return 0;
341 }
342
343 if( aEvent.IsAction( &SCH_ACTIONS::newSymbol ) )
344 editFrame->CreateNewSymbol();
346 editFrame->CreateNewSymbol( target.GetLibItemName() );
347 else if( aEvent.IsAction( &SCH_ACTIONS::importSymbol ) )
348 editFrame->ImportSymbol();
349
350 return 0;
351}
352
353
355{
356 if( !m_isSymbolEditor )
357 return 0;
358
360
361 if( aEvt.IsAction( &SCH_ACTIONS::save ) )
362 editFrame->Save();
363 else if( aEvt.IsAction( &SCH_ACTIONS::saveLibraryAs ) )
364 editFrame->SaveLibraryAs();
365 else if( aEvt.IsAction( &SCH_ACTIONS::saveSymbolAs ) )
366 editFrame->SaveSymbolCopyAs( true );
367 else if( aEvt.IsAction( &SCH_ACTIONS::saveSymbolCopyAs ) )
368 editFrame->SaveSymbolCopyAs( false );
369 else if( aEvt.IsAction( &SCH_ACTIONS::saveAll ) )
370 editFrame->SaveAll();
371
372 return 0;
373}
374
375
377{
378 if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
379 static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->Revert();
380
381 return 0;
382}
383
384
386{
387 if( !m_isSymbolEditor )
388 return 0;
389
392
393 LIB_ID libId = editFrame->GetTreeLIBID();
394
395 wxString libName = libId.GetLibNickname();
396 std::optional<wxString> libItemName =
397 manager.GetFullURI( LIBRARY_TABLE_TYPE::SYMBOL, libName, true );
398
399 wxCHECK( libItemName, 0 );
400
401 wxFileName fileName( *libItemName );
402
403 wxString filePath = wxEmptyString;
404 wxString explorerCommand;
405
406 if( COMMON_SETTINGS* cfg = Pgm().GetCommonSettings() )
407 explorerCommand = cfg->m_System.file_explorer;
408
409 if( explorerCommand.IsEmpty() )
410 {
411 filePath = fileName.GetFullPath().BeforeLast( wxFileName::GetPathSeparator() );
412
413 if( !filePath.IsEmpty() && wxDirExists( filePath ) )
414 LaunchExternal( filePath );
415
416 return 0;
417 }
418
419 if( !explorerCommand.EndsWith( "%F" ) )
420 {
421 wxMessageBox( _( "Missing/malformed file explorer argument '%F' in common settings." ) );
422 return 0;
423 }
424
425 filePath = fileName.GetFullPath();
426 filePath.Replace( wxS( "\"" ), wxS( "_" ) );
427
428 wxString fileArg = '"' + filePath + '"';
429
430 explorerCommand.Replace( wxT( "%F" ), fileArg );
431
432 if( !explorerCommand.IsEmpty() )
433 wxExecute( explorerCommand );
434
435 return 0;
436}
437
438
440{
441 if( !m_isSymbolEditor )
442 return 0;
443
445 wxString textEditorName = Pgm().GetTextEditor();
446
447 if( textEditorName.IsEmpty() )
448 {
449 wxMessageBox( _( "No text editor selected in KiCad. Please choose one." ) );
450 return 0;
451 }
452
454
455 LIB_ID libId = editFrame->GetTreeLIBID();
456 wxString libName = libId.GetLibNickname();
457
458 std::optional<wxString> optUri =
459 manager.GetFullURI( LIBRARY_TABLE_TYPE::SYMBOL, libName, true );
460
461 wxCHECK( optUri, 0 );
462
463 wxString tempFName = ( *optUri ).wc_str();
464
465 if( !tempFName.IsEmpty() )
466 ExecuteFile( textEditorName, tempFName, nullptr, false );
467
468 return 0;
469}
470
471
473{
474 if( !m_isSymbolEditor )
475 return 0;
476
478
480 editFrame->CopySymbolToClipboard();
481
483 {
484 bool hasWritableLibs = false;
485 wxString msg;
486
487 for( LIB_ID& sel : editFrame->GetSelectedLibIds() )
488 {
489 const wxString& libName = sel.GetLibNickname();
490
491 if( !editFrame->GetLibManager().LibraryExists( libName ) )
492 msg.Printf( _( "Symbol library '%s' not found." ), libName );
493 else if( editFrame->GetLibManager().IsLibraryReadOnly( libName ) )
494 msg.Printf( _( "Symbol library '%s' is not writable." ), libName );
495 else
496 hasWritableLibs = true;
497 }
498
499 if( !msg.IsEmpty() )
500 m_frame->ShowInfoBarError( msg );
501
502 if( !hasWritableLibs )
503 return 0;
504
505 editFrame->DeleteSymbolFromLibrary();
506 }
507
508 return 0;
509}
510
511
513{
514 if( !m_isSymbolEditor )
515 return 0;
516
518 LIB_ID sel = editFrame->GetTargetLibId();
519 // DuplicateSymbol() is called to duplicate a symbol, or to paste a previously
520 // saved symbol in clipboard
521 bool isPasteAction = aEvent.IsAction( &SCH_ACTIONS::pasteSymbol );
522 wxString msg;
523
524 if( !sel.IsValid() && !isPasteAction )
525 {
526 // When duplicating a symbol, a source symbol must exists.
527 msg.Printf( _( "No symbol selected" ) );
528 m_frame->ShowInfoBarError( msg );
529 return 0;
530 }
531
532 const wxString& libName = sel.GetLibNickname();
533
534 if( !editFrame->GetLibManager().LibraryExists( libName ) )
535 {
536 msg.Printf( _( "Symbol library '%s' not found." ), libName );
537 m_frame->ShowInfoBarError( msg );
538 return 0;
539 }
540
541 if( editFrame->GetLibManager().IsLibraryReadOnly( libName ) )
542 {
543 msg.Printf( _( "Symbol library '%s' is not writable." ), libName );
544 m_frame->ShowInfoBarError( msg );
545 return 0;
546 }
547
548 editFrame->DuplicateSymbol( isPasteAction );
549 return 0;
550}
551
552
554{
555 if( !m_isSymbolEditor )
556 return 0;
557
559 LIB_SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
561
562 LIB_ID libId = editFrame->GetTreeLIBID();
563 wxString libName = libId.GetLibNickname();
564 wxString oldName = libId.GetLibItemName();
565 wxString newName;
566 wxString msg;
567
568 if( !libMgr.LibraryExists( libName ) )
569 return 0;
570
571 if( !libTool->RenameLibrary( _( "Change Symbol Name" ), oldName,
572 [&]( const wxString& aNewName )
573 {
574 newName = EscapeString( aNewName, CTX_LIBID );
575
576 if( newName.IsEmpty() )
577 {
578 wxMessageBox( _( "Symbol must have a name." ) );
579 return false;
580 }
581
582 // If no change, accept it without prompting
583 if( newName != oldName && libMgr.SymbolNameInUse( newName, libName ) )
584 {
585 msg.Printf( _( "Symbol '%s' already exists in library '%s'." ),
586 UnescapeString( newName ),
587 libName );
588
589 KIDIALOG errorDlg( m_frame, msg, _( "Confirmation" ),
590 wxOK | wxCANCEL | wxICON_WARNING );
591
592 errorDlg.SetOKLabel( _( "Overwrite" ) );
593
594 return errorDlg.ShowModal() == wxID_OK;
595 }
596
597 return true;
598 } ) )
599 {
600 return 0; // cancelled by user
601 }
602
603 if( newName == oldName )
604 return 0;
605
606 LIB_SYMBOL* libSymbol = libMgr.GetBufferedSymbol( oldName, libName );
607
608 if( !libSymbol )
609 return 0;
610
611 // Renaming the current symbol
612 const bool isCurrentSymbol = editFrame->IsCurrentSymbol( libId );
613 bool overwritingCurrentSymbol = false;
614
615 if( libMgr.SymbolExists( newName, libName ) )
616 {
617 // Overwriting the current symbol also need to update the open symbol
618 LIB_SYMBOL* const overwrittenSymbol = libMgr.GetBufferedSymbol( newName, libName );
619 overwritingCurrentSymbol = editFrame->IsCurrentSymbol( overwrittenSymbol->GetLibId() );
620 libMgr.RemoveSymbol( newName, libName );
621 }
622
623 libSymbol->SetName( newName );
624
625 if( libSymbol->GetValueField().GetText() == oldName )
626 libSymbol->GetValueField().SetText( newName );
627
628 libMgr.UpdateSymbolAfterRename( libSymbol, newName, libName );
629 libMgr.SetSymbolModified( newName, libName );
630
631 if( overwritingCurrentSymbol )
632 {
633 // We overwrite the old current symbol with the renamed one, so show
634 // the renamed one now
635 editFrame->SetCurSymbol( new LIB_SYMBOL( *libSymbol ), false );
636 }
637 else if( isCurrentSymbol && editFrame->GetCurSymbol() )
638 {
639 // Renamed the current symbol - follow it
640 libSymbol = editFrame->GetCurSymbol();
641
642 libSymbol->SetName( newName );
643
644 if( libSymbol->GetValueField().GetText() == oldName )
645 libSymbol->GetValueField().SetText( newName );
646
647 editFrame->RebuildView();
648 editFrame->OnModify();
649 editFrame->UpdateTitle();
650
651 // N.B. The view needs to be rebuilt first as the Symbol Properties change may
652 // invalidate the view pointers by rebuilting the field table
653 editFrame->UpdateMsgPanel();
654 }
655
656 wxDataViewItem treeItem = libMgr.GetAdapter()->FindItem( libId );
657 editFrame->UpdateLibraryTree( treeItem, libSymbol );
658 editFrame->FocusOnLibId( LIB_ID( libName, newName ) );
659 return 0;
660}
661
662
670
671
673{
674 SCH_RENDER_SETTINGS* renderSettings = m_frame->GetRenderSettings();
675 renderSettings->m_ShowPinsElectricalType = !renderSettings->m_ShowPinsElectricalType;
676
677 // Update canvas
678 m_frame->GetCanvas()->GetView()->UpdateAllItems( KIGFX::REPAINT );
679 m_frame->GetCanvas()->Refresh();
680
681 return 0;
682}
683
684
686{
687 SCH_RENDER_SETTINGS* renderSettings = m_frame->GetRenderSettings();
688 renderSettings->m_ShowPinNumbers = !renderSettings->m_ShowPinNumbers;
689
690 // Update canvas
691 m_frame->GetCanvas()->GetView()->UpdateAllItems( KIGFX::REPAINT );
692 m_frame->GetCanvas()->Refresh();
693
694 return 0;
695}
696
697
699{
700 if( !m_isSymbolEditor )
701 return 0;
702
704 editFrame->m_SyncPinEdit = !editFrame->m_SyncPinEdit;
705
706 return 0;
707}
708
709
711{
712 if( !m_isSymbolEditor )
713 return 0;
714
715 SYMBOL_EDITOR_SETTINGS* cfg = m_frame->libeditconfig();
717
719 cfg->m_ShowHiddenPins;
720
722 m_frame->GetCanvas()->Refresh();
723 return 0;
724}
725
726
728{
729 if( !m_isSymbolEditor )
730 return 0;
731
732 SYMBOL_EDITOR_SETTINGS* cfg = m_frame->libeditconfig();
734
735 // TODO: Why is this needed in symbol edit and not in schematic edit?
738
740 m_frame->GetCanvas()->Refresh();
741 return 0;
742}
743
744
746{
747 if( !m_isSymbolEditor )
748 return 0;
749
750 SYMBOL_EDITOR_SETTINGS& cfg = *m_frame->libeditconfig();
752
753 m_frame->GetRenderSettings()->m_ShowPinAltIcons = cfg.m_ShowPinAltIcons;
754
756 m_frame->GetCanvas()->Refresh();
757 return 0;
758}
759
760
762{
763 if( !m_isSymbolEditor )
764 return 0;
765
767 LIB_SYMBOL* symbol = editFrame->GetCurSymbol();
768
769 if( !symbol )
770 {
771 wxMessageBox( _( "No symbol to export" ) );
772 return 0;
773 }
774
775 wxFileName fn( symbol->GetName() );
776 fn.SetExt( "png" );
777
778 wxString projectPath = wxPathOnly( m_frame->Prj().GetProjectFullName() );
779
780 wxFileDialog dlg( editFrame, _( "Export View as PNG" ), projectPath, fn.GetFullName(),
781 FILEEXT::PngFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
782
784
785 if( dlg.ShowModal() == wxID_OK && !dlg.GetPath().IsEmpty() )
786 {
787 // calling wxYield is mandatory under Linux, after closing the file selector dialog
788 // to refresh the screen before creating the PNG or JPEG image from screen
789 wxYield();
790
791 if( !editFrame->SaveCanvasImageToFile( dlg.GetPath(), BITMAP_TYPE::PNG ) )
792 {
793 wxMessageBox( wxString::Format( _( "Can't save file '%s'." ), dlg.GetPath() ) );
794 }
795 }
796
797 return 0;
798}
799
800
802{
803 if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
804 static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->ExportSymbol();
805
806 return 0;
807}
808
809
811{
812 if( !m_isSymbolEditor )
813 return 0;
814
816 LIB_SYMBOL* symbol = editFrame->GetCurSymbol();
817
818 if( !symbol )
819 {
820 wxMessageBox( _( "No symbol to export" ) );
821 return 0;
822 }
823
824 wxFileName fn( symbol->GetName() );
825 fn.SetExt( FILEEXT::SVGFileExtension );
826
827 wxString pro_dir = wxPathOnly( m_frame->Prj().GetProjectFullName() );
828
829 wxString fullFileName = wxFileSelector( _( "SVG File Name" ), pro_dir, fn.GetFullName(),
831 wxFD_SAVE,
832 m_frame );
833
834 if( !fullFileName.IsEmpty() )
835 {
836 PAGE_INFO pageSave = editFrame->GetScreen()->GetPageSettings();
837 PAGE_INFO pageTemp = pageSave;
838
839 BOX2I symbolBBox = symbol->GetUnitBoundingBox( editFrame->GetUnit(),
840 editFrame->GetBodyStyle(), false );
841
842 // Add a small margin (10% of size)to the plot bounding box
843 symbolBBox.Inflate( symbolBBox.GetSize().x * 0.1, symbolBBox.GetSize().y * 0.1 );
844
845 pageTemp.SetWidthMils( schIUScale.IUToMils( symbolBBox.GetSize().x ) );
846 pageTemp.SetHeightMils( schIUScale.IUToMils( symbolBBox.GetSize().y ) );
847
848 // Add an offet to plot the symbol centered on the page.
849 VECTOR2I plot_offset = symbolBBox.GetOrigin();
850
851 editFrame->GetScreen()->SetPageSettings( pageTemp );
852 editFrame->SVGPlotSymbol( fullFileName, -plot_offset );
853 editFrame->GetScreen()->SetPageSettings( pageSave );
854 }
855
856 return 0;
857}
858
859
861{
862 if( !m_isSymbolEditor )
863 return 0;
864
866 LIB_SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
867 LIB_ID symId = editFrame->GetTargetLibId();
868
869 if( !symId.IsValid() )
870 {
871 wxMessageBox( _( "No symbol to flatten" ) );
872 return 0;
873 }
874
875 const LIB_SYMBOL* symbol = libMgr.GetBufferedSymbol( symId.GetLibItemName(), symId.GetLibNickname() );
876 std::unique_ptr<LIB_SYMBOL> flatSymbol = symbol->Flatten();
877 wxCHECK_MSG( flatSymbol, 0, _( "Failed to flatten symbol" ) );
878
879 if( !libMgr.UpdateSymbol( flatSymbol.get(), symId.GetLibNickname() ) )
880 {
881 wxMessageBox( _( "Failed to update library with flattened symbol" ) );
882 return 0;
883 }
884
885 wxDataViewItem treeItem = libMgr.GetAdapter()->FindItem( symId );
886 editFrame->UpdateLibraryTree( treeItem, flatSymbol.get() );
887
888 return 0;
889}
890
891
893{
894 LIB_SYMBOL* libSymbol = nullptr;
895 LIB_ID libId;
896 int unit, bodyStyle;
897
898 if( m_isSymbolEditor )
899 {
901
902 libSymbol = editFrame->GetCurSymbol();
903 unit = editFrame->GetUnit();
904 bodyStyle = editFrame->GetBodyStyle();
905
906 if( libSymbol )
907 libId = libSymbol->GetLibId();
908 }
909 else
910 {
912
913 libSymbol = viewerFrame->GetSelectedSymbol();
914 unit = viewerFrame->GetUnit();
915 bodyStyle = viewerFrame->GetBodyStyle();
916
917 if( libSymbol )
918 libId = libSymbol->GetLibId();
919 }
920
921 if( libSymbol )
922 {
923 SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH, false );
924
925 if( !schframe ) // happens when the schematic editor is not active (or closed)
926 {
927 DisplayErrorMessage( m_frame, _( "No schematic currently open." ) );
928 return 0;
929 }
930
931 wxWindow* blocking_dialog = schframe->Kiway().GetBlockingDialog();
932
933 if( blocking_dialog )
934 {
935 blocking_dialog->Raise();
936 wxBell();
937 return 0;
938 }
939
940 SCH_SYMBOL* symbol = new SCH_SYMBOL( *libSymbol, libId, &schframe->GetCurrentSheet(),
941 unit, bodyStyle );
942
943 symbol->SetParent( schframe->GetScreen() );
944
945 if( schframe->eeconfig()->m_AutoplaceFields.enable )
946 {
947 // Not placed yet, so pass a nullptr screen reference
948 symbol->AutoplaceFields( nullptr, AUTOPLACE_AUTO );
949 }
950
951 schframe->Raise();
953 SCH_ACTIONS::PLACE_SYMBOL_PARAMS{ symbol, true } );
954 }
955
956 return 0;
957}
958
959
961{
962 if( !m_isSymbolEditor )
963 return 0;
964
966 const int deltaUnit = aEvent.Parameter<int>();
967
968 const int nUnits = editFrame->GetCurSymbol()->GetUnitCount();
969 const int newUnit = ( ( editFrame->GetUnit() - 1 + deltaUnit + nUnits ) % nUnits ) + 1;
970
971 editFrame->SetUnit( newUnit );
972
973 return 0;
974}
975
976
989
990
992{
1000
1002
1009
1017
1019
1022
1026
1030
1035
1038
1041}
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
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:1572
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:685
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:152
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:203
wxString GetName() const override
Definition lib_symbol.h:145
SCH_FIELD & GetValueField()
Return reference to the value field.
Definition lib_symbol.h:332
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:214
virtual LIBRARY_MANAGER & GetLibraryManager() const
Definition pgm_base.h:134
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
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:116
void SetText(const wxString &aText) override
const PAGE_INFO & GetPageSettings() const
Definition sch_screen.h:140
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition sch_screen.h:141
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:146
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
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:717
PGM_BASE & Pgm()
The global program "get" accessor.
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.