KiCad PCB EDA Suite
dialog_design_rules.cpp
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 2004-2009 Jean-Pierre Charras, jp.charras at wanadoo.fr
9  * Copyright (C) 2009 Dick Hollenbeck, dick@softplc.com
10  * Copyright (C) 2009-2015 KiCad Developers, see change_log.txt for contributors.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, you may find one here:
24  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
25  * or you may search the http://www.gnu.org website for the version 2 license,
26  * or you may write to the Free Software Foundation, Inc.,
27  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28  */
29 
30 
31 /* functions relative to the design rules editor
32  */
33 #include <fctsys.h>
34 #include <class_drawpanel.h>
35 #include <base_units.h>
36 #include <confirm.h>
37 #include <pcbnew.h>
38 #include <wxPcbStruct.h>
40 
41 #include <pcbnew_id.h>
42 #include <class_track.h>
43 #include <macros.h>
44 #include <html_messagebox.h>
45 
46 #include <dialog_design_rules.h>
47 #include <wx/generic/gridctrl.h>
49 
50 // Column labels for net lists
51 #define NET_TITLE _( "Net" )
52 #define CLASS_TITLE _( "Class" )
53 
54 // Field Positions on rules grid
55 enum {
64 };
65 
66 const wxString DIALOG_DESIGN_RULES::wildCard = _( "* (Any)" );
67 
68 // dialog should remember its previously selected tab
70 
71 // methods for the helper class NETS_LIST_CTRL
72 
73 wxString NETS_LIST_CTRL::OnGetItemText( long item, long column ) const
74 {
75  if( column == 0 )
76  {
77  if( item < (long) m_Netnames.GetCount() )
78  return m_Netnames[item];
79  else
80  return wxEmptyString;
81  }
82  else if( item < (long) m_Classnames.GetCount() )
83  return m_Classnames[item];
84 
85  return wxEmptyString;
86 }
87 
88 
89 void NETS_LIST_CTRL::SetRowItems( unsigned aRow,
90  const wxString& aNetname,
91  const wxString& aNetclassName )
92 {
93  // insert blanks if aRow is larger than existing row count
94  unsigned cnt = m_Netnames.GetCount();
95 
96  if( cnt <= aRow )
97  m_Netnames.Add( wxEmptyString, aRow - cnt + 1 );
98 
99  cnt = m_Classnames.GetCount();
100 
101  if( cnt <= aRow )
102  m_Classnames.Add( wxEmptyString, aRow - cnt + 1 );
103 
104  if( (int)aRow <= GetItemCount() )
105  SetItemCount( aRow + 1 );
106 
107  m_Netnames[aRow] = aNetname;
108  m_Classnames[aRow] = aNetclassName;
109 }
110 
111 
119 // @todo: maybe move this to common.cpp if it works.
120 static void EnsureGridColumnWidths( wxWindow* aShower, wxGrid* aGrid )
121 {
122  wxWindowDC sDC( aShower );
123 
124  sDC.SetFont( aGrid->GetLabelFont() );
125 
126  int colCount = aGrid->GetNumberCols();
127 
128  for( int col = 0; col < colCount; ++col )
129  {
130  // add two spaces to the text and size it.
131  wxString colText = aGrid->GetColLabelValue( col ) + wxT( " " );
132 
133  wxSize needed = sDC.GetTextExtent( colText );
134 
135  // set the width of this column
136  aGrid->SetColSize( col, needed.x );
137  }
138 }
139 
140 static void EnsureGridRowTitleWidth( wxWindow* aShower, wxGrid* aGrid, int aMinWidth )
141 {
142  wxWindowDC sDC( aShower );
143  sDC.SetFont( aGrid->GetLabelFont() );
144 
145  int minsize = aMinWidth;
146  int rowCount = aGrid->GetNumberRows();
147 
148  for( int row = 0; row < rowCount; ++row )
149  {
150  // add two spaces to the text and size it.
151  wxString rowText = aGrid->GetRowLabelValue( row ) + wxT( " " );
152 
153  wxSize needed = sDC.GetTextExtent( rowText );
154 
155  minsize = std::max( minsize, needed.x );
156  }
157 
158  // set the width of the row laberls
159  aGrid->SetRowLabelSize( minsize );
160 }
161 
162 
164  DIALOG_DESIGN_RULES_BASE( parent )
165 {
166  m_Parent = parent;
167  SetAutoLayout( true );
168 
169  m_initialRowLabelsSize = m_grid->GetRowLabelSize();
170  EnsureGridColumnWidths( this, m_grid ); // override any column widths set by wxformbuilder.
171 
172  wxListItem column0;
173  wxListItem column1;
174 
175  column0.Clear();
176  column1.Clear();
177 
178  column0.SetMask( wxLIST_MASK_TEXT );
179  column1.SetMask( wxLIST_MASK_TEXT );
180 
181  column0.SetText( NET_TITLE );
182  column1.SetText( CLASS_TITLE );
183 
185 
186  m_leftListCtrl->InsertColumn( 0, column0 );
187  m_leftListCtrl->InsertColumn( 1, column1 );
188  m_leftListCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE );
189  m_leftListCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE );
190 
191  m_rightListCtrl->InsertColumn( 0, column0 );
192  m_rightListCtrl->InsertColumn( 1, column1 );
193  m_rightListCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE );
194  m_rightListCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE );
195 
196  // if user has been into the dialog before, go back to same tab
197  if( s_LastTabSelection != -1 )
198  {
199  m_DRnotebook->SetSelection( s_LastTabSelection );
200  }
201 
202  InitDialogRules();
204 
205  m_sdbSizer1OK->SetDefault();
206 
207  // Allow tabbing out of grid controls.
208  m_grid->SetTabBehaviour( wxGrid::Tab_Leave );
209  m_gridViaSizeList->SetTabBehaviour( wxGrid::Tab_Leave );
210  m_gridTrackWidthList->SetTabBehaviour( wxGrid::Tab_Leave );
211 
212  Layout();
213 
214  // Now all widgets have the size fixed, call FinishDialogSettings
216 }
217 
219 {
220  // Set floating-point validators for numerical inputs
221  wxFloatingPointValidator< double > fpValidator( NULL, wxNUM_VAL_ZERO_AS_BLANK | wxNUM_VAL_NO_TRAILING_ZEROES );
222 
223  int maxDimension = 1000 * IU_PER_MILS; // One-inch
224 
225  fpValidator.SetRange( 0, To_User_Unit( g_UserUnit, maxDimension ) );
226  fpValidator.SetPrecision( 10 );
227 
228  m_SetViasMinSizeCtrl->SetValidator( fpValidator );
229  m_SetViasMinDrillCtrl->SetValidator( fpValidator );
230  m_SetMicroViasMinSizeCtrl->SetValidator( fpValidator );
231  m_SetMicroViasMinDrillCtrl->SetValidator( fpValidator );
232  m_SetTrackMinWidthCtrl->SetValidator( fpValidator );
233 }
234 
235 
237 {
238  // @todo: Move the initialization code into TransferDataToWindow() to follow wxWidgets
239  // dialog data transfer convention.
240  SetFocus();
241  SetReturnCode( 0 );
242 
243  m_Pcb = m_Parent->GetBoard();
245 
246  // Initialize the Rules List
247  InitRulesList();
248 
249  // copy all NETs into m_AllNets by adding them as NETCUPs.
250 
251  // @todo go fix m_Pcb->SynchronizeNetsAndNetClasses() so that the netcode==0 is not
252  // present in the BOARD::m_NetClasses
253  NETCLASSES& netclasses = m_BrdSettings->m_NetClasses;
254  NETCLASSPTR netclass = netclasses.GetDefault();
255 
256  // Initialize list of nets for Default Net Class
257  for( NETCLASS::iterator name = netclass->begin(); name != netclass->end(); ++name )
258  {
259  m_AllNets.push_back( NETCUP( *name, netclass->GetName() ) );
260  }
261 
262  // Initialize list of nets for others (custom) Net Classes
263  for( NETCLASSES::const_iterator nc = netclasses.begin(); nc != netclasses.end(); ++nc )
264  {
265  netclass = nc->second;
266 
267  for( NETCLASS::const_iterator name = netclass->begin(); name != netclass->end(); ++name )
268  {
269  m_AllNets.push_back( NETCUP( *name, netclass->GetName() ) );
270  }
271  }
272 
274  InitGlobalRules();
275 }
276 
277 
279 {
280  // Set unit labels
281  const wxString units = GetAbbreviatedUnitsLabel( g_UserUnit );
282 
283  m_ViaMinUnits->SetLabel( units );
284  m_ViaMinDrillUnits->SetLabel( units );
285  m_MicroViaMinSizeUnits->SetLabel( units );
286  m_MicroViaMinDrillUnits->SetLabel( units );
287  m_TrackMinWidthUnits->SetLabel( units );
288 
291 
294 
298 
299  // Initialize Vias and Tracks sizes lists.
300  // note we display only extra values, never the current netclass value.
301  // (the first value in history list)
303  m_TracksWidthList.erase( m_TracksWidthList.begin() ); // remove the netclass value
305  m_ViasDimensionsList.erase( m_ViasDimensionsList.begin() ); // remove the netclass value
307 }
308 
309 
311 {
312  wxString msg;
313 
314  // Compute the column widths here, after setting texts
315  msg = wxT("000000.000000"); // This is a very long text to display values.
316  // Actual values are shorter.
317  m_gridViaSizeList->SetCellValue( 0, 0, msg );
318  m_gridViaSizeList->SetCellValue( 0, 1, msg );
319  m_gridTrackWidthList->SetCellValue( 0, 0, msg );
320  m_gridViaSizeList->SetColMinimalWidth( 0, 150 );
321  m_gridViaSizeList->SetColMinimalWidth( 1, 150 );
322  m_gridViaSizeList->AutoSizeColumns( true );
323  m_gridTrackWidthList->SetColMinimalWidth( 0, 150 );
324  m_gridTrackWidthList->AutoSizeColumns( true );
325  m_gridViaSizeList->SetColMinimalWidth( 1, 150 );
326 
327  // Fill cells with actual values:
328  m_gridViaSizeList->SetCellValue( 0, 0, wxEmptyString );
329  m_gridViaSizeList->SetCellValue( 0, 1, wxEmptyString );
330  m_gridTrackWidthList->SetCellValue( 0, 0, wxEmptyString );
331 
332  // Give a correct size to row labels column
333  m_gridViaSizeList->SetRowLabelSize( wxGRID_AUTOSIZE );
334  m_gridTrackWidthList->SetRowLabelSize( wxGRID_AUTOSIZE );
335 
336  for( unsigned ii = 0; ii < m_TracksWidthList.size(); ii++ )
337  {
338  msg = StringFromValue( g_UserUnit, m_TracksWidthList[ii], false );
339  m_gridTrackWidthList->SetCellValue( ii, 0, msg );
340  }
341 
342  for( unsigned ii = 0; ii < m_ViasDimensionsList.size(); ii++ )
343  {
344  msg = StringFromValue( g_UserUnit, m_ViasDimensionsList[ii].m_Diameter, false );
345  m_gridViaSizeList->SetCellValue( ii, 0, msg );
346 
347  if( m_ViasDimensionsList[ii].m_Drill > 0 )
348  {
349  msg = StringFromValue( g_UserUnit, m_ViasDimensionsList[ii].m_Drill, false );
350  m_gridViaSizeList->SetCellValue( ii, 1, msg );
351  }
352  }
353 }
354 
355 
356 // Sort comparison function (helper for makePointers() )
357 static bool sortByClassThenName( NETCUP* a, NETCUP* b )
358 {
359  // return a < b
360  if( a->clazz < b->clazz )
361  return true;
362 
363  // inside the same class, sort by net name:
364  if( a->clazz == b->clazz )
365  {
366  if( a->net < b->net )
367  return true;
368  }
369 
370  return false;
371 }
372 
373 
374 void DIALOG_DESIGN_RULES::makePointers( PNETCUPS* aList, const wxString& aNetClassName )
375 {
376  aList->clear();
377 
378  if( wildCard == aNetClassName )
379  {
380  for( NETCUPS::iterator n = m_AllNets.begin(); n != m_AllNets.end(); ++n )
381  {
382  aList->push_back( &*n );
383  }
384 
385  sort( aList->begin(), aList->end(), sortByClassThenName );
386 
387  // could use a different sort order for wildCard case.
388  }
389  else
390  {
391  for( NETCUPS::iterator n = m_AllNets.begin(); n != m_AllNets.end(); ++n )
392  {
393  if( n->clazz == aNetClassName )
394  aList->push_back( &*n );
395  }
396 
397  sort( aList->begin(), aList->end(), sortByClassThenName );
398  }
399 }
400 
401 
403  const wxString& aNetClass )
404 {
405  aListCtrl->ClearList();
406 
407  PNETCUPS ptrList;
408 
409  // get a subset of m_AllNets in pointer form, sorted as desired.
410  makePointers( &ptrList, aNetClass );
411 
412 #if 0 && defined(DEBUG)
413  int r = 0;
414  for( PNETCUPS::iterator i = ptrList.begin(); i!=ptrList.end(); ++i, ++r )
415  {
416  printf( "[%d]: %s %s\n", r, TO_UTF8( (*i)->net ), TO_UTF8( (*i)->clazz ) );
417  }
418 
419 #endif
420 
421  // Add netclass info to m_Netnames and m_Classnames wxArrayString buffers
422  // aListCtrl uses wxLC_VIRTUAL option, so this is fast
423  wxClientDC sDC( aListCtrl );
424  int row = 0;
425  // recompute the column widths here, after setting texts
426  int net_colsize = sDC.GetTextExtent( NET_TITLE ).x;
427  int class_colsize = sDC.GetTextExtent( CLASS_TITLE ).x;
428 
429  for( PNETCUPS::iterator i = ptrList.begin(); i!=ptrList.end(); ++i, ++row )
430  {
431  wxSize net_needed = sDC.GetTextExtent( (*i)->net );
432  wxSize class_needed = sDC.GetTextExtent( (*i)->clazz );
433  net_colsize = std::max( net_colsize, net_needed.x );
434  class_colsize = std::max( class_colsize, class_needed.x );
435  aListCtrl->SetRowItems( row, (*i)->net, (*i)->clazz );
436  }
437 
438  int margin = sDC.GetTextExtent( wxT( "XX" ) ).x;
439  aListCtrl->SetColumnWidth( 0, net_colsize + margin );
440  aListCtrl->SetColumnWidth( 1, class_colsize + margin );
441  aListCtrl->Refresh();
442 }
443 
444 
445 /* Populates combo boxes with the list of existing net classes
446  */
448 {
449  m_rightClassChoice->Clear();
450  m_leftClassChoice->Clear();
451 
452  m_rightClassChoice->Append( wildCard );
453  m_leftClassChoice->Append( wildCard );
454 
455  for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
456  {
457  m_rightClassChoice->Append( m_grid->GetRowLabelValue( ii ) );
458  m_leftClassChoice->Append( m_grid->GetRowLabelValue( ii ) );
459  }
460 
461  m_rightClassChoice->Select( 0 );
462  m_leftClassChoice->Select( 0 );
463 
464  m_buttonRightToLeft->Enable( false );
465  m_buttonLeftToRight->Enable( false );
466 
467  FillListBoxWithNetNames( m_leftListCtrl, m_leftClassChoice->GetStringSelection() );
469 }
470 
471 
472 /* Initialize the rules list from board
473  */
474 
475 static void class2gridRow( wxGrid* grid, int row, NETCLASSPTR nc )
476 {
477  wxString msg;
478 
479  // label is netclass name
480  grid->SetRowLabelValue( row, nc->GetName() );
481 
482  msg = StringFromValue( g_UserUnit, nc->GetClearance() );
483  grid->SetCellValue( row, GRID_CLEARANCE, msg );
484 
485  msg = StringFromValue( g_UserUnit, nc->GetTrackWidth() );
486  grid->SetCellValue( row, GRID_TRACKSIZE, msg );
487 
488  msg = StringFromValue( g_UserUnit, nc->GetViaDiameter() );
489  grid->SetCellValue( row, GRID_VIASIZE, msg );
490 
491  msg = StringFromValue( g_UserUnit, nc->GetViaDrill() );
492  grid->SetCellValue( row, GRID_VIADRILL, msg );
493 
494  msg = StringFromValue( g_UserUnit, nc->GetuViaDiameter() );
495  grid->SetCellValue( row, GRID_uVIASIZE, msg );
496 
497  msg = StringFromValue( g_UserUnit, nc->GetuViaDrill() );
498  grid->SetCellValue( row, GRID_uVIADRILL, msg );
499 
500  msg = StringFromValue( g_UserUnit, nc->GetDiffPairGap() );
501  grid->SetCellValue( row, GRID_DIFF_PAIR_GAP, msg );
502 
503  msg = StringFromValue( g_UserUnit, nc->GetDiffPairWidth() );
504  grid->SetCellValue( row, GRID_DIFF_PAIR_WIDTH, msg );
505 
506 }
507 
508 
510 {
511  NETCLASSES& netclasses = m_BrdSettings->m_NetClasses;
512 
513  // the +1 is for the Default NETCLASS.
514  if( netclasses.GetCount() + 1 > (unsigned) m_grid->GetNumberRows() )
515  {
516  m_grid->AppendRows( netclasses.GetCount() + 1 - m_grid->GetNumberRows() );
517  }
518 
519  // enter the Default NETCLASS.
520  class2gridRow( m_grid, 0, netclasses.GetDefault() );
521 
522  // enter others netclasses
523  int row = 1;
524 
525  for( NETCLASSES::iterator i = netclasses.begin(); i!=netclasses.end(); ++i, ++row )
526  {
527  NETCLASSPTR netclass = i->second;
528 
529  class2gridRow( m_grid, row, netclass );
530  }
531 }
532 
533 
534 static void gridRow2class( wxGrid* grid, int row, NETCLASSPTR nc )
535 {
536 #define MYCELL( col ) \
537  ValueFromString( g_UserUnit, grid->GetCellValue( row, col ) )
538 
539  nc->SetClearance( MYCELL( GRID_CLEARANCE ) );
540  nc->SetTrackWidth( MYCELL( GRID_TRACKSIZE ) );
541  nc->SetViaDiameter( MYCELL( GRID_VIASIZE ) );
542  nc->SetViaDrill( MYCELL( GRID_VIADRILL ) );
543  nc->SetuViaDiameter( MYCELL( GRID_uVIASIZE ) );
544  nc->SetuViaDrill( MYCELL( GRID_uVIADRILL ) );
545  nc->SetDiffPairGap( MYCELL( GRID_DIFF_PAIR_GAP ) );
546  nc->SetDiffPairWidth( MYCELL( GRID_DIFF_PAIR_WIDTH ) );
547 
548 }
549 
550 
552 {
553  NETCLASSES& netclasses = m_BrdSettings->m_NetClasses;
554 
555  // Remove all netclasses from board. We'll copy new list after
556  netclasses.Clear();
557 
558  // Copy the default NetClass:
559  gridRow2class( m_grid, 0, netclasses.GetDefault() );
560 
561  // Copy other NetClasses :
562  for( int row = 1; row < m_grid->GetNumberRows(); ++row )
563  {
564  NETCLASSPTR nc = std::make_shared<NETCLASS>( m_grid->GetRowLabelValue( row ) );
565 
566  if( !m_BrdSettings->m_NetClasses.Add( nc ) )
567  {
568  // this netclass cannot be added because an other netclass with the same name exists
569  // Should not occur because OnAddNetclassClick() tests for existing NetClass names
570  wxString msg;
571  msg.Printf( wxT( "CopyRulesListToBoard(): The NetClass \"%s\" already exists. Skip" ),
572  GetChars( m_grid->GetRowLabelValue( row ) ) );
573  wxMessageBox( msg );
574 
575  continue;
576  }
577 
578  gridRow2class( m_grid, row, nc );
579  }
580 
581  // Now read all nets and push them in the corresponding netclass net buffer
582  for( NETCUPS::const_iterator netcup = m_AllNets.begin(); netcup != m_AllNets.end(); ++netcup )
583  {
584  NETCLASSPTR nc = netclasses.Find( netcup->clazz );
585  wxASSERT( nc );
586  nc->Add( netcup->net );
587  }
588 
590 }
591 
592 
594 {
596 
597  // Update vias minimum values for DRC
600 
602 
603  // Update microvias minimum values for DRC
606 
607  // Update tracks minimum values for DRC
609 }
610 
611 
613 {
614  wxString msg;
615 
616  // Reinitialize m_TrackWidthList
617  m_TracksWidthList.clear();
618 
619  for( int row = 0; row < m_gridTrackWidthList->GetNumberRows(); ++row )
620  {
621  msg = m_gridTrackWidthList->GetCellValue( row, 0 );
622 
623  if( msg.IsEmpty() )
624  continue;
625 
626  int value = ValueFromString( g_UserUnit, msg );
627  m_TracksWidthList.push_back( value );
628  }
629 
630  // Sort new list by by increasing value
631  sort( m_TracksWidthList.begin(), m_TracksWidthList.end() );
632 
633  // Reinitialize m_TrackWidthList
634  m_ViasDimensionsList.clear();
635 
636  for( int row = 0; row < m_gridViaSizeList->GetNumberRows(); ++row )
637  {
638  msg = m_gridViaSizeList->GetCellValue( row, 0 );
639 
640  if( msg.IsEmpty() )
641  continue;
642 
643  int value = ValueFromString( g_UserUnit, msg );
644  VIA_DIMENSION via_dim;
645  via_dim.m_Diameter = value;
646  msg = m_gridViaSizeList->GetCellValue( row, 1 );
647 
648  if( !msg.IsEmpty() )
649  {
650  value = ValueFromString( g_UserUnit, msg );
651  via_dim.m_Drill = value;
652  }
653 
654  m_ViasDimensionsList.push_back( via_dim );
655  }
656 
657  // Sort new list by by increasing value
658  sort( m_ViasDimensionsList.begin(), m_ViasDimensionsList.end() );
659 
660  std::vector<int>* tlist = &m_BrdSettings->m_TrackWidthList;
661 
662  // Remove old "custom" sizes
663  tlist->erase( tlist->begin() + 1, tlist->end() );
664 
665  // Add new "custom" sizes
666  tlist->insert( tlist->end(), m_TracksWidthList.begin(), m_TracksWidthList.end() );
667 
668  // Reinitialize m_ViaSizeList
669  std::vector<VIA_DIMENSION>* vialist = &m_BrdSettings->m_ViasDimensionsList;
670  vialist->erase( vialist->begin() + 1, vialist->end() );
671  vialist->insert( vialist->end(), m_ViasDimensionsList.begin(), m_ViasDimensionsList.end() );
672 }
673 
674 
675 void DIALOG_DESIGN_RULES::OnNotebookPageChanged( wxNotebookEvent& event )
676 {
677  s_LastTabSelection = event.GetSelection();
678 
679  // Skip() allows OSX to properly refresh controls.
680  event.Skip();
681 }
682 
683 
685 {
686  if( !wxDialog::TransferDataFromWindow() )
687  return false;
688 
689  wxString errorMsg;
690 
691  if( !TestDataValidity( &errorMsg ) )
692  {
693  HTML_MESSAGE_BOX dlg( this, _( "Design Rule Setting Error" ) );
694  dlg.MessageSet( errorMsg );
695  dlg.ShowModal();
696  return false;
697  }
698 
703  return true;
704 }
705 
706 
707 void DIALOG_DESIGN_RULES::OnAddNetclassClick( wxCommandEvent& event )
708 {
709  wxString class_name;
710 
711  // @todo set validator to ensure net class name is valid rather than all of the checks
712  // after the OK button has been selected.
713  wxTextEntryDialog dlg( this, _( "New Net Class Name:" ), wxEmptyString, class_name );
714 
715  if( dlg.ShowModal() != wxID_OK )
716  return; // canceled by user
717 
718  class_name = dlg.GetValue();
719  class_name.Trim( true );
720  class_name.Trim( false );
721 
722  if( class_name.IsEmpty() )
723  return; // empty name not allowed
724 
725  // The name must dot exists:
726  for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
727  {
728  wxString value;
729  value = m_grid->GetRowLabelValue( ii );
730 
731  if( class_name.CmpNoCase( value ) == 0 ) // Already exists!
732  {
733  DisplayError( this, _( "Duplicate net class names are not allowed." ) );
734  return;
735  }
736  }
737 
738  m_grid->AppendRows();
739  m_grid->SetRowLabelValue( m_grid->GetNumberRows() - 1, class_name );
740 
741  // Copy values of the default class:
742  int irow = m_grid->GetNumberRows() - 1;
743 
744  for( int icol = 0; icol < m_grid->GetNumberCols(); icol++ )
745  {
746  wxString value;
747  value = m_grid->GetCellValue( 0, icol );
748  m_grid->SetCellValue( irow, icol, value );
749  }
750 
752 
754 }
755 
756 
757 // Sort function for wxArrayInt. Items (ints) are sorted by decreasing value
758 // used in DIALOG_DESIGN_RULES::OnRemoveNetclassClick
759 int sort_int( int* first, int* second )
760 {
761  return *second - *first;
762 }
763 
764 
765 void DIALOG_DESIGN_RULES::OnRemoveNetclassClick( wxCommandEvent& event )
766 {
767  wxArrayInt select = m_grid->GetSelectedRows();
768 
769  // Sort selection by decreasing index order:
770  select.Sort( sort_int );
771  bool reinit = false;
772 
773  // rows labels are not removed when deleting rows: they are not deleted.
774  // So we must store them, remove corresponding labels and reinit them
775  wxArrayString labels;
776 
777  for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
778  labels.Add( m_grid->GetRowLabelValue( ii ) );
779 
780  // Delete rows from last to first (this is the order wxArrayInt select after sorting) )
781  // This order is Ok when removing rows
782  for( unsigned ii = 0; ii < select.GetCount(); ii++ )
783  {
784  int grid_row = select[ii];
785 
786  if( grid_row != 0 ) // Do not remove the default class
787  {
788  wxString classname = m_grid->GetRowLabelValue( grid_row );
789  m_grid->DeleteRows( grid_row );
790  labels.RemoveAt( grid_row ); // Remove corresponding row label
791  reinit = true;
792 
793  // reset the net class to default for members of the removed class
794  swapNetClass( classname, NETCLASS::Default );
795  }
796  else
797  wxMessageBox( _( "The default net class cannot be removed" ) );
798  }
799 
800  if( reinit )
801  {
802  // Reinit labels :
803  for( unsigned ii = 1; ii < labels.GetCount(); ii++ )
804  m_grid->SetRowLabelValue( ii, labels[ii] );
805 
808  }
809 }
810 
815 void DIALOG_DESIGN_RULES::OnAllowMicroVias( wxCommandEvent& event )
816 {
817  bool enabled = m_OptAllowMicroVias->GetValue();
818  m_SetMicroViasMinSizeCtrl->Enable( enabled );
819  m_SetMicroViasMinDrillCtrl->Enable( enabled );
820 }
821 
823 {
824  // Cannot move up rules if we have 1 or 2 rules only
825  if( m_grid->GetNumberRows() < 3 )
826  return;
827 
828  wxArrayInt select = m_grid->GetSelectedRows();
829  bool reinit = false;
830 
831  for( unsigned irow = 0; irow < select.GetCount(); irow++ )
832  {
833  int ii = select[irow];
834  if( ii < 2 ) // The default netclass *must* be the first netclass
835  continue; // so we cannot move up line 0 and 1
836 
837  // Swap the rule and the previous rule
838  wxString curr_value, previous_value;
839 
840  for( int icol = 0; icol < m_grid->GetNumberCols(); icol++ )
841  {
842  reinit = true;
843  curr_value = m_grid->GetCellValue( ii, icol );
844  previous_value = m_grid->GetCellValue( ii - 1, icol );
845  m_grid->SetCellValue( ii, icol, previous_value );
846  m_grid->SetCellValue( ii - 1, icol, curr_value );
847  }
848 
849  curr_value = m_grid->GetRowLabelValue( ii );
850  previous_value = m_grid->GetRowLabelValue( ii - 1 );
851  m_grid->SetRowLabelValue( ii, previous_value );
852  m_grid->SetRowLabelValue( ii - 1, curr_value );
853  }
854 
855  if( reinit )
857 }
858 
859 
860 void DIALOG_DESIGN_RULES::OnLeftCBSelection( wxCommandEvent& event )
861 {
862  FillListBoxWithNetNames( m_leftListCtrl, m_leftClassChoice->GetStringSelection() );
863 
864  if( m_leftClassChoice->GetStringSelection() == m_rightClassChoice->GetStringSelection() )
865  {
866  m_buttonRightToLeft->Enable( false );
867  m_buttonLeftToRight->Enable( false );
868  }
869  else
870  {
871  m_buttonRightToLeft->Enable( true );
872  m_buttonLeftToRight->Enable( true );
873  }
874 }
875 
876 
877 void DIALOG_DESIGN_RULES::OnRightCBSelection( wxCommandEvent& event )
878 {
880 
881  if( m_leftClassChoice->GetStringSelection() == m_rightClassChoice->GetStringSelection() )
882  {
883  m_buttonRightToLeft->Enable( false );
884  m_buttonLeftToRight->Enable( false );
885  }
886  else
887  {
888  m_buttonRightToLeft->Enable( true );
889  m_buttonLeftToRight->Enable( true );
890  }
891 }
892 
893 
894 void DIALOG_DESIGN_RULES::moveSelectedItems( NETS_LIST_CTRL* src, const wxString& newClassName )
895 {
896  wxListItem item;
897  wxString netName;
898 
899  item.m_mask |= wxLIST_MASK_TEXT; // Validate the member m_text of the wxListItem item
900 
901  for( int row = 0; row < src->GetItemCount(); ++row )
902  {
903  if( !src->GetItemState( row, wxLIST_STATE_SELECTED ) )
904  continue;
905 
906  item.SetColumn( 0 );
907  item.SetId( row );
908 
909  src->GetItem( item );
910  netName = item.GetText();
911 
912  setNetClass( netName, newClassName == wildCard ? NETCLASS::Default : newClassName );
913  }
914 }
915 
916 
917 void DIALOG_DESIGN_RULES::OnRightToLeftCopyButton( wxCommandEvent& event )
918 {
919  wxString newClassName = m_leftClassChoice->GetStringSelection();
920 
921  moveSelectedItems( m_rightListCtrl, newClassName );
922 
923  FillListBoxWithNetNames( m_leftListCtrl, m_leftClassChoice->GetStringSelection() );
925 }
926 
927 
928 void DIALOG_DESIGN_RULES::OnLeftToRightCopyButton( wxCommandEvent& event )
929 {
930  wxString newClassName = m_rightClassChoice->GetStringSelection();
931 
932  moveSelectedItems( m_leftListCtrl, newClassName );
933 
934  FillListBoxWithNetNames( m_leftListCtrl, m_leftClassChoice->GetStringSelection() );
936 }
937 
938 
939 void DIALOG_DESIGN_RULES::OnLeftSelectAllButton( wxCommandEvent& event )
940 {
941  for( int ii = 0; ii < m_leftListCtrl->GetItemCount(); ii++ )
942  m_leftListCtrl->SetItemState( ii, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
943 }
944 
945 
946 void DIALOG_DESIGN_RULES::OnRightSelectAllButton( wxCommandEvent& event )
947 {
948  for( int ii = 0; ii < m_rightListCtrl->GetItemCount(); ii++ )
949  m_rightListCtrl->SetItemState( ii, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
950 }
951 
952 
953 void DIALOG_DESIGN_RULES::setNetClass( const wxString& aNetName, const wxString& aClassName )
954 {
955  for( NETCUPS::iterator i = m_AllNets.begin(); i != m_AllNets.end(); ++i )
956  {
957  if( i->net == aNetName )
958  {
959  i->clazz = aClassName;
960  break;
961  }
962  }
963 }
964 
965 
966 bool DIALOG_DESIGN_RULES::TestDataValidity( wxString* aErrorMsg )
967 {
968  bool result = true;
969 
970  wxString msg;
971  wxString errorMsg;
972 
973  wxString netclassLabel; // Name of a given netclass
974  wxString netclassError; // Error message particular to a given netclass
975 
976  wxString units = ReturnUnitSymbol( g_UserUnit, "%s" );
977 
978  int minViaDia = ValueFromTextCtrl( *m_SetViasMinSizeCtrl );
979  int minViaDrill = ValueFromTextCtrl( *m_SetViasMinDrillCtrl );
980  int minUViaDia = ValueFromTextCtrl( *m_SetMicroViasMinSizeCtrl );
981  int minUViaDrill = ValueFromTextCtrl( *m_SetMicroViasMinDrillCtrl );
982  int minTrackWidth = ValueFromTextCtrl( *m_SetTrackMinWidthCtrl );
983  int maxval = 1000 * IU_PER_MILS; // a max value for tracks and vias sizes (1 inch)
984 
985  // @todo Change this code to set the focus to the control where the first error occurs
986  // so the user doesn't have to figure out where the issue is.
987 
988  // Test net class parameters.
989  for( int row = 0; row < m_grid->GetNumberRows(); row++ )
990  {
991  netclassLabel = GetChars( m_grid->GetRowLabelValue( row ) );
992  netclassError.Clear(); // Clear the error for this netclass
993 
994  int tracksize = ValueFromString( g_UserUnit,
995  m_grid->GetCellValue( row, GRID_TRACKSIZE ) );
996  if( tracksize < minTrackWidth )
997  {
998  result = false;
999  msg.Printf( _( " - <b>Track Size</b> (%f %s) &lt; <b>Min Track Size</b> (%f %s)<br>" ),
1000  To_User_Unit( g_UserUnit, tracksize ), units,
1001  To_User_Unit( g_UserUnit, minTrackWidth ), units );
1002 
1003  netclassError += msg;
1004  }
1005 
1006  int dpsize = ValueFromString( g_UserUnit,
1007  m_grid->GetCellValue( row, GRID_DIFF_PAIR_WIDTH ) );
1008 
1009  if( dpsize < minTrackWidth )
1010  {
1011  result = false;
1012  msg.Printf( _( " - <b>Differential Pair Size</b> (%f %s) &lt; <b>Min Track Size</b> (%f %s)<br>" ),
1013  To_User_Unit( g_UserUnit, dpsize ), units,
1014  To_User_Unit( g_UserUnit, minTrackWidth ), units );
1015  netclassError += msg;
1016  }
1017 
1018 
1019  // Test vias
1020  int viadia = ValueFromString( g_UserUnit,
1021  m_grid->GetCellValue( row, GRID_VIASIZE ) );
1022 
1023  if( viadia < minViaDia )
1024  {
1025  result = false;
1026  msg.Printf( _( " - <b>Via Diameter</b> (%f %s) &lt; <b>Minimum Via Diameter</b> (%f %s)<br>" ),
1027  To_User_Unit( g_UserUnit, viadia ), units,
1028  To_User_Unit( g_UserUnit, minViaDia ), units );
1029  netclassError += msg;
1030  }
1031 
1032  int viadrill = ValueFromString( g_UserUnit,
1033  m_grid->GetCellValue( row, GRID_VIADRILL ) );
1034 
1035  if( viadrill >= viadia )
1036  {
1037  result = false;
1038  msg.Printf( _( " - <b>Via Drill</b> (%f %s) &ge; <b>Via Dia</b> (%f %s)<br>" ),
1039  To_User_Unit( g_UserUnit, viadrill ), units,
1040  To_User_Unit( g_UserUnit, viadia ), units );
1041  netclassError += msg;
1042  }
1043 
1044  if( viadrill < minViaDrill )
1045  {
1046  result = false;
1047  msg.Printf( _( " - <b>Via Drill</b> (%f %s) &lt; <b>Min Via Drill</b> (%f %s)<br>" ),
1048  To_User_Unit( g_UserUnit, viadrill ), units,
1049  To_User_Unit( g_UserUnit, minViaDrill ), units );
1050  netclassError += msg;
1051  }
1052 
1053  // Test Micro vias
1054  int muviadia = ValueFromString( g_UserUnit,
1055  m_grid->GetCellValue( row, GRID_uVIASIZE ) );
1056 
1057  if( muviadia < minUViaDia )
1058  {
1059  result = false;
1060  msg.Printf( _( " - <b>MicroVia Diameter</b> (%f %s) &lt; <b>MicroVia Min Diameter</b> (%f %s)<br>" ),
1061  To_User_Unit( g_UserUnit, muviadia ), units,
1062  To_User_Unit( g_UserUnit, minUViaDia ), units );
1063  netclassError += msg;
1064  }
1065 
1066  int muviadrill = ValueFromString( g_UserUnit,
1067  m_grid->GetCellValue( row, GRID_uVIADRILL ) );
1068 
1069  if( muviadrill >= muviadia )
1070  {
1071  result = false;
1072  msg.Printf( _( " - <b>MicroVia Drill</b> (%f %s) &ge; <b>MicroVia Dia</b> (%f %s)<br>" ),
1073  To_User_Unit( g_UserUnit, muviadrill ), units,
1074  To_User_Unit( g_UserUnit, muviadia ), units );
1075  netclassError += msg;
1076  }
1077 
1078  if( muviadrill < minUViaDrill )
1079  {
1080  result = false;
1081  msg.Printf( _( " - <b>MicroVia Drill</b> (%f %s) &lt; <b>MicroVia Min Drill</b> (%f %s)<br>" ),
1082  To_User_Unit( g_UserUnit, muviadrill ), units,
1083  To_User_Unit( g_UserUnit, minUViaDrill ), units );
1084  netclassError += msg;
1085  }
1086 
1087  // If this netclass contains errors, add it to the error message
1088  if ( !netclassError.IsEmpty() )
1089  {
1090  msg.Printf( _( "Netclass: <b>%s</b><br>" ), netclassLabel );
1091  errorMsg += msg;
1092  errorMsg += netclassError;
1093  errorMsg += "<br>";
1094  }
1095  }
1096 
1097  // Test custom tracks
1098  for( int row = 0; row < m_gridTrackWidthList->GetNumberRows(); ++row )
1099  {
1100  wxString tvalue = m_gridTrackWidthList->GetCellValue( row, 0 );
1101 
1102  if( tvalue.IsEmpty() )
1103  continue;
1104 
1105  int tracksize = ValueFromString( g_UserUnit, tvalue );
1106 
1107  if( tracksize < minTrackWidth )
1108  {
1109  result = false;
1110  msg.Printf( _( "<b>Extra Track %d Size</b> %s &lt; <b>Min Track Size</b><br>" ),
1111  row + 1, GetChars( tvalue ) );
1112 
1113  errorMsg += msg;
1114  }
1115 
1116  if( tracksize > maxval )
1117  {
1118  result = false;
1119  msg.Printf( _( "<b>Extra Track %d Size</b> %s &gt; <b>1 inch!</b><br>" ),
1120  row + 1, GetChars( tvalue ) );
1121 
1122  errorMsg += msg;
1123  }
1124  }
1125 
1126  // Test custom vias
1127  for( int row = 0; row < m_gridViaSizeList->GetNumberRows(); ++row )
1128  {
1129  wxString tvalue = m_gridViaSizeList->GetCellValue( row, 0 );
1130 
1131  if( tvalue.IsEmpty() )
1132  continue;
1133 
1134  int viadia = ValueFromString( g_UserUnit, tvalue );
1135 
1136  if( viadia < minViaDia )
1137  {
1138  result = false;
1139  msg.Printf( _( "<b>Extra Via %d Size</b> %s &lt; <b>Min Via Size</b><br>" ),
1140  row + 1, GetChars( tvalue ) );
1141  errorMsg += msg;
1142  }
1143 
1144  wxString drlvalue = m_gridViaSizeList->GetCellValue( row, 1 );
1145 
1146  if( drlvalue.IsEmpty() )
1147  {
1148  result = false;
1149  msg.Printf( _( "<b>No via drill size define in row %d</b><br>" ), row + 1 );
1150  errorMsg += msg;
1151  continue;
1152  }
1153 
1154  int viadrill = ValueFromString( g_UserUnit, drlvalue );
1155 
1156  if( viadrill < minViaDrill )
1157  {
1158  result = false;
1159  msg.Printf( _( "<b>Extra Via %d Drill</b> %s &lt; <b>Min Via Drill %s</b><br>" ),
1160  row + 1, GetChars( drlvalue ),
1161  GetChars( m_SetViasMinDrillCtrl->GetValue() ) );
1162  errorMsg += msg;
1163  }
1164 
1165  if( viadia <= viadrill )
1166  {
1167  result = false;
1168  msg.Printf( _( "<b>Extra Via %d Size</b> %s &le; <b> Drill Size</b> %s<br>" ),
1169  row + 1, GetChars( tvalue ), GetChars( drlvalue ) );
1170  errorMsg += msg;
1171  }
1172 
1173  // Test for a reasonable via size:
1174  if( viadia > maxval ) // 1 inch!
1175  {
1176  result = false;
1177  msg.Printf( _( "<b>Extra Via %d Size</b>%s &gt; <b>1 inch!</b><br>" ),
1178  row + 1, GetChars( tvalue ) );
1179  errorMsg += msg;
1180  }
1181  }
1182 
1183  if( !result && aErrorMsg )
1184  *aErrorMsg = errorMsg;
1185 
1186  return result;
1187 }
void OnNotebookPageChanged(wxNotebookEvent &event) override
std::vector< int > m_TracksWidthList
Struct VIA_DIMENSION is a small helper container to handle a stock of specific vias each with unique ...
static void EnsureGridRowTitleWidth(wxWindow *aShower, wxGrid *aGrid, int aMinWidth)
virtual bool TransferDataFromWindow() override
NETCLASSPTR Find(const wxString &aName) const
Function Find searches this container for a NETCLASS given by aName.
void OnLeftToRightCopyButton(wxCommandEvent &event) override
Implementation of conversion functions that require both schematic and board internal units...
This file is part of the common library.
wxString clazz
a class name
std::vector< int > m_TrackWidthList
Track width list.
void InitRulesList()
Function InitRulesList Fill the grid showing current rules with values.
wxString ReturnUnitSymbol(EDA_UNITS_T aUnit, const wxString &formatString)
Returns the units symbol.
Definition: base_units.cpp:420
static bool sortByClassThenName(NETCUP *a, NETCUP *b)
void swapNetClass(const wxString &oldClass, const wxString &newClass)
Function swapNetClass replaces one net class name with another in the master list, m_AllNets.
wxString StringFromValue(EDA_UNITS_T aUnit, int aValue, bool aAddUnitSymbol)
Function StringFromValue returns the string from aValue according to units (inch, mm ...
Definition: base_units.cpp:203
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
void moveSelectedItems(NETS_LIST_CTRL *src, const wxString &newClassName)
std::vector< NETCUP * > PNETCUPS
BOARD * GetBoard() const
void OnMoveUpSelectedNetClass(wxCommandEvent &event) override
#define NET_TITLE
iterator end()
std::vector< VIA_DIMENSION > m_ViasDimensionsList
void OnRemoveNetclassClick(wxCommandEvent &event) override
void OnRightSelectAllButton(wxCommandEvent &event) override
NETCLASS_MAP::const_iterator const_iterator
PCB_EDIT_FRAME * m_Parent
Functions relatives to tracks, vias and segments used to fill zones.
This file contains miscellaneous commonly used macros and functions.
void OnRightCBSelection(wxCommandEvent &event) override
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
void SynchronizeNetsAndNetClasses()
Function SynchronizeNetsAndNetClasses copies NETCLASS info to each NET, based on NET membership in a ...
NETCLASS_MAP::iterator iterator
int sort_int(int *first, int *second)
Class DIALOG_DESIGN_RULES_BASE.
STRINGSET::iterator iterator
bool TestDataValidity(wxString *aErrorMsg=NULL)
iterator begin()
Class NETCLASSES is a container for NETCLASS instances.
static const char Default[]
the name of the default NETCLASS
bool Add(NETCLASSPTR aNetclass)
Function Add takes aNetclass and puts it into this NETCLASSES container.
Class NETS_LIST_CTRL is a helper to display lists of nets and associated netclasses used in dialog de...
static void gridRow2class(wxGrid *grid, int row, NETCLASSPTR nc)
int m_TrackMinWidth
track min value for width ((min copper size value
int m_ViasMinSize
vias (not micro vias) min diameter
wxString GetAbbreviatedUnitsLabel(EDA_UNITS_T aUnit)
Definition: base_units.cpp:479
static void class2gridRow(wxGrid *grid, int row, NETCLASSPTR nc)
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
int m_ViasMinDrill
vias (not micro vias) min drill diameter
int ValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue)
Function ValueFromString converts aTextValue in aUnits to internal units used by the application...
Definition: base_units.cpp:368
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:533
int m_initialRowLabelsSize
the initial width given by wxFormBuilder
void OnAddNetclassClick(wxCommandEvent &event) override
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
Class HTML_MESSAGE_BOX.
void makePointers(PNETCUPS *aList, const wxString &aNetClassName)
int m_MicroViasMinSize
micro vias (not vias) min diameter
wxArrayString m_Classnames
column 1: netclasses
int ValueFromTextCtrl(const wxTextCtrl &aTextCtr)
Convert the number Value in a string according to the internal units and the selected unit (g_UserUni...
Definition: base_units.cpp:384
wxString net
a net name
void OnAllowMicroVias(wxCommandEvent &event) override
Function OnAllowMicroVias is called whenever the AllowMicroVias checkbox is toggled.
void MessageSet(const wxString &message)
Function MessageSet adds a message (in bold) to message list.
void OnLeftCBSelection(wxCommandEvent &event) override
unsigned GetCount() const
Function GetCount.
EDA_UNITS_T g_UserUnit
Global variables definitions.
Definition: common.cpp:56
static const wxString wildCard
the name of a fictitious netclass which includes all NETs
#define CLASS_TITLE
void PutValueInLocalUnits(wxTextCtrl &aTextCtr, int aValue)
Function PutValueInLocalUnits converts aValue from internal units to user units and append the units ...
Definition: base_units.cpp:265
void SetRowItems(unsigned aRow, const wxString &aNetname, const wxString &aNetclassName)
Function SetRowItems sets the net name and the net class name at aRow.
void OnRightToLeftCopyButton(wxCommandEvent &event) override
static void EnsureGridColumnWidths(wxWindow *aShower, wxGrid *aGrid)
Function EnsureGridColumnWidths resizes all the columns in a wxGrid based only on the requirements of...
BOARD_DESIGN_SETTINGS * m_BrdSettings
void setNetClass(const wxString &aNetName, const wxString &aClassName)
bool SetCurrentNetClass(const wxString &aNetClassName)
Function SetCurrentNetClass Must be called after a netclass selection (or after a netclass parameter ...
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
void Clear()
Function Clear destroys any contained NETCLASS instances except the Default one.
void OnLeftSelectAllButton(wxCommandEvent &event) override
#define max(a, b)
Definition: auxiliary.h:86
NETCLASSPTR GetDefault() const
Function GetDefault.
static int s_LastTabSelection
which tab user had open last
void FillListBoxWithNetNames(NETS_LIST_CTRL *aListCtrl, const wxString &aNetClass)
Function FillListBoxWithNetNames populates aListCtrl with net names and class names from m_AllNets in...
std::vector< VIA_DIMENSION > m_ViasDimensionsList
Vias size and drill list.
const char * name
STRINGSET::const_iterator const_iterator
double To_User_Unit(EDA_UNITS_T aUnit, double aValue)
Function To_User_Unit convert aValue in internal units to the appropriate user units defined by aUnit...
Definition: base_units.cpp:90
NETCUPS m_AllNets
A two column table which gets filled once and never loses any elements, so it is basically constant...
bool m_MicroViasAllowed
true to allow micro vias
int m_MicroViasMinDrill
micro vias (not vias) min drill diameter
virtual wxString OnGetItemText(long item, long column) const override
Function OnGetItemText is an overloaded method needed by wxListCtrl with wxLC_VIRTUAL options...
#define MYCELL(col)
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:69
wxArrayString m_Netnames
column 0: nets
DIALOG_DESIGN_RULES(PCB_EDIT_FRAME *parent)
NETCLASSES m_NetClasses
List of current netclasses. There is always the default netclass.