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