KiCad PCB EDA Suite
panel_setup_tracks_and_vias.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 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 
24 
25 #include <base_units.h>
26 #include <pcb_edit_frame.h>
27 #include <board_design_settings.h>
28 #include <bitmaps.h>
29 #include <widgets/wx_grid.h>
30 #include <grid_tricks.h>
31 
33 
34 
36 {
38 };
39 
41 {
44 };
45 
47 {
51 };
52 
53 
55  PCB_EDIT_FRAME* aFrame,
56  PANEL_SETUP_CONSTRAINTS* aConstraintsPanel ) :
57  PANEL_SETUP_TRACKS_AND_VIAS_BASE( aParent->GetTreebook() )
58 {
59  m_Parent = aParent;
60  m_Frame = aFrame;
61  m_Pcb = m_Frame->GetBoard();
63  m_ConstraintsPanel = aConstraintsPanel;
64 
71 
72  // Membership combobox editors require a bit more room, so increase the row size of
73  // all our grids for consistency
74  m_trackWidthsGrid->SetDefaultRowSize( m_trackWidthsGrid->GetDefaultRowSize() + 4 );
75  m_viaSizesGrid->SetDefaultRowSize( m_viaSizesGrid->GetDefaultRowSize() + 4 );
76  m_diffPairsGrid->SetDefaultRowSize( m_diffPairsGrid->GetDefaultRowSize() + 4 );
77 
78  m_trackWidthsGrid->PushEventHandler( new GRID_TRICKS( m_trackWidthsGrid ) );
79  m_viaSizesGrid->PushEventHandler( new GRID_TRICKS( m_viaSizesGrid ) );
80  m_diffPairsGrid->PushEventHandler( new GRID_TRICKS( m_diffPairsGrid ) );
81 
82  m_trackWidthsGrid->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows );
83  m_viaSizesGrid->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows );
84  m_diffPairsGrid->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows );
85 }
86 
88 {
89  // Delete the GRID_TRICKS.
90  m_trackWidthsGrid->PopEventHandler( true );
91  m_viaSizesGrid->PopEventHandler( true );
92  m_diffPairsGrid->PopEventHandler( true );
93 }
94 
96 {
97  if( m_trackWidthsGrid->GetNumberRows() > 0 )
98  m_trackWidthsGrid->DeleteRows( 0, m_trackWidthsGrid->GetNumberRows() );
99 
100  if( m_viaSizesGrid->GetNumberRows() > 0 )
101  m_viaSizesGrid->DeleteRows( 0, m_viaSizesGrid->GetNumberRows() );
102 
103  if( m_diffPairsGrid->GetNumberRows() > 0 )
104  m_diffPairsGrid->DeleteRows( 0, m_diffPairsGrid->GetNumberRows() );
105 
106  // Skip the first item, which is the current netclass value
107  for( unsigned ii = 1; ii < m_BrdSettings->m_TrackWidthList.size(); ii++ )
108  {
110  }
111 
112  // Skip the first item, which is the current netclass value
113  for( unsigned ii = 1; ii < m_BrdSettings->m_ViasDimensionsList.size(); ii++ )
114  {
116  m_BrdSettings->m_ViasDimensionsList[ii].m_Drill );
117  }
118 
119  // Skip the first item, which is the current netclass value
120  for( unsigned ii = 1; ii < m_BrdSettings->m_DiffPairDimensionsList.size(); ii++ )
121  {
124  m_BrdSettings->m_DiffPairDimensionsList[ii].m_ViaGap );
125  }
126 
127  return true;
128 }
129 
130 
132 {
136  {
137  return false;
138  }
139 
140  wxString msg;
141  std::vector<int> trackWidths;
142  std::vector<VIA_DIMENSION> vias;
143  std::vector<DIFF_PAIR_DIMENSION> diffPairs;
144 
148  {
149  return false;
150  }
151 
152  // Test ONLY for malformed data. Design rules and constraints are the business of DRC.
153 
154  for( int row = 0; row < m_trackWidthsGrid->GetNumberRows(); ++row )
155  {
156  msg = m_trackWidthsGrid->GetCellValue( row, TR_WIDTH_COL );
157 
158  if( !msg.IsEmpty() )
159  trackWidths.push_back( ValueFromString( m_Frame->GetUserUnits(), msg ) );
160  }
161 
162  for( int row = 0; row < m_viaSizesGrid->GetNumberRows(); ++row )
163  {
164  msg = m_viaSizesGrid->GetCellValue( row, VIA_SIZE_COL );
165 
166  if( !msg.IsEmpty() )
167  {
168  VIA_DIMENSION via_dim;
169  via_dim.m_Diameter = ValueFromString( m_Frame->GetUserUnits(), msg );
170 
171  msg = m_viaSizesGrid->GetCellValue( row, VIA_DRILL_COL );
172 
173  if( !msg.IsEmpty() )
174  via_dim.m_Drill = ValueFromString( m_Frame->GetUserUnits(), msg );
175 
176  vias.push_back( via_dim );
177  }
178  }
179 
180  for( int row = 0; row < m_diffPairsGrid->GetNumberRows(); ++row )
181  {
182  msg = m_diffPairsGrid->GetCellValue( row, DP_WIDTH_COL );
183 
184  if( !msg.IsEmpty() )
185  {
186  DIFF_PAIR_DIMENSION diffPair_dim;
187  diffPair_dim.m_Width = ValueFromString( m_Frame->GetUserUnits(), msg );
188 
189  msg = m_diffPairsGrid->GetCellValue( row, DP_GAP_COL );
190  diffPair_dim.m_Gap = ValueFromString( m_Frame->GetUserUnits(), msg );
191 
192  msg = m_diffPairsGrid->GetCellValue( row, DP_VIA_GAP_COL );
193 
194  if( !msg.IsEmpty() )
195  diffPair_dim.m_ViaGap = ValueFromString( m_Frame->GetUserUnits(), msg );
196 
197  diffPairs.push_back( diffPair_dim );
198  }
199  }
200 
201  // Sort lists by increasing value
202  sort( trackWidths.begin(), trackWidths.end() );
203  sort( vias.begin(), vias.end() );
204  sort( diffPairs.begin(), diffPairs.end() );
205 
206  // These are all stored in project file, not board, so no need for OnModify()
207 
208  trackWidths.insert( trackWidths.begin(), 0 ); // dummy value for "use netclass"
209  m_BrdSettings->m_TrackWidthList = trackWidths;
210 
211  vias.insert( vias.begin(), { 0, 0 } ); // dummy value for "use netclass"
213 
214  diffPairs.insert( diffPairs.begin(), { 0, 0, 0 } ); // dummy value for "use netclass"
216 
217  return true;
218 }
219 
220 
222 {
226  {
227  return false;
228  }
229 
230  wxString msg;
231 
232  // Test vias
233  for( int row = 0; row < m_viaSizesGrid->GetNumberRows(); ++row )
234  {
235  wxString viaDia = m_viaSizesGrid->GetCellValue( row, VIA_SIZE_COL );
236  wxString viaDrill = m_viaSizesGrid->GetCellValue( row, VIA_DRILL_COL );
237 
238  if( !viaDia.IsEmpty() && viaDrill.IsEmpty() )
239  {
240  msg = _( "No via hole size defined." );
241  m_Parent->SetError( msg, this, m_viaSizesGrid, row, VIA_DRILL_COL );
242  return false;
243  }
244 
245  }
246 
247  // Test diff pairs
248  for( int row = 0; row < m_diffPairsGrid->GetNumberRows(); ++row )
249  {
250  wxString dpWidth = m_diffPairsGrid->GetCellValue( row, 0 );
251  wxString dpGap = m_diffPairsGrid->GetCellValue( row, 1 );
252 
253  if( !dpWidth.IsEmpty() && dpGap.IsEmpty() )
254  {
255  msg = _( "No differential pair gap defined." );
256  m_Parent->SetError( msg, this, m_diffPairsGrid, row, 1 );
257  return false;
258  }
259  }
260 
261  return true;
262 }
263 
264 
266 {
267  int i = m_trackWidthsGrid->GetNumberRows();
268 
269  m_trackWidthsGrid->AppendRows( 1 );
270 
271  wxString val = StringFromValue( m_Frame->GetUserUnits(), aWidth );
272  m_trackWidthsGrid->SetCellValue( i, TR_WIDTH_COL, val );
273 }
274 
275 
276 void PANEL_SETUP_TRACKS_AND_VIAS::AppendViaSize( const int aSize, const int aDrill )
277 {
278  int i = m_viaSizesGrid->GetNumberRows();
279 
280  m_viaSizesGrid->AppendRows( 1 );
281 
282  wxString val = StringFromValue( m_Frame->GetUserUnits(), aSize );
283  m_viaSizesGrid->SetCellValue( i, VIA_SIZE_COL, val );
284 
285  if( aDrill > 0 )
286  {
287  val = StringFromValue( m_Frame->GetUserUnits(), aDrill );
288  m_viaSizesGrid->SetCellValue( i, VIA_DRILL_COL, val );
289  }
290 }
291 
292 
293 void PANEL_SETUP_TRACKS_AND_VIAS::AppendDiffPairs( const int aWidth, const int aGap,
294  const int aViaGap )
295 {
296  int i = m_diffPairsGrid->GetNumberRows();
297 
298  m_diffPairsGrid->AppendRows( 1 );
299 
300  wxString val = StringFromValue( m_Frame->GetUserUnits(), aWidth );
301  m_diffPairsGrid->SetCellValue( i, DP_WIDTH_COL, val );
302 
303  if( aGap > 0 )
304  {
305  val = StringFromValue( m_Frame->GetUserUnits(), aGap );
306  m_diffPairsGrid->SetCellValue( i, DP_GAP_COL, val );
307  }
308 
309  if( aViaGap > 0 )
310  {
311  val = StringFromValue( m_Frame->GetUserUnits(), aViaGap );
312  m_diffPairsGrid->SetCellValue( i, DP_VIA_GAP_COL, val );
313  }
314 }
315 
317 {
318  AppendTrackWidth( 0 );
319 
320  m_trackWidthsGrid->MakeCellVisible( m_trackWidthsGrid->GetNumberRows() - 1, TR_WIDTH_COL );
321  m_trackWidthsGrid->SetGridCursor( m_trackWidthsGrid->GetNumberRows() - 1, TR_WIDTH_COL );
322 
323  m_trackWidthsGrid->EnableCellEditControl( true );
324  m_trackWidthsGrid->ShowCellEditControl();
325 }
326 
327 
329 {
330  int curRow = m_trackWidthsGrid->GetGridCursorRow();
331 
332  if( curRow < 0 || m_trackWidthsGrid->GetNumberRows() <= curRow )
333  return;
334 
335  m_trackWidthsGrid->DeleteRows( curRow, 1 );
336 
337  curRow = std::max( 0, curRow - 1 );
338  m_trackWidthsGrid->MakeCellVisible( curRow, m_trackWidthsGrid->GetGridCursorCol() );
339  m_trackWidthsGrid->SetGridCursor( curRow, m_trackWidthsGrid->GetGridCursorCol() );
340 }
341 
342 
344 {
345  AppendViaSize( 0, 0 );
346 
347  m_viaSizesGrid->MakeCellVisible( m_viaSizesGrid->GetNumberRows() - 1, VIA_SIZE_COL );
348  m_viaSizesGrid->SetGridCursor( m_viaSizesGrid->GetNumberRows() - 1, VIA_SIZE_COL );
349 
350  m_viaSizesGrid->EnableCellEditControl( true );
351  m_viaSizesGrid->ShowCellEditControl();
352 }
353 
354 
356 {
357  int curRow = m_viaSizesGrid->GetGridCursorRow();
358 
359  if( curRow < 0 || m_viaSizesGrid->GetNumberRows() <= curRow )
360  return;
361 
362  m_viaSizesGrid->DeleteRows( curRow, 1 );
363 
364  curRow = std::max( 0, curRow - 1 );
365  m_viaSizesGrid->MakeCellVisible( curRow, m_viaSizesGrid->GetGridCursorCol() );
366  m_viaSizesGrid->SetGridCursor( curRow, m_viaSizesGrid->GetGridCursorCol() );
367 }
368 
369 
371 {
372  AppendDiffPairs( 0, 0, 0 );
373 
374  m_diffPairsGrid->MakeCellVisible( m_diffPairsGrid->GetNumberRows() - 1, DP_WIDTH_COL );
375  m_diffPairsGrid->SetGridCursor( m_diffPairsGrid->GetNumberRows() - 1, DP_WIDTH_COL );
376 
377  m_diffPairsGrid->EnableCellEditControl( true );
378  m_diffPairsGrid->ShowCellEditControl();
379 }
380 
381 
383 {
384  int curRow = m_diffPairsGrid->GetGridCursorRow();
385 
386  if( curRow < 0 || m_diffPairsGrid->GetNumberRows() <= curRow )
387  return;
388 
389  m_diffPairsGrid->DeleteRows( curRow, 1 );
390 
391  curRow = std::max( 0, curRow - 1 );
392  m_diffPairsGrid->MakeCellVisible( curRow, m_diffPairsGrid->GetGridCursorCol() );
393  m_diffPairsGrid->SetGridCursor( curRow, m_diffPairsGrid->GetGridCursorCol() );
394 }
395 
396 
398 {
402 
403  // Note: do not change the board, as we need to get the current nets from it for
404  // netclass memberships. All the netclass definitions and dimension lists are in
405  // the BOARD_DESIGN_SETTINGS.
406 
407  BOARD_DESIGN_SETTINGS* savedSettings = m_BrdSettings;
408 
409  m_BrdSettings = &aBoard->GetDesignSettings();
411 
412  m_BrdSettings = savedSettings;
413 }
414 
Container to handle a stock of specific vias each with unique diameter and drill sizes in the BOARD c...
void OnRemoveViaSizesClick(wxCommandEvent &event) override
Implementation of conversion functions that require both schematic and board internal units.
std::vector< int > m_TrackWidthList
std::vector< DIFF_PAIR_DIMENSION > m_DiffPairDimensionsList
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:52
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:593
void SetError(const wxString &aMessage, const wxString &aPageName, int aCtrlId, int aRow=-1, int aCol=-1)
Container to handle a stock of specific differential pairs each with unique track width,...
void OnAddDiffPairsClick(wxCommandEvent &event) override
long long int ValueFromString(EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType)
Function ValueFromString converts aTextValue in aUnits to internal units used by the application.
Definition: base_units.cpp:402
PANEL_SETUP_TRACKS_AND_VIAS(PAGED_DIALOG *aParent, PCB_EDIT_FRAME *aFrame, PANEL_SETUP_CONSTRAINTS *aConstraintsPanel)
void OnRemoveDiffPairsClick(wxCommandEvent &event) override
void OnAddViaSizesClick(wxCommandEvent &event) override
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:182
void AppendViaSize(const int aSize, const int aDrill)
PANEL_SETUP_CONSTRAINTS * m_ConstraintsPanel
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
#define _(s)
Definition: 3d_actions.cpp:33
void OnAddTrackWidthsClick(wxCommandEvent &event) override
The main frame for Pcbnew.
std::vector< VIA_DIMENSION > m_ViasDimensionsList
wxString StringFromValue(EDA_UNITS aUnits, double aValue, bool aAddUnitSymbol, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:190
Class PANEL_SETUP_TRACKS_AND_VIAS_BASE.
void OnRemoveTrackWidthsClick(wxCommandEvent &event) override
BOARD * GetBoard() const
void AppendDiffPairs(const int aWidth, const int aGap, const int aViaGap)
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
Container for design settings for a BOARD object.
wxBitmap KiBitmap(BITMAPS aBitmap)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104