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 <footprint.h>
42#include <pad.h>
43#include <pcb_target.h>
44#include <pcb_track.h>
45#include <zone.h>
46#include <pcb_marker.h>
47#include <confirm.h>
51#include <dialog_plot.h>
54#include <kiface_base.h>
55#include <kiway.h>
57#include <origin_viewitem.h>
58#include <pcb_edit_frame.h>
59#include <pcbnew_id.h>
60#include <project.h>
61#include <project/project_file.h> // LAST_PATH_TYPE
63#include <kiplatform/ui.h>
64#include <pcbnew_settings.h>
65#include <tool/tool_manager.h>
66#include <tool/tool_event.h>
67#include <tools/drawing_tool.h>
68#include <tools/pcb_actions.h>
73#include <tools/edit_tool.h>
76#include <richio.h>
77#include <router/router_tool.h>
78#include <view/view_controls.h>
79#include <view/view_group.h>
83#include <wx/filedlg.h>
84#include <wx/msgdlg.h>
85#include <wx/log.h>
86
88
89using namespace std::placeholders;
90
91
92namespace
93{
94
95using ZonePriorityMap = std::map<unsigned, std::vector<ZONE*>>;
96
97
98std::vector<ZONE*> getOverlappingZones( BOARD* aBoard, ZONE* aZone )
99{
100 std::vector<ZONE*> overlapping;
101 BOX2I bbox = aZone->GetBoundingBox();
102
103 for( ZONE* candidate : aBoard->Zones() )
104 {
105 if( candidate == aZone )
106 continue;
107
108 if( candidate->GetIsRuleArea() || candidate->IsTeardropArea() )
109 continue;
110
111 if( !( candidate->GetLayerSet() & aZone->GetLayerSet() ).any() )
112 continue;
113
114 if( !candidate->GetBoundingBox().Intersects( bbox ) )
115 continue;
116
117 // Check edge collision and containment (one zone entirely inside another)
118 SHAPE_POLY_SET aOutline = aZone->GetBoardOutline();
119 SHAPE_POLY_SET candidateOutline = candidate->GetBoardOutline();
120
121 if( aOutline.Collide( &candidateOutline )
122 || ( candidateOutline.TotalVertices() > 0 && aOutline.Contains( candidateOutline.CVertex( 0 ) ) )
123 || ( aOutline.TotalVertices() > 0 && candidateOutline.Contains( aOutline.CVertex( 0 ) ) ) )
124 {
125 overlapping.push_back( candidate );
126 }
127 }
128
129 return overlapping;
130}
131
132
133ZonePriorityMap buildPriorityMap( BOARD* aBoard, ZONE* aExclude )
134{
135 ZonePriorityMap byPriority;
136
137 for( ZONE* z : aBoard->Zones() )
138 {
139 if( z == aExclude || z->GetIsRuleArea() || z->IsTeardropArea() )
140 continue;
141
142 byPriority[z->GetAssignedPriority()].push_back( z );
143 }
144
145 return byPriority;
146}
147
148
161std::vector<ZONE*> findCascadeZones( const ZonePriorityMap& aByPriority,
162 unsigned aFromPriority, bool aCascadeUp,
163 bool& aViable )
164{
165 std::vector<ZONE*> result;
166 unsigned p = aFromPriority;
167 aViable = true;
168
169 for( auto it = aByPriority.find( p ); it != aByPriority.end();
170 it = aByPriority.find( p ) )
171 {
172 for( ZONE* z : it->second )
173 result.push_back( z );
174
175 if( aCascadeUp )
176 {
177 if( p == UINT_MAX )
178 {
179 aViable = false;
180 break;
181 }
182
183 p++;
184 }
185 else
186 {
187 if( p == 0 )
188 {
189 aViable = false;
190 break;
191 }
192
193 p--;
194 }
195 }
196
197 return result;
198}
199
200} // anonymous namespace
201
202
204{
205public:
217
218protected:
219 ACTION_MENU* create() const override
220 {
221 return new ZONE_PRIORITY_CONTEXT_MENU();
222 }
223
224 void update() override
225 {
227
228 if( !selTool )
229 return;
230
231 const PCB_SELECTION& selection = selTool->GetSelection();
232 bool canRaise = false;
233 bool canLower = false;
234
235 if( selection.Size() == 1 )
236 {
237 ZONE* zone = dynamic_cast<ZONE*>( selection[0] );
238
239 if( zone && !zone->GetIsRuleArea() && !zone->IsTeardropArea() )
240 {
241 BOARD* board = zone->GetBoard();
242 std::vector<ZONE*> overlapping = getOverlappingZones( board, zone );
243
244 for( ZONE* other : overlapping )
245 {
246 if( other->GetAssignedPriority() > zone->GetAssignedPriority() )
247 canRaise = true;
248
249 if( other->GetAssignedPriority() < zone->GetAssignedPriority() )
250 canLower = true;
251 }
252 }
253 }
254
255 Enable( PCB_ACTIONS::zonePriorityMoveToTop.GetUIId(), canRaise );
256 Enable( PCB_ACTIONS::zonePriorityRaise.GetUIId(), canRaise );
257 Enable( PCB_ACTIONS::zonePriorityLower.GetUIId(), canLower );
258 Enable( PCB_ACTIONS::zonePriorityMoveToBottom.GetUIId(), canLower );
259 }
260};
261
262
264{
265public:
267 ACTION_MENU( true )
268 {
270 SetTitle( _( "Zones" ) );
271
276
277 AppendSeparator();
278
283
284 AppendSeparator();
285
287
288 AppendSeparator();
289
291 }
292
293protected:
294 ACTION_MENU* create() const override
295 {
296 return new ZONE_CONTEXT_MENU();
297 }
298};
299
300
302{
303public:
314
315 ACTION_MENU* create() const override
316 {
317 return new LOCK_CONTEXT_MENU( this->m_tool );
318 }
319};
320
321
323 PCB_TOOL_BASE( "pcbnew.EditorControl" ),
324 m_frame( nullptr ),
325 m_inPlaceFootprint( false ),
326 m_placingFootprint( false )
327{
328 m_placeOrigin = std::make_unique<KIGFX::ORIGIN_VIEWITEM>( KIGFX::COLOR4D( 0.8, 0.0, 0.0, 1.0 ),
330}
331
332
336
337
339{
341
342 if( aReason == MODEL_RELOAD || aReason == GAL_SWITCH || aReason == REDRAW )
343 {
344 m_placeOrigin->SetPosition( getModel<BOARD>()->GetDesignSettings().GetAuxOrigin() );
345 getView()->Remove( m_placeOrigin.get() );
346 getView()->Add( m_placeOrigin.get() );
347 }
348}
349
350// Update left-toolbar Line modes group icon based on current settings
352{
354
355 if( !f )
356 return 0;
357
358 LEADER_MODE mode = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_AngleSnapMode;
359
360 switch( mode )
361 {
364 default:
366 }
367
368 return 0;
369}
370
372{
373 LEADER_MODE mode = aEvent.Parameter<LEADER_MODE>();
374 GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_AngleSnapMode = mode;
375 m_toolMgr->PostAction( ACTIONS::refreshPreview );
377 return 0;
378}
379
380
382{
383 auto activeToolCondition =
384 [this]( const SELECTION& aSel )
385 {
386 return ( !m_frame->ToolStackIsEmpty() );
387 };
388
389 auto inactiveStateCondition =
390 [this]( const SELECTION& aSel )
391 {
392 return ( m_frame->ToolStackIsEmpty() && aSel.Size() == 0 );
393 };
394
395 auto placeModuleCondition =
396 [this]( const SELECTION& aSel )
397 {
398 return m_frame->IsCurrentTool( PCB_ACTIONS::placeFootprint ) && aSel.GetSize() == 0;
399 };
400
401 auto& ctxMenu = m_menu->GetMenu();
402
403 // "Cancel" goes at the top of the context menu when a tool is active
404 ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1 );
405 ctxMenu.AddSeparator( 1 );
406
407 // "Get and Place Footprint" should be available for Place Footprint tool
408 ctxMenu.AddItem( PCB_ACTIONS::getAndPlace, placeModuleCondition, 1000 );
409 ctxMenu.AddSeparator( 1000 );
410
411 // Finally, add the standard zoom & grid items
412 getEditFrame<PCB_BASE_FRAME>()->AddStandardSubMenus( *m_menu.get() );
413
414 std::shared_ptr<ZONE_CONTEXT_MENU> zoneMenu = std::make_shared<ZONE_CONTEXT_MENU>();
415 zoneMenu->SetTool( this );
416
417 std::shared_ptr<LOCK_CONTEXT_MENU> lockMenu = std::make_shared<LOCK_CONTEXT_MENU>( this );
418
419 // Add the PCB control menus to relevant other tools
420
421 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
422
423 if( selTool )
424 {
425 TOOL_MENU& toolMenu = selTool->GetToolMenu();
426 CONDITIONAL_MENU& menu = toolMenu.GetMenu();
427
428 // Add "Get and Place Footprint" when Selection tool is in an inactive state
429 menu.AddItem( PCB_ACTIONS::getAndPlace, inactiveStateCondition );
430 menu.AddSeparator();
431
432 toolMenu.RegisterSubMenu( zoneMenu );
433 toolMenu.RegisterSubMenu( lockMenu );
434
435 menu.AddMenu( lockMenu.get(), SELECTION_CONDITIONS::NotEmpty, 100 );
436
437 menu.AddMenu( zoneMenu.get(), SELECTION_CONDITIONS::OnlyTypes( { PCB_ZONE_T } ), 100 );
438 }
439
440 DRAWING_TOOL* drawingTool = m_toolMgr->GetTool<DRAWING_TOOL>();
441
442 if( drawingTool )
443 {
444 TOOL_MENU& toolMenu = drawingTool->GetToolMenu();
445 CONDITIONAL_MENU& menu = toolMenu.GetMenu();
446
447 toolMenu.RegisterSubMenu( zoneMenu );
448
449 // Functor to say if the PCB_EDIT_FRAME is in a given mode
450 // Capture the tool pointer and tool mode by value
451 auto toolActiveFunctor =
452 [=]( DRAWING_TOOL::MODE aMode )
453 {
454 return [=]( const SELECTION& sel )
455 {
456 return drawingTool->GetDrawingMode() == aMode;
457 };
458 };
459
460 menu.AddMenu( zoneMenu.get(), toolActiveFunctor( DRAWING_TOOL::MODE::ZONE ), 300 );
461 }
462
463 // Ensure the left toolbar's Line modes group reflects the current setting at startup
464 if( m_toolMgr )
466
467 return true;
468}
469
470
472{
473 wxWindow* focus = wxWindow::FindFocus();
474
475 if( focus )
476 {
477 wxWindow* topLevel = focus;
478
479 while( topLevel && !topLevel->IsTopLevel() )
480 topLevel = topLevel->GetParent();
481
482 RULE_EDITOR_DIALOG_BASE* reDlg = dynamic_cast<RULE_EDITOR_DIALOG_BASE*>( topLevel );
483
484 if( reDlg )
485 {
486 wxCommandEvent evt;
487 reDlg->OnSave( evt );
488 return 0;
489 }
490 }
491
492 m_frame->SaveBoard();
493 return 0;
494}
495
496
498{
499 m_frame->SaveBoard( true );
500 return 0;
501}
502
503
505{
506 m_frame->SaveBoard( true, true );
507 return 0;
508}
509
510
512{
513 m_frame->ExportFootprintsToLibrary( false );
514 return 0;
515}
516
517
519{
520 PICKED_ITEMS_LIST undoCmd;
522 ITEM_PICKER wrapper( nullptr, undoItem, UNDO_REDO::PAGESETTINGS );
523
524 undoCmd.PushItem( wrapper );
525 undoCmd.SetDescription( _( "Page Settings" ) );
526 m_frame->SaveCopyInUndoList( undoCmd, UNDO_REDO::PAGESETTINGS );
527
528 DIALOG_PAGES_SETTINGS dlg( m_frame, m_frame->GetBoard()->GetEmbeddedFiles(), pcbIUScale.IU_PER_MILS,
531
532 if( dlg.ShowModal() == wxID_OK )
533 {
534 m_frame->GetCanvas()->GetView()->UpdateAllItemsConditionally(
535 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
536 {
537 EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aItem );
538
539 if( text && text->HasTextVars() )
540 {
541 text->ClearRenderCache();
542 text->ClearBoundingBoxCache();
544 }
545
546 return 0;
547 } );
548
549 m_frame->OnModify();
550 }
551 else
552 {
553 m_frame->RollbackFromUndo();
554 }
555
556 return 0;
557}
558
559
561{
562 DIALOG_PLOT dlg( m_frame );
563 dlg.ShowQuasiModal();
564 return 0;
565}
566
567
569{
570 m_frame->ToggleSearch();
571 return 0;
572}
573
574
576{
577 m_frame->ShowFindDialog();
578 return 0;
579}
580
581
583{
584 m_frame->FindNext( aEvent.IsAction( &ACTIONS::findPrevious ) );
585 return 0;
586}
587
588
590{
591 m_frame->ShowFindByPropertiesDialog();
592 return 0;
593}
594
595
597{
598 getEditFrame<PCB_EDIT_FRAME>()->ShowBoardSetupDialog();
599 return 0;
600}
601
602
604{
605 getEditFrame<PCB_EDIT_FRAME>()->InstallNetlistFrame();
606 return 0;
607}
608
609
611{
612 wxString fullFileName = frame()->GetBoard()->GetFileName();
613 wxString path;
614 wxString name;
615 wxString ext;
616
617 wxFileName::SplitPath( fullFileName, &path, &name, &ext );
618 name += wxT( "." ) + wxString( FILEEXT::SpecctraSessionFileExtension );
619
620 fullFileName = wxFileSelector( _( "Specctra Session File" ), path, name,
621 wxT( "." ) + wxString( FILEEXT::SpecctraSessionFileExtension ),
622 FILEEXT::SpecctraSessionFileWildcard(), wxFD_OPEN | wxFD_CHANGE_DIR,
623 frame() );
624
625 if( !fullFileName.IsEmpty() )
626 getEditFrame<PCB_EDIT_FRAME>()->ImportSpecctraSession( fullFileName );
627
628 return 0;
629}
630
631
633{
634 wxString fullFileName = m_frame->GetLastPath( LAST_PATH_SPECCTRADSN );
635 wxFileName fn;
636
637 if( fullFileName.IsEmpty() )
638 {
639 fn = m_frame->GetBoard()->GetFileName();
641 }
642 else
643 {
644 fn = fullFileName;
645 }
646
647 fullFileName = wxFileSelector( _( "Specctra DSN File" ), fn.GetPath(), fn.GetFullName(),
649 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxFD_CHANGE_DIR, frame() );
650
651 if( !fullFileName.IsEmpty() )
652 {
653 m_frame->SetLastPath( LAST_PATH_SPECCTRADSN, fullFileName );
654 getEditFrame<PCB_EDIT_FRAME>()->ExportSpecctraFile( fullFileName );
655 }
656
657 return 0;
658}
659
660
662{
663 wxCHECK( m_frame, 0 );
664
665 wxFileName fn = m_frame->Prj().GetProjectFullName();
666
667 // Use a different file extension for the board netlist so the schematic netlist file
668 // is accidentally overwritten.
669 fn.SetExt( wxT( "pcb_net" ) );
670
671 wxFileDialog dlg( m_frame, _( "Export Board Netlist" ), fn.GetPath(), fn.GetFullName(),
672 _( "KiCad board netlist files" ) + AddFileExtListToFilter( { "pcb_net" } ),
673 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
674
675 dlg.SetExtraControlCreator( &LEGACYFILEDLG_NETLIST_OPTIONS::Create );
676
678
679 if( dlg.ShowModal() == wxID_CANCEL )
680 return 0;
681
682 fn = dlg.GetPath();
683
684 if( !fn.IsDirWritable() )
685 {
686 DisplayErrorMessage( m_frame, wxString::Format( _( "Insufficient permissions to folder '%s'." ),
687 fn.GetPath() ) );
688 return 0;
689 }
690
692 dynamic_cast<const LEGACYFILEDLG_NETLIST_OPTIONS*>( dlg.GetExtraControl() );
693 wxCHECK( noh, 0 );
694
696
697 for( const FOOTPRINT* footprint : board()->Footprints() )
698 {
699 COMPONENT* component = new COMPONENT( footprint->GetFPID(), footprint->GetReference(),
700 footprint->GetValue(), footprint->GetPath(),
701 { footprint->m_Uuid } );
702
703 for( const PAD* pad : footprint->Pads() )
704 {
705 const wxString& netname = pad->GetShortNetname();
706
707 if( !netname.IsEmpty() )
708 component->AddNet( pad->GetNumber(), netname, pad->GetPinFunction(), pad->GetPinType() );
709 }
710
711 nlohmann::ordered_map<wxString, wxString> fields;
712
713 for( PCB_FIELD* field : footprint->GetFields() )
714 {
715 wxCHECK2( field, continue );
716
717 fields[field->GetCanonicalName()] = field->GetText();
718 }
719
720 component->SetFields( fields );
721
722 netlist.AddComponent( component );
723 }
724
725 try
726 {
727 FILE_OUTPUTFORMATTER formatter( fn.GetFullPath() );
728
729 netlist.Format( "pcb_netlist", &formatter, 0, noh->GetNetlistOptions() );
730 formatter.Finish();
731 }
732 catch( const IO_ERROR& ioe )
733 {
734 DisplayErrorMessage( m_frame, wxString::Format( _( "Failed to export netlist to '%s': %s" ),
735 fn.GetFullPath(), ioe.What() ) );
736 }
737
738 return 0;
739}
740
741
743{
744 PCB_PLOT_PARAMS plotSettings = m_frame->GetPlotSettings();
745
746 plotSettings.SetFormat( PLOT_FORMAT::GERBER );
747
748 m_frame->SetPlotSettings( plotSettings );
749
750 DIALOG_PLOT dlg( m_frame );
751 dlg.ShowQuasiModal( );
752
753 return 0;
754}
755
756
758{
759 int errors = 0;
760 wxString details;
761 bool quiet = aEvent.Parameter<bool>();
762
763 int duplicates = board()->RepairDuplicateItemUuids();
764
765 if( duplicates )
766 {
767 errors += duplicates;
768 details += wxString::Format( _( "%d duplicate IDs replaced.\n" ), duplicates );
769 }
770
771 for( FOOTPRINT* footprint : board()->Footprints() )
772 {
773 for( PAD* pad : footprint->Pads() )
774 {
775 BOARD_CONNECTED_ITEM* cItem = pad;
776
777 if( cItem->GetNetCode() )
778 {
779 NETINFO_ITEM* netinfo = cItem->GetNet();
780
781 if( netinfo && !board()->FindNet( netinfo->GetNetname() ) )
782 {
783 board()->Add( netinfo );
784
785 details += wxString::Format( _( "Orphaned net %s re-parented.\n" ),
786 netinfo->GetNetname() );
787 errors++;
788 }
789 }
790 }
791 }
792
793 for( PCB_TRACK* track : board()->Tracks() )
794 {
795 BOARD_CONNECTED_ITEM* cItem = track;
796
797 if( cItem->GetNetCode() )
798 {
799 NETINFO_ITEM* netinfo = cItem->GetNet();
800
801 if( netinfo && !board()->FindNet( netinfo->GetNetname() ) )
802 {
803 board()->Add( netinfo );
804
805 details += wxString::Format( _( "Orphaned net %s re-parented.\n" ),
806 netinfo->GetNetname() );
807 errors++;
808 }
809 }
810 }
811
812 /*******************************
813 * Your test here
814 */
815
816 /*******************************
817 * Inform the user
818 */
819
820 if( errors )
821 {
822 m_frame->OnModify();
823
824 wxString msg = wxString::Format( _( "%d potential problems repaired." ), errors );
825
826 if( !quiet )
827 DisplayInfoMessage( m_frame, msg, details );
828 }
829 else if( !quiet )
830 {
831 DisplayInfoMessage( m_frame, _( "No board problems found." ) );
832 }
833
834 return 0;
835}
836
837
839{
841 bool fetched = false;
842
844 [&]()
845 {
846 fetched = m_frame->FetchNetlistFromSchematic(
847 netlist, _( "Updating PCB requires a fully annotated schematic." ) );
848 } );
849
850 if( fetched )
851 {
852 DIALOG_UPDATE_PCB updateDialog( m_frame, &netlist );
853 updateDialog.ShowModal();
854 }
855
856 return 0;
857}
858
860{
861 if( Kiface().IsSingle() )
862 {
863 DisplayErrorMessage( m_frame, _( "Cannot update schematic because Pcbnew is opened in "
864 "stand-alone mode. In order to create or update PCBs "
865 "from schematics, you must launch the KiCad project "
866 "manager and create a project." ) );
867 return 0;
868 }
869
872
873 KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_SCH, false );
874
875 if( frame )
876 {
877 std::string payload;
878
879 if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
880 blocking_win->Close( true );
881
882 m_frame->Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_UPDATE, payload, m_frame );
883 }
884 return 0;
885}
886
887
889{
890 wxString msg;
891 PCB_EDIT_FRAME* boardFrame = m_frame;
892 PROJECT& project = boardFrame->Prj();
893 wxFileName schematic( project.GetProjectPath(), project.GetProjectName(),
895
896 if( !schematic.FileExists() )
897 {
898 wxFileName legacySchematic( project.GetProjectPath(), project.GetProjectName(),
900
901 if( legacySchematic.FileExists() )
902 {
903 schematic = legacySchematic;
904 }
905 else
906 {
907 msg.Printf( _( "Schematic file '%s' not found." ), schematic.GetFullPath() );
909 return 0;
910 }
911 }
912
913 if( Kiface().IsSingle() )
914 {
915 ExecuteFile( EESCHEMA_EXE, schematic.GetFullPath() );
916 }
917 else
918 {
920 [&]()
921 {
922 KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_SCH, false );
923
924 // Please: note: DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::initBuffers() calls
925 // Kiway.Player( FRAME_SCH, true )
926 // therefore, the schematic editor is sometimes running, but the schematic project
927 // is not loaded, if the library editor was called, and the dialog field editor was used.
928 // On Linux, it happens the first time the schematic editor is launched, if
929 // library editor was running, and the dialog field editor was open
930 // On Windows, it happens always after the library editor was called,
931 // and the dialog field editor was used
932 if( !frame )
933 {
934 try
935 {
936 frame = boardFrame->Kiway().Player( FRAME_SCH, true );
937 }
938 catch( const IO_ERROR& err )
939 {
940 DisplayErrorMessage( boardFrame,
941 _( "Eeschema failed to load." ) + wxS( "\n" ) + err.What() );
942 return;
943 }
944 }
945
946 wxEventBlocker blocker( boardFrame );
947
948 // If Kiway() cannot create the eeschema frame, it shows a error message, and
949 // frame is null
950 if( !frame )
951 return;
952
953 if( !frame->IsShownOnScreen() ) // the frame exists, (created by the dialog field editor)
954 // but no project loaded.
955 {
956 frame->OpenProjectFiles( std::vector<wxString>( 1, schematic.GetFullPath() ) );
957 frame->Show( true );
958 }
959
960 // On Windows, Raise() does not bring the window on screen, when iconized or not shown
961 // On Linux, Raise() brings the window on screen, but this code works fine
962 if( frame->IsIconized() )
963 {
964 frame->Iconize( false );
965
966 // If an iconized frame was created by Pcbnew, Iconize( false ) is not enough
967 // to show the frame at its normal size: Maximize should be called.
968 frame->Maximize( false );
969 }
970
971 frame->Raise();
972 } );
973 }
974
975 return 0;
976}
977
978
980{
981 getEditFrame<PCB_EDIT_FRAME>()->ToggleLayersManager();
982 return 0;
983}
984
985
987{
988 getEditFrame<PCB_EDIT_FRAME>()->ToggleProperties();
989 return 0;
990}
991
992
994{
995 getEditFrame<PCB_EDIT_FRAME>()->ToggleNetInspector();
996 return 0;
997}
998
999
1001{
1002 getEditFrame<PCB_EDIT_FRAME>()->ToggleLibraryTree();
1003 return 0;
1004}
1005
1006
1008{
1009 getEditFrame<PCB_EDIT_FRAME>()->ToggleSearch();
1010 return 0;
1011}
1012
1013
1014// Track & via size control
1016{
1017 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1018 PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1019
1020 if( m_frame->ToolStackIsEmpty()
1021 && SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )( selection ) )
1022 {
1023 BOARD_COMMIT commit( this );
1024
1025 for( EDA_ITEM* item : selection )
1026 {
1027 if( item->IsType( { PCB_TRACE_T, PCB_ARC_T } ) )
1028 {
1029 PCB_TRACK* track = static_cast<PCB_TRACK*>( item );
1030
1031 for( int i = 0; i < (int) bds.m_TrackWidthList.size(); ++i )
1032 {
1033 int candidate = bds.m_NetSettings->GetDefaultNetclass()->GetTrackWidth();
1034
1035 if( i > 0 )
1036 candidate = bds.m_TrackWidthList[ i ];
1037
1038 if( candidate > track->GetWidth() )
1039 {
1040 commit.Modify( track );
1041 track->SetWidth( candidate );
1042 break;
1043 }
1044 }
1045 }
1046 }
1047
1048 commit.Push( _( "Increase Track Width" ) );
1049 return 0;
1050 }
1051
1052 ROUTER_TOOL* routerTool = m_toolMgr->GetTool<ROUTER_TOOL>();
1053
1054 if( routerTool && routerTool->IsToolActive()
1055 && routerTool->Router()->Mode() == PNS::PNS_MODE_ROUTE_DIFF_PAIR )
1056 {
1057 int widthIndex = bds.GetNextDiffPairIndex( bds.GetDiffPairIndex(), true );
1058
1059 bds.SetDiffPairIndex( widthIndex );
1060 bds.UseCustomDiffPairDimensions( false );
1061
1063 }
1064 else
1065 {
1066 // Issue #24644: stepping the index unconditionally lets the first press both enter the
1067 // connected-width override and advance into the list, instead of no-op'ing.
1068 if( routerTool && routerTool->IsToolActive()
1071 {
1072 bds.m_TempOverrideTrackWidth = true;
1073 }
1074
1076 bds.UseCustomTrackViaSize( false );
1077
1079 }
1080
1081 return 0;
1082}
1083
1084
1086{
1087 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1088 PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1089
1090 if( m_frame->ToolStackIsEmpty()
1091 && SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )( selection ) )
1092 {
1093 BOARD_COMMIT commit( this );
1094
1095 for( EDA_ITEM* item : selection )
1096 {
1097 if( item->IsType( { PCB_TRACE_T, PCB_ARC_T } ) )
1098 {
1099 PCB_TRACK* track = static_cast<PCB_TRACK*>( item );
1100
1101 for( int i = (int) bds.m_TrackWidthList.size() - 1; i >= 0; --i )
1102 {
1103 int candidate = bds.m_NetSettings->GetDefaultNetclass()->GetTrackWidth();
1104
1105 if( i > 0 )
1106 candidate = bds.m_TrackWidthList[ i ];
1107
1108 if( candidate < track->GetWidth() )
1109 {
1110 commit.Modify( track );
1111 track->SetWidth( candidate );
1112 break;
1113 }
1114 }
1115 }
1116 }
1117
1118 commit.Push( _( "Decrease Track Width" ) );
1119 return 0;
1120 }
1121
1122 ROUTER_TOOL* routerTool = m_toolMgr->GetTool<ROUTER_TOOL>();
1123
1124 if( routerTool && routerTool->IsToolActive()
1125 && routerTool->Router()->Mode() == PNS::PNS_MODE_ROUTE_DIFF_PAIR )
1126 {
1127 int widthIndex = bds.GetNextDiffPairIndex( bds.GetDiffPairIndex(), false );
1128
1129 bds.SetDiffPairIndex( widthIndex );
1130 bds.UseCustomDiffPairDimensions( false );
1131
1133 }
1134 else
1135 {
1136 // Issue #24644: mirror TrackWidthInc so the first invocation also advances into the
1137 // predefined list instead of merely flipping the override flag.
1138 if( routerTool && routerTool->IsToolActive()
1141 {
1142 bds.m_TempOverrideTrackWidth = true;
1143 }
1144
1146 bds.UseCustomTrackViaSize( false );
1147
1149 }
1150
1151 return 0;
1152}
1153
1154
1156{
1157 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1158 PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1159
1160 if( m_frame->ToolStackIsEmpty()
1161 && SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )( selection ) )
1162 {
1163 BOARD_COMMIT commit( this );
1164
1165 for( EDA_ITEM* item : selection )
1166 {
1167 if( item->Type() == PCB_VIA_T )
1168 {
1169 PCB_VIA* via = static_cast<PCB_VIA*>( item );
1170
1171 for( int i = 0; i < (int) bds.m_ViasDimensionsList.size(); ++i )
1172 {
1175
1176 if( i> 0 )
1177 dims = bds.m_ViasDimensionsList[ i ];
1178
1179 // TODO(JE) padstacks
1180 if( dims.m_Diameter > via->GetWidth( PADSTACK::ALL_LAYERS ) )
1181 {
1182 commit.Modify( via );
1183 via->SetWidth( PADSTACK::ALL_LAYERS, dims.m_Diameter );
1184 via->SetDrill( dims.m_Drill );
1185 break;
1186 }
1187 }
1188 }
1189 }
1190
1191 commit.Push( _( "Increase Via Size" ) );
1192 }
1193 else
1194 {
1195 int sizeIndex = bds.GetNextViaSizeIndex( bds.GetViaSizeIndex(), true );
1196
1197 bds.SetViaSizeIndex( sizeIndex );
1198 bds.UseCustomTrackViaSize( false );
1199
1201 }
1202
1203 return 0;
1204}
1205
1206
1208{
1209 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1210 PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1211
1212 if( m_frame->ToolStackIsEmpty()
1213 && SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )( selection ) )
1214 {
1215 BOARD_COMMIT commit( this );
1216
1217 for( EDA_ITEM* item : selection )
1218 {
1219 if( item->Type() == PCB_VIA_T )
1220 {
1221 PCB_VIA* via = static_cast<PCB_VIA*>( item );
1222
1223 for( int i = (int) bds.m_ViasDimensionsList.size() - 1; i >= 0; --i )
1224 {
1227
1228 if( i > 0 )
1229 dims = bds.m_ViasDimensionsList[ i ];
1230
1231 // TODO(JE) padstacks
1232 if( dims.m_Diameter < via->GetWidth( PADSTACK::ALL_LAYERS ) )
1233 {
1234 commit.Modify( via );
1235 via->SetWidth( PADSTACK::ALL_LAYERS, dims.m_Diameter );
1236 via->SetDrill( dims.m_Drill );
1237 break;
1238 }
1239 }
1240 }
1241 }
1242
1243 commit.Push( "Decrease Via Size" );
1244 }
1245 else
1246 {
1247 int sizeIndex = 0; // Assume we only have a single via size entry
1248
1249 // If there are more, cycle through them backwards
1250 if( bds.m_ViasDimensionsList.size() > 0 )
1251 sizeIndex = bds.GetNextViaSizeIndex( bds.GetViaSizeIndex(), false );
1252
1253 bds.SetViaSizeIndex( sizeIndex );
1254 bds.UseCustomTrackViaSize( false );
1255
1257 }
1258
1259 return 0;
1260}
1261
1262
1264{
1265 BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->GetDesignSettings();
1266
1267 if( bds.UseCustomTrackViaSize() )
1268 {
1269 bds.UseCustomTrackViaSize( false );
1270 bds.m_UseConnectedTrackWidth = true;
1271 }
1272 else
1273 {
1275 }
1276
1277 return 0;
1278}
1279
1280
1282{
1283 if( m_inPlaceFootprint )
1284 return 0;
1285
1287
1288 FOOTPRINT* fp = aEvent.Parameter<FOOTPRINT*>();
1289 bool fromOtherCommand = fp != nullptr;
1291 BOARD_COMMIT commit( m_frame );
1293 COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
1294
1295 m_toolMgr->RunAction( ACTIONS::selectionClear );
1296
1297 TOOL_EVENT pushedEvent = aEvent;
1298 m_frame->PushTool( aEvent );
1299
1300 auto setCursor =
1301 [&]()
1302 {
1303 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
1304 };
1305
1306 auto cleanup =
1307 [&] ()
1308 {
1309 m_toolMgr->RunAction( ACTIONS::selectionClear );
1310 commit.Revert();
1311
1312 if( fromOtherCommand )
1313 {
1314 PICKED_ITEMS_LIST* undo = m_frame->PopCommandFromUndoList();
1315
1316 if( undo )
1317 {
1318 m_frame->PutDataInPreviousState( undo );
1319 m_frame->ClearListAndDeleteItems( undo );
1320 delete undo;
1321 }
1322 }
1323
1324 fp = nullptr;
1325 m_placingFootprint = false;
1326 };
1327
1328 Activate();
1329 // Must be done after Activate() so that it gets set into the correct context
1330 controls->ShowCursor( true );
1331 // Set initial cursor
1332 setCursor();
1333
1334 VECTOR2I cursorPos = controls->GetCursorPosition();
1335 bool ignorePrimePosition = false;
1336 bool reselect = false;
1337
1338 // Prime the pump
1339 if( fp )
1340 {
1341 m_placingFootprint = true;
1342 fp->SetPosition( cursorPos );
1343 m_toolMgr->RunAction<EDA_ITEM*>( ACTIONS::selectItem, fp );
1344 m_toolMgr->PostAction( ACTIONS::refreshPreview );
1345 }
1346 else if( aEvent.HasPosition() )
1347 {
1348 m_toolMgr->PrimeTool( aEvent.Position() );
1349 }
1350 else if( common_settings->m_Input.immediate_actions && !aEvent.IsReactivate() )
1351 {
1352 m_toolMgr->PrimeTool( { 0, 0 } );
1353 ignorePrimePosition = true;
1354 }
1355
1356 // Main loop: keep receiving events
1357 while( TOOL_EVENT* evt = Wait() )
1358 {
1359 setCursor();
1360 cursorPos = controls->GetCursorPosition( !evt->DisableGridSnapping() );
1361
1362 if( reselect && fp )
1363 m_toolMgr->RunAction<EDA_ITEM*>( ACTIONS::selectItem, fp );
1364
1365 if( evt->IsCancelInteractive() || ( fp && evt->IsAction( &ACTIONS::undo ) ) )
1366 {
1367 if( fp )
1368 {
1369 cleanup();
1370 }
1371 else
1372 {
1373 m_frame->PopTool( pushedEvent );
1374 break;
1375 }
1376 }
1377 else if( evt->IsActivate() )
1378 {
1379 if( fp )
1380 cleanup();
1381
1382 if( evt->IsMoveTool() )
1383 {
1384 // leave ourselves on the stack so we come back after the move
1385 break;
1386 }
1387 else
1388 {
1389 frame()->PopTool( pushedEvent );
1390 break;
1391 }
1392 }
1393 else if( evt->IsClick( BUT_LEFT ) )
1394 {
1395 if( !fp )
1396 {
1397 // Pick the footprint to be placed
1398 fp = m_frame->SelectFootprintFromLibrary();
1399
1400 if( fp == nullptr )
1401 continue;
1402
1403 // If we started with a hotkey which has a position then warp back to that.
1404 // Otherwise update to the current mouse position pinned inside the autoscroll
1405 // boundaries.
1406 if( evt->IsPrime() && !ignorePrimePosition )
1407 {
1408 cursorPos = evt->Position();
1409 getViewControls()->WarpMouseCursor( cursorPos, true );
1410 }
1411 else
1412 {
1414 cursorPos = getViewControls()->GetMousePosition();
1415 }
1416
1417 m_placingFootprint = true;
1418
1419 fp->SetLink( niluuid );
1420
1421 fp->SetFlags( IS_NEW ); // whatever
1422
1423 // Set parent so that clearance can be loaded
1424 fp->SetParent( board );
1425 board->UpdateUserUnits( fp, m_frame->GetCanvas()->GetView() );
1426
1427 for( PAD* pad : fp->Pads() )
1428 {
1429 pad->SetLocalRatsnestVisible( m_frame->GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest );
1430
1431 // Pads in the library all have orphaned nets. Replace with Default.
1432 pad->SetNetCode( 0 );
1433 }
1434
1435 // Put it on FRONT layer,
1436 // (Can be stored flipped if the lib is an archive built from a board)
1437 if( fp->IsFlipped() )
1438 fp->Flip( fp->GetPosition(), m_frame->GetPcbNewSettings()->m_FlipDirection );
1439
1440 fp->SetOrientation( ANGLE_0 );
1441 fp->SetPosition( cursorPos );
1442
1443 commit.Add( fp );
1444 m_toolMgr->RunAction<EDA_ITEM*>( ACTIONS::selectItem, fp );
1445
1446 m_toolMgr->PostAction( ACTIONS::refreshPreview );
1447 }
1448 else
1449 {
1450 m_toolMgr->RunAction( ACTIONS::selectionClear );
1451 commit.Push( _( "Place Footprint" ) );
1452 fp = nullptr; // to indicate that there is no footprint that we currently modify
1453 m_placingFootprint = false;
1454 }
1455 }
1456 else if( evt->IsClick( BUT_RIGHT ) )
1457 {
1458 m_menu->ShowContextMenu( selection() );
1459 }
1460 else if( fp && ( evt->IsMotion() || evt->IsAction( &ACTIONS::refreshPreview ) ) )
1461 {
1462 fp->SetPosition( cursorPos );
1463 selection().SetReferencePoint( cursorPos );
1464 getView()->Update( &selection() );
1465 getView()->Update( fp );
1466 }
1467 else if( fp && evt->IsAction( &PCB_ACTIONS::properties ) )
1468 {
1469 // Calling 'Properties' action clears the selection, so we need to restore it
1470 reselect = true;
1471 }
1472 else if( fp && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
1473 || evt->IsAction( &ACTIONS::redo ) ) )
1474 {
1475 wxBell();
1476 }
1477 else
1478 {
1479 evt->SetPassEvent();
1480 }
1481
1482 // Enable autopanning and cursor capture only when there is a footprint to be placed
1483 controls->SetAutoPan( fp != nullptr );
1484 controls->CaptureCursor( fp != nullptr );
1485 }
1486
1487 controls->SetAutoPan( false );
1488 controls->CaptureCursor( false );
1489 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
1490
1491 return 0;
1492}
1493
1494
1496{
1497 return modifyLockSelected( TOGGLE );
1498}
1499
1500
1502{
1503 return modifyLockSelected( ON );
1504}
1505
1506
1508{
1509 return modifyLockSelected( OFF );
1510}
1511
1512
1514{
1515 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
1516
1517 // RequestSelection populates from the cursor when empty and marks it IsHover(), letting us
1518 // clear it afterwards without disturbing a pre-existing selection.
1519 const PCB_SELECTION& selection = selTool->RequestSelection( nullptr );
1520
1521 BOARD_COMMIT commit( m_frame );
1522
1523 if( selection.Empty() )
1524 return 0;
1525
1526 const bool isHover = selection.IsHover();
1527
1528 // Resolve TOGGLE mode
1529 if( aMode == TOGGLE )
1530 {
1531 aMode = ON;
1532
1533 for( EDA_ITEM* item : selection )
1534 {
1535 if( !item->IsBOARD_ITEM() )
1536 continue;
1537
1538 if( static_cast<BOARD_ITEM*>( item )->IsLocked() )
1539 {
1540 aMode = OFF;
1541 break;
1542 }
1543 }
1544 }
1545
1546 for( EDA_ITEM* item : selection )
1547 {
1548 if( !item->IsBOARD_ITEM() )
1549 continue;
1550
1551 BOARD_ITEM* const board_item = static_cast<BOARD_ITEM*>( item );
1552
1553 // Disallow locking free pads - it's confusing and not persisted
1554 // through save/load anyway.
1555 if( board_item->Type() == PCB_PAD_T )
1556 continue;
1557
1558 EDA_GROUP* parent_group = board_item->GetParentGroup();
1559
1560 if( parent_group && parent_group->AsEdaItem()->Type() == PCB_GENERATOR_T )
1561 {
1562 PCB_GENERATOR* generator = static_cast<PCB_GENERATOR*>( parent_group );
1563
1564 if( generator && commit.GetStatus( generator ) != CHT_MODIFY )
1565 {
1566 commit.Modify( generator );
1567
1568 if( aMode == ON )
1569 generator->SetLocked( true );
1570 else
1571 generator->SetLocked( false );
1572 }
1573 }
1574
1575 commit.Modify( board_item );
1576
1577 if( aMode == ON )
1578 board_item->SetLocked( true );
1579 else
1580 board_item->SetLocked( false );
1581 }
1582
1583 if( !commit.Empty() )
1584 {
1585 commit.Push( aMode == ON ? _( "Lock" ) : _( "Unlock" ), SKIP_TEARDROPS );
1586
1587 m_toolMgr->PostEvent( EVENTS::SelectedEvent );
1588 m_frame->OnModify();
1589 }
1590
1591 if( isHover )
1592 m_toolMgr->RunAction( ACTIONS::selectionClear );
1593
1594 return 0;
1595}
1596
1597
1598static bool mergeZones( EDA_DRAW_FRAME* aFrame, BOARD_COMMIT& aCommit,
1599 std::vector<ZONE*>& aOriginZones, std::vector<ZONE*>& aMergedZones )
1600{
1601 aCommit.Modify( aOriginZones[0] );
1602
1603 aOriginZones[0]->Outline()->ClearArcs();
1604
1605 for( unsigned int i = 1; i < aOriginZones.size(); i++ )
1606 {
1607 SHAPE_POLY_SET otherOutline = aOriginZones[i]->Outline()->CloneDropTriangulation();
1608 otherOutline.ClearArcs();
1609 aOriginZones[0]->Outline()->BooleanAdd( otherOutline );
1610 }
1611
1612 aOriginZones[0]->Outline()->Simplify();
1613
1614 // We should have one polygon, possibly with holes. If we end up with two polygons (either
1615 // because the intersection was a single point or because the intersection was within one of
1616 // the zone's holes) then we can't merge.
1617 if( aOriginZones[0]->Outline()->IsSelfIntersecting() || aOriginZones[0]->Outline()->OutlineCount() > 1 )
1618 {
1619 DisplayErrorMessage( aFrame, _( "Zones have insufficient overlap for merging." ) );
1620 aCommit.Revert();
1621 return false;
1622 }
1623
1624 // Adopt the highest priority from all merged zones so the result maintains
1625 // the most aggressive fill ordering.
1626 unsigned highestPriority = aOriginZones[0]->GetAssignedPriority();
1627
1628 for( unsigned int i = 1; i < aOriginZones.size(); i++ )
1629 {
1630 highestPriority = std::max( highestPriority, aOriginZones[i]->GetAssignedPriority() );
1631 aCommit.Remove( aOriginZones[i] );
1632 }
1633
1634 aOriginZones[0]->SetAssignedPriority( highestPriority );
1635
1636 aMergedZones.push_back( aOriginZones[0] );
1637
1638 aOriginZones[0]->SetLocalFlags( 1 );
1639 aOriginZones[0]->HatchBorder();
1640 aOriginZones[0]->CacheTriangulation();
1641
1642 return true;
1643}
1644
1645
1647{
1648 const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1650 BOARD_COMMIT commit( m_frame );
1651
1652 if( selection.Size() < 2 )
1653 return 0;
1654
1655 int netcode = -1;
1656
1657 ZONE* firstZone = nullptr;
1658 std::vector<ZONE*> toMerge, merged;
1659
1660 for( EDA_ITEM* item : selection )
1661 {
1662 ZONE* curr_area = dynamic_cast<ZONE*>( item );
1663
1664 if( !curr_area )
1665 continue;
1666
1667 if( !firstZone )
1668 firstZone = curr_area;
1669
1670 netcode = curr_area->GetNetCode();
1671
1672 if( firstZone->GetNetCode() != netcode )
1673 {
1674 wxLogMessage( _( "Some zone netcodes did not match and were not merged." ) );
1675 continue;
1676 }
1677
1678 if( curr_area->GetIsRuleArea() != firstZone->GetIsRuleArea() )
1679 {
1680 wxLogMessage( _( "Some zones were rule areas and were not merged." ) );
1681 continue;
1682 }
1683
1684 if( curr_area->GetLayerSet() != firstZone->GetLayerSet() )
1685 {
1686 wxLogMessage( _( "Some zone layer sets did not match and were not merged." ) );
1687 continue;
1688 }
1689
1690 bool intersects = curr_area == firstZone;
1691
1692 for( ZONE* candidate : toMerge )
1693 {
1694 if( intersects )
1695 break;
1696
1697 if( board->TestZoneIntersection( curr_area, candidate ) )
1698 intersects = true;
1699 }
1700
1701 if( !intersects )
1702 {
1703 wxLogMessage( _( "Some zones did not intersect and were not merged." ) );
1704 continue;
1705 }
1706
1707 toMerge.push_back( curr_area );
1708 }
1709
1710 m_toolMgr->RunAction( ACTIONS::selectionClear );
1711
1712 if( !toMerge.empty() )
1713 {
1714 if( mergeZones( m_frame, commit, toMerge, merged ) )
1715 {
1716 commit.Push( _( "Merge Zones" ) );
1717
1718 for( EDA_ITEM* item : merged )
1719 m_toolMgr->RunAction( ACTIONS::selectItem, item );
1720 }
1721 }
1722
1723 return 0;
1724}
1725
1726
1728{
1729 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
1730 const PCB_SELECTION& selection = selTool->GetSelection();
1731
1732 // because this pops up the zone editor, it would be confusing to handle multiple zones,
1733 // so just handle single selections containing exactly one zone
1734 if( selection.Size() != 1 )
1735 return 0;
1736
1737 ZONE* oldZone = dynamic_cast<ZONE*>( selection[0] );
1738
1739 if( !oldZone )
1740 return 0;
1741
1742 ZONE_SETTINGS zoneSettings;
1743 zoneSettings << *oldZone;
1744 int dialogResult;
1745
1746 if( oldZone->GetIsRuleArea() )
1747 dialogResult = InvokeRuleAreaEditor( m_frame, &zoneSettings, board() );
1748 else if( oldZone->IsOnCopperLayer() )
1749 dialogResult = InvokeCopperZonesEditor( m_frame, nullptr, &zoneSettings );
1750 else
1751 dialogResult = InvokeNonCopperZonesEditor( m_frame, &zoneSettings );
1752
1753 if( dialogResult != wxID_OK )
1754 return 0;
1755
1756 // duplicate the zone
1757 BOARD_COMMIT commit( m_frame );
1758
1759 std::unique_ptr<ZONE> newZone = std::make_unique<ZONE>( *oldZone );
1760 newZone->ClearSelected();
1761 newZone->UnFill();
1762 zoneSettings.ExportSetting( *newZone );
1763
1764 if( !newZone->GetZoneName().IsEmpty() )
1765 newZone->SetZoneName( board()->GetUniqueZoneName( newZone->GetZoneName() ) );
1766
1767 // If the new zone is on the same layer(s) as the initial zone,
1768 // offset it a bit so it can more easily be picked.
1769 if( oldZone->GetLayerSet() == zoneSettings.m_Layers )
1770 newZone->Move( VECTOR2I( pcbIUScale.IU_PER_MM, pcbIUScale.IU_PER_MM ) );
1771
1772 commit.Add( newZone.release() );
1773 commit.Push( _( "Duplicate Zone" ) );
1774
1775 return 0;
1776}
1777
1778
1780{
1781 const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1782
1783 if( selection.Size() != 1 )
1784 return 0;
1785
1786 ZONE* zone = dynamic_cast<ZONE*>( selection[0] );
1787
1788 if( !zone || zone->GetIsRuleArea() || zone->IsTeardropArea() )
1789 return 0;
1790
1791 std::vector<ZONE*> overlapping = getOverlappingZones( board(), zone );
1792
1793 unsigned maxOverlapping = zone->GetAssignedPriority();
1794
1795 for( ZONE* other : overlapping )
1796 maxOverlapping = std::max( maxOverlapping, other->GetAssignedPriority() );
1797
1798 if( zone->GetAssignedPriority() >= maxOverlapping )
1799 return 0;
1800
1801 // Two options to place our zone above all overlapping zones.
1802 // Pick whichever viable option displaces fewer other zones.
1803 ZonePriorityMap byPriority = buildPriorityMap( board(), zone );
1804
1805 // Option A: take maxOverlapping, cascade displaced zones down
1806 bool cascadeDownViable = false;
1807 std::vector<ZONE*> cascadeDown =
1808 findCascadeZones( byPriority, maxOverlapping, false, cascadeDownViable );
1809
1810 // Option B: take maxOverlapping + 1, cascade displaced zones up
1811 bool cascadeUpViable = false;
1812 std::vector<ZONE*> cascadeUp;
1813 bool canCascadeUp = ( maxOverlapping < UINT_MAX );
1814
1815 if( canCascadeUp )
1816 cascadeUp = findCascadeZones( byPriority, maxOverlapping + 1, true, cascadeUpViable );
1817
1818 if( !cascadeDownViable && !cascadeUpViable )
1819 return 0;
1820
1821 BOARD_COMMIT commit( m_frame );
1822 commit.Modify( zone );
1823
1824 bool useDown = cascadeDownViable
1825 && ( !cascadeUpViable || cascadeDown.size() <= cascadeUp.size() );
1826
1827 if( useDown )
1828 {
1829 zone->SetAssignedPriority( maxOverlapping );
1830
1831 for( ZONE* z : cascadeDown )
1832 {
1833 commit.Modify( z );
1835 z->SetNeedRefill( true );
1836 }
1837 }
1838 else
1839 {
1840 zone->SetAssignedPriority( maxOverlapping + 1 );
1841
1842 for( ZONE* z : cascadeUp )
1843 {
1844 commit.Modify( z );
1846 z->SetNeedRefill( true );
1847 }
1848 }
1849
1850 zone->SetNeedRefill( true );
1851 commit.Push( _( "Move Zone to Top Priority" ) );
1852
1853 return 0;
1854}
1855
1856
1858{
1859 const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1860
1861 if( selection.Size() != 1 )
1862 return 0;
1863
1864 ZONE* zone = dynamic_cast<ZONE*>( selection[0] );
1865
1866 if( !zone || zone->GetIsRuleArea() || zone->IsTeardropArea() )
1867 return 0;
1868
1869 std::vector<ZONE*> overlapping = getOverlappingZones( board(), zone );
1870
1871 // Find the overlapping zone with the lowest priority still above ours
1872 ZONE* target = nullptr;
1873 unsigned zonePriority = zone->GetAssignedPriority();
1874
1875 for( ZONE* other : overlapping )
1876 {
1877 if( other->GetAssignedPriority() > zonePriority )
1878 {
1879 if( !target || other->GetAssignedPriority() < target->GetAssignedPriority() )
1880 target = other;
1881 }
1882 }
1883
1884 if( !target )
1885 return 0;
1886
1887 BOARD_COMMIT commit( m_frame );
1888 commit.Modify( zone );
1889
1890 // Place our zone just above the target without modifying any other zone
1891 if( target->GetAssignedPriority() < UINT_MAX )
1892 {
1893 zone->SetAssignedPriority( target->GetAssignedPriority() + 1 );
1894 }
1895 else
1896 {
1897 // Can't go above UINT_MAX; swap as last resort
1898 commit.Modify( target );
1899 zone->SetAssignedPriority( UINT_MAX );
1900 target->SetAssignedPriority( zonePriority );
1901 target->SetNeedRefill( true );
1902 }
1903
1904 zone->SetNeedRefill( true );
1905 commit.Push( _( "Raise Zone Priority" ) );
1906
1907 return 0;
1908}
1909
1910
1912{
1913 const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1914
1915 if( selection.Size() != 1 )
1916 return 0;
1917
1918 ZONE* zone = dynamic_cast<ZONE*>( selection[0] );
1919
1920 if( !zone || zone->GetIsRuleArea() || zone->IsTeardropArea() )
1921 return 0;
1922
1923 std::vector<ZONE*> overlapping = getOverlappingZones( board(), zone );
1924
1925 // Find the overlapping zone with the highest priority still below ours
1926 ZONE* target = nullptr;
1927 unsigned zonePriority = zone->GetAssignedPriority();
1928
1929 for( ZONE* other : overlapping )
1930 {
1931 if( other->GetAssignedPriority() < zonePriority )
1932 {
1933 if( !target || other->GetAssignedPriority() > target->GetAssignedPriority() )
1934 target = other;
1935 }
1936 }
1937
1938 if( !target )
1939 return 0;
1940
1941 BOARD_COMMIT commit( m_frame );
1942 commit.Modify( zone );
1943
1944 // Place our zone just below the target without modifying any other zone
1945 if( target->GetAssignedPriority() > 0 )
1946 {
1947 zone->SetAssignedPriority( target->GetAssignedPriority() - 1 );
1948 }
1949 else
1950 {
1951 // Can't go below 0; swap as last resort
1952 commit.Modify( target );
1953 zone->SetAssignedPriority( 0 );
1954 target->SetAssignedPriority( zonePriority );
1955 target->SetNeedRefill( true );
1956 }
1957
1958 zone->SetNeedRefill( true );
1959 commit.Push( _( "Lower Zone Priority" ) );
1960
1961 return 0;
1962}
1963
1964
1966{
1967 const PCB_SELECTION& selection = m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
1968
1969 if( selection.Size() != 1 )
1970 return 0;
1971
1972 ZONE* zone = dynamic_cast<ZONE*>( selection[0] );
1973
1974 if( !zone || zone->GetIsRuleArea() || zone->IsTeardropArea() )
1975 return 0;
1976
1977 std::vector<ZONE*> overlapping = getOverlappingZones( board(), zone );
1978
1979 unsigned minOverlapping = zone->GetAssignedPriority();
1980
1981 for( ZONE* other : overlapping )
1982 minOverlapping = std::min( minOverlapping, other->GetAssignedPriority() );
1983
1984 if( zone->GetAssignedPriority() <= minOverlapping )
1985 return 0;
1986
1987 // Two options to place our zone below all overlapping zones.
1988 // Pick whichever viable option displaces fewer other zones.
1989 ZonePriorityMap byPriority = buildPriorityMap( board(), zone );
1990
1991 // Option A: take minOverlapping, cascade displaced zones up
1992 bool cascadeUpViable = false;
1993 std::vector<ZONE*> cascadeUp =
1994 findCascadeZones( byPriority, minOverlapping, true, cascadeUpViable );
1995
1996 // Option B: take minOverlapping - 1, cascade displaced zones down
1997 bool cascadeDownViable = false;
1998 std::vector<ZONE*> cascadeDown;
1999 bool canCascadeDown = ( minOverlapping > 0 );
2000
2001 if( canCascadeDown )
2002 {
2003 cascadeDown =
2004 findCascadeZones( byPriority, minOverlapping - 1, false, cascadeDownViable );
2005 }
2006
2007 if( !cascadeUpViable && !cascadeDownViable )
2008 return 0;
2009
2010 BOARD_COMMIT commit( m_frame );
2011 commit.Modify( zone );
2012
2013 bool useUp = cascadeUpViable
2014 && ( !cascadeDownViable || cascadeUp.size() <= cascadeDown.size() );
2015
2016 if( useUp )
2017 {
2018 zone->SetAssignedPriority( minOverlapping );
2019
2020 for( ZONE* z : cascadeUp )
2021 {
2022 commit.Modify( z );
2024 z->SetNeedRefill( true );
2025 }
2026 }
2027 else
2028 {
2029 zone->SetAssignedPriority( minOverlapping - 1 );
2030
2031 for( ZONE* z : cascadeDown )
2032 {
2033 commit.Modify( z );
2035 z->SetNeedRefill( true );
2036 }
2037 }
2038
2039 zone->SetNeedRefill( true );
2040 commit.Push( _( "Move Zone to Bottom Priority" ) );
2041
2042 return 0;
2043}
2044
2045
2047{
2048 doCrossProbePcbToSch( aEvent, false );
2049 return 0;
2050}
2051
2052
2054{
2055 doCrossProbePcbToSch( aEvent, true );
2056 return 0;
2057}
2058
2059
2061{
2062 // Don't get in an infinite loop PCB -> SCH -> PCB -> SCH -> ...
2063 if( m_frame->m_ProbingSchToPcb )
2064 return;
2065
2066 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
2067 const PCB_SELECTION& selection = selTool->GetSelection();
2068 EDA_ITEM* focusItem = nullptr;
2069
2070 if( aEvent.Matches( EVENTS::PointSelectedEvent ) )
2071 focusItem = selection.GetLastAddedItem();
2072
2073 m_frame->SendSelectItemsToSch( selection.GetItems(), focusItem, aForce );
2074
2075 // Update 3D viewer highlighting
2076 m_frame->Update3DView( false, frame()->GetPcbNewSettings()->m_Display.m_Live3DRefresh );
2077}
2078
2079
2081{
2082 PCB_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
2083
2084 const PCB_SELECTION& selection = selectionTool->RequestSelection(
2085 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2086 {
2087 // Iterate from the back so we don't have to worry about removals.
2088 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
2089 {
2090 if( !dynamic_cast<BOARD_CONNECTED_ITEM*>( aCollector[ i ] ) )
2091 aCollector.Remove( aCollector[ i ] );
2092 }
2093
2094 sTool->FilterCollectorForLockedItems( aCollector );
2095 } );
2096
2097 std::set<wxString> netNames;
2098 std::set<int> netCodes;
2099
2100 for( EDA_ITEM* item : selection )
2101 {
2102 const NETINFO_ITEM& net = *static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNet();
2103
2104 if( !net.HasAutoGeneratedNetname() )
2105 {
2106 netNames.insert( net.GetNetname() );
2107 netCodes.insert( net.GetNetCode() );
2108 }
2109 }
2110
2111 if( netNames.empty() )
2112 {
2113 m_frame->ShowInfoBarError( _( "Selection contains no items with labeled nets." ) );
2114 return 0;
2115 }
2116
2117 selectionTool->ClearSelection();
2118 for( const int& code : netCodes )
2119 {
2120 m_toolMgr->RunAction( PCB_ACTIONS::selectNet, code );
2121 }
2122 canvas()->ForceRefresh();
2123
2124 DIALOG_ASSIGN_NETCLASS dlg( m_frame, netNames, board()->GetNetClassAssignmentCandidates(),
2125 [this]( const std::vector<wxString>& aNetNames )
2126 {
2127 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
2128 selTool->ClearSelection();
2129
2130 for( const wxString& curr_netName : aNetNames )
2131 {
2132 int curr_netCode = board()->GetNetInfo().GetNetItem( curr_netName )->GetNetCode();
2133
2134 if( curr_netCode > 0 )
2135 selTool->SelectAllItemsOnNet( curr_netCode );
2136 }
2137
2138 canvas()->ForceRefresh();
2139 m_frame->UpdateMsgPanel();
2140 } );
2141
2142 if( dlg.ShowModal() == wxID_OK )
2143 {
2145 // Refresh UI that depends on netclasses, such as the properties panel
2147 }
2148
2149 return 0;
2150}
2151
2152
2154{
2155 PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
2156 const PCB_SELECTION& selection = selTool->RequestSelection( EDIT_TOOL::FootprintFilter );
2157
2158 if( selection.Empty() )
2159 {
2160 // Giant hack: by default we assign Edit Table to the same hotkey, so give the table
2161 // tool a chance to handle it if we can't.
2162 if( PCB_EDIT_TABLE_TOOL* tableTool = m_toolMgr->GetTool<PCB_EDIT_TABLE_TOOL>() )
2163 tableTool->EditTable( aEvent );
2164
2165 return 0;
2166 }
2167
2168 FOOTPRINT* fp = selection.FirstOfKind<FOOTPRINT>();
2169
2170 if( !fp )
2171 return 0;
2172
2174
2175 if( KIWAY_PLAYER* frame = editFrame->Kiway().Player( FRAME_FOOTPRINT_EDITOR, true ) )
2176 {
2177 FOOTPRINT_EDIT_FRAME* fp_editor = static_cast<FOOTPRINT_EDIT_FRAME*>( frame );
2178
2180 fp_editor->LoadFootprintFromBoard( fp );
2181 else if( aEvent.IsAction( &PCB_ACTIONS::editLibFpInFpEditor ) )
2182 fp_editor->LoadFootprintFromLibrary( fp->GetFPID() );
2183
2184 fp_editor->Show( true );
2185 fp_editor->Raise(); // Iconize( false );
2186 }
2187
2188 if( selection.IsHover() )
2189 m_toolMgr->RunAction( ACTIONS::selectionClear );
2190
2191 return 0;
2192}
2193
2194
2196 EDA_ITEM* originViewItem, const VECTOR2D& aPosition )
2197{
2198 aFrame->GetDesignSettings().SetAuxOrigin( VECTOR2I( aPosition ) );
2199 originViewItem->SetPosition( aPosition );
2200 aView->MarkDirty();
2201 aFrame->OnModify();
2202}
2203
2204
2206{
2208 {
2209 m_frame->SaveCopyInUndoList( m_placeOrigin.get(), UNDO_REDO::GRIDORIGIN );
2211 return 0;
2212 }
2213
2214 if( aEvent.IsAction( &PCB_ACTIONS::drillSetOrigin ) )
2215 {
2216 VECTOR2I origin = aEvent.Parameter<VECTOR2I>();
2217 m_frame->SaveCopyInUndoList( m_placeOrigin.get(), UNDO_REDO::GRIDORIGIN );
2218 DoSetDrillOrigin( getView(), m_frame, m_placeOrigin.get(), origin );
2219 return 0;
2220 }
2221
2222 PCB_PICKER_TOOL* picker = m_toolMgr->GetTool<PCB_PICKER_TOOL>();
2223
2224 // Deactivate other tools; particularly important if another PICKER is currently running
2225 Activate();
2226
2227 picker->SetCursor( KICURSOR::PLACE );
2228 picker->ClearHandlers();
2229
2230 picker->SetClickHandler(
2231 [this] ( const VECTOR2D& pt ) -> bool
2232 {
2233 m_frame->SaveCopyInUndoList( m_placeOrigin.get(), UNDO_REDO::DRILLORIGIN );
2235 return false; // drill origin is a one-shot; don't continue with tool
2236 } );
2237
2238 m_toolMgr->RunAction( ACTIONS::pickerTool, &aEvent );
2239
2240 return 0;
2241}
2242
2243
2245{
2254
2260
2267
2268 if( ADVANCED_CFG::GetCfg().m_ShowPcbnewExportNetlist && m_frame && m_frame->GetExportNetlistAction() )
2269 Go( &BOARD_EDITOR_CONTROL::ExportNetlist, m_frame->GetExportNetlistAction()->MakeEvent() );
2270
2279
2286
2287 // Track & via size control
2293
2294 // Zone actions
2301
2302 // Placing tools
2307
2310
2311 // Cross-select
2317
2318 // Other
2322
2324
2334 // Line modes: explicit, next, and notification
2339}
const char * name
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
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)
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
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 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
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
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)
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 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)
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 ZonePriorityRaise(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 ZonePriorityLower(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 FindByProperties(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 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:81
void SetLocked(bool aLocked) override
Definition board_item.h:356
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:373
const NETINFO_LIST & GetNetInfo() const
Definition board.h:1094
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1346
const ZONES & Zones() const
Definition board.h:425
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:3055
int RepairDuplicateItemUuids()
Rebind duplicate attached-item UUIDs so each live board item has a unique ID.
Definition board.cpp:2165
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:134
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:191
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
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:42
virtual EDA_ITEM * AsEdaItem()=0
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:96
virtual void SetPosition(const VECTOR2I &aPos)
Definition eda_item.h:283
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition eda_item.h:152
virtual EDA_GROUP * GetParentGroup() const
Definition eda_item.h:114
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:89
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:89
static const TOOL_EVENT ClearedEvent
Definition actions.h:343
static const TOOL_EVENT SelectedEvent
Definition actions.h:341
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition actions.h:348
static const TOOL_EVENT PointSelectedEvent
Definition actions.h:340
static const TOOL_EVENT UnselectedEvent
Definition actions.h:342
Used for text file output.
Definition richio.h:470
bool Finish() override
Flushes the temp file to disk and atomically renames it over the final target path.
Definition richio.cpp:642
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:1176
void SetOrientation(const EDA_ANGLE &aNewAngle)
std::deque< PAD * > & Pads()
Definition footprint.h:375
bool IsFlipped() const
Definition footprint.h:614
const LIB_ID & GetFPID() const
Definition footprint.h:441
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
VECTOR2I GetPosition() const override
Definition footprint.h:403
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:63
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:404
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:1835
void MarkDirty()
Force redraw of view on the next rendering.
Definition view.h:677
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:398
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:139
int GetViaDrill() const
Definition netclass.h:147
int GetTrackWidth() const
Definition netclass.h:131
Handle the data for a net.
Definition netinfo.h:46
const wxString & GetNetname() const
Definition netinfo.h:100
int GetNetCode() const
Definition netinfo.h:94
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.
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:61
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 zonePriorityMoveToBottom
static TOOL_ACTION zonePriorityMoveToTop
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 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:78
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.
Definition pcb_actions.h:99
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.
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:86
virtual int GetWidth() const
Definition pcb_track.h:87
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:553
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:77
void SetCursor(KICURSOR aCursor)
Definition picker_tool.h:60
ROUTER_MODE Mode() const
Definition pns_router.h:158
RouterState GetState() const
Definition pns_router.h:160
ROUTER * Router() const
Container for project specific data.
Definition project.h:62
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:117
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
Returns the instance of #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:469
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: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.
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:70
void SetNeedRefill(bool aNeedRefill)
Definition zone.h:310
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition zone.h:813
const BOX2I GetBoundingBox() const override
Definition zone.cpp:766
SHAPE_POLY_SET GetBoardOutline() const
Definition zone.cpp:874
bool IsTeardropArea() const
Definition zone.h:788
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:594
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:94
@ ARROW
Definition cursors.h:42
@ PENCIL
Definition cursors.h:48
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: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:160
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:44
@ 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:448
@ PNS_MODE_ROUTE_DIFF_PAIR
Definition pns_router.h:69
#define MAX_PAGE_SIZE_PCBNEW_MILS
Definition page_info.h:31
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.
@ 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:84
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:90
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:80
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682
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.