KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_track_via_properties.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) 2015 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 <core/kicad_algo.h>
31#include <footprint.h>
32#include <pad.h>
33#include <pcb_track.h>
34#include <confirm.h>
35#include <kidialog.h>
37#include <board_commit.h>
38#include <magic_enum.hpp>
39
40
42 const IPC4761_CONFIGURATION& aOther ) const
43{
44 return ( tent == aOther.tent ) && ( plug == aOther.plug ) && ( cover == aOther.cover )
45 && ( cap == aOther.cap ) && ( fill == aOther.fill );
46}
47
48
50 const PCB_SELECTION& aItems ) :
52 m_frame( aParent ),
53 m_items( aItems ),
56 m_trackEndX( aParent, m_TrackEndXLabel, m_TrackEndXCtrl, nullptr ),
60 m_viaX( aParent, m_ViaXLabel, m_ViaXCtrl, nullptr ),
69 m_tracks( false ),
70 m_vias( false ),
72{
74
75 wxASSERT( !m_items.Empty() );
76
77 m_legacyTeardropsIcon->SetBitmap( KiBitmapBundle( BITMAPS::dialog_warning ) );
79
80 m_bitmapTeardrop->SetBitmap( KiBitmapBundle( BITMAPS::teardrop_sizes ) );
81
82 m_teardropHDPercent.SetUnits( EDA_UNITS::PERCENT );
83 m_teardropLenPercent.SetUnits( EDA_UNITS::PERCENT );
84 m_teardropWidthPercent.SetUnits( EDA_UNITS::PERCENT );
85
86 m_minTrackWidthHint->SetFont( KIUI::GetInfoFont( this ).Italic() );
87
88 // Configure display origin transforms
95
96 VIATYPE viaType = VIATYPE::NOT_DEFINED;
97
102
105 m_ViaStartLayer->SetBoardFrame( aParent );
107
110 m_ViaEndLayer->SetBoardFrame( aParent );
112
113 wxFont infoFont = KIUI::GetInfoFont( this );
114 m_techLayersLabel->SetFont( infoFont );
115
116 bool nets = false;
117 int net = 0;
118 bool hasLocked = false;
119 bool hasUnlocked = false;
120
121 // Start and end layers of vias
122 // if at least 2 vias do not have the same start or the same end layer
123 // the layers will be set as undefined
124 int selection_first_layer = -1;
125 int selection_last_layer = -1;
126
127 // The selection layer for tracks
128 int track_selection_layer = -1;
129
130 auto getAnnularRingSelection = []( const PCB_VIA* via ) -> int
131 {
132 switch( via->Padstack().UnconnectedLayerMode() )
133 {
134 default:
138 }
139 };
140
141 for( auto& preset : magic_enum::enum_values<IPC4761_PRESET>() )
142 {
143 if( preset >= IPC4761_PRESET::CUSTOM )
144 continue;
145
146 const auto& name_it = m_IPC4761Names.find( preset );
147
148 wxString name = _( "Unknown choice" );
149
150 if( name_it != m_IPC4761Names.end() )
151 name = name_it->second;
152
153 m_protectionFeatures->AppendString( name );
154 }
155
156 auto getProtectionSurface = []( const std::optional<bool>& front,
157 const std::optional<bool>& back ) -> IPC4761_SURFACE
158 {
160
161 if( !front.has_value() )
163 else if( front.value() )
165 else
166 value = IPC4761_SURFACE::NONE;
167
168 if( !back.has_value() )
169 {
170 if( value == IPC4761_SURFACE::FROM_RULES )
172 }
173 else if( back.value() )
174 {
175 if( value == IPC4761_SURFACE::FRONT )
177 else if( value == IPC4761_SURFACE::NONE )
179 }
180 else
181 {
182 if( value == IPC4761_SURFACE::FRONT )
184 else if( value == IPC4761_SURFACE::NONE )
186 }
187
189 };
190
191 auto getProtectionDrill = []( const std::optional<bool>& drill ) -> IPC4761_DRILL
192 {
193 if( !drill.has_value() )
195 if( drill.value() )
196 return IPC4761_DRILL::SET;
197
199 };
200
201 auto getViaConfiguration = [&]( const PCB_VIA* via ) -> IPC4761_PRESET
202 {
204 config.tent = getProtectionSurface( via->Padstack().FrontOuterLayers().has_solder_mask,
205 via->Padstack().BackOuterLayers().has_solder_mask );
206
207 config.cover = getProtectionSurface( via->Padstack().FrontOuterLayers().has_covering,
208 via->Padstack().BackOuterLayers().has_covering );
209
210 config.plug = getProtectionSurface( via->Padstack().FrontOuterLayers().has_plugging,
211 via->Padstack().BackOuterLayers().has_plugging );
212
213 config.cap = getProtectionDrill( via->Padstack().Drill().is_capped );
214
215 config.fill = getProtectionDrill( via->Padstack().Drill().is_filled );
216
217 for( const auto& [preset, configuration] : m_IPC4761Presets )
218 {
219 if( configuration == config )
220 return preset;
221 }
222
224 };
225
226 // Look for values that are common for every item that is selected
227 for( EDA_ITEM* item : m_items )
228 {
229 if( !nets )
230 {
231 net = static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetCode();
232 nets = true;
233 }
234 else if( net != static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetCode() )
235 {
236 net = -1;
237 }
238
239 switch( item->Type() )
240 {
241 case PCB_TRACE_T:
242 case PCB_ARC_T:
243 {
244 const PCB_TRACK* t = static_cast<const PCB_TRACK*>( item );
245
246 if( !m_tracks ) // first track in the list
247 {
253 track_selection_layer = t->GetLayer();
254 m_trackHasSolderMask->SetValue ( t->HasSolderMask() );
255
256 if( t->GetLocalSolderMaskMargin().has_value() )
258 else
259 m_trackMaskMargin.SetValue( wxEmptyString );
260
261 m_tracks = true;
262 }
263 else // check if values are the same for every selected track
264 {
265 if( m_trackStartX.GetValue() != t->GetStartX() )
267
268 if( m_trackStartY.GetValue() != t->GetStartY() )
270
271 if( m_trackEndX.GetValue() != t->GetEndX() )
273
274 if( m_trackEndY.GetValue() != t->GetEndY() )
276
277 if( m_trackWidth.GetValue() != t->GetWidth() )
279
280 if( track_selection_layer != t->GetLayer() )
281 track_selection_layer = UNDEFINED_LAYER;
282
283 if( m_trackHasSolderMask->GetValue() != t->HasSolderMask() )
284 m_trackHasSolderMask->Set3StateValue( wxCHK_UNDETERMINED );
285
288 }
289
290 if( t->IsLocked() )
291 hasLocked = true;
292 else
293 hasUnlocked = true;
294
295 break;
296 }
297
298 case PCB_VIA_T:
299 {
300 PCB_VIA* v = static_cast<PCB_VIA*>( item );
301
302 if( !m_vias ) // first via in the list
303 {
306 m_viaStack = std::make_unique<PADSTACK>( v->Padstack() );
309 m_vias = true;
310 viaType = v->GetViaType();
311 m_viaNotFree->SetValue( !v->GetIsFree() );
312 m_annularRingsCtrl->SetSelection( getAnnularRingSelection( v ) );
313
314 selection_first_layer = v->TopLayer();
315 selection_last_layer = v->BottomLayer();
316
317 m_cbTeardrops->SetValue( v->GetTeardropParams().m_Enabled );
325
326 IPC4761_PRESET preset = getViaConfiguration( v );
327
328 if( preset >= IPC4761_PRESET::CUSTOM )
329 {
330 m_protectionFeatures->SetSelection(
332 }
333 else
334 {
335 m_protectionFeatures->SetSelection( static_cast<int>( preset ) );
336 }
337 }
338 else // check if values are the same for every selected via
339 {
340 if( m_viaX.GetValue() != v->GetPosition().x )
342
343 if( m_viaY.GetValue() != v->GetPosition().y )
345
348
349 if( m_viaDrill.GetValue() != v->GetDrillValue() )
351
352 if( viaType != v->GetViaType() )
353 viaType = VIATYPE::NOT_DEFINED;
354
355 if( v->GetIsFree() != !m_viaNotFree->GetValue() )
356 m_viaNotFree->Set3StateValue( wxCHK_UNDETERMINED );
357
358 if( selection_first_layer != v->TopLayer() )
359 selection_first_layer = UNDEFINED_LAYER;
360
361 if( selection_last_layer != v->BottomLayer() )
362 selection_last_layer = UNDEFINED_LAYER;
363
364 if( m_annularRingsCtrl->GetSelection() != getAnnularRingSelection( v ) )
365 {
366 if( m_annularRingsCtrl->GetStrings().size() < 4 )
368
369 m_annularRingsCtrl->SetSelection( 3 );
370 }
371
372 if( m_cbTeardrops->GetValue() != v->GetTeardropParams().m_Enabled )
373 m_cbTeardrops->Set3StateValue( wxCHK_UNDETERMINED );
374
376 m_cbTeardropsUseNextTrack->Set3StateValue( wxCHK_UNDETERMINED );
377
380
383
386
389
392
393
394 if( static_cast<int>( getViaConfiguration( v ) )
395 != m_protectionFeatures->GetSelection() )
396 {
397 m_protectionFeatures->SetSelection(
399 }
400 }
401
402 if( v->IsLocked() )
403 hasLocked = true;
404 else
405 hasUnlocked = true;
406
407 break;
408 }
409
410 default:
411 {
412 wxASSERT( false );
413 break;
414 }
415 }
416 }
417
418 if( m_tracks )
419 {
420 // Set the track layer selection state:
421 if( track_selection_layer == UNDEFINED_LAYER )
422 {
425 }
426
427 m_TrackLayerCtrl->SetLayerSelection( track_selection_layer );
428 }
429
430 // Set the vias layers selections state:
431 if( m_vias )
432 {
433 if( selection_first_layer == UNDEFINED_LAYER )
434 {
437 }
438
439 m_ViaStartLayer->SetLayerSelection( selection_first_layer );
440
441 if( selection_last_layer == UNDEFINED_LAYER )
442 {
445 }
446
447 m_ViaEndLayer->SetLayerSelection( selection_last_layer );
448 }
449
450 m_netSelector->SetBoard( aParent->GetBoard() );
451 m_netSelector->SetNetInfo( &aParent->GetBoard()->GetNetInfo() );
452
453 if ( net >= 0 )
454 {
456 }
457 else
458 {
461 }
462
463 wxASSERT( m_tracks || m_vias );
464
465 if( m_vias )
466 {
467 if( m_viaNotFree->GetValue() && !m_tracks )
468 {
469 // Disable net selector to re-inforce meaning of "Automatically update via nets",
470 // but not when tracks are also selected as then things get harder if you want to
471 // update all the nets to match.
472 m_netSelectorLabel->Disable();
473 m_netSelector->Disable();
474 }
475
476 int viaSelection = wxNOT_FOUND;
477
478 // 0 is the netclass place-holder
479 for( unsigned ii = 1; ii < aParent->GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
480 {
481 VIA_DIMENSION* viaDimension = &aParent->GetDesignSettings().m_ViasDimensionsList[ii];
482 wxString msg = m_frame->StringFromValue( viaDimension->m_Diameter )
483 + wxT( " / " )
484 + m_frame->StringFromValue( viaDimension->m_Drill );
485 m_predefinedViaSizesCtrl->Append( msg, viaDimension );
486
487 if( viaSelection == wxNOT_FOUND
488 && m_viaDiameter.GetValue() == viaDimension->m_Diameter
489 && m_viaDrill.GetValue() == viaDimension->m_Drill )
490 {
491 viaSelection = ii - 1;
492 }
493 }
494
495 m_predefinedViaSizesCtrl->SetSelection( viaSelection );
497
498 m_ViaTypeChoice->Enable();
499
500 switch( viaType )
501 {
502 case VIATYPE::THROUGH: m_ViaTypeChoice->SetSelection( 0 ); break;
503 case VIATYPE::MICROVIA: m_ViaTypeChoice->SetSelection( 1 ); break;
504 case VIATYPE::BLIND_BURIED: m_ViaTypeChoice->SetSelection( 2 ); break;
505 case VIATYPE::NOT_DEFINED: m_ViaTypeChoice->SetSelection( wxNOT_FOUND ); break;
506 }
507
508 m_ViaStartLayer->Enable( viaType != VIATYPE::THROUGH );
509 m_ViaEndLayer->Enable( viaType != VIATYPE::THROUGH );
510
511 m_annularRingsLabel->Show( getLayerDepth() > 1 );
512 m_annularRingsCtrl->Show( getLayerDepth() > 1 );
513
515 }
516 else
517 {
518 m_viaNotFree->Hide();
519 m_MainSizer->Hide( m_sbViaSizer, true );
520 }
521
522 if( m_tracks )
523 {
524 int widthSelection = wxNOT_FOUND;
525
526 // 0 is the netclass place-holder
527 for( unsigned ii = 1; ii < aParent->GetDesignSettings().m_TrackWidthList.size(); ii++ )
528 {
529 int width = aParent->GetDesignSettings().m_TrackWidthList[ii];
530 wxString msg = m_frame->StringFromValue( width );
531 m_predefinedTrackWidthsCtrl->Append( msg );
532
533 if( widthSelection == wxNOT_FOUND && m_trackWidth.GetValue() == width )
534 widthSelection = ii - 1;
535 }
536
537 m_predefinedTrackWidthsCtrl->SetSelection( widthSelection );
539
540 wxCommandEvent event;
541 onTrackEdit( event );
542 }
543 else
544 {
545 m_MainSizer->Hide( m_sbTrackSizer, true );
546 }
547
548 if( hasLocked && hasUnlocked )
549 m_lockedCbox->Set3StateValue( wxCHK_UNDETERMINED );
550 else if( hasLocked )
551 m_lockedCbox->Set3StateValue( wxCHK_CHECKED );
552 else
553 m_lockedCbox->Set3StateValue( wxCHK_UNCHECKED );
554
555 if( m_tracks )
557 else if( m_netSelector->IsEnabled() )
559 else
561
563
564 m_frame->Bind( EDA_EVT_UNITS_CHANGED, &DIALOG_TRACK_VIA_PROPERTIES::onUnitsChanged, this );
565 m_netSelector->Bind( FILTERED_ITEM_SELECTED, &DIALOG_TRACK_VIA_PROPERTIES::onNetSelector, this );
566
567 // Now all widgets have the size fixed, call FinishDialogSettings
569}
570
571
573{
574 m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &DIALOG_TRACK_VIA_PROPERTIES::onUnitsChanged, this );
575}
576
577
579{
580 if( m_vias )
581 {
582 int viaSel = m_predefinedViaSizesCtrl->GetSelection();
583
585
586 // 0 is the netclass place-holder
587 for( unsigned ii = 1; ii < m_frame->GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
588 {
590 wxString msg = m_frame->StringFromValue( viaDimension->m_Diameter )
591 + wxT( " / " )
592 + m_frame->StringFromValue( viaDimension->m_Drill );
593 m_predefinedViaSizesCtrl->Append( msg, viaDimension );
594 }
595
596 m_predefinedViaSizesCtrl->SetSelection( viaSel );
598 }
599
600 if( m_tracks )
601 {
602 int trackSel = m_predefinedTrackWidthsCtrl->GetSelection();
603
605
606 // 0 is the netclass place-holder
607 for( unsigned ii = 1; ii < m_frame->GetDesignSettings().m_TrackWidthList.size(); ii++ )
608 {
609 int width = m_frame->GetDesignSettings().m_TrackWidthList[ii];
610 wxString msg = m_frame->StringFromValue( width );
611 m_predefinedTrackWidthsCtrl->Append( msg );
612 }
613
614 m_predefinedTrackWidthsCtrl->SetSelection( trackSel );
616 }
617
618 aEvent.Skip();
619}
620
621
622bool DIALOG_TRACK_VIA_PROPERTIES::confirmShortingNets( int aNet, const std::set<int>& shortingNets )
623{
624 wxString msg;
625
626 if( shortingNets.size() == 1 )
627 {
628 msg.Printf( _( "Applying these changes will short net %s with %s." ),
629 m_netSelector->GetValue(),
630 m_frame->GetBoard()->FindNet( *shortingNets.begin() )->GetNetname() );
631 }
632 else
633 {
634 msg.Printf( _( "Applying these changes will short net %s with other nets." ),
635 m_netSelector->GetValue() );
636 }
637
638 KIDIALOG dlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
639 dlg.SetOKCancelLabels( _( "Apply Anyway" ), _( "Cancel Changes" ) );
640 dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
641
642 return dlg.ShowModal() == wxID_OK;
643}
644
645
646bool DIALOG_TRACK_VIA_PROPERTIES::confirmPadChange( const std::set<PAD*>& changingPads )
647{
648 wxString msg;
649
650 if( changingPads.size() == 1 )
651 {
652 PAD* pad = *changingPads.begin();
653 msg.Printf( _( "Changing the net will also update %s pad %s to %s." ),
654 pad->GetParentFootprint()->GetReference(),
655 pad->GetNumber(),
656 m_netSelector->GetValue() );
657 }
658 else if( changingPads.size() == 2 )
659 {
660 PAD* pad1 = *changingPads.begin();
661 PAD* pad2 = *( ++changingPads.begin() );
662 msg.Printf( _( "Changing the net will also update %s pad %s and %s pad %s to %s." ),
664 pad1->GetNumber(),
666 pad2->GetNumber(),
667 m_netSelector->GetValue() );
668 }
669 else
670 {
671 msg.Printf( _( "Changing the net will also update %lu connected pads to %s." ),
672 static_cast<unsigned long>( changingPads.size() ),
673 m_netSelector->GetValue() );
674 }
675
676 KIDIALOG dlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
677 dlg.SetOKCancelLabels( _( "Change Nets" ), _( "Leave Nets Unchanged" ) );
678 dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
679
680 return dlg.ShowModal() == wxID_OK;
681}
682
683
685{
686 std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_frame->GetBoard()->GetConnectivity();
687 std::vector<PCB_TRACK*> selected_tracks;
688 std::set<PCB_TRACK*> connected_tracks;
689
690 for( EDA_ITEM* item : m_items )
691 {
692 if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item ) )
693 selected_tracks.push_back( track );
694 }
695
696 for( PCB_TRACK* selected_track : selected_tracks )
697 {
698 for( BOARD_CONNECTED_ITEM* connected_item : connectivity->GetConnectedItems( selected_track ) )
699 {
700 if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( connected_item ) )
701 connected_tracks.insert( track );
702 }
703 }
704
705 // Check for malformed data ONLY; design rules and constraints are the business of DRC.
706
707 if( m_vias )
708 {
709 // TODO: This needs to move into the via class, not the dialog
710
712 || !m_viaDrill.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
713 {
714 return false;
715 }
716
717 if( m_ViaDiameterCtrl->IsEnabled() && !m_viaDiameter.IsIndeterminate()
718 && m_ViaDrillCtrl->IsEnabled() && !m_viaDrill.IsIndeterminate()
720 {
721 DisplayError( GetParent(), _( "Via hole size must be smaller than via diameter" ) );
722 m_ViaDrillCtrl->SelectAll();
723 m_ViaDrillCtrl->SetFocus();
724 return false;
725 }
726
729 {
730 DisplayError( GetParent(), _( "Via start layer and end layer cannot be the same" ) );
731 return false;
732 }
733
735 {
736 int diameter = m_viaDiameter.GetValue();
737 m_viaStack->SetSize( { diameter, diameter }, m_editLayer );
738 }
739 }
740
741 if( m_tracks )
742 {
743 if( !m_trackWidth.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
744 return false;
745 }
746
747 // If we survived that, then save the changes:
748 //
749 // We don't bother with updating the nets at this point as it will be useless (any connected
750 // pads will simply drive their existing nets back onto the track segments and vias).
751
752 BOARD_COMMIT commit( m_frame );
753 bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED;
754 bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED;
755
756 for( PCB_TRACK* track : selected_tracks )
757 {
758 commit.Modify( track );
759
760 switch( track->Type() )
761 {
762 case PCB_TRACE_T:
763 case PCB_ARC_T:
764 {
765 wxASSERT( m_tracks );
766
768 track->SetStartX( m_trackStartX.GetIntValue() );
769
771 track->SetStartY( m_trackStartY.GetIntValue() );
772
774 track->SetEndX( m_trackEndX.GetIntValue() );
775
777 track->SetEndY( m_trackEndY.GetIntValue() );
778
780 track->SetWidth( m_trackWidth.GetIntValue() );
781
782 int layer = m_TrackLayerCtrl->GetLayerSelection();
783
784 if( layer != UNDEFINED_LAYER )
785 track->SetLayer( (PCB_LAYER_ID) layer );
786
787 if ( m_trackHasSolderMask->Get3StateValue() != wxCHK_UNDETERMINED )
788 track->SetHasSolderMask( m_trackHasSolderMask->GetValue() );
789
791 {
793 track->SetLocalSolderMaskMargin( {} );
794 else
795 track->SetLocalSolderMaskMargin( m_trackMaskMargin.GetIntValue() );
796 }
797
798 if( changeLock )
799 track->SetLocked( setLock );
800
801 break;
802 }
803
804 case PCB_VIA_T:
805 {
806 wxASSERT( m_vias );
807 PCB_VIA* via = static_cast<PCB_VIA*>( track );
808
809 if( !m_viaX.IsIndeterminate() )
810 via->SetPosition( VECTOR2I( m_viaX.GetIntValue(), via->GetPosition().y ) );
811
812 if( !m_viaY.IsIndeterminate() )
813 via->SetPosition( VECTOR2I( via->GetPosition().x, m_viaY.GetIntValue() ) );
814
815 if( m_viaNotFree->Get3StateValue() != wxCHK_UNDETERMINED )
816 via->SetIsFree( !m_viaNotFree->GetValue() );
817
819 via->SetPadstack( *m_viaStack );
820
821 switch( m_ViaTypeChoice->GetSelection() )
822 {
823 case 0: via->SetViaType( VIATYPE::THROUGH ); break;
824 case 1: via->SetViaType( VIATYPE::MICROVIA ); break;
825 case 2: via->SetViaType( VIATYPE::BLIND_BURIED ); break;
826 default: break;
827 }
828
829 PCB_LAYER_ID startLayer = static_cast<PCB_LAYER_ID>( m_ViaStartLayer->GetLayerSelection() );
830 PCB_LAYER_ID endLayer = static_cast<PCB_LAYER_ID>( m_ViaEndLayer->GetLayerSelection() );
831
832 if( startLayer != UNDEFINED_LAYER )
833 {
834 m_viaStack->Drill().start = startLayer;
835 via->SetTopLayer( startLayer );
836 }
837
838 if( endLayer != UNDEFINED_LAYER )
839 {
840 m_viaStack->Drill().end = endLayer;
841 via->SetBottomLayer( endLayer );
842 }
843
844 via->SanitizeLayers();
845
846 switch( m_annularRingsCtrl->GetSelection() )
847 {
848 case 0:
849 via->Padstack().SetUnconnectedLayerMode(
851 break;
852 case 1:
853 via->Padstack().SetUnconnectedLayerMode(
855 break;
856 case 2:
857 via->Padstack().SetUnconnectedLayerMode(
859 break;
860 default:
861 break;
862 }
863
864
866 via->SetDrill( m_viaDrill.GetIntValue() );
867
868 TEARDROP_PARAMETERS* targetParams = &via->GetTeardropParams();
869
870 if( m_cbTeardrops->Get3StateValue() != wxCHK_UNDETERMINED )
871 targetParams->m_Enabled = m_cbTeardrops->GetValue();
872
873 if( m_cbTeardropsUseNextTrack->Get3StateValue() != wxCHK_UNDETERMINED )
874 targetParams->m_AllowUseTwoTracks = m_cbTeardropsUseNextTrack->GetValue();
875
877 targetParams->m_TdMaxLen = m_teardropMaxLen.GetIntValue();
878
881
883 targetParams->m_BestLengthRatio = m_teardropLenPercent.GetDoubleValue() / 100.0;
884
886 targetParams->m_BestWidthRatio =
888
891
892 if( m_curvedEdges->Get3StateValue() != wxCHK_UNDETERMINED )
893 targetParams->m_CurvedEdges = m_curvedEdges->GetValue();
894
895 if( changeLock )
896 via->SetLocked( setLock );
897
898 auto setSurfaceProtection =
899 [&]( std::optional<bool>& aFront, std::optional<bool>& aBack, IPC4761_SURFACE aProtection )
900 {
901 switch( aProtection )
902 {
904 aFront.reset();
905 aBack.reset();
906 break;
908 aFront = false;
909 aBack = false;
910 break;
912 aFront = true;
913 aBack = false;
914 break;
916 aFront = false;
917 aBack = true;
918 break;
920 aFront = true;
921 aBack = true;
922 break;
923 case IPC4761_SURFACE::CUSTOM: return;
924 }
925 };
926
927 auto setDrillProtection =
928 [&]( std::optional<bool>& aDrill, IPC4761_DRILL aProtection )
929 {
930 switch( aProtection )
931 {
932 case IPC4761_DRILL::FROM_RULES: aDrill.reset(); break;
933 case IPC4761_DRILL::NOT_SET: aDrill = false; break;
934 case IPC4761_DRILL::SET: aDrill = true; break;
935 }
936 };
937
938 IPC4761_PRESET selectedPreset = static_cast<IPC4761_PRESET>( m_protectionFeatures->GetSelection() );
939
940 if( selectedPreset < IPC4761_PRESET::CUSTOM ) // Do not change custom feaure list.
941 {
942 const IPC4761_CONFIGURATION config = m_IPC4761Presets.at( selectedPreset );
943
944 setSurfaceProtection( via->Padstack().FrontOuterLayers().has_solder_mask,
945 via->Padstack().BackOuterLayers().has_solder_mask,
946 config.tent );
947
948 setSurfaceProtection( via->Padstack().FrontOuterLayers().has_plugging,
949 via->Padstack().BackOuterLayers().has_plugging,
950 config.plug );
951
952 setSurfaceProtection( via->Padstack().FrontOuterLayers().has_covering,
953 via->Padstack().BackOuterLayers().has_covering,
954 config.cover );
955
956 setDrillProtection( via->Padstack().Drill().is_filled, config.fill );
957
958 setDrillProtection( via->Padstack().Drill().is_capped, config.cap );
959 }
960
961 break;
962 }
963
964 default:
965 wxASSERT( false );
966 break;
967 }
968 }
969
970 std::set<int> shortingNets;
971 int newNetCode = m_netSelector->GetSelectedNetcode();
972 std::set<PAD*> changingPads;
973
974 // Do NOT use the connectivity code here. It will propagate through zones, and we haven't
975 // refilled those yet so it's going to pick up a whole bunch of other nets any time the track
976 // width was increased.
977 auto collide =
979 {
980 for( PCB_LAYER_ID layer : LSET( a->GetLayerSet() & b->GetLayerSet() ).Seq() )
981 {
982 if( a->GetEffectiveShape( layer )->Collide( b->GetEffectiveShape( layer ).get() ) )
983 return true;
984 }
985
986 return false;
987 };
988
989 for( PCB_TRACK* track : connected_tracks )
990 {
991 for( PCB_TRACK* other : m_frame->GetBoard()->Tracks() )
992 {
993 if( other->GetNetCode() == track->GetNetCode() || other->GetNetCode() == newNetCode )
994 continue;
995
996 if( collide( track, other ) )
997 shortingNets.insert( other->GetNetCode() );
998 }
999
1000 for( FOOTPRINT* footprint : m_frame->GetBoard()->Footprints() )
1001 {
1002 for( PAD* pad : footprint->Pads() )
1003 {
1004 if( pad->GetNetCode() == newNetCode )
1005 continue;
1006
1007 if( collide( track, pad ) )
1008 {
1009 if( pad->GetNetCode() == track->GetNetCode() )
1010 changingPads.insert( pad );
1011 else
1012 shortingNets.insert( pad->GetNetCode() );
1013 }
1014 }
1015 }
1016 }
1017
1018 if( shortingNets.size() && !confirmShortingNets( newNetCode, shortingNets ) )
1019 {
1020 commit.Revert();
1021 return true;
1022 }
1023
1025 {
1026 if( changingPads.empty() || confirmPadChange( changingPads ) )
1027 {
1028 for( PCB_TRACK* track : selected_tracks )
1029 track->SetNetCode( newNetCode );
1030
1031 for( PAD* pad : changingPads )
1032 {
1033 commit.Modify( pad );
1034 pad->SetNetCode( newNetCode );
1035 }
1036 }
1037 }
1038
1039 commit.Push( _( "Edit Track/Via Properties" ) );
1040 return true;
1041}
1042
1043
1045{
1046 m_viaNotFree->SetValue( false );
1047}
1048
1049
1051{
1052 if( !m_tracks )
1053 {
1054 m_netSelectorLabel->Enable( !m_viaNotFree->GetValue() );
1055 m_netSelector->Enable( !m_viaNotFree->GetValue() );
1056 }
1057}
1058
1059
1061{
1062 m_TrackWidthCtrl->ChangeValue( m_predefinedTrackWidthsCtrl->GetStringSelection() );
1063 m_TrackWidthCtrl->SelectAll();
1064}
1065
1066
1067void DIALOG_TRACK_VIA_PROPERTIES::onWidthEdit( wxCommandEvent& aEvent )
1068{
1069 m_predefinedTrackWidthsCtrl->SetStringSelection( m_TrackWidthCtrl->GetValue() );
1070}
1071
1072
1073void DIALOG_TRACK_VIA_PROPERTIES::onViaSelect( wxCommandEvent& aEvent )
1074{
1075 VIA_DIMENSION* viaDimension = static_cast<VIA_DIMENSION*> ( aEvent.GetClientData() );
1076
1077 m_viaDiameter.ChangeValue( viaDimension->m_Diameter );
1078 m_viaDrill.ChangeValue( viaDimension->m_Drill );
1079}
1080
1081
1083{
1084 wxCHECK_MSG( m_viaStack, /* void */, "Expected valid via stack in onPadstackModeChanged" );
1085
1086 switch( m_cbPadstackMode->GetSelection() )
1087 {
1088 default:
1089 case 0: m_viaStack->SetMode( PADSTACK::MODE::NORMAL ); break;
1090 case 1: m_viaStack->SetMode( PADSTACK::MODE::FRONT_INNER_BACK ); break;
1091 case 2: m_viaStack->SetMode( PADSTACK::MODE::CUSTOM ); break;
1092 }
1093
1095}
1096
1097
1099{
1100 wxCHECK_MSG( m_viaStack, /* void */, "Expected valid via stack in onEditLayerChanged" );
1101
1102 // Save data from the previous layer
1104 {
1105 int diameter = m_viaDiameter.GetValue();
1106 m_viaStack->SetSize( { diameter, diameter }, m_editLayer );
1107 }
1108
1109 switch( m_viaStack->Mode() )
1110 {
1111 default:
1114 break;
1115
1117 switch( m_cbEditLayer->GetSelection() )
1118 {
1119 default:
1120 case 0: m_editLayer = F_Cu; break;
1121 case 1: m_editLayer = PADSTACK::INNER_LAYERS; break;
1122 case 2: m_editLayer = B_Cu; break;
1123 }
1124 break;
1125
1127 {
1128 int layer = m_cbEditLayer->GetSelection();
1129
1130 if( layer < 0 )
1131 layer = 0;
1132
1133 if( m_editLayerCtrlMap.contains( layer ) )
1134 m_editLayer = m_editLayerCtrlMap.at( layer );
1135 else
1136 m_editLayer = F_Cu;
1137 }
1138 }
1139
1140 // Load controls with the current layer
1142}
1143
1144
1146{
1147 // NOTE: synchronize changes here with DIALOG_PAD_PROPERTIES::afterPadstackModeChanged
1148
1149 wxCHECK_MSG( m_viaStack, /* void */, "Expected valid via stack in afterPadstackModeChanged" );
1150 m_cbEditLayer->Clear();
1151
1152 BOARD* board = m_frame->GetBoard();
1153
1154 switch( m_viaStack->Mode() )
1155 {
1157 m_cbPadstackMode->SetSelection( 0 );
1158 m_cbEditLayer->Append( _( "All layers" ) );
1159 m_cbEditLayer->Disable();
1162 break;
1163
1165 {
1166 m_cbPadstackMode->SetSelection( 1 );
1167 m_cbEditLayer->Enable();
1168
1169 std::vector choices = {
1170 board->GetLayerName( F_Cu ),
1171 _( "Inner Layers" ),
1172 board->GetLayerName( B_Cu )
1173 };
1174
1175 m_cbEditLayer->Append( choices );
1176
1178 { 0, F_Cu },
1180 { 2, B_Cu }
1181 };
1182
1183 if( m_editLayer != F_Cu && m_editLayer != B_Cu )
1185
1186 break;
1187 }
1188
1190 {
1191 m_cbPadstackMode->SetSelection( 2 );
1192 m_cbEditLayer->Enable();
1193 LSET layers = LSET::AllCuMask() & board->GetEnabledLayers();
1194
1195 for( PCB_LAYER_ID layer : layers.UIOrder() )
1196 {
1197 int idx = m_cbEditLayer->Append( board->GetLayerName( layer ) );
1198 m_editLayerCtrlMap[idx] = layer;
1199 }
1200
1201 break;
1202 }
1203 }
1204
1205 for( const auto& [idx, layer] : m_editLayerCtrlMap )
1206 {
1207 if( layer == m_editLayer )
1208 {
1209 m_cbEditLayer->SetSelection( idx );
1210 break;
1211 }
1212 }
1213}
1214
1215
1217{
1218 int viaType = m_ViaTypeChoice->GetSelection();
1219
1220 if( viaType <= 0 )
1221 return m_frame->GetBoard()->GetCopperLayerCount() - 1;
1222
1223 int startLayer = m_ViaStartLayer->GetLayerSelection();
1224 int endLayer = m_ViaEndLayer->GetLayerSelection();
1225
1226 if( startLayer < 0 || endLayer < 0 )
1227 return m_frame->GetBoard()->GetCopperLayerCount() - 1;
1228 else
1229 return m_frame->GetBoard()->LayerDepth( ToLAYER_ID( startLayer ), ToLAYER_ID( endLayer ) );
1230}
1231
1232
1233void DIALOG_TRACK_VIA_PROPERTIES::onViaEdit( wxCommandEvent& aEvent )
1234{
1235 m_predefinedViaSizesCtrl->SetSelection( wxNOT_FOUND );
1236
1237 if( m_vias )
1238 {
1239 if( m_ViaTypeChoice->GetSelection() != 0 ) // check if selected type isn't through.
1240 {
1241 m_ViaStartLayer->Enable();
1242 m_ViaEndLayer->Enable();
1243 }
1244 else
1245 {
1248
1249 m_ViaStartLayer->Enable( false );
1250 m_ViaEndLayer->Enable( false );
1251 }
1252
1253 m_annularRingsLabel->Show( getLayerDepth() > 1 );
1254 m_annularRingsCtrl->Show( getLayerDepth() > 1 );
1255 }
1256}
1257
1258
1259void DIALOG_TRACK_VIA_PROPERTIES::onTrackEdit( wxCommandEvent& aEvent )
1260{
1261 bool externalCuLayer = m_TrackLayerCtrl->GetLayerSelection() == F_Cu
1263
1264 m_techLayersLabel->Enable( externalCuLayer );
1265 m_trackHasSolderMask->Enable( externalCuLayer );
1266
1267 bool showMaskMargin = externalCuLayer && m_trackHasSolderMask->GetValue();
1268
1269 m_trackMaskMarginCtrl->Enable( showMaskMargin );
1270 m_trackMaskMarginLabel->Enable( showMaskMargin );
1271 m_trackMaskMarginUnit->Enable( showMaskMargin );
1272}
1273
1274
1276{
1277 event.Enable( !m_frame->GetBoard()->LegacyTeardrops() );
1278}
1279
const char * name
Definition: DXF_plotter.cpp:59
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition: bitmap.cpp:110
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
virtual void Revert() override
Revert the commit by restoring the modified items state.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
TEARDROP_PARAMETERS & GetTeardropParams()
std::vector< int > m_TrackWidthList
std::vector< VIA_DIMENSION > m_ViasDimensionsList
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 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
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:299
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:249
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:297
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:897
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:2011
int GetCopperLayerCount() const
Definition: board.cpp:781
const FOOTPRINTS & Footprints() const
Definition: board.h:338
const TRACKS & Tracks() const
Definition: board.h:336
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:614
int LayerDepth(PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer) const
Definition: board.cpp:817
bool LegacyTeardrops() const
Definition: board.h:1272
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:829
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:495
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Modify a given item in the model.
Definition: commit.h:108
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:66
void SetupStandardButtons(std::map< int, wxString > aLabels={})
bool m_useCalculatedSize
Definition: dialog_shim.h:198
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
Class DIALOG_TRACK_VIA_PROPERTIES_BASE.
void onWidthEdit(wxCommandEvent &aEvent) override
void onUnitsChanged(wxCommandEvent &aEvent)
void onNetSelector(wxCommandEvent &aEvent)
void onWidthSelect(wxCommandEvent &aEvent) override
bool confirmShortingNets(int aNet, const std::set< int > &shortingNets)
const std::map< IPC4761_PRESET, IPC4761_CONFIGURATION > m_IPC4761Presets
const std::map< IPC4761_PRESET, wxString > m_IPC4761Names
void onTeardropsUpdateUi(wxUpdateUIEvent &event) override
void onPadstackModeChanged(wxCommandEvent &aEvent) override
void onViaEdit(wxCommandEvent &aEvent) override
std::map< int, PCB_LAYER_ID > m_editLayerCtrlMap
PCB_LAYER_ID m_editLayer
The currently-shown copper layer of the edited via(s)
void onViaSelect(wxCommandEvent &aEvent) override
void onEditLayerChanged(wxCommandEvent &aEvent) override
void onViaNotFreeClicked(wxCommandEvent &aEvent) override
DIALOG_TRACK_VIA_PROPERTIES(PCB_BASE_EDIT_FRAME *aParent, const PCB_SELECTION &aItems)
std::unique_ptr< PADSTACK > m_viaStack
Temporary padstack of the edited via(s)
bool confirmPadChange(const std::set< PAD * > &connectedPads)
void onTrackEdit(wxCommandEvent &aEvent) override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:96
const wxString & GetReference() const
Definition: footprint.h:621
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
bool SetOKCancelLabels(const ButtonLabel &ok, const ButtonLabel &cancel) override
Definition: kidialog.h:53
int ShowModal() override
Definition: kidialog.cpp:95
int SetLayerSelection(int layer)
bool SetLayersHotkeys(bool value)
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
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition: lset.cpp:613
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:583
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:297
const wxString & GetNetname() const
Definition: netinfo.h:114
void SetNetInfo(const NETINFO_LIST *aNetInfoList)
bool IsIndeterminate()
void SetBoard(BOARD *aBoard)
int GetSelectedNetcode()
void SetIndeterminateString(const wxString &aString)
void SetSelectedNetcode(int aNetcode)
void SetIndeterminate()
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
Definition: padstack.h:124
@ NORMAL
Shape is the same on all layers.
@ CUSTOM
Shapes can be defined on arbitrary layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Definition: padstack.h:144
static constexpr PCB_LAYER_ID INNER_LAYERS
! The layer identifier to use for "inner layers" on top/inner/bottom padstacks
Definition: padstack.h:147
Definition: pad.h:54
const wxString & GetNumber() const
Definition: pad.h:136
Common, abstract interface for edit frames.
BOARD * GetBoard() const
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Return the BOARD_DESIGN_SETTINGS for the open project.
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
void SetUndefinedLayerName(const wxString &aName)
void SetNotAllowedLayerSet(const LSET &aMask)
bool HasSolderMask() const
Definition: pcb_track.h:176
int GetStartY() const
Definition: pcb_track.h:158
int GetEndX() const
Definition: pcb_track.h:163
std::optional< int > GetLocalSolderMaskMargin() const
Definition: pcb_track.h:179
int GetEndY() const
Definition: pcb_track.h:164
int GetStartX() const
Definition: pcb_track.h:157
virtual int GetWidth() const
Definition: pcb_track.h:146
bool GetIsFree() const
Check if the via is a free via (as opposed to one created on a track by the router).
Definition: pcb_track.h:700
PCB_LAYER_ID BottomLayer() const
Definition: pcb_track.cpp:1386
VECTOR2I GetPosition() const override
Definition: pcb_track.h:551
const PADSTACK & Padstack() const
Definition: pcb_track.h:453
int GetWidth() const override
Definition: pcb_track.cpp:380
PCB_LAYER_ID TopLayer() const
Definition: pcb_track.cpp:1380
int GetDrillValue() const
Calculate the drill value for vias (m_drill if > 0, or default drill value for the board).
Definition: pcb_track.cpp:634
VIATYPE GetViaType() const
Definition: pcb_track.h:450
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:110
TEARDROP_PARAMETARS is a helper class to handle parameters needed to build teardrops for a board thes...
double m_BestWidthRatio
The height of a teardrop as ratio between height and size of pad/via.
int m_TdMaxLen
max allowed length for teardrops in IU. <= 0 to disable
bool m_AllowUseTwoTracks
True to create teardrops using 2 track segments if the first in too small.
int m_TdMaxWidth
max allowed height for teardrops in IU. <= 0 to disable
double m_BestLengthRatio
The length of a teardrop as ratio between length and size of pad/via.
double m_WidthtoSizeFilterRatio
The ratio (H/D) between the via/pad size and the track width max value to create a teardrop 1....
bool m_Enabled
Flag to enable teardrops.
bool m_CurvedEdges
True if the teardrop should be curved.
EDA_UNITS GetUserUnits() 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.
int GetIntValue()
Definition: unit_binder.h:129
virtual long long int GetValue()
Return the current value in Internal Units.
virtual void SetUnits(EDA_UNITS aUnits)
Normally not needed (as the UNIT_BINDER inherits from the parent frame), but can be used to set to DE...
virtual double GetDoubleValue()
Return the current value in Internal Units.
bool IsIndeterminate() const
Return true if the control holds the indeterminate value (for instance, if it represents a multiple s...
virtual void SetDoubleValue(double aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Validate the control against the given range, informing the user of any errors found.
virtual void ChangeValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion WITHOUT trigger...
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
void SetCoordType(ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType)
Set the current origin transform mode.
Definition: unit_binder.h:200
bool IsNull() const
Return true if the control holds no value (ie: empty string, not 0).
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.
#define _(s)
@ ALL_LAYERS
This file is part of the common library.
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ B_Cu
Definition: layer_ids.h:65
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ F_Cu
Definition: layer_ids.h:64
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:747
KICOMMON_API wxString GetLabel(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
Definition: eda_units.cpp:180
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:156
#define GEOMETRY_MIN_SIZE
Definition: pcb_track.h:112
VIATYPE
Definition: pcb_track.h:66
bool collide(T aObject, U aAnotherObject, int aLayer, int aMinDistance)
Used by SHAPE_INDEX to implement Query().
Definition: shape_index.h:97
bool operator==(const IPC4761_CONFIGURATION &other) const
Container to handle a stock of specific vias each with unique diameter and drill sizes in the BOARD c...
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
#define INDETERMINATE_ACTION
Definition: ui_common.h:47
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
Definition: ui_common.h:46