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 {
240 Pgm().GetCommonSettings()->m_DoNotShowAgain.zone_fill_warning = true;
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 const wxString defaultRef = wxT( "REF**" );
928
929 if( aEvent.IsAction( &ACTIONS::pasteSpecial ) )
930 {
931 DIALOG_PASTE_SPECIAL dlg( m_frame, &mode, defaultRef );
932
933 if( dlg.ShowModal() == wxID_CANCEL )
934 return 0;
935 }
936
937 bool isFootprintEditor = m_isFootprintEditor || frame()->IsType( FRAME_FOOTPRINT_EDITOR );
938
939 if( clipItem->Type() == PCB_T )
940 {
941 if( isFootprintEditor )
942 {
943 for( BOARD_CONNECTED_ITEM* item : static_cast<BOARD*>( clipItem )->AllConnectedItems() )
944 item->SetNet( NETINFO_LIST::OrphanedItem() );
945 }
946 else
947 {
948 static_cast<BOARD*>( clipItem )->MapNets( m_frame->GetBoard() );
949 }
950 }
951
952 // The clipboard can contain two different things, an entire kicad_pcb or a single footprint
953 if( isFootprintEditor && ( !board() || !footprint() ) )
954 return 0;
955
956 BOARD_COMMIT commit( frame() );
957 bool cancelled = false;
958
959 switch( clipItem->Type() )
960 {
961 case PCB_T:
962 {
963 BOARD* clipBoard = static_cast<BOARD*>( clipItem );
964
965 if( isFootprintEditor )
966 {
967 FOOTPRINT* editorFootprint = board()->GetFirstFootprint();
968 std::vector<BOARD_ITEM*> pastedItems;
969
970 for( PCB_GROUP* group : clipBoard->Groups() )
971 {
972 group->SetParent( editorFootprint );
973 pastedItems.push_back( group );
974 }
975
976 clipBoard->Groups().clear();
977
978 for( FOOTPRINT* clipFootprint : clipBoard->Footprints() )
979 pasteFootprintItemsToFootprintEditor( clipFootprint, board(), pastedItems );
980
981 for( BOARD_ITEM* clipDrawItem : clipBoard->Drawings() )
982 {
983 switch( clipDrawItem->Type() )
984 {
985 case PCB_TEXT_T:
986 case PCB_TEXTBOX_T:
987 case PCB_SHAPE_T:
989 case PCB_DIM_CENTER_T:
990 case PCB_DIM_LEADER_T:
992 case PCB_DIM_RADIAL_T:
993 clipDrawItem->SetParent( editorFootprint );
994 pastedItems.push_back( clipDrawItem );
995 break;
996
997 default:
998 if( PCB_GROUP* parentGroup = clipDrawItem->GetParentGroup() )
999 parentGroup->RemoveItem( clipDrawItem );
1000
1001 break;
1002 }
1003 }
1004
1005 clipBoard->Drawings().clear();
1006
1007 clipBoard->Visit(
1008 [&]( EDA_ITEM* item, void* testData )
1009 {
1010 // Anything still on the clipboard didn't get copied and needs to be
1011 // removed from the pasted groups.
1012 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( item );
1013 PCB_GROUP* parentGroup = boardItem->GetParentGroup();
1014
1015 if( parentGroup )
1016 parentGroup->RemoveItem( boardItem );
1017
1018 return INSPECT_RESULT::CONTINUE;
1019 },
1021
1022 delete clipBoard;
1023
1024 pruneItemLayers( pastedItems );
1025
1026 cancelled = !placeBoardItems( &commit, pastedItems, true, true,
1027 mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
1028 }
1029 else
1030 {
1031 if( mode == PASTE_MODE::REMOVE_ANNOTATIONS )
1032 {
1033 for( FOOTPRINT* clipFootprint : clipBoard->Footprints() )
1034 clipFootprint->SetReference( defaultRef );
1035 }
1036
1037 cancelled = !placeBoardItems( &commit, clipBoard, true,
1038 mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
1039 }
1040
1041 break;
1042 }
1043
1044 case PCB_FOOTPRINT_T:
1045 {
1046 FOOTPRINT* clipFootprint = static_cast<FOOTPRINT*>( clipItem );
1047 std::vector<BOARD_ITEM*> pastedItems;
1048
1049 if( isFootprintEditor )
1050 {
1051 pasteFootprintItemsToFootprintEditor( clipFootprint, board(), pastedItems );
1052 delete clipFootprint;
1053 }
1054 else
1055 {
1056 if( mode == PASTE_MODE::REMOVE_ANNOTATIONS )
1057 clipFootprint->SetReference( defaultRef );
1058
1059 clipFootprint->SetParent( board() );
1060 pastedItems.push_back( clipFootprint );
1061 }
1062
1063 pruneItemLayers( pastedItems );
1064
1065 cancelled = !placeBoardItems( &commit, pastedItems, true, true,
1066 mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
1067 break;
1068 }
1069
1070 default:
1071 m_frame->DisplayToolMsg( _( "Invalid clipboard contents" ) );
1072 break;
1073 }
1074
1075 if( cancelled )
1076 commit.Revert();
1077 else
1078 commit.Push( _( "Paste" ) );
1079
1080 return 1;
1081}
1082
1083
1085{
1086 wxString fileName;
1087
1088 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1089
1090 if( !editFrame )
1091 return 1;
1092
1093 // Pick a file to append
1094 if( !AskLoadBoardFileName( editFrame, &fileName, KICTL_KICAD_ONLY ) )
1095 return 1;
1096
1097 PCB_IO_MGR::PCB_FILE_T pluginType =
1099 IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
1100
1101 if( !pi )
1102 return 1;
1103
1104 return AppendBoard( *pi, fileName );
1105}
1106
1107
1108template<typename T>
1109static void moveUnflaggedItems( std::deque<T>& aList, std::vector<BOARD_ITEM*>& aTarget,
1110 bool aIsNew )
1111{
1112 std::copy_if( aList.begin(), aList.end(), std::back_inserter( aTarget ),
1113 [aIsNew]( T aItem )
1114 {
1115 bool doCopy = ( aItem->GetFlags() & SKIP_STRUCT ) == 0;
1116
1117 aItem->ClearFlags( SKIP_STRUCT );
1118 aItem->SetFlags( aIsNew ? IS_NEW : 0 );
1119
1120 return doCopy;
1121 } );
1122
1123 if( aIsNew )
1124 aList.clear();
1125}
1126
1127
1128static void moveUnflaggedItems( ZONES& aList, std::vector<BOARD_ITEM*>& aTarget, bool aIsNew )
1129{
1130 if( aList.size() == 0 )
1131 return;
1132
1133 auto obj = aList.front();
1134 int idx = 0;
1135
1136 if( aIsNew )
1137 {
1138 obj = aList.back();
1139 aList.pop_back();
1140 }
1141
1142 for( ; obj ; )
1143 {
1144 if( obj->HasFlag( SKIP_STRUCT ) )
1145 obj->ClearFlags( SKIP_STRUCT );
1146 else
1147 aTarget.push_back( obj );
1148
1149 if( aIsNew )
1150 {
1151 if( aList.size() )
1152 {
1153 obj = aList.back();
1154 aList.pop_back();
1155 }
1156 else
1157 {
1158 obj = nullptr;
1159 }
1160 }
1161 else
1162 {
1163 obj = idx < int(aList.size()-1) ? aList[++idx] : nullptr;
1164 }
1165 }
1166}
1167
1168
1169
1170bool PCB_CONTROL::placeBoardItems( BOARD_COMMIT* aCommit, BOARD* aBoard, bool aAnchorAtOrigin,
1171 bool aReannotateDuplicates )
1172{
1173 // items are new if the current board is not the board source
1174 bool isNew = board() != aBoard;
1175 std::vector<BOARD_ITEM*> items;
1176
1177 moveUnflaggedItems( aBoard->Tracks(), items, isNew );
1178 moveUnflaggedItems( aBoard->Footprints(), items, isNew );
1179 moveUnflaggedItems( aBoard->Drawings(), items, isNew );
1180 moveUnflaggedItems( aBoard->Zones(), items, isNew );
1181
1182 // Subtlety: When selecting a group via the mouse,
1183 // PCB_SELECTION_TOOL::highlightInternal runs, which does a SetSelected() on all
1184 // descendants. In PCB_CONTROL::placeBoardItems, below, we skip that and
1185 // mark items non-recursively. That works because the saving of the
1186 // selection created aBoard that has the group and all descendants in it.
1187 moveUnflaggedItems( aBoard->Groups(), items, isNew );
1188
1189 moveUnflaggedItems( aBoard->Generators(), items, isNew );
1190
1191 pruneItemLayers( items );
1192
1193 return placeBoardItems( aCommit, items, isNew, aAnchorAtOrigin, aReannotateDuplicates );
1194}
1195
1196
1197bool PCB_CONTROL::placeBoardItems( BOARD_COMMIT* aCommit, std::vector<BOARD_ITEM*>& aItems,
1198 bool aIsNew, bool aAnchorAtOrigin, bool aReannotateDuplicates )
1199{
1201
1203
1204 std::vector<BOARD_ITEM*> itemsToSel;
1205 itemsToSel.reserve( aItems.size() );
1206
1207 for( BOARD_ITEM* item : aItems )
1208 {
1209 if( aIsNew )
1210 {
1211 const_cast<KIID&>( item->m_Uuid ) = KIID();
1212
1213 // Even though BOARD_COMMIT::Push() will add any new items to the group, we're
1214 // going to run PCB_ACTIONS::move first, and the move tool will throw out any
1215 // items that aren't in the entered group.
1216 if( selectionTool->GetEnteredGroup() && !item->GetParentGroup() )
1217 selectionTool->GetEnteredGroup()->AddItem( item );
1218
1219 item->SetParent( board() );
1220 }
1221
1222 // Update item attributes if needed
1223 if( BaseType( item->Type() ) == PCB_DIMENSION_T )
1224 {
1225 static_cast<PCB_DIMENSION_BASE*>( item )->UpdateUnits();
1226 }
1227 else if( item->Type() == PCB_FOOTPRINT_T )
1228 {
1229 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
1230
1231 // Update the footprint path with the new KIID path if the footprint is new
1232 if( aIsNew )
1234
1235 for( BOARD_ITEM* dwg : footprint->GraphicalItems() )
1236 {
1237 if( BaseType( dwg->Type() ) == PCB_DIMENSION_T )
1238 static_cast<PCB_DIMENSION_BASE*>( dwg )->UpdateUnits();
1239 }
1240 }
1241
1242 // We only need to add the items that aren't inside a group currently selected
1243 // to the selection. If an item is inside a group and that group is selected,
1244 // then the selection tool will select it for us.
1245 if( !item->GetParentGroup() || !alg::contains( aItems, item->GetParentGroup() ) )
1246 itemsToSel.push_back( item );
1247 }
1248
1249 // Select the items that should be selected
1250 EDA_ITEMS toSel( itemsToSel.begin(), itemsToSel.end() );
1252
1253 // Reannotate duplicate footprints (make sense only in board editor )
1254 if( aReannotateDuplicates && m_isBoardEditor )
1255 m_toolMgr->GetTool<BOARD_REANNOTATE_TOOL>()->ReannotateDuplicatesInSelection();
1256
1257 for( BOARD_ITEM* item : aItems )
1258 {
1259 if( aIsNew )
1260 aCommit->Add( item );
1261 else
1262 aCommit->Added( item );
1263 }
1264
1265 PCB_SELECTION& selection = selectionTool->GetSelection();
1266
1267 if( selection.Size() > 0 )
1268 {
1269 if( aAnchorAtOrigin )
1270 {
1272 }
1273 else
1274 {
1275 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.GetTopLeftItem() );
1277 }
1278
1279 getViewControls()->SetCursorPosition( getViewControls()->GetMousePosition(), false );
1280
1282
1284 }
1285
1286 return true;
1287}
1288
1289
1290int PCB_CONTROL::AppendBoard( PCB_IO& pi, wxString& fileName )
1291{
1292 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1293
1294 if( !editFrame )
1295 return 1;
1296
1297 BOARD* brd = board();
1298
1299 if( !brd )
1300 return 1;
1301
1302 BOARD_COMMIT commit( editFrame );
1303
1304 // Mark existing items, in order to know what are the new items so we can select only
1305 // the new items after loading
1306 for( PCB_TRACK* track : brd->Tracks() )
1307 track->SetFlags( SKIP_STRUCT );
1308
1309 for( FOOTPRINT* footprint : brd->Footprints() )
1311
1312 for( PCB_GROUP* group : brd->Groups() )
1313 group->SetFlags( SKIP_STRUCT );
1314
1315 for( BOARD_ITEM* drawing : brd->Drawings() )
1316 drawing->SetFlags( SKIP_STRUCT );
1317
1318 for( ZONE* zone : brd->Zones() )
1319 zone->SetFlags( SKIP_STRUCT );
1320
1321 for( PCB_GENERATOR* generator : brd->Generators() )
1322 generator->SetFlags( SKIP_STRUCT );
1323
1324 std::map<wxString, wxString> oldProperties = brd->GetProperties();
1325 std::map<wxString, wxString> newProperties;
1326
1327 PAGE_INFO oldPageInfo = brd->GetPageSettings();
1328 TITLE_BLOCK oldTitleBlock = brd->GetTitleBlock();
1329
1330 // Keep also the count of copper layers, to adjust if necessary
1331 int initialCopperLayerCount = brd->GetCopperLayerCount();
1332 LSET initialEnabledLayers = brd->GetEnabledLayers();
1333
1334 // Load the data
1335 try
1336 {
1337 STRING_UTF8_MAP props;
1338
1339 // PCB_IO_EAGLE can use this info to center the BOARD, but it does not yet.
1340
1341 props["page_width"] = std::to_string( editFrame->GetPageSizeIU().x );
1342 props["page_height"] = std::to_string( editFrame->GetPageSizeIU().y );
1343
1345 [&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool
1346 {
1347 KIDIALOG dlg( editFrame, aMessage, aTitle, wxOK | wxCANCEL | aIcon );
1348
1349 if( !aAction.IsEmpty() )
1350 dlg.SetOKLabel( aAction );
1351
1352 dlg.DoNotShowCheckbox( aMessage, 0 );
1353
1354 return dlg.ShowModal() == wxID_OK;
1355 } );
1356
1357 WX_PROGRESS_REPORTER progressReporter( editFrame, _( "Loading PCB" ), 1 );
1358
1359 editFrame->GetDesignSettings().m_NetSettings->m_NetClasses.clear();
1360 pi.SetProgressReporter( &progressReporter );
1361 pi.LoadBoard( fileName, brd, &props, nullptr );
1362 }
1363 catch( const IO_ERROR& ioe )
1364 {
1365 wxString msg = wxString::Format( _( "Error loading board.\n%s" ), ioe.What() );
1366 DisplayError( editFrame, msg );
1367
1368 return 0;
1369 }
1370
1371 newProperties = brd->GetProperties();
1372
1373 for( const std::pair<const wxString, wxString>& prop : oldProperties )
1374 newProperties[ prop.first ] = prop.second;
1375
1376 brd->SetProperties( newProperties );
1377
1378 brd->SetPageSettings( oldPageInfo );
1379 brd->SetTitleBlock( oldTitleBlock );
1380
1381 // rebuild nets and ratsnest before any use of nets
1382 brd->BuildListOfNets();
1383 brd->SynchronizeNetsAndNetClasses( true );
1384 brd->BuildConnectivity();
1385
1386 // Synchronize layers
1387 // we should not ask PLUGINs to do these items:
1388 int copperLayerCount = brd->GetCopperLayerCount();
1389
1390 if( copperLayerCount > initialCopperLayerCount )
1391 brd->SetCopperLayerCount( copperLayerCount );
1392
1393 // Enable all used layers, and make them visible:
1394 LSET enabledLayers = brd->GetEnabledLayers();
1395 enabledLayers |= initialEnabledLayers;
1396 brd->SetEnabledLayers( enabledLayers );
1397 brd->SetVisibleLayers( enabledLayers );
1398
1399 if( placeBoardItems( &commit, brd, false, false /* Don't reannotate dupes on Append Board */ ) )
1400 commit.Push( _( "Append Board" ) );
1401 else
1402 commit.Revert();
1403
1404 // Refresh the UI for the updated board properties
1405 editFrame->GetAppearancePanel()->OnBoardChanged();
1406
1407 return 0;
1408}
1409
1410
1411int PCB_CONTROL::Undo( const TOOL_EVENT& aEvent )
1412{
1413 PCB_BASE_EDIT_FRAME* editFrame = dynamic_cast<PCB_BASE_EDIT_FRAME*>( m_frame );
1414 wxCommandEvent dummy;
1415
1416 if( editFrame )
1417 editFrame->RestoreCopyFromUndoList( dummy );
1418
1419 return 0;
1420}
1421
1422
1423int PCB_CONTROL::Redo( const TOOL_EVENT& aEvent )
1424{
1425 PCB_BASE_EDIT_FRAME* editFrame = dynamic_cast<PCB_BASE_EDIT_FRAME*>( m_frame );
1426 wxCommandEvent dummy;
1427
1428 if( editFrame )
1429 editFrame->RestoreCopyFromRedoList( dummy );
1430
1431 return 0;
1432}
1433
1434
1436{
1440 bool& snapMode = settings.allLayers;
1441
1443 snapMode = false;
1444 else if( aEvent.IsAction( &PCB_ACTIONS::magneticSnapAllLayers ) )
1445 snapMode = true;
1446 else
1447 snapMode = !snapMode;
1448
1450
1451 return 0;
1452}
1453
1454
1456{
1457 if( !Pgm().GetCommonSettings()->m_Input.hotkey_feedback )
1458 return 0;
1459
1460 wxArrayString labels;
1461 labels.Add( _( "Active Layer" ) );
1462 labels.Add( _( "All Layers" ) );
1463
1464 if( !m_frame->GetHotkeyPopup() )
1466
1468
1472
1473 if( popup )
1474 popup->Popup( _( "Object Snapping" ), labels, static_cast<int>( settings.allLayers ) );
1475
1476 return 0;
1477}
1478
1479
1481{
1483 ROUTER_TOOL* routerTool = m_toolMgr->GetTool<ROUTER_TOOL>();
1484 PCB_SELECTION& selection = selTool->GetSelection();
1485 PCB_EDIT_FRAME* pcbFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1486 std::shared_ptr<DRC_ENGINE> drcEngine = m_frame->GetBoard()->GetDesignSettings().m_DRCEngine;
1487 DRC_CONSTRAINT constraint;
1488
1489 std::vector<MSG_PANEL_ITEM> msgItems;
1490
1491 if( routerTool && routerTool->RoutingInProgress() )
1492 {
1493 routerTool->UpdateMessagePanel();
1494 return 0;
1495 }
1496
1497 if( !pcbFrame && !m_frame->GetModel() )
1498 return 0;
1499
1500 if( selection.Empty() )
1501 {
1502 if( !pcbFrame )
1503 {
1504 FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_frame->GetModel() );
1505 fp->GetMsgPanelInfo( m_frame, msgItems );
1506 }
1507 else
1508 {
1510 }
1511 }
1512 else if( selection.GetSize() == 1 )
1513 {
1514 EDA_ITEM* item = selection.Front();
1515
1516 item->GetMsgPanelInfo( m_frame, msgItems );
1517
1518 PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item );
1519 NETINFO_ITEM* net = track ? track->GetNet() : nullptr;
1520 NETINFO_ITEM* coupledNet = net ? m_frame->GetBoard()->DpCoupledNet( net ) : nullptr;
1521
1522 if( coupledNet )
1523 {
1524 SEG trackSeg( track->GetStart(), track->GetEnd() );
1525 PCB_TRACK* coupledItem = nullptr;
1526 SEG::ecoord closestDist_sq = VECTOR2I::ECOORD_MAX;
1527
1528 for( PCB_TRACK* candidate : m_frame->GetBoard()->Tracks() )
1529 {
1530 if( candidate->GetNet() != coupledNet )
1531 continue;
1532
1533 SEG::ecoord dist_sq = trackSeg.SquaredDistance( SEG( candidate->GetStart(),
1534 candidate->GetEnd() ) );
1535
1536 if( !coupledItem || dist_sq < closestDist_sq )
1537 {
1538 coupledItem = candidate;
1539 closestDist_sq = dist_sq;
1540 }
1541 }
1542
1543 constraint = drcEngine->EvalRules( DIFF_PAIR_GAP_CONSTRAINT, track, coupledItem,
1544 track->GetLayer() );
1545
1546 wxString msg = m_frame->MessageTextFromMinOptMax( constraint.Value() );
1547
1548 if( !msg.IsEmpty() )
1549 {
1550 msgItems.emplace_back( wxString::Format( _( "DP Gap Constraints: %s" ), msg ),
1551 wxString::Format( _( "(from %s)" ), constraint.GetName() ) );
1552 }
1553
1554 constraint = drcEngine->EvalRules( MAX_UNCOUPLED_CONSTRAINT, track,
1555 coupledItem, track->GetLayer() );
1556
1557 if( constraint.Value().HasMax() )
1558 {
1559 msg = m_frame->MessageTextFromValue( constraint.Value().Max() );
1560 msgItems.emplace_back( wxString::Format( _( "DP Max Uncoupled-length: %s" ), msg ),
1561 wxString::Format( _( "(from %s)" ), constraint.GetName() ) );
1562 }
1563 }
1564 }
1565 else if( pcbFrame && selection.GetSize() == 2 )
1566 {
1567 // Pair selection broken into multiple, optional data, starting with the selected item
1568 // names
1569
1570 BOARD_ITEM* a = static_cast<BOARD_ITEM*>( selection[0] );
1571 BOARD_ITEM* b = static_cast<BOARD_ITEM*>( selection[1] );
1572
1573 msgItems.emplace_back( MSG_PANEL_ITEM( a->GetItemDescription( m_frame ),
1574 b->GetItemDescription( m_frame ) ) );
1575
1576 BOARD_CONNECTED_ITEM* a_conn = dyn_cast<BOARD_CONNECTED_ITEM*>( a );
1577 BOARD_CONNECTED_ITEM* b_conn = dyn_cast<BOARD_CONNECTED_ITEM*>( b );
1578
1579 if( a_conn && b_conn )
1580 {
1581 LSET overlap = a_conn->GetLayerSet() & b_conn->GetLayerSet() & LSET::AllCuMask();
1582 int a_netcode = a_conn->GetNetCode();
1583 int b_netcode = b_conn->GetNetCode();
1584
1585 if( overlap.count() > 0
1586 && ( a_netcode != b_netcode || a_netcode < 0 || b_netcode < 0 ) )
1587 {
1588 PCB_LAYER_ID layer = overlap.CuStack().front();
1589
1590 constraint = drcEngine->EvalRules( CLEARANCE_CONSTRAINT, a, b, layer );
1591 msgItems.emplace_back( _( "Resolved clearance" ),
1592 m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
1593
1594 std::shared_ptr<SHAPE> a_shape( a_conn->GetEffectiveShape( layer ) );
1595 std::shared_ptr<SHAPE> b_shape( b_conn->GetEffectiveShape( layer ) );
1596
1597 int actual_clearance = a_shape->GetClearance( b_shape.get() );
1598
1599 if( actual_clearance > -1 && actual_clearance < std::numeric_limits<int>::max() )
1600 {
1601 msgItems.emplace_back( _( "Actual clearance" ),
1602 m_frame->MessageTextFromValue( actual_clearance ) );
1603 }
1604 }
1605 }
1606
1607 if( ( a->HasHole() || b->HasHole() ) )
1608 {
1611
1612 if( b->IsOnLayer( active ) && IsCopperLayer( active ) )
1613 layer = active;
1614 else if( b->HasHole() && a->IsOnLayer( active ) && IsCopperLayer( active ) )
1615 layer = active;
1616 else if( a->HasHole() && b->IsOnCopperLayer() )
1617 layer = b->GetLayer();
1618 else if( b->HasHole() && a->IsOnCopperLayer() )
1619 layer = a->GetLayer();
1620
1621 if( IsCopperLayer( layer ) )
1622 {
1623 int actual = std::numeric_limits<int>::max();
1624
1625 if( a->HasHole() && b->IsOnCopperLayer() )
1626 {
1627 std::shared_ptr<SHAPE_SEGMENT> hole = a->GetEffectiveHoleShape();
1628 std::shared_ptr<SHAPE> other( b->GetEffectiveShape( layer ) );
1629
1630 actual = std::min( actual, hole->GetClearance( other.get() ) );
1631 }
1632
1633 if( b->HasHole() && a->IsOnCopperLayer() )
1634 {
1635 std::shared_ptr<SHAPE_SEGMENT> hole = b->GetEffectiveHoleShape();
1636 std::shared_ptr<SHAPE> other( a->GetEffectiveShape( layer ) );
1637
1638 actual = std::min( actual, hole->GetClearance( other.get() ) );
1639 }
1640
1641 if( actual < std::numeric_limits<int>::max() )
1642 {
1643 constraint = drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer );
1644 msgItems.emplace_back( _( "Resolved hole clearance" ),
1645 m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
1646
1647 if( actual > -1 && actual < std::numeric_limits<int>::max() )
1648 {
1649 msgItems.emplace_back( _( "Actual hole clearance" ),
1650 m_frame->MessageTextFromValue( actual ) );
1651 }
1652 }
1653 }
1654 }
1655
1656 for( PCB_LAYER_ID edgeLayer : { Edge_Cuts, Margin } )
1657 {
1660
1661 if( a->IsOnLayer( edgeLayer ) && b->Type() != PCB_FOOTPRINT_T )
1662 {
1663 if( b->IsOnLayer( active ) && IsCopperLayer( active ) )
1664 layer = active;
1665 else if( IsCopperLayer( b->GetLayer() ) )
1666 layer = b->GetLayer();
1667 }
1668 else if( b->IsOnLayer( edgeLayer ) && a->Type() != PCB_FOOTPRINT_T )
1669 {
1670 if( a->IsOnLayer( active ) && IsCopperLayer( active ) )
1671 layer = active;
1672 else if( IsCopperLayer( a->GetLayer() ) )
1673 layer = a->GetLayer();
1674 }
1675
1676 if( layer >= 0 )
1677 {
1678 constraint = drcEngine->EvalRules( EDGE_CLEARANCE_CONSTRAINT, a, b, layer );
1679
1680 if( edgeLayer == Edge_Cuts )
1681 {
1682 msgItems.emplace_back( _( "Resolved edge clearance" ),
1683 m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
1684 }
1685 else
1686 {
1687 msgItems.emplace_back( _( "Resolved margin clearance" ),
1688 m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
1689 }
1690 }
1691 }
1692 }
1693
1694 if( msgItems.empty() )
1695 {
1696 if( selection.GetSize() )
1697 {
1698 msgItems.emplace_back( _( "Selected Items" ),
1699 wxString::Format( wxT( "%d" ), selection.GetSize() ) );
1700
1701 if( m_isBoardEditor )
1702 {
1703 std::set<wxString> netNames;
1704 std::set<wxString> netClasses;
1705
1706 for( EDA_ITEM* item : selection )
1707 {
1708 if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
1709 {
1710 netNames.insert( UnescapeString( bci->GetNetname() ) );
1711 netClasses.insert( UnescapeString( bci->GetEffectiveNetClass()->GetName() ) );
1712
1713 if( netNames.size() > 1 && netClasses.size() > 1 )
1714 break;
1715 }
1716 }
1717
1718 if( netNames.size() == 1 )
1719 msgItems.emplace_back( _( "Net" ), *netNames.begin() );
1720
1721 if( netClasses.size() == 1 )
1722 msgItems.emplace_back( _( "Resolved Netclass" ), *netClasses.begin() );
1723 }
1724 }
1725 else
1726 {
1727 m_frame->GetBoard()->GetMsgPanelInfo( m_frame, msgItems );
1728 }
1729 }
1730
1731 m_frame->SetMsgPanel( msgItems );
1732
1733 return 0;
1734}
1735
1736
1738{
1739 wxFileName fileName = wxFileName( *aEvent.Parameter<wxString*>() );
1740
1741 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1742
1743 if( !editFrame )
1744 return 1;
1745
1746 wxString filePath = fileName.GetFullPath();
1748 IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
1749
1750 if( !pi )
1751 return 1;
1752
1753 return AppendBoard( *pi, filePath );
1754}
1755
1756
1758{
1759 view()->SetMirror( !view()->IsMirroredX(), false );
1760 view()->RecacheAllItems();
1763 return 0;
1764}
1765
1766
1768{
1771 Go( &PCB_CONTROL::Print, ACTIONS::print.MakeEvent() );
1772 Go( &PCB_CONTROL::Quit, ACTIONS::quit.MakeEvent() );
1773
1774 // Display modes
1790
1791 // Layer control
1829
1830 // Grid control
1833
1834 Go( &PCB_CONTROL::Undo, ACTIONS::undo.MakeEvent() );
1835 Go( &PCB_CONTROL::Redo, ACTIONS::redo.MakeEvent() );
1836
1837 // Snapping control
1842
1843 // Miscellaneous
1845
1846 // Append control
1849
1850 Go( &PCB_CONTROL::Paste, ACTIONS::paste.MakeEvent() );
1852
1859
1860 // Add library by dropping file
1863}
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:276
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:1531
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:689
NETINFO_ITEM * DpCoupledNet(const NETINFO_ITEM *aNet)
Definition: board.cpp:1751
void BuildListOfNets()
Definition: board.h:795
void SetEnabledLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:709
const PAGE_INFO & GetPageSettings() const
Definition: board.h:650
void SetProperties(const std::map< wxString, wxString > &aProps)
Definition: board.h:349
ZONES & Zones()
Definition: board.h:324
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:189
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition: board.cpp:1813
GENERATORS & Generators()
Definition: board.h:327
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:414
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:656
FOOTPRINTS & Footprints()
Definition: board.h:318
int GetCopperLayerCount() const
Definition: board.cpp:665
const std::map< wxString, wxString > & GetProperties() const
Definition: board.h:348
GROUPS & Groups()
The groups must maintain the following invariants.
Definition: board.h:343
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: board.h:651
TRACKS & Tracks()
Definition: board.h:315
void SetVisibleLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
Definition: board.cpp:721
void SetCopperLayerCount(int aCount)
Definition: board.cpp:671
DRAWINGS & Drawings()
Definition: board.h:321
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:695
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:1493
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:806
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
Definition: board.h:658
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
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:85
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:239
virtual void SetPosition(const VECTOR2I &aPos)
Definition: eda_item.h:240
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:123
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
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:199
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:100
The interactive edit tool.
Definition: edit_tool.h:55
void DeleteItems(const PCB_SELECTION &aItem, bool aIsCut)
Definition: edit_tool.cpp:2220
static const TOOL_EVENT ClearedEvent
Definition: actions.h:259
static const TOOL_EVENT SelectedEvent
Definition: actions.h:257
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:264
static const TOOL_EVENT PointSelectedEvent
Definition: actions.h:256
static const TOOL_EVENT ContrastModeChangedByKeyEvent
Definition: actions.h:278
static const TOOL_EVENT ConnectivityChangedEvent
Selected item had a property changed (except movement)
Definition: actions.h:261
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:258
EDA_ANGLE GetOrientation() const
Definition: footprint.h:209
ZONES & Zones()
Definition: footprint.h:194
void Remove(BOARD_ITEM *aItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: footprint.cpp:783
void SetPath(const KIID_PATH &aPath)
Definition: footprint.h:243
PCB_FIELD & Value()
read/write accessors:
Definition: footprint.h:617
bool IsFlipped() const
Definition: footprint.h:370
PADS & Pads()
Definition: footprint.h:188
void SetReference(const wxString &aReference)
Definition: footprint.h:587
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:1262
PCB_FIELD & Reference()
Definition: footprint.h:618
GROUPS & Groups()
Definition: footprint.h:197
PCB_FIELDS & Fields()
Definition: footprint.h:185
DRAWINGS & GraphicalItems()
Definition: footprint.h:191
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:78
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:379
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:1415
void UpdateLayerColor(int aLayer)
Apply the new coloring scheme held by RENDER_SETTINGS in case that it has changed.
Definition: view.cpp:742
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:573
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:371
static TOOL_ACTION layerInner12
Definition: pcb_actions.h:347
static TOOL_ACTION layerInner8
Definition: pcb_actions.h:343
static TOOL_ACTION zoneDisplayToggle
Definition: pcb_actions.h:331
static TOOL_ACTION layerInner3
Definition: pcb_actions.h:338
static TOOL_ACTION layerPrev
Definition: pcb_actions.h:368
static TOOL_ACTION showRatsnest
Definition: pcb_actions.h:320
static TOOL_ACTION zoneFillAll
Definition: pcb_actions.h:392
static TOOL_ACTION layerInner2
Definition: pcb_actions.h:337
static TOOL_ACTION magneticSnapAllLayers
Definition: pcb_actions.h:237
static TOOL_ACTION ddAppendBoard
Drag and drop.
Definition: pcb_actions.h:577
static TOOL_ACTION layerInner25
Definition: pcb_actions.h:360
static TOOL_ACTION magneticSnapActiveLayer
Snapping controls.
Definition: pcb_actions.h:236
static TOOL_ACTION layerAlphaDec
Definition: pcb_actions.h:370
static TOOL_ACTION zoneDisplayFilled
Definition: pcb_actions.h:327
static TOOL_ACTION layerInner24
Definition: pcb_actions.h:359
static TOOL_ACTION viaDisplayMode
Definition: pcb_actions.h:326
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:68
static TOOL_ACTION layerInner29
Definition: pcb_actions.h:364
static TOOL_ACTION layerInner11
Definition: pcb_actions.h:346
static TOOL_ACTION layerAlphaInc
Definition: pcb_actions.h:369
static TOOL_ACTION layerInner16
Definition: pcb_actions.h:351
static TOOL_ACTION layerInner26
Definition: pcb_actions.h:361
static TOOL_ACTION layerInner18
Definition: pcb_actions.h:353
static TOOL_ACTION layerInner14
Definition: pcb_actions.h:349
static TOOL_ACTION trackDisplayMode
Definition: pcb_actions.h:324
static TOOL_ACTION magneticSnapToggle
Definition: pcb_actions.h:238
static TOOL_ACTION layerInner6
Definition: pcb_actions.h:341
static TOOL_ACTION ddImportFootprint
Definition: pcb_actions.h:578
static TOOL_ACTION zoneDisplayTriangulated
Definition: pcb_actions.h:330
static TOOL_ACTION layerInner22
Definition: pcb_actions.h:357
static TOOL_ACTION layerInner5
Definition: pcb_actions.h:340
static TOOL_ACTION zoneDisplayFractured
Definition: pcb_actions.h:329
static TOOL_ACTION ratsnestModeCycle
Definition: pcb_actions.h:323
static TOOL_ACTION layerInner20
Definition: pcb_actions.h:355
static TOOL_ACTION layerInner7
Definition: pcb_actions.h:342
static TOOL_ACTION layerInner27
Definition: pcb_actions.h:362
static TOOL_ACTION appendBoard
Definition: pcb_actions.h:533
static TOOL_ACTION netColorModeCycle
Definition: pcb_actions.h:322
static TOOL_ACTION layerInner1
Definition: pcb_actions.h:336
static TOOL_ACTION layerInner10
Definition: pcb_actions.h:345
static TOOL_ACTION layerInner15
Definition: pcb_actions.h:350
static TOOL_ACTION layerInner17
Definition: pcb_actions.h:352
static TOOL_ACTION flipBoard
Definition: pcb_actions.h:378
static TOOL_ACTION layerBottom
Definition: pcb_actions.h:366
static TOOL_ACTION zoneDisplayOutline
Definition: pcb_actions.h:328
static TOOL_ACTION ratsnestLineMode
Definition: pcb_actions.h:321
static TOOL_ACTION layerInner19
Definition: pcb_actions.h:354
static TOOL_ACTION layerInner9
Definition: pcb_actions.h:344
static TOOL_ACTION move
move or drag an item
Definition: pcb_actions.h:120
static TOOL_ACTION layerInner30
Definition: pcb_actions.h:365
static TOOL_ACTION layerTop
Definition: pcb_actions.h:335
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:339
static TOOL_ACTION layerInner13
Definition: pcb_actions.h:348
static TOOL_ACTION layerInner21
Definition: pcb_actions.h:356
static TOOL_ACTION layerNext
Definition: pcb_actions.h:367
static TOOL_ACTION layerInner23
Definition: pcb_actions.h:358
static TOOL_ACTION layerInner28
Definition: pcb_actions.h:363
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:106
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
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:529
#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:1020
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:879
@ LAYER_RATSNEST
Definition: layer_ids.h:207
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ Edge_Cuts
Definition: layer_ids.h:114
@ B_Cu
Definition: layer_ids.h:96
@ F_Fab
Definition: layer_ids.h:121
@ Margin
Definition: layer_ids.h:115
@ F_SilkS
Definition: layer_ids.h:105
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ B_SilkS
Definition: layer_ids.h:104
@ F_Cu
Definition: layer_ids.h:65
@ B_Fab
Definition: layer_ids.h:120
#define ZONE_LAYER_FOR(boardLayer)
Definition: layer_ids.h:275
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)
static void moveUnflaggedItems(std::deque< T > &aList, std::vector< BOARD_ITEM * > &aTarget, bool aIsNew)
#define ALPHA_MIN
void Flip(T &aValue)
Class to handle a set of BOARD_ITEMs.
std::vector< ZONE * > ZONES
Definition: pcb_io_eagle.h:46
bool AskLoadBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, int aCtl=0)
Show a wxFileDialog asking for a BOARD filename to open.
see class PGM_BASE
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:119
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:257
@ 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_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:85
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588
Definition of file extensions used in Kicad.