KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_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-2016 CERN
5 * Copyright (C) 2019-2023 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
26#include <kiplatform/ui.h>
27#include <tools/edit_tool.h>
29#include <router/router_tool.h>
30#include <pgm_base.h>
31#include <tools/pcb_actions.h>
32#include <tools/pcb_control.h>
37#include <board_commit.h>
38#include <board.h>
40#include <board_item.h>
42#include <pcb_dimension.h>
44#include <footprint.h>
45#include <pcb_group.h>
46#include <pcb_textbox.h>
47#include <pcb_track.h>
48#include <pcb_generator.h>
50#include <zone.h>
51#include <confirm.h>
53#include <core/kicad_algo.h>
55#include <kicad_clipboard.h>
56#include <origin_viewitem.h>
57#include <pcb_edit_frame.h>
58#include <pcb_painter.h>
59#include <string_utf8_map.h>
61#include <string>
62#include <tool/tool_manager.h>
67#include <widgets/wx_infobar.h>
68#include <wx/hyperlink.h>
69
70using namespace std::placeholders;
71
72
73// files.cpp
74extern bool AskLoadBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, int aCtl = 0 );
75
76
78 PCB_TOOL_BASE( "pcbnew.Control" ),
79 m_frame( nullptr ),
80 m_pickerItem( nullptr )
81{
83}
84
85
87{
88}
89
90
92{
93 m_frame = getEditFrame<PCB_BASE_FRAME>();
94
95 if( aReason == MODEL_RELOAD || aReason == GAL_SWITCH || aReason == REDRAW )
96 {
97 m_gridOrigin->SetPosition( board()->GetDesignSettings().GetGridOrigin() );
98 m_gridOrigin->SetColor( m_frame->GetGridColor() );
99 getView()->Remove( m_gridOrigin.get() );
100 getView()->Add( m_gridOrigin.get() );
101 }
102}
103
104
106{
108 {
109 if( aEvent.IsAction( &ACTIONS::newLibrary ) )
110 static_cast<PCB_BASE_EDIT_FRAME*>( m_frame )->CreateNewLibrary();
111 else if( aEvent.IsAction( &ACTIONS::addLibrary ) )
112 static_cast<PCB_BASE_EDIT_FRAME*>( m_frame )->AddLibrary();
113 }
114
115 return 0;
116}
117
118
120{
121 const wxString fn = *aEvent.Parameter<wxString*>();
122 static_cast<PCB_BASE_EDIT_FRAME*>( m_frame )->AddLibrary( fn );
123 return 0;
124}
125
126
128{
129 const wxString fn = *aEvent.Parameter<wxString*>();
130 static_cast<FOOTPRINT_EDIT_FRAME*>( m_frame )->ImportFootprint( fn );
131 m_frame->Zoom_Automatique( false );
132 return 0;
133}
134
135
136int PCB_CONTROL::Quit( const TOOL_EVENT& aEvent )
137{
138 m_frame->Close( false );
139 return 0;
140}
141
142
143template<class T> void Flip( T& aValue )
144{
145 aValue = !aValue;
146}
147
148
150{
151 Flip( displayOptions().m_DisplayPcbTrackFill );
152
153 for( PCB_TRACK* track : board()->Tracks() )
154 {
155 if( track->Type() == PCB_TRACE_T || track->Type() == PCB_ARC_T )
156 view()->Update( track, KIGFX::REPAINT );
157 }
158
159 for( BOARD_ITEM* shape : board()->Drawings() )
160 {
161 if( shape->Type() == PCB_SHAPE_T && static_cast<PCB_SHAPE*>( shape )->IsOnCopperLayer() )
162 view()->Update( shape, KIGFX::REPAINT );
163 }
164
165 canvas()->Refresh();
166
167 return 0;
168}
169
170
172{
173 if( aEvent.IsAction( &PCB_ACTIONS::showRatsnest ) )
174 {
175 // N.B. Do not disable the Ratsnest layer here. We use it for local ratsnest
176 Flip( displayOptions().m_ShowGlobalRatsnest );
177 getEditFrame<PCB_EDIT_FRAME>()->SetElementVisibility( LAYER_RATSNEST,
178 displayOptions().m_ShowGlobalRatsnest );
179
180 }
181 else if( aEvent.IsAction( &PCB_ACTIONS::ratsnestLineMode ) )
182 {
183 Flip( displayOptions().m_DisplayRatsnestLinesCurved );
184 }
185
187
189 canvas()->Refresh();
190
191 return 0;
192}
193
194
196{
197 Flip( displayOptions().m_DisplayViaFill );
198
199 for( PCB_TRACK* track : board()->Tracks() )
200 {
201 if( track->Type() == PCB_VIA_T )
202 view()->Update( track, KIGFX::REPAINT );
203 }
204
205 canvas()->Refresh();
206 return 0;
207}
208
209
216{
217 if( Pgm().GetCommonSettings()->m_DoNotShowAgain.zone_fill_warning )
218 return;
219
220 bool unfilledZones = false;
221
222 for( const ZONE* zone : board()->Zones() )
223 {
224 if( !zone->GetIsRuleArea() && !zone->IsFilled() )
225 {
226 unfilledZones = true;
227 break;
228 }
229 }
230
231 if( unfilledZones )
232 {
233 WX_INFOBAR* infobar = frame()->GetInfoBar();
234 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, _( "Don't show again" ),
235 wxEmptyString );
236
237 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
238 [&]( wxHyperlinkEvent& aEvent )
239 {
241 frame()->GetInfoBar()->Dismiss();
242 } ) );
243
244 infobar->RemoveAllButtons();
245 infobar->AddButton( button );
246
247 wxString msg;
248 msg.Printf( _( "Not all zones are filled. Use Edit > Fill All Zones (%s) "
249 "if you wish to see all fills." ),
251
252 infobar->ShowMessageFor( msg, 5000, wxICON_WARNING );
253 }
254}
255
256
258{
260
261 // Apply new display options to the GAL canvas
263 {
265
266 opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_FILLED;
267 }
268 else if( aEvent.IsAction( &PCB_ACTIONS::zoneDisplayOutline ) )
269 {
270 opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_ZONE_OUTLINE;
271 }
272 else if( aEvent.IsAction( &PCB_ACTIONS::zoneDisplayFractured ) )
273 {
274 opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_FRACTURE_BORDERS;
275 }
277 {
278 opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_TRIANGULATION;
279 }
280 else if( aEvent.IsAction( &PCB_ACTIONS::zoneDisplayToggle ) )
281 {
282 if( opts.m_ZoneDisplayMode == ZONE_DISPLAY_MODE::SHOW_FILLED )
283 opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_ZONE_OUTLINE;
284 else
285 opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_FILLED;
286 }
287 else
288 {
289 wxFAIL;
290 }
291
292 m_frame->SetDisplayOptions( opts );
293
294 for( ZONE* zone : board()->Zones() )
295 view()->Update( zone, KIGFX::REPAINT );
296
297 canvas()->Refresh();
298
299 return 0;
300}
301
302
304{
306
307 opts.m_ContrastModeDisplay = opts.m_ContrastModeDisplay == HIGH_CONTRAST_MODE::NORMAL
308 ? HIGH_CONTRAST_MODE::DIMMED
309 : HIGH_CONTRAST_MODE::NORMAL;
310
311 m_frame->SetDisplayOptions( opts );
312 return 0;
313}
314
315
317{
319
320 switch( opts.m_ContrastModeDisplay )
321 {
322 case HIGH_CONTRAST_MODE::NORMAL: opts.m_ContrastModeDisplay = HIGH_CONTRAST_MODE::DIMMED; break;
323 case HIGH_CONTRAST_MODE::DIMMED: opts.m_ContrastModeDisplay = HIGH_CONTRAST_MODE::HIDDEN; break;
324 case HIGH_CONTRAST_MODE::HIDDEN: opts.m_ContrastModeDisplay = HIGH_CONTRAST_MODE::NORMAL; break;
325 }
326
327 m_frame->SetDisplayOptions( opts );
328
330 return 0;
331}
332
333
335{
336 if( !Pgm().GetCommonSettings()->m_Input.hotkey_feedback )
337 return 0;
338
340
341 wxArrayString labels;
342 labels.Add( _( "Normal" ) );
343 labels.Add( _( "Dimmed" ) );
344 labels.Add( _( "Hidden" ) );
345
346 if( !m_frame->GetHotkeyPopup() )
348
350
351 if( popup )
352 {
353 popup->Popup( _( "Inactive Layer Display" ), labels,
354 static_cast<int>( opts.m_ContrastModeDisplay ) );
355 }
356
357 return 0;
358}
359
360
362{
364
365 switch( opts.m_NetColorMode )
366 {
367 case NET_COLOR_MODE::ALL: opts.m_NetColorMode = NET_COLOR_MODE::RATSNEST; break;
368 case NET_COLOR_MODE::RATSNEST: opts.m_NetColorMode = NET_COLOR_MODE::OFF; break;
369 case NET_COLOR_MODE::OFF: opts.m_NetColorMode = NET_COLOR_MODE::ALL; break;
370 }
371
372 m_frame->SetDisplayOptions( opts );
373 return 0;
374}
375
376
378{
379 if( !displayOptions().m_ShowGlobalRatsnest )
380 {
382 displayOptions().m_RatsnestMode = RATSNEST_MODE::ALL;
383 }
384 else if( displayOptions().m_RatsnestMode == RATSNEST_MODE::ALL )
385 {
386 displayOptions().m_RatsnestMode = RATSNEST_MODE::VISIBLE;
387 }
388 else
389 {
391 }
392
393 getEditFrame<PCB_EDIT_FRAME>()->SetElementVisibility( LAYER_RATSNEST,
394 displayOptions().m_ShowGlobalRatsnest );
395
397
399 canvas()->Refresh();
400 return 0;
401}
402
403
405{
407
408 return 0;
409}
410
411
413{
414 PCB_BASE_FRAME* editFrame = m_frame;
415 BOARD* brd = board();
416 int layer = editFrame->GetActiveLayer();
417 int startLayer = layer;
418 bool wraparound = false;
419
420 while( startLayer != ++layer )
421 {
422 if( brd->IsLayerVisible( static_cast<PCB_LAYER_ID>( layer ) ) && IsCopperLayer( layer ) )
423 break;
424
425 if( layer >= B_Cu )
426 {
427 if( wraparound )
428 {
429 wxBell();
430 return 0;
431 }
432 else
433 {
434 wraparound = true;
435 layer = F_Cu - 1;
436 }
437 }
438 }
439
440 wxCHECK( IsCopperLayer( layer ), 0 );
441 editFrame->SwitchLayer( ToLAYER_ID( layer ) );
442
443 return 0;
444}
445
446
448{
449 PCB_BASE_FRAME* editFrame = m_frame;
450 BOARD* brd = board();
451 int layer = editFrame->GetActiveLayer();
452 int startLayer = layer;
453 bool wraparound = false;
454
455 while( startLayer != --layer )
456 {
457 if( IsCopperLayer( layer ) // also test for valid layer id (layer >= F_Cu)
458 && brd->IsLayerVisible( static_cast<PCB_LAYER_ID>( layer ) ) )
459 {
460 break;
461 }
462
463 if( layer <= F_Cu )
464 {
465 if( wraparound )
466 {
467 wxBell();
468 return 0;
469 }
470 else
471 {
472 wraparound = true;
473 layer = B_Cu + 1;
474 }
475 }
476 }
477
478 wxCHECK( IsCopperLayer( layer ), 0 );
479 editFrame->SwitchLayer( ToLAYER_ID( layer ) );
480
481 return 0;
482}
483
484
486{
487 int currentLayer = m_frame->GetActiveLayer();
488 PCB_SCREEN* screen = m_frame->GetScreen();
489
490 if( currentLayer == screen->m_Route_Layer_TOP )
492 else
494
495 return 0;
496}
497
498
499// It'd be nice to share the min/max with the DIALOG_COLOR_PICKER, but those are
500// set in wxFormBuilder.
501#define ALPHA_MIN 0.20
502#define ALPHA_MAX 1.00
503#define ALPHA_STEP 0.05
504
505
507{
509 int currentLayer = m_frame->GetActiveLayer();
510 KIGFX::COLOR4D currentColor = settings->GetColor( currentLayer );
511
512 if( currentColor.a <= ALPHA_MAX - ALPHA_STEP )
513 {
514 currentColor.a += ALPHA_STEP;
515 settings->SetColor( currentLayer, currentColor );
517
519 view->UpdateLayerColor( currentLayer );
520 view->UpdateLayerColor( GetNetnameLayer( currentLayer ) );
521
522 if( IsCopperLayer( currentLayer ) )
523 view->UpdateLayerColor( ZONE_LAYER_FOR( currentLayer ) );
524 }
525 else
526 {
527 wxBell();
528 }
529
530 return 0;
531}
532
533
535{
537 int currentLayer = m_frame->GetActiveLayer();
538 KIGFX::COLOR4D currentColor = settings->GetColor( currentLayer );
539
540 if( currentColor.a >= ALPHA_MIN + ALPHA_STEP )
541 {
542 currentColor.a -= ALPHA_STEP;
543 settings->SetColor( currentLayer, currentColor );
545
547 view->UpdateLayerColor( currentLayer );
548 view->UpdateLayerColor( GetNetnameLayer( currentLayer ) );
549
550 if( IsCopperLayer( currentLayer ) )
551 view->UpdateLayerColor( ZONE_LAYER_FOR( currentLayer ) );
552 }
553 else
554 {
555 wxBell();
556 }
557
558 return 0;
559}
560
561
563 EDA_ITEM* originViewItem, const VECTOR2D& aPoint )
564{
565 aFrame->GetDesignSettings().SetGridOrigin( VECTOR2I( aPoint ) );
566 aView->GetGAL()->SetGridOrigin( aPoint );
567 originViewItem->SetPosition( aPoint );
568 aView->MarkDirty();
569 aFrame->OnModify();
570}
571
572
574{
575 VECTOR2D* origin = aEvent.Parameter<VECTOR2D*>();
576
577 if( origin )
578 {
579 // We can't undo the other grid dialog settings, so no sense undoing just the origin
580 DoSetGridOrigin( getView(), m_frame, m_gridOrigin.get(), *origin );
581 delete origin;
582 }
583 else
584 {
585 if( m_isFootprintEditor && !getEditFrame<PCB_BASE_EDIT_FRAME>()->GetModel() )
586 return 0;
587
589
590 if( !picker ) // Happens in footprint wizard
591 return 0;
592
593 // Deactivate other tools; particularly important if another PICKER is currently running
594 Activate();
595
596 picker->SetClickHandler(
597 [this]( const VECTOR2D& pt ) -> bool
598 {
599 m_frame->SaveCopyInUndoList( m_gridOrigin.get(), UNDO_REDO::GRIDORIGIN );
601 return false; // drill origin is a one-shot; don't continue with tool
602 } );
603
605 }
606
607 return 0;
608}
609
610
612{
613 m_frame->SaveCopyInUndoList( m_gridOrigin.get(), UNDO_REDO::GRIDORIGIN );
615 return 0;
616}
617
618
619#define HITTEST_THRESHOLD_PIXELS 5
620
621
623{
625 return 0;
626
628
629 m_pickerItem = nullptr;
631
632 // Deactivate other tools; particularly important if another PICKER is currently running
633 Activate();
634
635 picker->SetCursor( KICURSOR::REMOVE );
636
637 picker->SetClickHandler(
638 [this]( const VECTOR2D& aPosition ) -> bool
639 {
640 if( m_pickerItem )
641 {
643 {
644 m_statusPopup.reset( new STATUS_TEXT_POPUP( m_frame ) );
645 m_statusPopup->SetText( _( "Item locked." ) );
646 m_statusPopup->PopupFor( 2000 );
647 m_statusPopup->Move( KIPLATFORM::UI::GetMousePosition()
648 + wxPoint( 20, 20 ) );
649 return true;
650 }
651
653 selectionTool->UnbrightenItem( m_pickerItem );
654
655 PCB_SELECTION items;
656 items.Add( m_pickerItem );
657
658 EDIT_TOOL* editTool = m_toolMgr->GetTool<EDIT_TOOL>();
659 editTool->DeleteItems( items, false );
660
661 m_pickerItem = nullptr;
662 }
663
664 return true;
665 } );
666
667 picker->SetMotionHandler(
668 [this]( const VECTOR2D& aPos )
669 {
673 GENERAL_COLLECTOR collector;
674 collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
675
677 collector.Collect( board, GENERAL_COLLECTOR::FootprintItems, aPos, guide );
678 else
679 collector.Collect( board, GENERAL_COLLECTOR::BoardLevelItems, aPos, guide );
680
681 // Remove unselectable items
682 for( int i = collector.GetCount() - 1; i >= 0; --i )
683 {
684 if( !selectionTool->Selectable( collector[ i ] ) )
685 collector.Remove( i );
686 }
687
688 selectionTool->FilterCollectorForHierarchy( collector, false );
689 selectionTool->FilterCollectedItems( collector, false );
690
691 if( collector.GetCount() > 1 )
692 selectionTool->GuessSelectionCandidates( collector, aPos );
693
694 BOARD_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
695
696 if( m_pickerItem != item )
697 {
698 if( m_pickerItem )
699 selectionTool->UnbrightenItem( m_pickerItem );
700
701 m_pickerItem = item;
702
703 if( m_pickerItem )
704 selectionTool->BrightenItem( m_pickerItem );
705 }
706 } );
707
708 picker->SetFinalizeHandler(
709 [this]( const int& aFinalState )
710 {
711 if( m_pickerItem )
712 m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
713
714 m_statusPopup.reset();
715
716 // Ensure the cursor gets changed&updated
717 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
719 } );
720
722
723 return 0;
724}
725
726
727static void pasteFootprintItemsToFootprintEditor( FOOTPRINT* aClipFootprint, BOARD* aBoard,
728 std::vector<BOARD_ITEM*>& aPastedItems )
729{
730 FOOTPRINT* editorFootprint = aBoard->GetFirstFootprint();
731
732 aClipFootprint->SetParent( aBoard );
733
734 for( PAD* pad : aClipFootprint->Pads() )
735 {
736 pad->SetParent( editorFootprint );
737 aPastedItems.push_back( pad );
738 }
739
740 aClipFootprint->Pads().clear();
741
742 // Not all graphic items can be added to the current footprint:
743 // mandatory fields are already existing in the current footprint.
744 //
745 for( PCB_FIELD* field : aClipFootprint->Fields() )
746 {
747 if( field->IsMandatoryField() )
748 {
749 if( PCB_GROUP* parentGroup = field->GetParentGroup() )
750 parentGroup->RemoveItem( field );
751 }
752 else
753 {
754 PCB_TEXT* text = static_cast<PCB_TEXT*>( field );
755
756 text->SetTextAngle( text->GetTextAngle() - aClipFootprint->GetOrientation() );
757 text->SetTextAngle( text->GetTextAngle() + editorFootprint->GetOrientation() );
758
759 VECTOR2I pos = field->GetFPRelativePosition();
760 field->SetParent( editorFootprint );
761 field->SetFPRelativePosition( pos );
762
763 aPastedItems.push_back( field );
764 }
765 }
766
767 aClipFootprint->Fields().clear();
768
769 for( BOARD_ITEM* item : aClipFootprint->GraphicalItems() )
770 {
771 if( item->Type() == PCB_TEXT_T )
772 {
773 PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
774
775 text->SetTextAngle( text->GetTextAngle() - aClipFootprint->GetOrientation() );
776 text->SetTextAngle( text->GetTextAngle() + editorFootprint->GetOrientation() );
777 }
778
779 VECTOR2I pos = item->GetFPRelativePosition();
780 item->SetParent( editorFootprint );
781 item->SetFPRelativePosition( pos );
782
783 aPastedItems.push_back( item );
784 }
785
786 aClipFootprint->GraphicalItems().clear();
787
788 for( ZONE* zone : aClipFootprint->Zones() )
789 {
790 zone->SetParent( editorFootprint );
791 aPastedItems.push_back( zone );
792 }
793
794 aClipFootprint->Zones().clear();
795
796 for( PCB_GROUP* group : aClipFootprint->Groups() )
797 {
798 group->SetParent( editorFootprint );
799 aPastedItems.push_back( group );
800 }
801
802 aClipFootprint->Groups().clear();
803}
804
805
806void PCB_CONTROL::pruneItemLayers( std::vector<BOARD_ITEM*>& aItems )
807{
808 // Do not prune items or layers when copying to the FP editor, because all
809 // layers are accepted, even if they are not enabled in the dummy board
810 // This is mainly true for internal copper layers: all are allowed but only one
811 // (In1.cu) is enabled for the GUI.
813 return;
814
815 LSET enabledLayers = board()->GetEnabledLayers();
816 std::vector<BOARD_ITEM*> returnItems;
817 bool fpItemDeleted = false;
818
819 auto processFPItem =
820 [&]( FOOTPRINT* aFootprint, BOARD_ITEM* aItem )
821 {
822 LSET allowed = aItem->GetLayerSet() & enabledLayers;
823
824 if( allowed.any() )
825 {
826 // Don't prune internal copper layers on items with holes
827 if( aItem->HasHole() && aItem->IsOnCopperLayer() )
828 allowed |= LSET::InternalCuMask();
829
830 aItem->SetLayerSet( allowed );
831 }
832 else
833 {
834 aFootprint->Remove( aItem );
835 fpItemDeleted = true;
836 }
837 };
838
839 for( BOARD_ITEM* item : aItems )
840 {
841 if( item->Type() == PCB_FOOTPRINT_T )
842 {
843 FOOTPRINT* fp = static_cast<FOOTPRINT*>( item );
844
845 if( !enabledLayers.test( fp->Reference().GetLayer() ) )
846 fp->Reference().SetLayer( fp->IsFlipped() ? B_SilkS : F_SilkS );
847
848 if( !enabledLayers.test( fp->Value().GetLayer() ) )
849 fp->Value().SetLayer( fp->IsFlipped() ? B_Fab : F_Fab );
850
851 // NOTE: all traversals from the back as processFPItem() might delete the item
852
853 for( int ii = static_cast<int>( fp->Fields().size() ) - 1; ii >= 0; ii-- )
854 {
855 PCB_FIELD* field = fp->Fields()[ii];
856
857 if( field->GetId() == REFERENCE_FIELD || field->GetId() == VALUE_FIELD )
858 continue;
859
860 processFPItem( fp, field );
861 }
862
863 for( int ii = static_cast<int>( fp->Pads().size() ) - 1; ii >= 0; ii-- )
864 processFPItem( fp, fp->Pads()[ii] );
865
866 for( int ii = static_cast<int>( fp->Zones().size() ) - 1; ii >= 0; ii-- )
867 processFPItem( fp, fp->Zones()[ii] );
868
869 for( int ii = static_cast<int>( fp->GraphicalItems().size() ) - 1; ii >= 0; ii-- )
870 processFPItem( fp, fp->GraphicalItems()[ii] );
871
872 if( fp->GraphicalItems().size() || fp->Pads().size() || fp->Zones().size() )
873 {
874 returnItems.push_back( fp );
875 }
876 else
877 {
878 if( PCB_GROUP* parentGroup = fp->GetParentGroup() )
879 parentGroup->RemoveItem( item );
880 }
881 }
882 else if( item->Type() == PCB_GROUP_T || item->Type() == PCB_GENERATOR_T )
883 {
884 returnItems.push_back( item );
885 }
886 else
887 {
888 LSET allowed = item->GetLayerSet() & enabledLayers;
889
890 if( allowed.any() )
891 {
892 item->SetLayerSet( allowed );
893 returnItems.push_back( item );
894 }
895 else
896 {
897 if( PCB_GROUP* parentGroup = item->GetParentGroup() )
898 parentGroup->RemoveItem( item );
899 }
900 }
901 }
902
903 if( ( returnItems.size() < aItems.size() ) || fpItemDeleted )
904 {
905 DisplayError( m_frame, _( "Warning: some pasted items were on layers which are not "
906 "present in the current board.\n"
907 "These items could not be pasted.\n" ) );
908 }
909
910 aItems = returnItems;
911}
912
913
914int PCB_CONTROL::Paste( const TOOL_EVENT& aEvent )
915{
916 CLIPBOARD_IO pi;
917 BOARD_ITEM* clipItem = pi.Parse();
918
919 if( !clipItem )
920 return 0;
921
922 // The viewer frames cannot paste
923 if( !frame()->IsType( FRAME_FOOTPRINT_EDITOR ) && !frame()->IsType( FRAME_PCB_EDITOR ) )
924 return 0;
925
926 PASTE_MODE mode = PASTE_MODE::KEEP_ANNOTATIONS;
927 bool clear_nets = false;
928 const wxString defaultRef = wxT( "REF**" );
929
930 if( aEvent.IsAction( &ACTIONS::pasteSpecial ) )
931 {
932 DIALOG_PASTE_SPECIAL dlg( m_frame, &mode, defaultRef );
933
934 if( clipItem->Type() != PCB_T )
935 dlg.HideClearNets();
936
937 if( dlg.ShowModal() == wxID_CANCEL )
938 return 0;
939
940 clear_nets = dlg.GetClearNets();
941 }
942
943 bool isFootprintEditor = m_isFootprintEditor || frame()->IsType( FRAME_FOOTPRINT_EDITOR );
944
945 if( clipItem->Type() == PCB_T )
946 {
947 BOARD* clipBoard = static_cast<BOARD*>( clipItem );
948
949 if( isFootprintEditor || clear_nets )
950 {
951 for( BOARD_CONNECTED_ITEM* item : clipBoard->AllConnectedItems() )
952 item->SetNet( NETINFO_LIST::OrphanedItem() );
953 }
954 else
955 {
956 clipBoard->MapNets( m_frame->GetBoard() );
957 }
958 }
959
960 // The clipboard can contain two different things, an entire kicad_pcb or a single footprint
961 if( isFootprintEditor && ( !board() || !footprint() ) )
962 return 0;
963
964 BOARD_COMMIT commit( frame() );
965 bool cancelled = false;
966
967 switch( clipItem->Type() )
968 {
969 case PCB_T:
970 {
971 BOARD* clipBoard = static_cast<BOARD*>( clipItem );
972
973 if( isFootprintEditor )
974 {
975 FOOTPRINT* editorFootprint = board()->GetFirstFootprint();
976 std::vector<BOARD_ITEM*> pastedItems;
977
978 for( PCB_GROUP* group : clipBoard->Groups() )
979 {
980 group->SetParent( editorFootprint );
981 pastedItems.push_back( group );
982 }
983
984 clipBoard->RemoveAll( { PCB_GROUP_T } );
985
986 for( FOOTPRINT* clipFootprint : clipBoard->Footprints() )
987 pasteFootprintItemsToFootprintEditor( clipFootprint, board(), pastedItems );
988
989 for( BOARD_ITEM* clipDrawItem : clipBoard->Drawings() )
990 {
991 switch( clipDrawItem->Type() )
992 {
993 case PCB_TEXT_T:
994 case PCB_TEXTBOX_T:
995 case PCB_TABLE_T:
996 case PCB_SHAPE_T:
998 case PCB_DIM_CENTER_T:
999 case PCB_DIM_LEADER_T:
1001 case PCB_DIM_RADIAL_T:
1002 clipDrawItem->SetParent( editorFootprint );
1003 pastedItems.push_back( clipDrawItem );
1004 break;
1005
1006 default:
1007 // Everything we *didn't* put into pastedItems is going to get nuked, so
1008 // make sure it's not still included in its parent group.
1009 if( PCB_GROUP* parentGroup = clipDrawItem->GetParentGroup() )
1010 parentGroup->RemoveItem( clipDrawItem );
1011
1012 break;
1013 }
1014 }
1015
1016 // NB: PCB_SHAPE_T actually removes everything in Drawings() (including PCB_TEXTs,
1017 // PCB_TABLES, dimensions, etc.), not just PCB_SHAPEs.)
1018 clipBoard->RemoveAll( { PCB_SHAPE_T } );
1019
1020 clipBoard->Visit(
1021 [&]( EDA_ITEM* item, void* testData )
1022 {
1023 // Anything still on the clipboard didn't get copied and needs to be
1024 // removed from the pasted groups.
1025 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( item );
1026 PCB_GROUP* parentGroup = boardItem->GetParentGroup();
1027
1028 if( parentGroup )
1029 parentGroup->RemoveItem( boardItem );
1030
1031 return INSPECT_RESULT::CONTINUE;
1032 },
1034
1035 delete clipBoard;
1036
1037 pruneItemLayers( pastedItems );
1038
1039 cancelled = !placeBoardItems( &commit, pastedItems, true, true,
1040 mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
1041 }
1042 else
1043 {
1044 if( mode == PASTE_MODE::REMOVE_ANNOTATIONS )
1045 {
1046 for( FOOTPRINT* clipFootprint : clipBoard->Footprints() )
1047 clipFootprint->SetReference( defaultRef );
1048 }
1049
1050 cancelled = !placeBoardItems( &commit, clipBoard, true,
1051 mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
1052 }
1053
1054 break;
1055 }
1056
1057 case PCB_FOOTPRINT_T:
1058 {
1059 FOOTPRINT* clipFootprint = static_cast<FOOTPRINT*>( clipItem );
1060 std::vector<BOARD_ITEM*> pastedItems;
1061
1062 if( isFootprintEditor )
1063 {
1064 pasteFootprintItemsToFootprintEditor( clipFootprint, board(), pastedItems );
1065 delete clipFootprint;
1066 }
1067 else
1068 {
1069 if( mode == PASTE_MODE::REMOVE_ANNOTATIONS )
1070 clipFootprint->SetReference( defaultRef );
1071
1072 clipFootprint->SetParent( board() );
1073 pastedItems.push_back( clipFootprint );
1074 }
1075
1076 pruneItemLayers( pastedItems );
1077
1078 cancelled = !placeBoardItems( &commit, pastedItems, true, true,
1079 mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
1080 break;
1081 }
1082
1083 default:
1084 m_frame->DisplayToolMsg( _( "Invalid clipboard contents" ) );
1085 break;
1086 }
1087
1088 if( cancelled )
1089 commit.Revert();
1090 else
1091 commit.Push( _( "Paste" ) );
1092
1093 return 1;
1094}
1095
1096
1098{
1099 wxString fileName;
1100
1101 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1102
1103 if( !editFrame )
1104 return 1;
1105
1106 // Pick a file to append
1107 if( !AskLoadBoardFileName( editFrame, &fileName, KICTL_KICAD_ONLY ) )
1108 return 1;
1109
1110 PCB_IO_MGR::PCB_FILE_T pluginType =
1112 IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
1113
1114 if( !pi )
1115 return 1;
1116
1117 return AppendBoard( *pi, fileName );
1118}
1119
1120
1121template<typename T>
1122static void moveUnflaggedItems( const std::deque<T>& aList, std::vector<BOARD_ITEM*>& aTarget,
1123 bool aIsNew )
1124{
1125 std::copy_if( aList.begin(), aList.end(), std::back_inserter( aTarget ),
1126 [aIsNew]( T aItem )
1127 {
1128 bool doCopy = ( aItem->GetFlags() & SKIP_STRUCT ) == 0;
1129
1130 aItem->ClearFlags( SKIP_STRUCT );
1131 aItem->SetFlags( aIsNew ? IS_NEW : 0 );
1132
1133 return doCopy;
1134 } );
1135}
1136
1137
1138template<typename T>
1139static void moveUnflaggedItems( const std::vector<T>& aList, std::vector<BOARD_ITEM*>& aTarget,
1140 bool aIsNew )
1141{
1142 std::copy_if( aList.begin(), aList.end(), std::back_inserter( aTarget ),
1143 [aIsNew]( T aItem )
1144 {
1145 bool doCopy = ( aItem->GetFlags() & SKIP_STRUCT ) == 0;
1146
1147 aItem->ClearFlags( SKIP_STRUCT );
1148 aItem->SetFlags( aIsNew ? IS_NEW : 0 );
1149
1150 return doCopy;
1151 } );
1152}
1153
1154
1155bool PCB_CONTROL::placeBoardItems( BOARD_COMMIT* aCommit, BOARD* aBoard, bool aAnchorAtOrigin,
1156 bool aReannotateDuplicates )
1157{
1158 // items are new if the current board is not the board source
1159 bool isNew = board() != aBoard;
1160 std::vector<BOARD_ITEM*> items;
1161
1162 moveUnflaggedItems( aBoard->Tracks(), items, isNew );
1163 moveUnflaggedItems( aBoard->Footprints(), items, isNew );
1164 moveUnflaggedItems( aBoard->Drawings(), items, isNew );
1165 moveUnflaggedItems( aBoard->Zones(), items, isNew );
1166
1167 // Subtlety: When selecting a group via the mouse,
1168 // PCB_SELECTION_TOOL::highlightInternal runs, which does a SetSelected() on all
1169 // descendants. In PCB_CONTROL::placeBoardItems, below, we skip that and
1170 // mark items non-recursively. That works because the saving of the
1171 // selection created aBoard that has the group and all descendants in it.
1172 moveUnflaggedItems( aBoard->Groups(), items, isNew );
1173
1174 moveUnflaggedItems( aBoard->Generators(), items, isNew );
1175
1176 if( isNew )
1177 aBoard->RemoveAll();
1178
1179 // Reparent before calling pruneItemLayers, as SetLayer can have a dependence on the
1180 // item's parent board being set correctly.
1181 if( isNew )
1182 {
1183 for( BOARD_ITEM* item : items )
1184 item->SetParent( board() );
1185 }
1186
1187 pruneItemLayers( items );
1188
1189 return placeBoardItems( aCommit, items, isNew, aAnchorAtOrigin, aReannotateDuplicates );
1190}
1191
1192
1193bool PCB_CONTROL::placeBoardItems( BOARD_COMMIT* aCommit, std::vector<BOARD_ITEM*>& aItems,
1194 bool aIsNew, bool aAnchorAtOrigin, bool aReannotateDuplicates )
1195{
1197
1199
1200 std::vector<BOARD_ITEM*> itemsToSel;
1201 itemsToSel.reserve( aItems.size() );
1202
1203 for( BOARD_ITEM* item : aItems )
1204 {
1205 if( aIsNew )
1206 {
1207 const_cast<KIID&>( item->m_Uuid ) = KIID();
1208
1209 // Even though BOARD_COMMIT::Push() will add any new items to the group, we're
1210 // going to run PCB_ACTIONS::move first, and the move tool will throw out any
1211 // items that aren't in the entered group.
1212 if( selectionTool->GetEnteredGroup() && !item->GetParentGroup() )
1213 selectionTool->GetEnteredGroup()->AddItem( item );
1214
1215 item->SetParent( board() );
1216 }
1217
1218 // Update item attributes if needed
1219 if( BaseType( item->Type() ) == PCB_DIMENSION_T )
1220 {
1221 static_cast<PCB_DIMENSION_BASE*>( item )->UpdateUnits();
1222 }
1223 else if( item->Type() == PCB_FOOTPRINT_T )
1224 {
1225 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
1226
1227 // Update the footprint path with the new KIID path if the footprint is new
1228 if( aIsNew )
1230
1231 for( BOARD_ITEM* dwg : footprint->GraphicalItems() )
1232 {
1233 if( BaseType( dwg->Type() ) == PCB_DIMENSION_T )
1234 static_cast<PCB_DIMENSION_BASE*>( dwg )->UpdateUnits();
1235 }
1236 }
1237
1238 // We only need to add the items that aren't inside a group currently selected
1239 // to the selection. If an item is inside a group and that group is selected,
1240 // then the selection tool will select it for us.
1241 if( !item->GetParentGroup() || !alg::contains( aItems, item->GetParentGroup() ) )
1242 itemsToSel.push_back( item );
1243 }
1244
1245 // Select the items that should be selected
1246 EDA_ITEMS toSel( itemsToSel.begin(), itemsToSel.end() );
1248
1249 // Reannotate duplicate footprints (make sense only in board editor )
1250 if( aReannotateDuplicates && m_isBoardEditor )
1251 m_toolMgr->GetTool<BOARD_REANNOTATE_TOOL>()->ReannotateDuplicatesInSelection();
1252
1253 for( BOARD_ITEM* item : aItems )
1254 {
1255 if( aIsNew )
1256 aCommit->Add( item );
1257 else
1258 aCommit->Added( item );
1259 }
1260
1261 PCB_SELECTION& selection = selectionTool->GetSelection();
1262
1263 if( selection.Size() > 0 )
1264 {
1265 if( aAnchorAtOrigin )
1266 {
1268 }
1269 else
1270 {
1271 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.GetTopLeftItem() );
1273 }
1274
1275 getViewControls()->SetCursorPosition( getViewControls()->GetMousePosition(), false );
1276
1278
1280 }
1281
1282 return true;
1283}
1284
1285
1286int PCB_CONTROL::AppendBoard( PCB_IO& pi, wxString& fileName )
1287{
1288 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1289
1290 if( !editFrame )
1291 return 1;
1292
1293 BOARD* brd = board();
1294
1295 if( !brd )
1296 return 1;
1297
1298 BOARD_COMMIT commit( editFrame );
1299
1300 // Mark existing items, in order to know what are the new items so we can select only
1301 // the new items after loading
1302 for( PCB_TRACK* track : brd->Tracks() )
1303 track->SetFlags( SKIP_STRUCT );
1304
1305 for( FOOTPRINT* footprint : brd->Footprints() )
1307
1308 for( PCB_GROUP* group : brd->Groups() )
1309 group->SetFlags( SKIP_STRUCT );
1310
1311 for( BOARD_ITEM* drawing : brd->Drawings() )
1312 drawing->SetFlags( SKIP_STRUCT );
1313
1314 for( ZONE* zone : brd->Zones() )
1315 zone->SetFlags( SKIP_STRUCT );
1316
1317 for( PCB_GENERATOR* generator : brd->Generators() )
1318 generator->SetFlags( SKIP_STRUCT );
1319
1320 std::map<wxString, wxString> oldProperties = brd->GetProperties();
1321 std::map<wxString, wxString> newProperties;
1322
1323 PAGE_INFO oldPageInfo = brd->GetPageSettings();
1324 TITLE_BLOCK oldTitleBlock = brd->GetTitleBlock();
1325
1326 // Keep also the count of copper layers, to adjust if necessary
1327 int initialCopperLayerCount = brd->GetCopperLayerCount();
1328 LSET initialEnabledLayers = brd->GetEnabledLayers();
1329
1330 // Load the data
1331 try
1332 {
1333 STRING_UTF8_MAP props;
1334
1335 // PCB_IO_EAGLE can use this info to center the BOARD, but it does not yet.
1336
1337 props["page_width"] = std::to_string( editFrame->GetPageSizeIU().x );
1338 props["page_height"] = std::to_string( editFrame->GetPageSizeIU().y );
1339
1341 [&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool
1342 {
1343 KIDIALOG dlg( editFrame, aMessage, aTitle, wxOK | wxCANCEL | aIcon );
1344
1345 if( !aAction.IsEmpty() )
1346 dlg.SetOKLabel( aAction );
1347
1348 dlg.DoNotShowCheckbox( aMessage, 0 );
1349
1350 return dlg.ShowModal() == wxID_OK;
1351 } );
1352
1353 WX_PROGRESS_REPORTER progressReporter( editFrame, _( "Loading PCB" ), 1 );
1354
1355 editFrame->GetDesignSettings().m_NetSettings->m_NetClasses.clear();
1356 pi.SetProgressReporter( &progressReporter );
1357 pi.LoadBoard( fileName, brd, &props, nullptr );
1358 }
1359 catch( const IO_ERROR& ioe )
1360 {
1361 wxString msg = wxString::Format( _( "Error loading board.\n%s" ), ioe.What() );
1362 DisplayError( editFrame, msg );
1363
1364 return 0;
1365 }
1366
1367 newProperties = brd->GetProperties();
1368
1369 for( const std::pair<const wxString, wxString>& prop : oldProperties )
1370 newProperties[ prop.first ] = prop.second;
1371
1372 brd->SetProperties( newProperties );
1373
1374 brd->SetPageSettings( oldPageInfo );
1375 brd->SetTitleBlock( oldTitleBlock );
1376
1377 // rebuild nets and ratsnest before any use of nets
1378 brd->BuildListOfNets();
1379 brd->SynchronizeNetsAndNetClasses( true );
1380 brd->BuildConnectivity();
1381
1382 // Synchronize layers
1383 // we should not ask PLUGINs to do these items:
1384 int copperLayerCount = brd->GetCopperLayerCount();
1385
1386 if( copperLayerCount > initialCopperLayerCount )
1387 brd->SetCopperLayerCount( copperLayerCount );
1388
1389 // Enable all used layers, and make them visible:
1390 LSET enabledLayers = brd->GetEnabledLayers();
1391 enabledLayers |= initialEnabledLayers;
1392 brd->SetEnabledLayers( enabledLayers );
1393 brd->SetVisibleLayers( enabledLayers );
1394
1395 if( placeBoardItems( &commit, brd, false, false /* Don't reannotate dupes on Append Board */ ) )
1396 commit.Push( _( "Append Board" ) );
1397 else
1398 commit.Revert();
1399
1400 // Refresh the UI for the updated board properties
1401 editFrame->GetAppearancePanel()->OnBoardChanged();
1402
1403 return 0;
1404}
1405
1406
1407int PCB_CONTROL::Undo( const TOOL_EVENT& aEvent )
1408{
1409 PCB_BASE_EDIT_FRAME* editFrame = dynamic_cast<PCB_BASE_EDIT_FRAME*>( m_frame );
1410 wxCommandEvent dummy;
1411
1412 if( editFrame )
1413 editFrame->RestoreCopyFromUndoList( dummy );
1414
1415 return 0;
1416}
1417
1418
1419int PCB_CONTROL::Redo( const TOOL_EVENT& aEvent )
1420{
1421 PCB_BASE_EDIT_FRAME* editFrame = dynamic_cast<PCB_BASE_EDIT_FRAME*>( m_frame );
1422 wxCommandEvent dummy;
1423
1424 if( editFrame )
1425 editFrame->RestoreCopyFromRedoList( dummy );
1426
1427 return 0;
1428}
1429
1430
1432{
1436 bool& snapMode = settings.allLayers;
1437
1439 snapMode = false;
1440 else if( aEvent.IsAction( &PCB_ACTIONS::magneticSnapAllLayers ) )
1441 snapMode = true;
1442 else
1443 snapMode = !snapMode;
1444
1446
1447 return 0;
1448}
1449
1450
1452{
1453 if( !Pgm().GetCommonSettings()->m_Input.hotkey_feedback )
1454 return 0;
1455
1456 wxArrayString labels;
1457 labels.Add( _( "Active Layer" ) );
1458 labels.Add( _( "All Layers" ) );
1459
1460 if( !m_frame->GetHotkeyPopup() )
1462
1464
1468
1469 if( popup )
1470 popup->Popup( _( "Object Snapping" ), labels, static_cast<int>( settings.allLayers ) );
1471
1472 return 0;
1473}
1474
1475
1477{
1479 ROUTER_TOOL* routerTool = m_toolMgr->GetTool<ROUTER_TOOL>();
1480 PCB_SELECTION& selection = selTool->GetSelection();
1481 PCB_EDIT_FRAME* pcbFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1482 std::shared_ptr<DRC_ENGINE> drcEngine = m_frame->GetBoard()->GetDesignSettings().m_DRCEngine;
1483 DRC_CONSTRAINT constraint;
1484
1485 std::vector<MSG_PANEL_ITEM> msgItems;
1486
1487 if( routerTool && routerTool->RoutingInProgress() )
1488 {
1489 routerTool->UpdateMessagePanel();
1490 return 0;
1491 }
1492
1493 if( !pcbFrame && !m_frame->GetModel() )
1494 return 0;
1495
1496 if( selection.Empty() )
1497 {
1498 if( !pcbFrame )
1499 {
1500 FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_frame->GetModel() );
1501 fp->GetMsgPanelInfo( m_frame, msgItems );
1502 }
1503 else
1504 {
1506 }
1507 }
1508 else if( selection.GetSize() == 1 )
1509 {
1510 EDA_ITEM* item = selection.Front();
1511
1512 item->GetMsgPanelInfo( m_frame, msgItems );
1513
1514 PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item );
1515 NETINFO_ITEM* net = track ? track->GetNet() : nullptr;
1516 NETINFO_ITEM* coupledNet = net ? m_frame->GetBoard()->DpCoupledNet( net ) : nullptr;
1517
1518 if( coupledNet )
1519 {
1520 SEG trackSeg( track->GetStart(), track->GetEnd() );
1521 PCB_TRACK* coupledItem = nullptr;
1522 SEG::ecoord closestDist_sq = VECTOR2I::ECOORD_MAX;
1523
1524 for( PCB_TRACK* candidate : m_frame->GetBoard()->Tracks() )
1525 {
1526 if( candidate->GetNet() != coupledNet )
1527 continue;
1528
1529 SEG::ecoord dist_sq = trackSeg.SquaredDistance( SEG( candidate->GetStart(),
1530 candidate->GetEnd() ) );
1531
1532 if( !coupledItem || dist_sq < closestDist_sq )
1533 {
1534 coupledItem = candidate;
1535 closestDist_sq = dist_sq;
1536 }
1537 }
1538
1539 constraint = drcEngine->EvalRules( DIFF_PAIR_GAP_CONSTRAINT, track, coupledItem,
1540 track->GetLayer() );
1541
1542 wxString msg = m_frame->MessageTextFromMinOptMax( constraint.Value() );
1543
1544 if( !msg.IsEmpty() )
1545 {
1546 msgItems.emplace_back( wxString::Format( _( "DP Gap Constraints: %s" ), msg ),
1547 wxString::Format( _( "(from %s)" ), constraint.GetName() ) );
1548 }
1549
1550 constraint = drcEngine->EvalRules( MAX_UNCOUPLED_CONSTRAINT, track,
1551 coupledItem, track->GetLayer() );
1552
1553 if( constraint.Value().HasMax() )
1554 {
1555 msg = m_frame->MessageTextFromValue( constraint.Value().Max() );
1556 msgItems.emplace_back( wxString::Format( _( "DP Max Uncoupled-length: %s" ), msg ),
1557 wxString::Format( _( "(from %s)" ), constraint.GetName() ) );
1558 }
1559 }
1560 }
1561 else if( pcbFrame && selection.GetSize() == 2 )
1562 {
1563 // Pair selection broken into multiple, optional data, starting with the selected item
1564 // names
1565
1566 BOARD_ITEM* a = static_cast<BOARD_ITEM*>( selection[0] );
1567 BOARD_ITEM* b = static_cast<BOARD_ITEM*>( selection[1] );
1568
1569 msgItems.emplace_back( MSG_PANEL_ITEM( a->GetItemDescription( m_frame ),
1570 b->GetItemDescription( m_frame ) ) );
1571
1572 BOARD_CONNECTED_ITEM* a_conn = dyn_cast<BOARD_CONNECTED_ITEM*>( a );
1573 BOARD_CONNECTED_ITEM* b_conn = dyn_cast<BOARD_CONNECTED_ITEM*>( b );
1574
1575 if( a_conn && b_conn )
1576 {
1577 LSET overlap = a_conn->GetLayerSet() & b_conn->GetLayerSet() & LSET::AllCuMask();
1578 int a_netcode = a_conn->GetNetCode();
1579 int b_netcode = b_conn->GetNetCode();
1580
1581 if( overlap.count() > 0
1582 && ( a_netcode != b_netcode || a_netcode < 0 || b_netcode < 0 ) )
1583 {
1584 PCB_LAYER_ID layer = overlap.CuStack().front();
1585
1586 constraint = drcEngine->EvalRules( CLEARANCE_CONSTRAINT, a, b, layer );
1587 msgItems.emplace_back( _( "Resolved clearance" ),
1588 m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
1589
1590 std::shared_ptr<SHAPE> a_shape( a_conn->GetEffectiveShape( layer ) );
1591 std::shared_ptr<SHAPE> b_shape( b_conn->GetEffectiveShape( layer ) );
1592
1593 int actual_clearance = a_shape->GetClearance( b_shape.get() );
1594
1595 if( actual_clearance > -1 && actual_clearance < std::numeric_limits<int>::max() )
1596 {
1597 msgItems.emplace_back( _( "Actual clearance" ),
1598 m_frame->MessageTextFromValue( actual_clearance ) );
1599 }
1600 }
1601 }
1602
1603 if( ( a->HasHole() || b->HasHole() ) )
1604 {
1607
1608 if( b->IsOnLayer( active ) && IsCopperLayer( active ) )
1609 layer = active;
1610 else if( b->HasHole() && a->IsOnLayer( active ) && IsCopperLayer( active ) )
1611 layer = active;
1612 else if( a->HasHole() && b->IsOnCopperLayer() )
1613 layer = b->GetLayer();
1614 else if( b->HasHole() && a->IsOnCopperLayer() )
1615 layer = a->GetLayer();
1616
1617 if( IsCopperLayer( layer ) )
1618 {
1619 int actual = std::numeric_limits<int>::max();
1620
1621 if( a->HasHole() && b->IsOnCopperLayer() )
1622 {
1623 std::shared_ptr<SHAPE_SEGMENT> hole = a->GetEffectiveHoleShape();
1624 std::shared_ptr<SHAPE> other( b->GetEffectiveShape( layer ) );
1625
1626 actual = std::min( actual, hole->GetClearance( other.get() ) );
1627 }
1628
1629 if( b->HasHole() && a->IsOnCopperLayer() )
1630 {
1631 std::shared_ptr<SHAPE_SEGMENT> hole = b->GetEffectiveHoleShape();
1632 std::shared_ptr<SHAPE> other( a->GetEffectiveShape( layer ) );
1633
1634 actual = std::min( actual, hole->GetClearance( other.get() ) );
1635 }
1636
1637 if( actual < std::numeric_limits<int>::max() )
1638 {
1639 constraint = drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer );
1640 msgItems.emplace_back( _( "Resolved hole clearance" ),
1641 m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
1642
1643 if( actual > -1 && actual < std::numeric_limits<int>::max() )
1644 {
1645 msgItems.emplace_back( _( "Actual hole clearance" ),
1646 m_frame->MessageTextFromValue( actual ) );
1647 }
1648 }
1649 }
1650 }
1651
1652 for( PCB_LAYER_ID edgeLayer : { Edge_Cuts, Margin } )
1653 {
1656
1657 if( a->IsOnLayer( edgeLayer ) && b->Type() != PCB_FOOTPRINT_T )
1658 {
1659 if( b->IsOnLayer( active ) && IsCopperLayer( active ) )
1660 layer = active;
1661 else if( IsCopperLayer( b->GetLayer() ) )
1662 layer = b->GetLayer();
1663 }
1664 else if( b->IsOnLayer( edgeLayer ) && a->Type() != PCB_FOOTPRINT_T )
1665 {
1666 if( a->IsOnLayer( active ) && IsCopperLayer( active ) )
1667 layer = active;
1668 else if( IsCopperLayer( a->GetLayer() ) )
1669 layer = a->GetLayer();
1670 }
1671
1672 if( layer >= 0 )
1673 {
1674 constraint = drcEngine->EvalRules( EDGE_CLEARANCE_CONSTRAINT, a, b, layer );
1675
1676 if( edgeLayer == Edge_Cuts )
1677 {
1678 msgItems.emplace_back( _( "Resolved edge clearance" ),
1679 m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
1680 }
1681 else
1682 {
1683 msgItems.emplace_back( _( "Resolved margin clearance" ),
1684 m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
1685 }
1686 }
1687 }
1688 }
1689
1690 if( msgItems.empty() )
1691 {
1692 if( selection.GetSize() )
1693 {
1694 msgItems.emplace_back( _( "Selected Items" ),
1695 wxString::Format( wxT( "%d" ), selection.GetSize() ) );
1696
1697 if( m_isBoardEditor )
1698 {
1699 std::set<wxString> netNames;
1700 std::set<wxString> netClasses;
1701
1702 for( EDA_ITEM* item : selection )
1703 {
1704 if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
1705 {
1706 netNames.insert( UnescapeString( bci->GetNetname() ) );
1707 netClasses.insert( UnescapeString( bci->GetEffectiveNetClass()->GetName() ) );
1708
1709 if( netNames.size() > 1 && netClasses.size() > 1 )
1710 break;
1711 }
1712 }
1713
1714 if( netNames.size() == 1 )
1715 msgItems.emplace_back( _( "Net" ), *netNames.begin() );
1716
1717 if( netClasses.size() == 1 )
1718 msgItems.emplace_back( _( "Resolved Netclass" ), *netClasses.begin() );
1719 }
1720 }
1721 else
1722 {
1723 m_frame->GetBoard()->GetMsgPanelInfo( m_frame, msgItems );
1724 }
1725 }
1726
1727 m_frame->SetMsgPanel( msgItems );
1728
1729 return 0;
1730}
1731
1732
1734{
1735 wxFileName fileName = wxFileName( *aEvent.Parameter<wxString*>() );
1736
1737 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1738
1739 if( !editFrame )
1740 return 1;
1741
1742 wxString filePath = fileName.GetFullPath();
1744 IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
1745
1746 if( !pi )
1747 return 1;
1748
1749 return AppendBoard( *pi, filePath );
1750}
1751
1752
1754{
1755 view()->SetMirror( !view()->IsMirroredX(), false );
1756 view()->RecacheAllItems();
1759 return 0;
1760}
1761
1762
1764{
1767 Go( &PCB_CONTROL::Print, ACTIONS::print.MakeEvent() );
1768 Go( &PCB_CONTROL::Quit, ACTIONS::quit.MakeEvent() );
1769
1770 // Display modes
1786
1787 // Layer control
1825
1826 // Grid control
1829
1830 Go( &PCB_CONTROL::Undo, ACTIONS::undo.MakeEvent() );
1831 Go( &PCB_CONTROL::Redo, ACTIONS::redo.MakeEvent() );
1832
1833 // Snapping control
1838
1839 // Miscellaneous
1841
1842 // Append control
1845
1846 Go( &PCB_CONTROL::Paste, ACTIONS::paste.MakeEvent() );
1848
1855
1856 // Add library by dropping file
1859}
static TOOL_ACTION paste
Definition: actions.h:70
static TOOL_ACTION addLibrary
Definition: actions.h:49
static TOOL_ACTION pickerTool
Definition: actions.h:189
static TOOL_ACTION gridResetOrigin
Definition: actions.h:170
static TOOL_ACTION pasteSpecial
Definition: actions.h:71
static TOOL_ACTION highContrastModeCycle
Definition: actions.h:134
static TOOL_ACTION undo
Definition: actions.h:66
static TOOL_ACTION highContrastMode
Definition: actions.h:133
static TOOL_ACTION quit
Definition: actions.h:59
static TOOL_ACTION redo
Definition: actions.h:67
static TOOL_ACTION deleteTool
Definition: actions.h:76
static TOOL_ACTION print
Definition: actions.h:57
static TOOL_ACTION newLibrary
Definition: actions.h:48
static TOOL_ACTION gridSetOrigin
Definition: actions.h:169
static TOOL_ACTION ddAddLibrary
Definition: actions.h:60
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
virtual void Revert() override
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.
std::shared_ptr< NET_SETTINGS > m_NetSettings
void SetGridOrigin(const VECTOR2I &aOrigin)
std::shared_ptr< DRC_ENGINE > m_DRCEngine
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:77
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:226
PCB_GROUP * GetParentGroup() const
Definition: board_item.h:91
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition: board_item.h:291
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:260
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: board_item.cpp:228
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:231
virtual bool IsLocked() const
Definition: board_item.cpp:74
virtual bool IsOnCopperLayer() const
Definition: board_item.h:151
virtual std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const
Definition: board_item.cpp:238
virtual bool HasHole() const
Definition: board_item.h:156
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:282
INSPECT_RESULT Visit(INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &scanTypes) override
May be re-implemented for each derived class in order to handle all the types given by its member dat...
Definition: board.cpp:1661
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:680
NETINFO_ITEM * DpCoupledNet(const NETINFO_ITEM *aNet)
Definition: board.cpp:1881
void MapNets(BOARD *aDestBoard)
Map all nets in the given board to nets with the same name (if any) in the destination board.
Definition: board.cpp:2470
void BuildListOfNets()
Definition: board.h:816
const GENERATORS & Generators() const
Definition: board.h:329
const std::vector< BOARD_CONNECTED_ITEM * > AllConnectedItems()
Definition: board.cpp:2444
void SetEnabledLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:700
const PAGE_INFO & GetPageSettings() const
Definition: board.h:671
void SetProperties(const std::map< wxString, wxString > &aProps)
Definition: board.h:355
const ZONES & Zones() const
Definition: board.h:327
const GROUPS & Groups() const
The groups must maintain the following invariants.
Definition: board.h:350
bool BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
Definition: board.cpp:180
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition: board.cpp:1943
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:433
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:677
int GetCopperLayerCount() const
Definition: board.cpp:656
const std::map< wxString, wxString > & GetProperties() const
Definition: board.h:354
const FOOTPRINTS & Footprints() const
Definition: board.h:323
void RemoveAll(std::initializer_list< KICAD_T > aTypes={ PCB_NETINFO_T, PCB_MARKER_T, PCB_GROUP_T, PCB_ZONE_T, PCB_GENERATOR_T, PCB_FOOTPRINT_T, PCB_TRACE_T, PCB_SHAPE_T })
An efficient way to remove all items of a certain type from the board.
Definition: board.cpp:1126
const TRACKS & Tracks() const
Definition: board.h:321
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: board.h:672
void SetVisibleLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
Definition: board.cpp:712
void SetCopperLayerCount(int aCount)
Definition: board.cpp:662
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
Definition: board.cpp:686
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: board.cpp:1623
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:797
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
Definition: board.h:679
const DRAWINGS & Drawings() const
Definition: board.h:325
BOARD_ITEM * Parse()
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:81
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:109
int m_Threshold
Definition: collector.h:234
Color settings are a bit different than most of the settings objects in that there can be more than o...
void SetColor(int aLayer, const COLOR4D &aColor)
COLOR4D GetColor(int aLayer) const
COMMIT & Added(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
Definition: commit.h:86
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
Definition: commit.h:80
DO_NOT_SHOW_AGAIN m_DoNotShowAgain
wxString GetName() const
Definition: drc_rule.h:149
MINOPTMAX< int > & Value()
Definition: drc_rule.h:142
MINOPTMAX< int > m_Value
Definition: drc_rule.h:172
bool IsType(FRAME_T aType) const
WX_INFOBAR * GetInfoBar()
HOTKEY_CYCLE_POPUP * GetHotkeyPopup()
void DisplayToolMsg(const wxString &msg) override
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
virtual COLOR4D GetGridColor()
virtual void Zoom_Automatique(bool aWarpPointer)
Redraw the screen with best zoom level and the best centering that shows all the page or the board.
virtual void CreateHotkeyPopup()
void ForceRefresh()
Force a redraw.
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:88
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:242
virtual void SetPosition(const VECTOR2I &aPos)
Definition: eda_item.h:243
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:126
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:100
virtual void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList)
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: eda_item.h:202
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const
Return a user-visible description string of this item.
Definition: eda_item.cpp:108
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:103
The interactive edit tool.
Definition: edit_tool.h:56
void DeleteItems(const PCB_SELECTION &aItem, bool aIsCut)
Definition: edit_tool.cpp:2265
static const TOOL_EVENT ClearedEvent
Definition: actions.h:262
static const TOOL_EVENT SelectedEvent
Definition: actions.h:260
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:267
static const TOOL_EVENT PointSelectedEvent
Definition: actions.h:259
static const TOOL_EVENT ContrastModeChangedByKeyEvent
Definition: actions.h:281
static const TOOL_EVENT ConnectivityChangedEvent
Selected item had a property changed (except movement)
Definition: actions.h:264
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:261
EDA_ANGLE GetOrientation() const
Definition: footprint.h:212
ZONES & Zones()
Definition: footprint.h:197
void Remove(BOARD_ITEM *aItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: footprint.cpp:1031
void SetPath(const KIID_PATH &aPath)
Definition: footprint.h:250
PCB_FIELD & Value()
read/write accessors:
Definition: footprint.h:624
bool IsFlipped() const
Definition: footprint.h:377
PADS & Pads()
Definition: footprint.h:191
void SetReference(const wxString &aReference)
Definition: footprint.h:594
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: footprint.cpp:1505
PCB_FIELD & Reference()
Definition: footprint.h:625
GROUPS & Groups()
Definition: footprint.h:200
PCB_FIELDS & Fields()
Definition: footprint.h:188
DRAWINGS & GraphicalItems()
Definition: footprint.h:194
A general implementation of a COLLECTORS_GUIDE.
Definition: collectors.h:323
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:206
static const std::vector< KICAD_T > BoardLevelItems
A scan list for all primary board items, omitting items which are subordinate to a FOOTPRINT,...
Definition: collectors.h:237
static const std::vector< KICAD_T > AllBoardItems
A scan list for all editable board items.
Definition: collectors.h:226
void Collect(BOARD_ITEM *aItem, const std::vector< KICAD_T > &aScanList, const VECTOR2I &aRefPos, const COLLECTORS_GUIDE &aGuide)
Scan a BOARD_ITEM using this class's Inspector method, which does the collection.
Definition: collectors.cpp:481
static const std::vector< KICAD_T > FootprintItems
A scan list for primary footprint items.
Definition: collectors.h:252
Similar to EDA_VIEW_SWITCHER, this dialog is a popup that shows feedback when using a hotkey to cycle...
void Popup(const wxString &aTitle, const wxArrayString &aItems, int aSelection)
virtual void SetProgressReporter(PROGRESS_REPORTER *aReporter)
Set an optional progress reporter.
Definition: io_base.h:81
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:47
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
Definition: confirm.cpp:56
int ShowModal() override
Definition: confirm.cpp:100
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
double a
Alpha component.
Definition: color4d.h:395
void SetGridOrigin(const VECTOR2D &aGridOrigin)
Set the origin point for the grid.
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: pcb_view.cpp:75
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false, long aArrowCommand=0)=0
Move cursor to the requested position expressed in world coordinates.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
void SetMirror(bool aMirrorX, bool aMirrorY)
Control the mirroring of the VIEW.
Definition: view.cpp:539
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:315
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:354
GAL * GetGAL() const
Return the #GAL this view is using to draw graphical primitives.
Definition: view.h:197
void RecacheAllItems()
Rebuild GAL display lists.
Definition: view.cpp:1410
void UpdateLayerColor(int aLayer)
Apply the new coloring scheme held by RENDER_SETTINGS in case that it has changed.
Definition: view.cpp:745
void MarkDirty()
Force redraw of view on the next rendering.
Definition: view.h:643
Definition: kiid.h:49
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:575
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
Definition: lset.cpp:177
static LSET InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
Definition: lset.cpp:823
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:863
T Min() const
Definition: minoptmax.h:33
bool HasMax() const
Definition: minoptmax.h:38
T Max() const
Definition: minoptmax.h:34
EDA_MSG_PANEL items for displaying messages.
Definition: msgpanel.h:54
Handle the data for a net.
Definition: netinfo.h:56
static NETINFO_ITEM * OrphanedItem()
NETINFO_ITEM meaning that there was no net assigned for an item, as there was no board storing net li...
Definition: netinfo.h:383
Definition: pad.h:59
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:59
MAGNETIC_SETTINGS m_MagneticItems
static TOOL_ACTION layerToggle
Definition: pcb_actions.h:372
static TOOL_ACTION layerInner12
Definition: pcb_actions.h:348
static TOOL_ACTION layerInner8
Definition: pcb_actions.h:344
static TOOL_ACTION zoneDisplayToggle
Definition: pcb_actions.h:332
static TOOL_ACTION layerInner3
Definition: pcb_actions.h:339
static TOOL_ACTION layerPrev
Definition: pcb_actions.h:369
static TOOL_ACTION showRatsnest
Definition: pcb_actions.h:321
static TOOL_ACTION zoneFillAll
Definition: pcb_actions.h:393
static TOOL_ACTION layerInner2
Definition: pcb_actions.h:338
static TOOL_ACTION magneticSnapAllLayers
Definition: pcb_actions.h:238
static TOOL_ACTION ddAppendBoard
Drag and drop.
Definition: pcb_actions.h:577
static TOOL_ACTION layerInner25
Definition: pcb_actions.h:361
static TOOL_ACTION magneticSnapActiveLayer
Snapping controls.
Definition: pcb_actions.h:237
static TOOL_ACTION layerAlphaDec
Definition: pcb_actions.h:371
static TOOL_ACTION zoneDisplayFilled
Definition: pcb_actions.h:328
static TOOL_ACTION layerInner24
Definition: pcb_actions.h:360
static TOOL_ACTION viaDisplayMode
Definition: pcb_actions.h:327
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:68
static TOOL_ACTION layerInner29
Definition: pcb_actions.h:365
static TOOL_ACTION layerInner11
Definition: pcb_actions.h:347
static TOOL_ACTION layerAlphaInc
Definition: pcb_actions.h:370
static TOOL_ACTION layerInner16
Definition: pcb_actions.h:352
static TOOL_ACTION layerInner26
Definition: pcb_actions.h:362
static TOOL_ACTION layerInner18
Definition: pcb_actions.h:354
static TOOL_ACTION layerInner14
Definition: pcb_actions.h:350
static TOOL_ACTION trackDisplayMode
Definition: pcb_actions.h:325
static TOOL_ACTION magneticSnapToggle
Definition: pcb_actions.h:239
static TOOL_ACTION layerInner6
Definition: pcb_actions.h:342
static TOOL_ACTION ddImportFootprint
Definition: pcb_actions.h:578
static TOOL_ACTION zoneDisplayTriangulated
Definition: pcb_actions.h:331
static TOOL_ACTION layerInner22
Definition: pcb_actions.h:358
static TOOL_ACTION layerInner5
Definition: pcb_actions.h:341
static TOOL_ACTION zoneDisplayFractured
Definition: pcb_actions.h:330
static TOOL_ACTION ratsnestModeCycle
Definition: pcb_actions.h:324
static TOOL_ACTION layerInner20
Definition: pcb_actions.h:356
static TOOL_ACTION layerInner7
Definition: pcb_actions.h:343
static TOOL_ACTION layerInner27
Definition: pcb_actions.h:363
static TOOL_ACTION appendBoard
Definition: pcb_actions.h:533
static TOOL_ACTION netColorModeCycle
Definition: pcb_actions.h:323
static TOOL_ACTION layerInner1
Definition: pcb_actions.h:337
static TOOL_ACTION layerInner10
Definition: pcb_actions.h:346
static TOOL_ACTION layerInner15
Definition: pcb_actions.h:351
static TOOL_ACTION layerInner17
Definition: pcb_actions.h:353
static TOOL_ACTION flipBoard
Definition: pcb_actions.h:379
static TOOL_ACTION layerBottom
Definition: pcb_actions.h:367
static TOOL_ACTION zoneDisplayOutline
Definition: pcb_actions.h:329
static TOOL_ACTION ratsnestLineMode
Definition: pcb_actions.h:322
static TOOL_ACTION layerInner19
Definition: pcb_actions.h:355
static TOOL_ACTION layerInner9
Definition: pcb_actions.h:345
static TOOL_ACTION move
move or drag an item
Definition: pcb_actions.h:120
static TOOL_ACTION layerInner30
Definition: pcb_actions.h:366
static TOOL_ACTION layerTop
Definition: pcb_actions.h:336
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
Definition: pcb_actions.h:76
static TOOL_ACTION layerInner4
Definition: pcb_actions.h:340
static TOOL_ACTION layerInner13
Definition: pcb_actions.h:349
static TOOL_ACTION layerInner21
Definition: pcb_actions.h:357
static TOOL_ACTION layerNext
Definition: pcb_actions.h:368
static TOOL_ACTION layerInner23
Definition: pcb_actions.h:359
static TOOL_ACTION layerInner28
Definition: pcb_actions.h:364
Common, abstract interface for edit frames.
bool AddLibrary(const wxString &aLibName=wxEmptyString, FP_LIB_TABLE *aTable=nullptr)
Add an existing library to either the global or project library table.
void RestoreCopyFromUndoList(wxCommandEvent &aEvent)
Undo the last edit:
Definition: undo_redo.cpp:197
APPEARANCE_CONTROLS * GetAppearancePanel()
void RestoreCopyFromRedoList(wxCommandEvent &aEvent)
Redo the last edit:
Definition: undo_redo.cpp:227
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
virtual void OnDisplayOptionsChanged()
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Display options control the way tracks, vias, outlines and other things are shown (for instance solid...
const VECTOR2I GetPageSizeIU() const override
Works off of GetPageSettings() to return the size of the paper page in the internal units of this par...
PCBNEW_SETTINGS * GetPcbNewSettings() const
virtual void SwitchLayer(PCB_LAYER_ID aLayer)
Change the active layer in the frame.
virtual PCB_LAYER_ID GetActiveLayer() const
void OnModify() override
Must be called after a change in order to set the "modify" flag and update other data structures and ...
virtual void SaveCopyInUndoList(EDA_ITEM *aItemToCopy, UNDO_REDO aTypeCommand)
Create a new entry in undo list of commands.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
BOARD * GetBoard() const
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Returns the BOARD_DESIGN_SETTINGS for the open project.
void SetDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions, bool aRefresh=true)
Updates the current display options from the given options struct.
GENERAL_COLLECTORS_GUIDE GetCollectorsGuide()
virtual BOARD_ITEM_CONTAINER * GetModel() const =0
FOOTPRINT_EDITOR_SETTINGS * GetFootprintEditorSettings() const
virtual COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Helper to retrieve the current color settings.
void setTransitions() override
< Sets up handlers for various events.
int AppendBoardFromFile(const TOOL_EVENT &aEvent)
int AddLibrary(const TOOL_EVENT &aEvent)
int DdAppendBoard(const TOOL_EVENT &aEvent)
int AppendBoard(PCB_IO &pi, wxString &fileName)
int DdImportFootprint(const TOOL_EVENT &aEvent)
int SnapModeFeedback(const TOOL_EVENT &aEvent)
int NetColorModeCycle(const TOOL_EVENT &aEvent)
int RatsnestModeCycle(const TOOL_EVENT &aEvent)
int TrackDisplayMode(const TOOL_EVENT &aEvent)
int DdAddLibrary(const TOOL_EVENT &aEvent)
int Redo(const TOOL_EVENT &aEvent)
int UpdateMessagePanel(const TOOL_EVENT &aEvent)
int LayerAlphaDec(const TOOL_EVENT &aEvent)
int LayerNext(const TOOL_EVENT &aEvent)
std::unique_ptr< STATUS_TEXT_POPUP > m_statusPopup
Definition: pcb_control.h:154
int ToggleRatsnest(const TOOL_EVENT &aEvent)
int LayerAlphaInc(const TOOL_EVENT &aEvent)
int HighContrastModeCycle(const TOOL_EVENT &aEvent)
std::unique_ptr< KIGFX::ORIGIN_VIEWITEM > m_gridOrigin
Definition: pcb_control.h:150
int Quit(const TOOL_EVENT &aEvent)
int HighContrastMode(const TOOL_EVENT &aEvent)
int Undo(const TOOL_EVENT &aEvent)
int ViaDisplayMode(const TOOL_EVENT &aEvent)
PCB_BASE_FRAME * m_frame
Grid origin marker.
Definition: pcb_control.h:147
static void DoSetGridOrigin(KIGFX::VIEW *aView, PCB_BASE_FRAME *aFrame, EDA_ITEM *originViewItem, const VECTOR2D &aPoint)
void pruneItemLayers(std::vector< BOARD_ITEM * > &aItems)
Helper for pasting.
int GridPlaceOrigin(const TOOL_EVENT &aEvent)
int FlipPcbView(const TOOL_EVENT &aEvent)
int SnapMode(const TOOL_EVENT &aEvent)
bool placeBoardItems(BOARD_COMMIT *aCommit, std::vector< BOARD_ITEM * > &aItems, bool aIsNew, bool aAnchorAtOrigin, bool aReannotateDuplicates)
Add and select or just select for move/place command a list of board items.
int ContrastModeFeedback(const TOOL_EVENT &aEvent)
int LayerToggle(const TOOL_EVENT &aEvent)
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
Definition: pcb_control.cpp:91
int Print(const TOOL_EVENT &aEvent)
int ZoneDisplayMode(const TOOL_EVENT &aEvent)
int GridResetOrigin(const TOOL_EVENT &aEvent)
BOARD_ITEM * m_pickerItem
Definition: pcb_control.h:152
int InteractiveDelete(const TOOL_EVENT &aEvent)
int LayerPrev(const TOOL_EVENT &aEvent)
int Paste(const TOOL_EVENT &aEvent)
void unfilledZoneCheck()
We have bug reports indicating that some new users confuse zone filling/unfilling with the display mo...
int LayerSwitch(const TOOL_EVENT &aEvent)
Abstract dimension API.
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
NET_COLOR_MODE m_NetColorMode
How to use color overrides on specific nets and netclasses.
ZONE_DISPLAY_MODE m_ZoneDisplayMode
void UpdateColors()
Update the color settings in the painter and GAL.
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
void RedrawRatsnest()
Return the bounding box of the view that should be used if model is not valid.
The main frame for Pcbnew.
static const TOOL_EVENT SnappingModeChangedByKeyEvent
Hotkey feedback.
Definition: pcb_actions.h:587
int GetId() const
Definition: pcb_field.h:109
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:51
virtual bool RemoveItem(BOARD_ITEM *aItem)
Remove item from group.
Definition: pcb_group.cpp:95
virtual bool AddItem(BOARD_ITEM *aItem)
Add item to group.
Definition: pcb_group.cpp:80
static PCB_IO * PluginFind(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: pcb_io_mgr.cpp:65
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
Definition: pcb_io_mgr.h:56
static PCB_FILE_T FindPluginTypeFromBoardPath(const wxString &aFileName, int aCtl=0)
Return a plugin type given a path for a board file.
Definition: pcb_io_mgr.cpp:108
A base class that BOARD loading and saving plugins should derive from.
Definition: pcb_io.h:72
virtual void SetQueryUserCallback(std::function< bool(wxString aTitle, int aIcon, wxString aMessage, wxString aAction)> aCallback)
Registers a KIDIALOG callback for collecting info from the user.
Definition: pcb_io.h:98
virtual BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const STRING_UTF8_MAP *aProperties=nullptr, PROJECT *aProject=nullptr)
Load information from some input file format that this PCB_IO implementation knows about into either ...
Definition: pcb_io.cpp:75
Generic tool for picking an item.
PCB_LAYER_ID m_Route_Layer_TOP
Definition: pcb_screen.h:43
PCB_LAYER_ID m_Route_Layer_BOTTOM
Definition: pcb_screen.h:44
The selection tool: currently supports:
void GuessSelectionCandidates(GENERAL_COLLECTOR &aCollector, const VECTOR2I &aWhere) const
Try to guess best selection candidates in case multiple items are clicked, by doing some brain-dead h...
bool Selectable(const BOARD_ITEM *aItem, bool checkVisibilityOnly=false) const
void FilterCollectedItems(GENERAL_COLLECTOR &aCollector, bool aMultiSelect)
Apply the SELECTION_FITLER_OPTIONS to the collector.
PCB_GROUP * GetEnteredGroup()
void FilterCollectorForHierarchy(GENERAL_COLLECTOR &aCollector, bool aMultiselect) const
In general we don't want to select both a parent and any of it's children.
PCB_SELECTION & GetSelection()
EDA_ITEM * GetTopLeftItem(bool aFootprintsOnly=false) const override
KIGFX::PCB_VIEW * view() const
PCB_BASE_EDIT_FRAME * frame() const
BOARD * board() const
PCB_DRAW_PANEL_GAL * canvas() const
PCBNEW_SETTINGS::DISPLAY_OPTIONS & displayOptions() const
bool m_isFootprintEditor
const PCB_SELECTION & selection() const
FOOTPRINT * footprint() const
const VECTOR2I & GetStart() const
Definition: pcb_track.h:113
const VECTOR2I & GetEnd() const
Definition: pcb_track.h:110
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:678
void SetMotionHandler(MOTION_HANDLER aHandler)
Set a handler for mouse motion.
Definition: picker_tool.h:83
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:72
void SetCursor(KICURSOR aCursor)
Definition: picker_tool.h:63
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:103
Definition: seg.h:42
ecoord SquaredDistance(const SEG &aSeg) const
Definition: seg.cpp:75
VECTOR2I::extended_type ecoord
Definition: seg.h:44
void BrightenItem(EDA_ITEM *aItem)
void UnbrightenItem(EDA_ITEM *aItem)
virtual void Add(EDA_ITEM *aItem)
Definition: selection.cpp:42
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:99
EDA_ITEM * Front() const
Definition: selection.h:208
int Size() const
Returns the number of selected parts.
Definition: selection.h:115
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.cpp:179
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:109
A name/value tuple with unique names and optional values.
Hold the information shown in the lower right corner of a plot, printout, or editing view.
Definition: title_block.h:41
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:216
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
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:167
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
Definition: tool_event.cpp:82
T Parameter() const
Return a parameter assigned to the event.
Definition: tool_event.h:460
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
void Activate()
Run the tool.
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:145
bool RunSynchronousAction(const TOOL_ACTION &aAction, COMMIT *aCommit, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:192
wxString MessageTextFromMinOptMax(const MINOPTMAX< int > &aValue) const
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:75
A modified version of the wxInfoBar class that allows us to:
Definition: wx_infobar.h:75
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: wx_infobar.cpp:301
void ShowMessageFor(const wxString &aMessage, int aTime, int aFlags=wxICON_INFORMATION, MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the infobar with the provided message and icon for a specific period of time.
Definition: wx_infobar.cpp:140
void AddButton(wxButton *aButton)
Add an already created button to the infobar.
Definition: wx_infobar.cpp:260
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: wx_infobar.cpp:187
Multi-thread safe progress reporter dialog, intended for use of tasks that parallel reporting back of...
Handle a list of polygons defining a copper zone.
Definition: zone.h:72
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:280
This file is part of the common library.
#define ALPHA_MAX
@ DIFF_PAIR_GAP_CONSTRAINT
Definition: drc_rule.h:66
@ EDGE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:50
@ CLEARANCE_CONSTRAINT
Definition: drc_rule.h:47
@ MAX_UNCOUPLED_CONSTRAINT
Definition: drc_rule.h:67
@ HOLE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:48
#define _(s)
Declaration of the eda_3d_viewer class.
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:532
#define SKIP_STRUCT
flag indicating that the structure should be ignored
#define HITTEST_THRESHOLD_PIXELS
@ FRAME_PCB_EDITOR
Definition: frame_type.h:42
@ FRAME_FOOTPRINT_EDITOR
Definition: frame_type.h:43
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Return the key name from the key code.
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition: io_mgr.h:33
#define KICTL_KICAD_ONLY
chosen file is from KiCad according to user
Definition: kiway_player.h:77
int GetNetnameLayer(int aLayer)
Returns a netname layer corresponding to the given layer.
Definition: layer_ids.h:1022
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:881
@ LAYER_RATSNEST
Definition: layer_ids.h:208
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ Edge_Cuts
Definition: layer_ids.h:113
@ B_Cu
Definition: layer_ids.h:95
@ F_Fab
Definition: layer_ids.h:120
@ Margin
Definition: layer_ids.h:114
@ F_SilkS
Definition: layer_ids.h:104
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ B_SilkS
Definition: layer_ids.h:103
@ F_Cu
Definition: layer_ids.h:64
@ B_Fab
Definition: layer_ids.h:119
#define ZONE_LAYER_FOR(boardLayer)
Definition: layer_ids.h:276
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:1022
@ REPAINT
Item needs to be redrawn.
Definition: view_item.h:57
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
bool AskLoadBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, int aCtl=0)
Show a wxFileDialog asking for a BOARD filename to open.
#define ALPHA_STEP
static void pasteFootprintItemsToFootprintEditor(FOOTPRINT *aClipFootprint, BOARD *aBoard, std::vector< BOARD_ITEM * > &aPastedItems)
#define ALPHA_MIN
void Flip(T &aValue)
static void moveUnflaggedItems(const std::deque< T > &aList, std::vector< BOARD_ITEM * > &aTarget, bool aIsNew)
Class to handle a set of BOARD_ITEMs.
bool AskLoadBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, int aCtl=0)
Show a wxFileDialog asking for a BOARD filename to open.
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1059
see class PGM_BASE
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition: typeinfo.h:248
@ PCB_T
Definition: typeinfo.h:82
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition: typeinfo.h:105
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:102
@ 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_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:103
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:110
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:93
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:92
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:101
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition: typeinfo.h:100
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
Definition: typeinfo.h:94
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition: typeinfo.h:104
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:118
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588
Definition of file extensions used in Kicad.