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 The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Maciej Suminski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include "pcb_control.h"
28
29#include <kiplatform/ui.h>
30#include <tools/edit_tool.h>
32#include <router/router_tool.h>
33#include <pgm_base.h>
34#include <tools/pcb_actions.h>
39#include <board_commit.h>
40#include <board.h>
42#include <board_item.h>
43#include <clipboard.h>
44#include <design_block.h>
46#include <pcb_dimension.h>
48#include <footprint.h>
49#include <layer_pairs.h>
50#include <pcb_group.h>
52#include <pcb_reference_image.h>
53#include <pcb_textbox.h>
54#include <pcb_track.h>
55#include <pcb_generator.h>
57#include <zone.h>
58#include <confirm.h>
59#include <kidialog.h>
61#include <core/kicad_algo.h>
63#include <kicad_clipboard.h>
64#include <origin_viewitem.h>
65#include <pcb_edit_frame.h>
66#include <pcb_painter.h>
68#include <string>
69#include <tool/tool_manager.h>
76#include <widgets/wx_infobar.h>
77#include <wx/hyperlink.h>
78
79
80using namespace std::placeholders;
81
82
83// files.cpp
84extern bool AskLoadBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, int aCtl = 0 );
85
86
88 PCB_TOOL_BASE( "pcbnew.Control" ),
89 m_frame( nullptr ),
90 m_pickerItem( nullptr )
91{
93}
94
95
97{
98}
99
100
102{
103 m_frame = getEditFrame<PCB_BASE_FRAME>();
104
105 if( aReason == MODEL_RELOAD || aReason == GAL_SWITCH || aReason == REDRAW )
106 {
107 m_gridOrigin->SetPosition( board()->GetDesignSettings().GetGridOrigin() );
108 m_gridOrigin->SetColor( m_frame->GetGridColor() );
109 getView()->Remove( m_gridOrigin.get() );
110 getView()->Add( m_gridOrigin.get() );
111 }
112}
113
114
116{
118 {
119 if( aEvent.IsAction( &ACTIONS::newLibrary ) )
120 static_cast<PCB_BASE_EDIT_FRAME*>( m_frame )->CreateNewLibrary();
121 else if( aEvent.IsAction( &ACTIONS::addLibrary ) )
122 static_cast<PCB_BASE_EDIT_FRAME*>( m_frame )->AddLibrary();
123 }
124
125 return 0;
126}
127
128
130{
132 static_cast<FOOTPRINT_EDIT_FRAME*>( m_frame )->LoadFootprintFromBoard( nullptr );
133
134 return 0;
135}
136
137
139{
141 static_cast<FOOTPRINT_EDIT_FRAME*>( m_frame )->SaveFootprintToBoard( true );
144
145 return 0;
146}
147
148
150{
151 const wxString fn = *aEvent.Parameter<wxString*>();
152 static_cast<PCB_BASE_EDIT_FRAME*>( m_frame )->AddLibrary( fn );
153 return 0;
154}
155
156
158{
159 const wxString fn = *aEvent.Parameter<wxString*>();
160 static_cast<FOOTPRINT_EDIT_FRAME*>( m_frame )->ImportFootprint( fn );
161 m_frame->Zoom_Automatique( false );
162 return 0;
163}
164
165
167{
169 static_cast<FOOTPRINT_VIEWER_FRAME*>( m_frame )->SelectAndViewFootprint( aEvent.Parameter<FPVIEWER_CONSTANTS>() );
170
171 return 0;
172}
173
174
175int PCB_CONTROL::Quit( const TOOL_EVENT& aEvent )
176{
177 m_frame->Close( false );
178 return 0;
179}
180
181
182template<class T> void Flip( T& aValue )
183{
184 aValue = !aValue;
185}
186
187
189{
190 Flip( displayOptions().m_DisplayPcbTrackFill );
191
192 for( PCB_TRACK* track : board()->Tracks() )
193 {
194 if( track->Type() == PCB_TRACE_T || track->Type() == PCB_ARC_T )
195 view()->Update( track, KIGFX::REPAINT );
196 }
197
198 for( BOARD_ITEM* shape : board()->Drawings() )
199 {
200 if( shape->Type() == PCB_SHAPE_T && static_cast<PCB_SHAPE*>( shape )->IsOnCopperLayer() )
201 view()->Update( shape, KIGFX::REPAINT );
202 }
203
204 canvas()->Refresh();
205
206 return 0;
207}
208
209
211{
212 if( aEvent.IsAction( &PCB_ACTIONS::showRatsnest ) )
213 {
214 // N.B. Do not disable the Ratsnest layer here. We use it for local ratsnest
215 Flip( displayOptions().m_ShowGlobalRatsnest );
216 getEditFrame<PCB_EDIT_FRAME>()->SetElementVisibility( LAYER_RATSNEST,
217 displayOptions().m_ShowGlobalRatsnest );
218
219 }
220 else if( aEvent.IsAction( &PCB_ACTIONS::ratsnestLineMode ) )
221 {
222 Flip( displayOptions().m_DisplayRatsnestLinesCurved );
223 }
224
225 frame()->OnDisplayOptionsChanged();
226
228 canvas()->Refresh();
229
230 return 0;
231}
232
233
235{
236 Flip( displayOptions().m_DisplayViaFill );
237
238 for( PCB_TRACK* track : board()->Tracks() )
239 {
240 if( track->Type() == PCB_VIA_T )
241 view()->Update( track, KIGFX::REPAINT );
242 }
243
244 canvas()->Refresh();
245 return 0;
246}
247
248
255{
256 if( Pgm().GetCommonSettings()->m_DoNotShowAgain.zone_fill_warning )
257 return;
258
259 bool unfilledZones = false;
260
261 for( const ZONE* zone : board()->Zones() )
262 {
263 if( !zone->GetIsRuleArea() && !zone->IsFilled() )
264 {
265 unfilledZones = true;
266 break;
267 }
268 }
269
270 if( unfilledZones )
271 {
272 WX_INFOBAR* infobar = frame()->GetInfoBar();
273 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, _( "Don't show again" ),
274 wxEmptyString );
275
276 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
277 [&]( wxHyperlinkEvent& aEvent )
278 {
280 frame()->GetInfoBar()->Dismiss();
281 } ) );
282
283 infobar->RemoveAllButtons();
284 infobar->AddButton( button );
285
286 wxString msg;
287 msg.Printf( _( "Not all zones are filled. Use Edit > Fill All Zones (%s) "
288 "if you wish to see all fills." ),
290
291 infobar->ShowMessageFor( msg, 5000, wxICON_WARNING );
292 }
293}
294
295
297{
298 PCB_DISPLAY_OPTIONS opts = frame()->GetDisplayOptions();
299
300 // Apply new display options to the GAL canvas
302 {
304
305 opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_FILLED;
306 }
307 else if( aEvent.IsAction( &PCB_ACTIONS::zoneDisplayOutline ) )
308 {
309 opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_ZONE_OUTLINE;
310 }
311 else if( aEvent.IsAction( &PCB_ACTIONS::zoneDisplayFractured ) )
312 {
313 opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_FRACTURE_BORDERS;
314 }
316 {
317 opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_TRIANGULATION;
318 }
319 else if( aEvent.IsAction( &PCB_ACTIONS::zoneDisplayToggle ) )
320 {
321 if( opts.m_ZoneDisplayMode == ZONE_DISPLAY_MODE::SHOW_FILLED )
322 opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_ZONE_OUTLINE;
323 else
324 opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_FILLED;
325 }
326 else
327 {
328 wxFAIL;
329 }
330
331 m_frame->SetDisplayOptions( opts );
332
333 for( ZONE* zone : board()->Zones() )
334 view()->Update( zone, KIGFX::REPAINT );
335
336 canvas()->Refresh();
337
338 return 0;
339}
340
341
343{
344 PCB_DISPLAY_OPTIONS opts = frame()->GetDisplayOptions();
345
346 opts.m_ContrastModeDisplay = opts.m_ContrastModeDisplay == HIGH_CONTRAST_MODE::NORMAL
347 ? HIGH_CONTRAST_MODE::DIMMED
348 : HIGH_CONTRAST_MODE::NORMAL;
349
350 m_frame->SetDisplayOptions( opts );
351 return 0;
352}
353
354
356{
357 PCB_DISPLAY_OPTIONS opts = frame()->GetDisplayOptions();
358
359 switch( opts.m_ContrastModeDisplay )
360 {
361 case HIGH_CONTRAST_MODE::NORMAL: opts.m_ContrastModeDisplay = HIGH_CONTRAST_MODE::DIMMED; break;
362 case HIGH_CONTRAST_MODE::DIMMED: opts.m_ContrastModeDisplay = HIGH_CONTRAST_MODE::HIDDEN; break;
363 case HIGH_CONTRAST_MODE::HIDDEN: opts.m_ContrastModeDisplay = HIGH_CONTRAST_MODE::NORMAL; break;
364 }
365
366 m_frame->SetDisplayOptions( opts );
367
369 return 0;
370}
371
372
374{
375 if( !Pgm().GetCommonSettings()->m_Input.hotkey_feedback )
376 return 0;
377
378 PCB_DISPLAY_OPTIONS opts = frame()->GetDisplayOptions();
379
380 wxArrayString labels;
381 labels.Add( _( "Normal" ) );
382 labels.Add( _( "Dimmed" ) );
383 labels.Add( _( "Hidden" ) );
384
385 if( !m_frame->GetHotkeyPopup() )
387
389
390 if( popup )
391 {
392 popup->Popup( _( "Inactive Layer Display" ), labels,
393 static_cast<int>( opts.m_ContrastModeDisplay ) );
394 }
395
396 return 0;
397}
398
399
401{
402 PCB_DISPLAY_OPTIONS opts = frame()->GetDisplayOptions();
403
404 switch( opts.m_NetColorMode )
405 {
406 case NET_COLOR_MODE::ALL: opts.m_NetColorMode = NET_COLOR_MODE::RATSNEST; break;
407 case NET_COLOR_MODE::RATSNEST: opts.m_NetColorMode = NET_COLOR_MODE::OFF; break;
408 case NET_COLOR_MODE::OFF: opts.m_NetColorMode = NET_COLOR_MODE::ALL; break;
409 }
410
411 m_frame->SetDisplayOptions( opts );
412 return 0;
413}
414
415
417{
418 if( !displayOptions().m_ShowGlobalRatsnest )
419 {
421 displayOptions().m_RatsnestMode = RATSNEST_MODE::ALL;
422 }
423 else if( displayOptions().m_RatsnestMode == RATSNEST_MODE::ALL )
424 {
425 displayOptions().m_RatsnestMode = RATSNEST_MODE::VISIBLE;
426 }
427 else
428 {
430 }
431
432 getEditFrame<PCB_EDIT_FRAME>()->SetElementVisibility( LAYER_RATSNEST,
433 displayOptions().m_ShowGlobalRatsnest );
434
435 frame()->OnDisplayOptionsChanged();
436
438 canvas()->Refresh();
439 return 0;
440}
441
442
444{
446
447 return 0;
448}
449
450
452{
453 PCB_BASE_FRAME* editFrame = m_frame;
454 BOARD* brd = board();
455 PCB_LAYER_ID layer = editFrame->GetActiveLayer();
456 bool wraparound = false;
457
458 if( !IsCopperLayer( layer ) )
459 {
460 editFrame->SwitchLayer( B_Cu );
461 return 0;
462 }
463
464 LSET cuMask = LSET::AllCuMask( brd->GetCopperLayerCount() );
465 LSEQ layerStack = cuMask.UIOrder();
466
467 int ii = 0;
468
469 // Find the active layer in list
470 for( ; ii < (int)layerStack.size(); ii++ )
471 {
472 if( layer == layerStack[ii] )
473 break;
474 }
475
476 // Find the next visible layer in list
477 for( ; ii < (int)layerStack.size(); ii++ )
478 {
479 int jj = ii+1;
480
481 if( jj >= (int)layerStack.size() )
482 jj = 0;
483
484 layer = layerStack[jj];
485
486 if( brd->IsLayerVisible( layer ) )
487 break;
488
489 if( jj == 0 ) // the end of list is reached. Try from the beginning
490 {
491 if( wraparound )
492 {
493 wxBell();
494 return 0;
495 }
496 else
497 {
498 wraparound = true;
499 ii = -1;
500 }
501 }
502 }
503
504 wxCHECK( IsCopperLayer( layer ), 0 );
505 editFrame->SwitchLayer( layer );
506
507 return 0;
508}
509
510
512{
513 PCB_BASE_FRAME* editFrame = m_frame;
514 BOARD* brd = board();
515 PCB_LAYER_ID layer = editFrame->GetActiveLayer();
516 bool wraparound = false;
517
518 if( !IsCopperLayer( layer ) )
519 {
520 editFrame->SwitchLayer( F_Cu );
521 return 0;
522 }
523
524 LSET cuMask = LSET::AllCuMask( brd->GetCopperLayerCount() );
525 LSEQ layerStack = cuMask.UIOrder();
526
527 int ii = 0;
528
529 // Find the active layer in list
530 for( ; ii < (int)layerStack.size(); ii++ )
531 {
532 if( layer == layerStack[ii] )
533 break;
534 }
535
536 // Find the previous visible layer in list
537 for( ; ii >= 0; ii-- )
538 {
539 int jj = ii - 1;
540
541 if( jj < 0 )
542 jj = (int)layerStack.size() - 1;
543
544 layer = layerStack[jj];
545
546 if( brd->IsLayerVisible( layer ) )
547 break;
548
549 if( ii == 0 ) // the start of list is reached. Try from the last
550 {
551 if( wraparound )
552 {
553 wxBell();
554 return 0;
555 }
556 else
557 {
558 wraparound = true;
559 ii = 1;
560 }
561 }
562 }
563
564 wxCHECK( IsCopperLayer( layer ), 0 );
565 editFrame->SwitchLayer( layer );
566
567 return 0;
568}
569
570
572{
573 int currentLayer = m_frame->GetActiveLayer();
574 PCB_SCREEN* screen = m_frame->GetScreen();
575
576 if( currentLayer == screen->m_Route_Layer_TOP )
578 else
580
581 return 0;
582}
583
584
585// It'd be nice to share the min/max with the DIALOG_COLOR_PICKER, but those are
586// set in wxFormBuilder.
587#define ALPHA_MIN 0.20
588#define ALPHA_MAX 1.00
589#define ALPHA_STEP 0.05
590
591
593{
595 int currentLayer = m_frame->GetActiveLayer();
596 KIGFX::COLOR4D currentColor = settings->GetColor( currentLayer );
597
598 if( currentColor.a <= ALPHA_MAX - ALPHA_STEP )
599 {
600 currentColor.a += ALPHA_STEP;
601 settings->SetColor( currentLayer, currentColor );
603
605 view->UpdateLayerColor( currentLayer );
606 view->UpdateLayerColor( GetNetnameLayer( currentLayer ) );
607
608 if( IsCopperLayer( currentLayer ) )
609 view->UpdateLayerColor( ZONE_LAYER_FOR( currentLayer ) );
610
612 }
613 else
614 {
615 wxBell();
616 }
617
618 return 0;
619}
620
621
623{
625 int currentLayer = m_frame->GetActiveLayer();
626 KIGFX::COLOR4D currentColor = settings->GetColor( currentLayer );
627
628 if( currentColor.a >= ALPHA_MIN + ALPHA_STEP )
629 {
630 currentColor.a -= ALPHA_STEP;
631 settings->SetColor( currentLayer, currentColor );
633
635 view->UpdateLayerColor( currentLayer );
636 view->UpdateLayerColor( GetNetnameLayer( currentLayer ) );
637
638 if( IsCopperLayer( currentLayer ) )
639 view->UpdateLayerColor( ZONE_LAYER_FOR( currentLayer ) );
640
642 }
643 else
644 {
645 wxBell();
646 }
647
648 return 0;
649}
650
651
653{
654 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
655
656 if( !editFrame )
657 return 0;
658
659 LAYER_PAIR_SETTINGS* settings = editFrame->GetLayerPairSettings();
660
661 if( !settings )
662 return 0;
663
664 int currentIndex;
665 std::vector<LAYER_PAIR_INFO> presets = settings->GetEnabledLayerPairs( currentIndex );
666
667 if( presets.size() < 2 )
668 return 0;
669
670 if( currentIndex < 0 )
671 {
672 wxASSERT_MSG( false, "Current layer pair not found in layer settings" );
673 currentIndex = 0;
674 }
675
676 const int nextIndex = ( currentIndex + 1 ) % presets.size();
677 const LAYER_PAIR& nextPair = presets[nextIndex].GetLayerPair();
678
679 settings->SetCurrentLayerPair( nextPair );
680
682 return 0;
683}
684
685
687{
688 if( !Pgm().GetCommonSettings()->m_Input.hotkey_feedback )
689 return 0;
690
691 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
692
693 if( !editFrame )
694 return 0;
695
696 LAYER_PAIR_SETTINGS* settings = editFrame->GetLayerPairSettings();
697
698 if( !settings )
699 return 0;
700
701 PCB_LAYER_PRESENTATION layerPresentation( editFrame );
702
703 int currentIndex;
704 std::vector<LAYER_PAIR_INFO> presets = settings->GetEnabledLayerPairs( currentIndex );
705
706 wxArrayString labels;
707 for( const LAYER_PAIR_INFO& layerPairInfo : presets )
708 {
709 wxString label = layerPresentation.getLayerPairName( layerPairInfo.GetLayerPair() );
710
711 if( layerPairInfo.GetName() )
712 label += wxT( " (" ) + *layerPairInfo.GetName() + wxT( ")" );
713
714 labels.Add( label );
715 }
716
717 if( !editFrame->GetHotkeyPopup() )
718 editFrame->CreateHotkeyPopup();
719
720 HOTKEY_CYCLE_POPUP* popup = editFrame->GetHotkeyPopup();
721
722 if( popup )
723 {
724 int selection = currentIndex;
725 popup->Popup( _( "Preset Layer Pairs" ), labels, selection );
726 }
727
728 return 0;
729}
730
731
733 EDA_ITEM* originViewItem, const VECTOR2D& aPoint )
734{
735 aFrame->GetDesignSettings().SetGridOrigin( VECTOR2I( aPoint ) );
736 aView->GetGAL()->SetGridOrigin( aPoint );
737 originViewItem->SetPosition( aPoint );
738 aView->MarkDirty();
739 aFrame->OnModify();
740}
741
742
744{
745 VECTOR2D* origin = aEvent.Parameter<VECTOR2D*>();
746
747 if( origin )
748 {
749 // We can't undo the other grid dialog settings, so no sense undoing just the origin
750 DoSetGridOrigin( getView(), m_frame, m_gridOrigin.get(), *origin );
751 delete origin;
752 }
753 else
754 {
755 if( m_isFootprintEditor && !getEditFrame<PCB_BASE_EDIT_FRAME>()->GetModel() )
756 return 0;
757
759
760 if( !picker ) // Happens in footprint wizard
761 return 0;
762
763 // Deactivate other tools; particularly important if another PICKER is currently running
764 Activate();
765
766 picker->SetClickHandler(
767 [this]( const VECTOR2D& pt ) -> bool
768 {
769 m_frame->SaveCopyInUndoList( m_gridOrigin.get(), UNDO_REDO::GRIDORIGIN );
771 return false; // drill origin is a one-shot; don't continue with tool
772 } );
773
775 }
776
777 return 0;
778}
779
780
782{
783 m_frame->SaveCopyInUndoList( m_gridOrigin.get(), UNDO_REDO::GRIDORIGIN );
785 return 0;
786}
787
788
789#define HITTEST_THRESHOLD_PIXELS 5
790
791
793{
795 return 0;
796
798
799 m_pickerItem = nullptr;
801
802 // Deactivate other tools; particularly important if another PICKER is currently running
803 Activate();
804
805 picker->SetCursor( KICURSOR::REMOVE );
806
807 picker->SetClickHandler(
808 [this]( const VECTOR2D& aPosition ) -> bool
809 {
810 if( m_pickerItem )
811 {
813 {
814 m_statusPopup.reset( new STATUS_TEXT_POPUP( m_frame ) );
815 m_statusPopup->SetText( _( "Item locked." ) );
816 m_statusPopup->PopupFor( 2000 );
817 m_statusPopup->Move( KIPLATFORM::UI::GetMousePosition() + wxPoint( 20, 20 ) );
818 return true;
819 }
820
822 selectionTool->UnbrightenItem( m_pickerItem );
823
824 PCB_SELECTION items;
825 items.Add( m_pickerItem );
826
827 EDIT_TOOL* editTool = m_toolMgr->GetTool<EDIT_TOOL>();
828 editTool->DeleteItems( items, false );
829
830 m_pickerItem = nullptr;
831 }
832
833 return true;
834 } );
835
836 picker->SetMotionHandler(
837 [this]( const VECTOR2D& aPos )
838 {
842 GENERAL_COLLECTOR collector;
843 collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
844
846 collector.Collect( board, GENERAL_COLLECTOR::FootprintItems, aPos, guide );
847 else
848 collector.Collect( board, GENERAL_COLLECTOR::BoardLevelItems, aPos, guide );
849
850 // Remove unselectable items
851 for( int i = collector.GetCount() - 1; i >= 0; --i )
852 {
853 if( !selectionTool->Selectable( collector[ i ] ) )
854 collector.Remove( i );
855 }
856
857 selectionTool->FilterCollectorForHierarchy( collector, false );
858 selectionTool->FilterCollectedItems( collector, false );
859
860 if( collector.GetCount() > 1 )
861 selectionTool->GuessSelectionCandidates( collector, aPos );
862
863 BOARD_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
864
865 if( m_pickerItem != item )
866 {
867 if( m_pickerItem )
868 selectionTool->UnbrightenItem( m_pickerItem );
869
870 m_pickerItem = item;
871
872 if( m_pickerItem )
873 selectionTool->BrightenItem( m_pickerItem );
874 }
875 } );
876
877 picker->SetFinalizeHandler(
878 [this]( const int& aFinalState )
879 {
880 if( m_pickerItem )
881 m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
882
883 m_statusPopup.reset();
884
885 // Ensure the cursor gets changed&updated
886 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
888 } );
889
891
892 return 0;
893}
894
895
896static void pasteFootprintItemsToFootprintEditor( FOOTPRINT* aClipFootprint, BOARD* aBoard,
897 std::vector<BOARD_ITEM*>& aPastedItems )
898{
899 FOOTPRINT* editorFootprint = aBoard->GetFirstFootprint();
900
901 aClipFootprint->SetParent( aBoard );
902
903 for( PAD* pad : aClipFootprint->Pads() )
904 {
905 pad->SetParent( editorFootprint );
906 aPastedItems.push_back( pad );
907 }
908
909 aClipFootprint->Pads().clear();
910
911 // Not all items can be added to the current footprint: mandatory fields are already existing
912 // in the current footprint.
913 //
914 for( PCB_FIELD* field : aClipFootprint->GetFields() )
915 {
916 if( field->IsMandatory() )
917 {
918 if( EDA_GROUP* parentGroup = field->GetParentGroup() )
919 parentGroup->RemoveItem( field );
920 }
921 else
922 {
923 PCB_TEXT* text = static_cast<PCB_TEXT*>( field );
924
925 text->SetTextAngle( text->GetTextAngle() - aClipFootprint->GetOrientation() );
926 text->SetTextAngle( text->GetTextAngle() + editorFootprint->GetOrientation() );
927
928 VECTOR2I pos = field->GetFPRelativePosition();
929 field->SetParent( editorFootprint );
930 field->SetFPRelativePosition( pos );
931
932 aPastedItems.push_back( field );
933 }
934 }
935
936 aClipFootprint->GetFields().clear();
937
938 for( BOARD_ITEM* item : aClipFootprint->GraphicalItems() )
939 {
940 if( item->Type() == PCB_TEXT_T )
941 {
942 PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
943
944 text->SetTextAngle( text->GetTextAngle() - aClipFootprint->GetOrientation() );
945 text->SetTextAngle( text->GetTextAngle() + editorFootprint->GetOrientation() );
946 }
947
948 item->Rotate( item->GetPosition(), -aClipFootprint->GetOrientation() );
949 item->Rotate( item->GetPosition(), editorFootprint->GetOrientation() );
950
951 VECTOR2I pos = item->GetFPRelativePosition();
952 item->SetParent( editorFootprint );
953 item->SetFPRelativePosition( pos );
954
955 aPastedItems.push_back( item );
956 }
957
958 aClipFootprint->GraphicalItems().clear();
959
960 for( ZONE* zone : aClipFootprint->Zones() )
961 {
962 zone->SetParent( editorFootprint );
963 aPastedItems.push_back( zone );
964 }
965
966 aClipFootprint->Zones().clear();
967
968 for( PCB_GROUP* group : aClipFootprint->Groups() )
969 {
970 group->SetParent( editorFootprint );
971 aPastedItems.push_back( group );
972 }
973
974 aClipFootprint->Groups().clear();
975}
976
977
978void PCB_CONTROL::pruneItemLayers( std::vector<BOARD_ITEM*>& aItems )
979{
980 // Do not prune items or layers when copying to the FP editor, because all
981 // layers are accepted, even if they are not enabled in the dummy board
982 // This is mainly true for internal copper layers: all are allowed but only one
983 // (In1.cu) is enabled for the GUI.
985 return;
986
987 LSET enabledLayers = board()->GetEnabledLayers();
988 std::vector<BOARD_ITEM*> returnItems;
989 bool fpItemDeleted = false;
990
991 for( BOARD_ITEM* item : aItems )
992 {
993 if( item->Type() == PCB_FOOTPRINT_T )
994 {
995 FOOTPRINT* fp = static_cast<FOOTPRINT*>( item );
996
997 // Items living in a parent footprint are never removed, even if their
998 // layer does not exist in the board editor
999 // Otherwise the parent footprint could be seriously broken especially
1000 // if some layers are later re-enabled.
1001 // Moreover a fp lives in a fp library, that does not know the enabled
1002 // layers of a given board, so fp items are just ignored when on not
1003 // enabled layers in board editor
1004 returnItems.push_back( fp );
1005 }
1006 else if( item->Type() == PCB_GROUP_T || item->Type() == PCB_GENERATOR_T )
1007 {
1008 returnItems.push_back( item );
1009 }
1010 else
1011 {
1012 LSET allowed = item->GetLayerSet() & enabledLayers;
1013 bool item_valid = true;
1014
1015 // Ensure, for vias, the top and bottom layers are compatible with
1016 // the current board copper layers.
1017 // Otherwise they must be skipped, even is one layer is valid
1018 if( item->Type() == PCB_VIA_T )
1019 item_valid = static_cast<PCB_VIA*>( item )->HasValidLayerPair(
1021
1022 if( allowed.any() && item_valid )
1023 {
1024 item->SetLayerSet( allowed );
1025 returnItems.push_back( item );
1026 }
1027 else
1028 {
1029 if( EDA_GROUP* parentGroup = item->GetParentGroup() )
1030 parentGroup->RemoveItem( item );
1031 }
1032 }
1033 }
1034
1035 if( ( returnItems.size() < aItems.size() ) || fpItemDeleted )
1036 {
1037 DisplayError( m_frame, _( "Warning: some pasted items were on layers which are not "
1038 "present in the current board.\n"
1039 "These items could not be pasted.\n" ) );
1040 }
1041
1042 aItems = returnItems;
1043}
1044
1045
1046int PCB_CONTROL::Paste( const TOOL_EVENT& aEvent )
1047{
1048 // The viewer frames cannot paste
1049 if( !frame()->IsType( FRAME_FOOTPRINT_EDITOR ) && !frame()->IsType( FRAME_PCB_EDITOR ) )
1050 return 0;
1051
1052 bool isFootprintEditor = m_isFootprintEditor || frame()->IsType( FRAME_FOOTPRINT_EDITOR );
1053 // The clipboard can contain two different things, an entire kicad_pcb or a single footprint
1054 if( isFootprintEditor && ( !board() || !footprint() ) )
1055 return 0;
1056
1057 // We should never get here if a modal dialog is up... but we do on MacOS.
1058 // https://gitlab.com/kicad/code/kicad/-/issues/18912
1059#ifdef __WXMAC__
1060 if( wxDialog::OSXHasModalDialogsOpen() )
1061 {
1062 wxBell();
1063 return 0;
1064 }
1065#endif
1066
1067 BOARD_COMMIT commit( frame() );
1068
1069 CLIPBOARD_IO pi;
1070 BOARD_ITEM* clipItem = pi.Parse();
1071
1072 if( !clipItem )
1073 {
1074 // When the clipboard doesn't parse, create a PCB item with the clipboard contents
1075 std::vector<BOARD_ITEM*> newItems;
1076
1077 if( std::unique_ptr<wxImage> clipImg = GetImageFromClipboard() )
1078 {
1079 auto refImg = std::make_unique<PCB_REFERENCE_IMAGE>( m_frame->GetModel() );
1080
1081 if( refImg->GetReferenceImage().SetImage( *clipImg ) )
1082 newItems.push_back( refImg.release() );
1083 }
1084 else
1085 {
1086 const wxString clipText = GetClipboardUTF8();
1087
1088 if( clipText.empty() )
1089 return 0;
1090
1091 // If it wasn't content, then paste as a text object.
1092 if( clipText.size() > static_cast<size_t>( ADVANCED_CFG::GetCfg().m_MaxPastedTextLength ) )
1093 {
1094 int result = IsOK( m_frame, _( "Pasting a long text text string may be very slow. "
1095 "Do you want to continue?" ) );
1096 if( !result )
1097 return 0;
1098 }
1099
1100 std::unique_ptr<PCB_TEXT> item = std::make_unique<PCB_TEXT>( m_frame->GetModel() );
1101 item->SetText( clipText );
1102
1103 newItems.push_back( item.release() );
1104 }
1105
1106 bool cancelled = !placeBoardItems( &commit, newItems, true, false, false );
1107
1108 if( cancelled )
1109 commit.Revert();
1110 else
1111 commit.Push( _( "Paste Text" ) );
1112 return 0;
1113 }
1114
1115 // If we get here, we have a parsed board/FP to paste
1116
1117 PASTE_MODE mode = PASTE_MODE::KEEP_ANNOTATIONS;
1118 bool clear_nets = false;
1119 const wxString defaultRef = wxT( "REF**" );
1120
1121 if( aEvent.IsAction( &ACTIONS::pasteSpecial ) )
1122 {
1123 DIALOG_PASTE_SPECIAL dlg( m_frame, &mode, defaultRef );
1124
1125 if( clipItem->Type() != PCB_T )
1126 dlg.HideClearNets();
1127
1128 if( dlg.ShowModal() == wxID_CANCEL )
1129 return 0;
1130
1131 clear_nets = dlg.GetClearNets();
1132 }
1133
1134 if( clipItem->Type() == PCB_T )
1135 {
1136 BOARD* clipBoard = static_cast<BOARD*>( clipItem );
1137
1138 if( isFootprintEditor || clear_nets )
1139 {
1140 for( BOARD_CONNECTED_ITEM* item : clipBoard->AllConnectedItems() )
1141 item->SetNet( NETINFO_LIST::OrphanedItem() );
1142 }
1143 else
1144 {
1145 clipBoard->MapNets( m_frame->GetBoard() );
1146 }
1147 }
1148
1149 bool cancelled = false;
1150
1151 switch( clipItem->Type() )
1152 {
1153 case PCB_T:
1154 {
1155 BOARD* clipBoard = static_cast<BOARD*>( clipItem );
1156
1157 if( isFootprintEditor )
1158 {
1159 FOOTPRINT* editorFootprint = board()->GetFirstFootprint();
1160 std::vector<BOARD_ITEM*> pastedItems;
1161
1162 for( PCB_GROUP* group : clipBoard->Groups() )
1163 {
1164 group->SetParent( editorFootprint );
1165 pastedItems.push_back( group );
1166 }
1167
1168 clipBoard->RemoveAll( { PCB_GROUP_T } );
1169
1170 for( FOOTPRINT* clipFootprint : clipBoard->Footprints() )
1171 pasteFootprintItemsToFootprintEditor( clipFootprint, board(), pastedItems );
1172
1173 for( BOARD_ITEM* clipDrawItem : clipBoard->Drawings() )
1174 {
1175 switch( clipDrawItem->Type() )
1176 {
1177 case PCB_TEXT_T:
1178 case PCB_TEXTBOX_T:
1179 case PCB_TABLE_T:
1180 case PCB_SHAPE_T:
1181 case PCB_DIM_ALIGNED_T:
1182 case PCB_DIM_CENTER_T:
1183 case PCB_DIM_LEADER_T:
1185 case PCB_DIM_RADIAL_T:
1186 clipDrawItem->SetParent( editorFootprint );
1187 pastedItems.push_back( clipDrawItem );
1188 break;
1189
1190 default:
1191 // Everything we *didn't* put into pastedItems is going to get nuked, so
1192 // make sure it's not still included in its parent group.
1193 if( EDA_GROUP* parentGroup = clipDrawItem->GetParentGroup() )
1194 parentGroup->RemoveItem( clipDrawItem );
1195
1196 break;
1197 }
1198 }
1199
1200 // NB: PCB_SHAPE_T actually removes everything in Drawings() (including PCB_TEXTs,
1201 // PCB_TABLES, dimensions, etc.), not just PCB_SHAPEs.)
1202 clipBoard->RemoveAll( { PCB_SHAPE_T } );
1203
1204 clipBoard->Visit(
1205 [&]( EDA_ITEM* item, void* testData )
1206 {
1207 // Anything still on the clipboard didn't get copied and needs to be
1208 // removed from the pasted groups.
1209 BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( item );
1210 EDA_GROUP* parentGroup = boardItem->GetParentGroup();
1211
1212 if( parentGroup )
1213 parentGroup->RemoveItem( boardItem );
1214
1215 return INSPECT_RESULT::CONTINUE;
1216 },
1218
1219 delete clipBoard;
1220
1221 pruneItemLayers( pastedItems );
1222
1223 cancelled = !placeBoardItems( &commit, pastedItems, true, true,
1224 mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
1225 }
1226 else // isBoardEditor
1227 {
1228 // Fixup footprint component classes
1229 for( FOOTPRINT* fp : clipBoard->Footprints() )
1230 {
1231 fp->ResolveComponentClassNames( board(), fp->GetTransientComponentClassNames() );
1232 fp->ClearTransientComponentClassNames();
1233 }
1234
1235 if( mode == PASTE_MODE::REMOVE_ANNOTATIONS )
1236 {
1237 for( FOOTPRINT* fp : clipBoard->Footprints() )
1238 fp->SetReference( defaultRef );
1239 }
1240
1241 cancelled = !placeBoardItems( &commit, clipBoard, true,
1242 mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
1243 }
1244
1245 break;
1246 }
1247
1248 case PCB_FOOTPRINT_T:
1249 {
1250 FOOTPRINT* clipFootprint = static_cast<FOOTPRINT*>( clipItem );
1251 std::vector<BOARD_ITEM*> pastedItems;
1252
1253 if( isFootprintEditor )
1254 {
1255 pasteFootprintItemsToFootprintEditor( clipFootprint, board(), pastedItems );
1256 delete clipFootprint;
1257 }
1258 else
1259 {
1260 if( mode == PASTE_MODE::REMOVE_ANNOTATIONS )
1261 clipFootprint->SetReference( defaultRef );
1262
1263 clipFootprint->SetParent( board() );
1264 clipFootprint->ResolveComponentClassNames(
1265 board(), clipFootprint->GetTransientComponentClassNames() );
1266 clipFootprint->ClearTransientComponentClassNames();
1267 pastedItems.push_back( clipFootprint );
1268 }
1269
1270 pruneItemLayers( pastedItems );
1271
1272 cancelled = !placeBoardItems( &commit, pastedItems, true, true,
1273 mode == PASTE_MODE::UNIQUE_ANNOTATIONS );
1274 break;
1275 }
1276
1277 default:
1278 m_frame->DisplayToolMsg( _( "Invalid clipboard contents" ) );
1279 break;
1280 }
1281
1282 if( cancelled )
1283 commit.Revert();
1284 else
1285 commit.Push( _( "Paste" ) );
1286
1287 return 1;
1288}
1289
1290
1292{
1293 wxString fileName;
1294
1295 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1296
1297 if( !editFrame )
1298 return 1;
1299
1300 // Pick a file to append
1301 if( !AskLoadBoardFileName( editFrame, &fileName, KICTL_KICAD_ONLY ) )
1302 return 1;
1303
1305 IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
1306
1307 if( !pi )
1308 return 1;
1309
1310 return AppendBoard( *pi, fileName );
1311}
1312
1313
1315{
1316 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1317
1318 if( !editFrame )
1319 return 1;
1320
1321 DESIGN_BLOCK* designBlock = nullptr;
1322
1323 if( !editFrame->GetDesignBlockPane()->GetSelectedLibId().IsValid() )
1324 return 1;
1325
1326
1327 designBlock = editFrame->GetDesignBlockPane()->GetDesignBlock( editFrame->GetDesignBlockPane()->GetSelectedLibId(),
1328 true, true );
1329
1330 if( !designBlock || designBlock->GetBoardFile().IsEmpty() )
1331 return 1;
1332
1333
1335 IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
1336
1337 if( !pi )
1338 return 1;
1339
1340 bool repeatPlacement = false;
1341
1342 if( APP_SETTINGS_BASE* cfg = editFrame->config() )
1343 repeatPlacement = cfg->m_DesignBlockChooserPanel.repeated_placement;
1344
1345 int ret = 0;
1346
1347 do
1348 {
1349 ret = AppendBoard( *pi, designBlock->GetBoardFile() );
1350 } while( repeatPlacement && ret == 0 );
1351
1352 return ret;
1353}
1354
1355
1357{
1358 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1359
1360 if( !editFrame )
1361 return 1;
1362
1363 // Need to have a group selected and it needs to have a linked design block
1366
1367 if( selection.Size() != 1 || selection[0]->Type() != PCB_GROUP_T )
1368 return 1;
1369
1370 PCB_GROUP* group = static_cast<PCB_GROUP*>( selection[0] );
1371
1372 if( !group->HasDesignBlockLink() )
1373 return 1;
1374
1375 // Get the associated design block
1376 DESIGN_BLOCK* designBlock =
1377 editFrame->GetDesignBlockPane()->GetDesignBlock( group->GetDesignBlockLibId(), true, true );
1378
1379 if( !designBlock )
1380 {
1381 wxString msg;
1382 msg.Printf( _( "Could not find design block %s." ), group->GetDesignBlockLibId().GetUniStringLibId() );
1383 m_frame->GetInfoBar()->ShowMessageFor( msg, 5000, wxICON_WARNING );
1384 return 1;
1385 }
1386
1387 if( designBlock->GetBoardFile().IsEmpty() )
1388 {
1389 wxString msg;
1390 msg.Printf( _( "Design block %s does not have a board file." ),
1391 group->GetDesignBlockLibId().GetUniStringLibId() );
1392 m_frame->GetInfoBar()->ShowMessageFor( msg, 5000, wxICON_WARNING );
1393 return 1;
1394 }
1395
1396
1398 IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
1399
1400 if( !pi )
1401 return 1;
1402
1403 int ret = AppendBoard( *pi, designBlock->GetBoardFile() );
1404
1405 return ret;
1406}
1407
1408
1409template<typename T>
1410static void moveUnflaggedItems( const std::deque<T>& aList, std::vector<BOARD_ITEM*>& aTarget,
1411 bool aIsNew )
1412{
1413 std::copy_if( aList.begin(), aList.end(), std::back_inserter( aTarget ),
1414 [aIsNew]( T aItem )
1415 {
1416 bool doCopy = ( aItem->GetFlags() & SKIP_STRUCT ) == 0;
1417
1418 aItem->ClearFlags( SKIP_STRUCT );
1419 aItem->SetFlags( aIsNew ? IS_NEW : 0 );
1420
1421 return doCopy;
1422 } );
1423}
1424
1425
1426template<typename T>
1427static void moveUnflaggedItems( const std::vector<T>& aList, std::vector<BOARD_ITEM*>& aTarget,
1428 bool aIsNew )
1429{
1430 std::copy_if( aList.begin(), aList.end(), std::back_inserter( aTarget ),
1431 [aIsNew]( T aItem )
1432 {
1433 bool doCopy = ( aItem->GetFlags() & SKIP_STRUCT ) == 0;
1434
1435 aItem->ClearFlags( SKIP_STRUCT );
1436 aItem->SetFlags( aIsNew ? IS_NEW : 0 );
1437
1438 return doCopy;
1439 } );
1440}
1441
1442
1443bool PCB_CONTROL::placeBoardItems( BOARD_COMMIT* aCommit, BOARD* aBoard, bool aAnchorAtOrigin,
1444 bool aReannotateDuplicates )
1445{
1446 // items are new if the current board is not the board source
1447 bool isNew = board() != aBoard;
1448 std::vector<BOARD_ITEM*> items;
1449
1450 moveUnflaggedItems( aBoard->Tracks(), items, isNew );
1451 moveUnflaggedItems( aBoard->Footprints(), items, isNew );
1452 moveUnflaggedItems( aBoard->Drawings(), items, isNew );
1453 moveUnflaggedItems( aBoard->Zones(), items, isNew );
1454
1455 // Subtlety: When selecting a group via the mouse,
1456 // PCB_SELECTION_TOOL::highlightInternal runs, which does a SetSelected() on all
1457 // descendants. In PCB_CONTROL::placeBoardItems, below, we skip that and
1458 // mark items non-recursively. That works because the saving of the
1459 // selection created aBoard that has the group and all descendants in it.
1460 moveUnflaggedItems( aBoard->Groups(), items, isNew );
1461
1462 moveUnflaggedItems( aBoard->Generators(), items, isNew );
1463
1464 if( isNew )
1465 aBoard->RemoveAll();
1466
1467 // Reparent before calling pruneItemLayers, as SetLayer can have a dependence on the
1468 // item's parent board being set correctly.
1469 if( isNew )
1470 {
1471 for( BOARD_ITEM* item : items )
1472 item->SetParent( board() );
1473 }
1474
1475 pruneItemLayers( items );
1476
1477 return placeBoardItems( aCommit, items, isNew, aAnchorAtOrigin, aReannotateDuplicates );
1478}
1479
1480
1481bool PCB_CONTROL::placeBoardItems( BOARD_COMMIT* aCommit, std::vector<BOARD_ITEM*>& aItems,
1482 bool aIsNew, bool aAnchorAtOrigin, bool aReannotateDuplicates )
1483{
1485
1487
1488 std::vector<BOARD_ITEM*> itemsToSel;
1489 itemsToSel.reserve( aItems.size() );
1490
1491 for( BOARD_ITEM* item : aItems )
1492 {
1493 if( aIsNew )
1494 {
1495 const_cast<KIID&>( item->m_Uuid ) = KIID();
1496
1497 item->RunOnChildren(
1498 []( BOARD_ITEM* aChild )
1499 {
1500 const_cast<KIID&>( aChild->m_Uuid ) = KIID();
1501 },
1502 RECURSE_MODE::RECURSE );
1503
1504 // Even though BOARD_COMMIT::Push() will add any new items to the group, we're
1505 // going to run PCB_ACTIONS::move first, and the move tool will throw out any
1506 // items that aren't in the entered group.
1507 if( selectionTool->GetEnteredGroup() && !item->GetParentGroup() )
1508 selectionTool->GetEnteredGroup()->AddItem( item );
1509
1510 item->SetParent( board() );
1511 }
1512
1513 // Update item attributes if needed
1514 if( BaseType( item->Type() ) == PCB_DIMENSION_T )
1515 {
1516 static_cast<PCB_DIMENSION_BASE*>( item )->UpdateUnits();
1517 }
1518 else if( item->Type() == PCB_FOOTPRINT_T )
1519 {
1520 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
1521
1522 // Update the footprint path with the new KIID path if the footprint is new
1523 if( aIsNew )
1525
1526 for( BOARD_ITEM* dwg : footprint->GraphicalItems() )
1527 {
1528 if( BaseType( dwg->Type() ) == PCB_DIMENSION_T )
1529 static_cast<PCB_DIMENSION_BASE*>( dwg )->UpdateUnits();
1530 }
1531 }
1532
1533 // We only need to add the items that aren't inside a group currently selected
1534 // to the selection. If an item is inside a group and that group is selected,
1535 // then the selection tool will select it for us.
1536 if( !item->GetParentGroup() || !alg::contains( aItems, item->GetParentGroup()->AsEdaItem() ) )
1537 itemsToSel.push_back( item );
1538 }
1539
1540 // Select the items that should be selected
1541 EDA_ITEMS toSel( itemsToSel.begin(), itemsToSel.end() );
1543
1544 // Reannotate duplicate footprints (make sense only in board editor )
1545 if( aReannotateDuplicates && m_isBoardEditor )
1546 m_toolMgr->GetTool<BOARD_REANNOTATE_TOOL>()->ReannotateDuplicatesInSelection();
1547
1548 for( BOARD_ITEM* item : aItems )
1549 {
1550 if( aIsNew )
1551 aCommit->Add( item );
1552 else
1553 aCommit->Added( item );
1554 }
1555
1556 PCB_SELECTION& selection = selectionTool->GetSelection();
1557
1558 if( selection.Size() > 0 )
1559 {
1560 if( aAnchorAtOrigin )
1561 {
1563 }
1564 else
1565 {
1566 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.GetTopLeftItem() );
1568 }
1569
1570 getViewControls()->SetCursorPosition( getViewControls()->GetMousePosition(), false );
1571
1573
1575 }
1576
1577 return true;
1578}
1579
1580
1581int PCB_CONTROL::AppendBoard( PCB_IO& pi, const wxString& fileName, DESIGN_BLOCK* aDesignBlock )
1582{
1583 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1584
1585 if( !editFrame )
1586 return 1;
1587
1588 BOARD* brd = board();
1589
1590 if( !brd )
1591 return 1;
1592
1593 BOARD_COMMIT commit( editFrame );
1594
1595 // Mark existing items, in order to know what are the new items so we can select only
1596 // the new items after loading
1597 for( PCB_TRACK* track : brd->Tracks() )
1598 track->SetFlags( SKIP_STRUCT );
1599
1600 for( FOOTPRINT* footprint : brd->Footprints() )
1602
1603 for( PCB_GROUP* group : brd->Groups() )
1604 group->SetFlags( SKIP_STRUCT );
1605
1606 for( BOARD_ITEM* drawing : brd->Drawings() )
1607 drawing->SetFlags( SKIP_STRUCT );
1608
1609 for( ZONE* zone : brd->Zones() )
1610 zone->SetFlags( SKIP_STRUCT );
1611
1612 for( PCB_GENERATOR* generator : brd->Generators() )
1613 generator->SetFlags( SKIP_STRUCT );
1614
1615 std::map<wxString, wxString> oldProperties = brd->GetProperties();
1616 std::map<wxString, wxString> newProperties;
1617
1618 PAGE_INFO oldPageInfo = brd->GetPageSettings();
1619 TITLE_BLOCK oldTitleBlock = brd->GetTitleBlock();
1620
1621 // Keep also the count of copper layers, to adjust if necessary
1622 int initialCopperLayerCount = brd->GetCopperLayerCount();
1623 LSET initialEnabledLayers = brd->GetEnabledLayers();
1624
1625 // Load the data
1626 try
1627 {
1628 std::map<std::string, UTF8> props;
1629
1630 // PCB_IO_EAGLE can use this info to center the BOARD, but it does not yet.
1631
1632 props["page_width"] = std::to_string( editFrame->GetPageSizeIU().x );
1633 props["page_height"] = std::to_string( editFrame->GetPageSizeIU().y );
1634
1636 [&]( wxString aTitle, int aIcon, wxString aMessage, wxString aAction ) -> bool
1637 {
1638 KIDIALOG dlg( editFrame, aMessage, aTitle, wxOK | wxCANCEL | aIcon );
1639
1640 if( !aAction.IsEmpty() )
1641 dlg.SetOKLabel( aAction );
1642
1643 dlg.DoNotShowCheckbox( aMessage, 0 );
1644
1645 return dlg.ShowModal() == wxID_OK;
1646 } );
1647
1648 WX_PROGRESS_REPORTER progressReporter( editFrame, _( "Loading PCB" ), 1 );
1649
1650 editFrame->GetDesignSettings().m_NetSettings->ClearNetclasses();
1651 pi.SetProgressReporter( &progressReporter );
1652 pi.LoadBoard( fileName, brd, &props, nullptr );
1653 }
1654 catch( const IO_ERROR& ioe )
1655 {
1656 DisplayErrorMessage( editFrame, _( "Error loading board." ), ioe.What() );
1657
1658 return 0;
1659 }
1660
1661 newProperties = brd->GetProperties();
1662
1663 for( const std::pair<const wxString, wxString>& prop : oldProperties )
1664 newProperties[ prop.first ] = prop.second;
1665
1666 brd->SetProperties( newProperties );
1667
1668 brd->SetPageSettings( oldPageInfo );
1669 brd->SetTitleBlock( oldTitleBlock );
1670
1671 // rebuild nets and ratsnest before any use of nets
1672 brd->BuildListOfNets();
1673 brd->SynchronizeNetsAndNetClasses( true );
1674 brd->BuildConnectivity();
1675
1676 // Synchronize layers
1677 // we should not ask PLUGINs to do these items:
1678 int copperLayerCount = brd->GetCopperLayerCount();
1679
1680 if( copperLayerCount > initialCopperLayerCount )
1681 brd->SetCopperLayerCount( copperLayerCount );
1682
1683 // Enable all used layers, and make them visible:
1684 LSET enabledLayers = brd->GetEnabledLayers();
1685 enabledLayers |= initialEnabledLayers;
1686 brd->SetEnabledLayers( enabledLayers );
1687 brd->SetVisibleLayers( enabledLayers );
1688
1689 int ret = 0;
1690
1691 bool placeAsGroup = editFrame->config() ? editFrame->config()->m_DesignBlockChooserPanel.place_as_group : false;
1692
1693 if( placeBoardItems( &commit, brd, false, false /* Don't reannotate dupes on Append Board */ ) )
1694 {
1695 commit.Push( _( "Append Board" ) );
1696
1697 if( placeAsGroup )
1698 {
1699 BOARD_COMMIT grpCommit( m_toolMgr );
1700 PCB_GROUP* group = new PCB_GROUP( brd );
1701
1702 if( aDesignBlock )
1703 {
1704 group->SetName( aDesignBlock->GetLibId().GetLibItemName() );
1705 group->SetDesignBlockLibId( aDesignBlock->GetLibId() );
1706 }
1707 else
1708 {
1709 group->SetName( wxFileName( fileName ).GetName() );
1710 }
1711
1712 // Get the selection tool selection
1715
1716 for( EDA_ITEM* eda_item : selection )
1717 {
1718 if( eda_item->IsBOARD_ITEM() )
1719 {
1720 if( static_cast<BOARD_ITEM*>( eda_item )->IsLocked() )
1721 group->SetLocked( true );
1722 }
1723 }
1724
1725 grpCommit.Add( group );
1726
1727 for( EDA_ITEM* eda_item : selection )
1728 {
1729 if( eda_item->IsBOARD_ITEM() && !static_cast<BOARD_ITEM*>( eda_item )->GetParentFootprint() )
1730 grpCommit.Stage( static_cast<BOARD_ITEM*>( eda_item ), CHT_GROUP );
1731 }
1732
1733 grpCommit.Push( _( "Group Items" ), APPEND_UNDO );
1734
1735 selTool->ClearSelection();
1736 selTool->select( group );
1737
1739 m_frame->OnModify();
1740 m_frame->Refresh();
1741 }
1742
1743 editFrame->GetBoard()->BuildConnectivity();
1744 ret = 0;
1745 }
1746 else
1747 {
1748 commit.Revert();
1749 ret = 1;
1750 }
1751
1752 // Refresh the UI for the updated board properties
1753 editFrame->GetAppearancePanel()->OnBoardChanged();
1754
1755 return ret;
1756}
1757
1758
1759int PCB_CONTROL::Undo( const TOOL_EVENT& aEvent )
1760{
1761 PCB_BASE_EDIT_FRAME* editFrame = dynamic_cast<PCB_BASE_EDIT_FRAME*>( m_frame );
1762 wxCommandEvent dummy;
1763
1764 if( editFrame )
1765 editFrame->RestoreCopyFromUndoList( dummy );
1766
1767 return 0;
1768}
1769
1770
1771int PCB_CONTROL::Redo( const TOOL_EVENT& aEvent )
1772{
1773 PCB_BASE_EDIT_FRAME* editFrame = dynamic_cast<PCB_BASE_EDIT_FRAME*>( m_frame );
1774 wxCommandEvent dummy;
1775
1776 if( editFrame )
1777 editFrame->RestoreCopyFromRedoList( dummy );
1778
1779 return 0;
1780}
1781
1782
1784{
1787 bool& snapMode = settings.allLayers;
1788
1790 snapMode = false;
1791 else if( aEvent.IsAction( &PCB_ACTIONS::magneticSnapAllLayers ) )
1792 snapMode = true;
1793 else
1794 snapMode = !snapMode;
1795
1797
1798 return 0;
1799}
1800
1801
1803{
1804 if( !Pgm().GetCommonSettings()->m_Input.hotkey_feedback )
1805 return 0;
1806
1807 wxArrayString labels;
1808 labels.Add( _( "Active Layer" ) );
1809 labels.Add( _( "All Layers" ) );
1810
1811 if( !m_frame->GetHotkeyPopup() )
1813
1815
1818
1819 if( popup )
1820 popup->Popup( _( "Object Snapping" ), labels, static_cast<int>( settings.allLayers ) );
1821
1822 return 0;
1823}
1824
1825
1827{
1829 ROUTER_TOOL* routerTool = m_toolMgr->GetTool<ROUTER_TOOL>();
1830 PCB_SELECTION& selection = selTool->GetSelection();
1831 PCB_EDIT_FRAME* pcbFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
1832 std::shared_ptr<DRC_ENGINE> drcEngine = m_frame->GetBoard()->GetDesignSettings().m_DRCEngine;
1833 DRC_CONSTRAINT constraint;
1834
1835 std::vector<MSG_PANEL_ITEM> msgItems;
1836
1837 if( routerTool && routerTool->RoutingInProgress() )
1838 {
1839 routerTool->UpdateMessagePanel();
1840 return 0;
1841 }
1842
1843 if( !pcbFrame && !m_frame->GetModel() )
1844 return 0;
1845
1846 if( selection.Empty() )
1847 {
1848 if( !pcbFrame )
1849 {
1850 FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_frame->GetModel() );
1851 fp->GetMsgPanelInfo( m_frame, msgItems );
1852 }
1853 else
1854 {
1856 }
1857 }
1858 else if( selection.GetSize() == 1 )
1859 {
1860 EDA_ITEM* item = selection.Front();
1861
1862 if( std::optional<wxString> uuid = GetMsgPanelDisplayUuid( item->m_Uuid ) )
1863 msgItems.emplace_back( _( "UUID" ), *uuid );
1864
1865 item->GetMsgPanelInfo( m_frame, msgItems );
1866
1867 PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item );
1868 NETINFO_ITEM* net = track ? track->GetNet() : nullptr;
1869 NETINFO_ITEM* coupledNet = net ? m_frame->GetBoard()->DpCoupledNet( net ) : nullptr;
1870
1871 if( coupledNet )
1872 {
1873 SEG trackSeg( track->GetStart(), track->GetEnd() );
1874 PCB_TRACK* coupledItem = nullptr;
1875 SEG::ecoord closestDist_sq = VECTOR2I::ECOORD_MAX;
1876
1877 for( PCB_TRACK* candidate : m_frame->GetBoard()->Tracks() )
1878 {
1879 if( candidate->GetNet() != coupledNet )
1880 continue;
1881
1882 SEG::ecoord dist_sq = trackSeg.SquaredDistance( SEG( candidate->GetStart(),
1883 candidate->GetEnd() ) );
1884
1885 if( !coupledItem || dist_sq < closestDist_sq )
1886 {
1887 coupledItem = candidate;
1888 closestDist_sq = dist_sq;
1889 }
1890 }
1891
1892 constraint = drcEngine->EvalRules( DIFF_PAIR_GAP_CONSTRAINT, track, coupledItem,
1893 track->GetLayer() );
1894
1895 wxString msg = m_frame->MessageTextFromMinOptMax( constraint.Value() );
1896
1897 if( !msg.IsEmpty() )
1898 {
1899 msgItems.emplace_back( wxString::Format( _( "DP Gap Constraints: %s" ), msg ),
1900 wxString::Format( _( "(from %s)" ), constraint.GetName() ) );
1901 }
1902
1903 constraint = drcEngine->EvalRules( MAX_UNCOUPLED_CONSTRAINT, track,
1904 coupledItem, track->GetLayer() );
1905
1906 if( constraint.Value().HasMax() )
1907 {
1908 msg = m_frame->MessageTextFromValue( constraint.Value().Max() );
1909 msgItems.emplace_back( wxString::Format( _( "DP Max Uncoupled-length: %s" ), msg ),
1910 wxString::Format( _( "(from %s)" ), constraint.GetName() ) );
1911 }
1912 }
1913 }
1914 else if( pcbFrame && selection.GetSize() == 2 )
1915 {
1916 // Pair selection broken into multiple, optional data, starting with the selected item
1917 // names
1918
1919 BOARD_ITEM* a = static_cast<BOARD_ITEM*>( selection[0] );
1920 BOARD_ITEM* b = static_cast<BOARD_ITEM*>( selection[1] );
1921
1922 msgItems.emplace_back( MSG_PANEL_ITEM( a->GetItemDescription( m_frame, false ),
1923 b->GetItemDescription( m_frame, false ) ) );
1924
1925 BOARD_CONNECTED_ITEM* a_conn = dyn_cast<BOARD_CONNECTED_ITEM*>( a );
1926 BOARD_CONNECTED_ITEM* b_conn = dyn_cast<BOARD_CONNECTED_ITEM*>( b );
1927
1928 if( a_conn && b_conn )
1929 {
1930 LSET overlap = a_conn->GetLayerSet() & b_conn->GetLayerSet() & LSET::AllCuMask();
1931 int a_netcode = a_conn->GetNetCode();
1932 int b_netcode = b_conn->GetNetCode();
1933
1934 if( overlap.count() > 0
1935 && ( a_netcode != b_netcode || a_netcode < 0 || b_netcode < 0 ) )
1936 {
1937 PCB_LAYER_ID layer = overlap.CuStack().front();
1938
1939 constraint = drcEngine->EvalRules( CLEARANCE_CONSTRAINT, a, b, layer );
1940 msgItems.emplace_back( _( "Resolved Clearance" ),
1941 m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
1942
1943 std::shared_ptr<SHAPE> a_shape( a_conn->GetEffectiveShape( layer ) );
1944 std::shared_ptr<SHAPE> b_shape( b_conn->GetEffectiveShape( layer ) );
1945
1946 int actual_clearance = a_shape->GetClearance( b_shape.get() );
1947
1948 if( actual_clearance > -1 && actual_clearance < std::numeric_limits<int>::max() )
1949 {
1950 msgItems.emplace_back( _( "Actual Clearance" ),
1951 m_frame->MessageTextFromValue( actual_clearance ) );
1952 }
1953 }
1954 }
1955
1956 if( ( a->HasHole() || b->HasHole() ) )
1957 {
1960
1961 if( b->IsOnLayer( active ) && IsCopperLayer( active ) )
1962 layer = active;
1963 else if( b->HasHole() && a->IsOnLayer( active ) && IsCopperLayer( active ) )
1964 layer = active;
1965 else if( a->HasHole() && b->IsOnCopperLayer() )
1966 layer = b->GetLayer();
1967 else if( b->HasHole() && a->IsOnCopperLayer() )
1968 layer = a->GetLayer();
1969
1970 if( IsCopperLayer( layer ) )
1971 {
1972 int actual = std::numeric_limits<int>::max();
1973
1974 if( a->HasHole() && b->IsOnCopperLayer() )
1975 {
1976 std::shared_ptr<SHAPE_SEGMENT> hole = a->GetEffectiveHoleShape();
1977 std::shared_ptr<SHAPE> other( b->GetEffectiveShape( layer ) );
1978
1979 actual = std::min( actual, hole->GetClearance( other.get() ) );
1980 }
1981
1982 if( b->HasHole() && a->IsOnCopperLayer() )
1983 {
1984 std::shared_ptr<SHAPE_SEGMENT> hole = b->GetEffectiveHoleShape();
1985 std::shared_ptr<SHAPE> other( a->GetEffectiveShape( layer ) );
1986
1987 actual = std::min( actual, hole->GetClearance( other.get() ) );
1988 }
1989
1990 if( actual < std::numeric_limits<int>::max() )
1991 {
1992 constraint = drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer );
1993 msgItems.emplace_back( _( "Resolved Hole Clearance" ),
1994 m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
1995
1996 if( actual > -1 && actual < std::numeric_limits<int>::max() )
1997 {
1998 msgItems.emplace_back( _( "Actual Hole Clearance" ),
2000 }
2001 }
2002 }
2003 }
2004
2005 for( PCB_LAYER_ID edgeLayer : { Edge_Cuts, Margin } )
2006 {
2009
2010 if( a->IsOnLayer( edgeLayer ) && b->Type() != PCB_FOOTPRINT_T )
2011 {
2012 if( b->IsOnLayer( active ) && IsCopperLayer( active ) )
2013 layer = active;
2014 else if( IsCopperLayer( b->GetLayer() ) )
2015 layer = b->GetLayer();
2016 }
2017 else if( b->IsOnLayer( edgeLayer ) && a->Type() != PCB_FOOTPRINT_T )
2018 {
2019 if( a->IsOnLayer( active ) && IsCopperLayer( active ) )
2020 layer = active;
2021 else if( IsCopperLayer( a->GetLayer() ) )
2022 layer = a->GetLayer();
2023 }
2024
2025 if( layer >= 0 )
2026 {
2027 constraint = drcEngine->EvalRules( EDGE_CLEARANCE_CONSTRAINT, a, b, layer );
2028
2029 if( edgeLayer == Edge_Cuts )
2030 {
2031 msgItems.emplace_back( _( "Resolved Edge Clearance" ),
2032 m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
2033 }
2034 else
2035 {
2036 msgItems.emplace_back( _( "Resolved Margin Clearance" ),
2037 m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
2038 }
2039 }
2040 }
2041 }
2042
2043 if( selection.GetSize() )
2044 {
2045 if( msgItems.empty() )
2046 {
2047 msgItems.emplace_back( _( "Selected Items" ),
2048 wxString::Format( wxT( "%d" ), selection.GetSize() ) );
2049
2050 if( m_isBoardEditor )
2051 {
2052 std::set<wxString> netNames;
2053 std::set<wxString> netClasses;
2054
2055 for( EDA_ITEM* item : selection )
2056 {
2057 if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
2058 {
2059 netNames.insert( UnescapeString( bci->GetNetname() ) );
2060 netClasses.insert( UnescapeString( bci->GetEffectiveNetClass()->GetHumanReadableName() ) );
2061
2062 if( netNames.size() > 1 && netClasses.size() > 1 )
2063 break;
2064 }
2065 }
2066
2067 if( netNames.size() == 1 )
2068 msgItems.emplace_back( _( "Net" ), *netNames.begin() );
2069
2070 if( netClasses.size() == 1 )
2071 msgItems.emplace_back( _( "Resolved Netclass" ), *netClasses.begin() );
2072 }
2073 }
2074
2075 if( selection.GetSize() >= 2 )
2076 {
2077 bool lengthValid = true;
2078 double selectedLength = 0;
2079
2080 // Lambda to accumulate track length if item is a track or arc, otherwise mark invalid
2081 std::function<void( EDA_ITEM* )> accumulateTrackLength;
2082
2083 accumulateTrackLength =
2084 [&]( EDA_ITEM* aItem )
2085 {
2086 if( aItem->Type() == PCB_TRACE_T || aItem->Type() == PCB_ARC_T )
2087 {
2088 selectedLength += static_cast<PCB_TRACK*>( aItem )->GetLength();
2089 }
2090 else if( aItem->Type() == PCB_VIA_T )
2091 {
2092 // zero 2D length
2093 }
2094 else if( aItem->Type() == PCB_SHAPE_T )
2095 {
2096 PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( aItem );
2097
2098 if( shape->GetShape() == SHAPE_T::SEGMENT
2099 || shape->GetShape() == SHAPE_T::ARC
2100 || shape->GetShape() == SHAPE_T::BEZIER )
2101 {
2102 selectedLength += shape->GetLength();
2103 }
2104 else
2105 {
2106 lengthValid = false;
2107 }
2108 }
2109 // Use dynamic_cast to include PCB_GENERATORs.
2110 else if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( aItem ) )
2111 {
2112 group->RunOnChildren( accumulateTrackLength, RECURSE_MODE::NO_RECURSE );
2113 }
2114 else
2115 {
2116 lengthValid = false;
2117 }
2118 };
2119
2120 for( EDA_ITEM* item : selection )
2121 {
2122 if( lengthValid )
2123 accumulateTrackLength( item );
2124 }
2125
2126 if( lengthValid )
2127 {
2128 msgItems.emplace_back( _( "Selected 2D Length" ),
2129 m_frame->MessageTextFromValue( selectedLength ) );
2130 }
2131 }
2132
2133 if( selection.GetSize() >= 2 && selection.GetSize() < 100 )
2134 {
2135 LSET enabledCopper = LSET::AllCuMask( m_frame->GetBoard()->GetCopperLayerCount() );
2136 bool areaValid = true;
2137
2138 std::map<PCB_LAYER_ID, SHAPE_POLY_SET> copperPolys;
2139 SHAPE_POLY_SET holes;
2140
2141 std::function<void( EDA_ITEM* )> accumulateArea;
2142
2143 accumulateArea =
2144 [&]( EDA_ITEM* aItem )
2145 {
2146 if( aItem->Type() == PCB_FOOTPRINT_T || aItem->Type() == PCB_MARKER_T )
2147 {
2148 areaValid = false;
2149 return;
2150 }
2151
2152 if( aItem->Type() == PCB_GROUP_T || aItem->Type() == PCB_GENERATOR_T )
2153 {
2154 // Use dynamic_cast to include PCB_GENERATORs.
2155 static_cast<PCB_GROUP*>( aItem )->RunOnChildren( accumulateArea, RECURSE_MODE::RECURSE );
2156 return;
2157 }
2158
2159 if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( aItem ) )
2160 {
2161 boardItem->RunOnChildren( accumulateArea, RECURSE_MODE::NO_RECURSE );
2162
2163 for( PCB_LAYER_ID layer : LSET( boardItem->GetLayerSet() & enabledCopper ) )
2164 {
2165 boardItem->TransformShapeToPolySet( copperPolys[layer], layer, 0,
2167 }
2168
2169 if( aItem->Type() == PCB_PAD_T && static_cast<PAD*>( aItem )->HasHole() )
2170 {
2171 static_cast<PAD*>( aItem )->TransformHoleToPolygon( holes, 0, ARC_LOW_DEF,
2172 ERROR_OUTSIDE );
2173 }
2174 else if( aItem->Type() == PCB_VIA_T )
2175 {
2176 PCB_VIA* via = static_cast<PCB_VIA*>( aItem );
2177 VECTOR2I center = via->GetPosition();
2178 int R = via->GetDrillValue() / 2;
2179
2181 }
2182 }
2183 };
2184
2185 for( EDA_ITEM* item : selection )
2186 {
2187 if( areaValid )
2188 accumulateArea( item );
2189 }
2190
2191 if( areaValid )
2192 {
2193 double area = 0.0;
2194
2195 for( auto& [layer, copperPoly] : copperPolys )
2196 {
2197 copperPoly.BooleanSubtract( holes );
2198 area += copperPoly.Area();
2199 }
2200
2201 msgItems.emplace_back( _( "Selected 2D Copper Area" ),
2202 m_frame->MessageTextFromValue( area, true, EDA_DATA_TYPE::AREA ) );
2203 }
2204 }
2205 }
2206 else
2207 {
2208 m_frame->GetBoard()->GetMsgPanelInfo( m_frame, msgItems );
2209 }
2210
2211 m_frame->SetMsgPanel( msgItems );
2212
2213 return 0;
2214}
2215
2216
2218{
2219 wxFileName fileName = wxFileName( *aEvent.Parameter<wxString*>() );
2220
2221 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
2222
2223 if( !editFrame )
2224 return 1;
2225
2226 wxString filePath = fileName.GetFullPath();
2228 IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
2229
2230 if( !pi )
2231 return 1;
2232
2233 return AppendBoard( *pi, filePath );
2234}
2235
2236
2238{
2239 BOARD_COMMIT commit( this );
2241 BOARD_STACKUP& stackup = settings.GetStackupDescriptor();
2242
2243 stackup.SynchronizeWithBoard( &settings );
2244
2246 table->SetLayer( m_frame->GetActiveLayer() );
2247 table->SetColCount( 4 );
2248
2249 auto addHeaderCell =
2250 [&]( const wxString& text )
2251 {
2252 PCB_TABLECELL* c = new PCB_TABLECELL( table );
2253 c->SetTextSize( VECTOR2I( pcbIUScale.mmToIU( 2.0 ), pcbIUScale.mmToIU( 2.0 ) ) );
2254 c->SetTextThickness( pcbIUScale.mmToIU( 0.4 ) );
2255 c->SetText( text );
2256 c->SetColSpan( table->GetColCount() );
2257 table->AddCell( c );
2258 };
2259
2260 auto addDataCell =
2261 [&]( const wxString& text )
2262 {
2263 PCB_TABLECELL* c = new PCB_TABLECELL( table );
2264 c->SetTextSize( VECTOR2I( pcbIUScale.mmToIU( 1.5 ), pcbIUScale.mmToIU( 1.5 ) ) );
2265 c->SetTextThickness( pcbIUScale.mmToIU( 0.2 ) );
2266 c->SetText( text );
2267 table->AddCell( c );
2268 };
2269
2270 addHeaderCell( _( "BOARD CHARACTERISTICS" ) );
2271
2272 for( int col = 1; col < table->GetColCount(); ++col )
2273 {
2274 addHeaderCell( wxEmptyString );
2275 table->GetCell( 0, col )->SetColSpan( 0 );
2276 }
2277
2278 addDataCell( _( "Copper layer count: " ) );
2279 addDataCell( EDA_UNIT_UTILS::UI::StringFromValue( unityScale, EDA_UNITS::UNSCALED,
2280 settings.GetCopperLayerCount(), false ) );
2281
2282 addDataCell( _( "Board thickness: " ) );
2283 addDataCell( m_frame->MessageTextFromValue( settings.GetBoardThickness(), true ) );
2284
2285 SHAPE_POLY_SET outline;
2287 BOX2I size = outline.BBox();
2288
2289 addDataCell( _( "Board overall dimensions: " ) );
2290 addDataCell( wxString::Format( wxT( "%s x %s" ),
2291 m_frame->MessageTextFromValue( size.GetWidth(), true ),
2292 m_frame->MessageTextFromValue( size.GetHeight(), true ) ) );
2293
2294 addDataCell( wxEmptyString );
2295 addDataCell( wxEmptyString );
2296
2297 addDataCell( _( "Min track/spacing: " ) );
2298 addDataCell( wxString::Format( wxT( "%s / %s" ),
2299 m_frame->MessageTextFromValue( settings.m_TrackMinWidth, true ),
2300 m_frame->MessageTextFromValue( settings.m_MinClearance, true ) ) );
2301
2302 double holeSize = std::min( settings.m_MinThroughDrill, settings.m_ViasMinSize );
2303
2304 addDataCell( _( "Min hole diameter: " ) );
2305 addDataCell( m_frame->MessageTextFromValue( holeSize, true ) );
2306
2307 addDataCell( _( "Copper finish: " ) );
2308 addDataCell( stackup.m_FinishType );
2309
2310 addDataCell( _( "Impedance control: " ) );
2311 addDataCell( stackup.m_HasDielectricConstrains ? _( "Yes" ) : _( "No" ) );
2312
2313 addDataCell( _( "Castellated pads: " ) );
2314 addDataCell( stackup.m_CastellatedPads ? _( "Yes" ) : _( "No" ) );
2315
2316 addDataCell( _( "Plated board edge: " ) );
2317 addDataCell( stackup.m_EdgePlating ? _( "Yes" ) : _( "No" ) );
2318
2319 wxString msg;
2320
2321 switch( stackup.m_EdgeConnectorConstraints )
2322 {
2323 case BS_EDGE_CONNECTOR_NONE: msg = _( "No" ); break;
2324 case BS_EDGE_CONNECTOR_IN_USE: msg = _( "Yes" ); break;
2325 case BS_EDGE_CONNECTOR_BEVELLED: msg = _( "Yes, Bevelled" ); break;
2326 }
2327
2328 addDataCell( _( "Edge card connectors: " ) );
2329 addDataCell( msg );
2330
2331 addDataCell( wxEmptyString );
2332 addDataCell( wxEmptyString );
2333
2334 table->SetStrokeExternal( false );
2335 table->SetStrokeHeaderSeparator( false );
2336 table->SetStrokeColumns( false );
2337 table->SetStrokeRows( false );
2338 table->Autosize();
2339
2340 std::vector<BOARD_ITEM*> items;
2341 items.push_back( table );
2342
2343 if( placeBoardItems( &commit, items, true, true, false ) )
2344 commit.Push( _( "Place Board Characteristics" ) );
2345 else
2346 delete table;
2347
2348 return 0;
2349}
2350
2351
2352
2354{
2355 BOARD_COMMIT commit( this );
2357 BOARD_STACKUP& stackup = settings.GetStackupDescriptor();
2358
2359 stackup.SynchronizeWithBoard( &settings );
2360
2361 std::vector<BOARD_STACKUP_ITEM*> layers = stackup.GetList();
2362
2364 table->SetLayer( m_frame->GetActiveLayer() );
2365 table->SetColCount( 7 );
2366
2367 auto addHeaderCell =
2368 [&]( const wxString& text )
2369 {
2370 PCB_TABLECELL* c = new PCB_TABLECELL( table );
2371 c->SetTextSize( VECTOR2I( pcbIUScale.mmToIU( 1.5 ), pcbIUScale.mmToIU( 1.5 ) ) );
2372 c->SetTextThickness( pcbIUScale.mmToIU( 0.3 ) );
2373 c->SetText( text );
2374 table->AddCell( c );
2375 };
2376
2377 auto addDataCell =
2378 [&]( const wxString& text, const char align = 'L' )
2379 {
2380 PCB_TABLECELL* c = new PCB_TABLECELL( table );
2381 c->SetTextSize( VECTOR2I( pcbIUScale.mmToIU( 1.5 ), pcbIUScale.mmToIU( 1.5 ) ) );
2382 c->SetTextThickness( pcbIUScale.mmToIU( 0.2 ) );
2383
2384 if( align == 'R' )
2386
2387 c->SetText( text );
2388 table->AddCell( c );
2389 };
2390
2391 addHeaderCell( _( "Layer Name" ) );
2392 addHeaderCell( _( "Type" ) );
2393 addHeaderCell( _( "Material" ) );
2394 addHeaderCell( _( "Thickness" ) );
2395 addHeaderCell( _( "Color" ) );
2396 addHeaderCell( _( "Epsilon R" ) );
2397 addHeaderCell( _( "Loss Tangent" ) );
2398
2399 for( int i = 0; i < stackup.GetCount(); i++ )
2400 {
2401 BOARD_STACKUP_ITEM* stackup_item = layers.at( i );
2402
2403 for( int sublayer_id = 0; sublayer_id < stackup_item->GetSublayersCount(); sublayer_id++ )
2404 {
2405 // Layer names are empty until we close at least once the board setup dialog.
2406 // If the user did not open the dialog, then get the names from the board.
2407 // But dielectric layer names will be missing.
2408 // In this case, for dielectric, a dummy name will be used
2409 if( stackup_item->GetLayerName().IsEmpty() )
2410 {
2411 wxString layerName;
2412
2413 if( IsValidLayer( stackup_item->GetBrdLayerId() ) )
2414 layerName = m_frame->GetBoard()->GetLayerName( stackup_item->GetBrdLayerId() );
2415
2416 if( layerName.IsEmpty() && stackup_item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
2417 layerName = _( "Dielectric" );
2418
2419 addDataCell( layerName );
2420 }
2421 else
2422 {
2423 addDataCell( stackup_item->GetLayerName() );
2424 }
2425
2426 addDataCell( InitialCaps( stackup_item->GetTypeName() ) );
2427 addDataCell( stackup_item->GetMaterial( sublayer_id ) );
2428 addDataCell( m_frame->StringFromValue( stackup_item->GetThickness( sublayer_id ), true ), 'R' );
2429 addDataCell( stackup_item->GetColor( sublayer_id ) );
2430 addDataCell( EDA_UNIT_UTILS::UI::StringFromValue( unityScale, EDA_UNITS::UNSCALED,
2431 stackup_item->GetEpsilonR( sublayer_id ) ), 'R' );
2432 addDataCell( EDA_UNIT_UTILS::UI::StringFromValue( unityScale, EDA_UNITS::UNSCALED,
2433 stackup_item->GetLossTangent( sublayer_id ) ), 'R' );
2434 }
2435 }
2436
2437 table->Autosize();
2438
2439 std::vector<BOARD_ITEM*> items;
2440 items.push_back( table );
2441
2442 if( placeBoardItems( &commit, items, true, true, false ) )
2443 commit.Push( _( "Place Board Stackup Table" ) );
2444 else
2445 delete table;
2446
2447 return 0;
2448}
2449
2450
2451
2453{
2454 view()->SetMirror( !view()->IsMirroredX(), false );
2455 view()->RecacheAllItems();
2456 frame()->GetCanvas()->ForceRefresh();
2457 frame()->OnDisplayOptionsChanged();
2458 return 0;
2459}
2460
2461
2463{
2464 if( aItem->Type() == PCB_SHAPE_T )
2465 {
2466 static_cast<PCB_SHAPE*>( aItem )->UpdateHatching();
2467
2468 if( view() )
2469 view()->Update( aItem );
2470 }
2471}
2472
2473
2475{
2476 for( FOOTPRINT* footprint : board()->Footprints() )
2478
2479 for( BOARD_ITEM* item : board()->Drawings() )
2480 rehatchBoardItem( item );
2481
2482 return 0;
2483}
2484
2485
2486// clang-format off
2488{
2491 Go( &PCB_CONTROL::Print, ACTIONS::print.MakeEvent() );
2492 Go( &PCB_CONTROL::Quit, ACTIONS::quit.MakeEvent() );
2493
2494 // Footprint library actions
2499
2500 // Display modes
2517
2518 // Layer control
2556
2559
2560 // Grid control
2563
2564 Go( &PCB_CONTROL::Undo, ACTIONS::undo.MakeEvent() );
2565 Go( &PCB_CONTROL::Redo, ACTIONS::redo.MakeEvent() );
2566
2567 // Snapping control
2572
2573 // Miscellaneous
2575
2576 // Append control
2583
2584 Go( &PCB_CONTROL::Paste, ACTIONS::paste.MakeEvent() );
2586
2593
2594 // Add library by dropping file
2597}
2598// clang-format on
@ ERROR_OUTSIDE
Definition: approximation.h:33
@ ERROR_INSIDE
Definition: approximation.h:34
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:110
constexpr int ARC_LOW_DEF
Definition: base_units.h:121
constexpr EDA_IU_SCALE unityScale
Definition: base_units.h:113
#define DEFAULT_LINE_WIDTH
@ BS_EDGE_CONNECTOR_BEVELLED
Definition: board_stackup.h:59
@ BS_EDGE_CONNECTOR_NONE
Definition: board_stackup.h:57
@ BS_EDGE_CONNECTOR_IN_USE
Definition: board_stackup.h:58
@ BS_ITEM_TYPE_DIELECTRIC
Definition: board_stackup.h:46
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
static TOOL_ACTION paste
Definition: actions.h:80
static TOOL_ACTION addLibrary
Definition: actions.h:56
static TOOL_ACTION pickerTool
Definition: actions.h:249
static TOOL_ACTION gridResetOrigin
Definition: actions.h:196
static TOOL_ACTION pasteSpecial
Definition: actions.h:81
static TOOL_ACTION highContrastModeCycle
Definition: actions.h:153
static TOOL_ACTION undo
Definition: actions.h:75
static TOOL_ACTION highContrastMode
Definition: actions.h:152
static TOOL_ACTION quit
Definition: actions.h:66
static TOOL_ACTION redo
Definition: actions.h:76
static TOOL_ACTION deleteTool
Definition: actions.h:86
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: actions.h:220
static TOOL_ACTION print
Definition: actions.h:64
static TOOL_ACTION newLibrary
Definition: actions.h:55
static TOOL_ACTION gridSetOrigin
Definition: actions.h:195
static TOOL_ACTION ddAddLibrary
Definition: actions.h:67
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
Definition: actions.h:228
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Definition: app_settings.h:108
PANEL_DESIGN_BLOCK_CHOOSER m_DesignBlockChooserPanel
Definition: app_settings.h:216
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN *aScreen=nullptr) override
Add a change of the item aItem of type aChangeType to the change list.
virtual void Revert() override
Revert the commit by restoring the modified items state.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
Container for design settings for a BOARD object.
std::shared_ptr< NET_SETTINGS > m_NetSettings
void SetGridOrigin(const VECTOR2I &aOrigin)
std::shared_ptr< DRC_ENGINE > m_DRCEngine
int GetBoardThickness() const
The full thickness of the board including copper and masks.
BOARD_STACKUP & GetStackupDescriptor()
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:78
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:229
bool IsLocked() const override
Definition: board_item.cpp:76
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition: board_item.h:311
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:279
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:249
virtual bool IsOnCopperLayer() const
Definition: board_item.h:148
virtual std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const
Definition: board_item.cpp:289
virtual bool HasHole() const
Definition: board_item.h:153
Manage one layer needed to make a physical board.
Definition: board_stackup.h:96
wxString GetTypeName() const
int GetSublayersCount() const
double GetEpsilonR(int aDielectricSubLayer=0) const
wxString GetColor(int aDielectricSubLayer=0) const
wxString GetLayerName() const
PCB_LAYER_ID GetBrdLayerId() const
int GetThickness(int aDielectricSubLayer=0) const
BOARD_STACKUP_ITEM_TYPE GetType() const
wxString GetMaterial(int aDielectricSubLayer=0) const
double GetLossTangent(int aDielectricSubLayer=0) const
Manage layers needed to make a physical board.
bool m_CastellatedPads
True if castellated pads exist.
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
int GetCount() const
bool SynchronizeWithBoard(BOARD_DESIGN_SETTINGS *aSettings)
Synchronize the BOARD_STACKUP_ITEM* list with the board.
bool m_HasDielectricConstrains
True if some layers have impedance controlled tracks or have specific constrains for micro-wave appli...
bool m_EdgePlating
True if the edge board is plated.
BS_EDGE_CONNECTOR_CONSTRAINTS m_EdgeConnectorConstraints
If the board has edge connector cards, some constrains can be specified in job file: BS_EDGE_CONNECTO...
wxString m_FinishType
The name of external copper finish.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:297
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:1871
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr, bool aAllowUseArcsInPolygons=false, bool aIncludeNPTHAsOutlines=false)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
Definition: board.cpp:2530
NETINFO_ITEM * DpCoupledNet(const NETINFO_ITEM *aNet)
Definition: board.cpp:2091
void SetVisibleLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
Definition: board.cpp:870
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:2681
void BuildListOfNets()
Definition: board.h:860
const GENERATORS & Generators() const
Definition: board.h:344
const std::vector< BOARD_CONNECTED_ITEM * > AllConnectedItems()
Definition: board.cpp:2655
const PAGE_INFO & GetPageSettings() const
Definition: board.h:715
void SetProperties(const std::map< wxString, wxString > &aProps)
Definition: board.h:370
const ZONES & Zones() const
Definition: board.h:342
const GROUPS & Groups() const
The groups must maintain the following invariants.
Definition: board.h:365
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:194
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition: board.cpp:2159
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:463
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:721
int GetCopperLayerCount() const
Definition: board.cpp:790
const std::map< wxString, wxString > & GetProperties() const
Definition: board.h:369
const FOOTPRINTS & Footprints() const
Definition: board.h:338
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:1335
const TRACKS & Tracks() const
Definition: board.h:336
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: board.h:716
void SetCopperLayerCount(int aCount)
Definition: board.cpp:796
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:623
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:844
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:1833
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:955
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:838
void SetEnabledLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:858
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
Definition: board.h:723
const DRAWINGS & Drawings() const
Definition: board.h:340
constexpr size_type GetWidth() const
Definition: box2.h:214
constexpr size_type GetHeight() const
Definition: box2.h:215
BOARD_ITEM * Parse()
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:82
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:110
int m_Threshold
Definition: collector.h:235
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)
Notify observers that aItem has been added.
Definition: commit.h:86
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition: commit.h:80
DO_NOT_SHOW_AGAIN m_DoNotShowAgain
LIB_ID GetSelectedLibId(int *aUnit=nullptr) const
DESIGN_BLOCK * GetDesignBlock(const LIB_ID &aLibId, bool aUseCacheLib, bool aShowErrorMsg)
Load design block from design block library table.
const wxString & GetBoardFile() const
Definition: design_block.h:48
const LIB_ID & GetLibId() const
Definition: design_block.h:37
int ShowModal() override
wxString GetName() const
Definition: drc_rule.h:165
MINOPTMAX< int > & Value()
Definition: drc_rule.h:158
MINOPTMAX< int > m_Value
Definition: drc_rule.h:199
virtual APP_SETTINGS_BASE * config() const
Return the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
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 set of EDA_ITEMs (i.e., without duplicates).
Definition: eda_group.h:46
virtual bool RemoveItem(EDA_ITEM *aItem)=0
Remove item from group.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:96
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:256
virtual void SetPosition(const VECTOR2I &aPos)
Definition: eda_item.h:257
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:138
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const
Return a user-visible description string of this item.
Definition: eda_item.cpp:118
const KIID m_Uuid
Definition: eda_item.h:502
virtual EDA_GROUP * GetParentGroup() const
Definition: eda_item.h:114
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:108
virtual void 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:216
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:111
SHAPE_T GetShape() const
Definition: eda_shape.h:168
double GetLength() const
Definition: eda_shape.cpp:375
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:533
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:284
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:270
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:409
The interactive edit tool.
Definition: edit_tool.h:56
void DeleteItems(const PCB_SELECTION &aItem, bool aIsCut)
Definition: edit_tool.cpp:2473
static const TOOL_EVENT ClearedEvent
Definition: actions.h:343
static const TOOL_EVENT SelectedEvent
Definition: actions.h:341
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:348
static const TOOL_EVENT PointSelectedEvent
Definition: actions.h:340
static const TOOL_EVENT ContrastModeChangedByKeyEvent
Definition: actions.h:362
static const TOOL_EVENT ConnectivityChangedEvent
Selected item had a property changed (except movement)
Definition: actions.h:345
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:342
Component library viewer main window.
void AddFootprintToPCB()
Export the current footprint name and close the library browser.
EDA_ANGLE GetOrientation() const
Definition: footprint.h:232
ZONES & Zones()
Definition: footprint.h:217
void SetPath(const KIID_PATH &aPath)
Definition: footprint.h:269
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const override
Invoke a function on all children.
Definition: footprint.cpp:2205
std::deque< PAD * > & Pads()
Definition: footprint.h:211
void ResolveComponentClassNames(BOARD *aBoard, const std::unordered_set< wxString > &aComponentClassNames)
Resolves a set of component class names to this footprint's actual component class.
Definition: footprint.cpp:4079
const std::unordered_set< wxString > & GetTransientComponentClassNames()
Gets the transient component class names.
Definition: footprint.h:1022
void SetReference(const wxString &aReference)
Definition: footprint.h:627
void ClearTransientComponentClassNames()
Remove the transient component class names.
Definition: footprint.h:1028
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:1677
GROUPS & Groups()
Definition: footprint.h:220
void GetFields(std::vector< PCB_FIELD * > &aVector, bool aVisibleOnly) const
Populate a std::vector with PCB_TEXTs.
Definition: footprint.cpp:630
DRAWINGS & GraphicalItems()
Definition: footprint.h:214
A general implementation of a COLLECTORS_GUIDE.
Definition: collectors.h:319
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:202
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:233
static const std::vector< KICAD_T > AllBoardItems
A scan list for all editable board items.
Definition: collectors.h:222
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:482
static const std::vector< KICAD_T > FootprintItems
A scan list for primary footprint items.
Definition: collectors.h:248
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:89
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: kidialog.h:43
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox.
Definition: kidialog.cpp:51
int ShowModal() override
Definition: kidialog.cpp:95
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:91
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:67
void SetMirror(bool aMirrorX, bool aMirrorY)
Control the mirroring of the VIEW.
Definition: view.cpp:547
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:297
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:332
GAL * GetGAL() const
Return the #GAL this view is using to draw graphical primitives.
Definition: view.h:198
void RecacheAllItems()
Rebuild GAL display lists.
Definition: view.cpp:1439
void UpdateLayerColor(int aLayer)
Apply the new coloring scheme held by RENDER_SETTINGS in case that it has changed.
Definition: view.cpp:744
void MarkDirty()
Force redraw of view on the next rendering.
Definition: view.h:655
Definition: kiid.h:49
All information about a layer pair as stored in the layer pair store.
Management class for layer pairs in a PCB.
Definition: layer_pairs.h:47
std::vector< LAYER_PAIR_INFO > GetEnabledLayerPairs(int &aCurrentIndex) const
Get a vector of all enabled layer pairs, in order.
void SetCurrentLayerPair(const LAYER_PAIR &aPair)
Set the "active" layer pair.
bool IsValid() const
Check if this LID_ID is valid.
Definition: lib_id.h:172
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition: lseq.h:47
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
LSEQ UIOrder() const
Return the copper, technical and user layers in the order shown in layer widget.
Definition: lset.cpp:736
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
Definition: lset.cpp:247
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:583
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:389
Definition: pad.h:54
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:361
static TOOL_ACTION layerInner12
Definition: pcb_actions.h:337
static TOOL_ACTION nextFootprint
Definition: pcb_actions.h:477
static TOOL_ACTION layerInner8
Definition: pcb_actions.h:333
static TOOL_ACTION zoneDisplayToggle
Definition: pcb_actions.h:320
static TOOL_ACTION previousFootprint
Definition: pcb_actions.h:476
static TOOL_ACTION layerInner3
Definition: pcb_actions.h:328
static TOOL_ACTION layerPrev
Definition: pcb_actions.h:358
static TOOL_ACTION showRatsnest
Definition: pcb_actions.h:309
static TOOL_ACTION zoneFillAll
Definition: pcb_actions.h:387
static TOOL_ACTION layerInner2
Definition: pcb_actions.h:327
static TOOL_ACTION magneticSnapAllLayers
Definition: pcb_actions.h:231
static TOOL_ACTION ddAppendBoard
Drag and drop.
Definition: pcb_actions.h:578
static TOOL_ACTION layerInner25
Definition: pcb_actions.h:350
static TOOL_ACTION magneticSnapActiveLayer
Snapping controls.
Definition: pcb_actions.h:230
static TOOL_ACTION layerAlphaDec
Definition: pcb_actions.h:360
static TOOL_ACTION zoneDisplayFilled
Definition: pcb_actions.h:316
static TOOL_ACTION layerInner24
Definition: pcb_actions.h:349
static TOOL_ACTION viaDisplayMode
Definition: pcb_actions.h:315
static TOOL_ACTION layerInner29
Definition: pcb_actions.h:354
static TOOL_ACTION placeCharacteristics
Definition: pcb_actions.h:209
static TOOL_ACTION layerInner11
Definition: pcb_actions.h:336
static TOOL_ACTION layerAlphaInc
Definition: pcb_actions.h:359
static TOOL_ACTION layerPairPresetsCycle
Definition: pcb_actions.h:362
static TOOL_ACTION layerInner16
Definition: pcb_actions.h:341
static TOOL_ACTION layerInner26
Definition: pcb_actions.h:351
static TOOL_ACTION layerInner18
Definition: pcb_actions.h:343
static TOOL_ACTION layerInner14
Definition: pcb_actions.h:339
static TOOL_ACTION trackDisplayMode
Definition: pcb_actions.h:313
static TOOL_ACTION magneticSnapToggle
Definition: pcb_actions.h:232
static TOOL_ACTION layerInner6
Definition: pcb_actions.h:331
static TOOL_ACTION ddImportFootprint
Definition: pcb_actions.h:579
static TOOL_ACTION zoneDisplayTriangulated
Definition: pcb_actions.h:319
static TOOL_ACTION rehatchShapes
Definition: pcb_actions.h:371
static TOOL_ACTION layerInner22
Definition: pcb_actions.h:347
static TOOL_ACTION placeDesignBlock
Definition: pcb_actions.h:439
static TOOL_ACTION layerInner5
Definition: pcb_actions.h:330
static TOOL_ACTION zoneDisplayFractured
Definition: pcb_actions.h:318
static TOOL_ACTION ratsnestModeCycle
Definition: pcb_actions.h:312
static TOOL_ACTION layerInner20
Definition: pcb_actions.h:345
static TOOL_ACTION layerInner7
Definition: pcb_actions.h:332
static TOOL_ACTION layerInner27
Definition: pcb_actions.h:352
static TOOL_ACTION loadFpFromBoard
Definition: pcb_actions.h:473
static TOOL_ACTION appendBoard
Definition: pcb_actions.h:534
static TOOL_ACTION netColorModeCycle
Definition: pcb_actions.h:311
static TOOL_ACTION layerInner1
Definition: pcb_actions.h:326
static TOOL_ACTION layerInner10
Definition: pcb_actions.h:335
static TOOL_ACTION layerInner15
Definition: pcb_actions.h:340
static TOOL_ACTION layerInner17
Definition: pcb_actions.h:342
static TOOL_ACTION flipBoard
Definition: pcb_actions.h:369
static TOOL_ACTION layerBottom
Definition: pcb_actions.h:356
static TOOL_ACTION zoneDisplayOutline
Definition: pcb_actions.h:317
static TOOL_ACTION ratsnestLineMode
Definition: pcb_actions.h:310
static TOOL_ACTION layerInner19
Definition: pcb_actions.h:344
static TOOL_ACTION layerInner9
Definition: pcb_actions.h:334
static TOOL_ACTION move
move or drag an item
Definition: pcb_actions.h:103
static TOOL_ACTION layerInner30
Definition: pcb_actions.h:355
static TOOL_ACTION layerTop
Definition: pcb_actions.h:325
static TOOL_ACTION layerInner4
Definition: pcb_actions.h:329
static TOOL_ACTION layerInner13
Definition: pcb_actions.h:338
static TOOL_ACTION layerInner21
Definition: pcb_actions.h:346
static TOOL_ACTION saveFpToBoard
Definition: pcb_actions.h:474
static TOOL_ACTION layerNext
Definition: pcb_actions.h:357
static TOOL_ACTION placeLinkedDesignBlock
Definition: pcb_actions.h:440
static TOOL_ACTION placeStackup
Definition: pcb_actions.h:210
static TOOL_ACTION layerInner23
Definition: pcb_actions.h:348
static TOOL_ACTION layerInner28
Definition: pcb_actions.h:353
Common, abstract interface for edit frames.
LAYER_PAIR_SETTINGS * GetLayerPairSettings()
Acess to the layer pair settings controller of the board, if available.
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:200
APPEARANCE_CONTROLS * GetAppearancePanel()
void RestoreCopyFromRedoList(wxCommandEvent &aEvent)
Redo the last edit:
Definition: undo_redo.cpp:230
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
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
Return the BOARD_DESIGN_SETTINGS for the open project.
void SetDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions, bool aRefresh=true)
Update the current display options.
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.
int RehatchShapes(const TOOL_EVENT &aEvent)
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 LoadFpFromBoard(const TOOL_EVENT &aEvent)
int DdImportFootprint(const TOOL_EVENT &aEvent)
int SnapModeFeedback(const TOOL_EVENT &aEvent)
int NetColorModeCycle(const TOOL_EVENT &aEvent)
int SaveFpToBoard(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 PlaceLinkedDesignBlock(const TOOL_EVENT &aEvent)
int LayerPresetFeedback(const TOOL_EVENT &aEvent)
int UpdateMessagePanel(const TOOL_EVENT &aEvent)
int LayerAlphaDec(const TOOL_EVENT &aEvent)
int LayerNext(const TOOL_EVENT &aEvent)
int PlaceStackup(const TOOL_EVENT &aEvent)
int AppendBoard(PCB_IO &pi, const wxString &fileName, DESIGN_BLOCK *aDesignBlock=nullptr)
std::unique_ptr< STATUS_TEXT_POPUP > m_statusPopup
Definition: pcb_control.h:168
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:164
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
Definition: pcb_control.h:162
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 PlaceCharacteristics(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.
int IterateFootprint(const TOOL_EVENT &aEvent)
int Print(const TOOL_EVENT &aEvent)
void rehatchBoardItem(BOARD_ITEM *aItem)
int ZoneDisplayMode(const TOOL_EVENT &aEvent)
int GridResetOrigin(const TOOL_EVENT &aEvent)
BOARD_ITEM * m_pickerItem
Definition: pcb_control.h:166
int InteractiveDelete(const TOOL_EVENT &aEvent)
int AppendDesignBlock(const TOOL_EVENT &aEvent)
int LayerPrev(const TOOL_EVENT &aEvent)
int CycleLayerPresets(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.
PCB_DESIGN_BLOCK_PANE * GetDesignBlockPane() const
static const TOOL_EVENT & SnappingModeChangedByKeyEvent()
Hotkey feedback.
static const TOOL_EVENT & LayerPairPresetChangedByKeyEvent()
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:53
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const override
Invoke a function on all children.
Definition: pcb_group.cpp:449
bool AddItem(EDA_ITEM *aItem) override
Add item to group.
Definition: pcb_group.cpp:81
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:69
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
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition: pcb_io_mgr.h:58
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:112
A base class that BOARD loading and saving plugins should derive from.
Definition: pcb_io.h:71
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:97
virtual BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *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:74
Class that manages the presentation of PCB layers in a PCB frame.
wxString getLayerPairName(const LAYER_PAIR &aPair) const
Definition: sel_layer.cpp:91
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...
void select(EDA_ITEM *aItem) override
Take necessary action mark an item as selected.
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.
int ClearSelection(const TOOL_EVENT &aEvent)
PCB_SELECTION & GetSelection()
EDA_ITEM * GetTopLeftItem(bool aFootprintsOnly=false) const override
void SetColSpan(int aSpan)
Definition: pcb_tablecell.h:69
T * frame() const
KIGFX::PCB_VIEW * view() 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:152
const VECTOR2I & GetEnd() const
Definition: pcb_track.h:149
bool HasValidLayerPair(int aCopperLayerCount)
Definition: pcb_track.cpp:1195
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:687
void SetMotionHandler(MOTION_HANDLER aHandler)
Set a handler for mouse motion.
Definition: picker_tool.h:84
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:73
void SetCursor(KICURSOR aCursor)
Definition: picker_tool.h:64
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:104
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:100
EDA_ITEM * Front() const
Definition: selection.h:172
int Size() const
Returns the number of selected parts.
Definition: selection.h:116
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.cpp:178
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:110
Represent a set of closed polygons.
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Hold the information shown in the lower right corner of a plot, printout, or editing view.
Definition: title_block.h:41
const std::string & GetName() const
Return the name of the tool.
Definition: tool_base.h:136
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:44
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:220
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:38
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:168
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:465
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:150
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:197
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
wxString MessageTextFromMinOptMax(const MINOPTMAX< int > &aValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
wxString StringFromValue(double aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts aValue in internal units into a united string.
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:76
A modified version of the wxInfoBar class that allows us to:
Definition: wx_infobar.h:76
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: wx_infobar.cpp:353
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:309
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:74
std::string GetClipboardUTF8()
Return the information currently stored in the system clipboard.
Definition: clipboard.cpp:57
std::unique_ptr< wxImage > GetImageFromClipboard()
Get image data from the clipboard, if there is any.
Definition: clipboard.cpp:83
@ CHT_GROUP
Definition: commit.h:45
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:249
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:194
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:170
This file is part of the common library.
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
#define ALPHA_MAX
@ DIFF_PAIR_GAP_CONSTRAINT
Definition: drc_rule.h:70
@ EDGE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:53
@ CLEARANCE_CONSTRAINT
Definition: drc_rule.h:49
@ MAX_UNCOUPLED_CONSTRAINT
Definition: drc_rule.h:71
@ HOLE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:51
#define _(s)
Declaration of the eda_3d_viewer class.
@ NO_RECURSE
Definition: eda_item.h:51
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
Definition: eda_item.h:552
#define SKIP_STRUCT
flag indicating that the structure should be ignored
FPVIEWER_CONSTANTS
@ FRAME_PCB_EDITOR
Definition: frame_type.h:42
@ FRAME_FOOTPRINT_VIEWER
Definition: frame_type.h:45
@ FRAME_FOOTPRINT_EDITOR
Definition: frame_type.h:43
int m_MaxPastedTextLength
Set the maximum number of characters that can be pasted without warning.
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
This file is part of the common library.
#define KICTL_KICAD_ONLY
chosen file is from KiCad according to user
Definition: kiway_player.h:75
int GetNetnameLayer(int aLayer)
Return a netname layer corresponding to the given layer.
Definition: layer_ids.h:839
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition: layer_ids.h:663
@ LAYER_RATSNEST
Definition: layer_ids.h:252
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ Edge_Cuts
Definition: layer_ids.h:112
@ B_Cu
Definition: layer_ids.h:65
@ Margin
Definition: layer_ids.h:113
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ F_Cu
Definition: layer_ids.h:64
#define ZONE_LAYER_FOR(boardLayer)
Definition: layer_ids.h:358
bool IsValidLayer(int aLayerId)
Test whether a given integer is a valid layer index, i.e.
Definition: layer_ids.h:641
std::optional< wxString > GetMsgPanelDisplayUuid(const KIID &aKiid)
Get a formatted UUID string for display in the message panel, according to the current advanced confi...
Definition: msgpanel.cpp:245
KICOMMON_API wxString StringFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Return the string from aValue according to aUnits (inch, mm ...) for display.
Definition: eda_units.cpp:310
@ REPAINT
Item needs to be redrawn.
Definition: view_item.h:58
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:1071
see class PGM_BASE
#define APPEND_UNDO
Definition: sch_commit.h:42
#define HITTEST_THRESHOLD_PIXELS
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
wxString InitialCaps(const wxString &aString)
Capitalize only the first word.
constexpr int mmToIU(double mm) const
Definition: base_units.h:90
VECTOR2I center
int actual
@ GR_TEXT_H_ALIGN_RIGHT
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition: typeinfo.h:250
@ 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_MARKER_T
class PCB_MARKER, a marker used to show something
Definition: typeinfo.h:99
@ 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_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_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
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695
Definition of file extensions used in Kicad.