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.

377 lines
13 KiB

16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2009-2016 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
  5. * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #include <fctsys.h>
  25. #include <confirm.h>
  26. #include <pcb_edit_frame.h>
  27. #include <class_drawpanel.h>
  28. #include <class_board.h>
  29. #include <connectivity/connectivity_data.h>
  30. #include <view/view.h>
  31. #include <pcb_layer_box_selector.h>
  32. #include <tool/tool_manager.h>
  33. #include <tool/selection.h>
  34. #include <tools/selection_tool.h>
  35. #include "dialog_global_edit_tracks_and_vias_base.h"
  36. // Columns of netclasses grid
  37. enum {
  38. GRID_NAME = 0,
  39. GRID_TRACKSIZE,
  40. GRID_VIASIZE,
  41. GRID_VIADRILL,
  42. GRID_uVIASIZE,
  43. GRID_uVIADRILL,
  44. GRID_DIFF_PAIR_WIDTH, // not currently included in grid
  45. GRID_DIFF_PAIR_GAP, // not currently included in grid
  46. GRID_DIFF_PAIR_VIA_GAP // not currently included in grid
  47. };
  48. // Globals to remember control settings during a session
  49. static bool g_modifyTracks = true;
  50. static bool g_modifyVias = true;
  51. static bool g_filterByNetclass;
  52. static wxString g_netclassFilter;
  53. static bool g_filterByNet;
  54. static wxString g_netFilter;
  55. static bool g_filterByLayer;
  56. static LAYER_NUM g_layerFilter;
  57. class DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS : public DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE
  58. {
  59. private:
  60. PCB_EDIT_FRAME* m_parent;
  61. BOARD* m_brd;
  62. int* m_originalColWidths;
  63. bool m_failedDRC;
  64. public:
  65. DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS( PCB_EDIT_FRAME* aParent );
  66. ~DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS() override;
  67. private:
  68. void visitItem( PICKED_ITEMS_LIST* aUndoList, TRACK* aItem );
  69. void processItem( PICKED_ITEMS_LIST* aUndoList, TRACK* aItem );
  70. bool TransferDataToWindow() override;
  71. bool TransferDataFromWindow() override;
  72. void OnUpdateUI( wxUpdateUIEvent& event ) override;
  73. void OnSizeNetclassGrid( wxSizeEvent& event ) override;
  74. void AdjustNetclassGridColumns( int aWidth );
  75. void OnNetFilterSelect( wxCommandEvent& event )
  76. {
  77. m_netFilterOpt->SetValue( true );
  78. }
  79. void OnNetclassFilterSelect( wxCommandEvent& event ) override
  80. {
  81. m_netclassFilterOpt->SetValue( true );
  82. }
  83. void OnLayerFilterSelect( wxCommandEvent& event ) override
  84. {
  85. m_layerFilterOpt->SetValue( true );
  86. }
  87. void buildNetclassesGrid();
  88. void buildFilterLists();
  89. };
  90. DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS( PCB_EDIT_FRAME* aParent ) :
  91. DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE( aParent )
  92. {
  93. m_parent = aParent;
  94. m_brd = m_parent->GetBoard();
  95. m_originalColWidths = new int[ m_netclassGrid->GetNumberCols() ];
  96. for( int i = 0; i < m_netclassGrid->GetNumberCols(); ++i )
  97. m_originalColWidths[ i ] = m_netclassGrid->GetColSize( i );
  98. m_failedDRC = false;
  99. buildFilterLists();
  100. m_parent->UpdateTrackWidthSelectBox( m_trackWidthSelectBox, false );
  101. m_parent->UpdateViaSizeSelectBox( m_viaSizesSelectBox, false );
  102. m_layerBox->SetBoardFrame( m_parent );
  103. m_layerBox->SetLayersHotkeys( false );
  104. m_layerBox->SetNotAllowedLayerSet( LSET::AllNonCuMask() );
  105. m_layerBox->Resync();
  106. wxFont infoFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
  107. infoFont.SetSymbolicSize( wxFONTSIZE_SMALL );
  108. m_netclassGrid->SetDefaultCellFont( infoFont );
  109. buildNetclassesGrid();
  110. m_netclassGrid->SetCellHighlightPenWidth( 0 );
  111. m_sdbSizerOK->SetDefault();
  112. m_netFilter->Connect( NET_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::OnNetFilterSelect ), NULL, this );
  113. FinishDialogSettings();
  114. }
  115. DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::~DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS()
  116. {
  117. g_modifyTracks = m_tracks->GetValue();
  118. g_modifyVias = m_vias->GetValue();
  119. g_filterByNetclass = m_netclassFilterOpt->GetValue();
  120. g_netclassFilter = m_netclassFilter->GetStringSelection();
  121. g_filterByNet = m_netFilterOpt->GetValue();
  122. g_netFilter = m_netFilter->GetSelectedNetname();
  123. g_filterByLayer = m_layerFilterOpt->GetValue();
  124. g_layerFilter = m_layerFilter->GetLayerSelection();
  125. m_netFilter->Disconnect( NET_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::OnNetFilterSelect ), NULL, this );
  126. delete[] m_originalColWidths;
  127. }
  128. void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::buildFilterLists()
  129. {
  130. // Populate the net filter list with net names
  131. m_netFilter->SetNetInfo( &m_brd->GetNetInfo() );
  132. m_netFilter->SetSelectedNetcode( m_brd->GetHighLightNetCode() );
  133. // Populate the netclass filter list with netclass names
  134. wxArrayString netclassNames;
  135. NETCLASSES& netclasses = m_brd->GetDesignSettings().m_NetClasses;
  136. netclassNames.push_back(netclasses.GetDefault()->GetName() );
  137. for( NETCLASSES::const_iterator nc = netclasses.begin(); nc != netclasses.end(); ++nc )
  138. netclassNames.push_back( nc->second->GetName() );
  139. m_netclassFilter->Set( netclassNames );
  140. m_netclassFilter->SetStringSelection( m_brd->GetDesignSettings().GetCurrentNetClassName() );
  141. // Populate the layer filter list
  142. m_layerFilter->SetBoardFrame( m_parent );
  143. m_layerFilter->SetLayersHotkeys( false );
  144. m_layerFilter->SetNotAllowedLayerSet( LSET::AllNonCuMask() );
  145. m_layerFilter->Resync();
  146. m_layerFilter->SetLayerSelection( m_parent->GetActiveLayer() );
  147. }
  148. void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::buildNetclassesGrid()
  149. {
  150. #define SET_NETCLASS_VALUE( row, col, val ) \
  151. m_netclassGrid->SetCellValue( row, col, StringFromValue( GetUserUnits(), val, true, true ) )
  152. m_netclassGrid->SetCellValue( 0, GRID_TRACKSIZE, _( "Track Width" ) );
  153. m_netclassGrid->SetCellValue( 0, GRID_VIASIZE, _( "Via Size" ) );
  154. m_netclassGrid->SetCellValue( 0, GRID_VIADRILL, _( "Via Drill" ) );
  155. m_netclassGrid->SetCellValue( 0, GRID_uVIASIZE, _( "uVia Size" ) );
  156. m_netclassGrid->SetCellValue( 0, GRID_uVIADRILL, _( "uVia Drill" ) );
  157. NETCLASSES& netclasses = m_brd->GetDesignSettings().m_NetClasses;
  158. NETCLASSPTR defaultNetclass = m_brd->GetDesignSettings().GetDefault();
  159. m_netclassGrid->AppendRows( netclasses.GetCount() + 1 );
  160. m_netclassGrid->SetCellValue( 1, GRID_NAME, defaultNetclass->GetName() );
  161. SET_NETCLASS_VALUE( 1, GRID_TRACKSIZE, defaultNetclass->GetTrackWidth() );
  162. SET_NETCLASS_VALUE( 1, GRID_VIASIZE, defaultNetclass->GetViaDiameter() );
  163. SET_NETCLASS_VALUE( 1, GRID_VIADRILL, defaultNetclass->GetViaDrill() );
  164. SET_NETCLASS_VALUE( 1, GRID_uVIASIZE, defaultNetclass->GetuViaDiameter() );
  165. SET_NETCLASS_VALUE( 1, GRID_uVIADRILL, defaultNetclass->GetuViaDrill() );
  166. int row = 2;
  167. for( const auto& netclass : netclasses )
  168. {
  169. m_netclassGrid->SetCellValue( row, GRID_NAME, netclass.first );
  170. SET_NETCLASS_VALUE( row, GRID_TRACKSIZE, netclass.second->GetTrackWidth() );
  171. SET_NETCLASS_VALUE( row, GRID_VIASIZE, netclass.second->GetViaDiameter() );
  172. SET_NETCLASS_VALUE( row, GRID_VIADRILL, netclass.second->GetViaDrill() );
  173. SET_NETCLASS_VALUE( row, GRID_uVIASIZE, netclass.second->GetuViaDiameter() );
  174. SET_NETCLASS_VALUE( row, GRID_uVIADRILL, netclass.second->GetuViaDrill() );
  175. row++;
  176. }
  177. }
  178. bool DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::TransferDataToWindow()
  179. {
  180. SELECTION& selection = GetToolManager()->GetTool<SELECTION_TOOL>()->GetSelection();
  181. auto item = dynamic_cast<BOARD_CONNECTED_ITEM*>( selection.Front() );
  182. m_tracks->SetValue( g_modifyTracks );
  183. m_vias->SetValue( g_modifyVias );
  184. if( g_filterByNetclass && m_netclassFilter->SetStringSelection( g_netclassFilter ) )
  185. m_netclassFilterOpt->SetValue( true );
  186. else if( item )
  187. m_netclassFilter->SetStringSelection( item->GetNet()->GetClassName() );
  188. if( g_filterByNet && m_brd->FindNet( g_netFilter ) != NULL )
  189. {
  190. m_netFilter->SetSelectedNet( g_netFilter );
  191. m_netFilterOpt->SetValue( true );
  192. }
  193. else if( item )
  194. m_netFilter->SetSelectedNetcode( item->GetNetCode() );
  195. if( g_filterByLayer && m_layerFilter->SetLayerSelection( g_layerFilter ) != wxNOT_FOUND )
  196. m_layerFilterOpt->SetValue( true );
  197. else if( item )
  198. m_layerFilter->SetLayerSelection( item->GetLayer() );
  199. return true;
  200. }
  201. void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::OnUpdateUI( wxUpdateUIEvent& )
  202. {
  203. m_trackWidthSelectBox->Enable( m_setToSpecifiedValues->GetValue() );
  204. m_viaSizesSelectBox->Enable( m_setToSpecifiedValues->GetValue() );
  205. if( m_failedDRC )
  206. {
  207. m_failedDRC = false;
  208. DisplayError( this, _( "Some items failed DRC and were not modified." ) );
  209. }
  210. }
  211. void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::processItem( PICKED_ITEMS_LIST* aUndoList, TRACK* aItem )
  212. {
  213. BOARD_DESIGN_SETTINGS& brdSettings = m_brd->GetDesignSettings();
  214. if( m_setToSpecifiedValues->GetValue() )
  215. {
  216. unsigned int prevTrackWidthIndex = brdSettings.GetTrackWidthIndex();
  217. unsigned int prevViaSizeIndex = brdSettings.GetViaSizeIndex();
  218. {
  219. brdSettings.SetTrackWidthIndex( (unsigned) m_trackWidthSelectBox->GetSelection() );
  220. brdSettings.SetViaSizeIndex( (unsigned) m_viaSizesSelectBox->GetSelection() );
  221. if( m_parent->SetTrackSegmentWidth( aItem, aUndoList, false ) == TRACK_ACTION_DRC_ERROR )
  222. m_failedDRC = true;
  223. }
  224. brdSettings.SetTrackWidthIndex( prevTrackWidthIndex );
  225. brdSettings.SetViaSizeIndex( prevViaSizeIndex );
  226. if( m_layerBox->GetLayerSelection() != UNDEFINED_LAYER && aItem->Type() == PCB_TRACE_T )
  227. {
  228. if( aUndoList->FindItem( aItem ) < 0 )
  229. {
  230. ITEM_PICKER picker( aItem, UR_CHANGED );
  231. picker.SetLink( aItem->Clone() );
  232. aUndoList->PushItem( picker );
  233. }
  234. aItem->SetLayer( ToLAYER_ID( m_layerBox->GetLayerSelection() ) );
  235. m_parent->GetBoard()->GetConnectivity()->Update( aItem );
  236. }
  237. }
  238. else
  239. {
  240. if( m_parent->SetTrackSegmentWidth( aItem, aUndoList, true ) == TRACK_ACTION_DRC_ERROR )
  241. m_failedDRC = true;
  242. }
  243. }
  244. void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::visitItem( PICKED_ITEMS_LIST* aUndoList, TRACK* aItem )
  245. {
  246. if( m_netFilterOpt->GetValue() && m_netFilter->GetSelectedNetcode() >= 0 )
  247. {
  248. if( aItem->GetNetCode() != m_netFilter->GetSelectedNetcode() )
  249. return;
  250. }
  251. if( m_netclassFilterOpt->GetValue() && !m_netclassFilter->GetStringSelection().IsEmpty() )
  252. {
  253. if( aItem->GetNetClassName() != m_netclassFilter->GetStringSelection() )
  254. return;
  255. }
  256. if( m_layerFilterOpt->GetValue() && m_layerFilter->GetLayerSelection() != UNDEFINED_LAYER )
  257. {
  258. if( aItem->GetLayer() != m_layerFilter->GetLayerSelection() )
  259. return;
  260. }
  261. processItem( aUndoList, aItem );
  262. }
  263. bool DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::TransferDataFromWindow()
  264. {
  265. PICKED_ITEMS_LIST itemsListPicker;
  266. wxBusyCursor dummy;
  267. // Examine segments
  268. for( TRACK* segment = m_brd->m_Track; segment != nullptr; segment = segment->Next() )
  269. {
  270. if( m_tracks->GetValue() && segment->Type() == PCB_TRACE_T )
  271. visitItem( &itemsListPicker, segment );
  272. else if (m_vias->GetValue() && segment->Type() == PCB_VIA_T )
  273. visitItem( &itemsListPicker, segment );
  274. }
  275. if( itemsListPicker.GetCount() > 0 )
  276. {
  277. m_parent->SaveCopyInUndoList( itemsListPicker, UR_CHANGED );
  278. for( TRACK* segment = m_brd->m_Track; segment != nullptr; segment = segment->Next() )
  279. m_parent->GetGalCanvas()->GetView()->Update( segment );
  280. }
  281. return !m_failedDRC;
  282. }
  283. void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::AdjustNetclassGridColumns( int aWidth )
  284. {
  285. for( int i = 1; i < m_netclassGrid->GetNumberCols(); i++ )
  286. {
  287. m_netclassGrid->SetColSize( i, m_originalColWidths[ i ] );
  288. aWidth -= m_originalColWidths[ i ];
  289. }
  290. m_netclassGrid->SetColSize( 0, aWidth );
  291. }
  292. void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::OnSizeNetclassGrid( wxSizeEvent& event )
  293. {
  294. AdjustNetclassGridColumns( event.GetSize().GetX() );
  295. event.Skip();
  296. }
  297. void PCB_EDIT_FRAME::OnEditTracksAndVias( wxCommandEvent& event )
  298. {
  299. DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS dlg( this );
  300. dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
  301. }