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 return 0;
310}
311
312
314{
315 m_frame->Close( false );
316 return 0;
317}
318
319
321{
322 doCrossProbeSchToPcb( aEvent, false );
323 return 0;
324}
325
326
328{
329 doCrossProbeSchToPcb( aEvent, true );
330 return 0;
331}
332
333
334void SCH_EDITOR_CONTROL::doCrossProbeSchToPcb( const TOOL_EVENT& aEvent, bool aForce )
335{
336 // Don't get in an infinite loop SCH -> PCB -> SCH -> PCB -> SCH -> ...
338 return;
339
341 SCH_SELECTION& selection = aForce ? selTool->RequestSelection() : selTool->GetSelection();
342
343 m_frame->SendSelectItemsToPcb( selection.GetItemsSortedBySelectionOrder(), aForce );
344}
345
346
348{
349 bool savePowerSymbols = false;
350 bool map = false;
352 wxString targetLib;
353
354 targetLib = m_frame->SelectLibrary( _( "Export Symbols" ), _( "Export symbols to library:" ),
355 { { _( "Include power symbols in export" ), &savePowerSymbols },
356 { _( "Update schematic symbols to link to exported symbols" ), &map }
357 } );
358
359 if( targetLib.empty() )
360 return 0;
361
363 SCH_REFERENCE_LIST symbols;
364 sheets.GetSymbols( symbols, savePowerSymbols );
365
366 std::map<LIB_ID, LIB_SYMBOL*> libSymbols;
367 std::map<LIB_ID, std::vector<SCH_SYMBOL*>> symbolMap;
368
369 for( size_t i = 0; i < symbols.GetCount(); ++i )
370 {
371 SCH_SYMBOL* symbol = symbols[i].GetSymbol();
372 LIB_SYMBOL* libSymbol = symbol->GetLibSymbolRef().get();
373 LIB_ID id = libSymbol->GetLibId();
374
375 if( libSymbols.count( id ) )
376 {
377 wxASSERT_MSG( libSymbols[id]->Compare( *libSymbol, SCH_ITEM::COMPARE_FLAGS::ERC ) == 0,
378 "Two symbols have the same LIB_ID but are different!" );
379 }
380 else
381 {
382 libSymbols[id] = libSymbol;
383 }
384
385 symbolMap[id].emplace_back( symbol );
386 }
387
388 bool append = false;
389 SCH_COMMIT commit( m_frame );
390 SYMBOL_LIB_TABLE_ROW* row = mgr.GetLibrary( targetLib );
391 SCH_IO_MGR::SCH_FILE_T type = SCH_IO_MGR::EnumFromStr( row->GetType() );
392 IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( type ) );
393
394 wxFileName dest = row->GetFullURI( true );
395 dest.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
396
397 for( const std::pair<const LIB_ID, LIB_SYMBOL*>& it : libSymbols )
398 {
399 LIB_SYMBOL* origSym = it.second;
400 LIB_SYMBOL* newSym = origSym->Flatten().release();
401
402 try
403 {
404 pi->SaveSymbol( dest.GetFullPath(), newSym );
405 }
406 catch( const IO_ERROR& ioe )
407 {
408 wxString msg;
409 msg.Printf( _( "Error saving symbol %s to library '%s'." ),
410 newSym->GetName(), row->GetNickName() );
411 msg += wxS( "\n\n" ) + ioe.What();
412 wxLogWarning( msg );
413 return 0;
414 }
415
416 if( map )
417 {
418 LIB_ID id = it.first;
419 id.SetLibNickname( targetLib );
420
421 for( SCH_SYMBOL* symbol : symbolMap[it.first] )
422 {
423 SCH_SCREEN* parentScreen = static_cast<SCH_SCREEN*>( symbol->GetParent() );
424
425 wxCHECK2( parentScreen, continue );
426
427 commit.Modify( symbol, parentScreen, RECURSE_MODE::NO_RECURSE );
428 symbol->SetLibId( id );
429 append = true;
430 }
431 }
432 }
433
434 // Save the modified symbol library table. We need to look this up by name in each table to find
435 // whether the new library is a global or project entity as the code above to choose the library
436 // returns a different type depending on whether a global or project library is chosen.
438 SYMBOL_LIB_TABLE* projectTable = nullptr;
439
440 if( !m_frame->Prj().IsNullProject() )
441 projectTable = PROJECT_SCH::SchSymbolLibTable( &m_frame->Prj() );
442
443 if( globalTable->FindRow( targetLib ) )
444 {
445 try
446 {
447 wxString globalTablePath = SYMBOL_LIB_TABLE::GetGlobalTableFileName();
448 globalTable->Save( globalTablePath );
449 }
450 catch( const IO_ERROR& ioe )
451 {
452 wxString msg;
453 msg.Printf( _( "Error saving global library table:\n\n%s" ), ioe.What() );
454 wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
455 }
456 }
457 else if( projectTable && projectTable->FindRow( targetLib ) )
458 {
459 try
460 {
461 wxString projectPath = m_frame->Prj().GetProjectPath();
462 wxFileName projectTableFn( projectPath, SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
463 projectTable->Save( projectTableFn.GetFullPath() );
464 }
465 catch( const IO_ERROR& ioe )
466 {
467 wxString msg;
468 msg.Printf( _( "Error saving project-specific library table:\n\n%s" ), ioe.What() );
469 wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
470 }
471 }
472
473 if( append )
474 {
475 std::set<SCH_SCREEN*> processedScreens;
476
477 for( SCH_SHEET_PATH& sheet : sheets )
478 {
479 SCH_SCREEN* screen = sheet.LastScreen();
480
481 if( processedScreens.find( ( screen ) ) == processedScreens.end() )
482 {
483 processedScreens.insert( screen );
484 screen->UpdateSymbolLinks();
485 }
486 }
487
488 commit.Push( wxS( "Update Library Identifiers" ) );
489 }
490
491 return 0;
492}
493
494
495#define HITTEST_THRESHOLD_PIXELS 5
496
498{
500 KIWAY_PLAYER* player = m_frame->Kiway().Player( FRAME_SIMULATOR, false );
501 SIMULATOR_FRAME* simFrame = static_cast<SIMULATOR_FRAME*>( player );
502
503 if( !simFrame ) // Defensive coding; shouldn't happen.
504 return 0;
505
506 if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
507 blocking_win->Close( true );
508
509 // Deactivate other tools; particularly important if another PICKER is currently running
510 Activate();
511
512 picker->SetCursor( KICURSOR::VOLTAGE_PROBE );
513 picker->SetSnapping( false );
514 picker->ClearHandlers();
515
516 picker->SetClickHandler(
517 [this, simFrame]( const VECTOR2D& aPosition )
518 {
520
521 // We do not really want to keep an item selected in schematic,
522 // so clear the current selection
523 selTool->ClearSelection();
524
525 EDA_ITEM* item = selTool->GetNode( aPosition );
527
528 if( !item )
529 return false;
530
531 if( item->Type() == SCH_PIN_T )
532 {
533 try
534 {
535 SCH_PIN* pin = static_cast<SCH_PIN*>( item )->GetLibPin();
536 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item->GetParent() );
537
538 WX_STRING_REPORTER reporter;
539 SIM_LIB_MGR mgr( &m_frame->Prj() );
540
541 std::vector<EMBEDDED_FILES*> embeddedFilesStack;
542 embeddedFilesStack.push_back( m_frame->Schematic().GetEmbeddedFiles() );
543 embeddedFilesStack.push_back( symbol->GetEmbeddedFiles() );
544
545 mgr.SetFilesStack( std::move( embeddedFilesStack ) );
546
547 SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, true, 0, reporter ).model;
548
549 if( reporter.HasMessage() )
550 THROW_IO_ERROR( reporter.GetMessages() );
551
552 SPICE_ITEM spiceItem;
553 spiceItem.refName = symbol->GetRef( &sheet ).ToStdString();
554 std::vector<std::string> currentNames = model.SpiceGenerator().CurrentNames( spiceItem );
555
556 if( currentNames.size() == 0 )
557 {
558 return true;
559 }
560 else if( currentNames.size() == 1 )
561 {
562 simFrame->AddCurrentTrace( currentNames.at( 0 ) );
563 return true;
564 }
565
566 int modelPinIndex = model.FindModelPinIndex( pin->GetNumber().ToStdString() );
567
568 if( modelPinIndex != SIM_MODEL_PIN::NOT_CONNECTED )
569 {
570 wxString name = currentNames.at( modelPinIndex );
571 simFrame->AddCurrentTrace( name );
572 }
573 }
574 catch( const IO_ERROR& e )
575 {
577 }
578 }
579 else if( item->IsType( { SCH_ITEM_LOCATE_WIRE_T } )
580 || item->IsType( { SCH_JUNCTION_T } ) )
581 {
582 if( SCH_CONNECTION* conn = static_cast<SCH_ITEM*>( item )->Connection() )
583 {
584 wxString spiceNet = UnescapeString( conn->Name() );
586
587 simFrame->AddVoltageTrace( wxString::Format( "V(%s)", spiceNet ) );
588 }
589 }
590
591 return true;
592 } );
593
594 picker->SetMotionHandler(
595 [this, picker]( const VECTOR2D& aPos )
596 {
597 SCH_COLLECTOR collector;
598 collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
599 collector.Collect( m_frame->GetScreen(), { SCH_ITEM_LOCATE_WIRE_T,
600 SCH_PIN_T,
601 SCH_SHEET_PIN_T }, aPos );
602
604 selectionTool->GuessSelectionCandidates( collector, aPos );
605
606 EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
607 SCH_LINE* wire = dynamic_cast<SCH_LINE*>( item );
608
609 const SCH_CONNECTION* conn = nullptr;
610
611 if( wire )
612 {
613 item = nullptr;
614 conn = wire->Connection();
615 }
616
617 if( item && item->Type() == SCH_PIN_T )
618 picker->SetCursor( KICURSOR::CURRENT_PROBE );
619 else
620 picker->SetCursor( KICURSOR::VOLTAGE_PROBE );
621
622 if( m_pickerItem != item )
623 {
624 if( m_pickerItem )
625 selectionTool->UnbrightenItem( m_pickerItem );
626
627 m_pickerItem = item;
628
629 if( m_pickerItem )
630 selectionTool->BrightenItem( m_pickerItem );
631 }
632
633 wxString connectionName = ( conn ) ? conn->Name() : wxString( wxS( "" ) );
634
635 if( m_frame->GetHighlightedConnection() != connectionName )
636 {
637 m_frame->SetHighlightedConnection( connectionName );
638
639 TOOL_EVENT dummyEvent;
640 UpdateNetHighlighting( dummyEvent );
641 }
642 } );
643
644 picker->SetFinalizeHandler(
645 [this]( const int& aFinalState )
646 {
647 if( m_pickerItem )
648 m_toolMgr->GetTool<SCH_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
649
650 if( !m_frame->GetHighlightedConnection().IsEmpty() )
651 {
652 m_frame->SetHighlightedConnection( wxEmptyString );
653
654 TOOL_EVENT dummyEvent;
655 UpdateNetHighlighting( dummyEvent );
656 }
657
658 // Wake the selection tool after exiting to ensure the cursor gets updated
659 // and deselect previous selection from simulator to avoid any issue
660 // ( avoid crash in some cases when the SimProbe tool is deselected )
662 selectionTool->ClearSelection();
664 } );
665
667
668 return 0;
669}
670
671
673{
675
676 // Deactivate other tools; particularly important if another PICKER is currently running
677 Activate();
678
679 picker->SetCursor( KICURSOR::TUNE );
680 picker->SetSnapping( false );
681 picker->ClearHandlers();
682
683 picker->SetClickHandler(
684 [this]( const VECTOR2D& aPosition )
685 {
687 EDA_ITEM* item = nullptr;
688 selTool->SelectPoint( aPosition, { SCH_SYMBOL_T, SCH_FIELD_T }, &item );
689
690 if( !item )
691 return false;
692
693 if( item->Type() != SCH_SYMBOL_T )
694 {
695 item = item->GetParent();
696
697 if( item->Type() != SCH_SYMBOL_T )
698 return false;
699 }
700
701 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
702 SCH_SHEET_PATH sheetPath = symbol->Schematic()->CurrentSheet();
703 KIWAY_PLAYER* simFrame = m_frame->Kiway().Player( FRAME_SIMULATOR, false );
704
705 if( simFrame )
706 {
707 if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
708 blocking_win->Close( true );
709
710 static_cast<SIMULATOR_FRAME*>( simFrame )->AddTuner( sheetPath, symbol );
711 }
712
713 // We do not really want to keep a symbol selected in schematic,
714 // so clear the current selection
715 selTool->ClearSelection();
716 return true;
717 } );
718
719 picker->SetMotionHandler(
720 [this]( const VECTOR2D& aPos )
721 {
722 SCH_COLLECTOR collector;
723 collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
724 collector.Collect( m_frame->GetScreen(), { SCH_SYMBOL_T, SCH_FIELD_T }, aPos );
725
727 selectionTool->GuessSelectionCandidates( collector, aPos );
728
729 EDA_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
730
731 if( item && item->Type() == SCH_FIELD_T )
732 item = static_cast<SCH_FIELD*>( item )->GetParentSymbol();
733
734 if( m_pickerItem != item )
735 {
736 if( m_pickerItem )
737 selectionTool->UnbrightenItem( m_pickerItem );
738
739 m_pickerItem = item;
740
741 if( m_pickerItem )
742 selectionTool->BrightenItem( m_pickerItem );
743 }
744 } );
745
746 picker->SetFinalizeHandler(
747 [this]( const int& aFinalState )
748 {
749 if( m_pickerItem )
750 m_toolMgr->GetTool<SCH_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
751
752 // Wake the selection tool after exiting to ensure the cursor gets updated
753 // and deselect previous selection from simulator to avoid any issue
754 // ( avoid crash in some cases when the SimTune tool is deselected )
756 selectionTool->ClearSelection();
758 } );
759
761
762 return 0;
763}
764
765
766// A singleton reference for clearing the highlight
768
769
770static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
771{
772 SCH_EDIT_FRAME* editFrame = static_cast<SCH_EDIT_FRAME*>( aToolMgr->GetToolHolder() );
773 SCH_SELECTION_TOOL* selTool = aToolMgr->GetTool<SCH_SELECTION_TOOL>();
774 SCH_EDITOR_CONTROL* editorControl = aToolMgr->GetTool<SCH_EDITOR_CONTROL>();
775 SCH_CONNECTION* conn = nullptr;
776 SCH_ITEM* item = nullptr;
777 bool retVal = true;
778
779 if( aPosition != CLEAR )
780 {
781 ERC_TESTER erc( &editFrame->Schematic() );
782
783 if( erc.TestDuplicateSheetNames( false ) > 0 )
784 {
785 wxMessageBox( _( "Error: duplicate sub-sheet names found in current sheet." ) );
786 retVal = false;
787 }
788 else
789 {
790 item = static_cast<SCH_ITEM*>( selTool->GetNode( aPosition ) );
791 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( item );
792
793 if( item )
794 {
795 if( item->IsConnectivityDirty() )
796 editFrame->RecalculateConnections( nullptr, NO_CLEANUP );
797
798 if( item->Type() == SCH_FIELD_T )
799 symbol = dynamic_cast<SCH_SYMBOL*>( item->GetParent() );
800
801 if( symbol && symbol->GetLibSymbolRef() && symbol->GetLibSymbolRef()->IsPower() )
802 {
803 std::vector<SCH_PIN*> pins = symbol->GetPins();
804
805 if( pins.size() == 1 )
806 conn = pins[0]->Connection();
807 }
808 else
809 {
810 conn = item->Connection();
811 }
812 }
813 }
814 }
815
816 wxString connName = ( conn ) ? conn->Name() : wxString( wxS( "" ) );
817
818 if( !conn )
819 {
820 editFrame->SetStatusText( wxT( "" ) );
821 editFrame->SendCrossProbeClearHighlight();
822 editFrame->SetHighlightedConnection( wxEmptyString );
823 editorControl->SetHighlightBusMembers( false );
824 }
825 else
826 {
827 NET_NAVIGATOR_ITEM_DATA itemData( editFrame->GetCurrentSheet(), item );
828
829 if( connName != editFrame->GetHighlightedConnection() )
830 {
831 editorControl->SetHighlightBusMembers( false );
832 editFrame->SetCrossProbeConnection( conn );
833 editFrame->SetHighlightedConnection( connName, &itemData );
834 }
835 else
836 {
837 editorControl->SetHighlightBusMembers( !editorControl->GetHighlightBusMembers() );
838
839 if( item != editFrame->GetSelectedNetNavigatorItem() )
840 editFrame->SelectNetNavigatorItem( &itemData );
841 }
842 }
843
844 editFrame->UpdateNetHighlightStatus();
845
847 editorControl->UpdateNetHighlighting( dummy );
848
849 return retVal;
850}
851
852
854{
856 VECTOR2D cursorPos = controls->GetCursorPosition( !aEvent.DisableGridSnapping() );
857
858 highlightNet( m_toolMgr, cursorPos );
859
860 return 0;
861}
862
863
865{
867
868 return 0;
869}
870
871
873{
875 SCHEMATIC& schematic = m_frame->Schematic();
877
878 const SCH_CONNECTION* conn = nullptr;
879 VECTOR2D connPos;
880
881 for( EDA_ITEM* item : selectionTool->GetSelection() )
882 {
883 conn = static_cast<SCH_ITEM*>( item )->Connection();
884 connPos = item->GetPosition();
885
886 if( conn )
887 break;
888 }
889
890 if( !conn )
891 {
892 m_frame->ShowInfoBarError( _( "No net selected." ) );
893 return 0;
894 }
895
896 // Remove selection in favor of highlighting so the whole net is highlighted
897 selectionTool->ClearSelection();
898 highlightNet( m_toolMgr, connPos );
899
900 wxString netName = conn->Name();
901
902 if( conn->IsBus() )
903 {
904 wxString prefix;
905
906 if( NET_SETTINGS::ParseBusVector( netName, &prefix, nullptr ) )
907 {
908 netName = prefix + wxT( "*" );
909 }
910 else if( NET_SETTINGS::ParseBusGroup( netName, &prefix, nullptr ) )
911 {
912 netName = prefix + wxT( ".*" );
913 }
914 }
915 else if( !conn->Driver() || CONNECTION_SUBGRAPH::GetDriverPriority( conn->Driver() )
917 {
918 m_frame->ShowInfoBarError( _( "Net must be labeled to assign a netclass." ) );
920 return 0;
921 }
922
923 DIALOG_ASSIGN_NETCLASS dlg( m_frame, netName, schematic.GetNetClassAssignmentCandidates(),
924 [&]( const std::vector<wxString>& aNetNames )
925 {
926 for( SCH_ITEM* item : screen->Items() )
927 {
928 bool redraw = item->IsBrightened();
929 SCH_CONNECTION* itemConn = item->Connection();
930
931 if( itemConn && alg::contains( aNetNames, itemConn->Name() ) )
932 item->SetBrightened();
933 else
934 item->ClearBrightened();
935
936 redraw |= item->IsBrightened();
937
938 if( item->Type() == SCH_SYMBOL_T )
939 {
940 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
941
942 redraw |= symbol->HasBrightenedPins();
943
944 symbol->ClearBrightenedPins();
945
946 for( SCH_PIN* pin : symbol->GetPins() )
947 {
948 SCH_CONNECTION* pin_conn = pin->Connection();
949
950 if( pin_conn && alg::contains( aNetNames, pin_conn->Name() ) )
951 {
952 pin->SetBrightened();
953 redraw = true;
954 }
955 }
956 }
957 else if( item->Type() == SCH_SHEET_T )
958 {
959 for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( item )->GetPins() )
960 {
961 SCH_CONNECTION* pin_conn = pin->Connection();
962
963 redraw |= pin->IsBrightened();
964
965 if( pin_conn && alg::contains( aNetNames, pin_conn->Name() ) )
966 pin->SetBrightened();
967 else
968 pin->ClearBrightened();
969
970 redraw |= pin->IsBrightened();
971 }
972 }
973
974 if( redraw )
975 getView()->Update( item, KIGFX::VIEW_UPDATE_FLAGS::REPAINT );
976 }
977
979 } );
980
981 if( dlg.ShowModal() )
982 {
983 getView()->UpdateAllItemsConditionally(
984 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
985 {
986 int flags = 0;
987
988 auto invalidateTextVars =
989 [&flags]( EDA_TEXT* text )
990 {
991 if( text->HasTextVars() )
992 {
993 text->ClearRenderCache();
994 text->ClearBoundingBoxCache();
996 }
997 };
998
999 // Netclass coloured items
1000 //
1001 if( dynamic_cast<SCH_LINE*>( aItem ) )
1002 flags |= KIGFX::REPAINT;
1003 else if( dynamic_cast<SCH_JUNCTION*>( aItem ) )
1004 flags |= KIGFX::REPAINT;
1005 else if( dynamic_cast<SCH_BUS_ENTRY_BASE*>( aItem ) )
1006 flags |= KIGFX::REPAINT;
1007
1008 // Items that might reference an item's netclass name
1009 //
1010 if( SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aItem ) )
1011 {
1012 item->RunOnChildren(
1013 [&invalidateTextVars]( SCH_ITEM* aChild )
1014 {
1015 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aChild ) )
1016 invalidateTextVars( text );
1017 },
1019
1020 if( flags & KIGFX::GEOMETRY )
1021 m_frame->GetScreen()->Update( item, false ); // Refresh RTree
1022 }
1023
1024 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aItem ) )
1025 invalidateTextVars( text );
1026
1027 return flags;
1028 } );
1029 }
1030
1031 highlightNet( m_toolMgr, CLEAR );
1032 return 0;
1033}
1034
1035
1037{
1038 wxCHECK( m_frame, 0 );
1039
1040 const SCH_SHEET_PATH& sheetPath = m_frame->GetCurrentSheet();
1042 CONNECTION_GRAPH* connectionGraph = m_frame->Schematic().ConnectionGraph();
1043 wxString selectedName = m_frame->GetHighlightedConnection();
1044
1045 std::set<wxString> connNames;
1046 std::vector<EDA_ITEM*> itemsToRedraw;
1047
1048 wxCHECK( screen && connectionGraph, 0 );
1049
1050 if( !selectedName.IsEmpty() )
1051 {
1052 connNames.emplace( selectedName );
1053
1054 if( CONNECTION_SUBGRAPH* sg = connectionGraph->FindSubgraphByName( selectedName, sheetPath ) )
1055 {
1057 {
1058 for( const SCH_ITEM* item : sg->GetItems() )
1059 {
1060 wxCHECK2( item, continue );
1061
1062 if( SCH_CONNECTION* connection = item->Connection() )
1063 {
1064 for( const std::shared_ptr<SCH_CONNECTION>& member : connection->AllMembers() )
1065 {
1066 if( member )
1067 connNames.emplace( member->Name() );
1068 }
1069 }
1070 }
1071 }
1072 }
1073
1074 // Place all bus names that are connected to the selected net in the set, regardless of
1075 // their sheet. This ensures that nets that are connected to a bus on a different sheet
1076 // get their buses highlighted as well.
1077 for( CONNECTION_SUBGRAPH* sg : connectionGraph->GetAllSubgraphs( selectedName ) )
1078 {
1079 for( const auto& [_, bus_sgs] : sg->GetBusParents() )
1080 {
1081 for( CONNECTION_SUBGRAPH* bus_sg : bus_sgs )
1082 connNames.emplace( bus_sg->GetNetName() );
1083 }
1084
1085 }
1086 }
1087
1088 for( SCH_ITEM* item : screen->Items() )
1089 {
1090 if( !item || !item->IsConnectable() )
1091 continue;
1092
1093 SCH_ITEM* redrawItem = nullptr;
1094
1095 if( item->Type() == SCH_SYMBOL_T )
1096 {
1097 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1098
1099 for( SCH_PIN* pin : symbol->GetPins() )
1100 {
1101 if( SCH_CONNECTION* pin_conn = pin->Connection() )
1102 {
1103 if( !pin->IsBrightened() && connNames.count( pin_conn->Name() ) )
1104 {
1105 pin->SetBrightened();
1106 redrawItem = symbol;
1107 }
1108 else if( pin->IsBrightened() && !connNames.count( pin_conn->Name() ) )
1109 {
1110 pin->ClearBrightened();
1111 redrawItem = symbol;
1112 }
1113 }
1114 }
1115
1116 if( symbol->IsPower() && symbol->GetPins().size() )
1117 {
1118 if( SCH_CONNECTION* pinConn = symbol->GetPins()[0]->Connection() )
1119 {
1120 for( FIELD_T id : { FIELD_T::REFERENCE, FIELD_T::VALUE } )
1121 {
1122 SCH_FIELD* field = symbol->GetField( id );
1123
1124 if( !field->IsVisible() )
1125 continue;
1126
1127 if( !field->IsBrightened() && connNames.count( pinConn->Name() ) )
1128 {
1129 field->SetBrightened();
1130 redrawItem = symbol;
1131 }
1132 else if( field->IsBrightened() && !connNames.count( pinConn->Name() ) )
1133 {
1134 field->ClearBrightened();
1135 redrawItem = symbol;
1136 }
1137 }
1138 }
1139 }
1140 }
1141 else if( item->Type() == SCH_SHEET_T )
1142 {
1143 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1144
1145 for( SCH_SHEET_PIN* pin : sheet->GetPins() )
1146 {
1147 wxCHECK2( pin, continue );
1148
1149 if( SCH_CONNECTION* pin_conn = pin->Connection() )
1150 {
1151 if( !pin->IsBrightened() && connNames.count( pin_conn->Name() ) )
1152 {
1153 pin->SetBrightened();
1154 redrawItem = sheet;
1155 }
1156 else if( pin->IsBrightened() && !connNames.count( pin_conn->Name() ) )
1157 {
1158 pin->ClearBrightened();
1159 redrawItem = sheet;
1160 }
1161 }
1162 }
1163 }
1164 else
1165 {
1166 if( SCH_CONNECTION* itemConn = item->Connection() )
1167 {
1168 if( !item->IsBrightened() && connNames.count( itemConn->Name() ) )
1169 {
1170 item->SetBrightened();
1171 redrawItem = item;
1172 }
1173 else if( item->IsBrightened() && !connNames.count( itemConn->Name() ) )
1174 {
1175 item->ClearBrightened();
1176 redrawItem = item;
1177 }
1178 }
1179 }
1180
1181 if( redrawItem )
1182 itemsToRedraw.push_back( redrawItem );
1183 }
1184
1185 if( itemsToRedraw.size() )
1186 {
1187 // Be sure highlight change will be redrawn
1188 KIGFX::VIEW* view = getView();
1189
1190 for( EDA_ITEM* redrawItem : itemsToRedraw )
1192
1194 }
1195
1196 return 0;
1197}
1198
1199
1201{
1203
1204 // Deactivate other tools; particularly important if another PICKER is currently running
1205 Activate();
1206
1207 picker->SetCursor( KICURSOR::BULLSEYE );
1208 picker->SetSnapping( false );
1209 picker->ClearHandlers();
1210
1211 picker->SetClickHandler(
1212 [this] ( const VECTOR2D& aPos )
1213 {
1214 return highlightNet( m_toolMgr, aPos );
1215 } );
1216
1218
1219 return 0;
1220}
1221
1222
1224{
1225 wxCHECK( m_frame, 0 );
1226
1227 if( m_frame->GetUndoCommandCount() <= 0 )
1228 return 0;
1229
1230 // Inform tools that undo command was issued
1232
1233 // Get the old list
1235
1236 wxCHECK( undo_list, 0 );
1237
1238 m_frame->PutDataInPreviousState( undo_list );
1239
1240 // Now push the old command to the RedoList
1241 undo_list->ReversePickersListOrder();
1242 m_frame->PushCommandToRedoList( undo_list );
1243
1244 m_toolMgr->GetTool<SCH_SELECTION_TOOL>()->RebuildSelection();
1245
1247 m_frame->OnModify();
1248
1249 return 0;
1250}
1251
1252
1254{
1255 wxCHECK( m_frame, 0 );
1256
1257 if( m_frame->GetRedoCommandCount() == 0 )
1258 return 0;
1259
1260 // Inform tools that undo command was issued
1262
1263 /* Get the old list */
1265
1266 wxCHECK( list, 0 );
1267
1268 /* Redo the command: */
1270
1271 /* Put the old list in UndoList */
1274
1275 m_toolMgr->GetTool<SCH_SELECTION_TOOL>()->RebuildSelection();
1276
1278 m_frame->OnModify();
1279
1280 return 0;
1281}
1282
1283
1284bool SCH_EDITOR_CONTROL::doCopy( bool aUseDuplicateClipboard )
1285{
1287 SCH_SELECTION& selection = selTool->RequestSelection();
1288 SCHEMATIC& schematic = m_frame->Schematic();
1289
1290 if( selection.Empty() )
1291 return false;
1292
1293 if( aUseDuplicateClipboard )
1294 m_duplicateIsHoverSelection = selection.IsHover();
1295
1296 selection.SetScreen( m_frame->GetScreen() );
1298
1299 for( EDA_ITEM* item : selection.GetItems() )
1300 {
1301 if( item->Type() == SCH_SHEET_T )
1302 {
1303 SCH_SHEET* sheet = (SCH_SHEET*) item;
1304 m_supplementaryClipboard[ sheet->GetFileName() ] = sheet->GetScreen();
1305 }
1306 else if( item->Type() == SCH_FIELD_T && selection.IsHover() )
1307 {
1308 // Most of the time the user is trying to duplicate the parent symbol
1309 // and the field text is in it
1310 selection.Add( item->GetParent() );
1311 }
1312 else if( item->Type() == SCH_MARKER_T )
1313 {
1314 // Don't let the markers be copied
1315 selection.Remove( item );
1316 }
1317 else if( item->Type() == SCH_GROUP_T )
1318 {
1319 // Groups need to have all their items selected
1320 static_cast<SCH_ITEM*>( item )->RunOnChildren(
1321 [&]( EDA_ITEM* aChild )
1322 {
1323 selection.Add( aChild );
1324 },
1325 RECURSE_MODE::RECURSE );
1326 }
1327 }
1328
1329 STRING_FORMATTER formatter;
1330 SCH_IO_KICAD_SEXPR plugin;
1332
1333 plugin.Format( &selection, &selPath, schematic, &formatter, true );
1334
1335 std::string prettyData = formatter.GetString();
1336 KICAD_FORMAT::Prettify( prettyData, true );
1337
1338 if( selection.IsHover() )
1340
1341 if( aUseDuplicateClipboard )
1342 {
1343 m_duplicateClipboard = prettyData;
1344 return true;
1345 }
1346
1347 return SaveClipboard( prettyData );
1348}
1349
1350
1351bool SCH_EDITOR_CONTROL::searchSupplementaryClipboard( const wxString& aSheetFilename,
1352 SCH_SCREEN** aScreen )
1353{
1354 if( m_supplementaryClipboard.count( aSheetFilename ) > 0 )
1355 {
1356 *aScreen = m_supplementaryClipboard[ aSheetFilename ];
1357 return true;
1358 }
1359
1360 return false;
1361}
1362
1363
1365{
1366 doCopy( true ); // Use the local clipboard
1367 Paste( aEvent );
1368
1369 return 0;
1370}
1371
1372
1374{
1375 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wxWindow::FindFocus() );
1376
1377 if( textEntry )
1378 {
1379 textEntry->Cut();
1380 return 0;
1381 }
1382
1383 if( doCopy() )
1385
1386 return 0;
1387}
1388
1389
1391{
1392 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wxWindow::FindFocus() );
1393
1394 if( textEntry )
1395 {
1396 textEntry->Copy();
1397 return 0;
1398 }
1399
1400 doCopy();
1401
1402 return 0;
1403}
1404
1405
1407{
1409 SCH_SELECTION& selection = selTool->RequestSelection();
1410
1411 if( selection.Empty() )
1412 return false;
1413
1414 wxString itemsAsText = GetSelectedItemsAsText( selection );
1415
1416 if( selection.IsHover() )
1418
1419 return SaveClipboard( itemsAsText.ToStdString() );
1420}
1421
1422
1424 const SCH_SHEET_PATH& aPastePath,
1425 const KIID_PATH& aClipPath,
1426 bool aForceKeepAnnotations )
1427{
1428 wxCHECK( m_frame && aSymbol, /* void */ );
1429
1430 SCH_SYMBOL_INSTANCE newInstance;
1431 bool instanceFound = false;
1432 KIID_PATH pasteLookupPath = aClipPath;
1433
1434 m_pastedSymbols.insert( aSymbol );
1435
1436 for( const SCH_SYMBOL_INSTANCE& tmp : aSymbol->GetInstances() )
1437 {
1438 if( ( tmp.m_Path.empty() && aClipPath.empty() )
1439 || ( !aClipPath.empty() && tmp.m_Path.EndsWith( aClipPath ) ) )
1440 {
1441 newInstance = tmp;
1442 instanceFound = true;
1443
1444 wxLogTrace( traceSchPaste,
1445 wxS( "Pasting found symbol instance with reference %s, unit %d:"
1446 "\n\tClipboard path: %s\n\tSymbol UUID: %s." ),
1447 tmp.m_Reference, tmp.m_Unit,
1448 aClipPath.AsString(), aSymbol->m_Uuid.AsString() );
1449
1450 break;
1451 }
1452 }
1453
1454 // The pasted symbol look up paths include the symbol UUID.
1455 pasteLookupPath.push_back( aSymbol->m_Uuid );
1456
1457 if( !instanceFound )
1458 {
1459 wxLogTrace( traceSchPaste,
1460 wxS( "Clipboard symbol instance **not** found:\n\tClipboard path: %s\n\t"
1461 "Symbol UUID: %s." ),
1462 aClipPath.AsString(), aSymbol->m_Uuid.AsString() );
1463
1464 // Some legacy versions saved value fields escaped. While we still do in the symbol
1465 // editor, we don't anymore in the schematic, so be sure to unescape them.
1466 SCH_FIELD* valueField = aSymbol->GetField( FIELD_T::VALUE );
1467 valueField->SetText( UnescapeString( valueField->GetText() ) );
1468
1469 // Pasted from notepad or an older instance of eeschema. Use the values in the fields
1470 // instead.
1471 newInstance.m_Reference = aSymbol->GetField( FIELD_T::REFERENCE )->GetText();
1472 newInstance.m_Unit = aSymbol->GetUnit();
1473 }
1474
1475 newInstance.m_Path = aPastePath.Path();
1476 newInstance.m_ProjectName = m_frame->Prj().GetProjectName();
1477
1478 aSymbol->AddHierarchicalReference( newInstance );
1479
1480 if( !aForceKeepAnnotations )
1481 aSymbol->ClearAnnotation( &aPastePath, false );
1482
1483 // We might clear annotations but always leave the original unit number from the paste.
1484 aSymbol->SetUnit( newInstance.m_Unit );
1485}
1486
1487
1489 const SCH_SHEET_PATH& aPastePath,
1490 const KIID_PATH& aClipPath,
1491 bool aForceKeepAnnotations,
1492 SCH_SHEET_LIST* aPastedSheets,
1493 std::map<SCH_SHEET_PATH,
1494 SCH_REFERENCE_LIST>& aPastedSymbols )
1495{
1496 wxCHECK( aSheet && aPastedSheets, aPastePath );
1497
1498 SCH_SHEET_PATH sheetPath = aPastePath;
1499 sheetPath.push_back( aSheet );
1500
1501 aPastedSheets->push_back( sheetPath );
1502
1503 if( aSheet->GetScreen() == nullptr )
1504 return sheetPath; // We can only really set the page number but not load any items
1505
1506 for( SCH_ITEM* item : aSheet->GetScreen()->Items() )
1507 {
1508 if( item->IsConnectable() )
1509 item->SetConnectivityDirty();
1510
1511 if( item->Type() == SCH_SYMBOL_T )
1512 {
1513 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1514
1515 wxCHECK2( symbol, continue );
1516
1517 // Only do this once if the symbol is shared across multiple sheets.
1518 if( !m_pastedSymbols.count( symbol ) )
1519 {
1520 for( SCH_PIN* pin : symbol->GetPins() )
1521 {
1522 const_cast<KIID&>( pin->m_Uuid ) = KIID();
1523 pin->SetConnectivityDirty();
1524 }
1525 }
1526
1527 updatePastedSymbol( symbol, sheetPath, aClipPath, aForceKeepAnnotations );
1528 }
1529 else if( item->Type() == SCH_SHEET_T )
1530 {
1531 SCH_SHEET* subsheet = static_cast<SCH_SHEET*>( item );
1532
1533 wxCHECK2( subsheet, continue );
1534
1535 // Make sure pins get a new UUID and set the dirty connectivity flag.
1536 if( !aPastedSheets->ContainsSheet( subsheet ) )
1537 {
1538 for( SCH_SHEET_PIN* pin : subsheet->GetPins() )
1539 {
1540 const_cast<KIID&>( pin->m_Uuid ) = KIID();
1541 pin->SetConnectivityDirty();
1542 }
1543 }
1544
1545 KIID_PATH newClipPath = aClipPath;
1546 newClipPath.push_back( subsheet->m_Uuid );
1547
1548 updatePastedSheet( subsheet, sheetPath, newClipPath, aForceKeepAnnotations,
1549 aPastedSheets, aPastedSymbols );
1550 }
1551 }
1552
1553 sheetPath.GetSymbols( aPastedSymbols[aPastePath] );
1554
1555 return sheetPath;
1556}
1557
1558
1560{
1561 wxCHECK( aScreen, /* void */ );
1562
1563 for( const SCH_ITEM* item : aScreen->Items() )
1564 {
1565 if( item->Type() == SCH_SYMBOL_T )
1566 {
1567 const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( item );
1568
1569 wxCHECK2( symbol, continue );
1570
1571 for( const SCH_SYMBOL_INSTANCE& symbolInstance : symbol->GetInstances() )
1572 {
1573 KIID_PATH pathWithSymbol = symbolInstance.m_Path;
1574
1575 pathWithSymbol.push_back( symbol->m_Uuid );
1576
1577 m_clipboardSymbolInstances[pathWithSymbol] = symbolInstance;
1578 }
1579 }
1580 }
1581}
1582
1583
1585{
1586 wxCHECK( m_frame, /* void */ );
1587
1588 for( SCH_SYMBOL* symbol : m_pastedSymbols )
1589 {
1590 wxCHECK2( symbol, continue );
1591
1592 std::vector<KIID_PATH> instancePathsToRemove;
1593
1594 for( const SCH_SYMBOL_INSTANCE& instance : symbol->GetInstances() )
1595 {
1596 if( ( instance.m_ProjectName != m_frame->Prj().GetProjectName() )
1597 || instance.m_Path.empty() )
1598 instancePathsToRemove.emplace_back( instance.m_Path );
1599 }
1600
1601 for( const KIID_PATH& path : instancePathsToRemove )
1602 symbol->RemoveInstance( path );
1603 }
1604}
1605
1606
1608{
1609 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wxWindow::FindFocus() );
1610
1611 if( textEntry )
1612 {
1613 textEntry->Paste();
1614 return 0;
1615 }
1616
1618 std::string content;
1619 VECTOR2I eventPos;
1620
1621 SCH_SHEET tempSheet;
1622 SCH_SCREEN* tempScreen = new SCH_SCREEN( &m_frame->Schematic() );
1623 std::unique_ptr<wxImage> clipImg = GetImageFromClipboard();
1624
1625 if( !aEvent.IsAction( &ACTIONS::duplicate ) && clipImg )
1626 {
1627 // Just image data
1628 auto bitmap = std::make_unique<SCH_BITMAP>();
1629
1630 bool ok = bitmap->GetReferenceImage().SetImage( *clipImg );
1631
1632 if( !ok )
1633 {
1634 delete tempScreen;
1635 return 0;
1636 }
1637
1638 tempScreen->Append( bitmap.release() );
1639 }
1640 else
1641 {
1642 if( aEvent.IsAction( &ACTIONS::duplicate ) )
1643 content = m_duplicateClipboard;
1644 else
1645 content = GetClipboardUTF8();
1646
1647 if( content.empty() )
1648 {
1649 delete tempScreen;
1650 return 0;
1651 }
1652
1653 if( aEvent.IsAction( &ACTIONS::duplicate ) )
1654 eventPos = getViewControls()->GetCursorPosition( false );
1655
1656 STRING_LINE_READER reader( content, "Clipboard" );
1657 SCH_IO_KICAD_SEXPR plugin;
1658
1659 // Screen object on heap is owned by the sheet.
1660 tempSheet.SetScreen( tempScreen );
1661
1662 try
1663 {
1664 plugin.LoadContent( reader, &tempSheet );
1665 }
1666 catch( IO_ERROR& )
1667 {
1668 // If it wasn't content, then paste as a text object.
1669 if( content.size() > static_cast<size_t>( ADVANCED_CFG::GetCfg().m_MaxPastedTextLength ) )
1670 {
1671 int result = IsOK( m_frame, _( "Pasting a long text text string may be very slow. "
1672 "Do you want to continue?" ) );
1673 if( !result )
1674 return 0;
1675 }
1676
1677 SCH_TEXT* text_item = new SCH_TEXT( VECTOR2I( 0, 0 ), content );
1678 tempScreen->Append( text_item );
1679 }
1680 }
1681
1682 m_pastedSymbols.clear();
1684
1685 // Save pasted symbol instances in case the user chooses to keep existing symbol annotation.
1686 setPastedSymbolInstances( tempScreen );
1687
1688 tempScreen->MigrateSimModels();
1689
1691 SCHEMATIC_SETTINGS& schematicSettings = m_frame->Schematic().Settings();
1692 int annotateStartNum = schematicSettings.m_AnnotateStartNum;
1693
1694 PASTE_MODE pasteMode = annotate.automatic ? PASTE_MODE::RESPECT_OPTIONS : PASTE_MODE::REMOVE_ANNOTATIONS;
1695 bool forceRemoveAnnotations = false;
1696
1697 if( aEvent.IsAction( &ACTIONS::pasteSpecial ) )
1698 {
1699 PASTE_MODE pasteModeSpecial = pasteMode;
1700 DIALOG_PASTE_SPECIAL dlg( m_frame, &pasteModeSpecial );
1701
1702 if( dlg.ShowModal() == wxID_CANCEL )
1703 return 0;
1704
1705 // We have to distinguish if removing was explicit
1706 forceRemoveAnnotations = ( pasteModeSpecial == PASTE_MODE::REMOVE_ANNOTATIONS );
1707 pasteMode = pasteModeSpecial;
1708 }
1709
1710 bool forceKeepAnnotations = pasteMode != PASTE_MODE::REMOVE_ANNOTATIONS;
1711
1712 // SCH_SEXP_PLUGIN added the items to the paste screen, but not to the view or anything
1713 // else. Pull them back out to start with.
1714 SCH_COMMIT commit( m_toolMgr );
1715 EDA_ITEMS loadedItems;
1716 std::vector<SCH_ITEM*> sortedLoadedItems;
1717 bool sheetsPasted = false;
1718 SCH_SHEET_LIST hierarchy = m_frame->Schematic().Hierarchy();
1719 SCH_SHEET_PATH& pasteRoot = m_frame->GetCurrentSheet();
1720 wxFileName destFn = pasteRoot.Last()->GetFileName();
1721
1722 if( destFn.IsRelative() )
1723 destFn.MakeAbsolute( m_frame->Prj().GetProjectPath() );
1724
1725 // List of paths in the hierarchy that refer to the destination sheet of the paste
1726 SCH_SHEET_LIST sheetPathsForScreen = hierarchy.FindAllSheetsForScreen( pasteRoot.LastScreen() );
1727 sheetPathsForScreen.SortByPageNumbers();
1728
1729 // Build a list of screens from the current design (to avoid loading sheets that already exist)
1730 std::map<wxString, SCH_SCREEN*> loadedScreens;
1731
1732 for( const SCH_SHEET_PATH& item : hierarchy )
1733 {
1734 if( item.LastScreen() )
1735 loadedScreens[item.Last()->GetFileName()] = item.LastScreen();
1736 }
1737
1738 // Get set of sheet names in the current schematic to prevent duplicate sheet names on paste.
1739 std::set<wxString> existingSheetNames = pasteRoot.LastScreen()->GetSheetNames();
1740
1741 // Build symbol list for reannotation of duplicates
1742 SCH_REFERENCE_LIST existingRefs;
1743 hierarchy.GetSymbols( existingRefs );
1744 existingRefs.SortByReferenceOnly();
1745
1746 std::set<wxString> existingRefsSet;
1747
1748 for( const SCH_REFERENCE& ref : existingRefs )
1749 existingRefsSet.insert( ref.GetRef() );
1750
1751 // Build UUID map for fetching last-resolved-properties
1752 std::map<KIID, EDA_ITEM*> itemMap;
1753 hierarchy.FillItemMap( itemMap );
1754
1755 // Keep track of pasted sheets and symbols for the different paths to the hierarchy.
1756 std::map<SCH_SHEET_PATH, SCH_REFERENCE_LIST> pastedSymbols;
1757 std::map<SCH_SHEET_PATH, SCH_SHEET_LIST> pastedSheets;
1758
1759 for( SCH_ITEM* item : tempScreen->Items() )
1760 {
1761 if( item->Type() == SCH_SHEET_T )
1762 sortedLoadedItems.push_back( item );
1763 else
1764 loadedItems.push_back( item );
1765 }
1766
1767 sort( sortedLoadedItems.begin(), sortedLoadedItems.end(),
1768 []( SCH_ITEM* firstItem, SCH_ITEM* secondItem )
1769 {
1770 SCH_SHEET* firstSheet = static_cast<SCH_SHEET*>( firstItem );
1771 SCH_SHEET* secondSheet = static_cast<SCH_SHEET*>( secondItem );
1772 return StrNumCmp( firstSheet->GetName(), secondSheet->GetName(), false ) < 0;
1773 });
1774
1775
1776 for( SCH_ITEM* item : sortedLoadedItems )
1777 {
1778 loadedItems.push_back( item );
1779
1780 if( item->Type() == SCH_SHEET_T )
1781 {
1782 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1783 wxFileName srcFn = sheet->GetFileName();
1784
1785 if( srcFn.IsRelative() )
1786 srcFn.MakeAbsolute( m_frame->Prj().GetProjectPath() );
1787
1788 SCH_SHEET_LIST sheetHierarchy( sheet );
1789
1790 if( hierarchy.TestForRecursion( sheetHierarchy, destFn.GetFullPath( wxPATH_UNIX ) ) )
1791 {
1792 auto msg = wxString::Format( _( "The pasted sheet '%s'\n"
1793 "was dropped because the destination already has "
1794 "the sheet or one of its subsheets as a parent." ),
1795 sheet->GetFileName() );
1796 DisplayError( m_frame, msg );
1797 loadedItems.pop_back();
1798 }
1799 }
1800 }
1801
1802 // Remove the references from our temporary screen to prevent freeing on the DTOR
1803 tempScreen->Clear( false );
1804
1805 for( EDA_ITEM* item : loadedItems )
1806 {
1807 KIID_PATH clipPath( wxT( "/" ) ); // clipboard is at root
1808
1809 SCH_ITEM* schItem = static_cast<SCH_ITEM*>( item );
1810
1811 wxCHECK2( schItem, continue );
1812
1813 if( schItem->IsConnectable() )
1814 schItem->SetConnectivityDirty();
1815
1816 if( item->Type() == SCH_SYMBOL_T )
1817 {
1818 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1819
1820 // The library symbol gets set from the cached library symbols in the current
1821 // schematic not the symbol libraries. The cached library symbol may have
1822 // changed from the original library symbol which would cause the copy to
1823 // be incorrect.
1824 SCH_SCREEN* currentScreen = m_frame->GetScreen();
1825
1826 wxCHECK2( currentScreen, continue );
1827
1828 auto it = currentScreen->GetLibSymbols().find( symbol->GetSchSymbolLibraryName() );
1829 auto end = currentScreen->GetLibSymbols().end();
1830
1831 if( it == end )
1832 {
1833 // If can't find library definition in the design, use the pasted library
1834 it = tempScreen->GetLibSymbols().find( symbol->GetSchSymbolLibraryName() );
1835 end = tempScreen->GetLibSymbols().end();
1836 }
1837
1838 LIB_SYMBOL* libSymbol = nullptr;
1839
1840 if( it != end )
1841 {
1842 libSymbol = new LIB_SYMBOL( *it->second );
1843 symbol->SetLibSymbol( libSymbol );
1844 }
1845
1846 // If the symbol is already in the schematic we have to always keep the
1847 // annotations. The exception is if the user has chosen to remove them.
1848 for( const SCH_SYMBOL_INSTANCE& instance : symbol->GetInstances() )
1849 {
1850 if( !existingRefsSet.contains( instance.m_Reference ) )
1851 {
1852 forceKeepAnnotations = !forceRemoveAnnotations;
1853 break;
1854 }
1855 }
1856
1857 for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
1858 updatePastedSymbol( symbol, sheetPath, clipPath, forceKeepAnnotations );
1859
1860 // Most modes will need new KIIDs for the symbol and its pins
1861 // However, if we are pasting unique annotations, we need to check if the symbol
1862 // is not already in the hierarchy. If we don't already have a copy of the
1863 // symbol, we just keep the existing KIID data as it is likely the same symbol
1864 // being moved around the schematic
1865 bool needsNewKiid = ( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS );
1866
1867 for( const SCH_SYMBOL_INSTANCE& instance : symbol->GetInstances() )
1868 {
1869 if( existingRefsSet.contains( instance.m_Reference ) )
1870 {
1871 needsNewKiid = true;
1872 break;
1873 }
1874 }
1875
1876 if( needsNewKiid )
1877 {
1878 // Assign a new KIID
1879 const_cast<KIID&>( item->m_Uuid ) = KIID();
1880
1881 // Make sure pins get a new UUID
1882 for( SCH_PIN* pin : symbol->GetPins() )
1883 {
1884 const_cast<KIID&>( pin->m_Uuid ) = KIID();
1885 pin->SetConnectivityDirty();
1886 }
1887
1888 for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
1889 {
1890 // Ignore symbols from a non-existant library.
1891 if( libSymbol )
1892 {
1893 SCH_REFERENCE schReference( symbol, sheetPath );
1894 schReference.SetSheetNumber( sheetPath.GetVirtualPageNumber() );
1895 pastedSymbols[sheetPath].AddItem( schReference );
1896 }
1897 }
1898 }
1899 }
1900 else if( item->Type() == SCH_SHEET_T )
1901 {
1902 SCH_SHEET* sheet = (SCH_SHEET*) item;
1903 SCH_FIELD* nameField = sheet->GetField( FIELD_T::SHEET_NAME );
1904 wxString baseName = nameField->GetText();
1905 wxString candidateName = baseName;
1906 wxString number;
1907
1908 while( !baseName.IsEmpty() && wxIsdigit( baseName.Last() ) )
1909 {
1910 number = baseName.Last() + number;
1911 baseName.RemoveLast();
1912 }
1913
1914 // Update hierarchy to include any other sheets we already added, avoiding
1915 // duplicate sheet names
1916 hierarchy = m_frame->Schematic().Hierarchy();
1917
1918 int uniquifier = std::max( 0, wxAtoi( number ) ) + 1;
1919
1920 while( existingSheetNames.count( candidateName ) )
1921 candidateName = wxString::Format( wxT( "%s%d" ), baseName, uniquifier++ );
1922
1923 nameField->SetText( candidateName );
1924 existingSheetNames.emplace( candidateName );
1925
1926 wxFileName fn = sheet->GetFileName();
1927 SCH_SCREEN* existingScreen = nullptr;
1928
1929 sheet->SetParent( pasteRoot.Last() );
1930 sheet->SetScreen( nullptr );
1931
1932 if( !fn.IsAbsolute() )
1933 {
1934 wxFileName currentSheetFileName = pasteRoot.LastScreen()->GetFileName();
1935 fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS,
1936 currentSheetFileName.GetPath() );
1937 }
1938
1939 // Try to find the screen for the pasted sheet by several means
1940 if( !m_frame->Schematic().Root().SearchHierarchy( fn.GetFullPath( wxPATH_UNIX ),
1941 &existingScreen ) )
1942 {
1943 if( loadedScreens.count( sheet->GetFileName() ) > 0 )
1944 existingScreen = loadedScreens.at( sheet->GetFileName() );
1945 else
1946 searchSupplementaryClipboard( sheet->GetFileName(), &existingScreen );
1947 }
1948
1949 if( existingScreen )
1950 {
1951 sheet->SetScreen( existingScreen );
1952 }
1953 else
1954 {
1955 if( !m_frame->LoadSheetFromFile( sheet, &pasteRoot, fn.GetFullPath() ) )
1956 m_frame->InitSheet( sheet, sheet->GetFileName() );
1957 }
1958
1959 // Save the symbol instances in case the user chooses to keep the existing
1960 // symbol annotation.
1962 sheetsPasted = true;
1963
1964 // Push it to the clipboard path while it still has its old KIID
1965 clipPath.push_back( sheet->m_Uuid );
1966
1967 // Assign a new KIID to the pasted sheet
1968 const_cast<KIID&>( sheet->m_Uuid ) = KIID();
1969
1970 // Make sure pins get a new UUID
1971 for( SCH_SHEET_PIN* pin : sheet->GetPins() )
1972 {
1973 const_cast<KIID&>( pin->m_Uuid ) = KIID();
1974 pin->SetConnectivityDirty();
1975 }
1976
1977 // Once we have our new KIID we can update all pasted instances. This will either
1978 // reset the annotations or copy "kept" annotations from the supplementary clipboard.
1979 for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
1980 {
1981 SCH_SHEET_PATH subPath = updatePastedSheet( sheet, sheetPath, clipPath,
1982 ( forceKeepAnnotations && annotate.automatic ),
1983 &pastedSheets[sheetPath],
1984 pastedSymbols );
1985 }
1986 }
1987 else
1988 {
1989 SCH_ITEM* srcItem = dynamic_cast<SCH_ITEM*>( itemMap[ item->m_Uuid ] );
1990 SCH_ITEM* destItem = dynamic_cast<SCH_ITEM*>( item );
1991
1992 // Everything gets a new KIID
1993 const_cast<KIID&>( item->m_Uuid ) = KIID();
1994
1995 if( srcItem && destItem )
1996 {
1997 destItem->SetConnectivityDirty( true );
1998 destItem->SetLastResolvedState( srcItem );
1999 }
2000 }
2001
2002 // Lines need both ends selected for a move after paste so the whole line moves.
2003 if( item->Type() == SCH_LINE_T )
2004 item->SetFlags( STARTPOINT | ENDPOINT );
2005
2006 item->SetFlags( IS_NEW | IS_PASTED | IS_MOVING );
2007
2008 if( !m_frame->GetScreen()->CheckIfOnDrawList( (SCH_ITEM*) item ) ) // don't want a loop!
2009 m_frame->AddToScreen( item, m_frame->GetScreen() );
2010
2011 commit.Added( (SCH_ITEM*) item, m_frame->GetScreen() );
2012
2013 // Start out hidden so the pasted items aren't "ghosted" in their original location
2014 // before being moved to the current location.
2015 getView()->Hide( item, true );
2016 }
2017
2018 if( sheetsPasted )
2019 {
2020 // The full schematic hierarchy need to be update before assigning new annotation and
2021 // page numbers.
2023
2024 // Update page numbers: Find next free numeric page number
2025 for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
2026 {
2027 for( SCH_SHEET_PATH& pastedSheet : pastedSheets[sheetPath] )
2028 {
2029 int page = 1;
2030 wxString pageNum = wxString::Format( "%d", page );
2031
2032 while( hierarchy.PageNumberExists( pageNum ) )
2033 pageNum = wxString::Format( "%d", ++page );
2034
2035 SCH_SHEET_INSTANCE sheetInstance;
2036
2037 sheetInstance.m_Path = pastedSheet.Path();
2038
2039 // Don't include the actual sheet in the instance path.
2040 sheetInstance.m_Path.pop_back();
2041 sheetInstance.m_PageNumber = pageNum;
2042 sheetInstance.m_ProjectName = m_frame->Prj().GetProjectName();
2043
2044 SCH_SHEET* sheet = pastedSheet.Last();
2045
2046 wxCHECK2( sheet, continue );
2047
2048 sheet->AddInstance( sheetInstance );
2049 hierarchy.push_back( pastedSheet );
2050
2051 // Remove all pasted sheet instance data that is not part of the current project.
2052 std::vector<KIID_PATH> instancesToRemove;
2053
2054 for( const SCH_SHEET_INSTANCE& instance : sheet->GetInstances() )
2055 {
2056 if( !hierarchy.HasPath( instance.m_Path ) )
2057 instancesToRemove.push_back( instance.m_Path );
2058 }
2059
2060 for( const KIID_PATH& instancePath : instancesToRemove )
2061 sheet->RemoveInstance( instancePath );
2062 }
2063 }
2064
2066
2067 // Get a version with correct sheet numbers since we've pasted sheets,
2068 // we'll need this when annotating next
2069 hierarchy = m_frame->Schematic().Hierarchy();
2070 }
2071
2072 std::map<SCH_SHEET_PATH, SCH_REFERENCE_LIST> annotatedSymbols;
2073
2074 // Update the list of symbol instances that satisfy the annotation criteria.
2075 for( const SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
2076 {
2077 for( size_t i = 0; i < pastedSymbols[sheetPath].GetCount(); i++ )
2078 {
2079 if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS
2080 || pasteMode == PASTE_MODE::RESPECT_OPTIONS
2081 || pastedSymbols[sheetPath][i].AlwaysAnnotate() )
2082 {
2083 annotatedSymbols[sheetPath].AddItem( pastedSymbols[sheetPath][i] );
2084 }
2085 }
2086
2087 for( const SCH_SHEET_PATH& pastedSheetPath : pastedSheets[sheetPath] )
2088 {
2089 for( size_t i = 0; i < pastedSymbols[pastedSheetPath].GetCount(); i++ )
2090 {
2091 if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS
2092 || pasteMode == PASTE_MODE::RESPECT_OPTIONS
2093 || pastedSymbols[pastedSheetPath][i].AlwaysAnnotate() )
2094 {
2095 annotatedSymbols[pastedSheetPath].AddItem( pastedSymbols[pastedSheetPath][i] );
2096 }
2097 }
2098 }
2099 }
2100
2101 if( !annotatedSymbols.empty() )
2102 {
2103 for( SCH_SHEET_PATH& path : sheetPathsForScreen )
2104 {
2105 annotatedSymbols[path].SortByReferenceOnly();
2106 annotatedSymbols[path].SetRefDesTracker( schematicSettings.m_refDesTracker );
2107
2108 if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS )
2109 {
2110 annotatedSymbols[path].ReannotateDuplicates( existingRefs );
2111 }
2112 else
2113 {
2114 annotatedSymbols[path].ReannotateByOptions( (ANNOTATE_ORDER_T) annotate.sort_order,
2115 (ANNOTATE_ALGO_T) annotate.method,
2116 annotateStartNum, existingRefs, false,
2117 &hierarchy );
2118 }
2119
2120 annotatedSymbols[path].UpdateAnnotation();
2121
2122 // Update existing refs for next iteration
2123 for( size_t i = 0; i < annotatedSymbols[path].GetCount(); i++ )
2124 existingRefs.AddItem( annotatedSymbols[path][i] );
2125
2126 for( const SCH_SHEET_PATH& pastedSheetPath : pastedSheets[path] )
2127 {
2128 annotatedSymbols[pastedSheetPath].SortByReferenceOnly();
2129 annotatedSymbols[pastedSheetPath].SetRefDesTracker( schematicSettings.m_refDesTracker );
2130
2131 if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS )
2132 {
2133 annotatedSymbols[pastedSheetPath].ReannotateDuplicates( existingRefs );
2134 }
2135 else
2136 {
2137 annotatedSymbols[pastedSheetPath].ReannotateByOptions( (ANNOTATE_ORDER_T) annotate.sort_order,
2138 (ANNOTATE_ALGO_T) annotate.method,
2139 annotateStartNum, existingRefs,
2140 false,
2141 &hierarchy );
2142 }
2143
2144 annotatedSymbols[pastedSheetPath].UpdateAnnotation();
2145
2146 // Update existing refs for next iteration
2147 for( size_t i = 0; i < annotatedSymbols[pastedSheetPath].GetCount(); i++ )
2148 existingRefs.AddItem( annotatedSymbols[pastedSheetPath][i] );
2149 }
2150 }
2151 }
2152
2154
2155 // The copy operation creates instance paths that are not valid for the current project or
2156 // saved as part of another project. Prune them now so they do not accumulate in the saved
2157 // schematic file.
2159
2161 SCH_SCREENS allScreens( m_frame->Schematic().Root() );
2162
2163 allScreens.PruneOrphanedSymbolInstances( m_frame->Prj().GetProjectName(), sheets );
2164 allScreens.PruneOrphanedSheetInstances( m_frame->Prj().GetProjectName(), sheets );
2165
2166 // Now clear the previous selection, select the pasted items, and fire up the "move" tool.
2168
2169 // If the item has a parent group, it will be part of the loadedItems, and will handle
2170 // the move action. Iterate backwards to avoid invalidating the iterator.
2171 for( int i = loadedItems.size() - 1; i >= 0; i-- )
2172 {
2173 EDA_ITEM* item = loadedItems[i];
2174
2175 if( item->GetParentGroup() )
2176 {
2177 loadedItems.erase( loadedItems.begin() + i );
2178 // These were hidden before because they would be added to the move preview,
2179 // but now they need to be shown as a preview so they appear to move when
2180 // the group moves.
2181 getView()->SetVisible( item );
2182 getView()->AddToPreview( item, false );
2183 }
2184 }
2185
2187
2188 SCH_SELECTION& selection = selTool->GetSelection();
2189
2190 if( !selection.Empty() )
2191 {
2192 if( aEvent.IsAction( &ACTIONS::duplicate ) )
2193 {
2194 int closest_dist = INT_MAX;
2195
2196 auto processPt =
2197 [&]( const VECTOR2I& pt )
2198 {
2199 int dist = ( eventPos - pt ).EuclideanNorm();
2200
2201 if( dist < closest_dist )
2202 {
2203 selection.SetReferencePoint( pt );
2204 closest_dist = dist;
2205 }
2206 };
2207
2208 // Prefer connection points (which should remain on grid)
2209 for( EDA_ITEM* item : selection.Items() )
2210 {
2211 SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
2212 SCH_PIN* pin = dynamic_cast<SCH_PIN*>( item );
2213
2214 if( sch_item && sch_item->IsConnectable() )
2215 {
2216 for( const VECTOR2I& pt : sch_item->GetConnectionPoints() )
2217 processPt( pt );
2218 }
2219 else if( pin )
2220 {
2221 processPt( pin->GetPosition() );
2222 }
2223
2224 // Symbols need to have their center point added since often users are trying to
2225 // move parts from their center.
2226 if( dynamic_cast<SCH_SYMBOL*>( item ) )
2227 processPt( item->GetPosition() );
2228 }
2229
2230 // Only process other points if we didn't find any connection points
2231 if( closest_dist == INT_MAX )
2232 {
2233 for( EDA_ITEM* item : selection.Items() )
2234 {
2235 switch( item->Type() )
2236 {
2237 case SCH_LINE_T:
2238 processPt( static_cast<SCH_LINE*>( item )->GetStartPoint() );
2239 processPt( static_cast<SCH_LINE*>( item )->GetEndPoint() );
2240 break;
2241
2242 case SCH_SHAPE_T:
2243 {
2244 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( item );
2245
2246 switch( shape->GetShape() )
2247 {
2248 case SHAPE_T::RECTANGLE:
2249 for( const VECTOR2I& pt : shape->GetRectCorners() )
2250 processPt( pt );
2251
2252 break;
2253
2254 case SHAPE_T::CIRCLE:
2255 processPt( shape->GetCenter() );
2256 break;
2257
2258 case SHAPE_T::POLY:
2259 for( int ii = 0; ii < shape->GetPolyShape().TotalVertices(); ++ii )
2260 processPt( shape->GetPolyShape().CVertex( ii ) );
2261
2262 break;
2263
2264 default:
2265 processPt( shape->GetStart() );
2266 processPt( shape->GetEnd() );
2267 break;
2268 }
2269
2270 break;
2271 }
2272
2273 default:
2274 processPt( item->GetPosition() );
2275 break;
2276 }
2277 }
2278 }
2279
2280 selection.SetIsHover( m_duplicateIsHoverSelection );
2281 }
2282 // We want to the first non-group item in the selection to be the reference point.
2283 else if( selection.GetTopLeftItem()->Type() == SCH_GROUP_T )
2284 {
2285 SCH_GROUP* group = static_cast<SCH_GROUP*>( selection.GetTopLeftItem() );
2286
2287 bool found = false;
2288 SCH_ITEM* item = nullptr;
2289
2290 group->RunOnChildren(
2291 [&]( SCH_ITEM* schItem )
2292 {
2293 if( !found && schItem->Type() != SCH_GROUP_T )
2294 {
2295 item = schItem;
2296 found = true;
2297 }
2298 },
2299 RECURSE_MODE::RECURSE );
2300
2301 if( found )
2302 selection.SetReferencePoint( item->GetPosition() );
2303 else
2304 selection.SetReferencePoint( group->GetPosition() );
2305 }
2306 else
2307 {
2308 SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetTopLeftItem() );
2309
2310 selection.SetReferencePoint( item->GetPosition() );
2311 }
2312
2314 {
2315 // Pushing the commit will update the connectivity.
2316 commit.Push( _( "Paste" ) );
2317
2318 if( sheetsPasted )
2319 {
2321 // UpdateHierarchyNavigator() will call RefreshNetNavigator()
2322 }
2323 else
2324 {
2326 }
2327 }
2328 else
2329 {
2330 commit.Revert();
2331 }
2332
2333 getView()->ClearPreview();
2334 }
2335
2336 return 0;
2337}
2338
2339
2341{
2343 SCH_SELECTION& selection = selTool->RequestSelection( { SCH_SYMBOL_T } );
2344 SCH_SYMBOL* symbol = nullptr;
2345 SYMBOL_EDIT_FRAME* symbolEditor;
2346
2347 if( selection.GetSize() >= 1 )
2348 symbol = (SCH_SYMBOL*) selection.Front();
2349
2350 if( selection.IsHover() )
2352
2353 if( !symbol )
2354 {
2355 // Giant hack: by default we assign Edit Table to the same hotkey, so give the table
2356 // tool a chance to handle it if we can't.
2358 tableTool->EditTable( aEvent );
2359
2360 return 0;
2361 }
2362
2363 if( symbol->GetEditFlags() != 0 )
2364 return 0;
2365
2366 if( symbol->IsMissingLibSymbol() )
2367 {
2368 m_frame->ShowInfoBarError( _( "Symbols with broken library symbol links cannot "
2369 "be edited." ) );
2370 return 0;
2371 }
2372
2374 symbolEditor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, false );
2375
2376 if( symbolEditor )
2377 {
2378 if( wxWindow* blocking_win = symbolEditor->Kiway().GetBlockingDialog() )
2379 blocking_win->Close( true );
2380
2381 if( aEvent.IsAction( &SCH_ACTIONS::editWithLibEdit ) )
2382 {
2383 symbolEditor->LoadSymbolFromSchematic( symbol );
2384 }
2386 {
2387 symbolEditor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(),
2388 symbol->GetBodyStyle() );
2389
2390 if( !symbolEditor->IsLibraryTreeShown() )
2391 symbolEditor->ToggleLibraryTree();
2392 }
2393 }
2394
2395 return 0;
2396}
2397
2398
2400{
2402 return 0;
2403}
2404
2405
2407{
2409 dlg.m_FirstRefDes->SetValidator( wxTextValidator( wxFILTER_EMPTY ) );
2410
2411 dlg.SetInitialFocus( dlg.m_FirstRefDes );
2412
2413 if( dlg.ShowModal() == wxID_OK )
2414 {
2415 SCH_REFERENCE startRef;
2416 startRef.SetRef( dlg.m_FirstRefDes->GetValue() );
2417
2418 if( startRef.IsSplitNeeded() )
2419 startRef.Split();
2420 else
2421 return 0;
2422
2423 int startNum = atoi( startRef.GetRefNumber().utf8_string().c_str() );
2424
2425 SCH_COMMIT commit( m_frame );
2426 SCHEMATIC* schematic = m_frame->m_schematic;
2427 SCH_REFERENCE_LIST references;
2428
2429 if( dlg.m_AllSheets->GetValue() )
2430 schematic->Hierarchy().GetSymbols( references );
2431 else
2432 schematic->CurrentSheet().GetSymbols( references );
2433
2434 references.SplitReferences();
2435
2436 for( SCH_REFERENCE& ref : references )
2437 {
2438 if( ref.GetRef() == startRef.GetRef() )
2439 {
2440 int num = atoi( ref.GetRefNumber().utf8_string().c_str() );
2441
2442 if( num >= startNum )
2443 {
2444 const SCH_SHEET_PATH& sheet = ref.GetSheetPath();
2445 wxString fullRef = ref.GetRef();
2446
2447 num += dlg.m_Increment->GetValue();
2448 fullRef << num;
2449
2450 commit.Modify( ref.GetSymbol(), sheet.LastScreen(), RECURSE_MODE::NO_RECURSE );
2451 ref.GetSymbol()->SetRef( &sheet, From_UTF8( fullRef.c_str() ) );
2452 }
2453 }
2454 }
2455
2456 if( !commit.Empty() )
2457 commit.Push( _( "Increment Annotations" ) );
2458 }
2459
2460 return 0;
2461}
2462
2463
2465{
2467 return 0;
2468}
2469
2470
2472{
2474
2475 wxCHECK( dlg, 0 );
2476
2477 // Needed at least on Windows. Raise() is not enough
2478 dlg->Show( true );
2479
2480 // Bring it to the top if already open. Dual monitor users need this.
2481 dlg->Raise();
2482
2483 dlg->ShowEditTab();
2484
2485 return 0;
2486}
2487
2488
2490{
2493
2494 return 0;
2495}
2496
2497
2499{
2501 return 0;
2502}
2503
2504
2506{
2508 return 0;
2509}
2510
2511
2513{
2515 dlg.ShowModal();
2516 return 0;
2517}
2518
2519
2521{
2522 int result = NET_PLUGIN_CHANGE;
2523
2524 // If a plugin is removed or added, rebuild and reopen the new dialog
2525 while( result == NET_PLUGIN_CHANGE )
2526 result = InvokeDialogNetList( m_frame );
2527
2528 return 0;
2529}
2530
2531
2533{
2535
2536 wxCHECK( dlg, 0 );
2537
2538 // Needed at least on Windows. Raise() is not enough
2539 dlg->Show( true );
2540
2541 // Bring it to the top if already open. Dual monitor users need this.
2542 dlg->Raise();
2543
2544 dlg->ShowExportTab();
2545
2546 return 0;
2547}
2548
2549
2551{
2553 return 0;
2554}
2555
2556
2558{
2561 return 0;
2562}
2563
2564
2566{
2567 getEditFrame<SCH_EDIT_FRAME>()->ToggleSearch();
2568 return 0;
2569}
2570
2571
2573{
2574 getEditFrame<SCH_EDIT_FRAME>()->ToggleSchematicHierarchy();
2575 return 0;
2576}
2577
2578
2580{
2581 getEditFrame<SCH_EDIT_FRAME>()->ToggleNetNavigator();
2582 return 0;
2583}
2584
2585
2587{
2588 getEditFrame<SCH_EDIT_FRAME>()->ToggleProperties();
2589 return 0;
2590}
2591
2592
2594{
2595 getEditFrame<SCH_EDIT_FRAME>()->ToggleLibraryTree();
2596 return 0;
2597}
2598
2599
2601{
2604
2607
2608 return 0;
2609}
2610
2611
2613{
2616
2619
2620 return 0;
2621}
2622
2623
2625{
2628
2631
2632 return 0;
2633}
2634
2635
2637{
2640
2643
2644 return 0;
2645}
2646
2647
2649{
2652
2655
2656 return 0;
2657}
2658
2659
2661{
2664
2666
2667 return 0;
2668}
2669
2670
2672{
2675
2677 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
2678 {
2679 int flags = 0;
2680
2681 auto invalidateTextVars =
2682 [&flags]( EDA_TEXT* text )
2683 {
2684 if( text->HasTextVars() )
2685 {
2686 text->ClearRenderCache();
2687 text->ClearBoundingBoxCache();
2689 }
2690 };
2691
2692 if( SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aItem ) )
2693 {
2694 item->RunOnChildren(
2695 [&invalidateTextVars]( SCH_ITEM* aChild )
2696 {
2697 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aChild ) )
2698 invalidateTextVars( text );
2699 },
2700 RECURSE_MODE::NO_RECURSE );
2701
2702 if( item->GetExcludedFromSim() )
2704 }
2705
2706 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aItem ) )
2707 invalidateTextVars( text );
2708
2709 return flags;
2710 } );
2711
2713
2714 return 0;
2715}
2716
2717
2719{
2722
2726
2727 return 0;
2728}
2729
2730
2732{
2735
2739
2740 return 0;
2741}
2742
2743
2745{
2748
2750
2753
2754 return 0;
2755}
2756
2757
2759{
2762 return 0;
2763}
2764
2765
2767{
2769 m_frame->eeconfig()->m_Drawing.line_mode %= LINE_MODE::LINE_MODE_COUNT;
2771 return 0;
2772}
2773
2774
2776{
2779 return 0;
2780}
2781
2782
2784{
2787 return 0;
2788}
2789
2790
2792{
2793
2795 return 0;
2796}
2797
2798
2800{
2801#ifdef KICAD_IPC_API
2802 if( Pgm().GetCommonSettings()->m_Api.enable_server )
2803 Pgm().GetPluginManager().ReloadPlugins();
2804#endif
2805 return 0;
2806}
2807
2808
2810{
2811 int errors = 0;
2812 wxString details;
2813 bool quiet = aEvent.Parameter<bool>();
2814
2815 // Repair duplicate IDs.
2816 std::map<KIID, EDA_ITEM*> ids;
2817 int duplicates = 0;
2818
2820
2821 auto processItem =
2822 [&]( EDA_ITEM* aItem )
2823 {
2824 auto it = ids.find( aItem->m_Uuid );
2825
2826 if( it != ids.end() && it->second != aItem )
2827 {
2828 duplicates++;
2829 const_cast<KIID&>( aItem->m_Uuid ) = KIID();
2830 }
2831
2832 ids[ aItem->m_Uuid ] = aItem;
2833 };
2834
2835 // Symbol IDs are the most important, so give them the first crack at "claiming" a
2836 // particular KIID.
2837
2838 for( const SCH_SHEET_PATH& sheet : sheets )
2839 {
2840 SCH_SCREEN* screen = sheet.LastScreen();
2841
2842 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
2843 {
2844 processItem( item );
2845
2846 for( SCH_PIN* pin : static_cast<SCH_SYMBOL*>( item )->GetPins( &sheet ) )
2847 processItem( pin );
2848 }
2849 }
2850
2851 for( const SCH_SHEET_PATH& sheet : sheets )
2852 {
2853 SCH_SCREEN* screen = sheet.LastScreen();
2854
2855 for( SCH_ITEM* item : screen->Items() )
2856 {
2857 processItem( item );
2858
2859 if( item->Type() != SCH_GROUP_T )
2860 {
2861 item->RunOnChildren(
2862 [&]( SCH_ITEM* aChild )
2863 {
2864 processItem( item );
2865 },
2866 RECURSE_MODE::NO_RECURSE );
2867 }
2868 }
2869 }
2870
2871 /*******************************
2872 * Your test here
2873 */
2874
2875 /*******************************
2876 * Inform the user
2877 */
2878
2879 if( duplicates )
2880 {
2881 errors += duplicates;
2882 details += wxString::Format( _( "%d duplicate IDs replaced.\n" ), duplicates );
2883
2884 // Rehash sheetpaths as we may have changed their uuids.
2886 }
2887
2888 if( errors )
2889 {
2890 m_frame->OnModify();
2891
2892 wxString msg = wxString::Format( _( "%d potential problems repaired." ), errors );
2893
2894 if( !quiet )
2895 DisplayInfoMessage( m_frame, msg, details );
2896 }
2897 else if( !quiet )
2898 {
2899 DisplayInfoMessage( m_frame, _( "No errors found." ) );
2900 }
2901
2902 return 0;
2903}
2904
2905
2907{
2908 if( !Pgm().GetCommonSettings()->m_Input.hotkey_feedback )
2909 return 0;
2910
2911 GRID_SETTINGS& gridSettings = m_toolMgr->GetSettings()->m_Window.grid;
2912 int currentIdx = m_toolMgr->GetSettings()->m_Window.grid.last_size_idx;
2913
2914 wxArrayString gridsLabels;
2915
2916 for( const GRID& grid : gridSettings.grids )
2917 gridsLabels.Add( grid.UserUnitsMessageText( m_frame ) );
2918
2919 if( !m_frame->GetHotkeyPopup() )
2921
2923
2924 if( popup )
2925 popup->Popup( _( "Grid" ), gridsLabels, currentIdx );
2926
2927 return 0;
2928}
2929
2930
2932{
2933 SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
2934
2935 if( !editFrame )
2936 return 1;
2937
2938 // Need to have a group selected and it needs to have a linked design block
2940 SCH_SELECTION selection = selTool->GetSelection();
2941
2942 if( selection.Size() != 1 || selection[0]->Type() != SCH_GROUP_T )
2943 return 1;
2944
2945 SCH_GROUP* group = static_cast<SCH_GROUP*>( selection[0] );
2946
2947 if( !group->HasDesignBlockLink() )
2948 return 1;
2949
2950 // Get the associated design block
2951 DESIGN_BLOCK_PANE* designBlockPane = editFrame->GetDesignBlockPane();
2952 std::unique_ptr<DESIGN_BLOCK> designBlock( designBlockPane->GetDesignBlock( group->GetDesignBlockLibId(),
2953 true, true ) );
2954
2955 if( !designBlock )
2956 {
2957 wxString msg;
2958 msg.Printf( _( "Could not find design block %s." ), group->GetDesignBlockLibId().GetUniStringLibId() );
2959 m_frame->GetInfoBar()->ShowMessageFor( msg, 5000, wxICON_WARNING );
2960 return 1;
2961 }
2962
2963 if( designBlock->GetSchematicFile().IsEmpty() )
2964 {
2965 wxString msg;
2966 msg.Printf( _( "Design block %s does not have a schematic file." ),
2967 group->GetDesignBlockLibId().GetUniStringLibId() );
2968 m_frame->GetInfoBar()->ShowMessageFor( msg, 5000, wxICON_WARNING );
2969 return 1;
2970 }
2971
2972 editFrame->GetDesignBlockPane()->SelectLibId( group->GetDesignBlockLibId() );
2973
2974 return m_toolMgr->RunAction( SCH_ACTIONS::placeDesignBlock, designBlock.release() );
2975}
2976
2977
2979{
2980 SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
2981
2982 if( !editFrame )
2983 return 1;
2984
2985 // Need to have a group selected and it needs to have a linked design block
2987 SCH_SELECTION selection = selTool->GetSelection();
2988
2989 if( selection.Size() != 1 || selection[0]->Type() != SCH_GROUP_T )
2990 return 1;
2991
2992 SCH_GROUP* group = static_cast<SCH_GROUP*>( selection[0] );
2993
2994 if( !group->HasDesignBlockLink() )
2995 return 1;
2996
2997 // Get the associated design block
2998 DESIGN_BLOCK_PANE* designBlockPane = editFrame->GetDesignBlockPane();
2999 std::unique_ptr<DESIGN_BLOCK> designBlock( designBlockPane->GetDesignBlock( group->GetDesignBlockLibId(),
3000 true, true ) );
3001
3002 if( !designBlock )
3003 {
3004 wxString msg;
3005 msg.Printf( _( "Could not find design block %s." ), group->GetDesignBlockLibId().GetUniStringLibId() );
3006 m_frame->GetInfoBar()->ShowMessageFor( msg, 5000, wxICON_WARNING );
3007 return 1;
3008 }
3009
3010 editFrame->GetDesignBlockPane()->SelectLibId( group->GetDesignBlockLibId() );
3011
3013}
3014
3015
3017{
3018 Go( &SCH_EDITOR_CONTROL::New, ACTIONS::doNew.MakeEvent() );
3019 Go( &SCH_EDITOR_CONTROL::Open, ACTIONS::open.MakeEvent() );
3020 Go( &SCH_EDITOR_CONTROL::Save, ACTIONS::save.MakeEvent() );
3027 Go( &SCH_EDITOR_CONTROL::Plot, ACTIONS::plot.MakeEvent() );
3028 Go( &SCH_EDITOR_CONTROL::Quit, ACTIONS::quit.MakeEvent() );
3029
3032
3038
3041
3047
3049
3050 Go( &SCH_EDITOR_CONTROL::Undo, ACTIONS::undo.MakeEvent() );
3051 Go( &SCH_EDITOR_CONTROL::Redo, ACTIONS::redo.MakeEvent() );
3052 Go( &SCH_EDITOR_CONTROL::Cut, ACTIONS::cut.MakeEvent() );
3053 Go( &SCH_EDITOR_CONTROL::Copy, ACTIONS::copy.MakeEvent() );
3058
3060
3076
3083
3099
3101
3103
3105
3108}
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:261
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:291
static TOOL_ACTION pickerTool
Definition: actions.h:250
static TOOL_ACTION showSymbolEditor
Definition: actions.h:257
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:262
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: actions.h:221
static TOOL_ACTION print
Definition: actions.h:64
static TOOL_ACTION showProperties
Definition: actions.h:263
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:229
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:233
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:83
int m_Threshold
Definition: collector.h:236
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:152
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 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:75
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.
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:98
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:272
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:148
const KIID m_Uuid
Definition: eda_item.h:516
virtual EDA_GROUP * GetParentGroup() const
Definition: eda_item.h:116
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:110
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition: eda_item.h:192
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:113
void ClearBrightened()
Definition: eda_item.h:138
void SetBrightened()
Definition: eda_item.h:135
EDA_ITEM * GetParent() const
Definition: eda_item.h:112
bool IsBrightened() const
Definition: eda_item.h:129
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:1599
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:344
static const TOOL_EVENT GridChangedByKeyEvent
Definition: actions.h:362
static const TOOL_EVENT SelectedEvent
Definition: actions.h:342
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:349
static const TOOL_EVENT PointSelectedEvent
Definition: actions.h:341
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:343
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:66
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:1685
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition: view.h:400
void ClearPreview()
Definition: view.cpp:1707
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition: view.cpp:1561
void Hide(VIEW_ITEM *aItem, bool aHide=true, bool aHideOverlay=false)
Temporarily hide the item in the view (e.g.
Definition: view.cpp:1633
void AddToPreview(VIEW_ITEM *aItem, bool aTakeOwnership=true)
Definition: view.cpp:1729
void MarkDirty()
Force redraw of view on the next rendering.
Definition: view.h:659
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:1571
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition: view.cpp:1612
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:344
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...
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.
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:149
virtual const wxString GetProjectName() const
Return the short name of the project.
Definition: project.cpp:161
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:167
static bool RescueProject(wxWindow *aParent, RESCUER &aRescuer, bool aRunningOnDemand)
size_t GetCandidateCount()
Return the number of rescue candidates found.
These are loaded from Eeschema settings but then overwritten by the project settings.
std::shared_ptr< REFDES_TRACKER > m_refDesTracker
A list of previously used schematic reference designators.
Holds all the data relating to one schematic.
Definition: schematic.h:88
SCH_SHEET_LIST BuildSheetListSortedByPageNumbers() const
Definition: schematic.h:108
wxString GetFileName() const
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:350
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:356
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
Definition: schematic.cpp:258
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition: schematic.cpp:927
CONNECTION_GRAPH * ConnectionGraph() const
Definition: schematic.h:183
SCH_SHEET & Root() const
Definition: schematic.h:140
SCH_SHEET_PATH & CurrentSheet() const
Definition: schematic.h:171
void RefreshHierarchy()
Definition: schematic.cpp:266
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:267
static TOOL_ACTION toggleOPCurrents
Definition: sch_actions.h:243
static TOOL_ACTION saveToLinkedDesignBlock
Definition: sch_actions.h:71
static TOOL_ACTION clearHighlight
Definition: sch_actions.h:297
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:270
static TOOL_ACTION editLibSymbolWithLibEdit
Definition: sch_actions.h:173
static TOOL_ACTION toggleERCWarnings
Definition: sch_actions.h:238
static TOOL_ACTION schematicSetup
Definition: sch_actions.h:159
static TOOL_ACTION toggleDirectiveLabels
Definition: sch_actions.h:237
static TOOL_ACTION highlightNetTool
Definition: sch_actions.h:299
static TOOL_ACTION toggleHiddenFields
Definition: sch_actions.h:234
static TOOL_ACTION saveCurrSheetCopyAs
Definition: sch_actions.h:43
static TOOL_ACTION repairSchematic
Definition: sch_actions.h:259
static TOOL_ACTION remapSymbols
Definition: sch_actions.h:166
static TOOL_ACTION lineMode45
Definition: sch_actions.h:266
static TOOL_ACTION editSymbolLibraryLinks
Definition: sch_actions.h:150
static TOOL_ACTION simTune
Definition: sch_actions.h:283
static TOOL_ACTION generateBOM
Definition: sch_actions.h:177
static TOOL_ACTION showHierarchy
Definition: sch_actions.h:225
static TOOL_ACTION showNetNavigator
Definition: sch_actions.h:300
static TOOL_ACTION markSimExclusions
Definition: sch_actions.h:241
static TOOL_ACTION editWithLibEdit
Definition: sch_actions.h:172
static TOOL_ACTION toggleERCErrors
Definition: sch_actions.h:239
static TOOL_ACTION incrementAnnotations
Definition: sch_actions.h:148
static TOOL_ACTION saveSelectionToDesignBlock
Definition: sch_actions.h:194
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:242
static TOOL_ACTION simProbe
Definition: sch_actions.h:282
static TOOL_ACTION lineMode90
Definition: sch_actions.h:265
static TOOL_ACTION lineModeFree
Definition: sch_actions.h:264
static TOOL_ACTION changeSheet
Definition: sch_actions.h:217
static TOOL_ACTION highlightNet
Definition: sch_actions.h:296
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:190
static TOOL_ACTION togglePinAltIcons
Definition: sch_actions.h:244
static TOOL_ACTION toggleERCExclusions
Definition: sch_actions.h:240
static TOOL_ACTION updateNetHighlighting
Definition: sch_actions.h:298
static TOOL_ACTION exportNetlist
Definition: sch_actions.h:176
static TOOL_ACTION drawSheetOnClipboard
Definition: sch_actions.h:254
static TOOL_ACTION exportSymbolsToLibrary
Definition: sch_actions.h:181
static TOOL_ACTION toggleHiddenPins
Definition: sch_actions.h:233
static TOOL_ACTION selectOnPCB
Definition: sch_actions.h:247
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.
void SyncView()
Mark all items for refresh.
wxString SelectLibrary(const wxString &aDialogTitle, const wxString &aListLabel, const std::vector< std::pair< wxString, bool * > > &aExtraCheckboxes={})
Display a list of loaded libraries and allows the user to select a library.
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:498
const SYMBOL * GetParentSymbol() const
Definition: sch_item.cpp:252
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:246
virtual void SetLastResolvedState(const SCH_ITEM *aItem)
Definition: sch_item.h:590
int GetBodyStyle() const
Definition: sch_item.h:248
int GetUnit() const
Definition: sch_item.h:239
void SetConnectivityDirty(bool aDirty=true)
Definition: sch_item.h:561
bool IsConnectivityDirty() const
Definition: sch_item.h:559
virtual void SetUnit(int aUnit)
Definition: sch_item.h:238
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:352
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Definition: sch_item.h:513
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:758
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:488
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition: sch_screen.h:117
const wxString & GetFileName() const
Definition: sch_screen.h:152
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:520
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:558
bool IsPower() const override
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:760
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:48
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.
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:52
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:566
#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 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:76
@ NO_CLEANUP
Definition: schematic.h:75
@ GLOBAL_CLEANUP
Definition: schematic.h:77
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