You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

262 lines
9.2 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2018 KiCad Developers, see change_log.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <fctsys.h>
  24. #include <class_drawpanel.h>
  25. #include <base_units.h>
  26. #include <pcb_edit_frame.h>
  27. #include <board_design_settings.h>
  28. #include <widgets/wx_grid.h>
  29. #include <panel_setup_tracks_and_vias.h>
  30. PANEL_SETUP_TRACKS_AND_VIAS::PANEL_SETUP_TRACKS_AND_VIAS(
  31. PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame,
  32. PANEL_SETUP_FEATURE_CONSTRAINTS* aConstraintsPanel ) :
  33. PANEL_SETUP_TRACKS_AND_VIAS_BASE( aParent->GetTreebook() )
  34. {
  35. m_Parent = aParent;
  36. m_Frame = aFrame;
  37. m_Pcb = m_Frame->GetBoard();
  38. m_BrdSettings = &m_Pcb->GetDesignSettings();
  39. m_ConstraintsPanel = aConstraintsPanel;
  40. // Membership combobox editors require a bit more room, so increase the row size of
  41. // all our grids for consistency
  42. m_trackWidthsGrid->SetDefaultRowSize( m_trackWidthsGrid->GetDefaultRowSize() + 4 );
  43. m_viaSizesGrid->SetDefaultRowSize( m_viaSizesGrid->GetDefaultRowSize() + 4 );
  44. m_diffPairsGrid->SetDefaultRowSize( m_diffPairsGrid->GetDefaultRowSize() + 4 );
  45. }
  46. bool PANEL_SETUP_TRACKS_AND_VIAS::TransferDataToWindow()
  47. {
  48. #define SETCELL( grid, row, col, val ) \
  49. grid->SetCellValue( row, col, StringFromValue( m_Frame->GetUserUnits(), val, true, true ) )
  50. m_trackWidthsGrid->ClearGrid();
  51. m_viaSizesGrid->ClearGrid();
  52. m_diffPairsGrid->ClearGrid();
  53. // Skip the first item, which is the current netclass value
  54. for( unsigned ii = 1; ii < m_BrdSettings->m_TrackWidthList.size(); ii++ )
  55. {
  56. SETCELL( m_trackWidthsGrid, ii-1, 0, m_BrdSettings->m_TrackWidthList[ii] );
  57. }
  58. // Skip the first item, which is the current netclass value
  59. for( unsigned ii = 1; ii < m_BrdSettings->m_ViasDimensionsList.size(); ii++ )
  60. {
  61. SETCELL( m_viaSizesGrid, ii-1, 0, m_BrdSettings->m_ViasDimensionsList[ii].m_Diameter );
  62. if( m_BrdSettings->m_ViasDimensionsList[ii].m_Drill > 0 )
  63. SETCELL( m_viaSizesGrid, ii-1, 1, m_BrdSettings->m_ViasDimensionsList[ii].m_Drill );
  64. }
  65. // Skip the first item, which is the current netclass value
  66. for( unsigned ii = 1; ii < m_BrdSettings->m_DiffPairDimensionsList.size(); ii++ )
  67. {
  68. SETCELL( m_diffPairsGrid, ii-1, 0, m_BrdSettings->m_DiffPairDimensionsList[ii].m_Width );
  69. if( m_BrdSettings->m_DiffPairDimensionsList[ii].m_Gap > 0 )
  70. SETCELL( m_diffPairsGrid, ii-1, 1, m_BrdSettings->m_DiffPairDimensionsList[ii].m_Gap );
  71. if( m_BrdSettings->m_DiffPairDimensionsList[ii].m_ViaGap > 0 )
  72. SETCELL( m_diffPairsGrid, ii-1, 2, m_BrdSettings->m_DiffPairDimensionsList[ii].m_ViaGap );
  73. }
  74. return true;
  75. }
  76. bool PANEL_SETUP_TRACKS_AND_VIAS::TransferDataFromWindow()
  77. {
  78. if( !validateData() )
  79. return false;
  80. wxString msg;
  81. std::vector<int> trackWidths;
  82. std::vector<VIA_DIMENSION> vias;
  83. std::vector<DIFF_PAIR_DIMENSION> diffPairs;
  84. for( int row = 0; row < m_trackWidthsGrid->GetNumberRows(); ++row )
  85. {
  86. msg = m_trackWidthsGrid->GetCellValue( row, 0 );
  87. if( !msg.IsEmpty() )
  88. trackWidths.push_back( ValueFromString( m_Frame->GetUserUnits(), msg, true ) );
  89. }
  90. for( int row = 0; row < m_viaSizesGrid->GetNumberRows(); ++row )
  91. {
  92. msg = m_viaSizesGrid->GetCellValue( row, 0 );
  93. if( !msg.IsEmpty() )
  94. {
  95. VIA_DIMENSION via_dim;
  96. via_dim.m_Diameter = ValueFromString( m_Frame->GetUserUnits(), msg, true );
  97. msg = m_viaSizesGrid->GetCellValue( row, 1 );
  98. if( !msg.IsEmpty() )
  99. via_dim.m_Drill = ValueFromString( m_Frame->GetUserUnits(), msg, true );
  100. vias.push_back( via_dim );
  101. }
  102. }
  103. for( int row = 0; row < m_viaSizesGrid->GetNumberRows(); ++row )
  104. {
  105. msg = m_diffPairsGrid->GetCellValue( row, 0 );
  106. if( !msg.IsEmpty() )
  107. {
  108. DIFF_PAIR_DIMENSION diffPair_dim;
  109. diffPair_dim.m_Width = ValueFromString( m_Frame->GetUserUnits(), msg, true );
  110. msg = m_diffPairsGrid->GetCellValue( row, 1 );
  111. diffPair_dim.m_Gap = ValueFromString( m_Frame->GetUserUnits(), msg, true );
  112. msg = m_diffPairsGrid->GetCellValue( row, 2 );
  113. if( !msg.IsEmpty() )
  114. diffPair_dim.m_ViaGap = ValueFromString( m_Frame->GetUserUnits(), msg, true );
  115. diffPairs.push_back( diffPair_dim );
  116. }
  117. }
  118. // Sort lists by increasing value
  119. sort( trackWidths.begin(), trackWidths.end() );
  120. sort( vias.begin(), vias.end() );
  121. sort( diffPairs.begin(), diffPairs.end() );
  122. trackWidths.insert( trackWidths.begin(), m_BrdSettings->m_TrackWidthList[ 0 ] );
  123. m_BrdSettings->m_TrackWidthList = trackWidths;
  124. vias.insert( vias.begin(), m_BrdSettings->m_ViasDimensionsList[ 0 ] );
  125. m_BrdSettings->m_ViasDimensionsList = vias;
  126. diffPairs.insert( diffPairs.begin(), m_BrdSettings->m_DiffPairDimensionsList[ 0 ] );
  127. m_BrdSettings->m_DiffPairDimensionsList = diffPairs;
  128. return true;
  129. }
  130. bool PANEL_SETUP_TRACKS_AND_VIAS::validateData()
  131. {
  132. if( !m_trackWidthsGrid->CommitPendingChanges()
  133. || !m_viaSizesGrid->CommitPendingChanges()
  134. || !m_diffPairsGrid->CommitPendingChanges() )
  135. return false;
  136. wxString msg;
  137. int minViaDia = m_ConstraintsPanel->m_viaMinSize.GetValue();
  138. int minViaDrill = m_ConstraintsPanel->m_viaMinDrill.GetValue();
  139. int minTrackWidth = m_ConstraintsPanel->m_trackMinWidth.GetValue();
  140. // Test tracks
  141. for( int row = 0; row < m_trackWidthsGrid->GetNumberRows(); ++row )
  142. {
  143. wxString tvalue = m_trackWidthsGrid->GetCellValue( row, 0 );
  144. if( tvalue.IsEmpty() )
  145. continue;
  146. if( ValueFromString( m_Frame->GetUserUnits(), tvalue ) < minTrackWidth )
  147. {
  148. msg.Printf( _( "Track width less than minimum track width (%s)." ),
  149. StringFromValue( m_Frame->GetUserUnits(), minTrackWidth, true, true ) );
  150. m_Parent->SetError( msg, this, m_trackWidthsGrid, row, 0 );
  151. return false;
  152. }
  153. }
  154. // Test vias
  155. for( int row = 0; row < m_viaSizesGrid->GetNumberRows(); ++row )
  156. {
  157. wxString viaDia = m_viaSizesGrid->GetCellValue( row, 0 );
  158. if( viaDia.IsEmpty() )
  159. continue;
  160. if( ValueFromString( m_Frame->GetUserUnits(), viaDia ) < minViaDia )
  161. {
  162. msg.Printf( _( "Via diameter less than minimum via diameter (%s)." ),
  163. StringFromValue( m_Frame->GetUserUnits(), minViaDia, true, true ) );
  164. m_Parent->SetError( msg, this, m_viaSizesGrid, row, 0 );
  165. return false;
  166. }
  167. wxString viaDrill = m_viaSizesGrid->GetCellValue( row, 1 );
  168. if( viaDrill.IsEmpty() )
  169. {
  170. msg = _( "No via drill defined." );
  171. m_Parent->SetError( msg, this, m_viaSizesGrid, row, 1 );
  172. return false;
  173. }
  174. if( ValueFromString( m_Frame->GetUserUnits(), viaDrill ) < minViaDrill )
  175. {
  176. msg.Printf( _( "Via drill less than minimum via drill (%s)." ),
  177. StringFromValue( m_Frame->GetUserUnits(), minViaDrill, true, true ) );
  178. m_Parent->SetError( msg, this, m_viaSizesGrid, row, 1 );
  179. return false;
  180. }
  181. if( ValueFromString( m_Frame->GetUserUnits(), viaDrill )
  182. >= ValueFromString( m_Frame->GetUserUnits(), viaDia ) )
  183. {
  184. msg = _( "Via drill larger than via diameter." );
  185. m_Parent->SetError( msg, this, m_viaSizesGrid, row, 1 );
  186. return false;
  187. }
  188. }
  189. return true;
  190. }
  191. void PANEL_SETUP_TRACKS_AND_VIAS::ImportSettingsFrom( BOARD* aBoard )
  192. {
  193. m_trackWidthsGrid->CommitPendingChanges( true );
  194. m_viaSizesGrid->CommitPendingChanges( true );
  195. m_diffPairsGrid->CommitPendingChanges( true );
  196. // Note: do not change the board, as we need to get the current nets from it for
  197. // netclass memberships. All the netclass definitions and dimension lists are in
  198. // the BOARD_DESIGN_SETTINGS.
  199. BOARD_DESIGN_SETTINGS* savedSettings = m_BrdSettings;
  200. m_BrdSettings = &aBoard->GetDesignSettings();
  201. TransferDataToWindow();
  202. m_BrdSettings = savedSettings;
  203. }