Browse Source
Cleanup Graphics to parallel Cleanup Tracks & Vias.
Cleanup Graphics to parallel Cleanup Tracks & Vias.
This also allows for easier migration to DRAWSEGMENT::S_RECTs by auto-converting 4 rectilinear lines to a rectangle.pull/16/head
37 changed files with 1558 additions and 250 deletions
-
59common/rc_item.cpp
-
24common/rc_item.h
-
44eeschema/sch_sheet_path.cpp
-
10include/pcb_base_frame.h
-
4pcbnew/CMakeLists.txt
-
9pcbnew/board_design_settings.cpp
-
1pcbnew/class_marker_pcb.cpp
-
72pcbnew/cleanup_item.cpp
-
124pcbnew/cleanup_item.h
-
149pcbnew/dialogs/dialog_cleanup_graphics.cpp
-
56pcbnew/dialogs/dialog_cleanup_graphics.h
-
76pcbnew/dialogs/dialog_cleanup_graphics_base.cpp
-
323pcbnew/dialogs/dialog_cleanup_graphics_base.fbp
-
57pcbnew/dialogs/dialog_cleanup_graphics_base.h
-
30pcbnew/dialogs/dialog_cleanup_tracks_and_vias.cpp
-
10pcbnew/dialogs/dialog_cleanup_tracks_and_vias.h
-
8pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.fbp
-
12pcbnew/drc/drc.h
-
10pcbnew/drc/drc_item.cpp
-
8pcbnew/drc/drc_item.h
-
4pcbnew/drc/drc_provider.h
-
2pcbnew/footprint_editor_settings.cpp
-
347pcbnew/graphics_cleaner.cpp
-
65pcbnew/graphics_cleaner.h
-
3pcbnew/menubar_footprint_editor.cpp
-
1pcbnew/menubar_pcb_editor.cpp
-
12pcbnew/pcb_base_frame.cpp
-
8pcbnew/pcb_edit_frame.cpp
-
3pcbnew/pcb_edit_frame.h
-
28pcbnew/tools/footprint_editor_tools.cpp
-
2pcbnew/tools/footprint_editor_tools.h
-
30pcbnew/tools/global_edit_tool.cpp
-
1pcbnew/tools/global_edit_tool.h
-
7pcbnew/tools/pcb_actions.cpp
-
1pcbnew/tools/pcb_actions.h
-
152pcbnew/tracks_cleaner.cpp
-
56pcbnew/tracks_cleaner.h
@ -0,0 +1,72 @@ |
|||||
|
/*
|
||||
|
* This program source code file is part of KiCad, a free EDA CAD application. |
||||
|
* |
||||
|
* Copyright (C) 2020 KiCad Developers, see change_log.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 <fctsys.h>
|
||||
|
#include <cleanup_item.h>
|
||||
|
#include <pcb_base_frame.h>
|
||||
|
|
||||
|
|
||||
|
CLEANUP_ITEM::CLEANUP_ITEM( int aErrorCode ) |
||||
|
{ |
||||
|
m_errorCode = aErrorCode; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
wxString CLEANUP_ITEM::GetErrorText( int aCode, bool aTranslate ) const |
||||
|
{ |
||||
|
wxString msg; |
||||
|
|
||||
|
if( aCode < 0 ) |
||||
|
aCode = m_errorCode; |
||||
|
|
||||
|
switch( aCode ) |
||||
|
{ |
||||
|
// For cleanup tracks and vias:
|
||||
|
case CLEANUP_SHORT: msg = _HKI( "Remove track shorting two nets" ); break; |
||||
|
case CLEANUP_REDUNDANT_VIA: msg = _HKI( "Remove redundant via" ); break; |
||||
|
case CLEANUP_DUPLICATE_TRACK: msg = _HKI( "Remove duplicate track" ); break; |
||||
|
case CLEANUP_MERGE_TRACKS: msg = _HKI( "Merge co-linear tracks" ); break; |
||||
|
case CLEANUP_DANGLING_TRACK: msg = _HKI( "Remove dangling track" ); break; |
||||
|
case CLEANUP_DANGLING_VIA: msg = _HKI( "Remove dangling via" ); break; |
||||
|
case CLEANUP_ZERO_LENGTH_TRACK: msg = _HKI( "Remove zero-length track" ); break; |
||||
|
case CLEANUP_TRACK_IN_PAD: msg = _HKI( "Remove track inside pad" ); break; |
||||
|
|
||||
|
// For cleanup graphics:
|
||||
|
case CLEANUP_NULL_GRAPHIC: msg = _HKI( "Remove zero-size graphic" ); break; |
||||
|
case CLEANUP_DUPLICATE_GRAPHIC: msg = _HKI( "Remove duplicated graphic" ); break; |
||||
|
case CLEANUP_LINES_TO_RECT: msg = _HKI( "Convert lines to rectangle" ); break; |
||||
|
|
||||
|
default: |
||||
|
wxFAIL_MSG( "Missing cleanup item description" ); |
||||
|
msg = _HKI( "Unknown cleanup action" ); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
if( aTranslate ) |
||||
|
return wxGetTranslation( msg ); |
||||
|
else |
||||
|
return msg; |
||||
|
} |
||||
|
|
||||
|
|
||||
@ -0,0 +1,124 @@ |
|||||
|
/* |
||||
|
* This program source code file is part of KiCad, a free EDA CAD application. |
||||
|
* |
||||
|
* Copyright (C) 2020 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 CLEANUP_ITEM_H |
||||
|
#define CLEANUP_ITEM_H |
||||
|
|
||||
|
#include <rc_item.h> |
||||
|
#include <drc/drc.h> |
||||
|
|
||||
|
class PCB_BASE_FRAME; |
||||
|
|
||||
|
|
||||
|
enum CLEANUP_RC_CODE { |
||||
|
CLEANUP_FIRST = DRCE_LAST + 1, |
||||
|
CLEANUP_SHORT = CLEANUP_FIRST, |
||||
|
CLEANUP_REDUNDANT_VIA, |
||||
|
CLEANUP_DUPLICATE_TRACK, |
||||
|
CLEANUP_MERGE_TRACKS, |
||||
|
CLEANUP_DANGLING_TRACK, |
||||
|
CLEANUP_DANGLING_VIA, |
||||
|
CLEANUP_ZERO_LENGTH_TRACK, |
||||
|
CLEANUP_TRACK_IN_PAD, |
||||
|
CLEANUP_NULL_GRAPHIC, |
||||
|
CLEANUP_DUPLICATE_GRAPHIC, |
||||
|
CLEANUP_LINES_TO_RECT |
||||
|
}; |
||||
|
|
||||
|
class CLEANUP_ITEM : public RC_ITEM |
||||
|
{ |
||||
|
public: |
||||
|
CLEANUP_ITEM( int aErrorCode ); |
||||
|
|
||||
|
/** |
||||
|
* Function GetErrorText |
||||
|
* returns the string form of a drc error code. |
||||
|
*/ |
||||
|
wxString GetErrorText( int aErrorCode = -1, bool aTranslate = true ) const override; |
||||
|
|
||||
|
/** |
||||
|
* Function ShowHtml |
||||
|
* translates this object into a fragment of HTML suitable for the wxHtmlListBox class. |
||||
|
* @return wxString - the html text. |
||||
|
*/ |
||||
|
wxString ShowHtml( PCB_BASE_FRAME* aFrame ) const; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* VECTOR_CLEANUP_ITEMS_PROVIDER |
||||
|
* is an implementation of the interface named RC_ITEMS_PROVIDER which uses a vector |
||||
|
* of pointers to CLEANUP_ITEMs to fulfill the interface. No ownership is taken of the |
||||
|
* vector. |
||||
|
*/ |
||||
|
class VECTOR_CLEANUP_ITEMS_PROVIDER : public RC_ITEMS_PROVIDER |
||||
|
{ |
||||
|
std::vector<CLEANUP_ITEM*>* m_sourceVector; // owns its CLEANUP_ITEMs |
||||
|
|
||||
|
public: |
||||
|
|
||||
|
VECTOR_CLEANUP_ITEMS_PROVIDER( std::vector<CLEANUP_ITEM*>* aList ) : |
||||
|
m_sourceVector( aList ) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void SetSeverities( int aSeverities ) override |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
int GetCount( int aSeverity = -1 ) override |
||||
|
{ |
||||
|
return m_sourceVector->size(); |
||||
|
} |
||||
|
|
||||
|
CLEANUP_ITEM* GetItem( int aIndex ) override |
||||
|
{ |
||||
|
return m_sourceVector->at( aIndex ); |
||||
|
} |
||||
|
|
||||
|
void DeleteItem( int aIndex, bool aDeep ) override |
||||
|
{ |
||||
|
if( aDeep ) |
||||
|
{ |
||||
|
CLEANUP_ITEM* item = m_sourceVector->at( aIndex ); |
||||
|
delete item; |
||||
|
|
||||
|
m_sourceVector->erase( m_sourceVector->begin() + aIndex ); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void DeleteAllItems() override |
||||
|
{ |
||||
|
if( m_sourceVector ) |
||||
|
{ |
||||
|
for( CLEANUP_ITEM* item : *m_sourceVector ) |
||||
|
delete item; |
||||
|
|
||||
|
m_sourceVector->clear(); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
|
||||
|
#endif // CLEANUP_ITEM_H |
||||
@ -0,0 +1,149 @@ |
|||||
|
/*
|
||||
|
* This program source code file is part of KiCad, a free EDA CAD application. |
||||
|
* |
||||
|
* Copyright (C) 2020 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_graphics.h>
|
||||
|
#include <tool/tool_manager.h>
|
||||
|
#include <tools/pcb_actions.h>
|
||||
|
#include <graphics_cleaner.h>
|
||||
|
|
||||
|
|
||||
|
DIALOG_CLEANUP_GRAPHICS::DIALOG_CLEANUP_GRAPHICS( PCB_BASE_FRAME* aParent, bool isModEdit ) : |
||||
|
DIALOG_CLEANUP_GRAPHICS_BASE( aParent ), |
||||
|
m_parentFrame( aParent ), |
||||
|
m_isModEdit( isModEdit ) |
||||
|
{ |
||||
|
m_changesTreeModel = new RC_TREE_MODEL( m_parentFrame, m_changesDataView ); |
||||
|
m_changesDataView->AssociateModel( m_changesTreeModel ); |
||||
|
|
||||
|
m_changesTreeModel->SetSeverities( RPT_SEVERITY_ACTION ); |
||||
|
|
||||
|
// 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( isModEdit ? _( "Update Footprint" ) : _( "Update PCB" ) ); |
||||
|
|
||||
|
m_sdbSizerOK->SetDefault(); |
||||
|
GetSizer()->SetSizeHints(this); |
||||
|
Centre(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
DIALOG_CLEANUP_GRAPHICS::~DIALOG_CLEANUP_GRAPHICS() |
||||
|
{ |
||||
|
for( CLEANUP_ITEM* item : m_items ) |
||||
|
delete item; |
||||
|
|
||||
|
m_changesTreeModel->DecRef(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void DIALOG_CLEANUP_GRAPHICS::OnCheckBox( wxCommandEvent& anEvent ) |
||||
|
{ |
||||
|
doCleanup( true ); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
bool DIALOG_CLEANUP_GRAPHICS::TransferDataToWindow() |
||||
|
{ |
||||
|
doCleanup( true ); |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
bool DIALOG_CLEANUP_GRAPHICS::TransferDataFromWindow() |
||||
|
{ |
||||
|
doCleanup( false ); |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void DIALOG_CLEANUP_GRAPHICS::doCleanup( bool aDryRun ) |
||||
|
{ |
||||
|
wxBusyCursor busy; |
||||
|
|
||||
|
BOARD_COMMIT commit( m_parentFrame ); |
||||
|
BOARD* board = m_parentFrame->GetBoard(); |
||||
|
MODULE* fp = m_isModEdit ? board->GetFirstModule() : nullptr; |
||||
|
GRAPHICS_CLEANER cleaner( fp ? fp->GraphicalItems() : board->Drawings(), fp, commit ); |
||||
|
|
||||
|
if( !aDryRun ) |
||||
|
{ |
||||
|
// Clear current selection list to avoid selection of deleted items
|
||||
|
m_parentFrame->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true ); |
||||
|
|
||||
|
// ... and to keep the treeModel from trying to refresh a deleted item
|
||||
|
m_changesTreeModel->SetProvider( nullptr ); |
||||
|
} |
||||
|
|
||||
|
for( CLEANUP_ITEM* item : m_items ) |
||||
|
delete item; |
||||
|
|
||||
|
m_items.clear(); |
||||
|
|
||||
|
// Old model has to be refreshed, GAL normally does not keep updating it
|
||||
|
m_parentFrame->Compile_Ratsnest( false ); |
||||
|
|
||||
|
cleaner.CleanupBoard( aDryRun, &m_items, m_createRectanglesOpt->GetValue(), |
||||
|
m_deleteRedundantOpt->GetValue() ); |
||||
|
|
||||
|
if( aDryRun ) |
||||
|
{ |
||||
|
RC_ITEMS_PROVIDER* provider = new VECTOR_CLEANUP_ITEMS_PROVIDER( &m_items ); |
||||
|
m_changesTreeModel->SetProvider( provider ); |
||||
|
} |
||||
|
else if( !commit.Empty() ) |
||||
|
{ |
||||
|
// Clear undo and redo lists to avoid inconsistencies between lists
|
||||
|
commit.Push( _( "Graphics cleanup" ) ); |
||||
|
m_parentFrame->GetCanvas()->Refresh( true ); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void DIALOG_CLEANUP_GRAPHICS::OnSelectItem( wxDataViewEvent& aEvent ) |
||||
|
{ |
||||
|
const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() ); |
||||
|
BOARD_ITEM* item = m_parentFrame->GetBoard()->GetItem( itemID ); |
||||
|
WINDOW_THAWER thawer( m_parentFrame ); |
||||
|
|
||||
|
m_parentFrame->FocusOnItem( item ); |
||||
|
m_parentFrame->GetCanvas()->Refresh(); |
||||
|
|
||||
|
aEvent.Skip(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void DIALOG_CLEANUP_GRAPHICS::OnLeftDClickItem( wxMouseEvent& event ) |
||||
|
{ |
||||
|
event.Skip(); |
||||
|
|
||||
|
if( m_changesDataView->GetCurrentItem().IsOk() ) |
||||
|
{ |
||||
|
if( !IsModal() ) |
||||
|
Show( false ); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
@ -0,0 +1,56 @@ |
|||||
|
/* |
||||
|
* This program source code file is part of KiCad, a free EDA CAD application. |
||||
|
* |
||||
|
* Copyright (C) 2010-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr |
||||
|
* 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 |
||||
|
*/ |
||||
|
|
||||
|
#ifndef DIALOG_CLEANUP_GRAPHICS_H_ |
||||
|
#define DIALOG_CLEANUP_GRAPHICS_H_ |
||||
|
|
||||
|
#include <dialog_cleanup_graphics_base.h> |
||||
|
#include <cleanup_item.h> |
||||
|
|
||||
|
|
||||
|
class PCB_BASE_FRAME; |
||||
|
|
||||
|
|
||||
|
class DIALOG_CLEANUP_GRAPHICS: public DIALOG_CLEANUP_GRAPHICS_BASE |
||||
|
{ |
||||
|
PCB_BASE_FRAME* m_parentFrame; |
||||
|
bool m_isModEdit; |
||||
|
std::vector<CLEANUP_ITEM*> m_items; |
||||
|
RC_TREE_MODEL* m_changesTreeModel; |
||||
|
|
||||
|
void doCleanup( bool aDryRun ); |
||||
|
|
||||
|
void OnCheckBox( wxCommandEvent& anEvent ) override; |
||||
|
void OnSelectItem( wxDataViewEvent& event ) override; |
||||
|
void OnLeftDClickItem( wxMouseEvent& event ) override; |
||||
|
|
||||
|
bool TransferDataToWindow() override; |
||||
|
bool TransferDataFromWindow() override; |
||||
|
|
||||
|
public: |
||||
|
DIALOG_CLEANUP_GRAPHICS( PCB_BASE_FRAME* aParent, bool isModEdit ); |
||||
|
~DIALOG_CLEANUP_GRAPHICS(); |
||||
|
}; |
||||
|
|
||||
|
#endif // DIALOG_CLEANUP_GRAPHICS_H_ |
||||
@ -0,0 +1,76 @@ |
|||||
|
///////////////////////////////////////////////////////////////////////////
|
||||
|
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
|
// http://www.wxformbuilder.org/
|
||||
|
//
|
||||
|
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
///////////////////////////////////////////////////////////////////////////
|
||||
|
|
||||
|
#include "dialog_cleanup_graphics_base.h"
|
||||
|
|
||||
|
///////////////////////////////////////////////////////////////////////////
|
||||
|
|
||||
|
DIALOG_CLEANUP_GRAPHICS_BASE::DIALOG_CLEANUP_GRAPHICS_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_createRectanglesOpt = new wxCheckBox( this, wxID_ANY, _("Merge lines into rectangles"), wxDefaultPosition, wxDefaultSize, 0 ); |
||||
|
m_createRectanglesOpt->SetToolTip( _("remove track segments connecting nodes belonging to different nets (short circuit)") ); |
||||
|
|
||||
|
bSizerUpper->Add( m_createRectanglesOpt, 0, wxALL, 5 ); |
||||
|
|
||||
|
m_deleteRedundantOpt = new wxCheckBox( this, wxID_ANY, _("Delete redundant graphics"), wxDefaultPosition, wxDefaultSize, 0 ); |
||||
|
bSizerUpper->Add( m_deleteRedundantOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 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_changesDataView = new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_NO_HEADER ); |
||||
|
bLowerSizer->Add( m_changesDataView, 1, wxALL|wxEXPAND, 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_createRectanglesOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_GRAPHICS_BASE::OnCheckBox ), NULL, this ); |
||||
|
m_changesDataView->Connect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_CLEANUP_GRAPHICS_BASE::OnSelectItem ), NULL, this ); |
||||
|
m_changesDataView->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_CLEANUP_GRAPHICS_BASE::OnLeftDClickItem ), NULL, this ); |
||||
|
} |
||||
|
|
||||
|
DIALOG_CLEANUP_GRAPHICS_BASE::~DIALOG_CLEANUP_GRAPHICS_BASE() |
||||
|
{ |
||||
|
// Disconnect Events
|
||||
|
m_createRectanglesOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_GRAPHICS_BASE::OnCheckBox ), NULL, this ); |
||||
|
m_changesDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_CLEANUP_GRAPHICS_BASE::OnSelectItem ), NULL, this ); |
||||
|
m_changesDataView->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_CLEANUP_GRAPHICS_BASE::OnLeftDClickItem ), NULL, this ); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,323 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> |
||||
|
<wxFormBuilder_Project> |
||||
|
<FileVersion major="1" minor="15" /> |
||||
|
<object class="Project" expanded="1"> |
||||
|
<property name="class_decoration"></property> |
||||
|
<property name="code_generation">C++</property> |
||||
|
<property name="disconnect_events">1</property> |
||||
|
<property name="disconnect_mode">source_name</property> |
||||
|
<property name="disconnect_php_events">0</property> |
||||
|
<property name="disconnect_python_events">0</property> |
||||
|
<property name="embedded_files_path">res</property> |
||||
|
<property name="encoding">UTF-8</property> |
||||
|
<property name="event_generation">connect</property> |
||||
|
<property name="file">dialog_cleanup_graphics_base</property> |
||||
|
<property name="first_id">1000</property> |
||||
|
<property name="help_provider">none</property> |
||||
|
<property name="indent_with_spaces"></property> |
||||
|
<property name="internationalize">1</property> |
||||
|
<property name="name">dialog_cleanup_graphics</property> |
||||
|
<property name="namespace"></property> |
||||
|
<property name="path">.</property> |
||||
|
<property name="precompiled_header"></property> |
||||
|
<property name="relative_path">1</property> |
||||
|
<property name="skip_lua_events">1</property> |
||||
|
<property name="skip_php_events">1</property> |
||||
|
<property name="skip_python_events">1</property> |
||||
|
<property name="ui_table">UI</property> |
||||
|
<property name="use_enum">0</property> |
||||
|
<property name="use_microsoft_bom">0</property> |
||||
|
<object class="Dialog" expanded="1"> |
||||
|
<property name="aui_managed">0</property> |
||||
|
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property> |
||||
|
<property name="bg"></property> |
||||
|
<property name="center">wxBOTH</property> |
||||
|
<property name="context_help"></property> |
||||
|
<property name="context_menu">1</property> |
||||
|
<property name="enabled">1</property> |
||||
|
<property name="event_handler">impl_virtual</property> |
||||
|
<property name="extra_style"></property> |
||||
|
<property name="fg"></property> |
||||
|
<property name="font"></property> |
||||
|
<property name="hidden">0</property> |
||||
|
<property name="id">wxID_ANY</property> |
||||
|
<property name="maximum_size"></property> |
||||
|
<property name="minimum_size"></property> |
||||
|
<property name="name">DIALOG_CLEANUP_GRAPHICS_BASE</property> |
||||
|
<property name="pos"></property> |
||||
|
<property name="size">-1,-1</property> |
||||
|
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> |
||||
|
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property> |
||||
|
<property name="title">Cleanup Graphics</property> |
||||
|
<property name="tooltip"></property> |
||||
|
<property name="window_extra_style"></property> |
||||
|
<property name="window_name"></property> |
||||
|
<property name="window_style"></property> |
||||
|
<object class="wxBoxSizer" expanded="1"> |
||||
|
<property name="minimum_size"></property> |
||||
|
<property name="name">bSizerMain</property> |
||||
|
<property name="orient">wxVERTICAL</property> |
||||
|
<property name="permission">none</property> |
||||
|
<object class="sizeritem" expanded="1"> |
||||
|
<property name="border">5</property> |
||||
|
<property name="flag">wxEXPAND|wxALL</property> |
||||
|
<property name="proportion">0</property> |
||||
|
<object class="wxBoxSizer" expanded="1"> |
||||
|
<property name="minimum_size"></property> |
||||
|
<property name="name">bSizerUpper</property> |
||||
|
<property name="orient">wxVERTICAL</property> |
||||
|
<property name="permission">none</property> |
||||
|
<object class="sizeritem" expanded="0"> |
||||
|
<property name="border">5</property> |
||||
|
<property name="flag">wxALL</property> |
||||
|
<property name="proportion">0</property> |
||||
|
<object class="wxCheckBox" expanded="0"> |
||||
|
<property name="BottomDockable">1</property> |
||||
|
<property name="LeftDockable">1</property> |
||||
|
<property name="RightDockable">1</property> |
||||
|
<property name="TopDockable">1</property> |
||||
|
<property name="aui_layer"></property> |
||||
|
<property name="aui_name"></property> |
||||
|
<property name="aui_position"></property> |
||||
|
<property name="aui_row"></property> |
||||
|
<property name="best_size"></property> |
||||
|
<property name="bg"></property> |
||||
|
<property name="caption"></property> |
||||
|
<property name="caption_visible">1</property> |
||||
|
<property name="center_pane">0</property> |
||||
|
<property name="checked">0</property> |
||||
|
<property name="close_button">1</property> |
||||
|
<property name="context_help"></property> |
||||
|
<property name="context_menu">1</property> |
||||
|
<property name="default_pane">0</property> |
||||
|
<property name="dock">Dock</property> |
||||
|
<property name="dock_fixed">0</property> |
||||
|
<property name="docking">Left</property> |
||||
|
<property name="enabled">1</property> |
||||
|
<property name="fg"></property> |
||||
|
<property name="floatable">1</property> |
||||
|
<property name="font"></property> |
||||
|
<property name="gripper">0</property> |
||||
|
<property name="hidden">0</property> |
||||
|
<property name="id">wxID_ANY</property> |
||||
|
<property name="label">Merge lines into rectangles</property> |
||||
|
<property name="max_size"></property> |
||||
|
<property name="maximize_button">0</property> |
||||
|
<property name="maximum_size"></property> |
||||
|
<property name="min_size"></property> |
||||
|
<property name="minimize_button">0</property> |
||||
|
<property name="minimum_size"></property> |
||||
|
<property name="moveable">1</property> |
||||
|
<property name="name">m_createRectanglesOpt</property> |
||||
|
<property name="pane_border">1</property> |
||||
|
<property name="pane_position"></property> |
||||
|
<property name="pane_size"></property> |
||||
|
<property name="permission">protected</property> |
||||
|
<property name="pin_button">1</property> |
||||
|
<property name="pos"></property> |
||||
|
<property name="resize">Resizable</property> |
||||
|
<property name="show">1</property> |
||||
|
<property name="size"></property> |
||||
|
<property name="style"></property> |
||||
|
<property name="subclass"></property> |
||||
|
<property name="toolbar_pane">0</property> |
||||
|
<property name="tooltip">remove track segments connecting nodes belonging to different nets (short circuit)</property> |
||||
|
<property name="validator_data_type"></property> |
||||
|
<property name="validator_style">wxFILTER_NUMERIC</property> |
||||
|
<property name="validator_type">wxDefaultValidator</property> |
||||
|
<property name="validator_variable"></property> |
||||
|
<property name="window_extra_style"></property> |
||||
|
<property name="window_name"></property> |
||||
|
<property name="window_style"></property> |
||||
|
<event name="OnCheckBox">OnCheckBox</event> |
||||
|
</object> |
||||
|
</object> |
||||
|
<object class="sizeritem" expanded="1"> |
||||
|
<property name="border">5</property> |
||||
|
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property> |
||||
|
<property name="proportion">0</property> |
||||
|
<object class="wxCheckBox" expanded="1"> |
||||
|
<property name="BottomDockable">1</property> |
||||
|
<property name="LeftDockable">1</property> |
||||
|
<property name="RightDockable">1</property> |
||||
|
<property name="TopDockable">1</property> |
||||
|
<property name="aui_layer"></property> |
||||
|
<property name="aui_name"></property> |
||||
|
<property name="aui_position"></property> |
||||
|
<property name="aui_row"></property> |
||||
|
<property name="best_size"></property> |
||||
|
<property name="bg"></property> |
||||
|
<property name="caption"></property> |
||||
|
<property name="caption_visible">1</property> |
||||
|
<property name="center_pane">0</property> |
||||
|
<property name="checked">0</property> |
||||
|
<property name="close_button">1</property> |
||||
|
<property name="context_help"></property> |
||||
|
<property name="context_menu">1</property> |
||||
|
<property name="default_pane">0</property> |
||||
|
<property name="dock">Dock</property> |
||||
|
<property name="dock_fixed">0</property> |
||||
|
<property name="docking">Left</property> |
||||
|
<property name="enabled">1</property> |
||||
|
<property name="fg"></property> |
||||
|
<property name="floatable">1</property> |
||||
|
<property name="font"></property> |
||||
|
<property name="gripper">0</property> |
||||
|
<property name="hidden">0</property> |
||||
|
<property name="id">wxID_ANY</property> |
||||
|
<property name="label">Delete redundant graphics</property> |
||||
|
<property name="max_size"></property> |
||||
|
<property name="maximize_button">0</property> |
||||
|
<property name="maximum_size"></property> |
||||
|
<property name="min_size"></property> |
||||
|
<property name="minimize_button">0</property> |
||||
|
<property name="minimum_size"></property> |
||||
|
<property name="moveable">1</property> |
||||
|
<property name="name">m_deleteRedundantOpt</property> |
||||
|
<property name="pane_border">1</property> |
||||
|
<property name="pane_position"></property> |
||||
|
<property name="pane_size"></property> |
||||
|
<property name="permission">protected</property> |
||||
|
<property name="pin_button">1</property> |
||||
|
<property name="pos"></property> |
||||
|
<property name="resize">Resizable</property> |
||||
|
<property name="show">1</property> |
||||
|
<property name="size"></property> |
||||
|
<property name="style"></property> |
||||
|
<property name="subclass">; ; forward_declare</property> |
||||
|
<property name="toolbar_pane">0</property> |
||||
|
<property name="tooltip"></property> |
||||
|
<property name="validator_data_type"></property> |
||||
|
<property name="validator_style">wxFILTER_NONE</property> |
||||
|
<property name="validator_type">wxDefaultValidator</property> |
||||
|
<property name="validator_variable"></property> |
||||
|
<property name="window_extra_style"></property> |
||||
|
<property name="window_name"></property> |
||||
|
<property name="window_style"></property> |
||||
|
</object> |
||||
|
</object> |
||||
|
</object> |
||||
|
</object> |
||||
|
<object class="sizeritem" expanded="1"> |
||||
|
<property name="border">5</property> |
||||
|
<property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property> |
||||
|
<property name="proportion">1</property> |
||||
|
<object class="wxBoxSizer" expanded="1"> |
||||
|
<property name="minimum_size">660,250</property> |
||||
|
<property name="name">bLowerSizer</property> |
||||
|
<property name="orient">wxVERTICAL</property> |
||||
|
<property name="permission">none</property> |
||||
|
<object class="sizeritem" expanded="0"> |
||||
|
<property name="border">5</property> |
||||
|
<property name="flag">wxTOP|wxRIGHT|wxLEFT</property> |
||||
|
<property name="proportion">0</property> |
||||
|
<object class="wxStaticText" expanded="0"> |
||||
|
<property name="BottomDockable">1</property> |
||||
|
<property name="LeftDockable">1</property> |
||||
|
<property name="RightDockable">1</property> |
||||
|
<property name="TopDockable">1</property> |
||||
|
<property name="aui_layer"></property> |
||||
|
<property name="aui_name"></property> |
||||
|
<property name="aui_position"></property> |
||||
|
<property name="aui_row"></property> |
||||
|
<property name="best_size"></property> |
||||
|
<property name="bg"></property> |
||||
|
<property name="caption"></property> |
||||
|
<property name="caption_visible">1</property> |
||||
|
<property name="center_pane">0</property> |
||||
|
<property name="close_button">1</property> |
||||
|
<property name="context_help"></property> |
||||
|
<property name="context_menu">1</property> |
||||
|
<property name="default_pane">0</property> |
||||
|
<property name="dock">Dock</property> |
||||
|
<property name="dock_fixed">0</property> |
||||
|
<property name="docking">Left</property> |
||||
|
<property name="enabled">1</property> |
||||
|
<property name="fg"></property> |
||||
|
<property name="floatable">1</property> |
||||
|
<property name="font"></property> |
||||
|
<property name="gripper">0</property> |
||||
|
<property name="hidden">0</property> |
||||
|
<property name="id">wxID_ANY</property> |
||||
|
<property name="label">Changes To Be Applied:</property> |
||||
|
<property name="markup">0</property> |
||||
|
<property name="max_size"></property> |
||||
|
<property name="maximize_button">0</property> |
||||
|
<property name="maximum_size"></property> |
||||
|
<property name="min_size"></property> |
||||
|
<property name="minimize_button">0</property> |
||||
|
<property name="minimum_size"></property> |
||||
|
<property name="moveable">1</property> |
||||
|
<property name="name">staticChangesLabel</property> |
||||
|
<property name="pane_border">1</property> |
||||
|
<property name="pane_position"></property> |
||||
|
<property name="pane_size"></property> |
||||
|
<property name="permission">protected</property> |
||||
|
<property name="pin_button">1</property> |
||||
|
<property name="pos"></property> |
||||
|
<property name="resize">Resizable</property> |
||||
|
<property name="show">1</property> |
||||
|
<property name="size"></property> |
||||
|
<property name="style"></property> |
||||
|
<property name="subclass">; forward_declare</property> |
||||
|
<property name="toolbar_pane">0</property> |
||||
|
<property name="tooltip"></property> |
||||
|
<property name="window_extra_style"></property> |
||||
|
<property name="window_name"></property> |
||||
|
<property name="window_style"></property> |
||||
|
<property name="wrap">-1</property> |
||||
|
</object> |
||||
|
</object> |
||||
|
<object class="sizeritem" expanded="1"> |
||||
|
<property name="border">5</property> |
||||
|
<property name="flag">wxALL|wxEXPAND</property> |
||||
|
<property name="proportion">1</property> |
||||
|
<object class="wxDataViewCtrl" expanded="1"> |
||||
|
<property name="bg"></property> |
||||
|
<property name="context_help"></property> |
||||
|
<property name="context_menu">1</property> |
||||
|
<property name="enabled">1</property> |
||||
|
<property name="fg"></property> |
||||
|
<property name="font"></property> |
||||
|
<property name="hidden">0</property> |
||||
|
<property name="id">wxID_ANY</property> |
||||
|
<property name="maximum_size"></property> |
||||
|
<property name="minimum_size"></property> |
||||
|
<property name="name">m_changesDataView</property> |
||||
|
<property name="permission">protected</property> |
||||
|
<property name="pos"></property> |
||||
|
<property name="size"></property> |
||||
|
<property name="style">wxDV_NO_HEADER</property> |
||||
|
<property name="subclass">; ; forward_declare</property> |
||||
|
<property name="tooltip"></property> |
||||
|
<property name="window_extra_style"></property> |
||||
|
<property name="window_name"></property> |
||||
|
<property name="window_style"></property> |
||||
|
<event name="OnDataViewCtrlSelectionChanged">OnSelectItem</event> |
||||
|
<event name="OnLeftDClick">OnLeftDClickItem</event> |
||||
|
</object> |
||||
|
</object> |
||||
|
</object> |
||||
|
</object> |
||||
|
<object class="sizeritem" expanded="0"> |
||||
|
<property name="border">5</property> |
||||
|
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property> |
||||
|
<property name="proportion">0</property> |
||||
|
<object class="wxStdDialogButtonSizer" expanded="0"> |
||||
|
<property name="Apply">0</property> |
||||
|
<property name="Cancel">1</property> |
||||
|
<property name="ContextHelp">0</property> |
||||
|
<property name="Help">0</property> |
||||
|
<property name="No">0</property> |
||||
|
<property name="OK">1</property> |
||||
|
<property name="Save">0</property> |
||||
|
<property name="Yes">0</property> |
||||
|
<property name="minimum_size"></property> |
||||
|
<property name="name">m_sdbSizer</property> |
||||
|
<property name="permission">protected</property> |
||||
|
</object> |
||||
|
</object> |
||||
|
</object> |
||||
|
</object> |
||||
|
</object> |
||||
|
</wxFormBuilder_Project> |
||||
@ -0,0 +1,57 @@ |
|||||
|
/////////////////////////////////////////////////////////////////////////// |
||||
|
// C++ code generated with wxFormBuilder (version Oct 26 2018) |
||||
|
// http://www.wxformbuilder.org/ |
||||
|
// |
||||
|
// PLEASE DO *NOT* EDIT THIS FILE! |
||||
|
/////////////////////////////////////////////////////////////////////////// |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#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/stattext.h> |
||||
|
#include <wx/dataview.h> |
||||
|
#include <wx/button.h> |
||||
|
#include <wx/dialog.h> |
||||
|
|
||||
|
/////////////////////////////////////////////////////////////////////////// |
||||
|
|
||||
|
|
||||
|
/////////////////////////////////////////////////////////////////////////////// |
||||
|
/// Class DIALOG_CLEANUP_GRAPHICS_BASE |
||||
|
/////////////////////////////////////////////////////////////////////////////// |
||||
|
class DIALOG_CLEANUP_GRAPHICS_BASE : public DIALOG_SHIM |
||||
|
{ |
||||
|
private: |
||||
|
|
||||
|
protected: |
||||
|
wxCheckBox* m_createRectanglesOpt; |
||||
|
wxCheckBox* m_deleteRedundantOpt; |
||||
|
wxStaticText* staticChangesLabel; |
||||
|
wxDataViewCtrl* m_changesDataView; |
||||
|
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 OnSelectItem( wxDataViewEvent& event ) { event.Skip(); } |
||||
|
virtual void OnLeftDClickItem( wxMouseEvent& event ) { event.Skip(); } |
||||
|
|
||||
|
|
||||
|
public: |
||||
|
|
||||
|
DIALOG_CLEANUP_GRAPHICS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Cleanup Graphics"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); |
||||
|
~DIALOG_CLEANUP_GRAPHICS_BASE(); |
||||
|
|
||||
|
}; |
||||
|
|
||||
@ -0,0 +1,347 @@ |
|||||
|
/*
|
||||
|
* This program source code file is part of KiCad, a free EDA CAD application. |
||||
|
* |
||||
|
* Copyright (C) 2004-2018 Jean-Pierre Charras, jp.charras at wanadoo.fr |
||||
|
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net> |
||||
|
* Copyright (C) 1992-2020 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 <fctsys.h>
|
||||
|
#include <reporter.h>
|
||||
|
#include <board_commit.h>
|
||||
|
#include <cleanup_item.h>
|
||||
|
#include <class_drawsegment.h>
|
||||
|
#include <class_edge_mod.h>
|
||||
|
#include <graphics_cleaner.h>
|
||||
|
|
||||
|
|
||||
|
GRAPHICS_CLEANER::GRAPHICS_CLEANER( DRAWINGS& aDrawings, MODULE* aParentModule, |
||||
|
BOARD_COMMIT& aCommit ) : |
||||
|
m_drawings( aDrawings ), |
||||
|
m_parentModule( aParentModule ), |
||||
|
m_commit( aCommit ), |
||||
|
m_dryRun( true ), |
||||
|
m_itemsList( nullptr ) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void GRAPHICS_CLEANER::CleanupBoard( bool aDryRun, std::vector<CLEANUP_ITEM*>* aItemsList, |
||||
|
bool aMergeRects, bool aDeleteRedundant ) |
||||
|
{ |
||||
|
m_dryRun = aDryRun; |
||||
|
m_itemsList = aItemsList; |
||||
|
|
||||
|
// Clear the flag used to mark some segments as deleted, in dry run:
|
||||
|
for( BOARD_ITEM* drawing : m_drawings ) |
||||
|
drawing->ClearFlags( IS_DELETED ); |
||||
|
|
||||
|
if( aDeleteRedundant ) |
||||
|
cleanupSegments(); |
||||
|
|
||||
|
if( aMergeRects ) |
||||
|
mergeRects(); |
||||
|
|
||||
|
// Clear the flag used to mark some segments:
|
||||
|
for( BOARD_ITEM* drawing : m_drawings ) |
||||
|
drawing->ClearFlags( IS_DELETED ); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
bool GRAPHICS_CLEANER::isNullSegment( DRAWSEGMENT* aSegment ) |
||||
|
{ |
||||
|
switch( aSegment->GetShape() ) |
||||
|
{ |
||||
|
case S_SEGMENT: |
||||
|
case S_RECT: |
||||
|
return aSegment->GetStart() == aSegment->GetEnd(); |
||||
|
|
||||
|
case S_CIRCLE: |
||||
|
return aSegment->GetRadius() == 0; |
||||
|
|
||||
|
case S_ARC: |
||||
|
return aSegment->GetCenter().x == aSegment->GetArcStart().x |
||||
|
&& aSegment->GetCenter().y == aSegment->GetArcStart().y; |
||||
|
|
||||
|
case S_POLYGON: |
||||
|
return aSegment->GetPointCount() == 0; |
||||
|
|
||||
|
case S_CURVE: |
||||
|
aSegment->RebuildBezierToSegmentsPointsList( aSegment->GetWidth() ); |
||||
|
return aSegment->GetBezierPoints().empty(); |
||||
|
|
||||
|
default: |
||||
|
wxFAIL_MSG( wxString::Format( "unknown DRAWSEGMENT shape: %d", aSegment->GetShape() ) ); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
bool GRAPHICS_CLEANER::areEquivalent( DRAWSEGMENT* aSegment1, DRAWSEGMENT* aSegment2 ) |
||||
|
{ |
||||
|
if( aSegment1->GetShape() != aSegment2->GetShape() |
||||
|
|| aSegment1->GetLayer() != aSegment2->GetLayer() |
||||
|
|| aSegment1->GetWidth() != aSegment2->GetWidth() ) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
switch( aSegment1->GetShape() ) |
||||
|
{ |
||||
|
case S_SEGMENT: |
||||
|
case S_RECT: |
||||
|
case S_CIRCLE: |
||||
|
return aSegment1->GetStart() == aSegment2->GetStart() |
||||
|
&& aSegment1->GetEnd() == aSegment2->GetEnd(); |
||||
|
|
||||
|
case S_ARC: |
||||
|
return aSegment1->GetCenter() == aSegment2->GetCenter() |
||||
|
&& aSegment1->GetArcStart() == aSegment2->GetArcStart() |
||||
|
&& aSegment1->GetAngle() == aSegment2->GetAngle(); |
||||
|
|
||||
|
case S_POLYGON: |
||||
|
// TODO
|
||||
|
return false; |
||||
|
|
||||
|
case S_CURVE: |
||||
|
return aSegment1->GetBezControl1() == aSegment2->GetBezControl1() |
||||
|
&& aSegment1->GetBezControl2() == aSegment2->GetBezControl2() |
||||
|
&& aSegment1->GetBezierPoints() == aSegment2->GetBezierPoints(); |
||||
|
|
||||
|
default: |
||||
|
wxFAIL_MSG( wxString::Format( "unknown DRAWSEGMENT shape: %d", aSegment1->GetShape() ) ); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void GRAPHICS_CLEANER::cleanupSegments() |
||||
|
{ |
||||
|
std::set<BOARD_ITEM*> toRemove; |
||||
|
|
||||
|
// Remove duplicate segments (2 superimposed identical segments):
|
||||
|
for( auto it = m_drawings.begin(); it != m_drawings.end(); it++ ) |
||||
|
{ |
||||
|
DRAWSEGMENT* segment = dynamic_cast<DRAWSEGMENT*>( *it ); |
||||
|
|
||||
|
if( !segment || segment->GetShape() != S_SEGMENT || segment->HasFlag( IS_DELETED ) ) |
||||
|
continue; |
||||
|
|
||||
|
if( isNullSegment( segment ) ) |
||||
|
{ |
||||
|
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_NULL_GRAPHIC ); |
||||
|
item->SetItems( segment ); |
||||
|
m_itemsList->push_back( item ); |
||||
|
|
||||
|
toRemove.insert( segment ); |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
for( auto it2 = it + 1; it2 != m_drawings.end(); it2++ ) |
||||
|
{ |
||||
|
DRAWSEGMENT* segment2 = dynamic_cast<DRAWSEGMENT*>( *it2 ); |
||||
|
|
||||
|
if( !segment2 || segment2->HasFlag( IS_DELETED ) ) |
||||
|
continue; |
||||
|
|
||||
|
if( areEquivalent( segment, segment2 ) ) |
||||
|
{ |
||||
|
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_DUPLICATE_GRAPHIC ); |
||||
|
item->SetItems( segment2 ); |
||||
|
m_itemsList->push_back( item ); |
||||
|
|
||||
|
segment2->SetFlags( IS_DELETED ); |
||||
|
toRemove.insert( segment2 ); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if( !m_dryRun ) |
||||
|
removeItems( toRemove ); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void GRAPHICS_CLEANER::mergeRects() |
||||
|
{ |
||||
|
struct SIDE_CANDIDATE |
||||
|
{ |
||||
|
SIDE_CANDIDATE( DRAWSEGMENT* aSeg ) : |
||||
|
start( aSeg->GetStart() ), |
||||
|
end( aSeg->GetEnd() ), |
||||
|
seg( aSeg ) |
||||
|
{ |
||||
|
if( start.x > end.x || start.y > end.y ) |
||||
|
std::swap( start, end ); |
||||
|
} |
||||
|
|
||||
|
wxPoint start; |
||||
|
wxPoint end; |
||||
|
DRAWSEGMENT* seg; |
||||
|
}; |
||||
|
|
||||
|
std::set<BOARD_ITEM*> toRemove; |
||||
|
|
||||
|
auto markForRemoval = [&]( SIDE_CANDIDATE* aSide ) |
||||
|
{ |
||||
|
toRemove.insert( aSide->seg ); |
||||
|
aSide->seg->SetFlags( IS_DELETED ); |
||||
|
}; |
||||
|
|
||||
|
std::vector<SIDE_CANDIDATE*> sides; |
||||
|
std::map<wxPoint, std::vector<SIDE_CANDIDATE*>> ptMap; |
||||
|
|
||||
|
// First load all the candidates into the side vector and layer maps
|
||||
|
for( BOARD_ITEM* item : m_drawings ) |
||||
|
{ |
||||
|
DRAWSEGMENT* seg = dynamic_cast<DRAWSEGMENT*>( item ); |
||||
|
|
||||
|
if( !seg || seg->GetShape() != S_SEGMENT ) |
||||
|
continue; |
||||
|
|
||||
|
if( seg->GetStart().x == seg->GetEnd().x || seg->GetStart().y == seg->GetEnd().y ) |
||||
|
{ |
||||
|
sides.emplace_back( new SIDE_CANDIDATE( seg ) ); |
||||
|
ptMap[ sides.back()->start ].push_back( sides.back() ); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Now go through the sides and try and match lines into rectangles
|
||||
|
for( SIDE_CANDIDATE* side : sides ) |
||||
|
{ |
||||
|
if( side->seg->HasFlag( IS_DELETED ) ) |
||||
|
continue; |
||||
|
|
||||
|
SIDE_CANDIDATE* left = nullptr; |
||||
|
SIDE_CANDIDATE* top = nullptr; |
||||
|
SIDE_CANDIDATE* right = nullptr; |
||||
|
SIDE_CANDIDATE* bottom = nullptr; |
||||
|
|
||||
|
auto viable = [&]( SIDE_CANDIDATE* aCandidate ) -> bool |
||||
|
{ |
||||
|
return aCandidate->seg->GetLayer() == side->seg->GetLayer() |
||||
|
&& aCandidate->seg->GetWidth() == side->seg->GetWidth() |
||||
|
&& !aCandidate->seg->HasFlag( IS_DELETED ); |
||||
|
}; |
||||
|
|
||||
|
if( side->start.x == side->end.x ) |
||||
|
{ |
||||
|
// We've found a possible left; see if we have a top
|
||||
|
//
|
||||
|
left = side; |
||||
|
|
||||
|
for( SIDE_CANDIDATE* candidate : ptMap[ left->start ] ) |
||||
|
{ |
||||
|
if( candidate != left && viable( candidate ) ) |
||||
|
{ |
||||
|
top = candidate; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else if( side->start.y == side->end.y ) |
||||
|
{ |
||||
|
// We've found a possible top; see if we have a left
|
||||
|
//
|
||||
|
top = side; |
||||
|
|
||||
|
for( SIDE_CANDIDATE* candidate : ptMap[ top->start ] ) |
||||
|
{ |
||||
|
if( candidate != top && viable( candidate ) ) |
||||
|
{ |
||||
|
left = candidate; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if( top && left ) |
||||
|
{ |
||||
|
// See if we can fill in the other two sides
|
||||
|
//
|
||||
|
for( SIDE_CANDIDATE* candidate : ptMap[ top->end ] ) |
||||
|
{ |
||||
|
if( candidate != top && viable( candidate ) ) |
||||
|
{ |
||||
|
right = candidate; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for( SIDE_CANDIDATE* candidate : ptMap[ left->end ] ) |
||||
|
{ |
||||
|
if( candidate != left && viable( candidate ) ) |
||||
|
{ |
||||
|
bottom = candidate; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if( right && bottom ) |
||||
|
{ |
||||
|
markForRemoval( left ); |
||||
|
markForRemoval( top ); |
||||
|
markForRemoval( right ); |
||||
|
markForRemoval( bottom ); |
||||
|
|
||||
|
CLEANUP_ITEM* item = new CLEANUP_ITEM( CLEANUP_LINES_TO_RECT ); |
||||
|
item->SetItems( left->seg, top->seg, right->seg, bottom->seg ); |
||||
|
m_itemsList->push_back( item ); |
||||
|
|
||||
|
if( !m_dryRun ) |
||||
|
{ |
||||
|
DRAWSEGMENT* rect; |
||||
|
|
||||
|
if( m_parentModule ) |
||||
|
rect = new EDGE_MODULE( m_parentModule ); |
||||
|
else |
||||
|
rect = new DRAWSEGMENT(); |
||||
|
|
||||
|
rect->SetShape( S_RECT ); |
||||
|
rect->SetStart( top->start ); |
||||
|
rect->SetEnd( bottom->end ); |
||||
|
rect->SetLayer( top->seg->GetLayer() ); |
||||
|
rect->SetWidth( top->seg->GetWidth() ); |
||||
|
|
||||
|
m_commit.Add( rect ); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if( !m_dryRun ) |
||||
|
removeItems( toRemove ); |
||||
|
|
||||
|
for( SIDE_CANDIDATE* side : sides ) |
||||
|
delete side; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void GRAPHICS_CLEANER::removeItems( std::set<BOARD_ITEM*>& aItems ) |
||||
|
{ |
||||
|
for( BOARD_ITEM* item : aItems ) |
||||
|
{ |
||||
|
if( m_parentModule ) |
||||
|
m_parentModule->Remove( item ); |
||||
|
else |
||||
|
item->GetParent()->Remove( item ); |
||||
|
|
||||
|
m_commit.Removed( item ); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
/* |
||||
|
* 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_GRAPHICS_CLEANER_H |
||||
|
#define KICAD_GRAPHICS_CLEANER_H |
||||
|
|
||||
|
#include <class_board.h> |
||||
|
|
||||
|
class MODULE; |
||||
|
class BOARD_COMMIT; |
||||
|
class CLEANUP_ITEM; |
||||
|
|
||||
|
|
||||
|
// Helper class used to clean tracks and vias |
||||
|
class GRAPHICS_CLEANER |
||||
|
{ |
||||
|
public: |
||||
|
GRAPHICS_CLEANER( DRAWINGS& aDrawings, MODULE* aParentModule, BOARD_COMMIT& aCommit ); |
||||
|
|
||||
|
/** |
||||
|
* the cleanup function. |
||||
|
* @param aMergeRects = merge for segments forming a rectangle into a rect |
||||
|
* @param aDeleteRedundant = true to delete null graphics and duplicated graphics |
||||
|
*/ |
||||
|
void CleanupBoard( bool aDryRun, std::vector<CLEANUP_ITEM*>* aItemsList, bool aMergeRects, |
||||
|
bool aDeleteRedundant ); |
||||
|
|
||||
|
private: |
||||
|
bool isNullSegment( DRAWSEGMENT* aSegment ); |
||||
|
bool areEquivalent( DRAWSEGMENT* aSegment1, DRAWSEGMENT* aSegment2 ); |
||||
|
|
||||
|
void cleanupSegments(); |
||||
|
void mergeRects(); |
||||
|
void removeItems( std::set<BOARD_ITEM*>& aItems ); |
||||
|
|
||||
|
private: |
||||
|
DRAWINGS& m_drawings; |
||||
|
MODULE* m_parentModule; // nullptr if not in ModEdit |
||||
|
BOARD_COMMIT& m_commit; |
||||
|
bool m_dryRun; |
||||
|
std::vector<CLEANUP_ITEM*>* m_itemsList; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
#endif //KICAD_GRAPHICS_CLEANER_H |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue