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 (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Maciej Suminski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <core/kicad_algo.h>
31#include <footprint.h>
32#include <pad.h>
33#include <pcb_track.h>
34#include <pcb_edit_frame.h>
35#include <confirm.h>
37#include <board_commit.h>
38#include <macros.h>
39
41 const PCB_SELECTION& aItems ) :
43 m_frame( aParent ),
44 m_items( aItems ),
45 m_trackStartX( aParent, m_TrackStartXLabel, m_TrackStartXCtrl, nullptr ),
46 m_trackStartY( aParent, m_TrackStartYLabel, m_TrackStartYCtrl, m_TrackStartYUnit ),
47 m_trackEndX( aParent, m_TrackEndXLabel, m_TrackEndXCtrl, nullptr ),
48 m_trackEndY( aParent, m_TrackEndYLabel, m_TrackEndYCtrl, m_TrackEndYUnit ),
49 m_trackWidth( aParent, m_TrackWidthLabel, m_TrackWidthCtrl, m_TrackWidthUnit ),
50 m_viaX( aParent, m_ViaXLabel, m_ViaXCtrl, nullptr ),
51 m_viaY( aParent, m_ViaYLabel, m_ViaYCtrl, m_ViaYUnit ),
52 m_viaDiameter( aParent, m_ViaDiameterLabel, m_ViaDiameterCtrl, m_ViaDiameterUnit ),
53 m_viaDrill( aParent, m_ViaDrillLabel, m_ViaDrillCtrl, m_ViaDrillUnit ),
54 m_teardropHDPercent( aParent, m_stHDRatio, m_tcHDRatio, m_stHDRatioUnits ),
55 m_teardropLenPercent( aParent, m_stLenPercentLabel, m_tcLenPercent, m_stLenPercentUnits ),
56 m_teardropMaxLen( aParent, m_stMaxLen, m_tcTdMaxLen, m_stMaxLenUnits ),
57 m_teardropHeightPercent( aParent, m_stHeightPercentLabel, m_tcHeightPercent, m_stHeightPercentUnits ),
58 m_teardropMaxHeight( aParent, m_stMaxHeight, m_tcMaxHeight, m_stMaxHeightUnits ),
59 m_tracks( false ),
60 m_vias( false )
61{
63
64 wxASSERT( !m_items.Empty() );
65
66 m_legacyTeardropsIcon->SetBitmap( KiBitmapBundle( BITMAPS::dialog_warning ) );
68
69 m_bitmapTeardrop->SetBitmap( KiBitmapBundle( BITMAPS::teardrop_sizes ) );
70
71 m_teardropHDPercent.SetUnits( EDA_UNITS::PERCENT );
72 m_teardropLenPercent.SetUnits( EDA_UNITS::PERCENT );
73 m_teardropHeightPercent.SetUnits( EDA_UNITS::PERCENT );
74
75 m_minTrackWidthHint->SetFont( KIUI::GetInfoFont( this ).Italic() );
76
77 // Configure display origin transforms
84
85 VIATYPE viaType = VIATYPE::NOT_DEFINED;
86
91
96
99 m_ViaEndLayer->SetBoardFrame( aParent );
101
102 bool nets = false;
103 int net = 0;
104 bool tracksMatchNetclassValues = true;
105 bool viasMatchNetclassValues = true;
106 bool hasLocked = false;
107 bool hasUnlocked = false;
108
109 // Start and end layers of vias
110 // if at least 2 vias do not have the same start or the same end layer
111 // the layers will be set as undefined
112 int selection_first_layer = -1;
113 int selection_last_layer = -1;
114
115 // The selection layer for tracks
116 int track_selection_layer = -1;
117
118 auto getAnnularRingSelection =
119 []( const PCB_VIA* via ) -> int
120 {
121 if( !via->GetRemoveUnconnected() )
122 return 0;
123 else if( via->GetKeepStartEnd() )
124 return 1;
125 else
126 return 2;
127 };
128
129 // Look for values that are common for every item that is selected
130 for( EDA_ITEM* item : m_items )
131 {
132 if( !nets )
133 {
134 net = static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetCode();
135 nets = true;
136 }
137 else if( net != static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetCode() )
138 {
139 net = -1;
140 }
141
142 switch( item->Type() )
143 {
144 case PCB_TRACE_T:
145 case PCB_ARC_T:
146 {
147 const PCB_TRACK* t = static_cast<const PCB_TRACK*>( item );
148
149 if( !m_tracks ) // first track in the list
150 {
156 m_trackDesignRules->SetValue( false );
157 track_selection_layer = t->GetLayer();
158 m_tracks = true;
159 }
160 else // check if values are the same for every selected track
161 {
162 if( m_trackStartX.GetValue() != t->GetStart().x )
164
165 if( m_trackStartY.GetValue() != t->GetStart().y )
167
168 if( m_trackEndX.GetValue() != t->GetEnd().x )
170
171 if( m_trackEndY.GetValue() != t->GetEnd().y )
173
174 if( m_trackWidth.GetValue() != t->GetWidth() )
176
177 if( track_selection_layer != t->GetLayer() )
178 track_selection_layer = UNDEFINED_LAYER;
179 }
180
181 if( tracksMatchNetclassValues )
182 {
183 MINOPTMAX<int> constraint = t->GetWidthConstraint();
184
185 if( constraint.HasOpt() )
186 tracksMatchNetclassValues &= constraint.Opt() == t->GetWidth();
187 else if( constraint.Min() > 0 )
188 tracksMatchNetclassValues &= constraint.Min() == t->GetWidth();
189 }
190
191 if( t->IsLocked() )
192 hasLocked = true;
193 else
194 hasUnlocked = true;
195
196 break;
197 }
198
199 case PCB_VIA_T:
200 {
201 PCB_VIA* v = static_cast<PCB_VIA*>( item );
202
203 if( !m_vias ) // first via in the list
204 {
209 m_vias = true;
210 viaType = v->GetViaType();
211 m_viaNotFree->SetValue( !v->GetIsFree() );
212 m_annularRingsCtrl->SetSelection( getAnnularRingSelection( v ) );
213 selection_first_layer = v->TopLayer();
214 selection_last_layer = v->BottomLayer();
215
216 m_cbTeardrops->SetValue( v->GetTeardropParams().m_Enabled );
223 m_curvedEdges->SetValue( v->GetTeardropParams().IsCurved() );
225 }
226 else // check if values are the same for every selected via
227 {
228 if( m_viaX.GetValue() != v->GetPosition().x )
230
231 if( m_viaY.GetValue() != v->GetPosition().y )
233
234 if( m_viaDiameter.GetValue() != v->GetWidth() )
236
237 if( m_viaDrill.GetValue() != v->GetDrillValue() )
239
240 if( viaType != v->GetViaType() )
241 viaType = VIATYPE::NOT_DEFINED;
242
243 if( v->GetIsFree() != !m_viaNotFree->GetValue() )
244 m_viaNotFree->Set3StateValue( wxCHK_UNDETERMINED );
245
246 if( selection_first_layer != v->TopLayer() )
247 selection_first_layer = UNDEFINED_LAYER;
248
249 if( selection_last_layer != v->BottomLayer() )
250 selection_last_layer = UNDEFINED_LAYER;
251
252 if( m_annularRingsCtrl->GetSelection() != getAnnularRingSelection( v ) )
253 {
254 if( m_annularRingsCtrl->GetStrings().size() < 4 )
256
257 m_annularRingsCtrl->SetSelection( 3 );
258 }
259
260 if( m_cbTeardrops->GetValue() != v->GetTeardropParams().m_Enabled )
261 m_cbTeardrops->Set3StateValue( wxCHK_UNDETERMINED );
262
264 m_cbTeardropsUseNextTrack->Set3StateValue( wxCHK_UNDETERMINED );
265
268
271
274
277
280
281 if( m_curvePointsCtrl->GetValue() != v->GetTeardropParams().m_CurveSegCount )
282 {
283 m_curvedEdges->Set3StateValue( wxCHK_UNDETERMINED );
284 m_curvePointsCtrl->SetValue( 5 );
285 }
286 }
287
288 if( viasMatchNetclassValues )
289 {
290 MINOPTMAX<int> constraint = v->GetWidthConstraint();
291
292 if( constraint.HasOpt() )
293 viasMatchNetclassValues &= constraint.Opt() == v->GetWidth();
294 else if( constraint.Min() > 0 )
295 viasMatchNetclassValues &= constraint.Min() == v->GetWidth();
296
297 constraint = v->GetDrillConstraint();
298
299 if( constraint.HasOpt() )
300 viasMatchNetclassValues &= constraint.Opt() == v->GetDrillValue();
301 else if( constraint.Min() > 0 )
302 viasMatchNetclassValues &= constraint.Min() == v->GetDrillValue();
303 }
304
305 if( v->IsLocked() )
306 hasLocked = true;
307 else
308 hasUnlocked = true;
309
310 break;
311 }
312
313 default:
314 {
315 wxASSERT( false );
316 break;
317 }
318 }
319 }
320
321 if( m_tracks )
322 {
323 // Set the track layer selection state:
324 if( track_selection_layer == UNDEFINED_LAYER )
325 {
328 }
329
330 m_TrackLayerCtrl->SetLayerSelection( track_selection_layer );
331 }
332
333 // Set the vias layers selections state:
334 if( m_vias )
335 {
336 if( selection_first_layer == UNDEFINED_LAYER )
337 {
340 }
341
342 m_ViaStartLayer->SetLayerSelection( selection_first_layer );
343
344 if( selection_last_layer == UNDEFINED_LAYER )
345 {
348 }
349
350 m_ViaEndLayer->SetLayerSelection( selection_last_layer );
351 }
352
353 m_netSelector->SetBoard( aParent->GetBoard() );
354 m_netSelector->SetNetInfo( &aParent->GetBoard()->GetNetInfo() );
355
356 if ( net >= 0 )
357 {
359 }
360 else
361 {
364 }
365
366 wxASSERT( m_tracks || m_vias );
367
368 if( m_vias )
369 {
370 if( m_viaNotFree->GetValue() && !m_tracks )
371 {
372 // Disable net selector to re-inforce meaning of "Automatically update via nets",
373 // but not when tracks are also selected as then things get harder if you want to
374 // update all the nets to match.
375 m_netSelectorLabel->Disable();
376 m_netSelector->Disable();
377 }
378
380
381 if( viasMatchNetclassValues )
382 {
383 m_viaDesignRules->SetValue( true );
384
385 m_DesignRuleVias->Enable( false );
386 m_DesignRuleViasCtrl->Enable( false );
387 m_DesignRuleViasUnit->Enable( false );
388 m_viaDiameter.Enable( false );
389 m_viaDrill.Enable( false );
390 }
391 else
392 {
393 int viaSelection = wxNOT_FOUND;
394
395 // 0 is the netclass place-holder
396 for( unsigned ii = 1; ii < aParent->GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
397 {
398 VIA_DIMENSION* viaDimension = &aParent->GetDesignSettings().m_ViasDimensionsList[ii];
399 wxString msg = m_frame->StringFromValue( viaDimension->m_Diameter )
400 + wxT( " / " )
401 + m_frame->StringFromValue( viaDimension->m_Drill );
402 m_DesignRuleViasCtrl->Append( msg, viaDimension );
403
404 if( viaSelection == wxNOT_FOUND
405 && m_viaDiameter.GetValue() == viaDimension->m_Diameter
406 && m_viaDrill.GetValue() == viaDimension->m_Drill )
407 {
408 viaSelection = ii - 1;
409 }
410 }
411
412 m_DesignRuleViasCtrl->SetSelection( viaSelection );
413 }
414
415 m_ViaTypeChoice->Enable();
416
417 switch( viaType )
418 {
419 case VIATYPE::THROUGH: m_ViaTypeChoice->SetSelection( 0 ); break;
420 case VIATYPE::MICROVIA: m_ViaTypeChoice->SetSelection( 1 ); break;
421 case VIATYPE::BLIND_BURIED: m_ViaTypeChoice->SetSelection( 2 ); break;
422 case VIATYPE::NOT_DEFINED: m_ViaTypeChoice->SetSelection( wxNOT_FOUND ); break;
423 }
424
425 m_ViaStartLayer->Enable( viaType != VIATYPE::THROUGH );
426 m_ViaEndLayer->Enable( viaType != VIATYPE::THROUGH );
427
428 m_annularRingsLabel->Show( getLayerDepth() > 1 );
429 m_annularRingsCtrl->Show( getLayerDepth() > 1 );
430 }
431 else
432 {
433 m_viaNotFree->Hide();
434 m_MainSizer->Hide( m_sbViaSizer, true );
435 }
436
437 if( m_tracks )
438 {
440
441 if( tracksMatchNetclassValues )
442 {
443 m_trackDesignRules->SetValue( true );
444
445 m_DesignRuleWidths->Enable( false );
446 m_DesignRuleWidthsCtrl->Enable( false );
447 m_DesignRuleWidthsUnits->Enable( false );
448 m_trackWidth.Enable( false );
449 }
450 else
451 {
452 int widthSelection = wxNOT_FOUND;
453
454 // 0 is the netclass place-holder
455 for( unsigned ii = 1; ii < aParent->GetDesignSettings().m_TrackWidthList.size(); ii++ )
456 {
457 int width = aParent->GetDesignSettings().m_TrackWidthList[ii];
458 wxString msg = m_frame->StringFromValue( width );
459 m_DesignRuleWidthsCtrl->Append( msg );
460
461 if( widthSelection == wxNOT_FOUND && m_trackWidth.GetValue() == width )
462 widthSelection = ii - 1;
463 }
464
465 m_DesignRuleWidthsCtrl->SetSelection( widthSelection );
466 }
467 }
468 else
469 {
470 m_MainSizer->Hide( m_sbTrackSizer, true );
471 }
472
473 if( hasLocked && hasUnlocked )
474 m_lockedCbox->Set3StateValue( wxCHK_UNDETERMINED );
475 else if( hasLocked )
476 m_lockedCbox->Set3StateValue( wxCHK_CHECKED );
477 else
478 m_lockedCbox->Set3StateValue( wxCHK_UNCHECKED );
479
480 if( m_tracks )
482 else if( m_netSelector->IsEnabled() )
484 else
486
488
489 m_frame->Bind( EDA_EVT_UNITS_CHANGED, &DIALOG_TRACK_VIA_PROPERTIES::onUnitsChanged, this );
490 m_netSelector->Bind( NET_SELECTED, &DIALOG_TRACK_VIA_PROPERTIES::onNetSelector, this );
491
492 // Now all widgets have the size fixed, call FinishDialogSettings
494}
495
496
498{
499 m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &DIALOG_TRACK_VIA_PROPERTIES::onUnitsChanged, this );
500}
501
502
504{
505 if( m_vias )
506 {
507 int viaSel = m_DesignRuleViasCtrl->GetSelection();
508
509 m_DesignRuleViasCtrl->Clear();
510
511 // 0 is the netclass place-holder
512 for( unsigned ii = 1; ii < m_frame->GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
513 {
515 wxString msg = m_frame->StringFromValue( viaDimension->m_Diameter )
516 + wxT( " / " )
517 + m_frame->StringFromValue( viaDimension->m_Drill );
518 m_DesignRuleViasCtrl->Append( msg, viaDimension );
519 }
520
521 m_DesignRuleViasCtrl->SetSelection( viaSel );
523 }
524
525 if( m_tracks )
526 {
527 int trackSel = m_DesignRuleWidthsCtrl->GetSelection();
528
529 m_DesignRuleWidthsCtrl->Clear();
530
531 // 0 is the netclass place-holder
532 for( unsigned ii = 1; ii < m_frame->GetDesignSettings().m_TrackWidthList.size(); ii++ )
533 {
534 int width = m_frame->GetDesignSettings().m_TrackWidthList[ii];
535 wxString msg = m_frame->StringFromValue( width );
536 m_DesignRuleWidthsCtrl->Append( msg );
537 }
538
539 m_DesignRuleWidthsCtrl->SetSelection( trackSel );
541 }
542
543 aEvent.Skip();
544}
545
546
547bool DIALOG_TRACK_VIA_PROPERTIES::confirmPadChange( const std::vector<PAD*>& changingPads )
548{
549 wxString msg;
550
551 if( changingPads.size() == 1 )
552 {
553 PAD* pad = *changingPads.begin();
554 msg.Printf( _( "Changing the net will also update %s pad %s to %s." ),
555 pad->GetParentFootprint()->GetReference(),
556 pad->GetNumber(),
557 m_netSelector->GetValue() );
558 }
559 else if( changingPads.size() == 2 )
560 {
561 PAD* pad1 = *changingPads.begin();
562 PAD* pad2 = *( ++changingPads.begin() );
563 msg.Printf( _( "Changing the net will also update %s pad %s and %s pad %s to %s." ),
565 pad1->GetNumber(),
567 pad2->GetNumber(),
568 m_netSelector->GetValue() );
569 }
570 else
571 {
572 msg.Printf( _( "Changing the net will also update %lu connected pads to %s." ),
573 static_cast<unsigned long>( changingPads.size() ),
574 m_netSelector->GetValue() );
575 }
576
577 KIDIALOG dlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
578 dlg.SetOKCancelLabels( _( "Change Nets" ), _( "Leave Nets Unchanged" ) );
579 dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
580
581 return dlg.ShowModal() == wxID_OK;
582}
583
584
586{
587 // Check for malformed data ONLY; design rules and constraints are the business of DRC.
588
589 if( m_vias )
590 {
592 || !m_viaDrill.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
593 {
594 return false;
595 }
596
597 if( m_ViaDiameterCtrl->IsEnabled() && !m_viaDiameter.IsIndeterminate()
598 && m_ViaDrillCtrl->IsEnabled() && !m_viaDrill.IsIndeterminate()
600 {
601 DisplayError( GetParent(), _( "Via hole size must be smaller than via diameter" ) );
602 m_ViaDrillCtrl->SelectAll();
603 m_ViaDrillCtrl->SetFocus();
604 return false;
605 }
606
609 {
610 DisplayError( GetParent(), _( "Via start layer and end layer cannot be the same" ) );
611 return false;
612 }
613 }
614
615 if( m_tracks )
616 {
617 if( !m_trackWidth.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
618 return false;
619 }
620
621 // If we survived that, then save the changes:
622 //
623 // We don't bother with updating the nets at this point as it will be useless (any connected
624 // pads will simply drive their existing nets back onto the track segments and vias).
625
626 BOARD_COMMIT commit( m_frame );
627 bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED;
628 bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED;
629
630 for( EDA_ITEM* item : m_items )
631 {
632 commit.Modify( item );
633
634 switch( item->Type() )
635 {
636 case PCB_TRACE_T:
637 case PCB_ARC_T:
638 {
639 wxASSERT( m_tracks );
640 PCB_TRACK* t = static_cast<PCB_TRACK*>( item );
641
644
647
650
653
654 if( m_trackDesignRules->IsChecked() )
655 {
656 MINOPTMAX<int> constraint = t->GetWidthConstraint();
657
658 if( constraint.HasOpt() )
659 t->SetWidth( constraint.Opt() );
660 else if( constraint.Min() > 0 )
661 t->SetWidth( constraint.Min() );
662 }
663 else if( !m_trackWidth.IsIndeterminate() )
664 {
666 }
667
668 int layer = m_TrackLayerCtrl->GetLayerSelection();
669
670 if( layer != UNDEFINED_LAYER )
671 t->SetLayer( (PCB_LAYER_ID) layer );
672
673 if( changeLock )
674 t->SetLocked( setLock );
675
676 break;
677 }
678
679 case PCB_VIA_T:
680 {
681 wxASSERT( m_vias );
682 PCB_VIA* v = static_cast<PCB_VIA*>( item );
683
684 if( !m_viaX.IsIndeterminate() )
686
687 if( !m_viaY.IsIndeterminate() )
689
690 if( m_viaNotFree->Get3StateValue() != wxCHK_UNDETERMINED )
691 v->SetIsFree( !m_viaNotFree->GetValue() );
692
693 switch( m_ViaTypeChoice->GetSelection() )
694 {
695 case 0:
696 v->SetViaType( VIATYPE::THROUGH );
697 v->SanitizeLayers();
698 break;
699 case 1:
700 v->SetViaType( VIATYPE::MICROVIA );
701 break;
702 case 2:
703 v->SetViaType( VIATYPE::BLIND_BURIED );
704 break;
705 default:
706 break;
707 }
708
709 auto startLayer = static_cast<PCB_LAYER_ID>( m_ViaStartLayer->GetLayerSelection() );
710 auto endLayer = static_cast<PCB_LAYER_ID>( m_ViaEndLayer->GetLayerSelection() );
711
712 if (startLayer != UNDEFINED_LAYER )
713 v->SetTopLayer( startLayer );
714
715 if (endLayer != UNDEFINED_LAYER )
716 v->SetBottomLayer( endLayer );
717
718 switch( m_annularRingsCtrl->GetSelection() )
719 {
720 case 0:
721 v->SetRemoveUnconnected( false );
722 break;
723 case 1:
724 v->SetRemoveUnconnected( true );
725 v->SetKeepStartEnd( true );
726 break;
727 case 2:
728 v->SetRemoveUnconnected( true );
729 v->SetKeepStartEnd( false );
730 break;
731 default:
732 break;
733 }
734
735 v->SanitizeLayers();
736
737 if( m_viaDesignRules->IsChecked() )
738 {
739 MINOPTMAX<int> constraint = v->GetWidthConstraint();
740
741 if( constraint.HasOpt() )
742 v->SetWidth( constraint.Opt() );
743 else if( constraint.Min() > 0 )
744 v->SetWidth( constraint.Min() );
745
746 constraint = v->GetDrillConstraint();
747
748 if( constraint.HasOpt() )
749 v->SetDrill( constraint.Opt() );
750 else if( constraint.Min() > 0 )
751 v->SetDrill( constraint.Min() );
752 }
753 else
754 {
757
760 }
761
762 TEARDROP_PARAMETERS* targetParams = &v->GetTeardropParams();
763
764 if( m_cbTeardrops->Get3StateValue() != wxCHK_UNDETERMINED )
765 targetParams->m_Enabled = m_cbTeardrops->GetValue();
766
767 if( m_cbTeardropsUseNextTrack->Get3StateValue() != wxCHK_UNDETERMINED )
768 targetParams->m_AllowUseTwoTracks = m_cbTeardropsUseNextTrack->GetValue();
769
771 targetParams->m_TdMaxLen = m_teardropMaxLen.GetIntValue();
772
775
777 targetParams->m_BestLengthRatio = m_teardropLenPercent.GetDoubleValue() / 100.0;
778
781
784
785 if( m_curvedEdges->Get3StateValue() != wxCHK_UNDETERMINED )
786 {
787 if( m_curvedEdges->GetValue() )
788 targetParams->m_CurveSegCount = m_curvePointsCtrl->GetValue();
789 else
790 targetParams->m_CurveSegCount = 0;
791 }
792
793 if( changeLock )
794 v->SetLocked( setLock );
795
796 break;
797 }
798
799 default:
800 wxASSERT( false );
801 break;
802 }
803 }
804
805 commit.Push( _( "Edit track/via properties" ) );
806
807 // Pushing the commit will have updated the connectivity so we can now test to see if we
808 // need to update any pad nets.
809
810 auto connectivity = m_frame->GetBoard()->GetConnectivity();
811 int newNetCode = m_netSelector->GetSelectedNetcode();
812 bool updateNets = false;
813 std::vector<PAD*> changingPads;
814
816 {
817 updateNets = true;
818
819 for( EDA_ITEM* item : m_items )
820 {
821 BOARD_CONNECTED_ITEM* boardItem = static_cast<BOARD_CONNECTED_ITEM*>( item );
822 auto connectedItems = connectivity->GetConnectedItems( boardItem,
824
825 for ( BOARD_CONNECTED_ITEM* citem : connectedItems )
826 {
827 if( citem->Type() == PCB_PAD_T )
828 {
829 PAD* pad = static_cast<PAD*>( citem );
830
831 if( pad->GetNetCode() != newNetCode && !alg::contains( changingPads, citem ) )
832 changingPads.push_back( pad );
833 }
834 }
835 }
836 }
837
838 if( changingPads.size() && !confirmPadChange( changingPads ) )
839 updateNets = false;
840
841 if( updateNets )
842 {
843 for( EDA_ITEM* item : m_items )
844 {
845 commit.Modify( item );
846
847 switch( item->Type() )
848 {
849 case PCB_TRACE_T:
850 case PCB_ARC_T:
851 static_cast<PCB_TRACK*>( item )->SetNetCode( newNetCode );
852 break;
853
854 case PCB_VIA_T:
855 static_cast<PCB_VIA*>( item )->SetNetCode( newNetCode );
856 break;
857
858 default:
859 wxASSERT( false );
860 break;
861 }
862 }
863
864 for( PAD* pad : changingPads )
865 {
866 commit.Modify( pad );
867 pad->SetNetCode( newNetCode );
868 }
869
870 commit.Push( _( "Updating nets" ) );
871 }
872
873 return true;
874}
875
876
877void DIALOG_TRACK_VIA_PROPERTIES::onNetSelector( wxCommandEvent& aEvent )
878{
879 m_viaNotFree->SetValue( false );
880}
881
882
884{
885 if( !m_tracks )
886 {
887 m_netSelectorLabel->Enable( !m_viaNotFree->GetValue() );
888 m_netSelector->Enable( !m_viaNotFree->GetValue() );
889 }
890}
891
892
894{
895 bool enableNC = aEvent.IsChecked();
896
897 m_DesignRuleWidths->Enable( !enableNC );
898 m_DesignRuleWidthsCtrl->Enable( !enableNC );
899 m_DesignRuleWidthsUnits->Enable( !enableNC );
900
901 m_trackWidth.Enable( !enableNC );
902}
903
904
905void DIALOG_TRACK_VIA_PROPERTIES::onWidthSelect( wxCommandEvent& aEvent )
906{
907 m_TrackWidthCtrl->ChangeValue( m_DesignRuleWidthsCtrl->GetStringSelection() );
908 m_TrackWidthCtrl->SelectAll();
909}
910
911
912void DIALOG_TRACK_VIA_PROPERTIES::onWidthEdit( wxCommandEvent& aEvent )
913{
914 m_DesignRuleWidthsCtrl->SetStringSelection( m_TrackWidthCtrl->GetValue() );
915}
916
917
919{
920 bool enableNC = aEvent.IsChecked();
921
922 m_DesignRuleVias->Enable( !enableNC );
923 m_DesignRuleViasCtrl->Enable( !enableNC );
924 m_DesignRuleViasUnit->Enable( !enableNC );
925
926 m_viaDiameter.Enable( !enableNC );
927 m_viaDrill.Enable( !enableNC );
928}
929
930
931void DIALOG_TRACK_VIA_PROPERTIES::onViaSelect( wxCommandEvent& aEvent )
932{
933 VIA_DIMENSION* viaDimension = static_cast<VIA_DIMENSION*> ( aEvent.GetClientData() );
934
935 m_viaDiameter.ChangeValue( viaDimension->m_Diameter );
936 m_viaDrill.ChangeValue( viaDimension->m_Drill );
937}
938
939
941{
942 int viaType = m_ViaTypeChoice->GetSelection();
943
944 if( viaType <= 0 )
945 return m_frame->GetBoard()->GetCopperLayerCount() - 1;
946
947 int startLayer = m_ViaStartLayer->GetLayerSelection();
948 int endLayer = m_ViaEndLayer->GetLayerSelection();
949
950 if( startLayer < 0 || endLayer < 0 )
951 return m_frame->GetBoard()->GetCopperLayerCount() - 1;
952 else
953 return m_frame->GetBoard()->LayerDepth( ToLAYER_ID( startLayer ), ToLAYER_ID( endLayer ) );
954}
955
956
957void DIALOG_TRACK_VIA_PROPERTIES::onViaEdit( wxCommandEvent& aEvent )
958{
959 m_DesignRuleViasCtrl->SetSelection( wxNOT_FOUND );
960
961 if( m_vias )
962 {
963 if( m_ViaTypeChoice->GetSelection() != 0 ) // check if selected type isn't through.
964 {
965 m_ViaStartLayer->Enable();
966 m_ViaEndLayer->Enable();
967 }
968 else
969 {
972
973 m_ViaStartLayer->Enable( false );
974 m_ViaEndLayer->Enable( false );
975 }
976
977 m_annularRingsLabel->Show( getLayerDepth() > 1 );
978 m_annularRingsCtrl->Show( getLayerDepth() > 1 );
979 }
980}
981
982
984{
985 event.Enable( !m_frame->GetBoard()->LegacyTeardrops() );
986}
987
988
990{
991 event.Enable( !m_frame->GetBoard()->LegacyTeardrops()
992 && m_curvedEdges->Get3StateValue() == wxCHK_CHECKED );
993}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) 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:225
virtual void SetLocked(bool aLocked)
Definition: board_item.h:299
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:259
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:247
virtual bool IsLocked() const
Definition: board_item.cpp:73
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:827
int GetCopperLayerCount() const
Definition: board.cpp:604
int LayerDepth(PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer) const
Definition: board.cpp:616
bool LegacyTeardrops() const
Definition: board.h:1209
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:441
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:97
void SetupStandardButtons(std::map< int, wxString > aLabels={})
bool m_useCalculatedSize
Definition: dialog_shim.h:209
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
void onTeardropsUpdateUi(wxUpdateUIEvent &event) override
void onViaEdit(wxCommandEvent &aEvent) override
bool confirmPadChange(const std::vector< PAD * > &connectedPads)
void onCurvedEdgesUpdateUi(wxUpdateUIEvent &event) override
void onViaSelect(wxCommandEvent &aEvent) override
void onViaNotFreeClicked(wxCommandEvent &aEvent) override
void onTrackNetclassCheck(wxCommandEvent &aEvent) override
void onViaNetclassCheck(wxCommandEvent &aEvent) override
DIALOG_TRACK_VIA_PROPERTIES(PCB_BASE_FRAME *aParent, const PCB_SELECTION &aItems)
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
const wxString & GetReference() const
Definition: footprint.h:556
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:47
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
Definition: confirm.cpp:56
bool SetOKCancelLabels(const ButtonLabel &ok, const ButtonLabel &cancel) override
Shows the 'do not show again' checkbox.
Definition: confirm.h:57
int ShowModal() override
Definition: confirm.cpp:100
int SetLayerSelection(int layer)
bool SetLayersHotkeys(bool value)
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition: lset.cpp:803
T Min() const
Definition: minoptmax.h:33
T Opt() const
Definition: minoptmax.h:35
bool HasOpt() const
Definition: minoptmax.h:39
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()
Definition: pad.h:58
const wxString & GetNumber() const
Definition: pad.h:130
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
BOARD * GetBoard() const
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Returns the BOARD_DESIGN_SETTINGS for the open project.
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
void SetNotAllowedLayerSet(LSET aMask)
void SetUndefinedLayerName(const wxString &aName)
void SetWidth(int aWidth)
Definition: pcb_track.h:106
int GetWidth() const
Definition: pcb_track.h:107
void SetEnd(const VECTOR2I &aEnd)
Definition: pcb_track.h:109
void SetStart(const VECTOR2I &aStart)
Definition: pcb_track.h:112
const VECTOR2I & GetStart() const
Definition: pcb_track.h:113
const VECTOR2I & GetEnd() const
Definition: pcb_track.h:110
virtual MINOPTMAX< int > GetWidthConstraint(wxString *aSource=nullptr) const
Definition: pcb_track.cpp:305
void SetRemoveUnconnected(bool aSet)
Sets the unconnected removal property.
Definition: pcb_track.h:500
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:578
PCB_LAYER_ID BottomLayer() const
Definition: pcb_track.cpp:767
VECTOR2I GetPosition() const override
Definition: pcb_track.h:465
void SetKeepStartEnd(bool aSet)
Sets whether we keep the start and end annular rings even if they are not connected.
Definition: pcb_track.h:506
void SetBottomLayer(PCB_LAYER_ID aLayer)
Definition: pcb_track.cpp:733
void SetDrill(int aDrill)
Set the drill value for vias.
Definition: pcb_track.h:550
MINOPTMAX< int > GetDrillConstraint(wxString *aSource=nullptr) const
Definition: pcb_track.cpp:341
void SetIsFree(bool aFree=true)
Definition: pcb_track.h:579
void SetTopLayer(PCB_LAYER_ID aLayer)
Definition: pcb_track.cpp:727
void SetPosition(const VECTOR2I &aPoint) override
Definition: pcb_track.h:466
void SanitizeLayers()
Check so that the layers are correct depending on the type of via, and so that the top actually is on...
Definition: pcb_track.cpp:773
void SetViaType(VIATYPE aViaType)
Definition: pcb_track.h:411
PCB_LAYER_ID TopLayer() const
Definition: pcb_track.cpp:761
int GetDrillValue() const
Calculate the drill value for vias (m_drill if > 0, or default drill value for the board).
Definition: pcb_track.cpp:390
VIATYPE GetViaType() const
Definition: pcb_track.h:410
MINOPTMAX< int > GetWidthConstraint(wxString *aSource=nullptr) const override
Definition: pcb_track.cpp:323
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:109
TEARDROP_PARAMETARS is a helper class to handle parameters needed to build teardrops for a board thes...
int m_CurveSegCount
number of segments to build the curved sides of a teardrop area must be > 2.
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....
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:127
virtual long long int GetValue()
Return the current value in Internal Units.
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
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:189
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:280
This file is part of the common library.
#define _(s)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ B_Cu
Definition: layer_ids.h:96
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ F_Cu
Definition: layer_ids.h:65
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:941
This file contains miscellaneous commonly used macros and functions.
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:139
wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:151
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
#define GEOMETRY_MIN_SIZE
Definition: pcb_track.h:75
VIATYPE
Definition: pcb_track.h:64
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:95
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ 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:96
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:94
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
Definition: ui_common.h:44