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.

716 lines
24 KiB

9 years ago
9 years ago
9 years ago
9 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015 CERN
  5. * Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
  6. * @author Maciej Suminski <maciej.suminski@cern.ch>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. #include <core/kicad_algo.h>
  26. #include <dialogs/dialog_track_via_properties.h>
  27. #include <pcb_layer_box_selector.h>
  28. #include <tools/pcb_selection_tool.h>
  29. #include <board_design_settings.h>
  30. #include <footprint.h>
  31. #include <pad.h>
  32. #include <pcb_track.h>
  33. #include <pcb_edit_frame.h>
  34. #include <confirm.h>
  35. #include <connectivity/connectivity_data.h>
  36. #include <board_commit.h>
  37. #include <macros.h>
  38. DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParent,
  39. const PCB_SELECTION& aItems,
  40. COMMIT& aCommit ) :
  41. DIALOG_TRACK_VIA_PROPERTIES_BASE( aParent ),
  42. m_frame( aParent ),
  43. m_items( aItems ),
  44. m_commit( aCommit ),
  45. m_trackStartX( aParent, m_TrackStartXLabel, m_TrackStartXCtrl, m_TrackStartXUnit ),
  46. m_trackStartY( aParent, m_TrackStartYLabel, m_TrackStartYCtrl, m_TrackStartYUnit ),
  47. m_trackEndX( aParent, m_TrackEndXLabel, m_TrackEndXCtrl, m_TrackEndXUnit ),
  48. m_trackEndY( aParent, m_TrackEndYLabel, m_TrackEndYCtrl, m_TrackEndYUnit ),
  49. m_trackWidth( aParent, m_TrackWidthLabel, m_TrackWidthCtrl, m_TrackWidthUnit ),
  50. m_viaX( aParent, m_ViaXLabel, m_ViaXCtrl, m_ViaXUnit ),
  51. m_viaY( aParent, m_ViaYLabel, m_ViaYCtrl, m_ViaYUnit ),
  52. m_viaDiameter( aParent, m_ViaDiameterLabel, m_ViaDiameterCtrl, m_ViaDiameterUnit ),
  53. m_viaDrill( aParent, m_ViaDrillLabel, m_ViaDrillCtrl, m_ViaDrillUnit ),
  54. m_tracks( false ),
  55. m_vias( false )
  56. {
  57. m_useCalculatedSize = true;
  58. wxASSERT( !m_items.Empty() );
  59. // Configure display origin transforms
  60. m_trackStartX.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
  61. m_trackStartY.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
  62. m_trackEndX.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
  63. m_trackEndY.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
  64. m_viaX.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
  65. m_viaY.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
  66. VIATYPE viaType = VIATYPE::NOT_DEFINED;
  67. m_TrackLayerCtrl->SetLayersHotkeys( false );
  68. m_TrackLayerCtrl->SetNotAllowedLayerSet( LSET::AllNonCuMask() );
  69. m_TrackLayerCtrl->SetBoardFrame( aParent );
  70. m_TrackLayerCtrl->Resync();
  71. m_ViaStartLayer->SetLayersHotkeys( false );
  72. m_ViaStartLayer->SetNotAllowedLayerSet( LSET::AllNonCuMask() );
  73. m_ViaStartLayer->SetBoardFrame( aParent );
  74. m_ViaStartLayer->Resync();
  75. m_ViaEndLayer->SetLayersHotkeys( false );
  76. m_ViaEndLayer->SetNotAllowedLayerSet( LSET::AllNonCuMask() );
  77. m_ViaEndLayer->SetBoardFrame( aParent );
  78. m_ViaEndLayer->Resync();
  79. bool nets = false;
  80. int net = 0;
  81. bool hasLocked = false;
  82. bool hasUnlocked = false;
  83. auto getAnnularRingSelection =
  84. []( const PCB_VIA* via ) -> int
  85. {
  86. if( !via->GetRemoveUnconnected() )
  87. return 0;
  88. else if( via->GetKeepTopBottom() )
  89. return 1;
  90. else
  91. return 2;
  92. };
  93. // Look for values that are common for every item that is selected
  94. for( EDA_ITEM* item : m_items )
  95. {
  96. if( !nets )
  97. {
  98. net = static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetCode();
  99. nets = true;
  100. }
  101. else if( net != static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetCode() )
  102. {
  103. net = -1;
  104. }
  105. switch( item->Type() )
  106. {
  107. case PCB_TRACE_T:
  108. case PCB_ARC_T:
  109. {
  110. const PCB_TRACK* t = static_cast<const PCB_TRACK*>( item );
  111. if( !m_tracks ) // first track in the list
  112. {
  113. m_trackStartX.SetValue( t->GetStart().x );
  114. m_trackStartY.SetValue( t->GetStart().y );
  115. m_trackEndX.SetValue( t->GetEnd().x );
  116. m_trackEndY.SetValue( t->GetEnd().y );
  117. m_trackWidth.SetValue( t->GetWidth() );
  118. m_TrackLayerCtrl->SetLayerSelection( t->GetLayer() );
  119. m_tracks = true;
  120. }
  121. else // check if values are the same for every selected track
  122. {
  123. if( m_trackStartX.GetValue() != t->GetStart().x )
  124. m_trackStartX.SetValue( INDETERMINATE_STATE );
  125. if( m_trackStartY.GetValue() != t->GetStart().y )
  126. m_trackStartY.SetValue( INDETERMINATE_STATE );
  127. if( m_trackEndX.GetValue() != t->GetEnd().x )
  128. m_trackEndX.SetValue( INDETERMINATE_STATE );
  129. if( m_trackEndY.GetValue() != t->GetEnd().y )
  130. m_trackEndY.SetValue( INDETERMINATE_STATE );
  131. if( m_trackWidth.GetValue() != t->GetWidth() )
  132. m_trackWidth.SetValue( INDETERMINATE_STATE );
  133. if( m_TrackLayerCtrl->GetLayerSelection() != t->GetLayer() )
  134. {
  135. m_TrackLayerCtrl->SetUndefinedLayerName( INDETERMINATE_STATE );
  136. m_TrackLayerCtrl->Resync();
  137. m_TrackLayerCtrl->SetLayerSelection( UNDEFINED_LAYER );
  138. }
  139. }
  140. if( t->IsLocked() )
  141. hasLocked = true;
  142. else
  143. hasUnlocked = true;
  144. break;
  145. }
  146. case PCB_VIA_T:
  147. {
  148. const PCB_VIA* v = static_cast<const PCB_VIA*>( item );
  149. if( !m_vias ) // first via in the list
  150. {
  151. m_viaX.SetValue( v->GetPosition().x );
  152. m_viaY.SetValue( v->GetPosition().y );
  153. m_viaDiameter.SetValue( v->GetWidth() );
  154. m_viaDrill.SetValue( v->GetDrillValue() );
  155. m_vias = true;
  156. viaType = v->GetViaType();
  157. m_ViaStartLayer->SetLayerSelection( v->TopLayer() );
  158. m_ViaEndLayer->SetLayerSelection( v->BottomLayer() );
  159. m_viaNotFree->SetValue( !v->GetIsFree() );
  160. m_annularRingsCtrl->SetSelection( getAnnularRingSelection( v ) );
  161. }
  162. else // check if values are the same for every selected via
  163. {
  164. if( m_viaX.GetValue() != v->GetPosition().x )
  165. m_viaX.SetValue( INDETERMINATE_STATE );
  166. if( m_viaY.GetValue() != v->GetPosition().y )
  167. m_viaY.SetValue( INDETERMINATE_STATE );
  168. if( m_viaDiameter.GetValue() != v->GetWidth() )
  169. m_viaDiameter.SetValue( INDETERMINATE_STATE );
  170. if( m_viaDrill.GetValue() != v->GetDrillValue() )
  171. m_viaDrill.SetValue( INDETERMINATE_STATE );
  172. if( viaType != v->GetViaType() )
  173. viaType = VIATYPE::NOT_DEFINED;
  174. if( v->GetIsFree() != !m_viaNotFree->GetValue() )
  175. m_viaNotFree->Set3StateValue( wxCHK_UNDETERMINED );
  176. if( m_ViaStartLayer->GetLayerSelection() != v->TopLayer() )
  177. {
  178. m_ViaStartLayer->SetUndefinedLayerName( INDETERMINATE_STATE );
  179. m_ViaStartLayer->Resync();
  180. m_ViaStartLayer->SetLayerSelection( UNDEFINED_LAYER );
  181. }
  182. if( m_ViaEndLayer->GetLayerSelection() != v->BottomLayer() )
  183. {
  184. m_ViaEndLayer->SetUndefinedLayerName( INDETERMINATE_STATE );
  185. m_ViaEndLayer->Resync();
  186. m_ViaEndLayer->SetLayerSelection( UNDEFINED_LAYER );
  187. }
  188. if( m_annularRingsCtrl->GetSelection() != getAnnularRingSelection( v ) )
  189. {
  190. if( m_annularRingsCtrl->GetStrings().size() < 4 )
  191. m_annularRingsCtrl->AppendString( INDETERMINATE_STATE );
  192. m_annularRingsCtrl->SetSelection( 3 );
  193. }
  194. }
  195. if( v->IsLocked() )
  196. hasLocked = true;
  197. else
  198. hasUnlocked = true;
  199. break;
  200. }
  201. default:
  202. {
  203. wxASSERT( false );
  204. break;
  205. }
  206. }
  207. }
  208. m_netSelector->SetBoard( aParent->GetBoard() );
  209. m_netSelector->SetNetInfo( &aParent->GetBoard()->GetNetInfo() );
  210. if ( net >= 0 )
  211. {
  212. m_netSelector->SetSelectedNetcode( net );
  213. }
  214. else
  215. {
  216. m_netSelector->SetIndeterminateString( INDETERMINATE_STATE );
  217. m_netSelector->SetIndeterminate();
  218. }
  219. wxASSERT( m_tracks || m_vias );
  220. if( m_vias )
  221. {
  222. if( m_viaNotFree->GetValue() )
  223. {
  224. m_netSelectorLabel->Disable();
  225. m_netSelector->Disable();
  226. }
  227. m_DesignRuleViasUnit->SetLabel( GetAbbreviatedUnitsLabel( m_units ) );
  228. int viaSelection = wxNOT_FOUND;
  229. // 0 is the netclass place-holder
  230. for( unsigned ii = 1; ii < aParent->GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
  231. {
  232. VIA_DIMENSION* viaDimension = &aParent->GetDesignSettings().m_ViasDimensionsList[ii];
  233. wxString msg = StringFromValue( m_units, viaDimension->m_Diameter, false )
  234. + " / " + StringFromValue( m_units, viaDimension->m_Drill, false );
  235. m_DesignRuleViasCtrl->Append( msg, viaDimension );
  236. if( viaSelection == wxNOT_FOUND
  237. && m_viaDiameter.GetValue() == viaDimension->m_Diameter
  238. && m_viaDrill.GetValue() == viaDimension->m_Drill )
  239. {
  240. viaSelection = ii;
  241. }
  242. }
  243. m_DesignRuleViasCtrl->SetSelection( viaSelection );
  244. SetInitialFocus( m_ViaDiameterCtrl );
  245. m_ViaTypeChoice->Enable();
  246. switch( viaType )
  247. {
  248. case VIATYPE::THROUGH: m_ViaTypeChoice->SetSelection( 0 ); break;
  249. case VIATYPE::MICROVIA: m_ViaTypeChoice->SetSelection( 1 ); break;
  250. case VIATYPE::BLIND_BURIED: m_ViaTypeChoice->SetSelection( 2 ); break;
  251. case VIATYPE::NOT_DEFINED: m_ViaTypeChoice->SetSelection( wxNOT_FOUND ); break;
  252. }
  253. m_ViaStartLayer->Enable( viaType != VIATYPE::THROUGH );
  254. m_ViaEndLayer->Enable( viaType != VIATYPE::THROUGH );
  255. }
  256. else
  257. {
  258. m_viaNotFree->Hide();
  259. m_MainSizer->Hide( m_sbViaSizer, true );
  260. }
  261. if( m_tracks )
  262. {
  263. m_DesignRuleWidthsUnits->SetLabel( GetAbbreviatedUnitsLabel( m_units ) );
  264. int widthSelection = wxNOT_FOUND;
  265. // 0 is the netclass place-holder
  266. for( unsigned ii = 1; ii < aParent->GetDesignSettings().m_TrackWidthList.size(); ii++ )
  267. {
  268. int width = aParent->GetDesignSettings().m_TrackWidthList[ii];
  269. wxString msg = StringFromValue( m_units, width, false );
  270. m_DesignRuleWidthsCtrl->Append( msg );
  271. if( widthSelection == wxNOT_FOUND && m_trackWidth.GetValue() == width )
  272. widthSelection = ii - 1;
  273. }
  274. m_DesignRuleWidthsCtrl->SetSelection( widthSelection );
  275. SetInitialFocus( m_TrackWidthCtrl );
  276. }
  277. else
  278. {
  279. m_MainSizer->Hide( m_sbTrackSizer, true );
  280. }
  281. if( hasLocked && hasUnlocked )
  282. m_lockedCbox->Set3StateValue( wxCHK_UNDETERMINED );
  283. else if( hasLocked )
  284. m_lockedCbox->Set3StateValue( wxCHK_CHECKED );
  285. else
  286. m_lockedCbox->Set3StateValue( wxCHK_UNCHECKED );
  287. SetInitialFocus( m_tracks ? m_TrackWidthCtrl : m_ViaDiameterCtrl );
  288. m_StdButtonsOK->SetDefault();
  289. // Now all widgets have the size fixed, call FinishDialogSettings
  290. finishDialogSettings();
  291. }
  292. bool DIALOG_TRACK_VIA_PROPERTIES::confirmPadChange( const std::vector<PAD*>& changingPads )
  293. {
  294. wxString msg;
  295. if( changingPads.size() == 1 )
  296. {
  297. PAD* pad = *changingPads.begin();
  298. msg.Printf( _( "Changing the net will also update %s pad %s to %s." ),
  299. pad->GetParent()->GetReference(),
  300. pad->GetNumber(),
  301. m_netSelector->GetValue() );
  302. }
  303. else if( changingPads.size() == 2 )
  304. {
  305. PAD* pad1 = *changingPads.begin();
  306. PAD* pad2 = *( ++changingPads.begin() );
  307. msg.Printf( _( "Changing the net will also update %s pad %s and %s pad %s to %s." ),
  308. pad1->GetParent()->GetReference(),
  309. pad1->GetNumber(),
  310. pad2->GetParent()->GetReference(),
  311. pad2->GetNumber(),
  312. m_netSelector->GetValue() );
  313. }
  314. else
  315. {
  316. msg.Printf( _( "Changing the net will also update %lu connected pads to %s." ),
  317. static_cast<unsigned long>( changingPads.size() ),
  318. m_netSelector->GetValue() );
  319. }
  320. KIDIALOG dlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
  321. dlg.SetOKCancelLabels( _( "Change Nets" ), _( "Leave Nets Unchanged" ) );
  322. dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
  323. return dlg.ShowModal() == wxID_OK;
  324. }
  325. bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow()
  326. {
  327. // Run validations:
  328. if( m_vias )
  329. {
  330. if( !m_viaDiameter.Validate( GEOMETRY_MIN_SIZE, INT_MAX )
  331. || !m_viaDrill.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
  332. return false;
  333. if( m_ViaDiameterCtrl->IsEnabled() && !m_viaDiameter.IsIndeterminate()
  334. && m_ViaDrillCtrl->IsEnabled() && !m_viaDrill.IsIndeterminate()
  335. && m_viaDiameter.GetValue() <= m_viaDrill.GetValue() )
  336. {
  337. DisplayError( GetParent(), _( "Via hole size must be smaller than via diameter" ) );
  338. m_ViaDrillCtrl->SelectAll();
  339. m_ViaDrillCtrl->SetFocus();
  340. return false;
  341. }
  342. if( m_ViaStartLayer->GetLayerSelection() != UNDEFINED_LAYER &&
  343. m_ViaStartLayer->GetLayerSelection() == m_ViaEndLayer->GetLayerSelection() )
  344. {
  345. DisplayError( GetParent(), _( "Via start layer and end layer cannot be the same" ) );
  346. return false;
  347. }
  348. }
  349. if( m_tracks )
  350. {
  351. if( !m_trackWidth.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
  352. return false;
  353. }
  354. // If we survived that, then save the changes:
  355. //
  356. // We don't bother with updating the nets at this point as it will be useless (any connected
  357. // pads will simply drive their existing nets back onto the track segments and vias).
  358. bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED;
  359. bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED;
  360. for( EDA_ITEM* item : m_items )
  361. {
  362. m_commit.Modify( item );
  363. switch( item->Type() )
  364. {
  365. case PCB_TRACE_T:
  366. case PCB_ARC_T:
  367. {
  368. wxASSERT( m_tracks );
  369. PCB_TRACK* t = static_cast<PCB_TRACK*>( item );
  370. if( !m_trackStartX.IsIndeterminate() )
  371. t->SetStart( wxPoint( m_trackStartX.GetValue(), t->GetStart().y ) );
  372. if( !m_trackStartY.IsIndeterminate() )
  373. t->SetStart( wxPoint( t->GetStart().x, m_trackStartY.GetValue() ) );
  374. if( !m_trackEndX.IsIndeterminate() )
  375. t->SetEnd( wxPoint( m_trackEndX.GetValue(), t->GetEnd().y ) );
  376. if( !m_trackEndY.IsIndeterminate() )
  377. t->SetEnd( wxPoint( t->GetEnd().x, m_trackEndY.GetValue() ) );
  378. if( m_trackNetclass->IsChecked() )
  379. t->SetWidth( t->GetNetClass()->GetTrackWidth() );
  380. else if( !m_trackWidth.IsIndeterminate() )
  381. t->SetWidth( m_trackWidth.GetValue() );
  382. LAYER_NUM layer = m_TrackLayerCtrl->GetLayerSelection();
  383. if( layer != UNDEFINED_LAYER )
  384. t->SetLayer( (PCB_LAYER_ID) layer );
  385. if( changeLock )
  386. t->SetLocked( setLock );
  387. break;
  388. }
  389. case PCB_VIA_T:
  390. {
  391. wxASSERT( m_vias );
  392. PCB_VIA* v = static_cast<PCB_VIA*>( item );
  393. if( !m_viaX.IsIndeterminate() )
  394. v->SetPosition( wxPoint( m_viaX.GetValue(), v->GetPosition().y ) );
  395. if( !m_viaY.IsIndeterminate() )
  396. v->SetPosition( wxPoint( v->GetPosition().x, m_viaY.GetValue() ) );
  397. if( m_viaNotFree->Get3StateValue() != wxCHK_UNDETERMINED )
  398. v->SetIsFree( !m_viaNotFree->GetValue() );
  399. switch( m_ViaTypeChoice->GetSelection() )
  400. {
  401. case 0:
  402. v->SetViaType( VIATYPE::THROUGH );
  403. v->SanitizeLayers();
  404. break;
  405. case 1:
  406. v->SetViaType( VIATYPE::MICROVIA );
  407. break;
  408. case 2:
  409. v->SetViaType( VIATYPE::BLIND_BURIED );
  410. break;
  411. default:
  412. break;
  413. }
  414. auto startLayer = static_cast<PCB_LAYER_ID>( m_ViaStartLayer->GetLayerSelection() );
  415. auto endLayer = static_cast<PCB_LAYER_ID>( m_ViaEndLayer->GetLayerSelection() );
  416. if (startLayer != UNDEFINED_LAYER )
  417. v->SetTopLayer( startLayer );
  418. if (endLayer != UNDEFINED_LAYER )
  419. v->SetBottomLayer( endLayer );
  420. switch( m_annularRingsCtrl->GetSelection() )
  421. {
  422. case 0:
  423. v->SetRemoveUnconnected( false );
  424. break;
  425. case 1:
  426. v->SetRemoveUnconnected( true );
  427. v->SetKeepTopBottom( true );
  428. break;
  429. case 2:
  430. v->SetRemoveUnconnected( true );
  431. v->SetKeepTopBottom( false );
  432. break;
  433. default:
  434. break;
  435. }
  436. v->SanitizeLayers();
  437. if( m_viaNetclass->IsChecked() )
  438. {
  439. switch( v->GetViaType() )
  440. {
  441. default:
  442. wxFAIL_MSG( "Unhandled via type" );
  443. KI_FALLTHROUGH;
  444. case VIATYPE::THROUGH:
  445. case VIATYPE::BLIND_BURIED:
  446. v->SetWidth( v->GetNetClass()->GetViaDiameter() );
  447. v->SetDrill( v->GetNetClass()->GetViaDrill() );
  448. break;
  449. case VIATYPE::MICROVIA:
  450. v->SetWidth( v->GetNetClass()->GetuViaDiameter() );
  451. v->SetDrill( v->GetNetClass()->GetuViaDrill() );
  452. break;
  453. }
  454. }
  455. else
  456. {
  457. if( !m_viaDiameter.IsIndeterminate() )
  458. v->SetWidth( m_viaDiameter.GetValue() );
  459. if( !m_viaDrill.IsIndeterminate() )
  460. v->SetDrill( m_viaDrill.GetValue() );
  461. }
  462. if( changeLock )
  463. v->SetLocked( setLock );
  464. break;
  465. }
  466. default:
  467. wxASSERT( false );
  468. break;
  469. }
  470. }
  471. m_commit.Push( _( "Edit track/via properties" ) );
  472. // Pushing the commit will have updated the connectivity so we can now test to see if we
  473. // need to update any pad nets.
  474. auto connectivity = m_frame->GetBoard()->GetConnectivity();
  475. int newNetCode = m_netSelector->GetSelectedNetcode();
  476. bool updateNets = false;
  477. std::vector<PAD*> changingPads;
  478. if ( !m_netSelector->IsIndeterminate() )
  479. {
  480. updateNets = true;
  481. for( EDA_ITEM* item : m_items )
  482. {
  483. const KICAD_T ourTypes[] = { PCB_TRACE_T, PCB_PAD_T, PCB_VIA_T, PCB_FOOTPRINT_T, EOT };
  484. BOARD_CONNECTED_ITEM* boardItem = static_cast<BOARD_CONNECTED_ITEM*>( item );
  485. auto connectedItems = connectivity->GetConnectedItems( boardItem, ourTypes, true );
  486. for ( BOARD_CONNECTED_ITEM* citem : connectedItems )
  487. {
  488. if( citem->Type() == PCB_PAD_T )
  489. {
  490. PAD* pad = static_cast<PAD*>( citem );
  491. if( pad->GetNetCode() != newNetCode && !alg::contains( changingPads, citem ) )
  492. changingPads.push_back( pad );
  493. }
  494. }
  495. }
  496. }
  497. if( changingPads.size() && !confirmPadChange( changingPads ) )
  498. updateNets = false;
  499. if( updateNets )
  500. {
  501. for( EDA_ITEM* item : m_items )
  502. {
  503. m_commit.Modify( item );
  504. switch( item->Type() )
  505. {
  506. case PCB_TRACE_T:
  507. case PCB_ARC_T:
  508. static_cast<PCB_TRACK*>( item )->SetNetCode( newNetCode );
  509. break;
  510. case PCB_VIA_T:
  511. static_cast<PCB_VIA*>( item )->SetNetCode( newNetCode );
  512. break;
  513. default:
  514. wxASSERT( false );
  515. break;
  516. }
  517. }
  518. for( PAD* pad : changingPads )
  519. {
  520. m_commit.Modify( pad );
  521. pad->SetNetCode( newNetCode );
  522. }
  523. m_commit.Push( _( "Updating nets" ) );
  524. }
  525. return true;
  526. }
  527. void DIALOG_TRACK_VIA_PROPERTIES::onViaNotFreeClicked( wxCommandEvent& event )
  528. {
  529. m_netSelectorLabel->Enable( !m_viaNotFree->GetValue() );
  530. m_netSelector->Enable( !m_viaNotFree->GetValue() );
  531. }
  532. void DIALOG_TRACK_VIA_PROPERTIES::onTrackNetclassCheck( wxCommandEvent& aEvent )
  533. {
  534. bool enableNC = aEvent.IsChecked();
  535. m_DesignRuleWidths->Enable( !enableNC );
  536. m_DesignRuleWidthsCtrl->Enable( !enableNC );
  537. m_DesignRuleWidthsUnits->Enable( !enableNC );
  538. m_trackWidth.Enable( !enableNC );
  539. }
  540. void DIALOG_TRACK_VIA_PROPERTIES::onWidthSelect( wxCommandEvent& aEvent )
  541. {
  542. m_TrackWidthCtrl->ChangeValue( m_DesignRuleWidthsCtrl->GetStringSelection() );
  543. m_TrackWidthCtrl->SelectAll();
  544. }
  545. void DIALOG_TRACK_VIA_PROPERTIES::onWidthEdit( wxCommandEvent& aEvent )
  546. {
  547. m_DesignRuleWidthsCtrl->SetStringSelection( m_TrackWidthCtrl->GetValue() );
  548. }
  549. void DIALOG_TRACK_VIA_PROPERTIES::onViaNetclassCheck( wxCommandEvent& aEvent )
  550. {
  551. bool enableNC = aEvent.IsChecked();
  552. m_DesignRuleVias->Enable( !enableNC );
  553. m_DesignRuleViasCtrl->Enable( !enableNC );
  554. m_DesignRuleViasUnit->Enable( !enableNC );
  555. m_viaDiameter.Enable( !enableNC );
  556. m_viaDrill.Enable( !enableNC );
  557. }
  558. void DIALOG_TRACK_VIA_PROPERTIES::onViaSelect( wxCommandEvent& aEvent )
  559. {
  560. VIA_DIMENSION* viaDimension = static_cast<VIA_DIMENSION*> ( aEvent.GetClientData() );
  561. m_viaDiameter.ChangeValue( viaDimension->m_Diameter );
  562. m_viaDrill.ChangeValue( viaDimension->m_Drill );
  563. }
  564. void DIALOG_TRACK_VIA_PROPERTIES::onViaEdit( wxCommandEvent& aEvent )
  565. {
  566. m_DesignRuleViasCtrl->SetSelection( wxNOT_FOUND );
  567. if( m_vias )
  568. {
  569. if( m_ViaTypeChoice->GetSelection() != 0 ) // check if selected type isn't through.
  570. {
  571. m_ViaStartLayer->Enable();
  572. m_ViaEndLayer->Enable();
  573. }
  574. else
  575. {
  576. m_ViaStartLayer->SetLayerSelection( F_Cu );
  577. m_ViaEndLayer->SetLayerSelection( B_Cu );
  578. m_ViaStartLayer->Enable( false );
  579. m_ViaEndLayer->Enable( false );
  580. }
  581. }
  582. }