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 
295 
299 
300  // Initialize Vias and Tracks sizes lists.
301  // note we display only extra values, never the current netclass value.
302  // (the first value in history list)
304  m_TracksWidthList.erase( m_TracksWidthList.begin() ); // remove the netclass value
306  m_ViasDimensionsList.erase( m_ViasDimensionsList.begin() ); // remove the netclass value
308 }
309 
310 
312 {
313  wxString msg;
314 
315  // Compute the column widths here, after setting texts
316  msg = wxT("000000.000000"); // This is a very long text to display values.
317  // Actual values are shorter.
318  m_gridViaSizeList->SetCellValue( 0, 0, msg );
319  m_gridViaSizeList->SetCellValue( 0, 1, msg );
320  m_gridTrackWidthList->SetCellValue( 0, 0, msg );
321  m_gridViaSizeList->SetColMinimalWidth( 0, 150 );
322  m_gridViaSizeList->SetColMinimalWidth( 1, 150 );
323  m_gridViaSizeList->AutoSizeColumns( true );
324  m_gridTrackWidthList->SetColMinimalWidth( 0, 150 );
325  m_gridTrackWidthList->AutoSizeColumns( true );
326  m_gridViaSizeList->SetColMinimalWidth( 1, 150 );
327 
328  // Fill cells with actual values:
329  m_gridViaSizeList->SetCellValue( 0, 0, wxEmptyString );
330  m_gridViaSizeList->SetCellValue( 0, 1, wxEmptyString );
331  m_gridTrackWidthList->SetCellValue( 0, 0, wxEmptyString );
332 
333  // Give a correct size to row labels column
334  m_gridViaSizeList->SetRowLabelSize( wxGRID_AUTOSIZE );
335  m_gridTrackWidthList->SetRowLabelSize( wxGRID_AUTOSIZE );
336 
337  for( unsigned ii = 0; ii < m_TracksWidthList.size(); ii++ )
338  {
339  msg = StringFromValue( g_UserUnit, m_TracksWidthList[ii], false );
340  m_gridTrackWidthList->SetCellValue( ii, 0, msg );
341  }
342 
343  for( unsigned ii = 0; ii < m_ViasDimensionsList.size(); ii++ )
344  {
345  msg = StringFromValue( g_UserUnit, m_ViasDimensionsList[ii].m_Diameter, false );
346  m_gridViaSizeList->SetCellValue( ii, 0, msg );
347 
348  if( m_ViasDimensionsList[ii].m_Drill > 0 )
349  {
350  msg = StringFromValue( g_UserUnit, m_ViasDimensionsList[ii].m_Drill, false );
351  m_gridViaSizeList->SetCellValue( ii, 1, msg );
352  }
353  }
354 }
355 
356 
357 // Sort comparison function (helper for makePointers() )
358 static bool sortByClassThenName( NETCUP* a, NETCUP* b )
359 {
360  // return a < b
361  if( a->clazz < b->clazz )
362  return true;
363 
364  // inside the same class, sort by net name:
365  if( a->clazz == b->clazz )
366  {
367  if( a->net < b->net )
368  return true;
369  }
370 
371  return false;
372 }
373 
374 
375 void DIALOG_DESIGN_RULES::makePointers( PNETCUPS* aList, const wxString& aNetClassName )
376 {
377  aList->clear();
378 
379  if( wildCard == aNetClassName )
380  {
381  for( NETCUPS::iterator n = m_AllNets.begin(); n != m_AllNets.end(); ++n )
382  {
383  aList->push_back( &*n );
384  }
385 
386  sort( aList->begin(), aList->end(), sortByClassThenName );
387 
388  // could use a different sort order for wildCard case.
389  }
390  else
391  {
392  for( NETCUPS::iterator n = m_AllNets.begin(); n != m_AllNets.end(); ++n )
393  {
394  if( n->clazz == aNetClassName )
395  aList->push_back( &*n );
396  }
397 
398  sort( aList->begin(), aList->end(), sortByClassThenName );
399  }
400 }
401 
402 
404  const wxString& aNetClass )
405 {
406  aListCtrl->ClearList();
407 
408  PNETCUPS ptrList;
409 
410  // get a subset of m_AllNets in pointer form, sorted as desired.
411  makePointers( &ptrList, aNetClass );
412 
413 #if 0 && defined(DEBUG)
414  int r = 0;
415  for( PNETCUPS::iterator i = ptrList.begin(); i!=ptrList.end(); ++i, ++r )
416  {
417  printf( "[%d]: %s %s\n", r, TO_UTF8( (*i)->net ), TO_UTF8( (*i)->clazz ) );
418  }
419 
420 #endif
421 
422  // Add netclass info to m_Netnames and m_Classnames wxArrayString buffers
423  // aListCtrl uses wxLC_VIRTUAL option, so this is fast
424  wxClientDC sDC( aListCtrl );
425  int row = 0;
426  // recompute the column widths here, after setting texts
427  int net_colsize = sDC.GetTextExtent( NET_TITLE ).x;
428  int class_colsize = sDC.GetTextExtent( CLASS_TITLE ).x;
429 
430  for( PNETCUPS::iterator i = ptrList.begin(); i!=ptrList.end(); ++i, ++row )
431  {
432  wxSize net_needed = sDC.GetTextExtent( (*i)->net );
433  wxSize class_needed = sDC.GetTextExtent( (*i)->clazz );
434  net_colsize = std::max( net_colsize, net_needed.x );
435  class_colsize = std::max( class_colsize, class_needed.x );
436  aListCtrl->SetRowItems( row, (*i)->net, (*i)->clazz );
437  }
438 
439  int margin = sDC.GetTextExtent( wxT( "XX" ) ).x;
440  aListCtrl->SetColumnWidth( 0, net_colsize + margin );
441  aListCtrl->SetColumnWidth( 1, class_colsize + margin );
442  aListCtrl->Refresh();
443 }
444 
445 
446 /* Populates combo boxes with the list of existing net classes
447  */
449 {
450  m_rightClassChoice->Clear();
451  m_leftClassChoice->Clear();
452 
453  m_rightClassChoice->Append( wildCard );
454  m_leftClassChoice->Append( wildCard );
455 
456  for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
457  {
458  m_rightClassChoice->Append( m_grid->GetRowLabelValue( ii ) );
459  m_leftClassChoice->Append( m_grid->GetRowLabelValue( ii ) );
460  }
461 
462  m_rightClassChoice->Select( 0 );
463  m_leftClassChoice->Select( 0 );
464 
465  m_buttonRightToLeft->Enable( false );
466  m_buttonLeftToRight->Enable( false );
467 
468  FillListBoxWithNetNames( m_leftListCtrl, m_leftClassChoice->GetStringSelection() );
470 }
471 
472 
473 /* Initialize the rules list from board
474  */
475 
476 static void class2gridRow( wxGrid* grid, int row, NETCLASSPTR nc )
477 {
478  wxString msg;
479 
480  // label is netclass name
481  grid->SetRowLabelValue( row, nc->GetName() );
482 
483  msg = StringFromValue( g_UserUnit, nc->GetClearance() );
484  grid->SetCellValue( row, GRID_CLEARANCE, msg );
485 
486  msg = StringFromValue( g_UserUnit, nc->GetTrackWidth() );
487  grid->SetCellValue( row, GRID_TRACKSIZE, msg );
488 
489  msg = StringFromValue( g_UserUnit, nc->GetViaDiameter() );
490  grid->SetCellValue( row, GRID_VIASIZE, msg );
491 
492  msg = StringFromValue( g_UserUnit, nc->GetViaDrill() );
493  grid->SetCellValue( row, GRID_VIADRILL, msg );
494 
495  msg = StringFromValue( g_UserUnit, nc->GetuViaDiameter() );
496  grid->SetCellValue( row, GRID_uVIASIZE, msg );
497 
498  msg = StringFromValue( g_UserUnit, nc->GetuViaDrill() );
499  grid->SetCellValue( row, GRID_uVIADRILL, msg );
500 
501  msg = StringFromValue( g_UserUnit, nc->GetDiffPairGap() );
502  grid->SetCellValue( row, GRID_DIFF_PAIR_GAP, msg );
503 
504  msg = StringFromValue( g_UserUnit, nc->GetDiffPairWidth() );
505  grid->SetCellValue( row, GRID_DIFF_PAIR_WIDTH, msg );
506 
507 }
508 
509 
511 {
512  NETCLASSES& netclasses = m_BrdSettings->m_NetClasses;
513 
514  // the +1 is for the Default NETCLASS.
515  if( netclasses.GetCount() + 1 > (unsigned) m_grid->GetNumberRows() )
516  {
517  m_grid->AppendRows( netclasses.GetCount() + 1 - m_grid->GetNumberRows() );
518  }
519 
520  // enter the Default NETCLASS.
521  class2gridRow( m_grid, 0, netclasses.GetDefault() );
522 
523  // enter others netclasses
524  int row = 1;
525 
526  for( NETCLASSES::iterator i = netclasses.begin(); i!=netclasses.end(); ++i, ++row )
527  {
528  NETCLASSPTR netclass = i->second;
529 
530  class2gridRow( m_grid, row, netclass );
531  }
532 }
533 
534 
535 static void gridRow2class( wxGrid* grid, int row, NETCLASSPTR nc )
536 {
537 #define MYCELL( col ) \
538  ValueFromString( g_UserUnit, grid->GetCellValue( row, col ) )
539 
540  nc->SetClearance( MYCELL( GRID_CLEARANCE ) );
541  nc->SetTrackWidth( MYCELL( GRID_TRACKSIZE ) );
542  nc->SetViaDiameter( MYCELL( GRID_VIASIZE ) );
543  nc->SetViaDrill( MYCELL( GRID_VIADRILL ) );
544  nc->SetuViaDiameter( MYCELL( GRID_uVIASIZE ) );
545  nc->SetuViaDrill( MYCELL( GRID_uVIADRILL ) );
546  nc->SetDiffPairGap( MYCELL( GRID_DIFF_PAIR_GAP ) );
547  nc->SetDiffPairWidth( MYCELL( GRID_DIFF_PAIR_WIDTH ) );
548 
549 }
550 
551 
553 {
554  NETCLASSES& netclasses = m_BrdSettings->m_NetClasses;
555 
556  // Remove all netclasses from board. We'll copy new list after
557  netclasses.Clear();
558 
559  // Copy the default NetClass:
560  gridRow2class( m_grid, 0, netclasses.GetDefault() );
561 
562  // Copy other NetClasses :
563  for( int row = 1; row < m_grid->GetNumberRows(); ++row )
564  {
565  NETCLASSPTR nc = std::make_shared<NETCLASS>( m_grid->GetRowLabelValue( row ) );
566 
567  if( !m_BrdSettings->m_NetClasses.Add( nc ) )
568  {
569  // this netclass cannot be added because an other netclass with the same name exists
570  // Should not occur because OnAddNetclassClick() tests for existing NetClass names
571  wxString msg;
572  msg.Printf( wxT( "CopyRulesListToBoard(): The NetClass \"%s\" already exists. Skip" ),
573  GetChars( m_grid->GetRowLabelValue( row ) ) );
574  wxMessageBox( msg );
575 
576  continue;
577  }
578 
579  gridRow2class( m_grid, row, nc );
580  }
581 
582  // Now read all nets and push them in the corresponding netclass net buffer
583  for( NETCUPS::const_iterator netcup = m_AllNets.begin(); netcup != m_AllNets.end(); ++netcup )
584  {
585  NETCLASSPTR nc = netclasses.Find( netcup->clazz );
586  wxASSERT( nc );
587  nc->Add( netcup->net );
588  }
589 
591 }
592 
593 
595 {
597 
598  // Update vias minimum values for DRC
601 
603 
604  // Update microvias minimum values for DRC
607 
608  // Update tracks minimum values for DRC
610 }
611 
612 
614 {
615  wxString msg;
616 
617  // Reinitialize m_TrackWidthList
618  m_TracksWidthList.clear();
619 
620  for( int row = 0; row < m_gridTrackWidthList->GetNumberRows(); ++row )
621  {
622  msg = m_gridTrackWidthList->GetCellValue( row, 0 );
623 
624  if( msg.IsEmpty() )
625  continue;
626 
627  int value = ValueFromString( g_UserUnit, msg );
628  m_TracksWidthList.push_back( value );
629  }
630 
631  // Sort new list by by increasing value
632  sort( m_TracksWidthList.begin(), m_TracksWidthList.end() );
633 
634  // Reinitialize m_TrackWidthList
635  m_ViasDimensionsList.clear();
636 
637  for( int row = 0; row < m_gridViaSizeList->GetNumberRows(); ++row )
638  {
639  msg = m_gridViaSizeList->GetCellValue( row, 0 );
640 
641  if( msg.IsEmpty() )
642  continue;
643 
644  int value = ValueFromString( g_UserUnit, msg );
645  VIA_DIMENSION via_dim;
646  via_dim.m_Diameter = value;
647  msg = m_gridViaSizeList->GetCellValue( row, 1 );
648 
649  if( !msg.IsEmpty() )
650  {
651  value = ValueFromString( g_UserUnit, msg );
652  via_dim.m_Drill = value;
653  }
654 
655  m_ViasDimensionsList.push_back( via_dim );
656  }
657 
658  // Sort new list by by increasing value
659  sort( m_ViasDimensionsList.begin(), m_ViasDimensionsList.end() );
660 
661  std::vector<int>* tlist = &m_BrdSettings->m_TrackWidthList;
662 
663  // Remove old "custom" sizes
664  tlist->erase( tlist->begin() + 1, tlist->end() );
665 
666  // Add new "custom" sizes
667  tlist->insert( tlist->end(), m_TracksWidthList.begin(), m_TracksWidthList.end() );
668 
669  // Reinitialize m_ViaSizeList
670  std::vector<VIA_DIMENSION>* vialist = &m_BrdSettings->m_ViasDimensionsList;
671  vialist->erase( vialist->begin() + 1, vialist->end() );
672  vialist->insert( vialist->end(), m_ViasDimensionsList.begin(), m_ViasDimensionsList.end() );
673 }
674 
675 
676 void DIALOG_DESIGN_RULES::OnNotebookPageChanged( wxNotebookEvent& event )
677 {
678  s_LastTabSelection = event.GetSelection();
679 
680  // Skip() allows OSX to properly refresh controls.
681  event.Skip();
682 }
683 
684 
686 {
687  if( !wxDialog::TransferDataFromWindow() )
688  return false;
689 
690  wxString errorMsg;
691 
692  if( !TestDataValidity( &errorMsg ) )
693  {
694  HTML_MESSAGE_BOX dlg( this, _( "Design Rule Setting Error" ) );
695  dlg.MessageSet( errorMsg );
696  dlg.ShowModal();
697  return false;
698  }
699 
704  return true;
705 }
706 
707 
708 void DIALOG_DESIGN_RULES::OnAddNetclassClick( wxCommandEvent& event )
709 {
710  wxString class_name;
711 
712  // @todo set validator to ensure net class name is valid rather than all of the checks
713  // after the OK button has been selected.
714  wxTextEntryDialog dlg( this, _( "New Net Class Name:" ), wxEmptyString, class_name );
715 
716  if( dlg.ShowModal() != wxID_OK )
717  return; // canceled by user
718 
719  class_name = dlg.GetValue();
720  class_name.Trim( true );
721  class_name.Trim( false );
722 
723  if( class_name.IsEmpty() )
724  return; // empty name not allowed
725 
726  // The name must dot exists:
727  for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
728  {
729  wxString value;
730  value = m_grid->GetRowLabelValue( ii );
731 
732  if( class_name.CmpNoCase( value ) == 0 ) // Already exists!
733  {
734  DisplayError( this, _( "Duplicate net class names are not allowed." ) );
735  return;
736  }
737  }
738 
739  m_grid->AppendRows();
740  m_grid->SetRowLabelValue( m_grid->GetNumberRows() - 1, class_name );
741 
742  // Copy values of the default class:
743  int irow = m_grid->GetNumberRows() - 1;
744 
745  for( int icol = 0; icol < m_grid->GetNumberCols(); icol++ )
746  {
747  wxString value;
748  value = m_grid->GetCellValue( 0, icol );
749  m_grid->SetCellValue( irow, icol, value );
750  }
751 
753 
755 }
756 
757 
758 // Sort function for wxArrayInt. Items (ints) are sorted by decreasing value
759 // used in DIALOG_DESIGN_RULES::OnRemoveNetclassClick
760 int sort_int( int* first, int* second )
761 {
762  return *second - *first;
763 }
764 
765 
766 void DIALOG_DESIGN_RULES::OnRemoveNetclassClick( wxCommandEvent& event )
767 {
768  wxArrayInt select = m_grid->GetSelectedRows();
769 
770  // Sort selection by decreasing index order:
771  select.Sort( sort_int );
772  bool reinit = false;
773 
774  // rows labels are not removed when deleting rows: they are not deleted.
775  // So we must store them, remove corresponding labels and reinit them
776  wxArrayString labels;
777 
778  for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
779  labels.Add( m_grid->GetRowLabelValue( ii ) );
780 
781  // Delete rows from last to first (this is the order wxArrayInt select after sorting) )
782  // This order is Ok when removing rows
783  for( unsigned ii = 0; ii < select.GetCount(); ii++ )
784  {
785  int grid_row = select[ii];
786 
787  if( grid_row != 0 ) // Do not remove the default class
788  {
789  wxString classname = m_grid->GetRowLabelValue( grid_row );
790  m_grid->DeleteRows( grid_row );
791  labels.RemoveAt( grid_row ); // Remove corresponding row label
792  reinit = true;
793 
794  // reset the net class to default for members of the removed class
795  swapNetClass( classname, NETCLASS::Default );
796  }
797  else
798  wxMessageBox( _( "The default net class cannot be removed" ) );
799  }
800 
801  if( reinit )
802  {
803  // Reinit labels :
804  for( unsigned ii = 1; ii < labels.GetCount(); ii++ )
805  m_grid->SetRowLabelValue( ii, labels[ii] );
806 
809  }
810 }
811 
813 {
814  bool enabled = m_OptAllowMicroVias->GetValue();
815  m_SetMicroViasMinSizeCtrl->Enable( enabled );
816  m_SetMicroViasMinDrillCtrl->Enable( enabled );
817 }
818 
823 void DIALOG_DESIGN_RULES::OnAllowMicroVias( wxCommandEvent& event )
824 {
826 }
827 
829 {
830  // Cannot move up rules if we have 1 or 2 rules only
831  if( m_grid->GetNumberRows() < 3 )
832  return;
833 
834  wxArrayInt select = m_grid->GetSelectedRows();
835  bool reinit = false;
836 
837  for( unsigned irow = 0; irow < select.GetCount(); irow++ )
838  {
839  int ii = select[irow];
840  if( ii < 2 ) // The default netclass *must* be the first netclass
841  continue; // so we cannot move up line 0 and 1
842 
843  // Swap the rule and the previous rule
844  wxString curr_value, previous_value;
845 
846  for( int icol = 0; icol < m_grid->GetNumberCols(); icol++ )
847  {
848  reinit = true;
849  curr_value = m_grid->GetCellValue( ii, icol );
850  previous_value = m_grid->GetCellValue( ii - 1, icol );
851  m_grid->SetCellValue( ii, icol, previous_value );
852  m_grid->SetCellValue( ii - 1, icol, curr_value );
853  }
854 
855  curr_value = m_grid->GetRowLabelValue( ii );
856  previous_value = m_grid->GetRowLabelValue( ii - 1 );
857  m_grid->SetRowLabelValue( ii, previous_value );
858  m_grid->SetRowLabelValue( ii - 1, curr_value );
859  }
860 
861  if( reinit )
863 }
864 
865 
866 void DIALOG_DESIGN_RULES::OnLeftCBSelection( wxCommandEvent& event )
867 {
868  FillListBoxWithNetNames( m_leftListCtrl, m_leftClassChoice->GetStringSelection() );
869 
870  if( m_leftClassChoice->GetStringSelection() == m_rightClassChoice->GetStringSelection() )
871  {
872  m_buttonRightToLeft->Enable( false );
873  m_buttonLeftToRight->Enable( false );
874  }
875  else
876  {
877  m_buttonRightToLeft->Enable( true );
878  m_buttonLeftToRight->Enable( true );
879  }
880 }
881 
882 
883 void DIALOG_DESIGN_RULES::OnRightCBSelection( wxCommandEvent& event )
884 {
886 
887  if( m_leftClassChoice->GetStringSelection() == m_rightClassChoice->GetStringSelection() )
888  {
889  m_buttonRightToLeft->Enable( false );
890  m_buttonLeftToRight->Enable( false );
891  }
892  else
893  {
894  m_buttonRightToLeft->Enable( true );
895  m_buttonLeftToRight->Enable( true );
896  }
897 }
898 
899 
900 void DIALOG_DESIGN_RULES::moveSelectedItems( NETS_LIST_CTRL* src, const wxString& newClassName )
901 {
902  wxListItem item;
903  wxString netName;
904 
905  item.m_mask |= wxLIST_MASK_TEXT; // Validate the member m_text of the wxListItem item
906 
907  for( int row = 0; row < src->GetItemCount(); ++row )
908  {
909  if( !src->GetItemState( row, wxLIST_STATE_SELECTED ) )
910  continue;
911 
912  item.SetColumn( 0 );
913  item.SetId( row );
914 
915  src->GetItem( item );
916  netName = item.GetText();
917 
918  setNetClass( netName, newClassName == wildCard ? NETCLASS::Default : newClassName );
919  }
920 }
921 
922 
923 void DIALOG_DESIGN_RULES::OnRightToLeftCopyButton( wxCommandEvent& event )
924 {
925  wxString newClassName = m_leftClassChoice->GetStringSelection();
926 
927  moveSelectedItems( m_rightListCtrl, newClassName );
928 
929  FillListBoxWithNetNames( m_leftListCtrl, m_leftClassChoice->GetStringSelection() );
931 }
932 
933 
934 void DIALOG_DESIGN_RULES::OnLeftToRightCopyButton( wxCommandEvent& event )
935 {
936  wxString newClassName = m_rightClassChoice->GetStringSelection();
937 
938  moveSelectedItems( m_leftListCtrl, newClassName );
939 
940  FillListBoxWithNetNames( m_leftListCtrl, m_leftClassChoice->GetStringSelection() );
942 }
943 
944 
945 void DIALOG_DESIGN_RULES::OnLeftSelectAllButton( wxCommandEvent& event )
946 {
947  for( int ii = 0; ii < m_leftListCtrl->GetItemCount(); ii++ )
948  m_leftListCtrl->SetItemState( ii, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
949 }
950 
951 
952 void DIALOG_DESIGN_RULES::OnRightSelectAllButton( wxCommandEvent& event )
953 {
954  for( int ii = 0; ii < m_rightListCtrl->GetItemCount(); ii++ )
955  m_rightListCtrl->SetItemState( ii, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
956 }
957 
958 
959 void DIALOG_DESIGN_RULES::setNetClass( const wxString& aNetName, const wxString& aClassName )
960 {
961  for( NETCUPS::iterator i = m_AllNets.begin(); i != m_AllNets.end(); ++i )
962  {
963  if( i->net == aNetName )
964  {
965  i->clazz = aClassName;
966  break;
967  }
968  }
969 }
970 
971 
972 bool DIALOG_DESIGN_RULES::TestDataValidity( wxString* aErrorMsg )
973 {
974  bool result = true;
975 
976  wxString msg;
977  wxString errorMsg;
978 
979  wxString netclassLabel; // Name of a given netclass
980  wxString netclassError; // Error message particular to a given netclass
981 
982  wxString units = ReturnUnitSymbol( g_UserUnit, "%s" );
983 
984  int minViaDia = ValueFromTextCtrl( *m_SetViasMinSizeCtrl );
985  int minViaDrill = ValueFromTextCtrl( *m_SetViasMinDrillCtrl );
986  int minUViaDia = ValueFromTextCtrl( *m_SetMicroViasMinSizeCtrl );
987  int minUViaDrill = ValueFromTextCtrl( *m_SetMicroViasMinDrillCtrl );
988  int minTrackWidth = ValueFromTextCtrl( *m_SetTrackMinWidthCtrl );
989  int maxval = 1000 * IU_PER_MILS; // a max value for tracks and vias sizes (1 inch)
990 
991  // @todo Change this code to set the focus to the control where the first error occurs
992  // so the user doesn't have to figure out where the issue is.
993 
994  // Test net class parameters.
995  for( int row = 0; row < m_grid->GetNumberRows(); row++ )
996  {
997  netclassLabel = GetChars( m_grid->GetRowLabelValue( row ) );
998  netclassError.Clear(); // Clear the error for this netclass
999 
1000  int tracksize = ValueFromString( g_UserUnit,
1001  m_grid->GetCellValue( row, GRID_TRACKSIZE ) );
1002  if( tracksize < minTrackWidth )
1003  {
1004  result = false;
1005  msg.Printf( _( " - <b>Track Size</b> (%f %s) &lt; <b>Min Track Size</b> (%f %s)<br>" ),
1006  To_User_Unit( g_UserUnit, tracksize ), units,
1007  To_User_Unit( g_UserUnit, minTrackWidth ), units );
1008 
1009  netclassError += msg;
1010  }
1011 
1012  int dpsize = ValueFromString( g_UserUnit,
1013  m_grid->GetCellValue( row, GRID_DIFF_PAIR_WIDTH ) );
1014 
1015  if( dpsize < minTrackWidth )
1016  {
1017  result = false;
1018  msg.Printf( _( " - <b>Differential Pair Size</b> (%f %s) &lt; <b>Min Track Size</b> (%f %s)<br>" ),
1019  To_User_Unit( g_UserUnit, dpsize ), units,
1020  To_User_Unit( g_UserUnit, minTrackWidth ), units );
1021  netclassError += msg;
1022  }
1023 
1024 
1025  // Test vias
1026  int viadia = ValueFromString( g_UserUnit,
1027  m_grid->GetCellValue( row, GRID_VIASIZE ) );
1028 
1029  if( viadia < minViaDia )
1030  {
1031  result = false;
1032  msg.Printf( _( " - <b>Via Diameter</b> (%f %s) &lt; <b>Minimum Via Diameter</b> (%f %s)<br>" ),
1033  To_User_Unit( g_UserUnit, viadia ), units,
1034  To_User_Unit( g_UserUnit, minViaDia ), units );
1035  netclassError += msg;
1036  }
1037 
1038  int viadrill = ValueFromString( g_UserUnit,
1039  m_grid->GetCellValue( row, GRID_VIADRILL ) );
1040 
1041  if( viadrill >= viadia )
1042  {
1043  result = false;
1044  msg.Printf( _( " - <b>Via Drill</b> (%f %s) &ge; <b>Via Dia</b> (%f %s)<br>" ),
1045  To_User_Unit( g_UserUnit, viadrill ), units,
1046  To_User_Unit( g_UserUnit, viadia ), units );
1047  netclassError += msg;
1048  }
1049 
1050  if( viadrill < minViaDrill )
1051  {
1052  result = false;
1053  msg.Printf( _( " - <b>Via Drill</b> (%f %s) &lt; <b>Min Via Drill</b> (%f %s)<br>" ),
1054  To_User_Unit( g_UserUnit, viadrill ), units,
1055  To_User_Unit( g_UserUnit, minViaDrill ), units );
1056  netclassError += msg;
1057  }
1058 
1059  // Test Micro vias
1060  int muviadia = ValueFromString( g_UserUnit,
1061  m_grid->GetCellValue( row, GRID_uVIASIZE ) );
1062 
1063  if( muviadia < minUViaDia )
1064  {
1065  result = false;
1066  msg.Printf( _( " - <b>MicroVia Diameter</b> (%f %s) &lt; <b>MicroVia Min Diameter</b> (%f %s)<br>" ),
1067  To_User_Unit( g_UserUnit, muviadia ), units,
1068  To_User_Unit( g_UserUnit, minUViaDia ), units );
1069  netclassError += msg;
1070  }
1071 
1072  int muviadrill = ValueFromString( g_UserUnit,
1073  m_grid->GetCellValue( row, GRID_uVIADRILL ) );
1074 
1075  if( muviadrill >= muviadia )
1076  {
1077  result = false;
1078  msg.Printf( _( " - <b>MicroVia Drill</b> (%f %s) &ge; <b>MicroVia Dia</b> (%f %s)<br>" ),
1079  To_User_Unit( g_UserUnit, muviadrill ), units,
1080  To_User_Unit( g_UserUnit, muviadia ), units );
1081  netclassError += msg;
1082  }
1083 
1084  if( muviadrill < minUViaDrill )
1085  {
1086  result = false;
1087  msg.Printf( _( " - <b>MicroVia Drill</b> (%f %s) &lt; <b>MicroVia Min Drill</b> (%f %s)<br>" ),
1088  To_User_Unit( g_UserUnit, muviadrill ), units,
1089  To_User_Unit( g_UserUnit, minUViaDrill ), units );
1090  netclassError += msg;
1091  }
1092 
1093  // If this netclass contains errors, add it to the error message
1094  if ( !netclassError.IsEmpty() )
1095  {
1096  msg.Printf( _( "Netclass: <b>%s</b><br>" ), netclassLabel );
1097  errorMsg += msg;
1098  errorMsg += netclassError;
1099  errorMsg += "<br>";
1100  }
1101  }
1102 
1103  // Test custom tracks
1104  for( int row = 0; row < m_gridTrackWidthList->GetNumberRows(); ++row )
1105  {
1106  wxString tvalue = m_gridTrackWidthList->GetCellValue( row, 0 );
1107 
1108  if( tvalue.IsEmpty() )
1109  continue;
1110 
1111  int tracksize = ValueFromString( g_UserUnit, tvalue );
1112 
1113  if( tracksize < minTrackWidth )
1114  {
1115  result = false;
1116  msg.Printf( _( "<b>Extra Track %d Size</b> %s &lt; <b>Min Track Size</b><br>" ),
1117  row + 1, GetChars( tvalue ) );
1118 
1119  errorMsg += msg;
1120  }
1121 
1122  if( tracksize > maxval )
1123  {
1124  result = false;
1125  msg.Printf( _( "<b>Extra Track %d Size</b> %s &gt; <b>1 inch!</b><br>" ),
1126  row + 1, GetChars( tvalue ) );
1127 
1128  errorMsg += msg;
1129  }
1130  }
1131 
1132  // Test custom vias
1133  for( int row = 0; row < m_gridViaSizeList->GetNumberRows(); ++row )
1134  {
1135  wxString tvalue = m_gridViaSizeList->GetCellValue( row, 0 );
1136 
1137  if( tvalue.IsEmpty() )
1138  continue;
1139 
1140  int viadia = ValueFromString( g_UserUnit, tvalue );
1141 
1142  if( viadia < minViaDia )
1143  {
1144  result = false;
1145  msg.Printf( _( "<b>Extra Via %d Size</b> %s &lt; <b>Min Via Size</b><br>" ),
1146  row + 1, GetChars( tvalue ) );
1147  errorMsg += msg;
1148  }
1149 
1150  wxString drlvalue = m_gridViaSizeList->GetCellValue( row, 1 );
1151 
1152  if( drlvalue.IsEmpty() )
1153  {
1154  result = false;
1155  msg.Printf( _( "<b>No via drill size define in row %d</b><br>" ), row + 1 );
1156  errorMsg += msg;
1157  continue;
1158  }
1159 
1160  int viadrill = ValueFromString( g_UserUnit, drlvalue );
1161 
1162  if( viadrill < minViaDrill )
1163  {
1164  result = false;
1165  msg.Printf( _( "<b>Extra Via %d Drill</b> %s &lt; <b>Min Via Drill %s</b><br>" ),
1166  row + 1, GetChars( drlvalue ),
1167  GetChars( m_SetViasMinDrillCtrl->GetValue() ) );
1168  errorMsg += msg;
1169  }
1170 
1171  if( viadia <= viadrill )
1172  {
1173  result = false;
1174  msg.Printf( _( "<b>Extra Via %d Size</b> %s &le; <b> Drill Size</b> %s<br>" ),
1175  row + 1, GetChars( tvalue ), GetChars( drlvalue ) );
1176  errorMsg += msg;
1177  }
1178 
1179  // Test for a reasonable via size:
1180  if( viadia > maxval ) // 1 inch!
1181  {
1182  result = false;
1183  msg.Printf( _( "<b>Extra Via %d Size</b>%s &gt; <b>1 inch!</b><br>" ),
1184  row + 1, GetChars( tvalue ) );
1185  errorMsg += msg;
1186  }
1187  }
1188 
1189  if( !result && aErrorMsg )
1190  *aErrorMsg = errorMsg;
1191 
1192  return result;
1193 }
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:532
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:73
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.