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.

180 lines
6.0 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.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 <wx/wx.h>
  24. #include <dialog_cleanup_tracks_and_vias.h>
  25. #include <pcb_edit_frame.h>
  26. #include <pcbnew_settings.h>
  27. #include <tool/tool_manager.h>
  28. #include <tools/pcb_actions.h>
  29. #include <tracks_cleaner.h>
  30. #include <drc/drc_item.h>
  31. #include <tools/zone_filler_tool.h>
  32. DIALOG_CLEANUP_TRACKS_AND_VIAS::DIALOG_CLEANUP_TRACKS_AND_VIAS( PCB_EDIT_FRAME* aParentFrame ) :
  33. DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE( aParentFrame ),
  34. m_parentFrame( aParentFrame ),
  35. m_firstRun( true )
  36. {
  37. auto cfg = m_parentFrame->GetPcbNewSettings();
  38. m_cleanViasOpt->SetValue( cfg->m_Cleanup.cleanup_vias );
  39. m_mergeSegmOpt->SetValue( cfg->m_Cleanup.merge_segments );
  40. m_deleteUnconnectedOpt->SetValue( cfg->m_Cleanup.cleanup_unconnected );
  41. m_cleanShortCircuitOpt->SetValue( cfg->m_Cleanup.cleanup_short_circuits );
  42. m_deleteTracksInPadsOpt->SetValue( cfg->m_Cleanup.cleanup_tracks_in_pad );
  43. m_deleteDanglingViasOpt->SetValue( cfg->m_Cleanup.delete_dangling_vias );
  44. m_changesTreeModel = new RC_TREE_MODEL( m_parentFrame, m_changesDataView );
  45. m_changesDataView->AssociateModel( m_changesTreeModel );
  46. m_changesTreeModel->SetSeverities( RPT_SEVERITY_ACTION );
  47. // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
  48. // that requires us to correct the button labels here.
  49. m_sdbSizerOK->SetLabel( _( "Update PCB" ) );
  50. m_sdbSizerOK->SetDefault();
  51. m_sdbSizer->SetSizeHints( this );
  52. finishDialogSettings();
  53. }
  54. DIALOG_CLEANUP_TRACKS_AND_VIAS::~DIALOG_CLEANUP_TRACKS_AND_VIAS()
  55. {
  56. auto cfg = m_parentFrame->GetPcbNewSettings();
  57. cfg->m_Cleanup.cleanup_vias = m_cleanViasOpt->GetValue();
  58. cfg->m_Cleanup.merge_segments = m_mergeSegmOpt->GetValue();
  59. cfg->m_Cleanup.cleanup_unconnected = m_deleteUnconnectedOpt->GetValue();
  60. cfg->m_Cleanup.cleanup_short_circuits = m_cleanShortCircuitOpt->GetValue();
  61. cfg->m_Cleanup.cleanup_tracks_in_pad = m_deleteTracksInPadsOpt->GetValue();
  62. cfg->m_Cleanup.delete_dangling_vias = m_deleteDanglingViasOpt->GetValue();
  63. m_changesTreeModel->DecRef();
  64. }
  65. void DIALOG_CLEANUP_TRACKS_AND_VIAS::OnCheckBox( wxCommandEvent& anEvent )
  66. {
  67. doCleanup( true );
  68. }
  69. bool DIALOG_CLEANUP_TRACKS_AND_VIAS::TransferDataToWindow()
  70. {
  71. doCleanup( true );
  72. return true;
  73. }
  74. bool DIALOG_CLEANUP_TRACKS_AND_VIAS::TransferDataFromWindow()
  75. {
  76. doCleanup( false );
  77. return true;
  78. }
  79. void DIALOG_CLEANUP_TRACKS_AND_VIAS::doCleanup( bool aDryRun )
  80. {
  81. wxBusyCursor busy;
  82. BOARD_COMMIT commit( m_parentFrame );
  83. TRACKS_CLEANER cleaner( m_parentFrame->GetBoard(), commit );
  84. if( !aDryRun )
  85. {
  86. // Clear current selection list to avoid selection of deleted items
  87. m_parentFrame->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
  88. // ... and to keep the treeModel from trying to refresh a deleted item
  89. m_changesTreeModel->SetProvider( nullptr );
  90. }
  91. m_items.clear();
  92. if( m_firstRun )
  93. {
  94. m_items.push_back( std::make_shared<CLEANUP_ITEM>( CLEANUP_CHECKING_ZONE_FILLS ) );
  95. RC_ITEMS_PROVIDER* provider = new VECTOR_CLEANUP_ITEMS_PROVIDER( &m_items );
  96. m_changesTreeModel->SetProvider( provider );
  97. m_parentFrame->GetToolManager()->GetTool<ZONE_FILLER_TOOL>()->CheckAllZones( this );
  98. wxSafeYield(); // Timeslice to close zone progress reporter
  99. m_changesTreeModel->SetProvider( nullptr );
  100. m_items.clear();
  101. m_firstRun = false;
  102. }
  103. // Old model has to be refreshed, GAL normally does not keep updating it
  104. m_parentFrame->Compile_Ratsnest( false );
  105. cleaner.CleanupBoard( aDryRun, &m_items, m_cleanShortCircuitOpt->GetValue(),
  106. m_cleanViasOpt->GetValue(),
  107. m_mergeSegmOpt->GetValue(),
  108. m_deleteUnconnectedOpt->GetValue(),
  109. m_deleteTracksInPadsOpt->GetValue(),
  110. m_deleteDanglingViasOpt->GetValue() );
  111. if( aDryRun )
  112. {
  113. RC_ITEMS_PROVIDER* provider = new VECTOR_CLEANUP_ITEMS_PROVIDER( &m_items );
  114. m_changesTreeModel->SetProvider( provider );
  115. }
  116. else if( !commit.Empty() )
  117. {
  118. // Clear undo and redo lists to avoid inconsistencies between lists
  119. commit.Push( _( "Board cleanup" ) );
  120. m_parentFrame->GetCanvas()->Refresh( true );
  121. }
  122. }
  123. void DIALOG_CLEANUP_TRACKS_AND_VIAS::OnSelectItem( wxDataViewEvent& aEvent )
  124. {
  125. const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
  126. BOARD_ITEM* item = m_parentFrame->GetBoard()->GetItem( itemID );
  127. WINDOW_THAWER thawer( m_parentFrame );
  128. m_parentFrame->FocusOnItem( item );
  129. m_parentFrame->GetCanvas()->Refresh();
  130. aEvent.Skip();
  131. }
  132. void DIALOG_CLEANUP_TRACKS_AND_VIAS::OnLeftDClickItem( wxMouseEvent& event )
  133. {
  134. event.Skip();
  135. if( m_changesDataView->GetCurrentItem().IsOk() )
  136. {
  137. if( !IsModal() )
  138. Show( false );
  139. }
  140. }