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, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
27
28#include <functional>
29#include <memory>
30
31#include <pgm_base.h>
32#include <executable_names.h>
33#include <advanced_config.h>
34#include <bitmaps.h>
35#include <gestfich.h>
36#include <pcb_painter.h>
37#include <board.h>
38#include <board_commit.h>
40#include <collectors.h>
42#include <pcb_generator.h>
43#include <footprint.h>
44#include <pad.h>
45#include <pcb_target.h>
46#include <pcb_track.h>
47#include <zone.h>
48#include <pcb_marker.h>
49#include <confirm.h>
53#include <dialog_plot.h>
55#include <kiface_base.h>
56#include <kiway.h>
58#include <origin_viewitem.h>
59#include <pcb_edit_frame.h>
60#include <pcbnew_id.h>
61#include <project.h>
62#include <project/project_file.h> // LAST_PATH_TYPE
64#include <kiplatform/ui.h>
65#include <pcbnew_settings.h>
66#include <tool/tool_manager.h>
67#include <tool/tool_event.h>
68#include <tools/drawing_tool.h>
69#include <tools/pcb_actions.h>
74#include <tools/edit_tool.h>
77#include <richio.h>
78#include <router/router_tool.h>
79#include <view/view_controls.h>
80#include <view/view_group.h>
84#include <wx/filedlg.h>
85#include <wx/msgdlg.h>
86#include <wx/log.h>
87
89
90using namespace std::placeholders;
91
92
94{
95public:
97 ACTION_MENU( true )
98 {
100 SetTitle( _( "Zones" ) );
101
106
107 AppendSeparator();
108
113
114 AppendSeparator();
115
117 }
118
119protected:
120 ACTION_MENU* create() const override
121 {
122 return new ZONE_CONTEXT_MENU();
123 }
124};
125
126
146
147
149 PCB_TOOL_BASE( "pcbnew.EditorControl" ),
150 m_frame( nullptr ),
151 m_inPlaceFootprint( false ),
152 m_placingFootprint( false )
153{
154 m_placeOrigin = std::make_unique<KIGFX::ORIGIN_VIEWITEM>( KIGFX::COLOR4D( 0.8, 0.0, 0.0, 1.0 ),
156}
157
158
162
163
165{
167
168 if( aReason == MODEL_RELOAD || aReason == GAL_SWITCH || aReason == REDRAW )
169 {
170 m_placeOrigin->SetPosition( getModel<BOARD>()->GetDesignSettings().GetAuxOrigin() );
171 getView()->Remove( m_placeOrigin.get() );
172 getView()->Add( m_placeOrigin.get() );
173 }
174}
175
176// Update left-toolbar Line modes group icon based on current settings
178{
180
181 if( !f )
182 return 0;
183
184 LEADER_MODE mode = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_AngleSnapMode;
185
186 switch( mode )
187 {
190 default:
192 }
193
194 return 0;
195}
196
198{
199 LEADER_MODE mode = aEvent.Parameter<LEADER_MODE>();
200 GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_AngleSnapMode = mode;
201 m_toolMgr->PostAction( ACTIONS::refreshPreview );
203 return 0;
204}
205
206
208{
209 auto activeToolCondition =
210 [this]( const SELECTION& aSel )
211 {
212 return ( !m_frame->ToolStackIsEmpty() );
213 };
214
215 auto inactiveStateCondition =
216 [this]( const SELECTION& aSel )
217 {
218 return ( m_frame->ToolStackIsEmpty() && aSel.Size() == 0 );
219 };
220
221 auto placeModuleCondition =
222 [this]( const SELECTION& aSel )
223 {
224 return m_frame->IsCurrentTool( PCB_ACTIONS::placeFootprint ) && aSel.GetSize() == 0;
225 };
226
227 auto& ctxMenu = m_menu->GetMenu();
228
229 // "Cancel" goes at the top of the context menu when a tool is active
230 ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1 );
231 ctxMenu.AddSeparator( 1 );
232
233 // "Get and Place Footprint" should be available for Place Footprint tool
234 ctxMenu.AddItem( PCB_ACTIONS::getAndPlace, placeModuleCondition, 1000 );
235 ctxMenu.AddSeparator( 1000 );
236
237 // Finally, add the standard zoom & grid items
238 getEditFrame<PCB_BASE_FRAME>()->AddStandardSubMenus( *m_menu.get() );
239
240 std::shared_ptr<ZONE_CONTEXT_MENU> zoneMenu = std::make_shared<ZONE_CONTEXT_MENU>();
241 zoneMenu->SetTool( this );
242
243 std::shared_ptr<LOCK_CONTEXT_MENU> lockMenu = std::make_shared<LOCK_CONTEXT_MENU>( this );
244
245 // Add the PCB control menus to relevant other tools
246
247 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
248
249 if( selTool )
250 {
251 TOOL_MENU& toolMenu = selTool->GetToolMenu();
252 CONDITIONAL_MENU& menu = toolMenu.GetMenu();
253
254 // Add "Get and Place Footprint" when Selection tool is in an inactive state
255 menu.AddItem( PCB_ACTIONS::getAndPlace, inactiveStateCondition );
256 menu.AddSeparator();
257
258 toolMenu.RegisterSubMenu( zoneMenu );
259 toolMenu.RegisterSubMenu( lockMenu );
260
261 menu.AddMenu( lockMenu.get(), SELECTION_CONDITIONS::NotEmpty, 100 );
262
263 menu.AddMenu( zoneMenu.get(), SELECTION_CONDITIONS::OnlyTypes( { PCB_ZONE_T } ), 100 );
264 }
265
266 DRAWING_TOOL* drawingTool = m_toolMgr->GetTool<DRAWING_TOOL>();
267
268 if( drawingTool )
269 {
270 TOOL_MENU& toolMenu = drawingTool->GetToolMenu();
271 CONDITIONAL_MENU& menu = toolMenu.GetMenu();
272
273 toolMenu.RegisterSubMenu( zoneMenu );
274
275 // Functor to say if the PCB_EDIT_FRAME is in a given mode
276 // Capture the tool pointer and tool mode by value
277 auto toolActiveFunctor =
278 [=]( DRAWING_TOOL::MODE aMode )
279 {
280 return [=]( const SELECTION& sel )
281 {
282 return drawingTool->GetDrawingMode() == aMode;
283 };
284 };
285
286 menu.AddMenu( zoneMenu.get(), toolActiveFunctor( DRAWING_TOOL::MODE::ZONE ), 300 );
287 }
288
289 // Ensure the left toolbar's Line modes group reflects the current setting at startup
290 if( m_toolMgr )
292
293 return true;
294}
295
296
298{
299 wxWindow* focus = wxWindow::FindFocus();
300
301 if( focus )
302 {
303 wxWindow* topLevel = focus;
304
305 while( topLevel && !topLevel->IsTopLevel() )
306 topLevel = topLevel->GetParent();
307
308 RULE_EDITOR_DIALOG_BASE* reDlg = dynamic_cast<RULE_EDITOR_DIALOG_BASE*>( topLevel );
309
310 if( reDlg )
311 {
312 wxCommandEvent evt;
313 reDlg->OnSave( evt );
314 return 0;
315 }
316 }
317
318 m_frame->SaveBoard();
319 return 0;
320}
321
322
324{
325 m_frame->SaveBoard( true );
326 return 0;
327}
328
329
331{
332 m_frame->SaveBoard( true, true );
333 return 0;
334}
335
336
338{
339 m_frame->ExportFootprintsToLibrary( false );
340 return 0;
341}
342
343
345{
346 PICKED_ITEMS_LIST undoCmd;
348 ITEM_PICKER wrapper( nullptr, undoItem, UNDO_REDO::PAGESETTINGS );
349
350 undoCmd.PushItem( wrapper );
351 undoCmd.SetDescription( _( "Page Settings" ) );
352 m_frame->SaveCopyInUndoList( undoCmd, UNDO_REDO::PAGESETTINGS );
353
354 DIALOG_PAGES_SETTINGS dlg( m_frame, m_frame->GetBoard()->GetEmbeddedFiles(), pcbIUScale.IU_PER_MILS,
357
358 if( dlg.ShowModal() == wxID_OK )
359 {
360 m_frame->GetCanvas()->GetView()->UpdateAllItemsConditionally(
361 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
362 {
363 EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aItem );
364
365 if( text && text->HasTextVars() )
366 {
367 text->ClearRenderCache();
368 text->ClearBoundingBoxCache();
370 }
371
372 return 0;
373 } );
374
375 m_frame->OnModify();
376 }
377 else
378 {
379 m_frame->RollbackFromUndo();
380 }
381
382 return 0;
383}
384
385
387{
388 DIALOG_PLOT dlg( m_frame );
389 dlg.ShowQuasiModal();
390 return 0;
391}
392
393
395{
396 m_frame->ToggleSearch();
397 return 0;
398}
399
400
402{
403 m_frame->ShowFindDialog();
404 return 0;
405}
406
407
409{
410 m_frame->FindNext( aEvent.IsAction( &ACTIONS::findPrevious ) );
411 return 0;
412}
413
414
416{
417 getEditFrame<PCB_EDIT_FRAME>()->ShowBoardSetupDialog();
418 return 0;
419}
420
421
423{
424 getEditFrame<PCB_EDIT_FRAME>()->InstallNetlistFrame();
425 return 0;
426}
427
428
430{
431 wxString fullFileName = frame()->GetBoard()->GetFileName();
432 wxString path;
433 wxString name;
434 wxString ext;
435
436 wxFileName::SplitPath( fullFileName, &path, &name, &ext );
437 name += wxT( "." ) + wxString( FILEEXT::SpecctraSessionFileExtension );
438
439 fullFileName = wxFileSelector( _( "Specctra Session File" ), path, name,
440 wxT( "." ) + wxString( FILEEXT::SpecctraSessionFileExtension ),
441 FILEEXT::SpecctraSessionFileWildcard(), wxFD_OPEN | wxFD_CHANGE_DIR,
442 frame() );
443
444 if( !fullFileName.IsEmpty() )
445 getEditFrame<PCB_EDIT_FRAME>()->ImportSpecctraSession( fullFileName );
446
447 return 0;
448}
449
450
452{
453 wxString fullFileName = m_frame->GetLastPath( LAST_PATH_SPECCTRADSN );
454 wxFileName fn;
455
456 if( fullFileName.IsEmpty() )
457 {
458 fn = m_frame->GetBoard()->GetFileName();
460 }
461 else
462 {
463 fn = fullFileName;
464 }
465
466 fullFileName = wxFileSelector( _( "Specctra DSN File" ), fn.GetPath(), fn.GetFullName(),
468 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxFD_CHANGE_DIR, frame() );
469
470 if( !fullFileName.IsEmpty() )
471 {
472 m_frame->SetLastPath( LAST_PATH_SPECCTRADSN, fullFileName );
473 getEditFrame<PCB_EDIT_FRAME>()->ExportSpecctraFile( fullFileName );
474 }
475
476 return 0;
477}
478
479
481{
482 wxCHECK( m_frame, 0 );
483
484 wxFileName fn = m_frame->Prj().GetProjectFullName();
485
486 // Use a different file extension for the board netlist so the schematic netlist file
487 // is accidentally overwritten.
488 fn.SetExt( wxT( "pcb_net" ) );
489
490 wxFileDialog dlg( m_frame, _( "Export Board Netlist" ), fn.GetPath(), fn.GetFullName(),
491 _( "KiCad board netlist files" ) + AddFileExtListToFilter( { "pcb_net" } ),
492 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
493
494 dlg.SetExtraControlCreator( &LEGACYFILEDLG_NETLIST_OPTIONS::Create );
495
497
498 if( dlg.ShowModal() == wxID_CANCEL )
499 return 0;
500
501 fn = dlg.GetPath();
502
503 if( !fn.IsDirWritable() )
504 {
505 DisplayErrorMessage( m_frame, wxString::Format( _( "Insufficient permissions to folder '%s'." ),
506 fn.GetPath() ) );
507 return 0;
508 }
509
511 dynamic_cast<const LEGACYFILEDLG_NETLIST_OPTIONS*>( dlg.GetExtraControl() );
512 wxCHECK( noh, 0 );
513
515
516 for( const FOOTPRINT* footprint : board()->Footprints() )
517 {
518 COMPONENT* component = new COMPONENT( footprint->GetFPID(), footprint->GetReference(),
519 footprint->GetValue(), footprint->GetPath(),
520 { footprint->m_Uuid } );
521
522 for( const PAD* pad : footprint->Pads() )
523 {
524 const wxString& netname = pad->GetShortNetname();
525
526 if( !netname.IsEmpty() )
527 component->AddNet( pad->GetNumber(), netname, pad->GetPinFunction(), pad->GetPinType() );
528 }
529
530 nlohmann::ordered_map<wxString, wxString> fields;
531
532 for( PCB_FIELD* field : footprint->GetFields() )
533 {
534 wxCHECK2( field, continue );
535
536 fields[field->GetCanonicalName()] = field->GetText();
537 }
538
539 component->SetFields( fields );
540
541 netlist.AddComponent( component );
542 }
543
544 FILE_OUTPUTFORMATTER formatter( fn.GetFullPath() );
545
546 netlist.Format( "pcb_netlist", &formatter, 0, noh->GetNetlistOptions() );
547
548 return 0;
549}
550
551
553{
554 PCB_PLOT_PARAMS plotSettings = m_frame->GetPlotSettings();
555
556 plotSettings.SetFormat( PLOT_FORMAT::GERBER );
557
558 m_frame->SetPlotSettings( plotSettings );
559
560 DIALOG_PLOT dlg( m_frame );
561 dlg.ShowQuasiModal( );
562
563 return 0;
564}
565
566
568{
569 int errors = 0;
570 wxString details;
571 bool quiet = aEvent.Parameter<bool>();
572
573 // Repair duplicate IDs and missing nets.
574 std::set<KIID> ids;
575 int duplicates = 0;
576
577 auto processItem =
578 [&]( EDA_ITEM* aItem )
579 {
580 if( ids.count( aItem->m_Uuid ) )
581 {
582 duplicates++;
583 const_cast<KIID&>( aItem->m_Uuid ) = KIID();
584 }
585
586 ids.insert( aItem->m_Uuid );
587
588 BOARD_CONNECTED_ITEM* cItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem );
589
590 if( cItem && cItem->GetNetCode() )
591 {
592 NETINFO_ITEM* netinfo = cItem->GetNet();
593
594 if( netinfo && !board()->FindNet( netinfo->GetNetname() ) )
595 {
596 board()->Add( netinfo );
597
598 details += wxString::Format( _( "Orphaned net %s re-parented.\n" ),
599 netinfo->GetNetname() );
600 errors++;
601 }
602 }
603 };
604
605 // Footprint IDs are the most important, so give them the first crack at "claiming" a
606 // particular KIID.
607
608 for( FOOTPRINT* footprint : board()->Footprints() )
609 processItem( footprint );
610
611 // After that the principal use is for DRC marker pointers, which are most likely to pads
612 // or tracks.
613
614 for( FOOTPRINT* footprint : board()->Footprints() )
615 {
616 for( PAD* pad : footprint->Pads() )
617 processItem( pad );
618 }
619
620 for( PCB_TRACK* track : board()->Tracks() )
621 processItem( track );
622
623 // From here out I don't think order matters much.
624
625 for( FOOTPRINT* footprint : board()->Footprints() )
626 {
627 processItem( &footprint->Reference() );
628 processItem( &footprint->Value() );
629
630 for( BOARD_ITEM* item : footprint->GraphicalItems() )
631 processItem( item );
632
633 for( ZONE* zone : footprint->Zones() )
634 processItem( zone );
635
636 for( PCB_GROUP* group : footprint->Groups() )
637 processItem( group );
638 }
639
640 // Everything owned by the board not handled above
641 for( BOARD_ITEM* item : board()->GetItemSet() )
642 {
643 // Top-level footprints and tracks were handled above.
644 switch( item->Type() )
645 {
646 case PCB_FOOTPRINT_T:
647 case PCB_TRACE_T:
648 case PCB_ARC_T:
649 case PCB_VIA_T:
650 break;
651
652 default:
653 processItem( item );
654 break;
655 }
656 }
657
658 if( duplicates )
659 {
660 errors += duplicates;
661 details += wxString::Format( _( "%d duplicate IDs replaced.\n" ), duplicates );
662 }
663
664 /*******************************
665 * Your test here
666 */
667
668 /*******************************
669 * Inform the user
670 */
671
672 if( errors )
673 {
674 m_frame->OnModify();
675
676 wxString msg = wxString::Format( _( "%d potential problems repaired." ), errors );
677
678 if( !quiet )
679 DisplayInfoMessage( m_frame, msg, details );
680 }
681 else if( !quiet )
682 {
683 DisplayInfoMessage( m_frame, _( "No board problems found." ) );
684 }
685
686 return 0;
687}
688
689
691{
693 bool fetched = false;
694
696 [&]()
697 {
698 fetched = m_frame->FetchNetlistFromSchematic(
699 netlist, _( "Updating PCB requires a fully annotated schematic." ) );
700 } );
701
702 if( fetched )
703 {
704 DIALOG_UPDATE_PCB updateDialog( m_frame, &netlist );
705 updateDialog.ShowModal();
706 }
707
708 return 0;
709}
710
712{
713 if( Kiface().IsSingle() )
714 {
715 DisplayErrorMessage( m_frame, _( "Cannot update schematic because Pcbnew is opened in "
716 "stand-alone mode. In order to create or update PCBs "
717 "from schematics, you must launch the KiCad project "
718 "manager and create a project." ) );
719 return 0;
720 }
721
724
725 KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_SCH, false );
726
727 if( frame )
728 {
729 std::string payload;
730
731 if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
732 blocking_win->Close( true );
733
734 m_frame->Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_UPDATE, payload, m_frame );
735 }
736 return 0;
737}
738
739
741{
742 wxString msg;
743 PCB_EDIT_FRAME* boardFrame = m_frame;
744 PROJECT& project = boardFrame->Prj();
745 wxFileName schematic( project.GetProjectPath(), project.GetProjectName(),
747
748 if( !schematic.FileExists() )
749 {
750 wxFileName legacySchematic( project.GetProjectPath(), project.GetProjectName(),
752
753 if( legacySchematic.FileExists() )
754 {
755 schematic = legacySchematic;
756 }
757 else
758 {
759 msg.Printf( _( "Schematic file '%s' not found." ), schematic.GetFullPath() );
761 return 0;
762 }
763 }
764
765 if( Kiface().IsSingle() )
766 {
767 ExecuteFile( EESCHEMA_EXE, schematic.GetFullPath() );
768 }
769 else
770 {
772 [&]()
773 {
774 KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_SCH, false );
775
776 // Please: note: DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::initBuffers() calls
777 // Kiway.Player( FRAME_SCH, true )
778 // therefore, the schematic editor is sometimes running, but the schematic project
779 // is not loaded, if the library editor was called, and the dialog field editor was used.
780 // On Linux, it happens the first time the schematic editor is launched, if
781 // library editor was running, and the dialog field editor was open
782 // On Windows, it happens always after the library editor was called,
783 // and the dialog field editor was used
784 if( !frame )
785 {
786 try
787 {
788 frame = boardFrame->Kiway().Player( FRAME_SCH, true );
789 }
790 catch( const IO_ERROR& err )
791 {
792 DisplayErrorMessage( boardFrame,
793 _( "Eeschema failed to load." ) + wxS( "\n" ) + err.What() );
794 return;
795 }
796 }
797
798 wxEventBlocker blocker( boardFrame );
799
800 // If Kiway() cannot create the eeschema frame, it shows a error message, and
801 // frame is null
802 if( !frame )
803 return;
804
805 if( !frame->IsShownOnScreen() ) // the frame exists, (created by the dialog field editor)
806 // but no project loaded.
807 {
808 frame->OpenProjectFiles( std::vector<wxString>( 1, schematic.GetFullPath() ) );
809 frame->Show( true );
810 }
811
812 // On Windows, Raise() does not bring the window on screen, when iconized or not shown
813 // On Linux, Raise() brings the window on screen, but this code works fine
814 if( frame->IsIconized() )
815 {
816 frame->Iconize( false );
817
818 // If an iconized frame was created by Pcbnew, Iconize( false ) is not enough
819 // to show the frame at its normal size: Maximize should be called.
820 frame->Maximize( false );
821 }
822
823 frame->Raise();
824 } );
825 }
826
827 return 0;
828}
829
830
832{
833 getEditFrame<PCB_EDIT_FRAME>()->ToggleLayersManager();
834 return 0;
835}
836
837
839{
840 getEditFrame<PCB_EDIT_FRAME>()->ToggleProperties();
841 return 0;
842}
843
844
846{
847 getEditFrame<PCB_EDIT_FRAME>()->ToggleNetInspector();
848 return 0;
849}
850
851
853{
854 getEditFrame<PCB_EDIT_FRAME>()->ToggleLibraryTree();
855 return 0;
856}
857
858
860{
861 getEditFrame<PCB_EDIT_FRAME>()->ToggleSearch();
862 return 0;
863}
864
865
867{
868 m_frame->ScriptingConsoleEnableDisable();
869 return 0;
870}
871
872
873// Track & via size control
875{
876 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
877 PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
878
879 if( m_frame->ToolStackIsEmpty()
880 && SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )( selection ) )
881 {
882 BOARD_COMMIT commit( this );
883
884 for( EDA_ITEM* item : selection )
885 {
886 if( item->IsType( { PCB_TRACE_T, PCB_ARC_T } ) )
887 {
888 PCB_TRACK* track = static_cast<PCB_TRACK*>( item );
889
890 for( int i = 0; i < (int) bds.m_TrackWidthList.size(); ++i )
891 {
892 int candidate = bds.m_NetSettings->GetDefaultNetclass()->GetTrackWidth();
893
894 if( i > 0 )
895 candidate = bds.m_TrackWidthList[ i ];
896
897 if( candidate > track->GetWidth() )
898 {
899 commit.Modify( track );
900 track->SetWidth( candidate );
901 break;
902 }
903 }
904 }
905 }
906
907 commit.Push( _( "Increase Track Width" ) );
908 return 0;
909 }
910
911 ROUTER_TOOL* routerTool = m_toolMgr->GetTool<ROUTER_TOOL>();
912
913 if( routerTool && routerTool->IsToolActive()
914 && routerTool->Router()->Mode() == PNS::PNS_MODE_ROUTE_DIFF_PAIR )
915 {
916 int widthIndex = bds.GetDiffPairIndex() + 1;
917
918 // If we go past the last track width entry in the list, start over at the beginning
919 if( widthIndex >= (int) bds.m_DiffPairDimensionsList.size() )
920 widthIndex = 0;
921
922 bds.SetDiffPairIndex( widthIndex );
923 bds.UseCustomDiffPairDimensions( false );
924
926 }
927 else
928 {
929 int widthIndex = bds.GetTrackWidthIndex();
930
931 if( routerTool && routerTool->IsToolActive()
934 {
935 bds.m_TempOverrideTrackWidth = true;
936 }
937 else
938 {
939 widthIndex++;
940 }
941
942 // If we go past the last track width entry in the list, start over at the beginning
943 if( widthIndex >= (int) bds.m_TrackWidthList.size() )
944 widthIndex = 0;
945
946 bds.SetTrackWidthIndex( widthIndex );
947 bds.UseCustomTrackViaSize( false );
948
950 }
951
952 return 0;
953}
954
955
957{
958 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
959 PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
960
961 if( m_frame->ToolStackIsEmpty()
962 && SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )( selection ) )
963 {
964 BOARD_COMMIT commit( this );
965
966 for( EDA_ITEM* item : selection )
967 {
968 if( item->IsType( { PCB_TRACE_T, PCB_ARC_T } ) )
969 {
970 PCB_TRACK* track = static_cast<PCB_TRACK*>( item );
971
972 for( int i = (int) bds.m_TrackWidthList.size() - 1; i >= 0; --i )
973 {
974 int candidate = bds.m_NetSettings->GetDefaultNetclass()->GetTrackWidth();
975
976 if( i > 0 )
977 candidate = bds.m_TrackWidthList[ i ];
978
979 if( candidate < track->GetWidth() )
980 {
981 commit.Modify( track );
982 track->SetWidth( candidate );
983 break;
984 }
985 }
986 }
987 }
988
989 commit.Push( _( "Decrease Track Width" ) );
990 return 0;
991 }
992
993 ROUTER_TOOL* routerTool = m_toolMgr->GetTool<ROUTER_TOOL>();
994
995 if( routerTool && routerTool->IsToolActive()
996 && routerTool->Router()->Mode() == PNS::PNS_MODE_ROUTE_DIFF_PAIR )
997 {
998 int widthIndex = bds.GetDiffPairIndex() - 1;
999
1000 // If we get to the lowest entry start over at the highest
1001 if( widthIndex < 0 )
1002 widthIndex = bds.m_DiffPairDimensionsList.size() - 1;
1003
1004 bds.SetDiffPairIndex( widthIndex );
1005 bds.UseCustomDiffPairDimensions( false );
1006
1008 }
1009 else
1010 {
1011 int widthIndex = bds.GetTrackWidthIndex();
1012
1013 if( routerTool && routerTool->IsToolActive()
1016 {
1017 bds.m_TempOverrideTrackWidth = true;
1018 }
1019 else
1020 {
1021 widthIndex--;
1022 }
1023
1024 // If we get to the lowest entry start over at the highest
1025 if( widthIndex < 0 )
1026 widthIndex = (int) bds.m_TrackWidthList.size() - 1;
1027
1028 bds.SetTrackWidthIndex( widthIndex );
1029 bds.UseCustomTrackViaSize( false );
1030
1032 }
1033
1034 return 0;
1035}
1036
1037
1039{
1040 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1041 PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1042
1043 if( m_frame->ToolStackIsEmpty()
1044 && SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )( selection ) )
1045 {
1046 BOARD_COMMIT commit( this );
1047
1048 for( EDA_ITEM* item : selection )
1049 {
1050 if( item->Type() == PCB_VIA_T )
1051 {
1052 PCB_VIA* via = static_cast<PCB_VIA*>( item );
1053
1054 for( int i = 0; i < (int) bds.m_ViasDimensionsList.size(); ++i )
1055 {
1058
1059 if( i> 0 )
1060 dims = bds.m_ViasDimensionsList[ i ];
1061
1062 // TODO(JE) padstacks
1063 if( dims.m_Diameter > via->GetWidth( PADSTACK::ALL_LAYERS ) )
1064 {
1065 commit.Modify( via );
1066 via->SetWidth( PADSTACK::ALL_LAYERS, dims.m_Diameter );
1067 via->SetDrill( dims.m_Drill );
1068 break;
1069 }
1070 }
1071 }
1072 }
1073
1074 commit.Push( _( "Increase Via Size" ) );
1075 }
1076 else
1077 {
1078 int sizeIndex = bds.GetViaSizeIndex() + 1;
1079
1080 // If we go past the last via entry in the list, start over at the beginning
1081 if( sizeIndex >= (int) bds.m_ViasDimensionsList.size() )
1082 sizeIndex = 0;
1083
1084 bds.SetViaSizeIndex( sizeIndex );
1085 bds.UseCustomTrackViaSize( false );
1086
1088 }
1089
1090 return 0;
1091}
1092
1093
1095{
1096 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1097 PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1098
1099 if( m_frame->ToolStackIsEmpty()
1100 && SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )( selection ) )
1101 {
1102 BOARD_COMMIT commit( this );
1103
1104 for( EDA_ITEM* item : selection )
1105 {
1106 if( item->Type() == PCB_VIA_T )
1107 {
1108 PCB_VIA* via = static_cast<PCB_VIA*>( item );
1109
1110 for( int i = (int) bds.m_ViasDimensionsList.size() - 1; i >= 0; --i )
1111 {
1114
1115 if( i > 0 )
1116 dims = bds.m_ViasDimensionsList[ i ];
1117
1118 // TODO(JE) padstacks
1119 if( dims.m_Diameter < via->GetWidth( PADSTACK::ALL_LAYERS ) )
1120 {
1121 commit.Modify( via );
1122 via->SetWidth( PADSTACK::ALL_LAYERS, dims.m_Diameter );
1123 via->SetDrill( dims.m_Drill );
1124 break;
1125 }
1126 }
1127 }
1128 }
1129
1130 commit.Push( "Decrease Via Size" );
1131 }
1132 else
1133 {
1134 int sizeIndex = 0; // Assume we only have a single via size entry
1135
1136 // If there are more, cycle through them backwards
1137 if( bds.m_ViasDimensionsList.size() > 0 )
1138 {
1139 sizeIndex = bds.GetViaSizeIndex() - 1;
1140
1141 // If we get to the lowest entry start over at the highest
1142 if( sizeIndex < 0 )
1143 sizeIndex = bds.m_ViasDimensionsList.size() - 1;
1144 }
1145
1146 bds.SetViaSizeIndex( sizeIndex );
1147 bds.UseCustomTrackViaSize( false );
1148
1150 }
1151
1152 return 0;
1153}
1154
1155
1157{
1158 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1159
1160 if( bds.UseCustomTrackViaSize() )
1161 {
1162 bds.UseCustomTrackViaSize( false );
1163 bds.m_UseConnectedTrackWidth = true;
1164 }
1165 else
1166 {
1168 }
1169
1170 return 0;
1171}
1172
1173
1175{
1176 if( m_inPlaceFootprint )
1177 return 0;
1178
1180
1181 FOOTPRINT* fp = aEvent.Parameter<FOOTPRINT*>();
1182 bool fromOtherCommand = fp != nullptr;
1184 BOARD_COMMIT commit( m_frame );
1186 COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
1187
1188 m_toolMgr->RunAction( ACTIONS::selectionClear );
1189
1190 TOOL_EVENT pushedEvent = aEvent;
1191 m_frame->PushTool( aEvent );
1192
1193 auto setCursor =
1194 [&]()
1195 {
1196 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
1197 };
1198
1199 auto cleanup =
1200 [&] ()
1201 {
1202 m_toolMgr->RunAction( ACTIONS::selectionClear );
1203 commit.Revert();
1204
1205 if( fromOtherCommand )
1206 {
1207 PICKED_ITEMS_LIST* undo = m_frame->PopCommandFromUndoList();
1208
1209 if( undo )
1210 {
1211 m_frame->PutDataInPreviousState( undo );
1212 m_frame->ClearListAndDeleteItems( undo );
1213 delete undo;
1214 }
1215 }
1216
1217 fp = nullptr;
1218 m_placingFootprint = false;
1219 };
1220
1221 Activate();
1222 // Must be done after Activate() so that it gets set into the correct context
1223 controls->ShowCursor( true );
1224 // Set initial cursor
1225 setCursor();
1226
1227 VECTOR2I cursorPos = controls->GetCursorPosition();
1228 bool ignorePrimePosition = false;
1229 bool reselect = false;
1230
1231 // Prime the pump
1232 if( fp )
1233 {
1234 m_placingFootprint = true;
1235 fp->SetPosition( cursorPos );
1236 m_toolMgr->RunAction<EDA_ITEM*>( ACTIONS::selectItem, fp );
1237 m_toolMgr->PostAction( ACTIONS::refreshPreview );
1238 }
1239 else if( aEvent.HasPosition() )
1240 {
1241 m_toolMgr->PrimeTool( aEvent.Position() );
1242 }
1243 else if( common_settings->m_Input.immediate_actions && !aEvent.IsReactivate() )
1244 {
1245 m_toolMgr->PrimeTool( { 0, 0 } );
1246 ignorePrimePosition = true;
1247 }
1248
1249 // Main loop: keep receiving events
1250 while( TOOL_EVENT* evt = Wait() )
1251 {
1252 setCursor();
1253 cursorPos = controls->GetCursorPosition( !evt->DisableGridSnapping() );
1254
1255 if( reselect && fp )
1256 m_toolMgr->RunAction<EDA_ITEM*>( ACTIONS::selectItem, fp );
1257
1258 if( evt->IsCancelInteractive() || ( fp && evt->IsAction( &ACTIONS::undo ) ) )
1259 {
1260 if( fp )
1261 {
1262 cleanup();
1263 }
1264 else
1265 {
1266 m_frame->PopTool( pushedEvent );
1267 break;
1268 }
1269 }
1270 else if( evt->IsActivate() )
1271 {
1272 if( fp )
1273 cleanup();
1274
1275 if( evt->IsMoveTool() )
1276 {
1277 // leave ourselves on the stack so we come back after the move
1278 break;
1279 }
1280 else
1281 {
1282 frame()->PopTool( pushedEvent );
1283 break;
1284 }
1285 }
1286 else if( evt->IsClick( BUT_LEFT ) )
1287 {
1288 if( !fp )
1289 {
1290 // Pick the footprint to be placed
1291 fp = m_frame->SelectFootprintFromLibrary();
1292
1293 if( fp == nullptr )
1294 continue;
1295
1296 // If we started with a hotkey which has a position then warp back to that.
1297 // Otherwise update to the current mouse position pinned inside the autoscroll
1298 // boundaries.
1299 if( evt->IsPrime() && !ignorePrimePosition )
1300 {
1301 cursorPos = evt->Position();
1302 getViewControls()->WarpMouseCursor( cursorPos, true );
1303 }
1304 else
1305 {
1307 cursorPos = getViewControls()->GetMousePosition();
1308 }
1309
1310 m_placingFootprint = true;
1311
1312 fp->SetLink( niluuid );
1313
1314 fp->SetFlags( IS_NEW ); // whatever
1315
1316 // Set parent so that clearance can be loaded
1317 fp->SetParent( board );
1318 board->UpdateUserUnits( fp, m_frame->GetCanvas()->GetView() );
1319
1320 for( PAD* pad : fp->Pads() )
1321 {
1322 pad->SetLocalRatsnestVisible( m_frame->GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest );
1323
1324 // Pads in the library all have orphaned nets. Replace with Default.
1325 pad->SetNetCode( 0 );
1326 }
1327
1328 // Put it on FRONT layer,
1329 // (Can be stored flipped if the lib is an archive built from a board)
1330 if( fp->IsFlipped() )
1331 fp->Flip( fp->GetPosition(), m_frame->GetPcbNewSettings()->m_FlipDirection );
1332
1333 fp->SetOrientation( ANGLE_0 );
1334 fp->SetPosition( cursorPos );
1335
1336 commit.Add( fp );
1337 m_toolMgr->RunAction<EDA_ITEM*>( ACTIONS::selectItem, fp );
1338
1339 m_toolMgr->PostAction( ACTIONS::refreshPreview );
1340 }
1341 else
1342 {
1343 m_toolMgr->RunAction( ACTIONS::selectionClear );
1344 commit.Push( _( "Place Footprint" ) );
1345 fp = nullptr; // to indicate that there is no footprint that we currently modify
1346 m_placingFootprint = false;
1347 }
1348 }
1349 else if( evt->IsClick( BUT_RIGHT ) )
1350 {
1351 m_menu->ShowContextMenu( selection() );
1352 }
1353 else if( fp && ( evt->IsMotion() || evt->IsAction( &ACTIONS::refreshPreview ) ) )
1354 {
1355 fp->SetPosition( cursorPos );
1356 selection().SetReferencePoint( cursorPos );
1357 getView()->Update( &selection() );
1358 getView()->Update( fp );
1359 }
1360 else if( fp && evt->IsAction( &PCB_ACTIONS::properties ) )
1361 {
1362 // Calling 'Properties' action clears the selection, so we need to restore it
1363 reselect = true;
1364 }
1365 else if( fp && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
1366 || evt->IsAction( &ACTIONS::redo ) ) )
1367 {
1368 wxBell();
1369 }
1370 else
1371 {
1372 evt->SetPassEvent();
1373 }
1374
1375 // Enable autopanning and cursor capture only when there is a footprint to be placed
1376 controls->SetAutoPan( fp != nullptr );
1377 controls->CaptureCursor( fp != nullptr );
1378 }
1379
1380 controls->SetAutoPan( false );
1381 controls->CaptureCursor( false );
1382 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
1383
1384 return 0;
1385}
1386
1387
1389{
1390 return modifyLockSelected( TOGGLE );
1391}
1392
1393
1395{
1396 return modifyLockSelected( ON );
1397}
1398
1399
1401{
1402 return modifyLockSelected( OFF );
1403}
1404
1405
1407{
1408 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
1409 const PCB_SELECTION& selection = selTool->GetSelection();
1410 BOARD_COMMIT commit( m_frame );
1411
1412 if( selection.Empty() )
1413 m_toolMgr->RunAction( ACTIONS::selectionCursor );
1414
1415 // Resolve TOGGLE mode
1416 if( aMode == TOGGLE )
1417 {
1418 aMode = ON;
1419
1420 for( EDA_ITEM* item : selection )
1421 {
1422 if( !item->IsBOARD_ITEM() )
1423 continue;
1424
1425 if( static_cast<BOARD_ITEM*>( item )->IsLocked() )
1426 {
1427 aMode = OFF;
1428 break;
1429 }
1430 }
1431 }
1432
1433 for( EDA_ITEM* item : selection )
1434 {
1435 if( !item->IsBOARD_ITEM() )
1436 continue;
1437
1438 BOARD_ITEM* const board_item = static_cast<BOARD_ITEM*>( item );
1439
1440 // Disallow locking free pads - it's confusing and not persisted
1441 // through save/load anyway.
1442 if( board_item->Type() == PCB_PAD_T )
1443 continue;
1444
1445 EDA_GROUP* parent_group = board_item->GetParentGroup();
1446
1447 if( parent_group && parent_group->AsEdaItem()->Type() == PCB_GENERATOR_T )
1448 {
1449 PCB_GENERATOR* generator = static_cast<PCB_GENERATOR*>( parent_group );
1450
1451 if( generator && commit.GetStatus( generator ) != CHT_MODIFY )
1452 {
1453 commit.Modify( generator );
1454
1455 if( aMode == ON )
1456 generator->SetLocked( true );
1457 else
1458 generator->SetLocked( false );
1459 }
1460 }
1461
1462 commit.Modify( board_item );
1463
1464 if( aMode == ON )
1465 board_item->SetLocked( true );
1466 else
1467 board_item->SetLocked( false );
1468 }
1469
1470 if( !commit.Empty() )
1471 {
1472 commit.Push( aMode == ON ? _( "Lock" ) : _( "Unlock" ), SKIP_TEARDROPS );
1473
1474 m_toolMgr->PostEvent( EVENTS::SelectedEvent );
1475 m_frame->OnModify();
1476 }
1477
1478 return 0;
1479}
1480
1481
1482static bool mergeZones( EDA_DRAW_FRAME* aFrame, BOARD_COMMIT& aCommit,
1483 std::vector<ZONE*>& aOriginZones, std::vector<ZONE*>& aMergedZones )
1484{
1485 aCommit.Modify( aOriginZones[0] );
1486
1487 aOriginZones[0]->Outline()->ClearArcs();
1488
1489 for( unsigned int i = 1; i < aOriginZones.size(); i++ )
1490 {
1491 SHAPE_POLY_SET otherOutline = aOriginZones[i]->Outline()->CloneDropTriangulation();
1492 otherOutline.ClearArcs();
1493 aOriginZones[0]->Outline()->BooleanAdd( otherOutline );
1494 }
1495
1496 aOriginZones[0]->Outline()->Simplify();
1497
1498 // We should have one polygon, possibly with holes. If we end up with two polygons (either
1499 // because the intersection was a single point or because the intersection was within one of
1500 // the zone's holes) then we can't merge.
1501 if( aOriginZones[0]->Outline()->IsSelfIntersecting() || aOriginZones[0]->Outline()->OutlineCount() > 1 )
1502 {
1503 DisplayErrorMessage( aFrame, _( "Zones have insufficient overlap for merging." ) );
1504 aCommit.Revert();
1505 return false;
1506 }
1507
1508 // Adopt the highest priority from all merged zones so the result maintains
1509 // the most aggressive fill ordering.
1510 unsigned highestPriority = aOriginZones[0]->GetAssignedPriority();
1511
1512 for( unsigned int i = 1; i < aOriginZones.size(); i++ )
1513 {
1514 highestPriority = std::max( highestPriority, aOriginZones[i]->GetAssignedPriority() );
1515 aCommit.Remove( aOriginZones[i] );
1516 }
1517
1518 aOriginZones[0]->SetAssignedPriority( highestPriority );
1519
1520 aMergedZones.push_back( aOriginZones[0] );
1521
1522 aOriginZones[0]->SetLocalFlags( 1 );
1523 aOriginZones[0]->HatchBorder();
1524 aOriginZones[0]->CacheTriangulation();
1525
1526 return true;
1527}
1528
1529
1531{
1532 const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1534 BOARD_COMMIT commit( m_frame );
1535
1536 if( selection.Size() < 2 )
1537 return 0;
1538
1539 int netcode = -1;
1540
1541 ZONE* firstZone = nullptr;
1542 std::vector<ZONE*> toMerge, merged;
1543
1544 for( EDA_ITEM* item : selection )
1545 {
1546 ZONE* curr_area = dynamic_cast<ZONE*>( item );
1547
1548 if( !curr_area )
1549 continue;
1550
1551 if( !firstZone )
1552 firstZone = curr_area;
1553
1554 netcode = curr_area->GetNetCode();
1555
1556 if( firstZone->GetNetCode() != netcode )
1557 {
1558 wxLogMessage( _( "Some zone netcodes did not match and were not merged." ) );
1559 continue;
1560 }
1561
1562 if( curr_area->GetIsRuleArea() != firstZone->GetIsRuleArea() )
1563 {
1564 wxLogMessage( _( "Some zones were rule areas and were not merged." ) );
1565 continue;
1566 }
1567
1568 if( curr_area->GetLayerSet() != firstZone->GetLayerSet() )
1569 {
1570 wxLogMessage( _( "Some zone layer sets did not match and were not merged." ) );
1571 continue;
1572 }
1573
1574 bool intersects = curr_area == firstZone;
1575
1576 for( ZONE* candidate : toMerge )
1577 {
1578 if( intersects )
1579 break;
1580
1581 if( board->TestZoneIntersection( curr_area, candidate ) )
1582 intersects = true;
1583 }
1584
1585 if( !intersects )
1586 {
1587 wxLogMessage( _( "Some zones did not intersect and were not merged." ) );
1588 continue;
1589 }
1590
1591 toMerge.push_back( curr_area );
1592 }
1593
1594 m_toolMgr->RunAction( ACTIONS::selectionClear );
1595
1596 if( !toMerge.empty() )
1597 {
1598 if( mergeZones( m_frame, commit, toMerge, merged ) )
1599 {
1600 commit.Push( _( "Merge Zones" ) );
1601
1602 for( EDA_ITEM* item : merged )
1603 m_toolMgr->RunAction( ACTIONS::selectItem, item );
1604 }
1605 }
1606
1607 return 0;
1608}
1609
1610
1612{
1613 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
1614 const PCB_SELECTION& selection = selTool->GetSelection();
1615
1616 // because this pops up the zone editor, it would be confusing to handle multiple zones,
1617 // so just handle single selections containing exactly one zone
1618 if( selection.Size() != 1 )
1619 return 0;
1620
1621 ZONE* oldZone = dynamic_cast<ZONE*>( selection[0] );
1622
1623 if( !oldZone )
1624 return 0;
1625
1626 ZONE_SETTINGS zoneSettings;
1627 zoneSettings << *oldZone;
1628 int dialogResult;
1629
1630 if( oldZone->GetIsRuleArea() )
1631 dialogResult = InvokeRuleAreaEditor( m_frame, &zoneSettings, board() );
1632 else if( oldZone->IsOnCopperLayer() )
1633 dialogResult = InvokeCopperZonesEditor( m_frame, nullptr, &zoneSettings );
1634 else
1635 dialogResult = InvokeNonCopperZonesEditor( m_frame, &zoneSettings );
1636
1637 if( dialogResult != wxID_OK )
1638 return 0;
1639
1640 // duplicate the zone
1641 BOARD_COMMIT commit( m_frame );
1642
1643 std::unique_ptr<ZONE> newZone = std::make_unique<ZONE>( *oldZone );
1644 newZone->ClearSelected();
1645 newZone->UnFill();
1646 zoneSettings.ExportSetting( *newZone );
1647
1648 // If the new zone is on the same layer(s) as the initial zone,
1649 // offset it a bit so it can more easily be picked.
1650 if( oldZone->GetLayerSet() == zoneSettings.m_Layers )
1651 newZone->Move( VECTOR2I( pcbIUScale.IU_PER_MM, pcbIUScale.IU_PER_MM ) );
1652
1653 commit.Add( newZone.release() );
1654 commit.Push( _( "Duplicate Zone" ) );
1655
1656 return 0;
1657}
1658
1659
1661{
1662 doCrossProbePcbToSch( aEvent, false );
1663 return 0;
1664}
1665
1666
1668{
1669 doCrossProbePcbToSch( aEvent, true );
1670 return 0;
1671}
1672
1673
1675{
1676 // Don't get in an infinite loop PCB -> SCH -> PCB -> SCH -> ...
1677 if( m_frame->m_ProbingSchToPcb )
1678 return;
1679
1680 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
1681 const PCB_SELECTION& selection = selTool->GetSelection();
1682 EDA_ITEM* focusItem = nullptr;
1683
1684 if( aEvent.Matches( EVENTS::PointSelectedEvent ) )
1685 focusItem = selection.GetLastAddedItem();
1686
1687 m_frame->SendSelectItemsToSch( selection.GetItems(), focusItem, aForce );
1688
1689 // Update 3D viewer highlighting
1690 m_frame->Update3DView( false, frame()->GetPcbNewSettings()->m_Display.m_Live3DRefresh );
1691}
1692
1693
1695{
1696 PCB_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
1697
1698 const PCB_SELECTION& selection = selectionTool->RequestSelection(
1699 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1700 {
1701 // Iterate from the back so we don't have to worry about removals.
1702 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
1703 {
1704 if( !dynamic_cast<BOARD_CONNECTED_ITEM*>( aCollector[ i ] ) )
1705 aCollector.Remove( aCollector[ i ] );
1706 }
1707
1708 sTool->FilterCollectorForLockedItems( aCollector );
1709 } );
1710
1711 std::set<wxString> netNames;
1712 std::set<int> netCodes;
1713
1714 for( EDA_ITEM* item : selection )
1715 {
1716 const NETINFO_ITEM& net = *static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNet();
1717
1718 if( !net.HasAutoGeneratedNetname() )
1719 {
1720 netNames.insert( net.GetNetname() );
1721 netCodes.insert( net.GetNetCode() );
1722 }
1723 }
1724
1725 if( netNames.empty() )
1726 {
1727 m_frame->ShowInfoBarError( _( "Selection contains no items with labeled nets." ) );
1728 return 0;
1729 }
1730
1731 selectionTool->ClearSelection();
1732 for( const int& code : netCodes )
1733 {
1734 m_toolMgr->RunAction( PCB_ACTIONS::selectNet, code );
1735 }
1736 canvas()->ForceRefresh();
1737
1738 DIALOG_ASSIGN_NETCLASS dlg( m_frame, netNames, board()->GetNetClassAssignmentCandidates(),
1739 [this]( const std::vector<wxString>& aNetNames )
1740 {
1741 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
1742 selTool->ClearSelection();
1743
1744 for( const wxString& curr_netName : aNetNames )
1745 {
1746 int curr_netCode = board()->GetNetInfo().GetNetItem( curr_netName )->GetNetCode();
1747
1748 if( curr_netCode > 0 )
1749 selTool->SelectAllItemsOnNet( curr_netCode );
1750 }
1751
1752 canvas()->ForceRefresh();
1753 m_frame->UpdateMsgPanel();
1754 } );
1755
1756 if( dlg.ShowModal() == wxID_OK )
1757 {
1759 // Refresh UI that depends on netclasses, such as the properties panel
1761 }
1762
1763 return 0;
1764}
1765
1766
1768{
1769 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
1770 const PCB_SELECTION& selection = selTool->RequestSelection( EDIT_TOOL::FootprintFilter );
1771
1772 if( selection.Empty() )
1773 {
1774 // Giant hack: by default we assign Edit Table to the same hotkey, so give the table
1775 // tool a chance to handle it if we can't.
1776 if( PCB_EDIT_TABLE_TOOL* tableTool = m_toolMgr->GetTool<PCB_EDIT_TABLE_TOOL>() )
1777 tableTool->EditTable( aEvent );
1778
1779 return 0;
1780 }
1781
1782 FOOTPRINT* fp = selection.FirstOfKind<FOOTPRINT>();
1783
1784 if( !fp )
1785 return 0;
1786
1788
1789 if( KIWAY_PLAYER* frame = editFrame->Kiway().Player( FRAME_FOOTPRINT_EDITOR, true ) )
1790 {
1791 FOOTPRINT_EDIT_FRAME* fp_editor = static_cast<FOOTPRINT_EDIT_FRAME*>( frame );
1792
1794 fp_editor->LoadFootprintFromBoard( fp );
1795 else if( aEvent.IsAction( &PCB_ACTIONS::editLibFpInFpEditor ) )
1796 fp_editor->LoadFootprintFromLibrary( fp->GetFPID() );
1797
1798 fp_editor->Show( true );
1799 fp_editor->Raise(); // Iconize( false );
1800 }
1801
1802 if( selection.IsHover() )
1803 m_toolMgr->RunAction( ACTIONS::selectionClear );
1804
1805 return 0;
1806}
1807
1808
1810 EDA_ITEM* originViewItem, const VECTOR2D& aPosition )
1811{
1812 aFrame->GetDesignSettings().SetAuxOrigin( VECTOR2I( aPosition ) );
1813 originViewItem->SetPosition( aPosition );
1814 aView->MarkDirty();
1815 aFrame->OnModify();
1816}
1817
1818
1820{
1822 {
1823 m_frame->SaveCopyInUndoList( m_placeOrigin.get(), UNDO_REDO::GRIDORIGIN );
1825 return 0;
1826 }
1827
1828 if( aEvent.IsAction( &PCB_ACTIONS::drillSetOrigin ) )
1829 {
1830 VECTOR2I origin = aEvent.Parameter<VECTOR2I>();
1831 m_frame->SaveCopyInUndoList( m_placeOrigin.get(), UNDO_REDO::GRIDORIGIN );
1832 DoSetDrillOrigin( getView(), m_frame, m_placeOrigin.get(), origin );
1833 return 0;
1834 }
1835
1836 PCB_PICKER_TOOL* picker = m_toolMgr->GetTool<PCB_PICKER_TOOL>();
1837
1838 // Deactivate other tools; particularly important if another PICKER is currently running
1839 Activate();
1840
1841 picker->SetCursor( KICURSOR::PLACE );
1842 picker->ClearHandlers();
1843
1844 picker->SetClickHandler(
1845 [this] ( const VECTOR2D& pt ) -> bool
1846 {
1847 m_frame->SaveCopyInUndoList( m_placeOrigin.get(), UNDO_REDO::DRILLORIGIN );
1849 return false; // drill origin is a one-shot; don't continue with tool
1850 } );
1851
1852 m_toolMgr->RunAction( ACTIONS::pickerTool, &aEvent );
1853
1854 return 0;
1855}
1856
1857
1859{
1868
1873
1880
1881 if( ADVANCED_CFG::GetCfg().m_ShowPcbnewExportNetlist && m_frame && m_frame->GetExportNetlistAction() )
1882 Go( &BOARD_EDITOR_CONTROL::ExportNetlist, m_frame->GetExportNetlistAction()->MakeEvent() );
1883
1892
1899
1900 // Track & via size control
1906
1907 // Zone actions
1910
1911 // Placing tools
1916
1919
1920 // Cross-select
1926
1927 // Other
1931
1933
1944 // Line modes: explicit, next, and notification
1949}
const char * name
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:112
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
#define SKIP_TEARDROPS
static bool mergeZones(EDA_DRAW_FRAME *aFrame, BOARD_COMMIT &aCommit, std::vector< ZONE * > &aOriginZones, std::vector< ZONE * > &aMergedZones)
static TOOL_ACTION updatePcbFromSchematic
Definition actions.h:264
static TOOL_ACTION cancelInteractive
Definition actions.h:72
static TOOL_ACTION revert
Definition actions.h:62
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition actions.h:227
static TOOL_ACTION saveAs
Definition actions.h:59
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
Definition actions.h:217
static TOOL_ACTION pickerTool
Definition actions.h:253
static TOOL_ACTION findPrevious
Definition actions.h:120
static TOOL_ACTION plot
Definition actions.h:65
static TOOL_ACTION open
Definition actions.h:57
static TOOL_ACTION findNext
Definition actions.h:119
static TOOL_ACTION pageSettings
Definition actions.h:63
static TOOL_ACTION showSearch
Definition actions.h:116
static TOOL_ACTION undo
Definition actions.h:75
static TOOL_ACTION save
Definition actions.h:58
static TOOL_ACTION redo
Definition actions.h:76
static TOOL_ACTION updateSchematicFromPcb
Definition actions.h:265
static TOOL_ACTION selectionClear
Clear the current selection.
Definition actions.h:224
static TOOL_ACTION showProperties
Definition actions.h:266
static TOOL_ACTION doNew
Definition actions.h:54
static TOOL_ACTION saveCopy
Definition actions.h:60
static TOOL_ACTION refreshPreview
Definition actions.h:159
static TOOL_ACTION find
Definition actions.h:117
ACTION_MENU(bool isContextMenu, TOOL_INTERACTIVE *aTool=nullptr)
Default constructor.
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:85
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
virtual 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 #NET_INFO 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
void SetViaSizeIndex(int aIndex)
Set the current via size list index to aIndex.
std::vector< DIFF_PAIR_DIMENSION > m_DiffPairDimensionsList
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.
std::vector< int > m_TrackWidthList
std::vector< VIA_DIMENSION > m_ViasDimensionsList
int ExportNetlist(const TOOL_EVENT &aEvent)
int UnlockSelected(const TOOL_EVENT &aEvent)
Run the drill origin tool for setting the origin for drill and pick-and-place files.
int Save(const TOOL_EVENT &aEvent)
int ImportNetlist(const TOOL_EVENT &aEvent)
int GenerateDrillFiles(const TOOL_EVENT &aEvent)
int ZoneMerge(const TOOL_EVENT &aEvent)
Duplicate a zone onto a layer (prompts for new layer)
int CrossProbeToSch(const TOOL_EVENT &aEvent)
Equivalent to the above, but initiated by the user.
int TogglePythonConsole(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)
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)
int ToggleNetInspector(const TOOL_EVENT &aEvent)
int UpdateSchematicFromPCB(const TOOL_EVENT &aEvent)
int ExplicitCrossProbeToSch(const TOOL_EVENT &aEvent)
Assign a netclass to a labelled net.
int ExportHyperlynx(const TOOL_EVENT &aEvent)
int ToggleSearch(const TOOL_EVENT &aEvent)
int DrillOrigin(const TOOL_EVENT &aEvent)
Low-level access (below undo) to setting the drill origin.
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)
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 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 modifyLockSelected(MODIFY_MODE aMode)
Set up handlers for various events.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
int TrackWidthInc(const TOOL_EVENT &aEvent)
int GenerateODBPPFiles(const TOOL_EVENT &aEvent)
int ToggleLockSelected(const TOOL_EVENT &aEvent)
Lock selected items.
int AutoTrackWidth(const TOOL_EVENT &aEvent)
int LockSelected(const TOOL_EVENT &aEvent)
Unlock selected items.
int PageSettings(const TOOL_EVENT &aEvent)
int ExportSpecctraDSN(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)
Notify Eeschema about selected items.
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:84
void SetLocked(bool aLocked) override
Definition board_item.h:328
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:322
const NETINFO_LIST & GetNetInfo() const
Definition board.h:996
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1223
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:2681
int GetCount() const
Return the number of objects in the list.
Definition collector.h:83
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition collector.h:111
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
Definition commit.h:90
bool Empty() const
Definition commit.h:137
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:106
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition commit.h:78
int GetStatus(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Returns status of an item.
Definition commit.cpp:171
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:41
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 MODE::NONE if not currently in any drawing mod...
void SelectToolbarAction(const TOOL_ACTION &aAction)
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:46
virtual EDA_ITEM * AsEdaItem()=0
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:99
virtual void SetPosition(const VECTOR2I &aPos)
Definition eda_item.h:279
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition eda_item.h:148
virtual EDA_GROUP * GetParentGroup() const
Definition eda_item.h:117
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:111
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:93
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:80
static const TOOL_EVENT ClearedEvent
Definition actions.h:347
static const TOOL_EVENT SelectedEvent
Definition actions.h:345
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition actions.h:352
static const TOOL_EVENT PointSelectedEvent
Definition actions.h:344
static const TOOL_EVENT UnselectedEvent
Definition actions.h:346
Used for text file output.
Definition richio.h:469
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:1074
void SetOrientation(const EDA_ANGLE &aNewAngle)
std::deque< PAD * > & Pads()
Definition footprint.h:306
bool IsFlipped() const
Definition footprint.h:524
const LIB_ID & GetFPID() const
Definition footprint.h:351
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
VECTOR2I GetPosition() const override
Definition footprint.h:327
Used when the right click button is pressed, or when the select tool is in effect.
Definition collectors.h:207
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:105
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:86
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:67
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition view.cpp:300
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:343
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:1727
void MarkDirty()
Force redraw of view on the next rendering.
Definition view.h:668
Definition kiid.h:49
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:407
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:133
int GetViaDrill() const
Definition netclass.h:141
int GetTrackWidth() const
Definition netclass.h:125
Handle the data for a net.
Definition netinfo.h:54
const wxString & GetNetname() const
Definition netinfo.h:112
int GetNetCode() const
Definition netinfo.h:106
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()
Gets the default netclass for the project.
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Definition padstack.h:177
Definition pad.h:55
static TOOL_ACTION lineModeFree
Unconstrained angle mode (icon lines_any)
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 viaSizeInc
static TOOL_ACTION angleSnapModeChanged
Notification event when angle mode changes.
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 generateGerbers
static TOOL_ACTION generateReportFile
static TOOL_ACTION exportHyperlynx
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 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 showPythonConsole
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.
A set of BOARD_ITEMs (i.e., without duplicates).
Definition pcb_group.h:53
void SetLocked(bool aLocked) override
Generic tool for picking an item.
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.
int ClearSelection(const TOOL_EVENT &aEvent)
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:90
virtual int GetWidth() const
Definition pcb_track.h:91
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:547
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:64
ROUTER_MODE Mode() const
Definition pns_router.h:154
RouterState GetState() const
Definition pns_router.h:156
ROUTER * Router() const
Container for project specific data.
Definition project.h:65
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.
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.
T * getEditFrame() const
Return the application window object, casted to requested user type.
Definition tool_base.h:186
T * getModel() const
Return the model object if it matches the requested type.
Definition tool_base.h:198
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
bool IsToolActive() const
Definition tool_base.cpp:32
RESET_REASON
Determine the reason of reset for a tool.
Definition tool_base.h:78
@ REDRAW
Full drawing refresh.
Definition tool_base.h:83
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition tool_base.h:80
@ GAL_SWITCH
Rendering engine changes.
Definition tool_base.h:82
Generic, UI-independent tool event.
Definition tool_event.h:171
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:260
bool Matches(const TOOL_EVENT &aEvent) const
Test whether two events match in terms of category & action or command.
Definition tool_event.h:392
const VECTOR2D Position() const
Return mouse cursor position in world coordinates.
Definition tool_event.h:293
bool IsReactivate() const
Control whether the tool is first being pushed to the stack or being reactivated after a pause.
Definition tool_event.h:273
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
T Parameter() const
Return a parameter assigned to the event.
Definition tool_event.h:473
void 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.
Manage a CONDITIONAL_MENU and some number of CONTEXT_MENUs as sub-menus.
Definition tool_menu.h:43
CONDITIONAL_MENU & GetMenu()
Definition tool_menu.cpp:44
void RegisterSubMenu(std::shared_ptr< ACTION_MENU > aSubMenu)
Store a submenu of this menu model.
Definition tool_menu.cpp:50
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)
ZONE_SETTINGS handles zones parameters.
void ExportSetting(ZONE &aTarget, bool aFullExport=true) const
Function ExportSetting copy settings to a given zone.
Handle a list of polygons defining a copper zone.
Definition zone.h:73
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition zone.h:719
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition zone.h:136
bool IsOnCopperLayer() const override
Definition zone.cpp:543
@ CHT_MODIFY
Definition commit.h:44
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition confirm.cpp:230
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:202
This file is part of the common library.
@ PLACE
Definition cursors.h:98
@ ARROW
Definition cursors.h:46
@ PENCIL
Definition cursors.h:52
int InvokeCopperZonesEditor(PCB_BASE_FRAME *aCaller, ZONE *aZone, ZONE_SETTINGS *aSettings, CONVERT_SETTINGS *aConvertSettings)
Function InvokeCopperZonesEditor invokes up a modal dialog window for copper zone editing.
int InvokeNonCopperZonesEditor(PCB_BASE_FRAME *aParent, ZONE_SETTINGS *aSettings, CONVERT_SETTINGS *aConvertSettings)
Function InvokeNonCopperZonesEditor invokes up a modal dialog window for non-copper zone editing.
int InvokeRuleAreaEditor(PCB_BASE_FRAME *aCaller, ZONE_SETTINGS *aZoneSettings, BOARD *aBoard, CONVERT_SETTINGS *aConvertSettings)
Function InvokeRuleAreaEditor invokes up a modal dialog window for copper zone editing.
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
#define IS_NEW
New item, just created.
KiCad executable names.
const wxString EESCHEMA_EXE
@ FRAME_SCH
Definition frame_type.h:34
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:43
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:146
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:47
@ REPAINT
Item needs to be redrawn.
Definition view_item.h:58
@ GEOMETRY
Position or shape has changed.
Definition view_item.h:55
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:435
@ PNS_MODE_ROUTE_DIFF_PAIR
Definition pns_router.h:69
#define MAX_PAGE_SIZE_PCBNEW_MILS
Definition page_info.h:35
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 path
@ BUT_LEFT
Definition tool_event.h:132
@ BUT_RIGHT
Definition tool_event.h:133
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
Definition typeinfo.h:91
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:97
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:86
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:87
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition typeinfo.h:98
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition typeinfo.h:96
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
VECTOR2< double > VECTOR2D
Definition vector2d.h:694
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.