KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_copper_zones.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) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
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 <wx/radiobut.h>
27#include <kiface_base.h>
28#include <confirm.h>
29#include <pcb_edit_frame.h>
30#include <pcbnew_settings.h>
31#include <zones.h>
32#include <widgets/unit_binder.h>
33#include <zone.h>
34#include <pad.h>
35#include <board.h>
36#include <trigo.h>
37#include <eda_pattern_match.h>
38
40#include <string_utils.h>
41
42
44{
45public:
47 CONVERT_SETTINGS* aConvertSettings );
48
50 { delete m_gap; }
51
52private:
53 using NET_FILTER = std::unique_ptr<EDA_PATTERN_MATCH>;
54 using NET_FILTER_LIST = std::vector<NET_FILTER>;
55
56 static constexpr int INVALID_NET_CODE{ 0 };
57
58 bool TransferDataToWindow() override;
59 bool TransferDataFromWindow() override;
60
64 bool AcceptOptions();
65
66 void OnStyleSelection( wxCommandEvent& event ) override;
67 void OnLayerSelection( wxDataViewEvent& event ) override;
68 void OnNetSortingOptionSelected( wxCommandEvent& event ) override;
69 void OnShowNetNameFilterChange( wxCommandEvent& event ) override;
70 void OnUpdateUI( wxUpdateUIEvent& ) override;
71 void OnNetSelectionUpdated( wxCommandEvent& event ) override;
72 void OnRemoveIslandsSelection( wxCommandEvent& event ) override;
73
74 void readNetInformation();
76 wxArrayString buildListOfNetsToDisplay();
77 void sortNetsByPadCount( std::vector<NETINFO_ITEM*>& nets, int maxNetCode );
79 int ensureSelectedNetIsVisible( int selectedNetCode, wxArrayString& netsList );
80 void displayNetsList( const wxArrayString& netNamesList, int selectIndex );
82 wxString getUnescapedNetName( const NETINFO_ITEM* net );
83 void sortNetsIfRequired();
85 void updateInfoBar();
86
87private:
89
94
99
105
112
113 wxStaticText* m_gapLabel;
114 wxTextCtrl* m_gapCtrl;
115 wxStaticText* m_gapUnits;
117
118 std::map<wxString, int> m_netNameToNetCode;
119 std::vector<NETINFO_ITEM*> m_netInfoItemList;
120
122 wxRadioButton* m_rbCenterline;
123 wxRadioButton* m_rbEnvelope;
125};
126
127
129 CONVERT_SETTINGS* aConvertSettings )
130{
131 DIALOG_COPPER_ZONE dlg( aCaller, aSettings, aConvertSettings );
132
133 // TODO: why does this need QuasiModal?
134 return dlg.ShowQuasiModal();
135}
136
137
138// The pad count for each netcode, stored in a buffer for a fast access.
139// This is needed by the sort function sortNetsByNodes()
140static std::vector<int> padCountListByNet;
141
142
143// Sort nets by decreasing pad count.
144// For same pad count, sort by alphabetic names
145static bool sortNetsByNodes( const NETINFO_ITEM* a, const NETINFO_ITEM* b )
146{
147 int countA = padCountListByNet[a->GetNetCode()];
148 int countB = padCountListByNet[b->GetNetCode()];
149
150 if( countA == countB )
151 return a->GetNetname() < b->GetNetname();
152 else
153 return countB < countA;
154}
155
156
157// Sort nets by alphabetic names
158static bool sortNetsByNames( const NETINFO_ITEM* a, const NETINFO_ITEM* b )
159{
160 return a->GetNetname() < b->GetNetname();
161}
162
163
165 CONVERT_SETTINGS* aConvertSettings ) :
166 DIALOG_COPPER_ZONE_BASE( aParent ),
167 m_cornerSmoothingType( ZONE_SETTINGS::SMOOTHING_UNDEFINED ),
179 m_convertSettings( aConvertSettings ),
180 m_rbCenterline( nullptr ),
181 m_rbEnvelope( nullptr ),
182 m_cbDeleteOriginals( nullptr )
183{
184 m_Parent = aParent;
185
186 m_ptr = aSettings;
187 m_settings = *aSettings;
188 m_settings.SetupLayersList( m_layers, m_Parent, LSET::AllCuMask( aParent->GetBoard()->GetCopperLayerCount() ) );
190
191 if( m_isTeardrop )
192 SetTitle( _( "Legacy Teardrop Properties" ) );
193
194 if( aConvertSettings )
195 {
196 wxStaticBox* bConvertBox = new wxStaticBox( this, wxID_ANY, _( "Conversion Settings" ) );
197 wxStaticBoxSizer* bConvertSizer = new wxStaticBoxSizer( bConvertBox, wxVERTICAL );
198
199 m_rbCenterline = new wxRadioButton( this, wxID_ANY, _( "Use centerlines" ) );
200 bConvertSizer->Add( m_rbCenterline, 0, wxLEFT|wxRIGHT, 5 );
201
202 bConvertSizer->AddSpacer( 2 );
203 m_rbEnvelope = new wxRadioButton( this, wxID_ANY, _( "Create bounding hull" ) );
204 bConvertSizer->Add( m_rbEnvelope, 0, wxLEFT|wxRIGHT, 5 );
205
206 m_gapLabel = new wxStaticText( this, wxID_ANY, _( "Gap:" ) );
207 m_gapCtrl = new wxTextCtrl( this, wxID_ANY );
208 m_gapUnits = new wxStaticText( this, wxID_ANY, _( "mm" ) );
210 m_gap->SetValue( m_convertSettings->m_Gap );
211
212 wxBoxSizer* hullParamsSizer = new wxBoxSizer( wxHORIZONTAL );
213 hullParamsSizer->Add( m_gapLabel, 0, wxALIGN_CENTRE_VERTICAL|wxRIGHT, 5 );
214 hullParamsSizer->Add( m_gapCtrl, 1, wxALIGN_CENTRE_VERTICAL|wxLEFT|wxRIGHT, 5 );
215 hullParamsSizer->Add( m_gapUnits, 0, wxALIGN_CENTRE_VERTICAL|wxLEFT, 5 );
216 bConvertSizer->AddSpacer( 2 );
217 bConvertSizer->Add( hullParamsSizer, 0, wxLEFT, 26 );
218
219 bConvertSizer->AddSpacer( 6 );
220 m_cbDeleteOriginals = new wxCheckBox( this, wxID_ANY, _( "Delete source objects after conversion" ) );
221 bConvertSizer->Add( m_cbDeleteOriginals, 0, wxALL, 5 );
222
223 GetSizer()->Insert( 0, bConvertSizer, 0, wxALL|wxEXPAND, 10 );
224
225 wxStaticLine* line = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
226 wxLI_HORIZONTAL );
227 GetSizer()->Insert( 1, line, 0, wxLEFT|wxRIGHT|wxEXPAND, 10 );
228
229 SetTitle( _( "Convert to Copper Zone" ) );
230 }
231 else
232 {
233 m_gapLabel = nullptr;
234 m_gapCtrl = nullptr;
235 m_gapUnits = nullptr;
236 m_gap = nullptr;
237 }
238
241
242 m_netSortingByPadCount = true; // false = alphabetic sort, true = pad count sort
243
244 m_ShowNetNameFilter->SetHint( _( "Filter" ) );
245
246 m_cbRemoveIslands->Bind( wxEVT_CHOICE,
247 [&]( wxCommandEvent& )
248 {
249 // Area mode is index 2
250 m_islandThreshold.Enable( m_cbRemoveIslands->GetSelection() == 2 );
251 } );
252
254
256}
257
258
260{
262 {
263 if( m_convertSettings->m_Strategy == BOUNDING_HULL )
264 m_rbEnvelope->SetValue( true );
265 else
266 m_rbCenterline->SetValue( true );
267
268 m_cbDeleteOriginals->SetValue( m_convertSettings->m_DeleteOriginals );
269 m_gap->Enable( m_rbEnvelope->GetValue() );
270 }
271
272 m_cbLocked->SetValue( m_settings.m_Locked );
273 m_cornerSmoothingChoice->SetSelection( m_settings.GetCornerSmoothingType() );
274 m_cornerRadius.SetValue( m_settings.GetCornerRadius() );
275 m_PriorityLevelCtrl->SetValue( m_settings.m_ZonePriority );
276
277 if( m_isTeardrop ) // outlines are never smoothed: they have already the right shape
278 {
279 m_cornerSmoothingChoice->SetSelection( 0 );
280 m_cornerSmoothingChoice->Enable( false );
281 m_cornerRadius.SetValue( 0 );
282 m_cornerRadius.Enable( false );
283 }
284
285 switch( m_settings.m_ZoneBorderDisplayStyle )
286 {
287 case ZONE_BORDER_DISPLAY_STYLE::NO_HATCH: m_OutlineDisplayCtrl->SetSelection( 0 ); break;
290 case ZONE_BORDER_DISPLAY_STYLE::INVISIBLE_BORDER: break; // Not used for standard zones
291 }
292
293 m_outlineHatchPitch.SetValue( m_settings.m_BorderHatchPitch );
294
295 m_clearance.SetValue( m_settings.m_ZoneClearance );
296 m_minWidth.SetValue( m_settings.m_ZoneMinThickness );
297
298 switch( m_settings.GetPadConnection() )
299 {
300 default:
301 case ZONE_CONNECTION::THERMAL: m_PadInZoneOpt->SetSelection( 1 ); break;
302 case ZONE_CONNECTION::THT_THERMAL: m_PadInZoneOpt->SetSelection( 2 ); break;
303 case ZONE_CONNECTION::NONE: m_PadInZoneOpt->SetSelection( 3 ); break;
304 case ZONE_CONNECTION::FULL: m_PadInZoneOpt->SetSelection( 0 ); break;
305 }
306
307 if( m_isTeardrop )
308 {
309 m_PadInZoneOpt->SetSelection( 0 );
310 m_PadInZoneOpt->Enable( false );
311 m_antipadClearance.Enable( false );
312 m_spokeWidth.Enable( false );
313 }
314
315 // Do not enable/disable antipad clearance and spoke width. They might be needed if
316 // a footprint or pad overrides the zone to specify a thermal connection.
317 m_antipadClearance.SetValue( m_settings.m_ThermalReliefGap );
318 m_spokeWidth.SetValue( m_settings.m_ThermalReliefSpokeWidth );
319
321 m_islandThreshold.SetDoubleValue( static_cast<double>( m_settings.GetMinIslandArea() ) );
322
323 m_cbRemoveIslands->SetSelection( static_cast<int>( m_settings.GetIslandRemovalMode() ) );
324
325 m_islandThreshold.Enable( m_settings.GetIslandRemovalMode() == ISLAND_REMOVAL_MODE::AREA );
326
329
331
332 // Initialize information required to display nets list
334
335 m_GridStyleCtrl->SetSelection( m_settings.m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN ? 1 : 0 );
336
337 if( m_isTeardrop )
338 {
339 m_GridStyleCtrl->SetSelection( 0 );
340 m_GridStyleCtrl->Enable( false );
341 }
342
344 m_gridStyleRotation.SetAngleValue( m_settings.m_HatchOrientation );
345 m_gridStyleThickness.SetValue( m_settings.m_HatchThickness );
346 m_gridStyleGap.SetValue( m_settings.m_HatchGap );
347
348 m_spinCtrlSmoothLevel->SetValue( m_settings.m_HatchSmoothingLevel );
349 m_spinCtrlSmoothValue->SetValue( m_settings.m_HatchSmoothingValue );
350
351 m_tcZoneName->SetValue( m_settings.m_Name );
352
354
355 // Enable/Disable some widgets
356 wxCommandEvent event;
357 OnStyleSelection( event );
358 OnNetSelectionUpdated( event );
359
360 Fit();
361
362 return true;
363}
364
365
367{
368 const NETINFO_LIST& netInfoList = m_Parent->GetBoard()->GetNetInfo();
369
370 m_netInfoItemList.clear();
371 m_netInfoItemList.reserve( netInfoList.GetNetCount() );
372
373 m_netNameToNetCode.clear();
374 m_netNameToNetCode[ _( "<no net>" ) ] = INVALID_NET_CODE;
375
377
378 for( NETINFO_ITEM* net : netInfoList )
379 {
380 const int netCode = net->GetNetCode();
381 const wxString& netName = getUnescapedNetName( net );
382
383 m_netNameToNetCode[netName] = netCode;
384
385 if( netCode > INVALID_NET_CODE && net->IsCurrent() )
386 {
387 m_netInfoItemList.push_back( net );
388 m_maxNetCode = std::max( netCode, m_maxNetCode );
389 }
390 }
391
393}
394
395
396void DIALOG_COPPER_ZONE::OnUpdateUI( wxUpdateUIEvent& )
397{
398 if( m_cornerSmoothingType != m_cornerSmoothingChoice->GetSelection() )
399 {
401
403 m_cornerRadiusLabel->SetLabel( _( "Chamfer distance:" ) );
404 else
405 m_cornerRadiusLabel->SetLabel( _( "Fillet radius:" ) );
406 }
407
409
410 if( m_gap )
411 m_gap->Enable( m_rbEnvelope->GetValue() );
412}
413
414
415void DIALOG_COPPER_ZONE::OnNetSelectionUpdated( wxCommandEvent& event )
416{
418
420
421 // When info bar is updated, the nets-list shrinks.
422 // Therefore, we need to reestablish the list and maintain the
423 // correct selection
425
426 // Zones with no net never have islands removed
428 {
429 if( m_cbRemoveIslands->IsEnabled() )
430 m_settings.SetIslandRemovalMode( (ISLAND_REMOVAL_MODE) m_cbRemoveIslands->GetSelection() );
431
432 m_cbRemoveIslands->SetSelection( 1 );
433 m_staticText40->Enable( false );
434 m_cbRemoveIslands->Enable( false );
435 }
436 else if( !m_cbRemoveIslands->IsEnabled() )
437 {
438 m_cbRemoveIslands->SetSelection( static_cast<int>( m_settings.GetIslandRemovalMode() ) );
439 m_staticText40->Enable( true );
440 m_cbRemoveIslands->Enable( true );
441 }
442}
443
444
446{
447 m_islandThreshold.Enable( m_cbRemoveIslands->GetSelection() == 2 );
448}
449
450
452{
453 if( m_GridStyleCtrl->GetSelection() > 0 )
455 else
457
458 if( !AcceptOptions() )
459 return false;
460
462 {
463 if( m_rbEnvelope->GetValue() )
464 m_convertSettings->m_Strategy = BOUNDING_HULL;
465 else
466 m_convertSettings->m_Strategy = CENTERLINE;
467
468 m_convertSettings->m_DeleteOriginals = m_cbDeleteOriginals->GetValue();
469 m_convertSettings->m_Gap = m_gap->GetIntValue();
470 }
471
472 m_settings.m_HatchOrientation = m_gridStyleRotation.GetAngleValue();
473 m_settings.m_HatchThickness = m_gridStyleThickness.GetIntValue();
474 m_settings.m_HatchGap = m_gridStyleGap.GetIntValue();
475 m_settings.m_HatchSmoothingLevel = m_spinCtrlSmoothLevel->GetValue();
476 m_settings.m_HatchSmoothingValue = m_spinCtrlSmoothValue->GetValue();
477
478 *m_ptr = m_settings;
479 return true;
480}
481
482
484{
485 if( !m_clearance.Validate( 0, pcbIUScale.mmToIU( ZONE_CLEARANCE_MAX_VALUE_MM ) ) )
486 return false;
487
488 if( !m_minWidth.Validate( pcbIUScale.mmToIU( ZONE_THICKNESS_MIN_VALUE_MM ), INT_MAX ) )
489 return false;
490
491 if( !m_cornerRadius.Validate( 0, INT_MAX ) )
492 return false;
493
494 if( !m_spokeWidth.Validate( 0, INT_MAX ) )
495 return false;
496
498
499 if( m_settings.m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN )
500 {
501 int minThickness = m_minWidth.GetIntValue();
502
503 if( !m_gridStyleThickness.Validate( minThickness, INT_MAX ) )
504 return false;
505
506 if( !m_gridStyleGap.Validate( minThickness, INT_MAX ) )
507 return false;
508 }
509
510 switch( m_PadInZoneOpt->GetSelection() )
511 {
512 case 3: m_settings.SetPadConnection( ZONE_CONNECTION::NONE ); break;
513 case 2: m_settings.SetPadConnection( ZONE_CONNECTION::THT_THERMAL ); break;
514 case 1: m_settings.SetPadConnection( ZONE_CONNECTION::THERMAL ); break;
515 case 0: m_settings.SetPadConnection( ZONE_CONNECTION::FULL ); break;
516 }
517
518 switch( m_OutlineDisplayCtrl->GetSelection() )
519 {
520 case 0: m_settings.m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::NO_HATCH; break;
521 case 1: m_settings.m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE; break;
522 case 2: m_settings.m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL; break;
523 }
524
527 {
528 return false;
529 }
530
531 m_settings.m_BorderHatchPitch = m_outlineHatchPitch.GetIntValue();
532
533 m_settings.m_ZoneClearance = m_clearance.GetIntValue();
534 m_settings.m_ZoneMinThickness = m_minWidth.GetIntValue();
535
536 m_settings.SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() );
537
538 if( m_settings.GetCornerSmoothingType() == ZONE_SETTINGS::SMOOTHING_NONE )
539 m_settings.SetCornerRadius( 0 );
540 else
541 m_settings.SetCornerRadius( m_cornerRadius.GetIntValue() );
542
543 m_settings.m_ZonePriority = m_PriorityLevelCtrl->GetValue();
544
545 m_settings.m_Locked = m_cbLocked->GetValue();
546
547 m_settings.m_ThermalReliefGap = m_antipadClearance.GetValue();
548 m_settings.m_ThermalReliefSpokeWidth = m_spokeWidth.GetValue();
549
550 if( m_settings.m_ThermalReliefSpokeWidth < m_settings.m_ZoneMinThickness )
551 {
552 DisplayError( this, _( "Thermal spoke width cannot be smaller than the minimum width." ) );
553 return false;
554 }
555
556 m_settings.SetIslandRemovalMode( (ISLAND_REMOVAL_MODE) m_cbRemoveIslands->GetSelection() );
557 m_settings.SetMinIslandArea( m_islandThreshold.GetValue() );
558
559 // Get the layer selection for this zone
560 int layers = 0;
561
562 for( int ii = 0; ii < m_layers->GetItemCount(); ++ii )
563 {
564 if( m_layers->GetToggleValue( (unsigned) ii, 0 ) )
565 layers++;
566 }
567
568 if( layers == 0 )
569 {
570 DisplayError( this, _( "No layer selected." ) );
571 return false;
572 }
573
575
576 m_settings.m_Name = m_tcZoneName->GetValue();
577
578 return true;
579}
580
581
583{
584 const int netSelection = m_ListNetNameSelection->GetSelection();
585
586 if( netSelection > 0 )
587 {
588 const wxString& selectedNetName = m_ListNetNameSelection->GetString( netSelection );
590 }
591 else
592 {
594 }
595}
596
597
598void DIALOG_COPPER_ZONE::OnStyleSelection( wxCommandEvent& event )
599{
600 bool enable = m_GridStyleCtrl->GetSelection() >= 1;
601 m_tcGridStyleThickness->Enable( enable );
602 m_tcGridStyleGap->Enable( enable );
603 m_tcGridStyleOrientation->Enable( enable );
604 m_spinCtrlSmoothLevel->Enable( enable );
605 m_spinCtrlSmoothValue->Enable( enable );
606}
607
608
609void DIALOG_COPPER_ZONE::OnLayerSelection( wxDataViewEvent& event )
610{
611 if( event.GetColumn() != 0 )
612 return;
613
614 int row = m_layers->ItemToRow( event.GetItem() );
615
616 bool checked = m_layers->GetToggleValue( row, 0 );
617
618 wxVariant layerID;
619 m_layers->GetValue( layerID, row, 2 );
620
621 m_settings.m_Layers.set( ToLAYER_ID( layerID.GetInteger() ), checked );
622}
623
624
629
630
635
636
638{
640
641 wxArrayString listOfNets = buildListOfNetsToDisplay();
642
643 const int selectedNet = ensureSelectedNetIsVisible( m_currentlySelectedNetcode, listOfNets );
644
645 displayNetsList( listOfNets, selectedNet );
646}
647
648
650{
652
653 // Hide nets filter criteria
655
656 // Nets sort criteria
658}
659
660
662{
663 wxString netNameShowFilter = m_ShowNetNameFilter->GetValue();
664
665 if( netNameShowFilter.Len() == 0 )
666 netNameShowFilter = wxT( "*" );
667
668 wxStringTokenizer showFilters( netNameShowFilter.Lower(), "," );
669
670 m_showNetsFilter.clear();
671
672 while( showFilters.HasMoreTokens() )
673 {
674 wxString filter = showFilters.GetNextToken().Trim( false ).Trim( true );
675
676 if( !filter.IsEmpty() )
677 {
678 m_showNetsFilter.emplace_back( std::make_unique<EDA_PATTERN_MATCH_WILDCARD>() );
679 m_showNetsFilter.back()->SetPattern( filter );
680 }
681 }
682}
683
684
686{
688
689 wxArrayString netNames;
690
691 for( NETINFO_ITEM* net : m_netInfoItemList )
692 {
693 if( m_hideAutoGeneratedNets && net->HasAutoGeneratedNetname() )
694 continue;
695
696 const wxString& netName = getUnescapedNetName( net );
697
698 for( const NET_FILTER& filter : m_showNetsFilter )
699 {
700 if( filter->Find( netName.Lower() ) )
701 {
702 netNames.Add( netName );
703 break;
704 }
705 }
706 }
707
708 netNames.Insert( _( "<no net>" ), INVALID_NET_CODE );
709
710 return netNames;
711}
712
713
721
722
723void DIALOG_COPPER_ZONE::sortNetsByPadCount( std::vector<NETINFO_ITEM*>& nets, int maxNetCode )
724{
725 const std::vector<PAD*> pads = m_Parent->GetBoard()->GetPads();
726
727 padCountListByNet.clear();
728
729 // +1 is required for <no-net> item
730 padCountListByNet.assign( maxNetCode + 1, 0 );
731
732 for( PAD* pad : pads )
733 {
734 const int netCode = pad->GetNetCode();
735
736 if( netCode > INVALID_NET_CODE )
737 padCountListByNet[netCode]++;
738 }
739
740 sort( nets.begin(), nets.end(), sortNetsByNodes );
741}
742
743
744void DIALOG_COPPER_ZONE::displayNetsList( const wxArrayString& netNamesList, int selectIndex )
745{
746 m_ListNetNameSelection->Clear();
747 m_ListNetNameSelection->InsertItems( netNamesList, 0 );
748 m_ListNetNameSelection->SetSelection( selectIndex );
749 m_ListNetNameSelection->EnsureVisible( selectIndex );
750}
751
752
753int DIALOG_COPPER_ZONE::ensureSelectedNetIsVisible( int selectedNetCode, wxArrayString& netsList )
754{
755 int selectedIndex = 0;
756
757 if( selectedNetCode > INVALID_NET_CODE )
758 {
759 NETINFO_ITEM* selectedNet = m_Parent->GetBoard()->FindNet( selectedNetCode );
760
761 if( selectedNet )
762 {
763 const wxString& netName = getUnescapedNetName( selectedNet );
764 selectedIndex = netsList.Index( netName );
765
766 if( wxNOT_FOUND == selectedIndex )
767 {
768 // the currently selected net must *always* be visible.
769 // <no net> is the zero'th index, so pick next lowest
770 netsList.Insert( netName, 1 );
771 selectedIndex = 1;
772 }
773 }
774 }
775
776 return selectedIndex;
777}
778
779
781{
782 return UnescapeString( net->GetNetname() );
783}
784
785
787{
789 && !m_copperZoneInfo->IsShown()
791 {
792 m_copperZoneInfo->ShowMessage( _( "<no net> will result in an isolated copper island." ),
793 wxICON_WARNING );
794 }
795 else if( m_copperZoneInfo->IsShown() )
796 {
797 m_copperZoneInfo->Dismiss();
798 }
799}
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:112
int GetCopperLayerCount() const
Definition board.cpp:879
DIALOG_COPPER_ZONE_BASE(wxWindow *parent, wxWindowID id=ID_DIALOG_COPPER_ZONE_BASE, const wxString &title=_("Copper Zone Properties"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
wxSpinCtrlDouble * m_spinCtrlSmoothValue
bool TransferDataFromWindow() override
void OnStyleSelection(wxCommandEvent &event) override
std::map< wxString, int > m_netNameToNetCode
NET_FILTER_LIST m_showNetsFilter
void OnNetSortingOptionSelected(wxCommandEvent &event) override
DIALOG_COPPER_ZONE(PCB_BASE_FRAME *aParent, ZONE_SETTINGS *aSettings, CONVERT_SETTINGS *aConvertSettings)
wxArrayString buildListOfNetsToDisplay()
int ensureSelectedNetIsVisible(int selectedNetCode, wxArrayString &netsList)
wxRadioButton * m_rbCenterline
bool TransferDataToWindow() override
wxString getUnescapedNetName(const NETINFO_ITEM *net)
void OnLayerSelection(wxDataViewEvent &event) override
CONVERT_SETTINGS * m_convertSettings
void OnShowNetNameFilterChange(wxCommandEvent &event) override
void OnRemoveIslandsSelection(wxCommandEvent &event) override
std::vector< NET_FILTER > NET_FILTER_LIST
static constexpr int INVALID_NET_CODE
std::unique_ptr< EDA_PATTERN_MATCH > NET_FILTER
void sortNetsByPadCount(std::vector< NETINFO_ITEM * > &nets, int maxNetCode)
PCB_BASE_FRAME * m_Parent
std::vector< NETINFO_ITEM * > m_netInfoItemList
void OnUpdateUI(wxUpdateUIEvent &) override
void displayNetsList(const wxArrayString &netNamesList, int selectIndex)
void OnNetSelectionUpdated(wxCommandEvent &event) override
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition dialog_shim.h:82
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition lset.cpp:582
Handle the data for a net.
Definition netinfo.h:54
const wxString & GetNetname() const
Definition netinfo.h:112
int GetNetCode() const
Definition netinfo.h:106
Container for NETINFO_ITEM elements, which are the nets.
Definition netinfo.h:212
unsigned GetNetCount() const
Definition netinfo.h:235
Definition pad.h:54
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
BOARD * GetBoard() const
ZONE_SETTINGS handles zones parameters.
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:177
This file is part of the common library.
static bool sortNetsByNodes(const NETINFO_ITEM *a, const NETINFO_ITEM *b)
int InvokeCopperZonesEditor(PCB_BASE_FRAME *aCaller, ZONE_SETTINGS *aSettings, CONVERT_SETTINGS *aConvertSettings)
Function InvokeCopperZonesEditor invokes up a modal dialog window for copper zone editing.
static bool sortNetsByNames(const NETINFO_ITEM *a, const NETINFO_ITEM *b)
static std::vector< int > padCountListByNet
#define _(s)
Abstract pattern-matching tool and implementations.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition lset.cpp:737
@ CENTERLINE
@ BOUNDING_HULL
wxString UnescapeString(const wxString &aSource)
T NormalizeAngle180(T Angle)
Normalize angle to be in the -180.0 .
Definition trigo.h:196
ISLAND_REMOVAL_MODE
Whether or not to remove isolated islands from a zone.
#define ZONE_CLEARANCE_MAX_VALUE_MM
Definition zones.h:38
@ THERMAL
Use thermal relief for pads.
Definition zones.h:50
@ THT_THERMAL
Thermal relief only for THT pads.
Definition zones.h:52
@ NONE
Pads are not covered.
Definition zones.h:49
@ FULL
pads are covered by copper
Definition zones.h:51
#define ZONE_BORDER_HATCH_MINDIST_MM
Definition zones.h:40
#define ZONE_THICKNESS_MIN_VALUE_MM
Definition zones.h:36
#define ZONE_BORDER_HATCH_MAXDIST_MM
Definition zones.h:41