KiCad PCB EDA Suite
Loading...
Searching...
No Matches
board_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) 2014 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Maciej Suminski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
23
24#include <algorithm>
25#include <climits>
26#include <functional>
27#include <memory>
28
29#include <pgm_base.h>
30#include <executable_names.h>
31#include <advanced_config.h>
32#include <bitmaps.h>
33#include <gestfich.h>
34#include <pcb_painter.h>
35#include <board.h>
36#include <board_commit.h>
38#include <collectors.h>
40#include <pcb_generator.h>
41#include <pcb_grid_item.h>
42#include <footprint.h>
43#include <pad.h>
44#include <pcb_target.h>
45#include <pcb_track.h>
46#include <zone.h>
47#include <pcb_marker.h>
48#include <confirm.h>
53#include <dialog_plot.h>
56#include <kiface_base.h>
57#include <kiway.h>
59#include <origin_viewitem.h>
60#include <pcb_edit_frame.h>
61#include <pcbnew_id.h>
62#include <project.h>
63#include <project/project_file.h> // LAST_PATH_TYPE
65#include <kiplatform/ui.h>
66#include <pcbnew_settings.h>
67#include <tool/tool_manager.h>
68#include <tool/tool_event.h>
69#include <tools/drawing_tool.h>
70#include <tools/pcb_actions.h>
75#include <tools/edit_tool.h>
78#include <richio.h>
79#include <router/router_tool.h>
80#include <view/view_controls.h>
81#include <view/view_group.h>
85#include <wx/filedlg.h>
86#include <wx/msgdlg.h>
87#include <wx/log.h>
88
90
91using namespace std::placeholders;
92
93
94namespace
95{
96
97using ZonePriorityMap = std::map<unsigned, std::vector<ZONE*>>;
98
99
100std::vector<ZONE*> getOverlappingZones( BOARD* aBoard, ZONE* aZone )
101{
102 std::vector<ZONE*> overlapping;
103 BOX2I bbox = aZone->GetBoundingBox();
104
105 for( ZONE* candidate : aBoard->Zones() )
106 {
107 if( candidate == aZone )
108 continue;
109
110 if( candidate->GetIsRuleArea() || candidate->IsTeardropArea() )
111 continue;
112
113 if( !( candidate->GetLayerSet() & aZone->GetLayerSet() ).any() )
114 continue;
115
116 if( !candidate->GetBoundingBox().Intersects( bbox ) )
117 continue;
118
119 // Check edge collision and containment (one zone entirely inside another)
120 SHAPE_POLY_SET aOutline = aZone->GetBoardOutline();
121 SHAPE_POLY_SET candidateOutline = candidate->GetBoardOutline();
122
123 if( aOutline.Collide( &candidateOutline )
124 || ( candidateOutline.TotalVertices() > 0 && aOutline.Contains( candidateOutline.CVertex( 0 ) ) )
125 || ( aOutline.TotalVertices() > 0 && candidateOutline.Contains( aOutline.CVertex( 0 ) ) ) )
126 {
127 overlapping.push_back( candidate );
128 }
129 }
130
131 return overlapping;
132}
133
134
135ZonePriorityMap buildPriorityMap( BOARD* aBoard, ZONE* aExclude )
136{
137 ZonePriorityMap byPriority;
138
139 for( ZONE* z : aBoard->Zones() )
140 {
141 if( z == aExclude || z->GetIsRuleArea() || z->IsTeardropArea() )
142 continue;
143
144 byPriority[z->GetAssignedPriority()].push_back( z );
145 }
146
147 return byPriority;
148}
149
150
163std::vector<ZONE*> findCascadeZones( const ZonePriorityMap& aByPriority,
164 unsigned aFromPriority, bool aCascadeUp,
165 bool& aViable )
166{
167 std::vector<ZONE*> result;
168 unsigned p = aFromPriority;
169 aViable = true;
170
171 for( auto it = aByPriority.find( p ); it != aByPriority.end();
172 it = aByPriority.find( p ) )
173 {
174 for( ZONE* z : it->second )
175 result.push_back( z );
176
177 if( aCascadeUp )
178 {
179 if( p == UINT_MAX )
180 {
181 aViable = false;
182 break;
183 }
184
185 p++;
186 }
187 else
188 {
189 if( p == 0 )
190 {
191 aViable = false;
192 break;
193 }
194
195 p--;
196 }
197 }
198
199 return result;
200}
201
202} // anonymous namespace
203
204
206{
207public:
219
220protected:
221 ACTION_MENU* create() const override
222 {
223 return new ZONE_PRIORITY_CONTEXT_MENU();
224 }
225
226 void update() override
227 {
229
230 if( !selTool )
231 return;
232
233 const PCB_SELECTION& selection = selTool->GetSelection();
234 bool canRaise = false;
235 bool canLower = false;
236
237 if( selection.Size() == 1 )
238 {
239 ZONE* zone = dynamic_cast<ZONE*>( selection[0] );
240
241 if( zone && !zone->GetIsRuleArea() && !zone->IsTeardropArea() )
242 {
243 BOARD* board = zone->GetBoard();
244 std::vector<ZONE*> overlapping = getOverlappingZones( board, zone );
245
246 for( ZONE* other : overlapping )
247 {
248 if( other->GetAssignedPriority() > zone->GetAssignedPriority() )
249 canRaise = true;
250
251 if( other->GetAssignedPriority() < zone->GetAssignedPriority() )
252 canLower = true;
253 }
254 }
255 }
256
257 Enable( PCB_ACTIONS::zonePriorityMoveToTop.GetUIId(), canRaise );
258 Enable( PCB_ACTIONS::zonePriorityRaise.GetUIId(), canRaise );
259 Enable( PCB_ACTIONS::zonePriorityLower.GetUIId(), canLower );
260 Enable( PCB_ACTIONS::zonePriorityMoveToBottom.GetUIId(), canLower );
261 }
262};
263
264
266{
267public:
269 ACTION_MENU( true )
270 {
272 SetTitle( _( "Zones" ) );
273
278
279 AppendSeparator();
280
285
286 AppendSeparator();
287
289
290 AppendSeparator();
291
293 }
294
295protected:
296 ACTION_MENU* create() const override
297 {
298 return new ZONE_CONTEXT_MENU();
299 }
300};
301
302
304{
305public:
316
317 ACTION_MENU* create() const override
318 {
319 return new LOCK_CONTEXT_MENU( this->m_tool );
320 }
321};
322
323
325 PCB_TOOL_BASE( "pcbnew.EditorControl" ),
326 m_frame( nullptr ),
327 m_inPlaceFootprint( false ),
328 m_placingFootprint( false )
329{
330 m_placeOrigin = std::make_unique<KIGFX::ORIGIN_VIEWITEM>( KIGFX::COLOR4D( 0.8, 0.0, 0.0, 1.0 ),
332}
333
334
338
339
341{
343
344 if( aReason == MODEL_RELOAD || aReason == GAL_SWITCH || aReason == REDRAW )
345 {
346 m_placeOrigin->SetPosition( getModel<BOARD>()->GetDesignSettings().GetAuxOrigin() );
347 getView()->Remove( m_placeOrigin.get() );
348 getView()->Add( m_placeOrigin.get() );
349 }
350}
351
352// Update left-toolbar Line modes group icon based on current settings
354{
356
357 if( !f )
358 return 0;
359
360 LEADER_MODE mode = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_AngleSnapMode;
361
362 switch( mode )
363 {
366 default:
368 }
369
370 return 0;
371}
372
374{
375 LEADER_MODE mode = aEvent.Parameter<LEADER_MODE>();
376 GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_AngleSnapMode = mode;
377 m_toolMgr->PostAction( ACTIONS::refreshPreview );
379 return 0;
380}
381
382
384{
385 auto activeToolCondition =
386 [this]( const SELECTION& aSel )
387 {
388 return ( !m_frame->ToolStackIsEmpty() );
389 };
390
391 auto inactiveStateCondition =
392 [this]( const SELECTION& aSel )
393 {
394 return ( m_frame->ToolStackIsEmpty() && aSel.Size() == 0 );
395 };
396
397 auto placeModuleCondition =
398 [this]( const SELECTION& aSel )
399 {
400 return m_frame->IsCurrentTool( PCB_ACTIONS::placeFootprint ) && aSel.GetSize() == 0;
401 };
402
403 auto& ctxMenu = m_menu->GetMenu();
404
405 // "Cancel" goes at the top of the context menu when a tool is active
406 ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1 );
407 ctxMenu.AddSeparator( 1 );
408
409 // "Get and Place Footprint" should be available for Place Footprint tool
410 ctxMenu.AddItem( PCB_ACTIONS::getAndPlace, placeModuleCondition, 1000 );
411 ctxMenu.AddSeparator( 1000 );
412
413 // Finally, add the standard zoom & grid items
414 getEditFrame<PCB_BASE_FRAME>()->AddStandardSubMenus( *m_menu.get() );
415
416 std::shared_ptr<ZONE_CONTEXT_MENU> zoneMenu = std::make_shared<ZONE_CONTEXT_MENU>();
417 zoneMenu->SetTool( this );
418
419 std::shared_ptr<LOCK_CONTEXT_MENU> lockMenu = std::make_shared<LOCK_CONTEXT_MENU>( this );
420
421 // Add the PCB control menus to relevant other tools
422
423 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
424
425 if( selTool )
426 {
427 TOOL_MENU& toolMenu = selTool->GetToolMenu();
428 CONDITIONAL_MENU& menu = toolMenu.GetMenu();
429
430 // Add "Get and Place Footprint" when Selection tool is in an inactive state
431 menu.AddItem( PCB_ACTIONS::getAndPlace, inactiveStateCondition );
432 menu.AddSeparator();
433
434 toolMenu.RegisterSubMenu( zoneMenu );
435 toolMenu.RegisterSubMenu( lockMenu );
436
437 menu.AddMenu( lockMenu.get(), SELECTION_CONDITIONS::NotEmpty, 100 );
438
439 menu.AddMenu( zoneMenu.get(), SELECTION_CONDITIONS::OnlyTypes( { PCB_ZONE_T } ), 100 );
440 }
441
442 DRAWING_TOOL* drawingTool = m_toolMgr->GetTool<DRAWING_TOOL>();
443
444 if( drawingTool )
445 {
446 TOOL_MENU& toolMenu = drawingTool->GetToolMenu();
447 CONDITIONAL_MENU& menu = toolMenu.GetMenu();
448
449 toolMenu.RegisterSubMenu( zoneMenu );
450
451 // Functor to say if the PCB_EDIT_FRAME is in a given mode
452 // Capture the tool pointer and tool mode by value
453 auto toolActiveFunctor =
454 [=]( DRAWING_TOOL::MODE aMode )
455 {
456 return [=]( const SELECTION& sel )
457 {
458 return drawingTool->GetDrawingMode() == aMode;
459 };
460 };
461
462 menu.AddMenu( zoneMenu.get(), toolActiveFunctor( DRAWING_TOOL::MODE::ZONE ), 300 );
463 }
464
465 // Ensure the left toolbar's Line modes group reflects the current setting at startup
466 if( m_toolMgr )
468
469 return true;
470}
471
472
474{
475 wxWindow* focus = wxWindow::FindFocus();
476
477 if( focus )
478 {
479 wxWindow* topLevel = focus;
480
481 while( topLevel && !topLevel->IsTopLevel() )
482 topLevel = topLevel->GetParent();
483
484 RULE_EDITOR_DIALOG_BASE* reDlg = dynamic_cast<RULE_EDITOR_DIALOG_BASE*>( topLevel );
485
486 if( reDlg )
487 {
488 wxCommandEvent evt;
489 reDlg->OnSave( evt );
490 return 0;
491 }
492 }
493
494 m_frame->SaveBoard();
495 return 0;
496}
497
498
500{
501 m_frame->SaveBoard( true );
502 return 0;
503}
504
505
507{
508 m_frame->SaveBoard( true, true );
509 return 0;
510}
511
512
514{
515 m_frame->ExportFootprintsToLibrary( false );
516 return 0;
517}
518
519
521{
522 PICKED_ITEMS_LIST undoCmd;
524 ITEM_PICKER wrapper( nullptr, undoItem, UNDO_REDO::PAGESETTINGS );
525
526 undoCmd.PushItem( wrapper );
527 undoCmd.SetDescription( _( "Page Settings" ) );
528 m_frame->SaveCopyInUndoList( undoCmd, UNDO_REDO::PAGESETTINGS );
529
530 DIALOG_PAGES_SETTINGS dlg( m_frame, m_frame->GetBoard()->GetEmbeddedFiles(), pcbIUScale.IU_PER_MILS,
533
534 if( dlg.ShowModal() == wxID_OK )
535 {
536 m_frame->GetCanvas()->GetView()->UpdateAllItemsConditionally(
537 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
538 {
539 EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aItem );
540
541 if( text && text->HasTextVars() )
542 {
543 text->ClearRenderCache();
544 text->ClearBoundingBoxCache();
546 }
547
548 return 0;
549 } );
550
551 m_frame->OnModify();
552 }
553 else
554 {
555 m_frame->RollbackFromUndo();
556 }
557
558 return 0;
559}
560
561
563{
564 DIALOG_PLOT dlg( m_frame );
565 dlg.ShowQuasiModal();
566 return 0;
567}
568
569
571{
572 DIALOG_FOOTPRINT_FIELDS_TABLE* dlg = m_frame->GetFootprintFieldsTableDialog();
573
574 if( !dlg )
575 return 0;
576
577 // Needed at least on Windows. Raise() is not enough
578 dlg->Show( true );
579
580 // Bring it to the top if already open. Dual monitor users need this.
581 dlg->Raise();
582
583 dlg->ShowEditTab();
584
585 return 0;
586}
587
588
590{
591 DIALOG_FOOTPRINT_FIELDS_TABLE* dlg = m_frame->GetFootprintFieldsTableDialog();
592
593 if( !dlg )
594 return 0;
595
596 // Needed at least on Windows. Raise() is not enough
597 dlg->Show( true );
598
599 // Bring it to the top if already open. Dual monitor users need this.
600 dlg->Raise();
601
602 dlg->ShowExportTab();
603
604 return 0;
605}
606
607
609{
610 m_frame->ToggleSearch();
611 return 0;
612}
613
614
616{
617 m_frame->ShowFindDialog();
618 return 0;
619}
620
621
623{
624 m_frame->FindNext( aEvent.IsAction( &ACTIONS::findPrevious ) );
625 return 0;
626}
627
628
630{
631 m_frame->ShowFindByPropertiesDialog();
632 return 0;
633}
634
635
637{
638 getEditFrame<PCB_EDIT_FRAME>()->ShowBoardSetupDialog();
639 return 0;
640}
641
642
644{
645 getEditFrame<PCB_EDIT_FRAME>()->InstallNetlistFrame();
646 return 0;
647}
648
649
651{
652 wxString fullFileName = frame()->GetBoard()->GetFileName();
653 wxString path;
654 wxString name;
655 wxString ext;
656
657 wxFileName::SplitPath( fullFileName, &path, &name, &ext );
658 name += wxT( "." ) + wxString( FILEEXT::SpecctraSessionFileExtension );
659
660 fullFileName = wxFileSelector( _( "Specctra Session File" ), path, name,
661 wxT( "." ) + wxString( FILEEXT::SpecctraSessionFileExtension ),
662 FILEEXT::SpecctraSessionFileWildcard(), wxFD_OPEN | wxFD_CHANGE_DIR,
663 frame() );
664
665 if( !fullFileName.IsEmpty() )
666 getEditFrame<PCB_EDIT_FRAME>()->ImportSpecctraSession( fullFileName );
667
668 return 0;
669}
670
671
673{
674 wxString fullFileName = m_frame->GetLastPath( LAST_PATH_SPECCTRADSN );
675 wxFileName fn;
676
677 if( fullFileName.IsEmpty() )
678 {
679 fn = m_frame->GetBoard()->GetFileName();
681 }
682 else
683 {
684 fn = fullFileName;
685 }
686
687 fullFileName = wxFileSelector( _( "Specctra DSN File" ), fn.GetPath(), fn.GetFullName(),
689 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxFD_CHANGE_DIR, frame() );
690
691 if( !fullFileName.IsEmpty() )
692 {
693 m_frame->SetLastPath( LAST_PATH_SPECCTRADSN, fullFileName );
694 getEditFrame<PCB_EDIT_FRAME>()->ExportSpecctraFile( fullFileName );
695 }
696
697 return 0;
698}
699
700
702{
703 wxCHECK( m_frame, 0 );
704
705 wxFileName fn = m_frame->Prj().GetProjectFullName();
706
707 // Use a different file extension for the board netlist so the schematic netlist file
708 // is accidentally overwritten.
709 fn.SetExt( wxT( "pcb_net" ) );
710
711 wxFileDialog dlg( m_frame, _( "Export Board Netlist" ), fn.GetPath(), fn.GetFullName(),
712 _( "KiCad board netlist files" ) + AddFileExtListToFilter( { "pcb_net" } ),
713 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
714
715 dlg.SetExtraControlCreator( &LEGACYFILEDLG_NETLIST_OPTIONS::Create );
716
718
719 if( dlg.ShowModal() == wxID_CANCEL )
720 return 0;
721
722 fn = dlg.GetPath();
723
724 if( !fn.IsDirWritable() )
725 {
726 DisplayErrorMessage( m_frame, wxString::Format( _( "Insufficient permissions to folder '%s'." ),
727 fn.GetPath() ) );
728 return 0;
729 }
730
732 dynamic_cast<const LEGACYFILEDLG_NETLIST_OPTIONS*>( dlg.GetExtraControl() );
733 wxCHECK( noh, 0 );
734
736
737 for( const FOOTPRINT* footprint : board()->Footprints() )
738 {
739 COMPONENT* component = new COMPONENT( footprint->GetFPID(), footprint->GetReference(),
740 footprint->GetValue(), footprint->GetPath(),
741 { footprint->m_Uuid } );
742
743 for( const PAD* pad : footprint->Pads() )
744 {
745 const wxString& netname = pad->GetShortNetname();
746
747 if( !netname.IsEmpty() )
748 component->AddNet( pad->GetNumber(), netname, pad->GetPinFunction(), pad->GetPinType() );
749 }
750
751 nlohmann::ordered_map<wxString, wxString> fields;
752
753 for( PCB_FIELD* field : footprint->GetFields() )
754 {
755 wxCHECK2( field, continue );
756
757 fields[field->GetUntranslatedName()] = field->GetText();
758 }
759
760 component->SetFields( fields );
761
762 netlist.AddComponent( component );
763 }
764
765 try
766 {
767 FILE_OUTPUTFORMATTER formatter( fn.GetFullPath() );
768
769 netlist.Format( "pcb_netlist", &formatter, 0, noh->GetNetlistOptions() );
770 formatter.Finish();
771 }
772 catch( const IO_ERROR& ioe )
773 {
774 DisplayErrorMessage( m_frame, wxString::Format( _( "Failed to export netlist to '%s': %s" ),
775 fn.GetFullPath(), ioe.What() ) );
776 }
777
778 return 0;
779}
780
781
783{
784 PCB_PLOT_PARAMS plotSettings = m_frame->GetPlotSettings();
785
786 plotSettings.SetFormat( PLOT_FORMAT::GERBER );
787
788 m_frame->SetPlotSettings( plotSettings );
789
790 DIALOG_PLOT dlg( m_frame );
791 dlg.ShowQuasiModal( );
792
793 return 0;
794}
795
796
798{
799 int errors = 0;
800 wxString details;
801 bool quiet = aEvent.Parameter<bool>();
802
803 int duplicates = board()->RepairDuplicateItemUuids();
804
805 if( duplicates )
806 {
807 errors += duplicates;
808 details += wxString::Format( _( "%d duplicate IDs replaced.\n" ), duplicates );
809 }
810
811 for( FOOTPRINT* footprint : board()->Footprints() )
812 {
813 for( PAD* pad : footprint->Pads() )
814 {
815 BOARD_CONNECTED_ITEM* cItem = pad;
816
817 if( cItem->GetNetCode() )
818 {
819 NETINFO_ITEM* netinfo = cItem->GetNet();
820
821 if( netinfo && !board()->FindNet( netinfo->GetNetname() ) )
822 {
823 board()->Add( netinfo );
824
825 details += wxString::Format( _( "Orphaned net %s re-parented.\n" ),
826 netinfo->GetNetname() );
827 errors++;
828 }
829 }
830 }
831 }
832
833 for( PCB_TRACK* track : board()->Tracks() )
834 {
835 BOARD_CONNECTED_ITEM* cItem = track;
836
837 if( cItem->GetNetCode() )
838 {
839 NETINFO_ITEM* netinfo = cItem->GetNet();
840
841 if( netinfo && !board()->FindNet( netinfo->GetNetname() ) )
842 {
843 board()->Add( netinfo );
844
845 details += wxString::Format( _( "Orphaned net %s re-parented.\n" ),
846 netinfo->GetNetname() );
847 errors++;
848 }
849 }
850 }
851
852 /*******************************
853 * Your test here
854 */
855
856 /*******************************
857 * Inform the user
858 */
859
860 if( errors )
861 {
862 m_frame->OnModify();
863
864 wxString msg = wxString::Format( _( "%d potential problems repaired." ), errors );
865
866 if( !quiet )
867 DisplayInfoMessage( m_frame, msg, details );
868 }
869 else if( !quiet )
870 {
871 DisplayInfoMessage( m_frame, _( "No board problems found." ) );
872 }
873
874 return 0;
875}
876
877
879{
881 bool fetched = false;
882
884 [&]()
885 {
886 fetched = m_frame->FetchNetlistFromSchematic(
887 netlist, _( "Updating PCB requires a fully annotated schematic." ) );
888 } );
889
890 if( fetched )
891 {
892 DIALOG_UPDATE_PCB updateDialog( m_frame, &netlist );
893 updateDialog.ShowModal();
894 }
895
896 return 0;
897}
898
900{
901 if( Kiface().IsSingle() )
902 {
903 DisplayErrorMessage( m_frame, _( "Cannot update schematic because Pcbnew is opened in "
904 "stand-alone mode. In order to create or update PCBs "
905 "from schematics, you must launch the KiCad project "
906 "manager and create a project." ) );
907 return 0;
908 }
909
912
913 KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_SCH, false );
914
915 if( frame )
916 {
917 std::string payload;
918
919 if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
920 blocking_win->Close( true );
921
922 m_frame->Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_UPDATE, payload, m_frame );
923 }
924 return 0;
925}
926
927
929{
930 wxString msg;
931 PCB_EDIT_FRAME* boardFrame = m_frame;
932 PROJECT& project = boardFrame->Prj();
933 wxFileName schematic( project.GetProjectPath(), project.GetProjectName(),
935
936 if( !schematic.FileExists() )
937 {
938 wxFileName legacySchematic( project.GetProjectPath(), project.GetProjectName(),
940
941 if( legacySchematic.FileExists() )
942 {
943 schematic = legacySchematic;
944 }
945 else
946 {
947 msg.Printf( _( "Schematic file '%s' not found." ), schematic.GetFullPath() );
949 return 0;
950 }
951 }
952
953 if( Kiface().IsSingle() )
954 {
955 ExecuteFile( EESCHEMA_EXE, schematic.GetFullPath() );
956 }
957 else
958 {
960 [&]()
961 {
962 KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_SCH, false );
963
964 // Please: note: DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::initBuffers() calls
965 // Kiway.Player( FRAME_SCH, true )
966 // therefore, the schematic editor is sometimes running, but the schematic project
967 // is not loaded, if the library editor was called, and the dialog field editor was used.
968 // On Linux, it happens the first time the schematic editor is launched, if
969 // library editor was running, and the dialog field editor was open
970 // On Windows, it happens always after the library editor was called,
971 // and the dialog field editor was used
972 if( !frame )
973 {
974 try
975 {
976 frame = boardFrame->Kiway().Player( FRAME_SCH, true );
977 }
978 catch( const IO_ERROR& err )
979 {
980 DisplayErrorMessage( boardFrame,
981 _( "Eeschema failed to load." ) + wxS( "\n" ) + err.What() );
982 return;
983 }
984 }
985
986 wxEventBlocker blocker( boardFrame );
987
988 // If Kiway() cannot create the eeschema frame, it shows a error message, and
989 // frame is null
990 if( !frame )
991 return;
992
993 if( !frame->IsShownOnScreen() ) // the frame exists, (created by the dialog field editor)
994 // but no project loaded.
995 {
996 frame->OpenProjectFiles( std::vector<wxString>( 1, schematic.GetFullPath() ) );
997 frame->Show( true );
998 }
999
1000 // On Windows, Raise() does not bring the window on screen, when iconized or not shown
1001 // On Linux, Raise() brings the window on screen, but this code works fine
1002 if( frame->IsIconized() )
1003 {
1004 frame->Iconize( false );
1005
1006 // If an iconized frame was created by Pcbnew, Iconize( false ) is not enough
1007 // to show the frame at its normal size: Maximize should be called.
1008 frame->Maximize( false );
1009 }
1010
1011 frame->Raise();
1012 } );
1013 }
1014
1015 return 0;
1016}
1017
1018
1020{
1021 getEditFrame<PCB_EDIT_FRAME>()->ToggleLayersManager();
1022 return 0;
1023}
1024
1025
1027{
1028 getEditFrame<PCB_EDIT_FRAME>()->ToggleProperties();
1029 return 0;
1030}
1031
1032
1034{
1035 getEditFrame<PCB_EDIT_FRAME>()->ToggleNetInspector();
1036 return 0;
1037}
1038
1039
1041{
1042 getEditFrame<PCB_EDIT_FRAME>()->ToggleGitCommitPane();
1043 return 0;
1044}
1045
1046
1048{
1049 getEditFrame<PCB_EDIT_FRAME>()->ToggleLibraryTree();
1050 return 0;
1051}
1052
1053
1055{
1056 getEditFrame<PCB_EDIT_FRAME>()->ToggleSearch();
1057 return 0;
1058}
1059
1060
1062{
1063 getEditFrame<PCB_EDIT_FRAME>()->ToggleConstraintsPanel();
1064 return 0;
1065}
1066
1067
1068// Track & via size control
1070{
1071 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1072 PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1073
1074 if( m_frame->ToolStackIsEmpty()
1075 && SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )( selection ) )
1076 {
1077 BOARD_COMMIT commit( this );
1078
1079 for( EDA_ITEM* item : selection )
1080 {
1081 if( item->IsType( { PCB_TRACE_T, PCB_ARC_T } ) )
1082 {
1083 PCB_TRACK* track = static_cast<PCB_TRACK*>( item );
1084
1085 for( int i = 0; i < (int) bds.m_TrackWidthList.size(); ++i )
1086 {
1087 int candidate = bds.m_NetSettings->GetDefaultNetclass()->GetTrackWidth();
1088
1089 if( i > 0 )
1090 candidate = bds.m_TrackWidthList[ i ];
1091
1092 if( candidate > track->GetWidth() )
1093 {
1094 commit.Modify( track );
1095 track->SetWidth( candidate );
1096 break;
1097 }
1098 }
1099 }
1100 }
1101
1102 commit.Push( _( "Increase Track Width" ) );
1103 return 0;
1104 }
1105
1106 ROUTER_TOOL* routerTool = m_toolMgr->GetTool<ROUTER_TOOL>();
1107
1108 if( routerTool && routerTool->IsToolActive()
1109 && routerTool->Router()->Mode() == PNS::PNS_MODE_ROUTE_DIFF_PAIR )
1110 {
1111 int widthIndex = bds.GetNextDiffPairIndex( bds.GetDiffPairIndex(), true );
1112
1113 bds.SetDiffPairIndex( widthIndex );
1114 bds.UseCustomDiffPairDimensions( false );
1115
1117 }
1118 else
1119 {
1120 // Issue #24644: stepping the index unconditionally lets the first press both enter the
1121 // connected-width override and advance into the list, instead of no-op'ing.
1122 if( routerTool && routerTool->IsToolActive()
1125 {
1126 bds.m_TempOverrideTrackWidth = true;
1127 }
1128
1130 bds.UseCustomTrackViaSize( false );
1131
1133 }
1134
1135 return 0;
1136}
1137
1138
1140{
1141 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1142 PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1143
1144 if( m_frame->ToolStackIsEmpty()
1145 && SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )( selection ) )
1146 {
1147 BOARD_COMMIT commit( this );
1148
1149 for( EDA_ITEM* item : selection )
1150 {
1151 if( item->IsType( { PCB_TRACE_T, PCB_ARC_T } ) )
1152 {
1153 PCB_TRACK* track = static_cast<PCB_TRACK*>( item );
1154
1155 for( int i = (int) bds.m_TrackWidthList.size() - 1; i >= 0; --i )
1156 {
1157 int candidate = bds.m_NetSettings->GetDefaultNetclass()->GetTrackWidth();
1158
1159 if( i > 0 )
1160 candidate = bds.m_TrackWidthList[ i ];
1161
1162 if( candidate < track->GetWidth() )
1163 {
1164 commit.Modify( track );
1165 track->SetWidth( candidate );
1166 break;
1167 }
1168 }
1169 }
1170 }
1171
1172 commit.Push( _( "Decrease Track Width" ) );
1173 return 0;
1174 }
1175
1176 ROUTER_TOOL* routerTool = m_toolMgr->GetTool<ROUTER_TOOL>();
1177
1178 if( routerTool && routerTool->IsToolActive()
1179 && routerTool->Router()->Mode() == PNS::PNS_MODE_ROUTE_DIFF_PAIR )
1180 {
1181 int widthIndex = bds.GetNextDiffPairIndex( bds.GetDiffPairIndex(), false );
1182
1183 bds.SetDiffPairIndex( widthIndex );
1184 bds.UseCustomDiffPairDimensions( false );
1185
1187 }
1188 else
1189 {
1190 // Issue #24644: mirror TrackWidthInc so the first invocation also advances into the
1191 // predefined list instead of merely flipping the override flag.
1192 if( routerTool && routerTool->IsToolActive()
1195 {
1196 bds.m_TempOverrideTrackWidth = true;
1197 }
1198
1200 bds.UseCustomTrackViaSize( false );
1201
1203 }
1204
1205 return 0;
1206}
1207
1208
1210{
1211 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1212 PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1213
1214 if( m_frame->ToolStackIsEmpty()
1215 && SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )( selection ) )
1216 {
1217 int complexPadstacks = 0;
1218 int incremented = 0;
1219 BOARD_COMMIT commit( this );
1220
1221 for( EDA_ITEM* item : selection )
1222 {
1223 if( item->Type() == PCB_VIA_T )
1224 {
1225 PCB_VIA* via = static_cast<PCB_VIA*>( item );
1226
1227 if( via->Padstack().Mode() != PADSTACK::MODE::NORMAL )
1228 {
1229 complexPadstacks++;
1230 continue;
1231 }
1232
1233 for( int i = 0; i < (int) bds.m_ViasDimensionsList.size(); ++i )
1234 {
1237
1238 if( i> 0 )
1239 dims = bds.m_ViasDimensionsList[ i ];
1240
1241 if( dims.m_Diameter > via->GetWidth( PADSTACK::ALL_LAYERS ) )
1242 {
1243 commit.Modify( via );
1244 via->SetWidth( PADSTACK::ALL_LAYERS, dims.m_Diameter );
1245 via->SetDrill( dims.m_Drill );
1246 incremented++;
1247 break;
1248 }
1249 }
1250 }
1251 }
1252
1253 if( incremented == 0 && complexPadstacks > 0 )
1254 {
1255 m_frame->ShowInfoBarError( wxString::Format( _( "%s not supported on complex padstacks." ),
1256 PCB_ACTIONS::viaSizeInc.GetFriendlyName() ) );
1257 }
1258
1259 commit.Push( PCB_ACTIONS::viaSizeInc.GetFriendlyName() );
1260 }
1261 else
1262 {
1263 int sizeIndex = bds.GetNextViaSizeIndex( bds.GetViaSizeIndex(), true );
1264
1265 bds.SetViaSizeIndex( sizeIndex );
1266 bds.UseCustomTrackViaSize( false );
1267
1269 }
1270
1271 return 0;
1272}
1273
1274
1276{
1277 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1278 PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1279
1280 if( m_frame->ToolStackIsEmpty()
1281 && SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )( selection ) )
1282 {
1283 int complexPadstacks = 0;
1284 int decremented = 0;
1285 BOARD_COMMIT commit( this );
1286
1287 for( EDA_ITEM* item : selection )
1288 {
1289 if( item->Type() == PCB_VIA_T )
1290 {
1291 PCB_VIA* via = static_cast<PCB_VIA*>( item );
1292
1293 if( via->Padstack().Mode() != PADSTACK::MODE::NORMAL )
1294 {
1295 complexPadstacks++;
1296 continue;
1297 }
1298
1299 for( int i = (int) bds.m_ViasDimensionsList.size() - 1; i >= 0; --i )
1300 {
1303
1304 if( i > 0 )
1305 dims = bds.m_ViasDimensionsList[ i ];
1306
1307 if( dims.m_Diameter < via->GetWidth( PADSTACK::ALL_LAYERS ) )
1308 {
1309 commit.Modify( via );
1310 via->SetWidth( PADSTACK::ALL_LAYERS, dims.m_Diameter );
1311 via->SetDrill( dims.m_Drill );
1312 decremented++;
1313 break;
1314 }
1315 }
1316 }
1317 }
1318
1319 if( decremented == 0 && complexPadstacks > 0 )
1320 {
1321 m_frame->ShowInfoBarError( wxString::Format( _( "%s not supported on complex padstacks." ),
1322 PCB_ACTIONS::viaSizeDec.GetFriendlyName() ) );
1323 }
1324
1325 commit.Push( PCB_ACTIONS::viaSizeDec.GetFriendlyName() );
1326 }
1327 else
1328 {
1329 int sizeIndex = 0; // Assume we only have a single via size entry
1330
1331 // If there are more, cycle through them backwards
1332 if( bds.m_ViasDimensionsList.size() > 0 )
1333 sizeIndex = bds.GetNextViaSizeIndex( bds.GetViaSizeIndex(), false );
1334
1335 bds.SetViaSizeIndex( sizeIndex );
1336 bds.UseCustomTrackViaSize( false );
1337
1339 }
1340
1341 return 0;
1342}
1343
1344
1346{
1347 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1348
1349 if( bds.UseCustomTrackViaSize() )
1350 {
1351 bds.UseCustomTrackViaSize( false );
1352 bds.m_UseConnectedTrackWidth = true;
1353 }
1354 else
1355 {
1357 }
1358
1359 return 0;
1360}
1361
1362
1364{
1365 if( m_inPlaceFootprint )
1366 return 0;
1367
1369
1370 FOOTPRINT* fp = aEvent.Parameter<FOOTPRINT*>();
1371 bool fromOtherCommand = fp != nullptr;
1373 BOARD_COMMIT commit( m_frame );
1375 COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
1376
1377 m_toolMgr->RunAction( ACTIONS::selectionClear );
1378
1379 TOOL_EVENT originalEvent = aEvent; // This can change out from under us when the event loop runs
1380 SCOPED_TOOL_PUSHER raii( m_frame, originalEvent );
1381
1382 // Frame angle already applied to fp; recaptured whenever fp is (re)acquired, so
1383 // stale state can never leak into the next placement.
1384 EDA_ANGLE prevFrameAngle = ANGLE_0;
1385
1386 auto setCursor =
1387 [&]()
1388 {
1389 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
1390 };
1391
1392 auto cleanup =
1393 [&] ()
1394 {
1395 m_toolMgr->RunAction( ACTIONS::selectionClear );
1396 commit.Revert();
1397
1398 if( fromOtherCommand )
1399 {
1400 PICKED_ITEMS_LIST* undo = m_frame->PopCommandFromUndoList();
1401
1402 if( undo )
1403 {
1404 m_frame->PutDataInPreviousState( undo );
1405 m_frame->ClearListAndDeleteItems( undo );
1406 delete undo;
1407 }
1408 }
1409
1410 fp = nullptr;
1411 m_placingFootprint = false;
1412 };
1413
1414 Activate();
1415 // Must be done after Activate() so that it gets set into the correct context
1416 controls->ShowCursor( true );
1417 // Set initial cursor
1418 setCursor();
1419
1420 VECTOR2I cursorPos = controls->GetCursorPosition();
1421 bool ignorePrimePosition = false;
1422 bool reselect = false;
1423
1424 auto applyPlacementFrameOrientation =
1425 [&]()
1426 {
1427 if( !fp )
1428 return;
1429
1431 EDA_ANGLE delta = GridFrameRotationDelta( prevFrameAngle, newAngle, m_frame->GetRotationAngle() );
1432
1433 prevFrameAngle = newAngle;
1434
1435 if( !delta.IsZero() )
1436 fp->Rotate( fp->GetPosition(), delta );
1437 };
1438
1439 // Prime the pump
1440 if( fp )
1441 {
1442 m_placingFootprint = true;
1443
1444 // A footprint handed over from another command may already carry the frame
1445 // rotation of the grid it sits in; count that as applied, like a move pick-up.
1446 prevFrameAngle = GridFrameAngleAt( *board, fp->GetPosition(), PCB_GRID_ROLE::PLACEMENT );
1447 fp->SetPosition( cursorPos );
1448 applyPlacementFrameOrientation();
1449 m_toolMgr->RunAction<EDA_ITEM*>( ACTIONS::selectItem, fp );
1450 m_toolMgr->PostAction( ACTIONS::refreshPreview );
1451 }
1452 else if( aEvent.HasPosition() )
1453 {
1454 m_toolMgr->PrimeTool( aEvent.Position() );
1455 }
1456 else if( common_settings->m_Input.immediate_actions && !aEvent.IsReactivate() )
1457 {
1458 m_toolMgr->PrimeTool( { 0, 0 } );
1459 ignorePrimePosition = true;
1460 }
1461
1462 // Main loop: keep receiving events
1463 while( TOOL_EVENT* evt = Wait() )
1464 {
1465 setCursor();
1466 cursorPos = controls->GetCursorPosition( !evt->DisableGridSnapping() );
1467
1468 if( reselect && fp )
1469 m_toolMgr->RunAction<EDA_ITEM*>( ACTIONS::selectItem, fp );
1470
1471 if( evt->IsCancelInteractive() || ( fp && evt->IsAction( &ACTIONS::undo ) ) )
1472 {
1473 if( fp )
1474 cleanup();
1475 else
1476 break;
1477 }
1478 else if( evt->IsActivate() )
1479 {
1480 if( fp )
1481 cleanup();
1482
1483 if( evt->IsMoveTool() )
1484 {
1485 // Make sure we come back after the move tool is done
1486 m_frame->PushTool( originalEvent );
1487 }
1488
1489 break;
1490 }
1491 else if( evt->IsClick( BUT_LEFT ) )
1492 {
1493 if( !fp )
1494 {
1495 // Pick the footprint to be placed
1496 fp = m_frame->SelectFootprintFromLibrary();
1497
1498 if( fp == nullptr )
1499 continue;
1500
1501 // If we started with a hotkey which has a position then warp back to that.
1502 // Otherwise update to the current mouse position pinned inside the autoscroll
1503 // boundaries.
1504 if( evt->IsPrime() && !ignorePrimePosition )
1505 {
1506 cursorPos = evt->Position();
1507 getViewControls()->WarpMouseCursor( cursorPos, true );
1508 }
1509 else
1510 {
1512 cursorPos = getViewControls()->GetMousePosition();
1513 }
1514
1515 m_placingFootprint = true;
1516
1517 fp->SetLink( niluuid );
1518
1519 fp->SetFlags( IS_NEW ); // whatever
1520
1521 // Set parent so that clearance can be loaded
1522 fp->SetParent( board );
1523 board->UpdateUserUnits( fp, m_frame->GetCanvas()->GetView() );
1524
1525 for( PAD* pad : fp->Pads() )
1526 {
1527 pad->SetLocalRatsnestVisible( m_frame->GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest );
1528
1529 // Pads in the library all have orphaned nets. Replace with Default.
1530 pad->SetNetCode( 0 );
1531 }
1532
1533 // Put it on FRONT layer,
1534 // (Can be stored flipped if the lib is an archive built from a board)
1535 if( fp->IsFlipped() )
1536 fp->Flip( fp->GetPosition(), m_frame->GetPcbNewSettings()->m_FlipDirection );
1537
1538 fp->SetOrientation( ANGLE_0 );
1539 fp->SetPosition( cursorPos );
1540 prevFrameAngle = ANGLE_0;
1541 applyPlacementFrameOrientation();
1542
1543 commit.Add( fp );
1544 m_toolMgr->RunAction<EDA_ITEM*>( ACTIONS::selectItem, fp );
1545
1546 m_toolMgr->PostAction( ACTIONS::refreshPreview );
1547 }
1548 else
1549 {
1550 m_toolMgr->RunAction( ACTIONS::selectionClear );
1551 commit.Push( _( "Place Footprint" ) );
1552 fp = nullptr; // to indicate that there is no footprint that we currently modify
1553 m_placingFootprint = false;
1554 }
1555 }
1556 else if( evt->IsClick( BUT_RIGHT ) )
1557 {
1558 m_menu->ShowContextMenu( selection() );
1559 }
1560 else if( fp && ( evt->IsMotion() || evt->IsAction( &ACTIONS::refreshPreview ) ) )
1561 {
1562 fp->SetPosition( cursorPos );
1563 applyPlacementFrameOrientation();
1564 selection().SetReferencePoint( cursorPos );
1565 getView()->Update( &selection() );
1566 getView()->Update( fp );
1567 }
1568 else if( fp && evt->IsAction( &PCB_ACTIONS::properties ) )
1569 {
1570 // Calling 'Properties' action clears the selection, so we need to restore it
1571 reselect = true;
1572 }
1573 else if( fp && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
1574 || evt->IsAction( &ACTIONS::redo ) ) )
1575 {
1576 wxBell();
1577 }
1578 else
1579 {
1580 evt->SetPassEvent();
1581 }
1582
1583 // Enable autopanning and cursor capture only when there is a footprint to be placed
1584 controls->SetAutoPan( fp != nullptr );
1585 controls->CaptureCursor( fp != nullptr );
1586 }
1587
1588 controls->SetAutoPan( false );
1589 controls->CaptureCursor( false );
1590 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
1591
1592 return 0;
1593}
1594
1595
1597{
1598 return modifyLockSelected( TOGGLE );
1599}
1600
1601
1603{
1604 return modifyLockSelected( ON );
1605}
1606
1607
1609{
1610 return modifyLockSelected( OFF );
1611}
1612
1613
1615{
1616 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
1617
1618 // RequestSelection populates from the cursor when empty and marks it IsHover(), letting us
1619 // clear it afterwards without disturbing a pre-existing selection.
1620 const PCB_SELECTION& selection = selTool->RequestSelection( nullptr );
1621
1622 BOARD_COMMIT commit( m_frame );
1623
1624 if( selection.Empty() )
1625 return 0;
1626
1627 const bool isHover = selection.IsHover();
1628
1629 // Resolve TOGGLE mode
1630 if( aMode == TOGGLE )
1631 {
1632 aMode = ON;
1633
1634 for( EDA_ITEM* item : selection )
1635 {
1636 if( !item->IsBOARD_ITEM() )
1637 continue;
1638
1639 if( static_cast<BOARD_ITEM*>( item )->IsLocked() )
1640 {
1641 aMode = OFF;
1642 break;
1643 }
1644 }
1645 }
1646
1647 for( EDA_ITEM* item : selection )
1648 {
1649 if( !item->IsBOARD_ITEM() )
1650 continue;
1651
1652 BOARD_ITEM* const board_item = static_cast<BOARD_ITEM*>( item );
1653
1654 // Disallow locking free pads - it's confusing and not persisted
1655 // through save/load anyway.
1656 if( board_item->Type() == PCB_PAD_T )
1657 continue;
1658
1659 EDA_GROUP* parent_group = board_item->GetParentGroup();
1660
1661 if( parent_group && parent_group->AsEdaItem()->Type() == PCB_GENERATOR_T )
1662 {
1663 PCB_GENERATOR* generator = static_cast<PCB_GENERATOR*>( parent_group );
1664
1665 if( generator && commit.GetStatus( generator ) != CHT_MODIFY )
1666 {
1667 commit.Modify( generator );
1668
1669 if( aMode == ON )
1670 generator->SetLocked( true );
1671 else
1672 generator->SetLocked( false );
1673 }
1674 }
1675
1676 commit.Modify( board_item );
1677
1678 if( aMode == ON )
1679 board_item->SetLocked( true );
1680 else
1681 board_item->SetLocked( false );
1682
1683 if( aMode == OFF && board_item->Type() == PCB_FOOTPRINT_T )
1684 {
1685 board_item->RunOnChildren(
1686 []( BOARD_ITEM* child )
1687 {
1688 child->SetLocked( false );
1689 },
1691 }
1692 }
1693
1694 if( !commit.Empty() )
1695 {
1696 commit.Push( aMode == ON ? _( "Lock" ) : _( "Unlock" ), SKIP_TEARDROPS );
1697
1698 m_toolMgr->PostEvent( EVENTS::SelectedEvent );
1699 m_frame->OnModify();
1700 }
1701
1702 if( isHover )
1703 m_toolMgr->RunAction( ACTIONS::selectionClear );
1704
1705 return 0;
1706}
1707
1708
1709static bool mergeZones( EDA_DRAW_FRAME* aFrame, BOARD_COMMIT& aCommit,
1710 std::vector<ZONE*>& aOriginZones, std::vector<ZONE*>& aMergedZones )
1711{
1712 aCommit.Modify( aOriginZones[0] );
1713
1714 aOriginZones[0]->Outline()->ClearArcs();
1715
1716 for( unsigned int i = 1; i < aOriginZones.size(); i++ )
1717 {
1718 SHAPE_POLY_SET otherOutline = aOriginZones[i]->Outline()->CloneDropTriangulation();
1719 otherOutline.ClearArcs();
1720 aOriginZones[0]->Outline()->BooleanAdd( otherOutline );
1721 }
1722
1723 aOriginZones[0]->Outline()->Simplify();
1724
1725 // We should have one polygon, possibly with holes. If we end up with two polygons (either
1726 // because the intersection was a single point or because the intersection was within one of
1727 // the zone's holes) then we can't merge.
1728 if( aOriginZones[0]->Outline()->IsSelfIntersecting() || aOriginZones[0]->Outline()->OutlineCount() > 1 )
1729 {
1730 DisplayErrorMessage( aFrame, _( "Zones have insufficient overlap for merging." ) );
1731 aCommit.Revert();
1732 return false;
1733 }
1734
1735 // Adopt the highest priority from all merged zones so the result maintains
1736 // the most aggressive fill ordering.
1737 unsigned highestPriority = aOriginZones[0]->GetAssignedPriority();
1738
1739 for( unsigned int i = 1; i < aOriginZones.size(); i++ )
1740 {
1741 highestPriority = std::max( highestPriority, aOriginZones[i]->GetAssignedPriority() );
1742 aCommit.Remove( aOriginZones[i] );
1743 }
1744
1745 aOriginZones[0]->SetAssignedPriority( highestPriority );
1746
1747 aMergedZones.push_back( aOriginZones[0] );
1748
1749 aOriginZones[0]->SetLocalFlags( 1 );
1750 aOriginZones[0]->HatchBorder();
1751 aOriginZones[0]->CacheTriangulation();
1752
1753 return true;
1754}
1755
1756
1758{
1759 const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1761 BOARD_COMMIT commit( m_frame );
1762
1763 if( selection.Size() < 2 )
1764 return 0;
1765
1766 int netcode = -1;
1767
1768 ZONE* firstZone = nullptr;
1769 std::vector<ZONE*> toMerge, merged;
1770
1771 for( EDA_ITEM* item : selection )
1772 {
1773 ZONE* curr_area = dynamic_cast<ZONE*>( item );
1774
1775 if( !curr_area )
1776 continue;
1777
1778 if( !firstZone )
1779 firstZone = curr_area;
1780
1781 netcode = curr_area->GetNetCode();
1782
1783 if( firstZone->GetNetCode() != netcode )
1784 {
1785 wxLogMessage( _( "Some zone netcodes did not match and were not merged." ) );
1786 continue;
1787 }
1788
1789 if( curr_area->GetIsRuleArea() != firstZone->GetIsRuleArea() )
1790 {
1791 wxLogMessage( _( "Some zones were rule areas and were not merged." ) );
1792 continue;
1793 }
1794
1795 if( curr_area->GetLayerSet() != firstZone->GetLayerSet() )
1796 {
1797 wxLogMessage( _( "Some zone layer sets did not match and were not merged." ) );
1798 continue;
1799 }
1800
1801 bool intersects = curr_area == firstZone;
1802
1803 for( ZONE* candidate : toMerge )
1804 {
1805 if( intersects )
1806 break;
1807
1808 if( board->TestZoneIntersection( curr_area, candidate ) )
1809 intersects = true;
1810 }
1811
1812 if( !intersects )
1813 {
1814 wxLogMessage( _( "Some zones did not intersect and were not merged." ) );
1815 continue;
1816 }
1817
1818 toMerge.push_back( curr_area );
1819 }
1820
1821 m_toolMgr->RunAction( ACTIONS::selectionClear );
1822
1823 if( !toMerge.empty() )
1824 {
1825 if( mergeZones( m_frame, commit, toMerge, merged ) )
1826 {
1827 commit.Push( _( "Merge Zones" ) );
1828
1829 for( EDA_ITEM* item : merged )
1830 m_toolMgr->RunAction( ACTIONS::selectItem, item );
1831 }
1832 }
1833
1834 return 0;
1835}
1836
1837
1839{
1840 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
1841 const PCB_SELECTION& selection = selTool->GetSelection();
1842
1843 // because this pops up the zone editor, it would be confusing to handle multiple zones,
1844 // so just handle single selections containing exactly one zone
1845 if( selection.Size() != 1 )
1846 return 0;
1847
1848 ZONE* oldZone = dynamic_cast<ZONE*>( selection[0] );
1849
1850 if( !oldZone )
1851 return 0;
1852
1853 ZONE_SETTINGS zoneSettings;
1854 zoneSettings << *oldZone;
1855 int dialogResult;
1856
1857 if( oldZone->GetIsRuleArea() )
1858 dialogResult = InvokeRuleAreaEditor( m_frame, &zoneSettings, board() );
1859 else if( oldZone->IsOnCopperLayer() )
1860 dialogResult = InvokeCopperZonesEditor( m_frame, nullptr, &zoneSettings );
1861 else
1862 dialogResult = InvokeNonCopperZonesEditor( m_frame, &zoneSettings );
1863
1864 if( dialogResult != wxID_OK )
1865 return 0;
1866
1867 // duplicate the zone
1868 BOARD_COMMIT commit( m_frame );
1869
1870 std::unique_ptr<ZONE> newZone = std::make_unique<ZONE>( *oldZone );
1871 newZone->ClearSelected();
1872 newZone->UnFill();
1873 zoneSettings.ExportSetting( *newZone );
1874
1875 if( !newZone->GetZoneName().IsEmpty() )
1876 newZone->SetZoneName( board()->GetUniqueZoneName( newZone->GetZoneName() ) );
1877
1878 // If the new zone is on the same layer(s) as the initial zone,
1879 // offset it a bit so it can more easily be picked.
1880 if( oldZone->GetLayerSet() == zoneSettings.m_Layers )
1881 newZone->Move( VECTOR2I( pcbIUScale.IU_PER_MM, pcbIUScale.IU_PER_MM ) );
1882
1883 commit.Add( newZone.release() );
1884 commit.Push( _( "Duplicate Zone" ) );
1885
1886 return 0;
1887}
1888
1889
1891{
1892 const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1893
1894 if( selection.Size() != 1 )
1895 return 0;
1896
1897 ZONE* zone = dynamic_cast<ZONE*>( selection[0] );
1898
1899 if( !zone || zone->GetIsRuleArea() || zone->IsTeardropArea() )
1900 return 0;
1901
1902 std::vector<ZONE*> overlapping = getOverlappingZones( board(), zone );
1903
1904 unsigned maxOverlapping = zone->GetAssignedPriority();
1905
1906 for( ZONE* other : overlapping )
1907 maxOverlapping = std::max( maxOverlapping, other->GetAssignedPriority() );
1908
1909 if( zone->GetAssignedPriority() >= maxOverlapping )
1910 return 0;
1911
1912 // Two options to place our zone above all overlapping zones.
1913 // Pick whichever viable option displaces fewer other zones.
1914 ZonePriorityMap byPriority = buildPriorityMap( board(), zone );
1915
1916 // Option A: take maxOverlapping, cascade displaced zones down
1917 bool cascadeDownViable = false;
1918 std::vector<ZONE*> cascadeDown =
1919 findCascadeZones( byPriority, maxOverlapping, false, cascadeDownViable );
1920
1921 // Option B: take maxOverlapping + 1, cascade displaced zones up
1922 bool cascadeUpViable = false;
1923 std::vector<ZONE*> cascadeUp;
1924 bool canCascadeUp = ( maxOverlapping < UINT_MAX );
1925
1926 if( canCascadeUp )
1927 cascadeUp = findCascadeZones( byPriority, maxOverlapping + 1, true, cascadeUpViable );
1928
1929 if( !cascadeDownViable && !cascadeUpViable )
1930 return 0;
1931
1932 BOARD_COMMIT commit( m_frame );
1933 commit.Modify( zone );
1934
1935 bool useDown = cascadeDownViable
1936 && ( !cascadeUpViable || cascadeDown.size() <= cascadeUp.size() );
1937
1938 if( useDown )
1939 {
1940 zone->SetAssignedPriority( maxOverlapping );
1941
1942 for( ZONE* z : cascadeDown )
1943 {
1944 commit.Modify( z );
1946 z->SetNeedRefill( true );
1947 }
1948 }
1949 else
1950 {
1951 zone->SetAssignedPriority( maxOverlapping + 1 );
1952
1953 for( ZONE* z : cascadeUp )
1954 {
1955 commit.Modify( z );
1957 z->SetNeedRefill( true );
1958 }
1959 }
1960
1961 zone->SetNeedRefill( true );
1962 commit.Push( _( "Move Zone to Top Priority" ) );
1963
1964 return 0;
1965}
1966
1967
1969{
1970 const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1971
1972 if( selection.Size() != 1 )
1973 return 0;
1974
1975 ZONE* zone = dynamic_cast<ZONE*>( selection[0] );
1976
1977 if( !zone || zone->GetIsRuleArea() || zone->IsTeardropArea() )
1978 return 0;
1979
1980 std::vector<ZONE*> overlapping = getOverlappingZones( board(), zone );
1981
1982 // Find the overlapping zone with the lowest priority still above ours
1983 ZONE* target = nullptr;
1984 unsigned zonePriority = zone->GetAssignedPriority();
1985
1986 for( ZONE* other : overlapping )
1987 {
1988 if( other->GetAssignedPriority() > zonePriority )
1989 {
1990 if( !target || other->GetAssignedPriority() < target->GetAssignedPriority() )
1991 target = other;
1992 }
1993 }
1994
1995 if( !target )
1996 return 0;
1997
1998 BOARD_COMMIT commit( m_frame );
1999 commit.Modify( zone );
2000
2001 // Place our zone just above the target without modifying any other zone
2002 if( target->GetAssignedPriority() < UINT_MAX )
2003 {
2004 zone->SetAssignedPriority( target->GetAssignedPriority() + 1 );
2005 }
2006 else
2007 {
2008 // Can't go above UINT_MAX; swap as last resort
2009 commit.Modify( target );
2010 zone->SetAssignedPriority( UINT_MAX );
2011 target->SetAssignedPriority( zonePriority );
2012 target->SetNeedRefill( true );
2013 }
2014
2015 zone->SetNeedRefill( true );
2016 commit.Push( _( "Raise Zone Priority" ) );
2017
2018 return 0;
2019}
2020
2021
2023{
2024 const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
2025
2026 if( selection.Size() != 1 )
2027 return 0;
2028
2029 ZONE* zone = dynamic_cast<ZONE*>( selection[0] );
2030
2031 if( !zone || zone->GetIsRuleArea() || zone->IsTeardropArea() )
2032 return 0;
2033
2034 std::vector<ZONE*> overlapping = getOverlappingZones( board(), zone );
2035
2036 // Find the overlapping zone with the highest priority still below ours
2037 ZONE* target = nullptr;
2038 unsigned zonePriority = zone->GetAssignedPriority();
2039
2040 for( ZONE* other : overlapping )
2041 {
2042 if( other->GetAssignedPriority() < zonePriority )
2043 {
2044 if( !target || other->GetAssignedPriority() > target->GetAssignedPriority() )
2045 target = other;
2046 }
2047 }
2048
2049 if( !target )
2050 return 0;
2051
2052 BOARD_COMMIT commit( m_frame );
2053 commit.Modify( zone );
2054
2055 // Place our zone just below the target without modifying any other zone
2056 if( target->GetAssignedPriority() > 0 )
2057 {
2058 zone->SetAssignedPriority( target->GetAssignedPriority() - 1 );
2059 }
2060 else
2061 {
2062 // Can't go below 0; swap as last resort
2063 commit.Modify( target );
2064 zone->SetAssignedPriority( 0 );
2065 target->SetAssignedPriority( zonePriority );
2066 target->SetNeedRefill( true );
2067 }
2068
2069 zone->SetNeedRefill( true );
2070 commit.Push( _( "Lower Zone Priority" ) );
2071
2072 return 0;
2073}
2074
2075
2077{
2078 const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
2079
2080 if( selection.Size() != 1 )
2081 return 0;
2082
2083 ZONE* zone = dynamic_cast<ZONE*>( selection[0] );
2084
2085 if( !zone || zone->GetIsRuleArea() || zone->IsTeardropArea() )
2086 return 0;
2087
2088 std::vector<ZONE*> overlapping = getOverlappingZones( board(), zone );
2089
2090 unsigned minOverlapping = zone->GetAssignedPriority();
2091
2092 for( ZONE* other : overlapping )
2093 minOverlapping = std::min( minOverlapping, other->GetAssignedPriority() );
2094
2095 if( zone->GetAssignedPriority() <= minOverlapping )
2096 return 0;
2097
2098 // Two options to place our zone below all overlapping zones.
2099 // Pick whichever viable option displaces fewer other zones.
2100 ZonePriorityMap byPriority = buildPriorityMap( board(), zone );
2101
2102 // Option A: take minOverlapping, cascade displaced zones up
2103 bool cascadeUpViable = false;
2104 std::vector<ZONE*> cascadeUp =
2105 findCascadeZones( byPriority, minOverlapping, true, cascadeUpViable );
2106
2107 // Option B: take minOverlapping - 1, cascade displaced zones down
2108 bool cascadeDownViable = false;
2109 std::vector<ZONE*> cascadeDown;
2110 bool canCascadeDown = ( minOverlapping > 0 );
2111
2112 if( canCascadeDown )
2113 {
2114 cascadeDown =
2115 findCascadeZones( byPriority, minOverlapping - 1, false, cascadeDownViable );
2116 }
2117
2118 if( !cascadeUpViable && !cascadeDownViable )
2119 return 0;
2120
2121 BOARD_COMMIT commit( m_frame );
2122 commit.Modify( zone );
2123
2124 bool useUp = cascadeUpViable
2125 && ( !cascadeDownViable || cascadeUp.size() <= cascadeDown.size() );
2126
2127 if( useUp )
2128 {
2129 zone->SetAssignedPriority( minOverlapping );
2130
2131 for( ZONE* z : cascadeUp )
2132 {
2133 commit.Modify( z );
2135 z->SetNeedRefill( true );
2136 }
2137 }
2138 else
2139 {
2140 zone->SetAssignedPriority( minOverlapping - 1 );
2141
2142 for( ZONE* z : cascadeDown )
2143 {
2144 commit.Modify( z );
2146 z->SetNeedRefill( true );
2147 }
2148 }
2149
2150 zone->SetNeedRefill( true );
2151 commit.Push( _( "Move Zone to Bottom Priority" ) );
2152
2153 return 0;
2154}
2155
2156
2158{
2159 m_frame->GetBoard()->OnBoardSelectionChanged();
2160 doCrossProbePcbToSch( aEvent, false );
2161 return 0;
2162}
2163
2164
2166{
2167 doCrossProbePcbToSch( aEvent, true );
2168 return 0;
2169}
2170
2171
2173{
2174 // Don't get in an infinite loop PCB -> SCH -> PCB -> SCH -> ...
2175 if( m_frame->m_ProbingSchToPcb )
2176 return;
2177
2178 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
2179 const PCB_SELECTION& selection = selTool->GetSelection();
2180 EDA_ITEM* focusItem = nullptr;
2181
2182 if( aEvent.Matches( EVENTS::PointSelectedEvent ) )
2183 focusItem = selection.GetLastAddedItem();
2184
2185 m_frame->SendSelectItemsToSch( selection.GetItems(), focusItem, aForce );
2186
2187 // Update 3D viewer highlighting
2188 m_frame->Update3DView( false, frame()->GetPcbNewSettings()->m_Display.m_Live3DRefresh );
2189}
2190
2191
2193{
2194 PCB_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
2195
2196 const PCB_SELECTION& selection = selectionTool->RequestSelection(
2197 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2198 {
2199 // Iterate from the back so we don't have to worry about removals.
2200 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
2201 {
2202 if( !dynamic_cast<BOARD_CONNECTED_ITEM*>( aCollector[ i ] ) )
2203 aCollector.Remove( aCollector[ i ] );
2204 }
2205
2206 sTool->FilterCollectorForLockedItems( aCollector );
2207 } );
2208
2209 if( selectionTool->ReportFilteredLockedItems() )
2210 return 0;
2211
2212 std::set<wxString> netNames;
2213 std::set<int> netCodes;
2214
2215 for( EDA_ITEM* item : selection )
2216 {
2217 const NETINFO_ITEM& net = *static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNet();
2218
2219 if( !net.HasAutoGeneratedNetname() )
2220 {
2221 netNames.insert( net.GetNetname() );
2222 netCodes.insert( net.GetNetCode() );
2223 }
2224 }
2225
2226 if( netNames.empty() )
2227 {
2228 m_frame->ShowInfoBarError( _( "Selection contains no items with labeled nets." ) );
2229 return 0;
2230 }
2231
2232 selectionTool->ClearSelection();
2233 for( const int& code : netCodes )
2234 {
2235 m_toolMgr->RunAction( PCB_ACTIONS::selectNet, code );
2236 }
2237 canvas()->ForceRefresh();
2238
2239 DIALOG_ASSIGN_NETCLASS dlg( m_frame, netNames, board()->GetNetClassAssignmentCandidates(),
2240 [this]( const std::vector<wxString>& aNetNames )
2241 {
2242 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
2243 selTool->ClearSelection();
2244
2245 for( const wxString& curr_netName : aNetNames )
2246 {
2247 int curr_netCode = board()->GetNetInfo().GetNetItem( curr_netName )->GetNetCode();
2248
2249 if( curr_netCode > 0 )
2250 selTool->SelectAllItemsOnNet( curr_netCode );
2251 }
2252
2253 canvas()->ForceRefresh();
2254 m_frame->UpdateMsgPanel();
2255 } );
2256
2257 if( dlg.ShowModal() == wxID_OK )
2258 {
2260 // Refresh UI that depends on netclasses, such as the properties panel
2262 }
2263
2264 return 0;
2265}
2266
2267
2269{
2270 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
2271 const PCB_SELECTION& selection = selTool->RequestSelection( EDIT_TOOL::FootprintFilter );
2272
2273 if( selection.Empty() )
2274 {
2275 // Giant hack: by default we assign Edit Table to the same hotkey, so give the table
2276 // tool a chance to handle it if we can't.
2277 if( PCB_EDIT_TABLE_TOOL* tableTool = m_toolMgr->GetTool<PCB_EDIT_TABLE_TOOL>() )
2278 tableTool->EditTable( aEvent );
2279
2280 return 0;
2281 }
2282
2283 FOOTPRINT* fp = selection.FirstOfKind<FOOTPRINT>();
2284
2285 if( !fp )
2286 return 0;
2287
2289
2290 if( KIWAY_PLAYER* frame = editFrame->Kiway().Player( FRAME_FOOTPRINT_EDITOR, true ) )
2291 {
2292 FOOTPRINT_EDIT_FRAME* fp_editor = static_cast<FOOTPRINT_EDIT_FRAME*>( frame );
2293
2295 fp_editor->LoadFootprintFromBoard( fp );
2296 else if( aEvent.IsAction( &PCB_ACTIONS::editLibFpInFpEditor ) )
2297 fp_editor->LoadFootprintFromLibrary( fp->GetFPID() );
2298
2299 fp_editor->Show( true );
2300 fp_editor->Raise(); // Iconize( false );
2301 }
2302
2303 if( selection.IsHover() )
2304 m_toolMgr->RunAction( ACTIONS::selectionClear );
2305
2306 return 0;
2307}
2308
2309
2311 EDA_ITEM* originViewItem, const VECTOR2D& aPosition )
2312{
2313 aFrame->GetDesignSettings().SetAuxOrigin( VECTOR2I( aPosition ) );
2314 originViewItem->SetPosition( aPosition );
2315 aView->MarkDirty();
2316 aFrame->OnModify();
2317}
2318
2319
2321{
2323 {
2324 m_frame->SaveCopyInUndoList( m_placeOrigin.get(), UNDO_REDO::GRIDORIGIN );
2326 return 0;
2327 }
2328
2329 if( aEvent.IsAction( &PCB_ACTIONS::drillSetOrigin ) )
2330 {
2331 VECTOR2I origin = aEvent.Parameter<VECTOR2I>();
2332 m_frame->SaveCopyInUndoList( m_placeOrigin.get(), UNDO_REDO::GRIDORIGIN );
2333 DoSetDrillOrigin( getView(), m_frame, m_placeOrigin.get(), origin );
2334 return 0;
2335 }
2336
2337 PCB_PICKER_TOOL* picker = m_toolMgr->GetTool<PCB_PICKER_TOOL>();
2338
2339 // Deactivate other tools; particularly important if another PICKER is currently running
2340 Activate();
2341
2342 picker->SetCursor( KICURSOR::PLACE );
2343 picker->ClearHandlers();
2344
2345 picker->SetClickHandler(
2346 [this] ( const VECTOR2D& pt ) -> bool
2347 {
2348 m_frame->SaveCopyInUndoList( m_placeOrigin.get(), UNDO_REDO::DRILLORIGIN );
2350 return false; // drill origin is a one-shot; don't continue with tool
2351 } );
2352
2353 m_toolMgr->RunAction( ACTIONS::pickerTool, &aEvent );
2354
2355 return 0;
2356}
2357
2358
2360{
2369
2375
2383
2384 if( ADVANCED_CFG::GetCfg().m_ShowPcbnewExportNetlist && m_frame && m_frame->GetExportNetlistAction() )
2385 Go( &BOARD_EDITOR_CONTROL::ExportNetlist, m_frame->GetExportNetlistAction()->MakeEvent() );
2386
2396
2403
2404 // Track & via size control
2410
2411 // Zone actions
2418
2419 // Placing tools
2424
2427
2428 // Cross-select
2434
2435 // Other
2439
2441
2453 // Line modes: explicit, next, and notification
2458}
const char * name
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:128
#define SKIP_TEARDROPS
static bool mergeZones(EDA_DRAW_FRAME *aFrame, BOARD_COMMIT &aCommit, std::vector< ZONE * > &aOriginZones, std::vector< ZONE * > &aMergedZones)
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
static TOOL_ACTION updatePcbFromSchematic
Definition actions.h:260
static TOOL_ACTION cancelInteractive
Definition actions.h:68
static TOOL_ACTION revert
Definition actions.h:58
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition actions.h:223
static TOOL_ACTION saveAs
Definition actions.h:55
static TOOL_ACTION pickerTool
Definition actions.h:249
static TOOL_ACTION findPrevious
Definition actions.h:116
static TOOL_ACTION plot
Definition actions.h:61
static TOOL_ACTION open
Definition actions.h:53
static TOOL_ACTION findNext
Definition actions.h:115
static TOOL_ACTION pageSettings
Definition actions.h:59
static TOOL_ACTION showSearch
Definition actions.h:112
static TOOL_ACTION undo
Definition actions.h:71
static TOOL_ACTION showGitCommitPane
Definition actions.h:263
static TOOL_ACTION save
Definition actions.h:54
static TOOL_ACTION redo
Definition actions.h:72
static TOOL_ACTION updateSchematicFromPcb
Definition actions.h:261
static TOOL_ACTION selectionClear
Clear the current selection.
Definition actions.h:220
static TOOL_ACTION showProperties
Definition actions.h:262
static TOOL_ACTION doNew
Definition actions.h:50
static TOOL_ACTION saveCopy
Definition actions.h:56
static TOOL_ACTION refreshPreview
Definition actions.h:155
static TOOL_ACTION find
Definition actions.h:113
ACTION_MENU(bool isContextMenu, TOOL_INTERACTIVE *aTool=nullptr)
Default constructor.
TOOL_MANAGER * getToolManager() const
Return an instance of TOOL_MANAGER class.
void SetTitle(const wxString &aTitle) override
Set title for the menu.
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
wxMenuItem * Add(const wxString &aLabel, int aId, BITMAPS aIcon)
Add a wxWidgets-style entry to the menu.
friend class TOOL_INTERACTIVE
TOOL_INTERACTIVE * m_tool
Creator of the menu.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
static wxString m_DrawingSheetFileName
the name of the drawing sheet file, or empty to use the default drawing sheet
Definition base_screen.h:81
void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
void Revert() override
Revert the commit by restoring the modified items state.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
NETINFO_ITEM * GetNet() const
Return NETINFO_ITEM object for a given item.
Container for design settings for a BOARD object.
void UseCustomTrackViaSize(bool aEnabled)
Enables/disables custom track/via size settings.
std::shared_ptr< NET_SETTINGS > m_NetSettings
int GetNextDiffPairIndex(int aIndex, bool aForward) const
Compute the next diff pair dimensions list index when cycling predefined sizes, skipping the index-0 ...
void SetViaSizeIndex(int aIndex)
Set the current via size list index to aIndex.
int GetNextTrackWidthIndex(int aIndex, bool aForward) const
Compute the next track width list index when cycling predefined sizes, skipping the index-0 netclass ...
void SetAuxOrigin(const VECTOR2I &aOrigin)
void SetTrackWidthIndex(int aIndex)
Set the current track width list index to aIndex.
void UseCustomDiffPairDimensions(bool aEnabled)
Enables/disables custom differential pair dimensions.
int GetNextViaSizeIndex(int aIndex, bool aForward) const
Compute the next via size list index when cycling predefined sizes, skipping the index-0 netclass pla...
std::vector< int > m_TrackWidthList
std::vector< VIA_DIMENSION > m_ViasDimensionsList
int ExportNetlist(const TOOL_EVENT &aEvent)
int UnlockSelected(const TOOL_EVENT &aEvent)
Unlock selected items.
int Save(const TOOL_EVENT &aEvent)
int ImportNetlist(const TOOL_EVENT &aEvent)
int GenerateDrillFiles(const TOOL_EVENT &aEvent)
int ZoneMerge(const TOOL_EVENT &aEvent)
int CrossProbeToSch(const TOOL_EVENT &aEvent)
Notify Eeschema about selected items.
int ZonePriorityMoveToTop(const TOOL_EVENT &aEvent)
int GenBOMFileFromBoard(const TOOL_EVENT &aEvent)
static void DoSetDrillOrigin(KIGFX::VIEW *aView, PCB_BASE_FRAME *aFrame, EDA_ITEM *aItem, const VECTOR2D &aPoint)
Low-level access (below undo) to setting the drill origin.
int UpdatePCBFromSchematic(const TOOL_EVENT &aEvent)
std::unique_ptr< KIGFX::ORIGIN_VIEWITEM > m_placeOrigin
int ShowEeschema(const TOOL_EVENT &aEvent)
int ExportFootprints(const TOOL_EVENT &aEvent)
int SaveAs(const TOOL_EVENT &aEvent)
int AssignNetclass(const TOOL_EVENT &aEvent)
Assign a netclass to a labelled net.
int ToggleNetInspector(const TOOL_EVENT &aEvent)
int UpdateSchematicFromPCB(const TOOL_EVENT &aEvent)
int ZonePriorityRaise(const TOOL_EVENT &aEvent)
int ExplicitCrossProbeToSch(const TOOL_EVENT &aEvent)
Equivalent to the above, but initiated by the user.
int ExportHyperlynx(const TOOL_EVENT &aEvent)
int ToggleSearch(const TOOL_EVENT &aEvent)
int DrillOrigin(const TOOL_EVENT &aEvent)
Run the drill origin tool for setting the origin for drill and pick-and-place files.
MODIFY_MODE
How to modify a property for selected items.
int ViaSizeDec(const TOOL_EVENT &aEvent)
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
int RepairBoard(const TOOL_EVENT &aEvent)
int ZoneDuplicate(const TOOL_EVENT &aEvent)
Duplicate a zone onto a layer (prompts for new layer)
int ToggleLayersManager(const TOOL_EVENT &aEvent)
int ImportSpecctraSession(const TOOL_EVENT &aEvent)
bool Init() override
Init() is called once upon a registration of the tool.
int GenerateBOM(const TOOL_EVENT &aEvent)
int ToggleGitCommitPane(const TOOL_EVENT &aEvent)
int PlaceFootprint(const TOOL_EVENT &aEvent)
Display a dialog to select a footprint to be added and allows the user to set its position.
int BoardSetup(const TOOL_EVENT &aEvent)
int ZonePriorityLower(const TOOL_EVENT &aEvent)
int modifyLockSelected(MODIFY_MODE aMode)
void setTransitions() override
Set up handlers for various events.
int TrackWidthInc(const TOOL_EVENT &aEvent)
int GenerateODBPPFiles(const TOOL_EVENT &aEvent)
int ToggleLockSelected(const TOOL_EVENT &aEvent)
Toggle 'lock' property for selected items.
int ToggleConstraintsPanel(const TOOL_EVENT &aEvent)
int AutoTrackWidth(const TOOL_EVENT &aEvent)
int LockSelected(const TOOL_EVENT &aEvent)
Lock selected items.
int PageSettings(const TOOL_EVENT &aEvent)
int ExportSpecctraDSN(const TOOL_EVENT &aEvent)
int FindByProperties(const TOOL_EVENT &aEvent)
int EditFootprintFields(const TOOL_EVENT &aEvent)
int FindNext(const TOOL_EVENT &aEvent)
int ToggleLibraryTree(const TOOL_EVENT &aEvent)
int ExportGenCAD(const TOOL_EVENT &aEvent)
Export GenCAD 1.4 format.
int ViaSizeInc(const TOOL_EVENT &aEvent)
int New(const TOOL_EVENT &aEvent)
int OnAngleSnapModeChanged(const TOOL_EVENT &aEvent)
int ExportCmpFile(const TOOL_EVENT &aEvent)
int Find(const TOOL_EVENT &aEvent)
int GenFootprintsReport(const TOOL_EVENT &aEvent)
void doCrossProbePcbToSch(const TOOL_EVENT &aEvent, bool aForce)
int GenD356File(const TOOL_EVENT &aEvent)
int Plot(const TOOL_EVENT &aEvent)
int ExportIDF(const TOOL_EVENT &aEvent)
int TrackWidthDec(const TOOL_EVENT &aEvent)
int Revert(const TOOL_EVENT &aEvent)
int Search(const TOOL_EVENT &aEvent)
int GenIPC2581File(const TOOL_EVENT &aEvent)
int ExportVRML(const TOOL_EVENT &aEvent)
int Open(const TOOL_EVENT &aEvent)
int SaveCopy(const TOOL_EVENT &aEvent)
int ChangeLineMode(const TOOL_EVENT &aEvent)
int GeneratePosFile(const TOOL_EVENT &aEvent)
int EditFpInFpEditor(const TOOL_EVENT &aEvent)
int ZonePriorityMoveToBottom(const TOOL_EVENT &aEvent)
int GenerateGerbers(const TOOL_EVENT &aEvent)
int ToggleProperties(const TOOL_EVENT &aEvent)
int OpenNonKicadBoard(const TOOL_EVENT &aEvent)
int ExportSTEP(const TOOL_EVENT &aEvent)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:85
void SetLocked(bool aLocked) override
Definition board_item.h:427
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
virtual void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const
Invoke a function on all children.
Definition board_item.h:265
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:411
const NETINFO_LIST & GetNetInfo() const
Definition board.h:1217
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1520
const ZONES & Zones() const
Definition board.h:469
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:3221
int RepairDuplicateItemUuids()
Rebind duplicate attached-item UUIDs so each live board item has a unique ID.
Definition board.cpp:2292
int GetCount() const
Return the number of objects in the list.
Definition collector.h:79
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition collector.h:107
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
Definition commit.h:86
bool Empty() const
Definition commit.h:145
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:102
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition commit.h:74
int GetStatus(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Returns status of an item.
Definition commit.cpp:235
Store all of the related component information found in a netlist.
void AddNet(const wxString &aPinName, const wxString &aNetName, const wxString &aPinFunction, const wxString &aPinType)
void SetFields(nlohmann::ordered_map< wxString, wxString > aFields)
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a menu entry to run a TOOL_ACTION on selected items.
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
void AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Add a submenu to the menu.
CONDITIONAL_MENU(TOOL_INTERACTIVE *aTool)
void SetWksFileName(const wxString &aFilename)
A dialog to set the plot options and create plot files in various formats.
Definition dialog_plot.h:37
bool Show(bool show) override
int ShowModal() override
Tool responsible for drawing graphical elements like lines, arcs, circles, etc.
MODE GetDrawingMode() const
Return the current drawing mode of the DRAWING_TOOL or NONE if not currently in any drawing mode.
MODE
The possible drawing modes of DRAWING_TOOL.
void SelectToolbarAction(const TOOL_ACTION &aAction) override
Select the given action in the toolbar group which contains it, if any.
The base class for create windows for drawing purpose.
void ForceRefresh()
Force a redraw.
A set of EDA_ITEMs (i.e., without duplicates).
Definition eda_group.h:43
virtual EDA_ITEM * AsEdaItem()=0
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:98
virtual void SetPosition(const VECTOR2I &aPos)
Definition eda_item.h:349
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition eda_item.h:158
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 void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:153
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:94
static const TOOL_EVENT ClearedEvent
Definition actions.h:348
static const TOOL_EVENT SelectedEvent
Definition actions.h:346
static const TOOL_EVENT SelectedItemsModified
Selected item had a property changed (except movement)
Definition actions.h:353
static const TOOL_EVENT PointSelectedEvent
Definition actions.h:345
static const TOOL_EVENT UnselectedEvent
Definition actions.h:347
Used for text file output.
Definition richio.h:483
bool Finish() override
Flushes the temp file to disk and atomically renames it over the final target path.
Definition richio.cpp:682
void LoadFootprintFromLibrary(LIB_ID aFPID)
bool LoadFootprintFromBoard(FOOTPRINT *aFootprint)
Load a footprint from the main board into the Footprint Editor.
void SetPosition(const VECTOR2I &aPos) override
void SetLink(const KIID &aLink)
Definition footprint.h:1151
void SetOrientation(const EDA_ANGLE &aNewAngle)
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
std::deque< PAD * > & Pads()
Definition footprint.h:355
bool IsFlipped() const
Definition footprint.h:620
const LIB_ID & GetFPID() const
Definition footprint.h:417
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
VECTOR2I GetPosition() const override
Definition footprint.h:379
Used when the right click button is pressed, or when the select tool is in effect.
Definition collectors.h:203
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
An interface for classes handling user events controlling the view behavior such as zooming,...
virtual void WarpMouseCursor(const VECTOR2D &aPosition, bool aWorldCoordinates=false, bool aWarpView=false)=0
If enabled (.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
virtual void PinCursorInsideNonAutoscrollArea(bool aWarpMouseCursor)=0
An abstract base class for deriving all objects that can be added to a VIEW.
Definition view_item.h:82
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:68
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition view.cpp:365
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:488
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:2631
void MarkDirty()
Force redraw of view on the next rendering.
Definition view.h:779
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.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:401
Helper widget to add controls to a wxFileDialog to set netlist configuration options.
static wxWindow * Create(wxWindow *aParent)
ACTION_MENU * create() const override
Return an instance of this class. It has to be overridden in inheriting classes.
LOCK_CONTEXT_MENU(TOOL_INTERACTIVE *aTool)
int GetViaDiameter() const
Definition netclass.h:158
int GetViaDrill() const
Definition netclass.h:166
int GetTrackWidth() const
Definition netclass.h:150
Handle the data for a net.
Definition netinfo.h:50
const wxString & GetNetname() const
Definition netinfo.h:110
int GetNetCode() const
Definition netinfo.h:104
bool HasAutoGeneratedNetname() const
NETINFO_ITEM * GetNetItem(int aNetCode) const
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
std::shared_ptr< NETCLASS > GetDefaultNetclass() const
Gets the default netclass for the project.
@ NORMAL
Shape is the same on all layers.
Definition padstack.h:170
static constexpr PCB_LAYER_ID ALL_LAYERS
! The layer identifier to use for the single defintion on normal padstacks
Definition padstack.h:179
Definition pad.h:61
static TOOL_ACTION lineModeFree
Unconstrained angle mode (icon lines_any)
static TOOL_ACTION showConstraintsPanel
Toggle the docked constraints pane (board editor).
static TOOL_ACTION zonesManager
static TOOL_ACTION generateBOM
static TOOL_ACTION exportGenCAD
static TOOL_ACTION zoneFillAll
static TOOL_ACTION showLayersManager
static TOOL_ACTION trackWidthDec
static TOOL_ACTION generateDrillFiles
static TOOL_ACTION exportVRML
static TOOL_ACTION generateD356File
static TOOL_ACTION exportCmpFile
static TOOL_ACTION trackViaSizeChanged
static TOOL_ACTION exportSpecctraDSN
static TOOL_ACTION trackWidthInc
static TOOL_ACTION autoTrackWidth
static TOOL_ACTION generateIPC2581File
static TOOL_ACTION getAndPlace
Find an item and start moving.
static TOOL_ACTION generateODBPPFile
static TOOL_ACTION drawZoneCutout
static TOOL_ACTION openNonKicadBoard
static TOOL_ACTION viaSizeDec
static TOOL_ACTION zoneFill
static TOOL_ACTION properties
Activation of the edit tool.
static TOOL_ACTION editFpInFpEditor
static TOOL_ACTION toggleLock
static TOOL_ACTION drillResetOrigin
static TOOL_ACTION lineMode45
45-degree-or-orthogonal mode (icon hv45mode)
static TOOL_ACTION zonePriorityMoveToBottom
static TOOL_ACTION zonePriorityMoveToTop
static TOOL_ACTION viaSizeInc
static TOOL_ACTION angleSnapModeChanged
Notification event when angle mode changes.
static TOOL_ACTION generateBOMLegacy
static TOOL_ACTION zoneUnfill
static TOOL_ACTION generatePosFile
static TOOL_ACTION drillOrigin
static TOOL_ACTION assignNetClass
static TOOL_ACTION repairBoard
static TOOL_ACTION exportSTEP
static TOOL_ACTION showNetInspector
static TOOL_ACTION findByProperties
Find items by property criteria or expression.
static TOOL_ACTION generateGerbers
static TOOL_ACTION generateReportFile
static TOOL_ACTION exportHyperlynx
static TOOL_ACTION zonePriorityLower
static TOOL_ACTION exportIDF
static TOOL_ACTION zoneDuplicate
Duplicate zone onto another layer.
static TOOL_ACTION importNetlist
static TOOL_ACTION drawSimilarZone
static TOOL_ACTION boardSetup
static TOOL_ACTION showEeschema
static TOOL_ACTION showDesignBlockPanel
static TOOL_ACTION zoneUnfillAll
static TOOL_ACTION selectNet
Select all connections belonging to a single net.
Definition pcb_actions.h:82
static TOOL_ACTION editFootprintFields
static TOOL_ACTION lineMode90
90-degree-only mode (icon lines90)
static TOOL_ACTION editLibFpInFpEditor
static TOOL_ACTION zoneMerge
static TOOL_ACTION drillSetOrigin
static TOOL_ACTION unlock
static TOOL_ACTION exportFootprints
static TOOL_ACTION placeFootprint
static TOOL_ACTION zonePriorityRaise
static TOOL_ACTION importSpecctraSession
static TOOL_ACTION selectOnSchematic
Select symbols/pins on schematic corresponding to selected footprints/pads.
static TOOL_ACTION lock
Common, abstract interface for edit frames.
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
void OnModify() override
Must be called after a change in order to set the "modify" flag and update other data structures and ...
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Return the BOARD_DESIGN_SETTINGS for the open project.
The main frame for Pcbnew.
void SetLocked(bool aLocked) override
Generic tool for picking an item.
void ClearHandlers()
Handlers only.
Parameters and options when plotting/printing a board.
void SetFormat(PLOT_FORMAT aFormat)
static bool HasUnlockedItems(const SELECTION &aSelection)
Test if any selected items are unlocked.
static bool HasLockedItems(const SELECTION &aSelection)
Test if any selected items are locked.
The selection tool: currently supports:
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter)
Return the current selection, filtered according to aClientFilter.
bool ReportFilteredLockedItems()
If the most recent FilterCollectorForLockedItems call filtered a locked item, show an InfoBar warning...
int ClearSelection(const TOOL_EVENT &aEvent)
Clear current selection event handler.
PCB_SELECTION & GetSelection()
void FilterCollectorForLockedItems(GENERAL_COLLECTOR &aCollector)
In the PCB editor strip out any locked items unless the OverrideLocks checkbox is set.
void SelectAllItemsOnNet(int aNetCode, bool aSelect=true)
Select all items with the given net code.
T * frame() const
KIGFX::VIEW_CONTROLS * controls() const
PCB_TOOL_BASE(TOOL_ID aId, const std::string &aName)
Constructor.
BOARD * board() const
PCB_DRAW_PANEL_GAL * canvas() const
const PCB_SELECTION & selection() const
FOOTPRINT * footprint() const
virtual void SetWidth(int aWidth)
Definition pcb_track.h:91
virtual int GetWidth() const
Definition pcb_track.h:92
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:562
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 SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition picker_tool.h:81
void SetCursor(KICURSOR aCursor)
Definition picker_tool.h:63
ROUTER_MODE Mode() const
Definition pns_router.h:182
RouterState GetState() const
Definition pns_router.h:184
ROUTER * Router() const
Container for project specific data.
Definition project.h:63
virtual void OnSave(wxCommandEvent &aEvent)=0
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
int Size() const
Returns the number of selected parts.
Definition selection.h:120
void SetReferencePoint(const VECTOR2I &aP)
Represent a set of closed polygons.
void ClearArcs()
Removes all arc references from all the outlines and holes in the polyset.
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
int TotalVertices() const
Return total number of vertices stored in the set.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
Return true if a given subpolygon contains the point aP.
T * getEditFrame() const
Return the application window object, casted to requested user type.
Definition tool_base.h:182
T * getModel() const
Return the model object if it matches the requested type.
Definition tool_base.h:195
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition tool_base.cpp:40
TOOL_MANAGER * m_toolMgr
Definition tool_base.h:220
KIGFX::VIEW * getView() const
Return the instance of KIGFX::VIEW object used in the application.
Definition tool_base.cpp:34
bool IsToolActive() const
Definition tool_base.cpp:28
RESET_REASON
Determine the reason of reset for a tool.
Definition tool_base.h:74
@ REDRAW
Full drawing refresh.
Definition tool_base.h:79
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition tool_base.h:76
@ GAL_SWITCH
Rendering engine changes.
Definition tool_base.h:78
Generic, UI-independent tool event.
Definition tool_event.h:167
bool HasPosition() const
Returns if it this event has a valid position (true for mouse events and context-menu or hotkey-based...
Definition tool_event.h:256
bool Matches(const TOOL_EVENT &aEvent) const
Test whether two events match in terms of category & action or command.
Definition tool_event.h:388
const VECTOR2D Position() const
Return mouse cursor position in world coordinates.
Definition tool_event.h:289
bool IsReactivate() const
Control whether the tool is first being pushed to the stack or being reactivated after a pause.
Definition tool_event.h:269
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
T Parameter() const
Return a parameter assigned to the event.
Definition tool_event.h:484
void RunMainStack(std::function< void()> aFunc)
Call a function using the main stack.
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).
TOOL_MENU & GetToolMenu()
std::unique_ptr< TOOL_MENU > m_menu
The functions below are not yet implemented - their interface may change.
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Suspend execution of the tool until an event specified in aEventList arrives.
void Activate()
Run the tool.
T * GetTool()
Return the tool of given type or nullptr if there is no such tool registered.
Manage a CONDITIONAL_MENU and some number of CONTEXT_MENUs as sub-menus.
Definition tool_menu.h:39
CONDITIONAL_MENU & GetMenu()
Definition tool_menu.cpp:40
void RegisterSubMenu(std::shared_ptr< ACTION_MENU > aSubMenu)
Store a submenu of this menu model.
Definition tool_menu.cpp:46
ACTION_MENU * create() const override
Return an instance of this class. It has to be overridden in inheriting classes.
static bool IsZoneFillAction(const TOOL_EVENT *aEvent)
ACTION_MENU * create() const override
Return an instance of this class. It has to be overridden in inheriting classes.
void update() override
Update menu state stub.
Handle zones parameters.
void ExportSetting(ZONE &aTarget, bool aFullExport=true) const
Copy settings to a given zone.
Handle a list of polygons defining a copper zone.
Definition zone.h:70
void SetNeedRefill(bool aNeedRefill)
Definition zone.h:310
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition zone.h:832
const BOX2I GetBoundingBox() const override
Definition zone.cpp:822
SHAPE_POLY_SET GetBoardOutline() const
Definition zone.cpp:951
bool IsTeardropArea() const
Definition zone.h:807
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition zone.h:133
bool IsOnCopperLayer() const override
Definition zone.cpp:650
void SetAssignedPriority(unsigned aPriority)
Definition zone.h:117
unsigned GetAssignedPriority() const
Definition zone.h:122
@ CHT_MODIFY
Definition commit.h:40
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition confirm.cpp:245
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
This file is part of the common library.
@ PLACE
Definition cursors.h:95
@ ARROW
Definition cursors.h:43
@ PENCIL
Definition cursors.h:49
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
Definition cvpcb.cpp:165
int InvokeCopperZonesEditor(PCB_BASE_FRAME *aCaller, ZONE *aZone, ZONE_SETTINGS *aSettings, CONVERT_SETTINGS *aConvertSettings)
Invoke a modal dialog window for copper zone editing.
int InvokeNonCopperZonesEditor(PCB_BASE_FRAME *aParent, ZONE_SETTINGS *aSettings, CONVERT_SETTINGS *aConvertSettings)
Invoke a modal dialog window for non-copper zone editing.
int InvokeRuleAreaEditor(PCB_BASE_FRAME *aCaller, ZONE_SETTINGS *aZoneSettings, BOARD *aBoard, CONVERT_SETTINGS *aConvertSettings)
Invoke a modal dialog window for copper zone editing.
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:448
@ RECURSE
Definition eda_item.h:51
#define IS_NEW
New item, just created.
KiCad executable names.
const wxString EESCHEMA_EXE
@ FRAME_SCH
Definition frame_type.h:30
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:39
LEADER_MODE
The kind of the leader line.
@ DEG45
45 Degree only
@ DIRECT
Unconstrained point-to-point.
@ DEG90
90 Degree only
int ExecuteFile(const wxString &aEditorName, const wxString &aFileName, wxProcess *aCallback, bool aFileForKicad)
Call the executable file aEditorName with the parameter aFileName.
Definition gestfich.cpp:166
static const std::string LegacySchematicFileExtension
static const std::string KiCadSchematicFileExtension
static const std::string SpecctraDsnFileExtension
static const std::string SpecctraSessionFileExtension
static wxString SpecctraSessionFileWildcard()
static wxString SpecctraDsnFileWildcard()
KIID niluuid(0)
@ MAIL_SCH_UPDATE
Definition mail_type.h:43
@ REPAINT
Item needs to be redrawn.
Definition view_item.h:54
@ GEOMETRY
Position or shape has changed.
Definition view_item.h:51
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:640
@ PNS_MODE_ROUTE_DIFF_PAIR
Definition pns_router.h:70
#define MAX_PAGE_SIZE_PCBNEW_MILS
Definition page_info.h:31
EDA_ANGLE GridFrameAngleAt(const BOARD &aBoard, const VECTOR2I &aPos, PCB_GRID_ROLE aRole)
World frame angle of the grid active for aRole at aPos; ANGLE_0 when no grid applies.
EDA_ANGLE GridFrameRotationDelta(const EDA_ANGLE &aFrom, const EDA_ANGLE &aTo, const EDA_ANGLE &aRotationStep)
Minimal rotation that re-aligns an item from frame angle aFrom to aTo, reduced modulo min( aRotationS...
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
@ LAST_PATH_SPECCTRADSN
T * GetAppSettings(const char *aFilename)
std::vector< FAB_LAYER_COLOR > dummy
Container to handle a stock of specific vias each with unique diameter and drill sizes in the BOARD c...
std::string netlist
std::string path
wxString result
Test unit parsing edge cases and error handling.
int delta
@ BUT_LEFT
Definition tool_event.h:128
@ BUT_RIGHT
Definition tool_event.h:129
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
Definition typeinfo.h:83
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:89
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:78
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:79
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708
VECTOR2< double > VECTOR2D
Definition vector2d.h:707
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
Definition of file extensions used in Kicad.