Browse Source
Implement a dry run for Cleanup Tracks and Vias.
Implement a dry run for Cleanup Tracks and Vias.
Uses the DRC architecture to support inspection of the changes to be made (right click on items, hover over them in the menu to highlight them on the board). Fixes: lp:1571305 * https://bugs.launchpad.net/kicad/+bug/1571305 Fixes: lp:1809474 * https://bugs.launchpad.net/kicad/+bug/1809474pull/13/head
17 changed files with 969 additions and 547 deletions
-
4pcbnew/CMakeLists.txt
-
9pcbnew/class_track.h
-
50pcbnew/dialogs/dialog_cleaning_options.cpp
-
67pcbnew/dialogs/dialog_cleaning_options_base.cpp
-
53pcbnew/dialogs/dialog_cleaning_options_base.h
-
221pcbnew/dialogs/dialog_cleanup_tracks_and_vias.cpp
-
44pcbnew/dialogs/dialog_cleanup_tracks_and_vias.h
-
98pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.cpp
-
277pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.fbp
-
65pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.h
-
8pcbnew/dialogs/dialog_drclistbox.h
-
6pcbnew/drc.cpp
-
8pcbnew/drc.h
-
15pcbnew/drc_item.cpp
-
8pcbnew/pcbnew.h
-
465pcbnew/tracks_cleaner.cpp
-
118pcbnew/tracks_cleaner.h
@ -1,50 +0,0 @@ |
|||
/**
|
|||
* @file dialog_cleaning_options.cpp |
|||
*/ |
|||
|
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
#include <wx/wx.h>
|
|||
|
|||
#include <dialog_cleaning_options.h>
|
|||
|
|||
|
|||
DIALOG_CLEANING_OPTIONS::DIALOG_CLEANING_OPTIONS( wxWindow* parent ): |
|||
DIALOG_CLEANING_OPTIONS_BASE( parent ) |
|||
{ |
|||
m_cleanViasOpt->SetValue( m_cleanVias ); |
|||
m_mergeSegmOpt->SetValue( m_mergeSegments ); |
|||
m_deleteUnconnectedOpt->SetValue( m_deleteUnconnectedSegm ); |
|||
m_cleanShortCircuitOpt->SetValue( m_deleteShortCircuits ); |
|||
|
|||
m_sdbSizerOK->SetDefault(); |
|||
GetSizer()->SetSizeHints(this); |
|||
Centre(); |
|||
} |
|||
|
|||
// Static members of DIALOG_CLEANING_OPTIONS
|
|||
bool DIALOG_CLEANING_OPTIONS::m_cleanVias = true; |
|||
bool DIALOG_CLEANING_OPTIONS::m_mergeSegments = true; |
|||
bool DIALOG_CLEANING_OPTIONS::m_deleteUnconnectedSegm = true; |
|||
bool DIALOG_CLEANING_OPTIONS::m_deleteShortCircuits = true; |
|||
|
@ -1,67 +0,0 @@ |
|||
///////////////////////////////////////////////////////////////////////////
|
|||
// C++ code generated with wxFormBuilder (version Nov 22 2017)
|
|||
// http://www.wxformbuilder.org/
|
|||
//
|
|||
// PLEASE DO *NOT* EDIT THIS FILE!
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
|
|||
#include "dialog_cleaning_options_base.h"
|
|||
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
|
|||
DIALOG_CLEANING_OPTIONS_BASE::DIALOG_CLEANING_OPTIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) |
|||
{ |
|||
this->SetSizeHints( wxDefaultSize, wxDefaultSize ); |
|||
|
|||
wxBoxSizer* bSizerMain; |
|||
bSizerMain = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
wxBoxSizer* bSizerUpper; |
|||
bSizerUpper = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
m_cleanShortCircuitOpt = new wxCheckBox( this, wxID_ANY, _("Delete &track segments connecting different nets"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_cleanShortCircuitOpt->SetToolTip( _("remove track segments connecting nodes belonging to different nets (short circuit)") ); |
|||
|
|||
bSizerUpper->Add( m_cleanShortCircuitOpt, 0, wxALL, 5 ); |
|||
|
|||
m_cleanViasOpt = new wxCheckBox( this, wxID_ANY, _("&Delete redundant vias"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_cleanViasOpt->SetToolTip( _("remove vias on through hole pads and superimposed vias") ); |
|||
|
|||
bSizerUpper->Add( m_cleanViasOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 ); |
|||
|
|||
m_mergeSegmOpt = new wxCheckBox( this, wxID_ANY, _("&Merge overlapping segments"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_mergeSegmOpt->SetToolTip( _("merge aligned track segments, and remove null segments") ); |
|||
|
|||
bSizerUpper->Add( m_mergeSegmOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 ); |
|||
|
|||
m_deleteUnconnectedOpt = new wxCheckBox( this, wxID_ANY, _("Delete &dangling tracks"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_deleteUnconnectedOpt->SetToolTip( _("delete tracks having at least one dangling end") ); |
|||
|
|||
bSizerUpper->Add( m_deleteUnconnectedOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 ); |
|||
|
|||
|
|||
bSizerMain->Add( bSizerUpper, 1, wxEXPAND|wxALL, 5 ); |
|||
|
|||
m_staticline = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); |
|||
bSizerMain->Add( m_staticline, 0, wxEXPAND | wxALL, 5 ); |
|||
|
|||
m_sdbSizer = new wxStdDialogButtonSizer(); |
|||
m_sdbSizerOK = new wxButton( this, wxID_OK ); |
|||
m_sdbSizer->AddButton( m_sdbSizerOK ); |
|||
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL ); |
|||
m_sdbSizer->AddButton( m_sdbSizerCancel ); |
|||
m_sdbSizer->Realize(); |
|||
|
|||
bSizerMain->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 ); |
|||
|
|||
|
|||
this->SetSizer( bSizerMain ); |
|||
this->Layout(); |
|||
bSizerMain->Fit( this ); |
|||
|
|||
this->Centre( wxBOTH ); |
|||
} |
|||
|
|||
DIALOG_CLEANING_OPTIONS_BASE::~DIALOG_CLEANING_OPTIONS_BASE() |
|||
{ |
|||
} |
@ -1,53 +0,0 @@ |
|||
/////////////////////////////////////////////////////////////////////////// |
|||
// C++ code generated with wxFormBuilder (version Nov 22 2017) |
|||
// http://www.wxformbuilder.org/ |
|||
// |
|||
// PLEASE DO *NOT* EDIT THIS FILE! |
|||
/////////////////////////////////////////////////////////////////////////// |
|||
|
|||
#ifndef __DIALOG_CLEANING_OPTIONS_BASE_H__ |
|||
#define __DIALOG_CLEANING_OPTIONS_BASE_H__ |
|||
|
|||
#include <wx/artprov.h> |
|||
#include <wx/xrc/xmlres.h> |
|||
#include <wx/intl.h> |
|||
#include "dialog_shim.h" |
|||
#include <wx/string.h> |
|||
#include <wx/checkbox.h> |
|||
#include <wx/gdicmn.h> |
|||
#include <wx/font.h> |
|||
#include <wx/colour.h> |
|||
#include <wx/settings.h> |
|||
#include <wx/sizer.h> |
|||
#include <wx/statline.h> |
|||
#include <wx/button.h> |
|||
#include <wx/dialog.h> |
|||
|
|||
/////////////////////////////////////////////////////////////////////////// |
|||
|
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class DIALOG_CLEANING_OPTIONS_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class DIALOG_CLEANING_OPTIONS_BASE : public DIALOG_SHIM |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxCheckBox* m_cleanShortCircuitOpt; |
|||
wxCheckBox* m_cleanViasOpt; |
|||
wxCheckBox* m_mergeSegmOpt; |
|||
wxCheckBox* m_deleteUnconnectedOpt; |
|||
wxStaticLine* m_staticline; |
|||
wxStdDialogButtonSizer* m_sdbSizer; |
|||
wxButton* m_sdbSizerOK; |
|||
wxButton* m_sdbSizerCancel; |
|||
|
|||
public: |
|||
|
|||
DIALOG_CLEANING_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Cleaning Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); |
|||
~DIALOG_CLEANING_OPTIONS_BASE(); |
|||
|
|||
}; |
|||
|
|||
#endif //__DIALOG_CLEANING_OPTIONS_BASE_H__ |
@ -0,0 +1,221 @@ |
|||
/**
|
|||
* @file dialog_cleaning_options.cpp |
|||
*/ |
|||
|
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
#include <wx/wx.h>
|
|||
|
|||
#include <dialog_cleanup_tracks_and_vias.h>
|
|||
#include <wx_html_report_panel.h>
|
|||
#include <board_commit.h>
|
|||
#include <tools/pcb_actions.h>
|
|||
#include <pcb_edit_frame.h>
|
|||
#include <tracks_cleaner.h>
|
|||
#include <reporter.h>
|
|||
#include <class_drawpanel.h>
|
|||
#include <tool/tool_manager.h>
|
|||
#include <collectors.h>
|
|||
#include "dialog_drclistbox.h"
|
|||
|
|||
// Static members of DIALOG_CLEANUP_TRACKS_AND_VIAS
|
|||
bool DIALOG_CLEANUP_TRACKS_AND_VIAS::m_cleanVias = true; |
|||
bool DIALOG_CLEANUP_TRACKS_AND_VIAS::m_mergeSegments = true; |
|||
bool DIALOG_CLEANUP_TRACKS_AND_VIAS::m_deleteUnconnectedSegm = true; |
|||
bool DIALOG_CLEANUP_TRACKS_AND_VIAS::m_deleteShortCircuits = true; |
|||
|
|||
|
|||
DIALOG_CLEANUP_TRACKS_AND_VIAS::DIALOG_CLEANUP_TRACKS_AND_VIAS( PCB_EDIT_FRAME* aParentFrame ): |
|||
DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE( aParentFrame ), |
|||
m_parentFrame( aParentFrame ) |
|||
{ |
|||
m_cleanViasOpt->SetValue( m_cleanVias ); |
|||
m_mergeSegmOpt->SetValue( m_mergeSegments ); |
|||
m_deleteUnconnectedOpt->SetValue( m_deleteUnconnectedSegm ); |
|||
m_cleanShortCircuitOpt->SetValue( m_deleteShortCircuits ); |
|||
|
|||
// We use a sdbSizer to get platform-dependent ordering of the action buttons, but
|
|||
// that requires us to correct the button labels here.
|
|||
m_sdbSizerOK->SetLabel( _( "Update PCB" ) ); |
|||
|
|||
m_sdbSizerOK->SetDefault(); |
|||
GetSizer()->SetSizeHints(this); |
|||
Centre(); |
|||
} |
|||
|
|||
|
|||
DIALOG_CLEANUP_TRACKS_AND_VIAS::~DIALOG_CLEANUP_TRACKS_AND_VIAS() |
|||
{ |
|||
m_cleanVias = m_cleanViasOpt->GetValue(); |
|||
m_mergeSegments = m_mergeSegmOpt->GetValue(); |
|||
m_deleteUnconnectedSegm = m_deleteUnconnectedOpt->GetValue(); |
|||
m_deleteShortCircuits = m_cleanShortCircuitOpt->GetValue(); |
|||
|
|||
for( DRC_ITEM* item : m_items ) |
|||
delete item; |
|||
} |
|||
|
|||
|
|||
void DIALOG_CLEANUP_TRACKS_AND_VIAS::OnCheckBox( wxCommandEvent& anEvent ) |
|||
{ |
|||
doCleanup( true ); |
|||
} |
|||
|
|||
|
|||
bool DIALOG_CLEANUP_TRACKS_AND_VIAS::TransferDataToWindow() |
|||
{ |
|||
doCleanup( true ); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
bool DIALOG_CLEANUP_TRACKS_AND_VIAS::TransferDataFromWindow() |
|||
{ |
|||
doCleanup( false ); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
void DIALOG_CLEANUP_TRACKS_AND_VIAS::doCleanup( bool aDryRun ) |
|||
{ |
|||
for( DRC_ITEM* item : m_items ) |
|||
delete item; |
|||
|
|||
m_items.clear(); |
|||
|
|||
wxBusyCursor busy; |
|||
BOARD_COMMIT commit( m_parentFrame ); |
|||
TRACKS_CLEANER cleaner( m_parentFrame->GetUserUnits(), m_parentFrame->GetBoard(), commit ); |
|||
|
|||
if( !aDryRun ) |
|||
{ |
|||
// Clear current selection list to avoid selection of deleted items
|
|||
m_parentFrame->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true ); |
|||
} |
|||
|
|||
// Old model has to be refreshed, GAL normally does not keep updating it
|
|||
m_parentFrame->Compile_Ratsnest( NULL, false ); |
|||
|
|||
bool modified = cleaner.CleanupBoard( aDryRun, &m_items, |
|||
m_cleanShortCircuitOpt->GetValue(), |
|||
m_cleanViasOpt->GetValue(), |
|||
m_mergeSegmOpt->GetValue(), |
|||
m_deleteUnconnectedOpt->GetValue() ); |
|||
|
|||
if( aDryRun ) |
|||
{ |
|||
m_ItemsListBox->SetList( GetUserUnits(), new DRC_LIST_GENERIC( &m_items ) ); |
|||
} |
|||
else if( modified ) |
|||
{ |
|||
// Clear undo and redo lists to avoid inconsistencies between lists
|
|||
m_parentFrame->SetCurItem( NULL ); |
|||
commit.Push( _( "Board cleanup" ) ); |
|||
|
|||
m_parentFrame->GetCanvas()->Refresh( true ); |
|||
} |
|||
} |
|||
|
|||
|
|||
void DIALOG_CLEANUP_TRACKS_AND_VIAS::OnSelectItem( wxCommandEvent& event ) |
|||
{ |
|||
int selection = event.GetSelection(); |
|||
|
|||
if( selection != wxNOT_FOUND ) |
|||
{ |
|||
// Find the selected DRC_ITEM in the listbox, position cursor there.
|
|||
const DRC_ITEM* item = m_ItemsListBox->GetItem( selection ); |
|||
|
|||
if( item ) |
|||
{ |
|||
// When selecting a item, center it on GAL and just move the graphic
|
|||
// cursor in legacy mode gives the best result
|
|||
bool center = m_parentFrame->IsGalCanvasActive() ? true : false; |
|||
m_parentFrame->FocusOnLocation( item->GetPointA(), false, center ); |
|||
|
|||
WINDOW_THAWER thawer( m_parentFrame ); |
|||
m_parentFrame->GetCanvas()->Refresh(); |
|||
} |
|||
} |
|||
|
|||
event.Skip(); |
|||
} |
|||
|
|||
|
|||
void DIALOG_CLEANUP_TRACKS_AND_VIAS::OnLeftDClickItem( wxMouseEvent& event ) |
|||
{ |
|||
event.Skip(); |
|||
|
|||
int selection = m_ItemsListBox->GetSelection(); |
|||
|
|||
if( selection != wxNOT_FOUND ) |
|||
{ |
|||
// Find the selected DRC_ITEM in the listbox, position cursor there.
|
|||
// Then hide the dialog.
|
|||
const DRC_ITEM* item = m_ItemsListBox->GetItem( selection ); |
|||
if( item ) |
|||
{ |
|||
// When selecting a item, center it on GAL and just move the graphic
|
|||
// cursor in legacy mode gives the best result
|
|||
bool center = m_parentFrame->IsGalCanvasActive() ? true : false; |
|||
m_parentFrame->FocusOnLocation( item->GetPointA(), true, center ); |
|||
|
|||
if( !IsModal() ) |
|||
{ |
|||
Show( false ); |
|||
|
|||
// We do not want the clarify selection popup when releasing the
|
|||
// left button in the main window
|
|||
m_parentFrame->SkipNextLeftButtonReleaseEvent(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
void DIALOG_CLEANUP_TRACKS_AND_VIAS::OnRightUpItem( wxMouseEvent& event ) |
|||
{ |
|||
// popup menu to go to either of the items listed in the DRC_ITEM.
|
|||
|
|||
int selection = m_ItemsListBox->GetSelection(); |
|||
|
|||
if( selection != wxNOT_FOUND ) |
|||
{ |
|||
// popup menu to go to either of the items listed in the DRC_ITEM.
|
|||
const DRC_ITEM* item = m_ItemsListBox->GetItem( selection ); |
|||
GENERAL_COLLECTOR items; |
|||
|
|||
items.Append( item->GetMainItem( m_parentFrame->GetBoard() ) ); |
|||
|
|||
if( item->HasSecondItem() ) |
|||
items.Append( item->GetAuxiliaryItem( m_parentFrame->GetBoard() ) ); |
|||
|
|||
WINDOW_THAWER thawer( m_parentFrame ); |
|||
m_parentFrame->GetToolManager()->RunAction( PCB_ACTIONS::selectionMenu, true, &items ); |
|||
m_parentFrame->GetCanvas()->Refresh(); |
|||
} |
|||
} |
|||
|
|||
|
@ -0,0 +1,98 @@ |
|||
///////////////////////////////////////////////////////////////////////////
|
|||
// C++ code generated with wxFormBuilder (version Dec 30 2017)
|
|||
// http://www.wxformbuilder.org/
|
|||
//
|
|||
// PLEASE DO *NOT* EDIT THIS FILE!
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
|
|||
#include "dialog_drclistbox.h"
|
|||
|
|||
#include "dialog_cleanup_tracks_and_vias_base.h"
|
|||
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
|
|||
DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) |
|||
{ |
|||
this->SetSizeHints( wxDefaultSize, wxDefaultSize ); |
|||
|
|||
wxBoxSizer* bSizerMain; |
|||
bSizerMain = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
wxBoxSizer* bSizerUpper; |
|||
bSizerUpper = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
m_cleanShortCircuitOpt = new wxCheckBox( this, wxID_ANY, _("Delete &tracks connecting different nets"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_cleanShortCircuitOpt->SetToolTip( _("remove track segments connecting nodes belonging to different nets (short circuit)") ); |
|||
|
|||
bSizerUpper->Add( m_cleanShortCircuitOpt, 0, wxALL, 5 ); |
|||
|
|||
m_cleanViasOpt = new wxCheckBox( this, wxID_ANY, _("&Delete redundant vias"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_cleanViasOpt->SetToolTip( _("remove vias on through hole pads and superimposed vias") ); |
|||
|
|||
bSizerUpper->Add( m_cleanViasOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 ); |
|||
|
|||
m_mergeSegmOpt = new wxCheckBox( this, wxID_ANY, _("&Merge co-linear tracks"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_mergeSegmOpt->SetToolTip( _("merge aligned track segments, and remove null segments") ); |
|||
|
|||
bSizerUpper->Add( m_mergeSegmOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 ); |
|||
|
|||
m_deleteUnconnectedOpt = new wxCheckBox( this, wxID_ANY, _("Delete &dangling tracks"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_deleteUnconnectedOpt->SetToolTip( _("delete tracks having at least one dangling end") ); |
|||
|
|||
bSizerUpper->Add( m_deleteUnconnectedOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 ); |
|||
|
|||
|
|||
bSizerMain->Add( bSizerUpper, 0, wxEXPAND|wxALL, 5 ); |
|||
|
|||
wxBoxSizer* bLowerSizer; |
|||
bLowerSizer = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
bLowerSizer->SetMinSize( wxSize( 660,250 ) ); |
|||
staticChangesLabel = new wxStaticText( this, wxID_ANY, _("Changes To Be Applied:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
staticChangesLabel->Wrap( -1 ); |
|||
bLowerSizer->Add( staticChangesLabel, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); |
|||
|
|||
m_ItemsListBox = new DRCLISTBOX( this, ID_CLEANUP_ITEMS_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); |
|||
bLowerSizer->Add( m_ItemsListBox, 1, wxEXPAND | wxALL, 5 ); |
|||
|
|||
|
|||
bSizerMain->Add( bLowerSizer, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); |
|||
|
|||
m_sdbSizer = new wxStdDialogButtonSizer(); |
|||
m_sdbSizerOK = new wxButton( this, wxID_OK ); |
|||
m_sdbSizer->AddButton( m_sdbSizerOK ); |
|||
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL ); |
|||
m_sdbSizer->AddButton( m_sdbSizerCancel ); |
|||
m_sdbSizer->Realize(); |
|||
|
|||
bSizerMain->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 ); |
|||
|
|||
|
|||
this->SetSizer( bSizerMain ); |
|||
this->Layout(); |
|||
bSizerMain->Fit( this ); |
|||
|
|||
this->Centre( wxBOTH ); |
|||
|
|||
// Connect Events
|
|||
m_cleanShortCircuitOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); |
|||
m_cleanViasOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); |
|||
m_mergeSegmOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); |
|||
m_deleteUnconnectedOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); |
|||
m_ItemsListBox->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnLeftDClickItem ), NULL, this ); |
|||
m_ItemsListBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnSelectItem ), NULL, this ); |
|||
m_ItemsListBox->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnRightUpItem ), NULL, this ); |
|||
} |
|||
|
|||
DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::~DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE() |
|||
{ |
|||
// Disconnect Events
|
|||
m_cleanShortCircuitOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); |
|||
m_cleanViasOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); |
|||
m_mergeSegmOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); |
|||
m_deleteUnconnectedOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); |
|||
m_ItemsListBox->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnLeftDClickItem ), NULL, this ); |
|||
m_ItemsListBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnSelectItem ), NULL, this ); |
|||
m_ItemsListBox->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnRightUpItem ), NULL, this ); |
|||
|
|||
} |
@ -0,0 +1,65 @@ |
|||
/////////////////////////////////////////////////////////////////////////// |
|||
// C++ code generated with wxFormBuilder (version Dec 30 2017) |
|||
// http://www.wxformbuilder.org/ |
|||
// |
|||
// PLEASE DO *NOT* EDIT THIS FILE! |
|||
/////////////////////////////////////////////////////////////////////////// |
|||
|
|||
#ifndef __DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE_H__ |
|||
#define __DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE_H__ |
|||
|
|||
#include <wx/artprov.h> |
|||
#include <wx/xrc/xmlres.h> |
|||
#include <wx/intl.h> |
|||
class DRCLISTBOX; |
|||
|
|||
#include "dialog_shim.h" |
|||
#include <wx/string.h> |
|||
#include <wx/checkbox.h> |
|||
#include <wx/gdicmn.h> |
|||
#include <wx/font.h> |
|||
#include <wx/colour.h> |
|||
#include <wx/settings.h> |
|||
#include <wx/sizer.h> |
|||
#include <wx/stattext.h> |
|||
#include <wx/listbox.h> |
|||
#include <wx/button.h> |
|||
#include <wx/dialog.h> |
|||
|
|||
/////////////////////////////////////////////////////////////////////////// |
|||
|
|||
#define ID_CLEANUP_ITEMS_LIST 1000 |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE : public DIALOG_SHIM |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxCheckBox* m_cleanShortCircuitOpt; |
|||
wxCheckBox* m_cleanViasOpt; |
|||
wxCheckBox* m_mergeSegmOpt; |
|||
wxCheckBox* m_deleteUnconnectedOpt; |
|||
wxStaticText* staticChangesLabel; |
|||
wxStdDialogButtonSizer* m_sdbSizer; |
|||
wxButton* m_sdbSizerOK; |
|||
wxButton* m_sdbSizerCancel; |
|||
|
|||
// Virtual event handlers, overide them in your derived class |
|||
virtual void OnCheckBox( wxCommandEvent& event ) { event.Skip(); } |
|||
virtual void OnLeftDClickItem( wxMouseEvent& event ) { event.Skip(); } |
|||
virtual void OnSelectItem( wxCommandEvent& event ) { event.Skip(); } |
|||
virtual void OnRightUpItem( wxMouseEvent& event ) { event.Skip(); } |
|||
|
|||
|
|||
public: |
|||
DRCLISTBOX* m_ItemsListBox; |
|||
|
|||
DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Cleanup Tracks and Vias"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); |
|||
~DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE(); |
|||
|
|||
}; |
|||
|
|||
#endif //__DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE_H__ |
@ -0,0 +1,118 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
|||
* or you may search the http://www.gnu.org website for the version 2 license, |
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
#ifndef KICAD_TRACKS_CLEANER_H |
|||
#define KICAD_TRACKS_CLEANER_H |
|||
|
|||
#include <class_track.h> |
|||
|
|||
class BOARD; |
|||
class BOARD_COMMIT; |
|||
|
|||
|
|||
// Helper class used to clean tracks and vias |
|||
class TRACKS_CLEANER |
|||
{ |
|||
public: |
|||
TRACKS_CLEANER( EDA_UNITS_T aUnits, BOARD* aPcb, BOARD_COMMIT& aCommit ); |
|||
|
|||
/** |
|||
* the cleanup function. |
|||
* return true if some item was modified |
|||
* @param aCleanVias = true to remove superimposed vias |
|||
* @param aRemoveMisConnected = true to remove segments connecting 2 different nets |
|||
* @param aMergeSegments = true to merge collinear segmenst and remove 0 len segm |
|||
* @param aDeleteUnconnected = true to remove dangling tracks |
|||
* (short circuits) |
|||
*/ |
|||
bool CleanupBoard( bool aDryRun, DRC_LIST* aItemsList, |
|||
bool aCleanVias, bool aRemoveMisConnected, |
|||
bool aMergeSegments, bool aDeleteUnconnected ); |
|||
|
|||
private: |
|||
/* finds and remove all track segments which are connected to more than one net. |
|||
* (short circuits) |
|||
*/ |
|||
bool removeBadTrackSegments(); |
|||
|
|||
/** |
|||
* Removes redundant vias like vias at same location |
|||
* or on pad through |
|||
*/ |
|||
bool cleanupVias(); |
|||
|
|||
/** |
|||
* Removes all the following THT vias on the same position of the |
|||
* specified one |
|||
*/ |
|||
void removeDuplicatesOfVia( const VIA *aVia, std::set<BOARD_ITEM *>& aToRemove ); |
|||
|
|||
/** |
|||
* Removes all the following duplicates tracks of the specified one |
|||
*/ |
|||
void removeDuplicatesOfTrack( const TRACK* aSeg, std::set<BOARD_ITEM*>& aToRemove ); |
|||
|
|||
/** |
|||
* Removes dangling tracks |
|||
*/ |
|||
bool deleteDanglingTracks(); |
|||
|
|||
/// Delete null length track segments |
|||
bool deleteNullSegments(); |
|||
|
|||
/// Try to merge the segment to a following collinear one |
|||
bool MergeCollinearTracks( TRACK* aSegment ); |
|||
|
|||
/** |
|||
* Merge collinear segments and remove duplicated and null len segments |
|||
*/ |
|||
bool cleanupSegments(); |
|||
|
|||
/** |
|||
* helper function |
|||
* Rebuild list of tracks, and connected tracks |
|||
* this info must be rebuilt when tracks are erased |
|||
*/ |
|||
void buildTrackConnectionInfo(); |
|||
|
|||
/** |
|||
* helper function |
|||
* merge aTrackRef and aCandidate, when possible, |
|||
* i.e. when they are colinear, same width, and obviously same layer |
|||
*/ |
|||
TRACK* mergeCollinearSegments( TRACK* aSeg1, |
|||
TRACK* aSeg2, ENDPOINT_T aEndType ); |
|||
|
|||
bool testTrackEndpointDangling( TRACK* aTrack, ENDPOINT_T aEndPoint ); |
|||
|
|||
EDA_UNITS_T m_units; |
|||
BOARD* m_brd; |
|||
BOARD_COMMIT& m_commit; |
|||
bool m_dryRun; |
|||
DRC_LIST* m_itemsList; |
|||
|
|||
bool removeItems( std::set<BOARD_ITEM*>& aItems ); |
|||
}; |
|||
|
|||
|
|||
#endif //KICAD_TRACKS_CLEANER_H |
Write
Preview
Loading…
Cancel
Save
Reference in new issue