KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_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-2023 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 <clipboard.h>
28#include <confirm.h>
29#include <connection_graph.h>
30#include <design_block.h>
40#include <project_rescue.h>
41#include <erc/erc.h>
42#include <invoke_sch_dialog.h>
43#include <string_utils.h>
44#include <kiway.h>
46#include <paths.h>
47#include <pgm_base.h>
50#include <project_sch.h>
52#include <sch_edit_frame.h>
54#include <sch_bitmap.h>
55#include <sch_group.h>
56#include <sch_line.h>
57#include <sch_junction.h>
58#include <sch_bus_entry.h>
59#include <sch_shape.h>
60#include <sch_painter.h>
61#include <sch_sheet_pin.h>
62#include <sch_commit.h>
63#include <sim/simulator_frame.h>
64#include <symbol_lib_table.h>
65#include <symbol_library.h>
67#include <symbol_viewer_frame.h>
68#include <tool/picker_tool.h>
69#include <tool/tool_manager.h>
70#include <tools/sch_actions.h>
71#include <tools/sch_selection.h>
76#include <eda_list_dialog.h>
77#include <view/view_controls.h>
79#include <wx_filename.h>
80#include <wx/filedlg.h>
81#include <wx/log.h>
82#include <wx/treectrl.h>
83#include <wx/msgdlg.h>
86
87#ifdef KICAD_IPC_API
89#endif
90
91
97static const wxChar traceSchPaste[] = wxT( "KICAD_SCH_PASTE" );
98
99
101{
103 return 0;
104}
105
106
108{
110 return 0;
111}
112
113
115{
117 return 0;
118}
119
120
122{
123 m_frame->SaveProject( true );
124 return 0;
125}
126
127
129{
130 SCH_SHEET* curr_sheet = m_frame->GetCurrentSheet().Last();
131 wxFileName curr_fn = curr_sheet->GetFileName();
132 wxFileDialog dlg( m_frame, _( "Schematic Files" ), curr_fn.GetPath(), curr_fn.GetFullName(),
134 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
135
136 if( dlg.ShowModal() == wxID_CANCEL )
137 return false;
138
139 wxString newFilename =
141
142 m_frame->saveSchematicFile( curr_sheet, newFilename );
143 return 0;
144}
145
146
148{
149 SCHEMATIC& schematic = m_frame->Schematic();
150 SCH_SHEET& root = schematic.Root();
151
152 if( m_frame->GetCurrentSheet().Last() != &root )
153 {
154 SCH_SHEET_PATH rootSheetPath;
155 rootSheetPath.push_back( &root );
156
158 wxSafeYield();
159 }
160
161 wxString msg;
162 msg.Printf( _( "Revert '%s' (and all sub-sheets) to last version saved?" ),
163 schematic.GetFileName() );
164
165 if( !IsOK( m_frame, msg ) )
166 return false;
167
168 SCH_SCREENS screenList( schematic.Root() );
169
170 for( SCH_SCREEN* screen = screenList.GetFirst(); screen; screen = screenList.GetNext() )
171 screen->SetContentModified( false ); // do not prompt the user for changes
172
174 m_frame->OpenProjectFiles( std::vector<wxString>( 1, schematic.GetFileName() ), KICTL_REVERT );
175
176 return 0;
177}
178
179
181{
183 return 0;
184}
185
186
188{
189 PICKED_ITEMS_LIST undoCmd;
191 ITEM_PICKER wrapper( m_frame->GetScreen(), undoItem, UNDO_REDO::PAGESETTINGS );
192
193 undoCmd.PushItem( wrapper );
194 undoCmd.SetDescription( _( "Page Settings" ) );
195 m_frame->SaveCopyInUndoList( undoCmd, UNDO_REDO::PAGESETTINGS, false, false );
196
200
201 if( dlg.ShowModal() == wxID_OK )
202 {
203 // Update text variables
207
208 m_frame->OnModify();
209 }
210 else
211 {
213 }
214
215 return 0;
216}
217
218
220{
221 SCH_SCREENS schematic( m_frame->Schematic().Root() );
222
223 if( schematic.HasNoFullyDefinedLibIds() )
224 RescueLegacyProject( true );
225 else
227
228 return 0;
229}
230
231
232bool SCH_EDITOR_CONTROL::RescueLegacyProject( bool aRunningOnDemand )
233{
236
237 return rescueProject( rescuer, aRunningOnDemand );
238}
239
240
242{
246
247 return rescueProject( rescuer, aRunningOnDemand );
248}
249
250
251bool SCH_EDITOR_CONTROL::rescueProject( RESCUER& aRescuer, bool aRunningOnDemand )
252{
253 if( !RESCUER::RescueProject( m_frame, aRescuer, aRunningOnDemand ) )
254 return false;
255
256 if( aRescuer.GetCandidateCount() )
257 {
258 KIWAY_PLAYER* viewer = m_frame->Kiway().Player( FRAME_SCH_VIEWER, false );
259
260 if( viewer )
261 static_cast<SYMBOL_VIEWER_FRAME*>( viewer )->ReCreateLibList();
262
263 if( aRunningOnDemand )
264 {
265 SCH_SCREENS schematic( m_frame->Schematic().Root() );
266
267 schematic.UpdateSymbolLinks();
269 }
270
272 m_frame->SyncView();
274 m_frame->OnModify();
275 }
276
277 return true;
278}
279
280
282{
283 DIALOG_SYMBOL_REMAP dlgRemap( m_frame );
284
285 dlgRemap.ShowQuasiModal();
286
287 m_frame->GetCanvas()->Refresh( true );
288
289 return 0;
290}
291
292
294{
295 DIALOG_PRINT dlg( m_frame );
296
297 dlg.ShowModal();
298
299 return 0;
300}
301
302
304{
306
307 dlg.ShowModal();
308
309 // save project config if the prj config has changed:
310 if( dlg.PrjConfigChanged() )
311 m_frame->OnModify();
312
313 return 0;
314}
315
316
318{
319 m_frame->Close( false );
320 return 0;
321}
322
323
325{
326 doCrossProbeSchToPcb( aEvent, false );
327 return 0;
328}
329
330
332{
333 doCrossProbeSchToPcb( aEvent, true );
334 return 0;
335}
336
337
338void SCH_EDITOR_CONTROL::doCrossProbeSchToPcb( const TOOL_EVENT& aEvent, bool aForce )
339{
340 // Don't get in an infinite loop SCH -> PCB -> SCH -> PCB -> SCH -> ...
342 return;
343
345 SCH_SELECTION& selection = aForce ? selTool->RequestSelection() : selTool->GetSelection();
346
347 m_frame->SendSelectItemsToPcb( selection.GetItemsSortedBySelectionOrder(), aForce );
348}
349
350
352{
353 bool savePowerSymbols = IsOK( m_frame,
354 _( "Include power symbols in schematic to the library?" ) );
355
356 bool createNew = aEvent.IsAction( &SCH_ACTIONS::exportSymbolsToNewLibrary );
357
359 SCH_REFERENCE_LIST symbols;
360 sheets.GetSymbols( symbols, savePowerSymbols );
361
362 std::map<LIB_ID, LIB_SYMBOL*> libSymbols;
363 std::map<LIB_ID, std::vector<SCH_SYMBOL*>> symbolMap;
364
365 for( size_t i = 0; i < symbols.GetCount(); ++i )
366 {
367 SCH_SYMBOL* symbol = symbols[i].GetSymbol();
368 LIB_SYMBOL* libSymbol = symbol->GetLibSymbolRef().get();
369 LIB_ID id = libSymbol->GetLibId();
370
371 if( libSymbols.count( id ) )
372 {
373 wxASSERT_MSG( libSymbols[id]->Compare( *libSymbol, SCH_ITEM::COMPARE_FLAGS::ERC ) == 0,
374 "Two symbols have the same LIB_ID but are different!" );
375 }
376 else
377 {
378 libSymbols[id] = libSymbol;
379 }
380
381 symbolMap[id].emplace_back( symbol );
382 }
383
385
386 wxString targetLib;
387
388 if( createNew )
389 {
390 wxFileName fn;
392
393 if( !libTable ) // Cancelled by user
394 return 0;
395
398 ( libTable == &SYMBOL_LIB_TABLE::GetGlobalLibTable() ),
400 {
401 return 0;
402 }
403
404 targetLib = fn.GetName();
405
406 if( libTable->HasLibrary( targetLib, false ) )
407 {
408 DisplayError( m_frame, wxString::Format( _( "Library '%s' already exists." ),
409 targetLib ) );
410 return 0;
411 }
412
413 // if the "new" library is in fact an existing library and the used asked for replacing
414 // it by the recreated lib, erase it:
415 if( fn.FileExists() )
416 wxRemoveFile( fn.GetFullPath() );
417
418 if( !mgr.CreateLibrary( fn.GetFullPath(), *libTable ) )
419 {
420 DisplayError( m_frame, wxString::Format( _( "Could not add library '%s'." ),
421 targetLib ) );
422 return 0;
423 }
424 }
425 else
426 {
427 targetLib = m_frame->SelectLibraryFromList();
428 }
429
430 if( targetLib.IsEmpty() )
431 return 0;
432
433 bool map = IsOK( m_frame, _( "Update symbols in schematic to refer to new library?" ) );
434 bool append = false;
435
436 SCH_COMMIT commit( m_frame );
437 SYMBOL_LIB_TABLE_ROW* row = mgr.GetLibrary( targetLib );
438 SCH_IO_MGR::SCH_FILE_T type = SCH_IO_MGR::EnumFromStr( row->GetType() );
439 IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( type ) );
440
441 wxFileName dest = row->GetFullURI( true );
442 dest.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
443
444 for( const std::pair<const LIB_ID, LIB_SYMBOL*>& it : libSymbols )
445 {
446 LIB_SYMBOL* origSym = it.second;
447 LIB_SYMBOL* newSym = origSym->Flatten().release();
448
449 try
450 {
451 pi->SaveSymbol( dest.GetFullPath(), newSym );
452 }
453 catch( const IO_ERROR& ioe )
454 {
455 wxString msg;
456 msg.Printf( _( "Error saving symbol %s to library '%s'." ),
457 newSym->GetName(), row->GetNickName() );
458 msg += wxS( "\n\n" ) + ioe.What();
459 wxLogWarning( msg );
460 return 0;
461 }
462
463 if( map )
464 {
465 LIB_ID id = it.first;
466 id.SetLibNickname( targetLib );
467
468 for( SCH_SYMBOL* symbol : symbolMap[it.first] )
469 {
470 SCH_SCREEN* parentScreen = static_cast<SCH_SCREEN*>( symbol->GetParent() );
471
472 wxCHECK2( parentScreen, continue );
473
474 commit.Modify( symbol, parentScreen, RECURSE_MODE::NO_RECURSE );
475 symbol->SetLibId( id );
476 append = true;
477 }
478 }
479 }
480
481 // Save the modified symbol library table. We need to look this up by name in each table to find
482 // whether the new library is a global or project entity as the code above to choose the library
483 // returns a different type depending on whether a global or project library is chosen.
485 SYMBOL_LIB_TABLE* projectTable = nullptr;
486
487 if( !m_frame->Prj().IsNullProject() )
488 projectTable = PROJECT_SCH::SchSymbolLibTable( &m_frame->Prj() );
489
490 if( globalTable->FindRow( targetLib ) )
491 {
492 try
493 {
494 wxString globalTablePath = SYMBOL_LIB_TABLE::GetGlobalTableFileName();
495 globalTable->Save( globalTablePath );
496 }
497 catch( const IO_ERROR& ioe )
498 {
499 wxString msg;
500 msg.Printf( _( "Error saving global library table:\n\n%s" ), ioe.What() );
501 wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
502 }
503 }
504 else if( projectTable && projectTable->FindRow( targetLib ) )
505 {
506 try
507 {
508 wxString projectPath = m_frame->Prj().GetProjectPath();
509 wxFileName projectTableFn( projectPath, SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
510 projectTable->Save( projectTableFn.GetFullPath() );
511 }
512 catch( const IO_ERROR& ioe )
513 {
514 wxString msg;
515 msg.Printf( _( "Error saving project-specific library table:\n\n%s" ), ioe.What() );
516 wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
517 }
518 }
519
520 if( append )
521 {
522 std::set<SCH_SCREEN*> processedScreens;
523
524 for( SCH_SHEET_PATH& sheet : sheets )
525 {
526 SCH_SCREEN* screen = sheet.LastScreen();
527
528 if( processedScreens.find( ( screen ) ) == processedScreens.end() )
529 {
530 processedScreens.insert( screen );
531 screen->UpdateSymbolLinks();
532 }
533 }
534
535 commit.Push( wxS( "Update Library Identifiers" ) );
536 }
537
538 return 0;
539}
540
541
542#define HITTEST_THRESHOLD_PIXELS 5
543
545{
547 KIWAY_PLAYER* player = m_frame->Kiway().Player( FRAME_SIMULATOR, false );
548 SIMULATOR_FRAME* simFrame = static_cast<SIMULATOR_FRAME*>( player );
549
550 if( !simFrame ) // Defensive coding; shouldn't happen.
551 return 0;
552
553 if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
554 blocking_win->Close( true );
555
556 // Deactivate other tools; particularly important if another PICKER is currently running
557 Activate();
558
559 picker->SetCursor( KICURSOR::VOLTAGE_PROBE );
560 picker->SetSnapping( false );
561 picker->ClearHandlers();
562
563 picker->SetClickHandler(
564 [this, simFrame]( const VECTOR2D& aPosition )
565 {
567
568 // We do not really want to keep an item selected in schematic,
569 // so clear the current selection
570 selTool->ClearSelection();
571
572 EDA_ITEM* item = selTool->GetNode( aPosition );
574
575 if( !item )
576 return false;
577
578 if( item->Type() == SCH_PIN_T )
579 {
580 try
581 {
582 SCH_PIN* pin = static_cast<SCH_PIN*>( item )->GetLibPin();
583 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item->GetParent() );
584
585 WX_STRING_REPORTER reporter;
586 SIM_LIB_MGR mgr( &m_frame->Prj() );
587
588 std::vector<EMBEDDED_FILES*> embeddedFilesStack;
589 embeddedFilesStack.push_back( m_frame->Schematic().GetEmbeddedFiles() );
590 embeddedFilesStack.push_back( symbol->GetEmbeddedFiles() );
591
592 mgr.SetFilesStack( std::move( embeddedFilesStack ) );
593
594 SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, true, 0, reporter ).model;
595
596 if( reporter.HasMessage() )
597 THROW_IO_ERROR( reporter.GetMessages() );
598
599 SPICE_ITEM spiceItem;
600 spiceItem.refName = symbol->GetRef( &sheet ).ToStdString();
601 std::vector<std::string> currentNames = model.SpiceGenerator().CurrentNames( spiceItem );
602
603 if( currentNames.size() == 0 )
604 {
605 return true;
606 }
607 else if( currentNames.size() == 1 )
608 {
609 simFrame->AddCurrentTrace( currentNames.at( 0 ) );
610 return true;
611 }
612
613 int modelPinIndex = model.FindModelPinIndex( pin->GetNumber().ToStdString() );
614
615 if( modelPinIndex != SIM_MODEL_PIN::NOT_CONNECTED )
616 {
617 wxString name = currentNames.at( modelPinIndex );
618 simFrame->AddCurrentTrace( name );
619 }
620 }
621 catch( const IO_ERROR& e )
622 {
624 }
625 }
626 else if( item->IsType( { SCH_ITEM_LOCATE_WIRE_T } )
627 || item->IsType( { SCH_JUNCTION_T } ) )
628 {
629 if( SCH_CONNECTION* conn = static_cast<SCH_ITEM*>( item )->Connection() )
630 {
631 wxString spiceNet = UnescapeString( conn->Name() );
633
634 simFrame->AddVoltageTrace( wxString::Format( "V(%s)", spiceNet ) );
635 }
636 }
637
638 return true;
639 } );
640
641 picker->SetMotionHandler(
642 [this, picker]( const VECTOR2D& aPos )
643 {
644 SCH_COLLECTOR collector;
645 collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
646 collector.Collect( m_frame->GetScreen(), { SCH_ITEM_LOCATE_WIRE_T,
647 SCH_PIN_T,
648 SCH_SHEET_PIN_T }, aPos );
649
651 selectionTool->GuessSelectionCandidates( collector, aPos );
652
653 EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
654 SCH_LINE* wire = dynamic_cast<SCH_LINE*>( item );
655
656 const SCH_CONNECTION* conn = nullptr;
657
658 if( wire )
659 {
660 item = nullptr;
661 conn = wire->Connection();
662 }
663
664 if( item && item->Type() == SCH_PIN_T )
665 picker->SetCursor( KICURSOR::CURRENT_PROBE );
666 else
667 picker->SetCursor( KICURSOR::VOLTAGE_PROBE );
668
669 if( m_pickerItem != item )
670 {
671 if( m_pickerItem )
672 selectionTool->UnbrightenItem( m_pickerItem );
673
674 m_pickerItem = item;
675
676 if( m_pickerItem )
677 selectionTool->BrightenItem( m_pickerItem );
678 }
679
680 wxString connectionName = ( conn ) ? conn->Name() : wxString( wxS( "" ) );
681
682 if( m_frame->GetHighlightedConnection() != connectionName )
683 {
684 m_frame->SetHighlightedConnection( connectionName );
685
686 TOOL_EVENT dummyEvent;
687 UpdateNetHighlighting( dummyEvent );
688 }
689 } );
690
691 picker->SetFinalizeHandler(
692 [this]( const int& aFinalState )
693 {
694 if( m_pickerItem )
695 m_toolMgr->GetTool<SCH_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
696
697 if( !m_frame->GetHighlightedConnection().IsEmpty() )
698 {
699 m_frame->SetHighlightedConnection( wxEmptyString );
700
701 TOOL_EVENT dummyEvent;
702 UpdateNetHighlighting( dummyEvent );
703 }
704
705 // Wake the selection tool after exiting to ensure the cursor gets updated
706 // and deselect previous selection from simulator to avoid any issue
707 // ( avoid crash in some cases when the SimProbe tool is deselected )
709 selectionTool->ClearSelection();
711 } );
712
714
715 return 0;
716}
717
718
720{
722
723 // Deactivate other tools; particularly important if another PICKER is currently running
724 Activate();
725
726 picker->SetCursor( KICURSOR::TUNE );
727 picker->SetSnapping( false );
728 picker->ClearHandlers();
729
730 picker->SetClickHandler(
731 [this]( const VECTOR2D& aPosition )
732 {
734 EDA_ITEM* item = nullptr;
735 selTool->SelectPoint( aPosition, { SCH_SYMBOL_T, SCH_FIELD_T }, &item );
736
737 if( !item )
738 return false;
739
740 if( item->Type() != SCH_SYMBOL_T )
741 {
742 item = item->GetParent();
743
744 if( item->Type() != SCH_SYMBOL_T )
745 return false;
746 }
747
748 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
749 SCH_SHEET_PATH sheetPath = symbol->Schematic()->CurrentSheet();
750 KIWAY_PLAYER* simFrame = m_frame->Kiway().Player( FRAME_SIMULATOR, false );
751
752 if( simFrame )
753 {
754 if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
755 blocking_win->Close( true );
756
757 static_cast<SIMULATOR_FRAME*>( simFrame )->AddTuner( sheetPath, symbol );
758 }
759
760 // We do not really want to keep a symbol selected in schematic,
761 // so clear the current selection
762 selTool->ClearSelection();
763 return true;
764 } );
765
766 picker->SetMotionHandler(
767 [this]( const VECTOR2D& aPos )
768 {
769 SCH_COLLECTOR collector;
770 collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
771 collector.Collect( m_frame->GetScreen(), { SCH_SYMBOL_T, SCH_FIELD_T }, aPos );
772
774 selectionTool->GuessSelectionCandidates( collector, aPos );
775
776 EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
777
778 if( item && item->Type() == SCH_FIELD_T )
779 item = static_cast<SCH_FIELD*>( item )->GetParentSymbol();
780
781 if( m_pickerItem != item )
782 {
783 if( m_pickerItem )
784 selectionTool->UnbrightenItem( m_pickerItem );
785
786 m_pickerItem = item;
787
788 if( m_pickerItem )
789 selectionTool->BrightenItem( m_pickerItem );
790 }
791 } );
792
793 picker->SetFinalizeHandler(
794 [this]( const int& aFinalState )
795 {
796 if( m_pickerItem )
797 m_toolMgr->GetTool<SCH_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
798
799 // Wake the selection tool after exiting to ensure the cursor gets updated
800 // and deselect previous selection from simulator to avoid any issue
801 // ( avoid crash in some cases when the SimTune tool is deselected )
803 selectionTool->ClearSelection();
805 } );
806
808
809 return 0;
810}
811
812
813// A singleton reference for clearing the highlight
815
816
817static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
818{
819 SCH_EDIT_FRAME* editFrame = static_cast<SCH_EDIT_FRAME*>( aToolMgr->GetToolHolder() );
820 SCH_SELECTION_TOOL* selTool = aToolMgr->GetTool<SCH_SELECTION_TOOL>();
821 SCH_EDITOR_CONTROL* editorControl = aToolMgr->GetTool<SCH_EDITOR_CONTROL>();
822 SCH_CONNECTION* conn = nullptr;
823 SCH_ITEM* item = nullptr;
824 bool retVal = true;
825
826 if( aPosition != CLEAR )
827 {
828 ERC_TESTER erc( &editFrame->Schematic() );
829
830 if( erc.TestDuplicateSheetNames( false ) > 0 )
831 {
832 wxMessageBox( _( "Error: duplicate sub-sheet names found in current sheet." ) );
833 retVal = false;
834 }
835 else
836 {
837 item = static_cast<SCH_ITEM*>( selTool->GetNode( aPosition ) );
838 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( item );
839
840 if( item )
841 {
842 if( item->IsConnectivityDirty() )
843 editFrame->RecalculateConnections( nullptr, NO_CLEANUP );
844
845 if( item->Type() == SCH_FIELD_T )
846 symbol = dynamic_cast<SCH_SYMBOL*>( item->GetParent() );
847
848 if( symbol && symbol->GetLibSymbolRef() && symbol->GetLibSymbolRef()->IsPower() )
849 {
850 std::vector<SCH_PIN*> pins = symbol->GetPins();
851
852 if( pins.size() == 1 )
853 conn = pins[0]->Connection();
854 }
855 else
856 {
857 conn = item->Connection();
858 }
859 }
860 }
861 }
862
863 wxString connName = ( conn ) ? conn->Name() : wxString( wxS( "" ) );
864
865 if( !conn )
866 {
867 editFrame->SetStatusText( wxT( "" ) );
868 editFrame->SendCrossProbeClearHighlight();
869 editFrame->SetHighlightedConnection( wxEmptyString );
870 editorControl->SetHighlightBusMembers( false );
871 }
872 else
873 {
874 NET_NAVIGATOR_ITEM_DATA itemData( editFrame->GetCurrentSheet(), item );
875
876 if( connName != editFrame->GetHighlightedConnection() )
877 {
878 editorControl->SetHighlightBusMembers( false );
879 editFrame->SetCrossProbeConnection( conn );
880 editFrame->SetHighlightedConnection( connName, &itemData );
881 }
882 else
883 {
884 editorControl->SetHighlightBusMembers( !editorControl->GetHighlightBusMembers() );
885
886 if( item != editFrame->GetSelectedNetNavigatorItem() )
887 editFrame->SelectNetNavigatorItem( &itemData );
888 }
889 }
890
891 editFrame->UpdateNetHighlightStatus();
892
894 editorControl->UpdateNetHighlighting( dummy );
895
896 return retVal;
897}
898
899
901{
903 VECTOR2D cursorPos = controls->GetCursorPosition( !aEvent.DisableGridSnapping() );
904
905 highlightNet( m_toolMgr, cursorPos );
906
907 return 0;
908}
909
910
912{
914
915 return 0;
916}
917
918
920{
922 SCHEMATIC& schematic = m_frame->Schematic();
924
925 const SCH_CONNECTION* conn = nullptr;
926 VECTOR2D connPos;
927
928 for( EDA_ITEM* item : selectionTool->GetSelection() )
929 {
930 conn = static_cast<SCH_ITEM*>( item )->Connection();
931 connPos = item->GetPosition();
932
933 if( conn )
934 break;
935 }
936
937 if( !conn )
938 {
939 m_frame->ShowInfoBarError( _( "No net selected." ) );
940 return 0;
941 }
942
943 // Remove selection in favor of highlighting so the whole net is highlighted
944 selectionTool->ClearSelection();
945 highlightNet( m_toolMgr, connPos );
946
947 wxString netName = conn->Name();
948
949 if( conn->IsBus() )
950 {
951 wxString prefix;
952
953 if( NET_SETTINGS::ParseBusVector( netName, &prefix, nullptr ) )
954 {
955 netName = prefix + wxT( "*" );
956 }
957 else if( NET_SETTINGS::ParseBusGroup( netName, &prefix, nullptr ) )
958 {
959 netName = prefix + wxT( ".*" );
960 }
961 }
962 else if( !conn->Driver() || CONNECTION_SUBGRAPH::GetDriverPriority( conn->Driver() )
964 {
965 m_frame->ShowInfoBarError( _( "Net must be labeled to assign a netclass." ) );
967 return 0;
968 }
969
970 DIALOG_ASSIGN_NETCLASS dlg( m_frame, netName, schematic.GetNetClassAssignmentCandidates(),
971 [&]( const std::vector<wxString>& aNetNames )
972 {
973 for( SCH_ITEM* item : screen->Items() )
974 {
975 bool redraw = item->IsBrightened();
976 SCH_CONNECTION* itemConn = item->Connection();
977
978 if( itemConn && alg::contains( aNetNames, itemConn->Name() ) )
979 item->SetBrightened();
980 else
981 item->ClearBrightened();
982
983 redraw |= item->IsBrightened();
984
985 if( item->Type() == SCH_SYMBOL_T )
986 {
987 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
988
989 redraw |= symbol->HasBrightenedPins();
990
991 symbol->ClearBrightenedPins();
992
993 for( SCH_PIN* pin : symbol->GetPins() )
994 {
995 SCH_CONNECTION* pin_conn = pin->Connection();
996
997 if( pin_conn && alg::contains( aNetNames, pin_conn->Name() ) )
998 {
999 pin->SetBrightened();
1000 redraw = true;
1001 }
1002 }
1003 }
1004 else if( item->Type() == SCH_SHEET_T )
1005 {
1006 for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( item )->GetPins() )
1007 {
1008 SCH_CONNECTION* pin_conn = pin->Connection();
1009
1010 redraw |= pin->IsBrightened();
1011
1012 if( pin_conn && alg::contains( aNetNames, pin_conn->Name() ) )
1013 pin->SetBrightened();
1014 else
1015 pin->ClearBrightened();
1016
1017 redraw |= pin->IsBrightened();
1018 }
1019 }
1020
1021 if( redraw )
1022 getView()->Update( item, KIGFX::VIEW_UPDATE_FLAGS::REPAINT );
1023 }
1024
1026 } );
1027
1028 if( dlg.ShowModal() )
1029 {
1030 getView()->UpdateAllItemsConditionally(
1031 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
1032 {
1033 int flags = 0;
1034
1035 auto invalidateTextVars =
1036 [&flags]( EDA_TEXT* text )
1037 {
1038 if( text->HasTextVars() )
1039 {
1040 text->ClearRenderCache();
1041 text->ClearBoundingBoxCache();
1043 }
1044 };
1045
1046 // Netclass coloured items
1047 //
1048 if( dynamic_cast<SCH_LINE*>( aItem ) )
1049 flags |= KIGFX::REPAINT;
1050 else if( dynamic_cast<SCH_JUNCTION*>( aItem ) )
1051 flags |= KIGFX::REPAINT;
1052 else if( dynamic_cast<SCH_BUS_ENTRY_BASE*>( aItem ) )
1053 flags |= KIGFX::REPAINT;
1054
1055 // Items that might reference an item's netclass name
1056 //
1057 if( SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aItem ) )
1058 {
1059 item->RunOnChildren(
1060 [&invalidateTextVars]( SCH_ITEM* aChild )
1061 {
1062 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aChild ) )
1063 invalidateTextVars( text );
1064 },
1066
1067 if( flags & KIGFX::GEOMETRY )
1068 m_frame->GetScreen()->Update( item, false ); // Refresh RTree
1069 }
1070
1071 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aItem ) )
1072 invalidateTextVars( text );
1073
1074 return flags;
1075 } );
1076 }
1077
1078 highlightNet( m_toolMgr, CLEAR );
1079 return 0;
1080}
1081
1082
1084{
1085 wxCHECK( m_frame, 0 );
1086
1087 const SCH_SHEET_PATH& sheetPath = m_frame->GetCurrentSheet();
1089 CONNECTION_GRAPH* connectionGraph = m_frame->Schematic().ConnectionGraph();
1090 wxString selectedName = m_frame->GetHighlightedConnection();
1091
1092 std::set<wxString> connNames;
1093 std::vector<EDA_ITEM*> itemsToRedraw;
1094
1095 wxCHECK( screen && connectionGraph, 0 );
1096
1097 if( !selectedName.IsEmpty() )
1098 {
1099 connNames.emplace( selectedName );
1100
1101 if( CONNECTION_SUBGRAPH* sg = connectionGraph->FindSubgraphByName( selectedName, sheetPath ) )
1102 {
1104 {
1105 for( const SCH_ITEM* item : sg->GetItems() )
1106 {
1107 wxCHECK2( item, continue );
1108
1109 if( SCH_CONNECTION* connection = item->Connection() )
1110 {
1111 for( const std::shared_ptr<SCH_CONNECTION>& member : connection->AllMembers() )
1112 {
1113 if( member )
1114 connNames.emplace( member->Name() );
1115 }
1116 }
1117 }
1118 }
1119 }
1120
1121 // Place all bus names that are connected to the selected net in the set, regardless of
1122 // their sheet. This ensures that nets that are connected to a bus on a different sheet
1123 // get their buses highlighted as well.
1124 for( CONNECTION_SUBGRAPH* sg : connectionGraph->GetAllSubgraphs( selectedName ) )
1125 {
1126 for( const auto& [_, bus_sgs] : sg->GetBusParents() )
1127 {
1128 for( CONNECTION_SUBGRAPH* bus_sg : bus_sgs )
1129 connNames.emplace( bus_sg->GetNetName() );
1130 }
1131
1132 }
1133 }
1134
1135 for( SCH_ITEM* item : screen->Items() )
1136 {
1137 if( !item || !item->IsConnectable() )
1138 continue;
1139
1140 SCH_ITEM* redrawItem = nullptr;
1141
1142 if( item->Type() == SCH_SYMBOL_T )
1143 {
1144 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1145
1146 for( SCH_PIN* pin : symbol->GetPins() )
1147 {
1148 if( SCH_CONNECTION* pin_conn = pin->Connection() )
1149 {
1150 if( !pin->IsBrightened() && connNames.count( pin_conn->Name() ) )
1151 {
1152 pin->SetBrightened();
1153 redrawItem = symbol;
1154 }
1155 else if( pin->IsBrightened() && !connNames.count( pin_conn->Name() ) )
1156 {
1157 pin->ClearBrightened();
1158 redrawItem = symbol;
1159 }
1160 }
1161 }
1162
1163 if( symbol->IsPower() && symbol->GetPins().size() )
1164 {
1165 if( SCH_CONNECTION* pinConn = symbol->GetPins()[0]->Connection() )
1166 {
1167 for( FIELD_T id : { FIELD_T::REFERENCE, FIELD_T::VALUE } )
1168 {
1169 SCH_FIELD* field = symbol->GetField( id );
1170
1171 if( !field->IsVisible() )
1172 continue;
1173
1174 if( !field->IsBrightened() && connNames.count( pinConn->Name() ) )
1175 {
1176 field->SetBrightened();
1177 redrawItem = symbol;
1178 }
1179 else if( field->IsBrightened() && !connNames.count( pinConn->Name() ) )
1180 {
1181 field->ClearBrightened();
1182 redrawItem = symbol;
1183 }
1184 }
1185 }
1186 }
1187 }
1188 else if( item->Type() == SCH_SHEET_T )
1189 {
1190 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1191
1192 for( SCH_SHEET_PIN* pin : sheet->GetPins() )
1193 {
1194 wxCHECK2( pin, continue );
1195
1196 if( SCH_CONNECTION* pin_conn = pin->Connection() )
1197 {
1198 if( !pin->IsBrightened() && connNames.count( pin_conn->Name() ) )
1199 {
1200 pin->SetBrightened();
1201 redrawItem = sheet;
1202 }
1203 else if( pin->IsBrightened() && !connNames.count( pin_conn->Name() ) )
1204 {
1205 pin->ClearBrightened();
1206 redrawItem = sheet;
1207 }
1208 }
1209 }
1210 }
1211 else
1212 {
1213 if( SCH_CONNECTION* itemConn = item->Connection() )
1214 {
1215 if( !item->IsBrightened() && connNames.count( itemConn->Name() ) )
1216 {
1217 item->SetBrightened();
1218 redrawItem = item;
1219 }
1220 else if( item->IsBrightened() && !connNames.count( itemConn->Name() ) )
1221 {
1222 item->ClearBrightened();
1223 redrawItem = item;
1224 }
1225 }
1226 }
1227
1228 if( redrawItem )
1229 itemsToRedraw.push_back( redrawItem );
1230 }
1231
1232 if( itemsToRedraw.size() )
1233 {
1234 // Be sure highlight change will be redrawn
1235 KIGFX::VIEW* view = getView();
1236
1237 for( EDA_ITEM* redrawItem : itemsToRedraw )
1239
1241 }
1242
1243 return 0;
1244}
1245
1246
1248{
1250
1251 // Deactivate other tools; particularly important if another PICKER is currently running
1252 Activate();
1253
1254 picker->SetCursor( KICURSOR::BULLSEYE );
1255 picker->SetSnapping( false );
1256 picker->ClearHandlers();
1257
1258 picker->SetClickHandler(
1259 [this] ( const VECTOR2D& aPos )
1260 {
1261 return highlightNet( m_toolMgr, aPos );
1262 } );
1263
1265
1266 return 0;
1267}
1268
1269
1271{
1272 wxCHECK( m_frame, 0 );
1273
1274 if( m_frame->GetUndoCommandCount() <= 0 )
1275 return 0;
1276
1277 // Inform tools that undo command was issued
1279
1280 // Get the old list
1282
1283 wxCHECK( undo_list, 0 );
1284
1285 m_frame->PutDataInPreviousState( undo_list );
1286
1287 // Now push the old command to the RedoList
1288 undo_list->ReversePickersListOrder();
1289 m_frame->PushCommandToRedoList( undo_list );
1290
1291 m_toolMgr->GetTool<SCH_SELECTION_TOOL>()->RebuildSelection();
1292
1294 m_frame->OnModify();
1295
1296 return 0;
1297}
1298
1299
1301{
1302 wxCHECK( m_frame, 0 );
1303
1304 if( m_frame->GetRedoCommandCount() == 0 )
1305 return 0;
1306
1307 // Inform tools that undo command was issued
1309
1310 /* Get the old list */
1312
1313 wxCHECK( list, 0 );
1314
1315 /* Redo the command: */
1317
1318 /* Put the old list in UndoList */
1321
1322 m_toolMgr->GetTool<SCH_SELECTION_TOOL>()->RebuildSelection();
1323
1325 m_frame->OnModify();
1326
1327 return 0;
1328}
1329
1330
1331bool SCH_EDITOR_CONTROL::doCopy( bool aUseDuplicateClipboard )
1332{
1334 SCH_SELECTION& selection = selTool->RequestSelection();
1335 SCHEMATIC& schematic = m_frame->Schematic();
1336
1337 if( selection.Empty() )
1338 return false;
1339
1340 if( aUseDuplicateClipboard )
1341 m_duplicateIsHoverSelection = selection.IsHover();
1342
1343 selection.SetScreen( m_frame->GetScreen() );
1345
1346 for( EDA_ITEM* item : selection.GetItems() )
1347 {
1348 if( item->Type() == SCH_SHEET_T )
1349 {
1350 SCH_SHEET* sheet = (SCH_SHEET*) item;
1351 m_supplementaryClipboard[ sheet->GetFileName() ] = sheet->GetScreen();
1352 }
1353 else if( item->Type() == SCH_FIELD_T && selection.IsHover() )
1354 {
1355 // Most of the time the user is trying to duplicate the parent symbol
1356 // and the field text is in it
1357 selection.Add( item->GetParent() );
1358 }
1359 else if( item->Type() == SCH_MARKER_T )
1360 {
1361 // Don't let the markers be copied
1362 selection.Remove( item );
1363 }
1364 else if( item->Type() == SCH_GROUP_T )
1365 {
1366 // Groups need to have all their items selected
1367 static_cast<SCH_ITEM*>( item )->RunOnChildren(
1368 [&]( EDA_ITEM* aChild )
1369 {
1370 selection.Add( aChild );
1371 },
1372 RECURSE_MODE::RECURSE );
1373 }
1374 }
1375
1376 STRING_FORMATTER formatter;
1377 SCH_IO_KICAD_SEXPR plugin;
1379
1380 plugin.Format( &selection, &selPath, schematic, &formatter, true );
1381
1382 std::string prettyData = formatter.GetString();
1383 KICAD_FORMAT::Prettify( prettyData, true );
1384
1385 if( selection.IsHover() )
1387
1388 if( aUseDuplicateClipboard )
1389 {
1390 m_duplicateClipboard = prettyData;
1391 return true;
1392 }
1393
1394 return SaveClipboard( prettyData );
1395}
1396
1397
1398bool SCH_EDITOR_CONTROL::searchSupplementaryClipboard( const wxString& aSheetFilename,
1399 SCH_SCREEN** aScreen )
1400{
1401 if( m_supplementaryClipboard.count( aSheetFilename ) > 0 )
1402 {
1403 *aScreen = m_supplementaryClipboard[ aSheetFilename ];
1404 return true;
1405 }
1406
1407 return false;
1408}
1409
1410
1412{
1413 doCopy( true ); // Use the local clipboard
1414 Paste( aEvent );
1415
1416 return 0;
1417}
1418
1419
1421{
1422 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wxWindow::FindFocus() );
1423
1424 if( textEntry )
1425 {
1426 textEntry->Cut();
1427 return 0;
1428 }
1429
1430 if( doCopy() )
1432
1433 return 0;
1434}
1435
1436
1438{
1439 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wxWindow::FindFocus() );
1440
1441 if( textEntry )
1442 {
1443 textEntry->Copy();
1444 return 0;
1445 }
1446
1447 doCopy();
1448
1449 return 0;
1450}
1451
1452
1454{
1456 SCH_SELECTION& selection = selTool->RequestSelection();
1457
1458 if( selection.Empty() )
1459 return false;
1460
1461 wxString itemsAsText = GetSelectedItemsAsText( selection );
1462
1463 if( selection.IsHover() )
1465
1466 return SaveClipboard( itemsAsText.ToStdString() );
1467}
1468
1469
1471 const SCH_SHEET_PATH& aPastePath,
1472 const KIID_PATH& aClipPath,
1473 bool aForceKeepAnnotations )
1474{
1475 wxCHECK( m_frame && aSymbol, /* void */ );
1476
1477 SCH_SYMBOL_INSTANCE newInstance;
1478 bool instanceFound = false;
1479 KIID_PATH pasteLookupPath = aClipPath;
1480
1481 m_pastedSymbols.insert( aSymbol );
1482
1483 for( const SCH_SYMBOL_INSTANCE& tmp : aSymbol->GetInstances() )
1484 {
1485 if( ( tmp.m_Path.empty() && aClipPath.empty() )
1486 || ( !aClipPath.empty() && tmp.m_Path.EndsWith( aClipPath ) ) )
1487 {
1488 newInstance = tmp;
1489 instanceFound = true;
1490
1491 wxLogTrace( traceSchPaste,
1492 wxS( "Pasting found symbol instance with reference %s, unit %d:"
1493 "\n\tClipboard path: %s\n\tSymbol UUID: %s." ),
1494 tmp.m_Reference, tmp.m_Unit,
1495 aClipPath.AsString(), aSymbol->m_Uuid.AsString() );
1496
1497 break;
1498 }
1499 }
1500
1501 // The pasted symbol look up paths include the symbol UUID.
1502 pasteLookupPath.push_back( aSymbol->m_Uuid );
1503
1504 if( !instanceFound )
1505 {
1506 wxLogTrace( traceSchPaste,
1507 wxS( "Clipboard symbol instance **not** found:\n\tClipboard path: %s\n\t"
1508 "Symbol UUID: %s." ),
1509 aClipPath.AsString(), aSymbol->m_Uuid.AsString() );
1510
1511 // Some legacy versions saved value fields escaped. While we still do in the symbol
1512 // editor, we don't anymore in the schematic, so be sure to unescape them.
1513 SCH_FIELD* valueField = aSymbol->GetField( FIELD_T::VALUE );
1514 valueField->SetText( UnescapeString( valueField->GetText() ) );
1515
1516 // Pasted from notepad or an older instance of eeschema. Use the values in the fields
1517 // instead.
1518 newInstance.m_Reference = aSymbol->GetField( FIELD_T::REFERENCE )->GetText();
1519 newInstance.m_Unit = aSymbol->GetUnit();
1520 }
1521
1522 newInstance.m_Path = aPastePath.Path();
1523 newInstance.m_ProjectName = m_frame->Prj().GetProjectName();
1524
1525 aSymbol->AddHierarchicalReference( newInstance );
1526
1527 if( !aForceKeepAnnotations )
1528 aSymbol->ClearAnnotation( &aPastePath, false );
1529
1530 // We might clear annotations but always leave the original unit number from the paste.
1531 aSymbol->SetUnit( newInstance.m_Unit );
1532}
1533
1534
1536 const SCH_SHEET_PATH& aPastePath,
1537 const KIID_PATH& aClipPath,
1538 bool aForceKeepAnnotations,
1539 SCH_SHEET_LIST* aPastedSheets,
1540 std::map<SCH_SHEET_PATH,
1541 SCH_REFERENCE_LIST>& aPastedSymbols )
1542{
1543 wxCHECK( aSheet && aPastedSheets, aPastePath );
1544
1545 SCH_SHEET_PATH sheetPath = aPastePath;
1546 sheetPath.push_back( aSheet );
1547
1548 aPastedSheets->push_back( sheetPath );
1549
1550 if( aSheet->GetScreen() == nullptr )
1551 return sheetPath; // We can only really set the page number but not load any items
1552
1553 for( SCH_ITEM* item : aSheet->GetScreen()->Items() )
1554 {
1555 if( item->IsConnectable() )
1556 item->SetConnectivityDirty();
1557
1558 if( item->Type() == SCH_SYMBOL_T )
1559 {
1560 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1561
1562 wxCHECK2( symbol, continue );
1563
1564 // Only do this once if the symbol is shared across multiple sheets.
1565 if( !m_pastedSymbols.count( symbol ) )
1566 {
1567 for( SCH_PIN* pin : symbol->GetPins() )
1568 {
1569 const_cast<KIID&>( pin->m_Uuid ) = KIID();
1570 pin->SetConnectivityDirty();
1571 }
1572 }
1573
1574 updatePastedSymbol( symbol, sheetPath, aClipPath, aForceKeepAnnotations );
1575 }
1576 else if( item->Type() == SCH_SHEET_T )
1577 {
1578 SCH_SHEET* subsheet = static_cast<SCH_SHEET*>( item );
1579
1580 wxCHECK2( subsheet, continue );
1581
1582 // Make sure pins get a new UUID and set the dirty connectivity flag.
1583 if( !aPastedSheets->ContainsSheet( subsheet ) )
1584 {
1585 for( SCH_SHEET_PIN* pin : subsheet->GetPins() )
1586 {
1587 const_cast<KIID&>( pin->m_Uuid ) = KIID();
1588 pin->SetConnectivityDirty();
1589 }
1590 }
1591
1592 KIID_PATH newClipPath = aClipPath;
1593 newClipPath.push_back( subsheet->m_Uuid );
1594
1595 updatePastedSheet( subsheet, sheetPath, newClipPath, aForceKeepAnnotations,
1596 aPastedSheets, aPastedSymbols );
1597 }
1598 }
1599
1600 sheetPath.GetSymbols( aPastedSymbols[aPastePath] );
1601
1602 return sheetPath;
1603}
1604
1605
1607{
1608 wxCHECK( aScreen, /* void */ );
1609
1610 for( const SCH_ITEM* item : aScreen->Items() )
1611 {
1612 if( item->Type() == SCH_SYMBOL_T )
1613 {
1614 const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( item );
1615
1616 wxCHECK2( symbol, continue );
1617
1618 for( const SCH_SYMBOL_INSTANCE& symbolInstance : symbol->GetInstances() )
1619 {
1620 KIID_PATH pathWithSymbol = symbolInstance.m_Path;
1621
1622 pathWithSymbol.push_back( symbol->m_Uuid );
1623
1624 m_clipboardSymbolInstances[pathWithSymbol] = symbolInstance;
1625 }
1626 }
1627 }
1628}
1629
1630
1632{
1633 wxCHECK( m_frame, /* void */ );
1634
1635 for( SCH_SYMBOL* symbol : m_pastedSymbols )
1636 {
1637 wxCHECK2( symbol, continue );
1638
1639 std::vector<KIID_PATH> instancePathsToRemove;
1640
1641 for( const SCH_SYMBOL_INSTANCE& instance : symbol->GetInstances() )
1642 {
1643 if( ( instance.m_ProjectName != m_frame->Prj().GetProjectName() )
1644 || instance.m_Path.empty() )
1645 instancePathsToRemove.emplace_back( instance.m_Path );
1646 }
1647
1648 for( const KIID_PATH& path : instancePathsToRemove )
1649 symbol->RemoveInstance( path );
1650 }
1651}
1652
1653
1655{
1656 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wxWindow::FindFocus() );
1657
1658 if( textEntry )
1659 {
1660 textEntry->Paste();
1661 return 0;
1662 }
1663
1665 std::string content;
1666 VECTOR2I eventPos;
1667
1668 SCH_SHEET tempSheet;
1669 SCH_SCREEN* tempScreen = new SCH_SCREEN( &m_frame->Schematic() );
1670 std::unique_ptr<wxImage> clipImg = GetImageFromClipboard();
1671
1672 if( !aEvent.IsAction( &ACTIONS::duplicate ) && clipImg )
1673 {
1674 // Just image data
1675 auto bitmap = std::make_unique<SCH_BITMAP>();
1676
1677 bool ok = bitmap->GetReferenceImage().SetImage( *clipImg );
1678
1679 if( !ok )
1680 {
1681 delete tempScreen;
1682 return 0;
1683 }
1684
1685 tempScreen->Append( bitmap.release() );
1686 }
1687 else
1688 {
1689 if( aEvent.IsAction( &ACTIONS::duplicate ) )
1690 content = m_duplicateClipboard;
1691 else
1692 content = GetClipboardUTF8();
1693
1694 if( content.empty() )
1695 {
1696 delete tempScreen;
1697 return 0;
1698 }
1699
1700 if( aEvent.IsAction( &ACTIONS::duplicate ) )
1701 eventPos = getViewControls()->GetCursorPosition( false );
1702
1703 STRING_LINE_READER reader( content, "Clipboard" );
1704 SCH_IO_KICAD_SEXPR plugin;
1705
1706 // Screen object on heap is owned by the sheet.
1707 tempSheet.SetScreen( tempScreen );
1708
1709 try
1710 {
1711 plugin.LoadContent( reader, &tempSheet );
1712 }
1713 catch( IO_ERROR& )
1714 {
1715 // If it wasn't content, then paste as a text object.
1716 if( content.size() > static_cast<size_t>( ADVANCED_CFG::GetCfg().m_MaxPastedTextLength ) )
1717 {
1718 int result = IsOK( m_frame, _( "Pasting a long text text string may be very slow. "
1719 "Do you want to continue?" ) );
1720 if( !result )
1721 return 0;
1722 }
1723
1724 SCH_TEXT* text_item = new SCH_TEXT( VECTOR2I( 0, 0 ), content );
1725 tempScreen->Append( text_item );
1726 }
1727 }
1728
1729 m_pastedSymbols.clear();
1731
1732 // Save pasted symbol instances in case the user chooses to keep existing symbol annotation.
1733 setPastedSymbolInstances( tempScreen );
1734
1735 tempScreen->MigrateSimModels();
1736
1738 int annotateStartNum = m_frame->Schematic().Settings().m_AnnotateStartNum;
1739
1740 PASTE_MODE pasteMode = annotate.automatic ? PASTE_MODE::RESPECT_OPTIONS : PASTE_MODE::REMOVE_ANNOTATIONS;
1741 bool forceRemoveAnnotations = false;
1742
1743 if( aEvent.IsAction( &ACTIONS::pasteSpecial ) )
1744 {
1745 PASTE_MODE pasteModeSpecial = pasteMode;
1746 DIALOG_PASTE_SPECIAL dlg( m_frame, &pasteModeSpecial );
1747
1748 if( dlg.ShowModal() == wxID_CANCEL )
1749 return 0;
1750
1751 // We have to distinguish if removing was explicit
1752 forceRemoveAnnotations = ( pasteModeSpecial == PASTE_MODE::REMOVE_ANNOTATIONS );
1753 pasteMode = pasteModeSpecial;
1754 }
1755
1756 bool forceKeepAnnotations = pasteMode != PASTE_MODE::REMOVE_ANNOTATIONS;
1757
1758 // SCH_SEXP_PLUGIN added the items to the paste screen, but not to the view or anything
1759 // else. Pull them back out to start with.
1760 SCH_COMMIT commit( m_toolMgr );
1761 EDA_ITEMS loadedItems;
1762 std::vector<SCH_ITEM*> sortedLoadedItems;
1763 bool sheetsPasted = false;
1764 SCH_SHEET_LIST hierarchy = m_frame->Schematic().Hierarchy();
1765 SCH_SHEET_PATH& pasteRoot = m_frame->GetCurrentSheet();
1766 wxFileName destFn = pasteRoot.Last()->GetFileName();
1767
1768 if( destFn.IsRelative() )
1769 destFn.MakeAbsolute( m_frame->Prj().GetProjectPath() );
1770
1771 // List of paths in the hierarchy that refer to the destination sheet of the paste
1772 SCH_SHEET_LIST sheetPathsForScreen = hierarchy.FindAllSheetsForScreen( pasteRoot.LastScreen() );
1773 sheetPathsForScreen.SortByPageNumbers();
1774
1775 // Build a list of screens from the current design (to avoid loading sheets that already exist)
1776 std::map<wxString, SCH_SCREEN*> loadedScreens;
1777
1778 for( const SCH_SHEET_PATH& item : hierarchy )
1779 {
1780 if( item.LastScreen() )
1781 loadedScreens[item.Last()->GetFileName()] = item.LastScreen();
1782 }
1783
1784 // Get set of sheet names in the current schematic to prevent duplicate sheet names on paste.
1785 std::set<wxString> existingSheetNames = pasteRoot.LastScreen()->GetSheetNames();
1786
1787 // Build symbol list for reannotation of duplicates
1788 SCH_REFERENCE_LIST existingRefs;
1789 hierarchy.GetSymbols( existingRefs );
1790 existingRefs.SortByReferenceOnly();
1791
1792 std::set<wxString> existingRefsSet;
1793
1794 for( const SCH_REFERENCE& ref : existingRefs )
1795 existingRefsSet.insert( ref.GetRef() );
1796
1797 // Build UUID map for fetching last-resolved-properties
1798 std::map<KIID, EDA_ITEM*> itemMap;
1799 hierarchy.FillItemMap( itemMap );
1800
1801 // Keep track of pasted sheets and symbols for the different paths to the hierarchy.
1802 std::map<SCH_SHEET_PATH, SCH_REFERENCE_LIST> pastedSymbols;
1803 std::map<SCH_SHEET_PATH, SCH_SHEET_LIST> pastedSheets;
1804
1805 for( SCH_ITEM* item : tempScreen->Items() )
1806 {
1807 if( item->Type() == SCH_SHEET_T )
1808 sortedLoadedItems.push_back( item );
1809 else
1810 loadedItems.push_back( item );
1811 }
1812
1813 sort( sortedLoadedItems.begin(), sortedLoadedItems.end(),
1814 []( SCH_ITEM* firstItem, SCH_ITEM* secondItem )
1815 {
1816 SCH_SHEET* firstSheet = static_cast<SCH_SHEET*>( firstItem );
1817 SCH_SHEET* secondSheet = static_cast<SCH_SHEET*>( secondItem );
1818 return StrNumCmp( firstSheet->GetName(), secondSheet->GetName(), false ) < 0;
1819 });
1820
1821
1822 for( SCH_ITEM* item : sortedLoadedItems )
1823 {
1824 loadedItems.push_back( item );
1825
1826 if( item->Type() == SCH_SHEET_T )
1827 {
1828 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1829 wxFileName srcFn = sheet->GetFileName();
1830
1831 if( srcFn.IsRelative() )
1832 srcFn.MakeAbsolute( m_frame->Prj().GetProjectPath() );
1833
1834 SCH_SHEET_LIST sheetHierarchy( sheet );
1835
1836 if( hierarchy.TestForRecursion( sheetHierarchy, destFn.GetFullPath( wxPATH_UNIX ) ) )
1837 {
1838 auto msg = wxString::Format( _( "The pasted sheet '%s'\n"
1839 "was dropped because the destination already has "
1840 "the sheet or one of its subsheets as a parent." ),
1841 sheet->GetFileName() );
1842 DisplayError( m_frame, msg );
1843 loadedItems.pop_back();
1844 }
1845 }
1846 }
1847
1848 // Remove the references from our temporary screen to prevent freeing on the DTOR
1849 tempScreen->Clear( false );
1850
1851 for( EDA_ITEM* item : loadedItems )
1852 {
1853 KIID_PATH clipPath( wxT( "/" ) ); // clipboard is at root
1854
1855 SCH_ITEM* schItem = static_cast<SCH_ITEM*>( item );
1856
1857 wxCHECK2( schItem, continue );
1858
1859 if( schItem->IsConnectable() )
1860 schItem->SetConnectivityDirty();
1861
1862 if( item->Type() == SCH_SYMBOL_T )
1863 {
1864 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1865
1866 // The library symbol gets set from the cached library symbols in the current
1867 // schematic not the symbol libraries. The cached library symbol may have
1868 // changed from the original library symbol which would cause the copy to
1869 // be incorrect.
1870 SCH_SCREEN* currentScreen = m_frame->GetScreen();
1871
1872 wxCHECK2( currentScreen, continue );
1873
1874 auto it = currentScreen->GetLibSymbols().find( symbol->GetSchSymbolLibraryName() );
1875 auto end = currentScreen->GetLibSymbols().end();
1876
1877 if( it == end )
1878 {
1879 // If can't find library definition in the design, use the pasted library
1880 it = tempScreen->GetLibSymbols().find( symbol->GetSchSymbolLibraryName() );
1881 end = tempScreen->GetLibSymbols().end();
1882 }
1883
1884 LIB_SYMBOL* libSymbol = nullptr;
1885
1886 if( it != end )
1887 {
1888 libSymbol = new LIB_SYMBOL( *it->second );
1889 symbol->SetLibSymbol( libSymbol );
1890 }
1891
1892 // If the symbol is already in the schematic we have to always keep the
1893 // annotations. The exception is if the user has chosen to remove them.
1894 for( const SCH_SYMBOL_INSTANCE& instance : symbol->GetInstances() )
1895 {
1896 if( !existingRefsSet.contains( instance.m_Reference ) )
1897 {
1898 forceKeepAnnotations = !forceRemoveAnnotations;
1899 break;
1900 }
1901 }
1902
1903 for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
1904 updatePastedSymbol( symbol, sheetPath, clipPath, forceKeepAnnotations );
1905
1906 // Most modes will need new KIIDs for the symbol and its pins
1907 // However, if we are pasting unique annotations, we need to check if the symbol
1908 // is not already in the hierarchy. If we don't already have a copy of the
1909 // symbol, we just keep the existing KIID data as it is likely the same symbol
1910 // being moved around the schematic
1911 bool needsNewKiid = ( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS );
1912
1913 for( const SCH_SYMBOL_INSTANCE& instance : symbol->GetInstances() )
1914 {
1915 if( existingRefsSet.contains( instance.m_Reference ) )
1916 {
1917 needsNewKiid = true;
1918 break;
1919 }
1920 }
1921
1922 if( needsNewKiid )
1923 {
1924 // Assign a new KIID
1925 const_cast<KIID&>( item->m_Uuid ) = KIID();
1926
1927 // Make sure pins get a new UUID
1928 for( SCH_PIN* pin : symbol->GetPins() )
1929 {
1930 const_cast<KIID&>( pin->m_Uuid ) = KIID();
1931 pin->SetConnectivityDirty();
1932 }
1933
1934 for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
1935 {
1936 // Ignore symbols from a non-existant library.
1937 if( libSymbol )
1938 {
1939 SCH_REFERENCE schReference( symbol, sheetPath );
1940 schReference.SetSheetNumber( sheetPath.GetVirtualPageNumber() );
1941 pastedSymbols[sheetPath].AddItem( schReference );
1942 }
1943 }
1944 }
1945 }
1946 else if( item->Type() == SCH_SHEET_T )
1947 {
1948 SCH_SHEET* sheet = (SCH_SHEET*) item;
1949 SCH_FIELD* nameField = sheet->GetField( FIELD_T::SHEET_NAME );
1950 wxString baseName = nameField->GetText();
1951 wxString candidateName = baseName;
1952 wxString number;
1953
1954 while( !baseName.IsEmpty() && wxIsdigit( baseName.Last() ) )
1955 {
1956 number = baseName.Last() + number;
1957 baseName.RemoveLast();
1958 }
1959
1960 // Update hierarchy to include any other sheets we already added, avoiding
1961 // duplicate sheet names
1962 hierarchy = m_frame->Schematic().Hierarchy();
1963
1964 int uniquifier = std::max( 0, wxAtoi( number ) ) + 1;
1965
1966 while( existingSheetNames.count( candidateName ) )
1967 candidateName = wxString::Format( wxT( "%s%d" ), baseName, uniquifier++ );
1968
1969 nameField->SetText( candidateName );
1970 existingSheetNames.emplace( candidateName );
1971
1972 wxFileName fn = sheet->GetFileName();
1973 SCH_SCREEN* existingScreen = nullptr;
1974
1975 sheet->SetParent( pasteRoot.Last() );
1976 sheet->SetScreen( nullptr );
1977
1978 if( !fn.IsAbsolute() )
1979 {
1980 wxFileName currentSheetFileName = pasteRoot.LastScreen()->GetFileName();
1981 fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS,
1982 currentSheetFileName.GetPath() );
1983 }
1984
1985 // Try to find the screen for the pasted sheet by several means
1986 if( !m_frame->Schematic().Root().SearchHierarchy( fn.GetFullPath( wxPATH_UNIX ),
1987 &existingScreen ) )
1988 {
1989 if( loadedScreens.count( sheet->GetFileName() ) > 0 )
1990 existingScreen = loadedScreens.at( sheet->GetFileName() );
1991 else
1992 searchSupplementaryClipboard( sheet->GetFileName(), &existingScreen );
1993 }
1994
1995 if( existingScreen )
1996 {
1997 sheet->SetScreen( existingScreen );
1998 }
1999 else
2000 {
2001 if( !m_frame->LoadSheetFromFile( sheet, &pasteRoot, fn.GetFullPath() ) )
2002 m_frame->InitSheet( sheet, sheet->GetFileName() );
2003 }
2004
2005 // Save the symbol instances in case the user chooses to keep the existing
2006 // symbol annotation.
2008 sheetsPasted = true;
2009
2010 // Push it to the clipboard path while it still has its old KIID
2011 clipPath.push_back( sheet->m_Uuid );
2012
2013 // Assign a new KIID to the pasted sheet
2014 const_cast<KIID&>( sheet->m_Uuid ) = KIID();
2015
2016 // Make sure pins get a new UUID
2017 for( SCH_SHEET_PIN* pin : sheet->GetPins() )
2018 {
2019 const_cast<KIID&>( pin->m_Uuid ) = KIID();
2020 pin->SetConnectivityDirty();
2021 }
2022
2023 // Once we have our new KIID we can update all pasted instances. This will either
2024 // reset the annotations or copy "kept" annotations from the supplementary clipboard.
2025 for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
2026 {
2027 SCH_SHEET_PATH subPath = updatePastedSheet( sheet, sheetPath, clipPath,
2028 ( forceKeepAnnotations && annotate.automatic ),
2029 &pastedSheets[sheetPath],
2030 pastedSymbols );
2031 }
2032 }
2033 else
2034 {
2035 SCH_ITEM* srcItem = dynamic_cast<SCH_ITEM*>( itemMap[ item->m_Uuid ] );
2036 SCH_ITEM* destItem = dynamic_cast<SCH_ITEM*>( item );
2037
2038 // Everything gets a new KIID
2039 const_cast<KIID&>( item->m_Uuid ) = KIID();
2040
2041 if( srcItem && destItem )
2042 {
2043 destItem->SetConnectivityDirty( true );
2044 destItem->SetLastResolvedState( srcItem );
2045 }
2046 }
2047
2048 // Lines need both ends selected for a move after paste so the whole line moves.
2049 if( item->Type() == SCH_LINE_T )
2050 item->SetFlags( STARTPOINT | ENDPOINT );
2051
2052 item->SetFlags( IS_NEW | IS_PASTED | IS_MOVING );
2053
2054 if( !m_frame->GetScreen()->CheckIfOnDrawList( (SCH_ITEM*) item ) ) // don't want a loop!
2055 m_frame->AddToScreen( item, m_frame->GetScreen() );
2056
2057 commit.Added( (SCH_ITEM*) item, m_frame->GetScreen() );
2058
2059 // Start out hidden so the pasted items aren't "ghosted" in their original location
2060 // before being moved to the current location.
2061 getView()->Hide( item, true );
2062 }
2063
2064 if( sheetsPasted )
2065 {
2066 // The full schematic hierarchy need to be update before assigning new annotation and
2067 // page numbers.
2069
2070 // Update page numbers: Find next free numeric page number
2071 for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
2072 {
2073 for( SCH_SHEET_PATH& pastedSheet : pastedSheets[sheetPath] )
2074 {
2075 int page = 1;
2076 wxString pageNum = wxString::Format( "%d", page );
2077
2078 while( hierarchy.PageNumberExists( pageNum ) )
2079 pageNum = wxString::Format( "%d", ++page );
2080
2081 SCH_SHEET_INSTANCE sheetInstance;
2082
2083 sheetInstance.m_Path = pastedSheet.Path();
2084
2085 // Don't include the actual sheet in the instance path.
2086 sheetInstance.m_Path.pop_back();
2087 sheetInstance.m_PageNumber = pageNum;
2088 sheetInstance.m_ProjectName = m_frame->Prj().GetProjectName();
2089
2090 SCH_SHEET* sheet = pastedSheet.Last();
2091
2092 wxCHECK2( sheet, continue );
2093
2094 sheet->AddInstance( sheetInstance );
2095 hierarchy.push_back( pastedSheet );
2096
2097 // Remove all pasted sheet instance data that is not part of the current project.
2098 std::vector<KIID_PATH> instancesToRemove;
2099
2100 for( const SCH_SHEET_INSTANCE& instance : sheet->GetInstances() )
2101 {
2102 if( !hierarchy.HasPath( instance.m_Path ) )
2103 instancesToRemove.push_back( instance.m_Path );
2104 }
2105
2106 for( const KIID_PATH& instancePath : instancesToRemove )
2107 sheet->RemoveInstance( instancePath );
2108 }
2109 }
2110
2112
2113 // Get a version with correct sheet numbers since we've pasted sheets,
2114 // we'll need this when annotating next
2115 hierarchy = m_frame->Schematic().Hierarchy();
2116 }
2117
2118 std::map<SCH_SHEET_PATH, SCH_REFERENCE_LIST> annotatedSymbols;
2119
2120 // Update the list of symbol instances that satisfy the annotation criteria.
2121 for( const SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
2122 {
2123 for( size_t i = 0; i < pastedSymbols[sheetPath].GetCount(); i++ )
2124 {
2125 if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS
2126 || pasteMode == PASTE_MODE::RESPECT_OPTIONS
2127 || pastedSymbols[sheetPath][i].AlwaysAnnotate() )
2128 {
2129 annotatedSymbols[sheetPath].AddItem( pastedSymbols[sheetPath][i] );
2130 }
2131 }
2132
2133 for( const SCH_SHEET_PATH& pastedSheetPath : pastedSheets[sheetPath] )
2134 {
2135 for( size_t i = 0; i < pastedSymbols[pastedSheetPath].GetCount(); i++ )
2136 {
2137 if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS
2138 || pasteMode == PASTE_MODE::RESPECT_OPTIONS
2139 || pastedSymbols[pastedSheetPath][i].AlwaysAnnotate() )
2140 {
2141 annotatedSymbols[pastedSheetPath].AddItem( pastedSymbols[pastedSheetPath][i] );
2142 }
2143 }
2144 }
2145 }
2146
2147 if( !annotatedSymbols.empty() )
2148 {
2149 for( SCH_SHEET_PATH& path : sheetPathsForScreen )
2150 {
2151 annotatedSymbols[path].SortByReferenceOnly();
2152
2153 if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS )
2154 {
2155 annotatedSymbols[path].ReannotateDuplicates( existingRefs );
2156 }
2157 else
2158 {
2159 annotatedSymbols[path].ReannotateByOptions( (ANNOTATE_ORDER_T) annotate.sort_order,
2160 (ANNOTATE_ALGO_T) annotate.method,
2161 annotateStartNum, existingRefs, false,
2162 &hierarchy );
2163 }
2164
2165 annotatedSymbols[path].UpdateAnnotation();
2166
2167 // Update existing refs for next iteration
2168 for( size_t i = 0; i < annotatedSymbols[path].GetCount(); i++ )
2169 existingRefs.AddItem( annotatedSymbols[path][i] );
2170
2171 for( const SCH_SHEET_PATH& pastedSheetPath : pastedSheets[path] )
2172 {
2173 annotatedSymbols[pastedSheetPath].SortByReferenceOnly();
2174
2175 if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS )
2176 {
2177 annotatedSymbols[pastedSheetPath].ReannotateDuplicates( existingRefs );
2178 }
2179 else
2180 {
2181 annotatedSymbols[pastedSheetPath].ReannotateByOptions( (ANNOTATE_ORDER_T) annotate.sort_order,
2182 (ANNOTATE_ALGO_T) annotate.method,
2183 annotateStartNum, existingRefs,
2184 false,
2185 &hierarchy );
2186 }
2187
2188 annotatedSymbols[pastedSheetPath].UpdateAnnotation();
2189
2190 // Update existing refs for next iteration
2191 for( size_t i = 0; i < annotatedSymbols[pastedSheetPath].GetCount(); i++ )
2192 existingRefs.AddItem( annotatedSymbols[pastedSheetPath][i] );
2193 }
2194 }
2195 }
2196
2198
2199 // The copy operation creates instance paths that are not valid for the current project or
2200 // saved as part of another project. Prune them now so they do not accumulate in the saved
2201 // schematic file.
2203
2205 SCH_SCREENS allScreens( m_frame->Schematic().Root() );
2206
2207 allScreens.PruneOrphanedSymbolInstances( m_frame->Prj().GetProjectName(), sheets );
2208 allScreens.PruneOrphanedSheetInstances( m_frame->Prj().GetProjectName(), sheets );
2209
2210 // Now clear the previous selection, select the pasted items, and fire up the "move" tool.
2212
2213 // If the item has a parent group, it will be part of the loadedItems, and will handle
2214 // the move action. Iterate backwards to avoid invalidating the iterator.
2215 for( int i = loadedItems.size() - 1; i >= 0; i-- )
2216 {
2217 EDA_ITEM* item = loadedItems[i];
2218
2219 if( item->GetParentGroup() )
2220 {
2221 loadedItems.erase( loadedItems.begin() + i );
2222 // These were hidden before because they would be added to the move preview,
2223 // but now they need to be shown as a preview so they appear to move when
2224 // the group moves.
2225 getView()->SetVisible( item );
2226 getView()->AddToPreview( item, false );
2227 }
2228 }
2229
2231
2232 SCH_SELECTION& selection = selTool->GetSelection();
2233
2234 if( !selection.Empty() )
2235 {
2236 if( aEvent.IsAction( &ACTIONS::duplicate ) )
2237 {
2238 int closest_dist = INT_MAX;
2239
2240 auto processPt =
2241 [&]( const VECTOR2I& pt )
2242 {
2243 int dist = ( eventPos - pt ).EuclideanNorm();
2244
2245 if( dist < closest_dist )
2246 {
2247 selection.SetReferencePoint( pt );
2248 closest_dist = dist;
2249 }
2250 };
2251
2252 // Prefer connection points (which should remain on grid)
2253 for( EDA_ITEM* item : selection.Items() )
2254 {
2255 SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
2256 SCH_PIN* pin = dynamic_cast<SCH_PIN*>( item );
2257
2258 if( sch_item && sch_item->IsConnectable() )
2259 {
2260 for( const VECTOR2I& pt : sch_item->GetConnectionPoints() )
2261 processPt( pt );
2262 }
2263 else if( pin )
2264 {
2265 processPt( pin->GetPosition() );
2266 }
2267
2268 // Symbols need to have their center point added since often users are trying to
2269 // move parts from their center.
2270 if( dynamic_cast<SCH_SYMBOL*>( item ) )
2271 processPt( item->GetPosition() );
2272 }
2273
2274 // Only process other points if we didn't find any connection points
2275 if( closest_dist == INT_MAX )
2276 {
2277 for( EDA_ITEM* item : selection.Items() )
2278 {
2279 switch( item->Type() )
2280 {
2281 case SCH_LINE_T:
2282 processPt( static_cast<SCH_LINE*>( item )->GetStartPoint() );
2283 processPt( static_cast<SCH_LINE*>( item )->GetEndPoint() );
2284 break;
2285
2286 case SCH_SHAPE_T:
2287 {
2288 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( item );
2289
2290 switch( shape->GetShape() )
2291 {
2292 case SHAPE_T::RECTANGLE:
2293 for( const VECTOR2I& pt : shape->GetRectCorners() )
2294 processPt( pt );
2295
2296 break;
2297
2298 case SHAPE_T::CIRCLE:
2299 processPt( shape->GetCenter() );
2300 break;
2301
2302 case SHAPE_T::POLY:
2303 for( int ii = 0; ii < shape->GetPolyShape().TotalVertices(); ++ii )
2304 processPt( shape->GetPolyShape().CVertex( ii ) );
2305
2306 break;
2307
2308 default:
2309 processPt( shape->GetStart() );
2310 processPt( shape->GetEnd() );
2311 break;
2312 }
2313
2314 break;
2315 }
2316
2317 default:
2318 processPt( item->GetPosition() );
2319 break;
2320 }
2321 }
2322 }
2323
2324 selection.SetIsHover( m_duplicateIsHoverSelection );
2325 }
2326 // We want to the first non-group item in the selection to be the reference point.
2327 else if( selection.GetTopLeftItem()->Type() == SCH_GROUP_T )
2328 {
2329 SCH_GROUP* group = static_cast<SCH_GROUP*>( selection.GetTopLeftItem() );
2330
2331 bool found = false;
2332 SCH_ITEM* item = nullptr;
2333
2334 group->RunOnChildren(
2335 [&]( SCH_ITEM* schItem )
2336 {
2337 if( !found && schItem->Type() != SCH_GROUP_T )
2338 {
2339 item = schItem;
2340 found = true;
2341 }
2342 },
2343 RECURSE_MODE::RECURSE );
2344
2345 if( found )
2346 selection.SetReferencePoint( item->GetPosition() );
2347 else
2348 selection.SetReferencePoint( group->GetPosition() );
2349 }
2350 else
2351 {
2352 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetTopLeftItem() );
2353
2354 selection.SetReferencePoint( item->GetPosition() );
2355 }
2356
2358 {
2359 // Pushing the commit will update the connectivity.
2360 commit.Push( _( "Paste" ) );
2361
2362 if( sheetsPasted )
2363 {
2365 // UpdateHierarchyNavigator() will call RefreshNetNavigator()
2366 }
2367 else
2368 {
2370 }
2371 }
2372 else
2373 {
2374 commit.Revert();
2375 }
2376
2377 getView()->ClearPreview();
2378 }
2379
2380 return 0;
2381}
2382
2383
2385{
2387 SCH_SELECTION& selection = selTool->RequestSelection( { SCH_SYMBOL_T } );
2388 SCH_SYMBOL* symbol = nullptr;
2389 SYMBOL_EDIT_FRAME* symbolEditor;
2390
2391 if( selection.GetSize() >= 1 )
2392 symbol = (SCH_SYMBOL*) selection.Front();
2393
2394 if( selection.IsHover() )
2396
2397 if( !symbol )
2398 {
2399 // Giant hack: by default we assign Edit Table to the same hotkey, so give the table
2400 // tool a chance to handle it if we can't.
2402 tableTool->EditTable( aEvent );
2403
2404 return 0;
2405 }
2406
2407 if( symbol->GetEditFlags() != 0 )
2408 return 0;
2409
2410 if( symbol->IsMissingLibSymbol() )
2411 {
2412 m_frame->ShowInfoBarError( _( "Symbols with broken library symbol links cannot "
2413 "be edited." ) );
2414 return 0;
2415 }
2416
2418 symbolEditor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, false );
2419
2420 if( symbolEditor )
2421 {
2422 if( wxWindow* blocking_win = symbolEditor->Kiway().GetBlockingDialog() )
2423 blocking_win->Close( true );
2424
2425 if( aEvent.IsAction( &SCH_ACTIONS::editWithLibEdit ) )
2426 {
2427 symbolEditor->LoadSymbolFromSchematic( symbol );
2428 }
2430 {
2431 symbolEditor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(),
2432 symbol->GetBodyStyle() );
2433
2434 if( !symbolEditor->IsLibraryTreeShown() )
2435 symbolEditor->ToggleLibraryTree();
2436 }
2437 }
2438
2439 return 0;
2440}
2441
2442
2444{
2446 return 0;
2447}
2448
2449
2451{
2453 dlg.m_FirstRefDes->SetValidator( wxTextValidator( wxFILTER_EMPTY ) );
2454
2455 dlg.SetInitialFocus( dlg.m_FirstRefDes );
2456
2457 if( dlg.ShowModal() == wxID_OK )
2458 {
2459 SCH_REFERENCE startRef;
2460 startRef.SetRef( dlg.m_FirstRefDes->GetValue() );
2461
2462 if( startRef.IsSplitNeeded() )
2463 startRef.Split();
2464 else
2465 return 0;
2466
2467 int startNum = atoi( startRef.GetRefNumber().utf8_string().c_str() );
2468
2469 SCH_COMMIT commit( m_frame );
2470 SCHEMATIC* schematic = m_frame->m_schematic;
2471 SCH_REFERENCE_LIST references;
2472
2473 if( dlg.m_AllSheets->GetValue() )
2474 schematic->Hierarchy().GetSymbols( references );
2475 else
2476 schematic->CurrentSheet().GetSymbols( references );
2477
2478 references.SplitReferences();
2479
2480 for( SCH_REFERENCE& ref : references )
2481 {
2482 if( ref.GetRef() == startRef.GetRef() )
2483 {
2484 int num = atoi( ref.GetRefNumber().utf8_string().c_str() );
2485
2486 if( num >= startNum )
2487 {
2488 const SCH_SHEET_PATH& sheet = ref.GetSheetPath();
2489 wxString fullRef = ref.GetRef();
2490
2491 num += dlg.m_Increment->GetValue();
2492 fullRef << num;
2493
2494 commit.Modify( ref.GetSymbol(), sheet.LastScreen(), RECURSE_MODE::NO_RECURSE );
2495 ref.GetSymbol()->SetRef( &sheet, From_UTF8( fullRef.c_str() ) );
2496 }
2497 }
2498 }
2499
2500 if( !commit.Empty() )
2501 commit.Push( _( "Increment Annotations" ) );
2502 }
2503
2504 return 0;
2505}
2506
2507
2509{
2511 return 0;
2512}
2513
2514
2516{
2518
2519 wxCHECK( dlg, 0 );
2520
2521 // Needed at least on Windows. Raise() is not enough
2522 dlg->Show( true );
2523
2524 // Bring it to the top if already open. Dual monitor users need this.
2525 dlg->Raise();
2526
2527 dlg->ShowEditTab();
2528
2529 return 0;
2530}
2531
2532
2534{
2537
2538 return 0;
2539}
2540
2541
2543{
2545 return 0;
2546}
2547
2548
2550{
2552 return 0;
2553}
2554
2555
2557{
2559 dlg.ShowModal();
2560 return 0;
2561}
2562
2563
2565{
2566 int result = NET_PLUGIN_CHANGE;
2567
2568 // If a plugin is removed or added, rebuild and reopen the new dialog
2569 while( result == NET_PLUGIN_CHANGE )
2570 result = InvokeDialogNetList( m_frame );
2571
2572 return 0;
2573}
2574
2575
2577{
2579
2580 wxCHECK( dlg, 0 );
2581
2582 // Needed at least on Windows. Raise() is not enough
2583 dlg->Show( true );
2584
2585 // Bring it to the top if already open. Dual monitor users need this.
2586 dlg->Raise();
2587
2588 dlg->ShowExportTab();
2589
2590 return 0;
2591}
2592
2593
2595{
2597 return 0;
2598}
2599
2600
2602{
2605 return 0;
2606}
2607
2608
2610{
2611 getEditFrame<SCH_EDIT_FRAME>()->ToggleSearch();
2612 return 0;
2613}
2614
2615
2617{
2618 getEditFrame<SCH_EDIT_FRAME>()->ToggleSchematicHierarchy();
2619 return 0;
2620}
2621
2622
2624{
2625 getEditFrame<SCH_EDIT_FRAME>()->ToggleNetNavigator();
2626 return 0;
2627}
2628
2629
2631{
2632 getEditFrame<SCH_EDIT_FRAME>()->ToggleProperties();
2633 return 0;
2634}
2635
2636
2638{
2639 getEditFrame<SCH_EDIT_FRAME>()->ToggleLibraryTree();
2640 return 0;
2641}
2642
2643
2645{
2648
2651
2652 return 0;
2653}
2654
2655
2657{
2660
2663
2664 return 0;
2665}
2666
2667
2669{
2672
2675
2676 return 0;
2677}
2678
2679
2681{
2684
2687
2688 return 0;
2689}
2690
2691
2693{
2696
2699
2700 return 0;
2701}
2702
2703
2705{
2708
2710
2711 return 0;
2712}
2713
2714
2716{
2719
2721 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
2722 {
2723 int flags = 0;
2724
2725 auto invalidateTextVars =
2726 [&flags]( EDA_TEXT* text )
2727 {
2728 if( text->HasTextVars() )
2729 {
2730 text->ClearRenderCache();
2731 text->ClearBoundingBoxCache();
2733 }
2734 };
2735
2736 if( SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aItem ) )
2737 {
2738 item->RunOnChildren(
2739 [&invalidateTextVars]( SCH_ITEM* aChild )
2740 {
2741 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aChild ) )
2742 invalidateTextVars( text );
2743 },
2744 RECURSE_MODE::NO_RECURSE );
2745
2746 if( item->GetExcludedFromSim() )
2748 }
2749
2750 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aItem ) )
2751 invalidateTextVars( text );
2752
2753 return flags;
2754 } );
2755
2757
2758 return 0;
2759}
2760
2761
2763{
2766
2770
2771 return 0;
2772}
2773
2774
2776{
2779
2783
2784 return 0;
2785}
2786
2787
2789{
2792
2794
2797
2798 return 0;
2799}
2800
2801
2803{
2806 return 0;
2807}
2808
2809
2811{
2813 m_frame->eeconfig()->m_Drawing.line_mode %= LINE_MODE::LINE_MODE_COUNT;
2815 return 0;
2816}
2817
2818
2820{
2823 return 0;
2824}
2825
2826
2828{
2831 return 0;
2832}
2833
2834
2836{
2837
2839 return 0;
2840}
2841
2842
2844{
2845#ifdef KICAD_IPC_API
2846 if( Pgm().GetCommonSettings()->m_Api.enable_server )
2847 Pgm().GetPluginManager().ReloadPlugins();
2848#endif
2849 return 0;
2850}
2851
2852
2854{
2855 int errors = 0;
2856 wxString details;
2857 bool quiet = aEvent.Parameter<bool>();
2858
2859 // Repair duplicate IDs.
2860 std::map<KIID, EDA_ITEM*> ids;
2861 int duplicates = 0;
2862
2864
2865 auto processItem =
2866 [&]( EDA_ITEM* aItem )
2867 {
2868 auto it = ids.find( aItem->m_Uuid );
2869
2870 if( it != ids.end() && it->second != aItem )
2871 {
2872 duplicates++;
2873 const_cast<KIID&>( aItem->m_Uuid ) = KIID();
2874 }
2875
2876 ids[ aItem->m_Uuid ] = aItem;
2877 };
2878
2879 // Symbol IDs are the most important, so give them the first crack at "claiming" a
2880 // particular KIID.
2881
2882 for( const SCH_SHEET_PATH& sheet : sheets )
2883 {
2884 SCH_SCREEN* screen = sheet.LastScreen();
2885
2886 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
2887 {
2888 processItem( item );
2889
2890 for( SCH_PIN* pin : static_cast<SCH_SYMBOL*>( item )->GetPins( &sheet ) )
2891 processItem( pin );
2892 }
2893 }
2894
2895 for( const SCH_SHEET_PATH& sheet : sheets )
2896 {
2897 SCH_SCREEN* screen = sheet.LastScreen();
2898
2899 for( SCH_ITEM* item : screen->Items() )
2900 {
2901 processItem( item );
2902
2903 if( item->Type() != SCH_GROUP_T )
2904 {
2905 item->RunOnChildren(
2906 [&]( SCH_ITEM* aChild )
2907 {
2908 processItem( item );
2909 },
2910 RECURSE_MODE::NO_RECURSE );
2911 }
2912 }
2913 }
2914
2915 /*******************************
2916 * Your test here
2917 */
2918
2919 /*******************************
2920 * Inform the user
2921 */
2922
2923 if( duplicates )
2924 {
2925 errors += duplicates;
2926 details += wxString::Format( _( "%d duplicate IDs replaced.\n" ), duplicates );
2927
2928 // Rehash sheetpaths as we may have changed their uuids.
2930 }
2931
2932 if( errors )
2933 {
2934 m_frame->OnModify();
2935
2936 wxString msg = wxString::Format( _( "%d potential problems repaired." ), errors );
2937
2938 if( !quiet )
2939 DisplayInfoMessage( m_frame, msg, details );
2940 }
2941 else if( !quiet )
2942 {
2943 DisplayInfoMessage( m_frame, _( "No errors found." ) );
2944 }
2945
2946 return 0;
2947}
2948
2949
2951{
2952 if( !Pgm().GetCommonSettings()->m_Input.hotkey_feedback )
2953 return 0;
2954
2955 GRID_SETTINGS& gridSettings = m_toolMgr->GetSettings()->m_Window.grid;
2956 int currentIdx = m_toolMgr->GetSettings()->m_Window.grid.last_size_idx;
2957
2958 wxArrayString gridsLabels;
2959
2960 for( const GRID& grid : gridSettings.grids )
2961 gridsLabels.Add( grid.UserUnitsMessageText( m_frame ) );
2962
2963 if( !m_frame->GetHotkeyPopup() )
2965
2967
2968 if( popup )
2969 popup->Popup( _( "Grid" ), gridsLabels, currentIdx );
2970
2971 return 0;
2972}
2973
2974
2976{
2977 SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
2978
2979 if( !editFrame )
2980 return 1;
2981
2982 // Need to have a group selected and it needs to have a linked design block
2984 SCH_SELECTION selection = selTool->GetSelection();
2985
2986 if( selection.Size() != 1 || selection[0]->Type() != SCH_GROUP_T )
2987 return 1;
2988
2989 SCH_GROUP* group = static_cast<SCH_GROUP*>( selection[0] );
2990
2991 if( !group->HasDesignBlockLink() )
2992 return 1;
2993
2994 // Get the associated design block
2995 DESIGN_BLOCK_PANE* designBlockPane = editFrame->GetDesignBlockPane();
2996 std::unique_ptr<DESIGN_BLOCK> designBlock( designBlockPane->GetDesignBlock( group->GetDesignBlockLibId(),
2997 true, true ) );
2998
2999 if( !designBlock )
3000 {
3001 wxString msg;
3002 msg.Printf( _( "Could not find design block %s." ), group->GetDesignBlockLibId().GetUniStringLibId() );
3003 m_frame->GetInfoBar()->ShowMessageFor( msg, 5000, wxICON_WARNING );
3004 return 1;
3005 }
3006
3007 if( designBlock->GetSchematicFile().IsEmpty() )
3008 {
3009 wxString msg;
3010 msg.Printf( _( "Design block %s does not have a schematic file." ),
3011 group->GetDesignBlockLibId().GetUniStringLibId() );
3012 m_frame->GetInfoBar()->ShowMessageFor( msg, 5000, wxICON_WARNING );
3013 return 1;
3014 }
3015
3016 editFrame->GetDesignBlockPane()->SelectLibId( group->GetDesignBlockLibId() );
3017
3018 return m_toolMgr->RunAction( SCH_ACTIONS::placeDesignBlock, designBlock.release() );
3019}
3020
3021
3023{
3024 SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
3025
3026 if( !editFrame )
3027 return 1;
3028
3029 // Need to have a group selected and it needs to have a linked design block
3031 SCH_SELECTION selection = selTool->GetSelection();
3032
3033 if( selection.Size() != 1 || selection[0]->Type() != SCH_GROUP_T )
3034 return 1;
3035
3036 SCH_GROUP* group = static_cast<SCH_GROUP*>( selection[0] );
3037
3038 if( !group->HasDesignBlockLink() )
3039 return 1;
3040
3041 // Get the associated design block
3042 DESIGN_BLOCK_PANE* designBlockPane = editFrame->GetDesignBlockPane();
3043 std::unique_ptr<DESIGN_BLOCK> designBlock( designBlockPane->GetDesignBlock( group->GetDesignBlockLibId(),
3044 true, true ) );
3045
3046 if( !designBlock )
3047 {
3048 wxString msg;
3049 msg.Printf( _( "Could not find design block %s." ), group->GetDesignBlockLibId().GetUniStringLibId() );
3050 m_frame->GetInfoBar()->ShowMessageFor( msg, 5000, wxICON_WARNING );
3051 return 1;
3052 }
3053
3054 editFrame->GetDesignBlockPane()->SelectLibId( group->GetDesignBlockLibId() );
3055
3057}
3058
3059
3061{
3062 Go( &SCH_EDITOR_CONTROL::New, ACTIONS::doNew.MakeEvent() );
3063 Go( &SCH_EDITOR_CONTROL::Open, ACTIONS::open.MakeEvent() );
3064 Go( &SCH_EDITOR_CONTROL::Save, ACTIONS::save.MakeEvent() );
3071 Go( &SCH_EDITOR_CONTROL::Plot, ACTIONS::plot.MakeEvent() );
3072 Go( &SCH_EDITOR_CONTROL::Quit, ACTIONS::quit.MakeEvent() );
3073
3076
3082
3085
3091
3093
3094 Go( &SCH_EDITOR_CONTROL::Undo, ACTIONS::undo.MakeEvent() );
3095 Go( &SCH_EDITOR_CONTROL::Redo, ACTIONS::redo.MakeEvent() );
3096 Go( &SCH_EDITOR_CONTROL::Cut, ACTIONS::cut.MakeEvent() );
3097 Go( &SCH_EDITOR_CONTROL::Copy, ACTIONS::copy.MakeEvent() );
3102
3104
3120
3127
3143
3145
3147
3150
3153}
const char * name
Definition: DXF_plotter.cpp:62
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
static TOOL_ACTION updatePcbFromSchematic
Definition: actions.h:257
static TOOL_ACTION paste
Definition: actions.h:80
static TOOL_ACTION revert
Definition: actions.h:62
static TOOL_ACTION saveAs
Definition: actions.h:59
static TOOL_ACTION copy
Definition: actions.h:78
static TOOL_ACTION pluginsReload
Definition: actions.h:287
static TOOL_ACTION pickerTool
Definition: actions.h:246
static TOOL_ACTION showSymbolEditor
Definition: actions.h:253
static TOOL_ACTION pasteSpecial
Definition: actions.h:81
static TOOL_ACTION plot
Definition: actions.h:65
static TOOL_ACTION open
Definition: actions.h:57
static TOOL_ACTION pageSettings
Definition: actions.h:63
static TOOL_ACTION showSearch
Definition: actions.h:115
static TOOL_ACTION undo
Definition: actions.h:75
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: actions.h:211
static TOOL_ACTION duplicate
Definition: actions.h:84
static TOOL_ACTION doDelete
Definition: actions.h:85
static TOOL_ACTION quit
Definition: actions.h:66
static TOOL_ACTION save
Definition: actions.h:58
static TOOL_ACTION redo
Definition: actions.h:76
static TOOL_ACTION updateSchematicFromPcb
Definition: actions.h:258
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: actions.h:217
static TOOL_ACTION print
Definition: actions.h:64
static TOOL_ACTION showProperties
Definition: actions.h:259
static TOOL_ACTION doNew
Definition: actions.h:54
static TOOL_ACTION cut
Definition: actions.h:77
static TOOL_ACTION copyAsText
Definition: actions.h:79
static TOOL_ACTION refreshPreview
Definition: actions.h:156
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
Definition: actions.h:225
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
WINDOW_SETTINGS m_Window
Definition: app_settings.h:234
static wxString m_DrawingSheetFileName
the name of the drawing sheet file, or empty to use the default drawing sheet
Definition: base_screen.h:85
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:82
int m_Threshold
Definition: collector.h:235
COMMIT & Added(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
Definition: commit.h:85
bool Empty() const
Definition: commit.h:150
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition: commit.h:107
Calculate the connectivity of a schematic and generates netlists.
CONNECTION_SUBGRAPH * FindSubgraphByName(const wxString &aNetName, const SCH_SHEET_PATH &aPath)
Return the subgraph for a given net name on a given sheet.
const std::vector< CONNECTION_SUBGRAPH * > & GetAllSubgraphs(const wxString &aNetName) const
A subgraph is a set of items that are electrically connected on a single sheet.
PRIORITY GetDriverPriority()
void SelectLibId(const LIB_ID &aLibId)
DESIGN_BLOCK * GetDesignBlock(const LIB_ID &aLibId, bool aUseCacheLib, bool aShowErrorMsg)
Load design block from design block library table.
Class DIALOG_INCREMENT_ANNOTATIONS_BASE.
void SetWksFileName(const wxString &aFilename)
bool PrjConfigChanged()
Return true if the project configuration was modified.
bool Show(bool show) override
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:66
int ShowQuasiModal()
int ShowModal() override
virtual void PushCommandToUndoList(PICKED_ITEMS_LIST *aItem)
Add a command to undo in the undo list.
virtual int GetRedoCommandCount() const
virtual void ClearUndoRedoList()
Clear the undo and redo list using ClearUndoORRedoList()
virtual PICKED_ITEMS_LIST * PopCommandFromRedoList()
Return the last command to undo and remove it from list, nothing is deleted.
virtual PICKED_ITEMS_LIST * PopCommandFromUndoList()
Return the last command to undo and remove it from list, nothing is deleted.
virtual int GetUndoCommandCount() const
virtual void PushCommandToRedoList(PICKED_ITEMS_LIST *aItem)
Add a command to redo in the redo list.
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false, WX_INFOBAR::MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
WX_INFOBAR * GetInfoBar()
HOTKEY_CYCLE_POPUP * GetHotkeyPopup()
void ReleaseFile()
Release the current file marked in use.
void ScriptingConsoleEnableDisable()
Toggle the scripting console visibility.
bool LibraryFileBrowser(bool doOpen, wxFileName &aFilename, const wxString &wildcard, const wxString &ext, bool isDirectory=false, bool aIsGlobal=false, const wxString &aGlobalPath=wxEmptyString)
virtual void CreateHotkeyPopup()
GAL_TYPE GetBackend() const
Return the type of backend currently used by GAL canvas.
void ForceRefresh()
Force a redraw.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:97
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:259
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:147
const KIID m_Uuid
Definition: eda_item.h:502
virtual EDA_GROUP * GetParentGroup() const
Definition: eda_item.h:115
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:109
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition: eda_item.h:191
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:112
void ClearBrightened()
Definition: eda_item.h:137
void SetBrightened()
Definition: eda_item.h:134
EDA_ITEM * GetParent() const
Definition: eda_item.h:111
bool IsBrightened() const
Definition: eda_item.h:128
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:337
SHAPE_T GetShape() const
Definition: eda_shape.h:168
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:215
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:173
std::vector< VECTOR2I > GetRectCorners() const
Definition: eda_shape.cpp:1590
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:79
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:97
virtual bool IsVisible() const
Definition: eda_text.h:184
PANEL_ANNOTATE m_AnnotatePanel
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:241
Definition: erc.h:52
static const TOOL_EVENT ClearedEvent
Definition: actions.h:340
static const TOOL_EVENT GridChangedByKeyEvent
Definition: actions.h:358
static const TOOL_EVENT SelectedEvent
Definition: actions.h:338
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:345
static const TOOL_EVENT PointSelectedEvent
Definition: actions.h:337
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:339
Similar to EDA_VIEW_SWITCHER, this dialog is a popup that shows feedback when using a hotkey to cycle...
void Popup(const wxString &aTitle, const wxArrayString &aItems, int aSelection)
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
An interface for classes handling user events controlling the view behavior such as zooming,...
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
An abstract base class for deriving all objects that can be added to a VIEW.
Definition: view_item.h:86
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:67
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1675
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition: view.h:396
void ClearPreview()
Definition: view.cpp:1697
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition: view.cpp:1551
void Hide(VIEW_ITEM *aItem, bool aHide=true, bool aHideOverlay=false)
Temporarily hide the item in the view (e.g.
Definition: view.cpp:1623
void AddToPreview(VIEW_ITEM *aItem, bool aTakeOwnership=true)
Definition: view.cpp:1719
void MarkDirty()
Force redraw of view on the next rendering.
Definition: view.h:655
void UpdateAllItemsConditionally(int aUpdateFlags, std::function< bool(VIEW_ITEM *)> aCondition)
Update items in the view according to the given flags and condition.
Definition: view.cpp:1561
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition: view.cpp:1602
bool EndsWith(const KIID_PATH &aPath) const
Test if aPath from the last path towards the first path.
Definition: kiid.cpp:335
wxString AsString() const
Definition: kiid.cpp:356
Definition: kiid.h:49
wxString AsString() const
Definition: kiid.cpp:246
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:55
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:65
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:395
wxWindow * GetBlockingDialog()
Gets the window pointer to the blocking dialog (to send it signals)
Definition: kiway.cpp:637
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition: lib_id.cpp:100
Define a library symbol object.
Definition: lib_symbol.h:85
const LIB_ID & GetLibId() const override
Definition: lib_symbol.h:155
wxString GetName() const override
Definition: lib_symbol.h:149
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:345
const wxString & GetNickName() const
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
static void ConvertToSpiceMarkup(wxString *aNetName)
Remove formatting wrappers and replace illegal spice net name characters with underscores.
Tree view item data for the net navigator.
static bool ParseBusGroup(const wxString &aGroup, wxString *name, std::vector< wxString > *aMemberList)
Parse a bus group label into the name and a list of components.
static bool ParseBusVector(const wxString &aBus, wxString *aName, std::vector< wxString > *aMemberList)
Parse a bus vector (e.g.
static wxString GetDefaultUserSymbolsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:88
A holder to handle information on schematic or board items.
void PushItem(const ITEM_PICKER &aItem)
Push aItem to the top of the list.
void SetDescription(const wxString &aDescription)
void ReversePickersListOrder()
Reverse the order of pickers stored in this list.
void SetMotionHandler(MOTION_HANDLER aHandler)
Set a handler for mouse motion.
Definition: picker_tool.h:92
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:81
void SetSnapping(bool aSnap)
Definition: picker_tool.h:66
void ClearHandlers()
Definition: picker_tool.h:68
void SetCursor(KICURSOR aCursor)
Definition: picker_tool.h:64
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:112
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:148
virtual const wxString GetProjectName() const
Return the short name of the project.
Definition: project.cpp:160
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:166
static bool RescueProject(wxWindow *aParent, RESCUER &aRescuer, bool aRunningOnDemand)
size_t GetCandidateCount()
Return the number of rescue candidates found.
Holds all the data relating to one schematic.
Definition: schematic.h:87
SCH_SHEET_LIST BuildSheetListSortedByPageNumbers() const
Definition: schematic.h:107
wxString GetFileName() const
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:311
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:317
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
Definition: schematic.cpp:219
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition: schematic.cpp:888
CONNECTION_GRAPH * ConnectionGraph() const
Definition: schematic.h:182
SCH_SHEET & Root() const
Definition: schematic.h:139
SCH_SHEET_PATH & CurrentSheet() const
Definition: schematic.h:170
void RefreshHierarchy()
Definition: schematic.cpp:227
static TOOL_ACTION showPcbNew
Definition: sch_actions.h:174
static TOOL_ACTION assignFootprints
Definition: sch_actions.h:157
static TOOL_ACTION lineModeNext
Definition: sch_actions.h:268
static TOOL_ACTION toggleOPCurrents
Definition: sch_actions.h:244
static TOOL_ACTION saveToLinkedDesignBlock
Definition: sch_actions.h:71
static TOOL_ACTION clearHighlight
Definition: sch_actions.h:298
static TOOL_ACTION editSymbolFields
Definition: sch_actions.h:149
static TOOL_ACTION importFPAssignments
Definition: sch_actions.h:175
static TOOL_ACTION toggleAnnotateAuto
Definition: sch_actions.h:271
static TOOL_ACTION editLibSymbolWithLibEdit
Definition: sch_actions.h:173
static TOOL_ACTION toggleERCWarnings
Definition: sch_actions.h:239
static TOOL_ACTION schematicSetup
Definition: sch_actions.h:159
static TOOL_ACTION toggleDirectiveLabels
Definition: sch_actions.h:238
static TOOL_ACTION highlightNetTool
Definition: sch_actions.h:300
static TOOL_ACTION toggleHiddenFields
Definition: sch_actions.h:235
static TOOL_ACTION saveCurrSheetCopyAs
Definition: sch_actions.h:43
static TOOL_ACTION exportSymbolsToNewLibrary
Definition: sch_actions.h:182
static TOOL_ACTION repairSchematic
Definition: sch_actions.h:260
static TOOL_ACTION remapSymbols
Definition: sch_actions.h:166
static TOOL_ACTION lineMode45
Definition: sch_actions.h:267
static TOOL_ACTION editSymbolLibraryLinks
Definition: sch_actions.h:150
static TOOL_ACTION simTune
Definition: sch_actions.h:284
static TOOL_ACTION generateBOM
Definition: sch_actions.h:177
static TOOL_ACTION showHierarchy
Definition: sch_actions.h:226
static TOOL_ACTION showNetNavigator
Definition: sch_actions.h:301
static TOOL_ACTION markSimExclusions
Definition: sch_actions.h:242
static TOOL_ACTION editWithLibEdit
Definition: sch_actions.h:172
static TOOL_ACTION toggleERCErrors
Definition: sch_actions.h:240
static TOOL_ACTION incrementAnnotations
Definition: sch_actions.h:148
static TOOL_ACTION saveSelectionToDesignBlock
Definition: sch_actions.h:195
static TOOL_ACTION rescueSymbols
Definition: sch_actions.h:165
static TOOL_ACTION placeLinkedDesignBlock
Definition: sch_actions.h:70
static TOOL_ACTION generateBOMLegacy
Definition: sch_actions.h:178
static TOOL_ACTION placeDesignBlock
Definition: sch_actions.h:69
static TOOL_ACTION toggleOPVoltages
Definition: sch_actions.h:243
static TOOL_ACTION simProbe
Definition: sch_actions.h:283
static TOOL_ACTION lineMode90
Definition: sch_actions.h:266
static TOOL_ACTION lineModeFree
Definition: sch_actions.h:265
static TOOL_ACTION changeSheet
Definition: sch_actions.h:218
static TOOL_ACTION highlightNet
Definition: sch_actions.h:297
static TOOL_ACTION assignNetclass
Definition: sch_actions.h:158
static TOOL_ACTION annotate
Definition: sch_actions.h:147
static TOOL_ACTION showDesignBlockPanel
Definition: sch_actions.h:191
static TOOL_ACTION togglePinAltIcons
Definition: sch_actions.h:245
static TOOL_ACTION toggleERCExclusions
Definition: sch_actions.h:241
static TOOL_ACTION updateNetHighlighting
Definition: sch_actions.h:299
static TOOL_ACTION exportNetlist
Definition: sch_actions.h:176
static TOOL_ACTION drawSheetOnClipboard
Definition: sch_actions.h:255
static TOOL_ACTION exportSymbolsToLibrary
Definition: sch_actions.h:181
static TOOL_ACTION toggleHiddenPins
Definition: sch_actions.h:234
static TOOL_ACTION selectOnPCB
Definition: sch_actions.h:248
static TOOL_ACTION move
Definition: sch_actions.h:117
SCH_RENDER_SETTINGS * GetRenderSettings()
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
SYMBOL_LIB_TABLE * SelectSymLibTable(bool aOptional=false)
Display a dialog asking the user to select a symbol library table.
wxString SelectLibraryFromList()
Display a list of loaded libraries and allows the user to select a library.
void SyncView()
Mark all items for refresh.
EESCHEMA_SETTINGS * eeconfig() const
void AddToScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen=nullptr) override
Add an item to the screen (and view) aScreen is the screen the item is located on,...
Base class for a bus or wire entry.
Definition: sch_bus_entry.h:38
void Collect(SCH_SCREEN *aScreen, const std::vector< KICAD_T > &aScanTypes, const VECTOR2I &aPos, int aUnit=0, int aConvert=0)
Scan a EDA_ITEM using this class's Inspector method which does the collection.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Definition: sch_commit.cpp:489
virtual void Revert() override
Revert the commit by restoring the modified items state.
Definition: sch_commit.cpp:567
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString Name(bool aIgnoreSheet=false) const
bool IsBus() const
SCH_ITEM * Driver() const
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
Handle actions specific to the schematic editor.
int PageSetup(const TOOL_EVENT &aEvent)
bool RescueLegacyProject(bool aRunningOnDemand)
int ToggleDirectiveLabels(const TOOL_EVENT &aEvent)
int SaveAs(const TOOL_EVENT &aEvent)
int MarkSimExclusions(const TOOL_EVENT &aEvent)
int Annotate(const TOOL_EVENT &aEvent)
int ToggleAnnotateRecursive(const TOOL_EVENT &aEvent)
int ShowSchematicSetup(const TOOL_EVENT &aEvent)
int HighlightNet(const TOOL_EVENT &aEvent)
Remove any net highlighting.
int ClearHighlight(const TOOL_EVENT &aEvent)
Update net highlighting after an edit.
int EditSymbolFields(const TOOL_EVENT &aEvent)
int GenerateBOMLegacy(const TOOL_EVENT &aEvent)
int HighlightNetCursor(const TOOL_EVENT &aEvent)
int CopyAsText(const TOOL_EVENT &aEvent)
int ImportFPAssignments(const TOOL_EVENT &aEvent)
int ChangeLineMode(const TOOL_EVENT &aEvent)
void doCrossProbeSchToPcb(const TOOL_EVENT &aEvent, bool aForce)
int ExportSymbolsToLibrary(const TOOL_EVENT &aEvent)
int SaveCurrSheetCopyAs(const TOOL_EVENT &aEvent)
Saves the currently-open schematic sheet to an other name.
bool rescueProject(RESCUER &aRescuer, bool aRunningOnDemand)
int CrossProbeToPcb(const TOOL_EVENT &aEvent)
Equivalent to the above, but initiated by the user.
int PlaceLinkedDesignBlock(const TOOL_EVENT &aEvent)
int Quit(const TOOL_EVENT &aEvent)
int RemapSymbols(const TOOL_EVENT &aEvent)
int DrawSheetOnClipboard(const TOOL_EVENT &aEvent)
SCH_SHEET_PATH updatePastedSheet(SCH_SHEET *aSheet, const SCH_SHEET_PATH &aPastePath, const KIID_PATH &aClipPath, bool aForceKeepAnnotations, SCH_SHEET_LIST *aPastedSheets, std::map< SCH_SHEET_PATH, SCH_REFERENCE_LIST > &aPastedSymbols)
int TogglePinAltIcons(const TOOL_EVENT &aEvent)
int RescueSymbols(const TOOL_EVENT &aEvent)
Perform rescue operations to recover old projects from before certain changes were made.
int AssignNetclass(const TOOL_EVENT &aEvent)
std::string m_duplicateClipboard
int ExportNetlist(const TOOL_EVENT &aEvent)
int Open(const TOOL_EVENT &aEvent)
int Paste(const TOOL_EVENT &aEvent)
int ToggleOPVoltages(const TOOL_EVENT &aEvent)
int Copy(const TOOL_EVENT &aEvent)
int SaveToLinkedDesignBlock(const TOOL_EVENT &aEvent)
int ToggleERCWarnings(const TOOL_EVENT &aEvent)
int NextLineMode(const TOOL_EVENT &aEvent)
int Redo(const TOOL_EVENT &aEvent)
Clipboard support.
int UpdatePCB(const TOOL_EVENT &aEvent)
int UpdateFromPCB(const TOOL_EVENT &aEvent)
int ToggleAnnotateAuto(const TOOL_EVENT &aEvent)
int ToggleHiddenPins(const TOOL_EVENT &aEvent)
int Duplicate(const TOOL_EVENT &aEvent)
int IncrementAnnotations(const TOOL_EVENT &aEvent)
bool searchSupplementaryClipboard(const wxString &aSheetFilename, SCH_SCREEN **aScreen)
int GridFeedback(const TOOL_EVENT &aEvent)
int ShowSearch(const TOOL_EVENT &aEvent)
int EditWithSymbolEditor(const TOOL_EVENT &aEvent)
int SimTune(const TOOL_EVENT &aEvent)
Highlight net under the cursor.
int EditSymbolLibraryLinks(const TOOL_EVENT &aEvent)
int New(const TOOL_EVENT &aEvent)
std::map< wxString, SCH_SCREEN * > m_supplementaryClipboard
int ExplicitCrossProbeToPcb(const TOOL_EVENT &aEvent)
int ToggleOPCurrents(const TOOL_EVENT &aEvent)
int ShowPcbNew(const TOOL_EVENT &aEvent)
int UpdateNetHighlighting(const TOOL_EVENT &aEvent)
Launch a tool to highlight nets.
int ToggleERCErrors(const TOOL_EVENT &aEvent)
int TogglePythonConsole(const TOOL_EVENT &aEvent)
int ShowHierarchy(const TOOL_EVENT &aEvent)
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
int ShowNetNavigator(const TOOL_EVENT &aEvent)
int SimProbe(const TOOL_EVENT &aEvent)
void updatePastedSymbol(SCH_SYMBOL *aSymbol, const SCH_SHEET_PATH &aPastePath, const KIID_PATH &aClipPath, bool aForceKeepAnnotations)
int ShowCvpcb(const TOOL_EVENT &aEvent)
int ToggleLibraryTree(const TOOL_EVENT &aEvent)
int RepairSchematic(const TOOL_EVENT &aEvent)
std::set< SCH_SYMBOL * > m_pastedSymbols
void prunePastedSymbolInstances()
Remove all pasted symbol instances that do not belong to the current project.
int Cut(const TOOL_EVENT &aEvent)
int ToggleProperties(const TOOL_EVENT &aEvent)
std::map< KIID_PATH, SCH_SYMBOL_INSTANCE > m_clipboardSymbolInstances
int Save(const TOOL_EVENT &aEvent)
bool RescueSymbolLibTableProject(bool aRunningOnDemand)
Notifies pcbnew about the selected item.
bool doCopy(bool aUseDuplicateClipboard=false)
< copy selection to clipboard or to m_duplicateClipboard
int Undo(const TOOL_EVENT &aEvent)
int ToggleERCExclusions(const TOOL_EVENT &aEvent)
int Plot(const TOOL_EVENT &aEvent)
int Print(const TOOL_EVENT &aEvent)
int Revert(const TOOL_EVENT &aEvent)
int GenerateBOM(const TOOL_EVENT &aEvent)
int ReloadPlugins(const TOOL_EVENT &aEvent)
void setPastedSymbolInstances(const SCH_SCREEN *aScreen)
int ToggleHiddenFields(const TOOL_EVENT &aEvent)
Schematic editor (Eeschema) main window.
void ShowSchematicSetupDialog(const wxString &aInitialPage=wxEmptyString)
void RollbackSchematicFromUndo()
Perform an undo of the last edit without logging a corresponding redo.
bool IsSyncingSelection()
void RefreshOperatingPointDisplay()
Refresh the display of any operating points.
SCH_DESIGN_BLOCK_PANE * GetDesignBlockPane() const
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Open a project or set of files given by aFileList.
void SetHighlightedConnection(const wxString &aConnection, const NET_NAVIGATOR_ITEM_DATA *aSelection=nullptr)
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void InitSheet(SCH_SHEET *aSheet, const wxString &aNewFilename)
Definition: sheet.cpp:110
bool LoadSheetFromFile(SCH_SHEET *aSheet, SCH_SHEET_PATH *aCurrentSheet, const wxString &aFileName, bool aSkipRecursionCheck=false, bool aSkipLibCheck=false)
Load a the KiCad schematic file aFileName into the sheet aSheet.
Definition: sheet.cpp:169
void SendSelectItemsToPcb(const std::vector< EDA_ITEM * > &aItems, bool aForce)
Send items to board editor for selection.
void SaveCopyInUndoList(SCH_SCREEN *aScreen, SCH_ITEM *aItemToCopy, UNDO_REDO aTypeCommand, bool aAppend, bool aDirtyConnectivity=true)
Create a copy of the current schematic item, and put it in the undo list.
void SendCrossProbeClearHighlight()
Tell Pcbnew to clear the existing highlighted net, if one exists.
void HardRedraw() override
Rebuild the GAL and redraw the screen.
SCHEMATIC * m_schematic
The currently loaded schematic.
SCH_SHEET_PATH & GetCurrentSheet() const
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags, PROGRESS_REPORTER *aProgressReporter=nullptr)
Generate the connection data for the entire schematic hierarchy.
const SCH_ITEM * GetSelectedNetNavigatorItem() const
SCHEMATIC & Schematic() const
bool saveSchematicFile(SCH_SHEET *aSheet, const wxString &aSavePath)
Save aSheet to a schematic file.
void DrawCurrentSheetToClipboard()
Use the wxWidgets print code to draw an image of the current sheet onto the clipboard.
Definition: sheet.cpp:622
void RefreshNetNavigator(const NET_NAVIGATOR_ITEM_DATA *aSelection=nullptr)
void UpdateHierarchyNavigator(bool aRefreshNetNavigator=true, bool aClear=false)
Update the hierarchy navigation tree and history.
void SetSheetNumberAndCount()
Set the m_ScreenNumber and m_NumberOfScreens members for screens.
void PutDataInPreviousState(PICKED_ITEMS_LIST *aList)
Restore an undo or redo command to put data pointed by aList in the previous state.
const wxString & GetHighlightedConnection() const
void UpdateNetHighlightStatus()
void SelectNetNavigatorItem(const NET_NAVIGATOR_ITEM_DATA *aSelection=nullptr)
DIALOG_SYMBOL_FIELDS_TABLE * GetSymbolFieldsTableDialog()
void SetCrossProbeConnection(const SCH_CONNECTION *aConnection)
Send a connection (net or bus) to Pcbnew for highlighting.
bool SaveProject(bool aSaveAs=false)
Save the currently-open schematic (including its hierarchy) and associated project.
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1089
A set of SCH_ITEMs (i.e., without duplicates).
Definition: sch_group.h:52
A SCH_IO derivation for loading schematic files using the new s-expression file format.
void LoadContent(LINE_READER &aReader, SCH_SHEET *aSheet, int aVersion=SEXPR_SCHEMATIC_FILE_VERSION)
void Format(SCH_SHEET *aSheet)
static SCH_FILE_T EnumFromStr(const wxString &aFileType)
Return the #SCH_FILE_T from the corresponding plugin type name: "kicad", "legacy",...
Definition: sch_io_mgr.cpp:107
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:168
virtual bool IsConnectable() const
Definition: sch_item.h:494
const SYMBOL * GetParentSymbol() const
Definition: sch_item.cpp:218
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:212
virtual void SetLastResolvedState(const SCH_ITEM *aItem)
Definition: sch_item.h:586
int GetBodyStyle() const
Definition: sch_item.h:246
int GetUnit() const
Definition: sch_item.h:242
void SetConnectivityDirty(bool aDirty=true)
Definition: sch_item.h:557
bool IsConnectivityDirty() const
Definition: sch_item.h:555
virtual void SetUnit(int aUnit)
Definition: sch_item.h:241
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition: sch_item.cpp:318
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Definition: sch_item.h:509
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:42
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
void SortByReferenceOnly()
Sort the list of references by reference.
size_t GetCount() const
void SplitReferences()
Attempt to split all reference designators into a name (U) and number (1).
void AddItem(const SCH_REFERENCE &aItem)
A helper to define a symbol's reference designator in a schematic.
void SetRef(const wxString &aReference)
void Split()
Attempt to split the reference designator into a name (U) and number (1).
bool IsSplitNeeded()
Determine if this reference needs to be split or if it likely already has been.
wxString GetRef() const
void SetSheetNumber(int aSheetNumber)
wxString GetRefNumber() const
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:753
SCH_SCREEN * GetNext()
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in the full schematic.
SCH_SCREEN * GetFirst()
void PruneOrphanedSheetInstances(const wxString &aProjectName, const SCH_SHEET_LIST &aValidSheetPaths)
void PruneOrphanedSymbolInstances(const wxString &aProjectName, const SCH_SHEET_LIST &aValidSheetPaths)
bool HasNoFullyDefinedLibIds()
Test all of the schematic symbols to see if all LIB_ID objects library nickname is not set.
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Definition: sch_screen.cpp:160
void Clear(bool aFree=true)
Delete all draw items and clears the project settings.
Definition: sch_screen.cpp:285
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in this schematic from the project SYMB...
Definition: sch_screen.cpp:664
std::set< wxString > GetSheetNames() const
const std::map< wxString, LIB_SYMBOL * > & GetLibSymbols() const
Fetch a list of unique LIB_SYMBOL object pointers required to properly render each SCH_SYMBOL in this...
Definition: sch_screen.h:483
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition: sch_screen.h:112
const wxString & GetFileName() const
Definition: sch_screen.h:147
bool Remove(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:330
bool CheckIfOnDrawList(const SCH_ITEM *aItem) const
Definition: sch_screen.cpp:393
void MigrateSimModels()
Migrate any symbols having V6 simulation models to their V7 equivalents.
EDA_ITEM * GetNode(const VECTOR2I &aPosition)
Finds a connected item at a point (usually the cursor position).
bool SelectPoint(const VECTOR2I &aWhere, const std::vector< KICAD_T > &aScanTypes={ SCH_LOCATE_ANY_T }, EDA_ITEM **aItem=nullptr, bool *aSelectionCancelledFlag=nullptr, bool aCheckLocked=false, bool aAdd=false, bool aSubtract=false, bool aExclusiveOr=false)
Perform a click-type selection at a point (usually the cursor position).
int ClearSelection(const TOOL_EVENT &aEvent)
Select all visible items in sheet.
void GuessSelectionCandidates(SCH_COLLECTOR &collector, const VECTOR2I &aPos)
Apply heuristics to try and determine a single object when multiple are found under the cursor.
SCH_SELECTION & GetSelection()
SCH_SELECTION & RequestSelection(const std::vector< KICAD_T > &aScanTypes={ SCH_LOCATE_ANY_T }, bool aPromoteCellSelections=false, bool aPromoteGroups=false)
Return either an existing selection (filtered), or the selection at the current cursor position if th...
VECTOR2I GetCenter() const
Definition: sch_shape.h:87
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void FillItemMap(std::map< KIID, EDA_ITEM * > &aMap)
Fill an item cache for temporary use when many items need to be fetched.
void SortByPageNumbers(bool aUpdateVirtualPageNums=true)
Sort the list of sheets by page number.
SCH_SHEET_LIST FindAllSheetsForScreen(const SCH_SCREEN *aScreen) const
Return a SCH_SHEET_LIST with a copy of all the SCH_SHEET_PATH using a particular screen.
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
bool PageNumberExists(const wxString &aPageNumber) const
bool ContainsSheet(const SCH_SHEET *aSheet) const
bool HasPath(const KIID_PATH &aPath) const
bool TestForRecursion(const SCH_SHEET_LIST &aSrcSheetHierarchy, const wxString &aDestFileName)
Test every SCH_SHEET_PATH in this SCH_SHEET_LIST to verify if adding the sheets stored in aSrcSheetHi...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Adds SCH_REFERENCE object to aReferences for each symbol in the sheet.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
void UpdateAllScreenReferences() const
Update all the symbol references for this sheet path.
SCH_SCREEN * LastScreen()
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:66
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:47
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition: sch_sheet.h:321
void RemoveInstance(const KIID_PATH &aInstancePath)
Definition: sch_sheet.cpp:1337
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this sheet.
Definition: sch_sheet.cpp:367
bool SearchHierarchy(const wxString &aFilename, SCH_SCREEN **aScreen)
Search the existing hierarchy for an instance of screen loaded from aFileName.
Definition: sch_sheet.cpp:751
void AddInstance(const SCH_SHEET_INSTANCE &aInstance)
Definition: sch_sheet.cpp:1358
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:116
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Definition: sch_sheet.cpp:137
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition: sch_sheet.h:187
const std::vector< SCH_SHEET_INSTANCE > & GetInstances() const
Definition: sch_sheet.h:429
Schematic symbol object.
Definition: sch_symbol.h:75
EMBEDDED_FILES * GetEmbeddedFiles() override
SCH_SYMBOLs don't currently support embedded files, but their LIB_SYMBOL counterparts do.
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
Definition: sch_symbol.h:134
wxString GetSchSymbolLibraryName() const
Definition: sch_symbol.cpp:243
void ClearAnnotation(const SCH_SHEET_PATH *aSheetPath, bool aResetPrefix)
Clear exiting symbol annotation.
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit)
Add a full hierarchical reference to this symbol.
Definition: sch_symbol.cpp:512
bool IsMissingLibSymbol() const
Check to see if the library symbol is set to the dummy library symbol.
Definition: sch_symbol.cpp:210
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
const LIB_ID & GetLibId() const override
Definition: sch_symbol.h:164
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:183
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
Definition: sch_symbol.cpp:252
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
Definition: sch_symbol.cpp:550
bool IsPower() const override
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:752
void BrightenItem(EDA_ITEM *aItem)
void UnbrightenItem(EDA_ITEM *aItem)
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.cpp:178
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
The SIMULATOR_FRAME holds the main user-interface for running simulations.
void AddCurrentTrace(const wxString &aDeviceName)
Add a current trace for a given device to the current plot.
void AddVoltageTrace(const wxString &aNetName)
Add a voltage trace for a given net to the current plot.
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, const std::vector< SCH_PIN * > &aPins, REPORTER &aReporter)
void SetFilesStack(std::vector< EMBEDDED_FILES * > aFilesStack)
Definition: sim_lib_mgr.h:49
int FindModelPinIndex(const std::string &aSymbolPinNumber)
Definition: sim_model.cpp:655
const SPICE_GENERATOR & SpiceGenerator() const
Definition: sim_model.h:431
virtual std::vector< std::string > CurrentNames(const SPICE_ITEM &aItem) const
Implement an OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:449
const std::string & GetString()
Definition: richio.h:472
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:253
The symbol library editor main window.
bool IsLibraryTreeShown() const override
void LoadSymbol(const wxString &aLibrary, const wxString &aSymbol, int Unit)
void LoadSymbolFromSchematic(SCH_SYMBOL *aSymbol)
Load a symbol from the schematic to edit in place.
void ToggleLibraryTree() override
Class to handle modifications to the symbol libraries.
bool CreateLibrary(const wxString &aFilePath, SYMBOL_LIB_TABLE &aTable)
Create an empty library and adds it to the library table.
SYMBOL_LIB_TABLE_ROW * GetLibrary(const wxString &aLibrary) const
Find a single library within the (aggregate) library table.
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_IO object i...
const wxString GetType() const override
Return the type of symbol library table represented by this row.
static SYMBOL_LIB_TABLE & GetGlobalLibTable()
static const wxString GetSymbolLibTableFileName()
static wxString GetGlobalTableFileName()
Fetch the global symbol library table file name.
SYMBOL_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an SYMBOL_LIB_TABLE_ROW if aNickName is found in this table or in any chained fallBack table f...
Symbol library viewer main window.
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:44
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:220
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:38
Generic, UI-independent tool event.
Definition: tool_event.h:168
bool DisableGridSnapping() const
Definition: tool_event.h:368
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
Definition: tool_event.cpp:82
T Parameter() const
Return a parameter assigned to the event.
Definition: tool_event.h:465
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
void Activate()
Run the tool.
Master controller class:
Definition: tool_manager.h:62
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:150
TOOLS_HOLDER * GetToolHolder() const
Definition: tool_manager.h:406
APP_SETTINGS_BASE * GetSettings() const
Definition: tool_manager.h:404
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
Definition: tool_manager.h:235
bool RunSynchronousAction(const TOOL_ACTION &aAction, COMMIT *aCommit, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:197
void ShowMessageFor(const wxString &aMessage, int aTime, int aFlags=wxICON_INFORMATION, MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the infobar with the provided message and icon for a specific period of time.
Definition: wx_infobar.cpp:142
A wrapper for reporting to a wxString object.
Definition: reporter.h:190
bool HasMessage() const override
Returns true if the reporter client is non-empty.
Definition: reporter.cpp:96
const wxString & GetMessages() const
Definition: reporter.cpp:83
bool SaveClipboard(const std::string &aTextUTF8)
Store information to the system clipboard.
Definition: clipboard.cpp:37
std::string GetClipboardUTF8()
Return the information currently stored in the system clipboard.
Definition: clipboard.cpp:57
std::unique_ptr< wxImage > GetImageFromClipboard()
Get image data from the clipboard, if there is any.
Definition: clipboard.cpp:83
wxString EnsureFileExtension(const wxString &aFilename, const wxString &aExtension)
It's annoying to throw up nag dialogs when the extension isn't right.
Definition: common.cpp:429
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:251
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:222
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:194
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:169
This file is part of the common library.
int InvokeDialogCreateBOM(SCH_EDIT_FRAME *aCaller)
Create and show DIALOG_BOM and return whatever DIALOG_BOM::ShowModal() returns.
Definition: dialog_bom.cpp:60
bool InvokeDialogEditSymbolsLibId(SCH_EDIT_FRAME *aCaller)
Run a dialog to modify the LIB_ID of symbols for instance when a symbol has moved from a symbol libra...
int InvokeDialogNetList(SCH_EDIT_FRAME *aCaller)
#define _(s)
@ NO_RECURSE
Definition: eda_item.h:51
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:552
#define IS_PASTED
Modifier on IS_NEW which indicates it came from clipboard.
#define IS_NEW
New item, just created.
#define ENDPOINT
ends. (Used to support dragging.)
#define IS_MOVING
Item being moved.
#define STARTPOINT
When a line is selected, these flags indicate which.
LINE_MODE
@ FRAME_SCH_SYMBOL_EDITOR
Definition: frame_type.h:35
@ FRAME_SCH_VIEWER
Definition: frame_type.h:36
@ FRAME_SIMULATOR
Definition: frame_type.h:38
int m_MaxPastedTextLength
Set the maximum number of characters that can be pasted without warning.
static const std::string KiCadSchematicFileExtension
static const std::string KiCadSymbolLibFileExtension
static wxString KiCadSymbolLibFileWildcard()
static wxString KiCadSchematicFileWildcard()
static const wxChar traceSchPaste[]
Flag to enable schematic paste debugging output.
#define NET_PLUGIN_CHANGE
Create and shows DIALOG_EXPORT_NETLIST and returns whatever DIALOG_EXPORT_NETLIST::ShowModal() return...
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition: io_mgr.h:33
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:39
#define KICTL_REVERT
reverting to a previously-saved (KiCad) file.
Definition: kiway_player.h:78
@ LAYER_ERC_WARN
Definition: layer_ids.h:469
@ LAYER_ERC_ERR
Definition: layer_ids.h:470
@ LAYER_OP_CURRENTS
Definition: layer_ids.h:491
@ LAYER_OP_VOLTAGES
Definition: layer_ids.h:490
void Prettify(std::string &aSource, bool aCompactSave)
@ REPAINT
Item needs to be redrawn.
Definition: view_item.h:58
@ GEOMETRY
Position or shape has changed.
Definition: view_item.h:55
#define MAX_PAGE_SIZE_EESCHEMA_MILS
Definition: page_info.h:40
PGM_BASE & Pgm()
The global program "get" accessor.
Definition: pgm_base.cpp:902
see class PGM_BASE
#define HITTEST_THRESHOLD_PIXELS
static bool highlightNet(TOOL_MANAGER *aToolMgr, const VECTOR2D &aPosition)
static VECTOR2D CLEAR
Class to handle a set of SCH_ITEMs.
ANNOTATE_ORDER_T
Schematic annotation order options.
ANNOTATE_ALGO_T
Schematic annotation type options.
wxString GetSelectedItemsAsText(const SELECTION &aSel)
@ LOCAL_CLEANUP
Definition: schematic.h:75
@ NO_CLEANUP
Definition: schematic.h:74
@ GLOBAL_CLEANUP
Definition: schematic.h:76
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
wxString From_UTF8(const char *cstring)
std::vector< GRID > grids
Definition: grid_settings.h:66
Common grid settings, available to every frame.
Definition: grid_settings.h:34
A simple container for sheet instance information.
A simple container for schematic symbol instance information.
static constexpr auto NOT_CONNECTED
Definition: sim_model.h:73
std::string refName
GRID_SETTINGS grid
Definition: app_settings.h:97
Definition for symbol library class.
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
VECTOR2I end
@ AS_GLOBAL
Global action (toolbar/main menu event, global shortcut)
Definition: tool_action.h:49
@ TA_UNDO_REDO_PRE
This event is sent before undo/redo command is performed.
Definition: tool_event.h:106
@ TC_MESSAGE
Definition: tool_event.h:58
@ SCH_GROUP_T
Definition: typeinfo.h:174
@ SCH_LINE_T
Definition: typeinfo.h:164
@ SCH_SYMBOL_T
Definition: typeinfo.h:173
@ SCH_FIELD_T
Definition: typeinfo.h:151
@ SCH_SHEET_T
Definition: typeinfo.h:176
@ SCH_MARKER_T
Definition: typeinfo.h:159
@ SCH_SHAPE_T
Definition: typeinfo.h:150
@ SCH_PIN_T
Definition: typeinfo.h:154
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695
Definition of file extensions used in Kicad.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:39