Edit->Global Deletions & Edit->Cleanup Tracks and Vias work in GAL, without toggling between canvases.

This commit is contained in:
Maciej Suminski 2014-04-04 15:43:30 +02:00
parent 8b8e8d8f7f
commit 89da70fe94
4 changed files with 111 additions and 34 deletions

View File

@ -38,18 +38,19 @@
#include <class_track.h> #include <class_track.h>
#include <connect.h> #include <connect.h>
#include <dialog_cleaning_options.h> #include <dialog_cleaning_options.h>
#include <ratsnest_data.h>
// Helper class used to clean tracks and vias // Helper class used to clean tracks and vias
class TRACKS_CLEANER: CONNECTIONS class TRACKS_CLEANER : CONNECTIONS
{ {
private: private:
BOARD * m_Brd; BOARD* m_Brd;
bool m_deleteUnconnectedTracks; bool m_deleteUnconnectedTracks;
bool m_mergeSegments; bool m_mergeSegments;
bool m_cleanVias; bool m_cleanVias;
public: public:
TRACKS_CLEANER( BOARD * aPcb ); TRACKS_CLEANER( BOARD* aPcb );
/** /**
* the cleanup function. * the cleanup function.
@ -102,8 +103,7 @@ private:
* merge aTrackRef and aCandidate, when possible, * merge aTrackRef and aCandidate, when possible,
* i.e. when they are colinear, same width, and obviously same layer * i.e. when they are colinear, same width, and obviously same layer
*/ */
TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aCandidate, int aEndType );
TRACK* aCandidate, int aEndType );
}; };
/* Install the cleanup dialog frame to know what should be cleaned /* Install the cleanup dialog frame to know what should be cleaned
@ -161,7 +161,7 @@ bool TRACKS_CLEANER::CleanupBoard()
return modified; return modified;
} }
TRACKS_CLEANER::TRACKS_CLEANER( BOARD * aPcb ): CONNECTIONS( aPcb ) TRACKS_CLEANER::TRACKS_CLEANER( BOARD* aPcb ) : CONNECTIONS( aPcb )
{ {
m_Brd = aPcb; m_Brd = aPcb;
m_deleteUnconnectedTracks = false; m_deleteUnconnectedTracks = false;
@ -177,22 +177,22 @@ void TRACKS_CLEANER::buildTrackConnectionInfo()
BuildTracksCandidatesList( m_Brd->m_Track, NULL); BuildTracksCandidatesList( m_Brd->m_Track, NULL);
// clear flags and variables used in cleanup // clear flags and variables used in cleanup
for( TRACK * track = m_Brd->m_Track; track; track = track->Next() ) for( TRACK* track = m_Brd->m_Track; track; track = track->Next() )
{ {
track->start = NULL; track->start = NULL;
track->end = NULL; track->end = NULL;
track->m_PadsConnected.clear(); track->m_PadsConnected.clear();
track->SetState( START_ON_PAD|END_ON_PAD|BUSY, false ); track->SetState( START_ON_PAD | END_ON_PAD | BUSY, false );
} }
// Build connections info tracks to pads // Build connections info tracks to pads
SearchTracksConnectedToPads(); SearchTracksConnectedToPads();
for( TRACK * track = m_Brd->m_Track; track; track = track->Next() ) for( TRACK* track = m_Brd->m_Track; track; track = track->Next() )
{ {
// Mark track if connected to pads // Mark track if connected to pads
for( unsigned jj = 0; jj < track->m_PadsConnected.size(); jj++ ) for( unsigned jj = 0; jj < track->m_PadsConnected.size(); jj++ )
{ {
D_PAD * pad = track->m_PadsConnected[jj]; D_PAD* pad = track->m_PadsConnected[jj];
if( pad->HitTest( track->GetStart() ) ) if( pad->HitTest( track->GetStart() ) )
{ {
@ -240,6 +240,8 @@ bool TRACKS_CLEANER::clean_vias()
continue; continue;
// delete via // delete via
m_Brd->GetRatsnest()->Remove( alt_track );
alt_track->ViewRelease();
alt_track->UnLink(); alt_track->UnLink();
delete alt_track; delete alt_track;
modified = true; modified = true;
@ -258,11 +260,13 @@ bool TRACKS_CLEANER::clean_vias()
// if one pad through is found, the via can be removed // if one pad through is found, the via can be removed
for( unsigned ii = 0; ii < track->m_PadsConnected.size(); ii++ ) for( unsigned ii = 0; ii < track->m_PadsConnected.size(); ii++ )
{ {
D_PAD * pad = track->m_PadsConnected[ii]; D_PAD* pad = track->m_PadsConnected[ii];
if( (pad->GetLayerMask() & ALL_CU_LAYERS) == ALL_CU_LAYERS ) if( ( pad->GetLayerMask() & ALL_CU_LAYERS ) == ALL_CU_LAYERS )
{ {
// redundant: via delete it // redundant: via delete it
m_Brd->GetRatsnest()->Remove( track );
track->ViewRelease();
track->UnLink(); track->UnLink();
delete track; delete track;
modified = true; modified = true;
@ -291,7 +295,8 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks()
{ {
item_erased = false; item_erased = false;
TRACK* next_track; TRACK* next_track;
for( TRACK * track = m_Brd->m_Track; track ; track = next_track )
for( TRACK* track = m_Brd->m_Track; track ; track = next_track )
{ {
next_track = track->Next(); next_track = track->Next();
@ -312,7 +317,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks()
LAYER_NUM top_layer, bottom_layer; LAYER_NUM top_layer, bottom_layer;
ZONE_CONTAINER* zone; ZONE_CONTAINER* zone;
if( (type_end & START_ON_PAD ) == 0 ) if( ( type_end & START_ON_PAD ) == 0 )
{ {
TRACK* other = track->GetTrace( m_Brd->m_Track, NULL, FLG_START ); TRACK* other = track->GetTrace( m_Brd->m_Track, NULL, FLG_START );
@ -334,7 +339,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks()
} }
} }
if( (other == NULL) && (zone == NULL) ) if( ( other == NULL ) && ( zone == NULL ) )
{ {
flag_erase |= 1; flag_erase |= 1;
} }
@ -422,7 +427,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks()
via->GetNetCode() ); via->GetNetCode() );
} }
if( (other == NULL) && (zone == NULL) ) if( ( other == NULL ) && ( zone == NULL ) )
flag_erase |= 0x20; flag_erase |= 0x20;
track->SetState( BUSY, false ); track->SetState( BUSY, false );
@ -433,6 +438,8 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks()
if( flag_erase ) if( flag_erase )
{ {
// remove segment from board // remove segment from board
m_Brd->GetRatsnest()->Remove( track );
track->ViewRelease();
track->DeleteStructure(); track->DeleteStructure();
// iterate, because a track connected to the deleted track // iterate, because a track connected to the deleted track
// is now perhaps now not connected and should be deleted // is now perhaps now not connected and should be deleted
@ -461,7 +468,11 @@ bool TRACKS_CLEANER::clean_segments()
nextsegment = segment->Next(); nextsegment = segment->Next();
if( segment->IsNull() ) // Length segment = 0; delete it if( segment->IsNull() ) // Length segment = 0; delete it
{
m_Brd->GetRatsnest()->Remove( segment );
segment->ViewRelease();
segment->DeleteStructure(); segment->DeleteStructure();
}
} }
// Delete redundant segments, i.e. segments having the same end points // Delete redundant segments, i.e. segments having the same end points
@ -493,6 +504,8 @@ bool TRACKS_CLEANER::clean_segments()
// Delete redundant point // Delete redundant point
if( erase ) if( erase )
{ {
m_Brd->GetRatsnest()->Remove( other );
other->ViewRelease();
other->DeleteStructure(); other->DeleteStructure();
modified = true; modified = true;
} }
@ -548,6 +561,8 @@ bool TRACKS_CLEANER::clean_segments()
if( segDelete ) if( segDelete )
{ {
no_inc = 1; no_inc = 1;
m_Brd->GetRatsnest()->Remove( segDelete );
segDelete->ViewRelease();
segDelete->DeleteStructure(); segDelete->DeleteStructure();
modified = true; modified = true;
} }
@ -589,6 +604,8 @@ bool TRACKS_CLEANER::clean_segments()
if( segDelete ) if( segDelete )
{ {
no_inc = 1; no_inc = 1;
m_Brd->GetRatsnest()->Remove( segDelete );
segDelete->ViewRelease();
segDelete->DeleteStructure(); segDelete->DeleteStructure();
modified = true; modified = true;
} }
@ -688,6 +705,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
aTrackRef->SetStart( aCandidate->GetEnd()); aTrackRef->SetStart( aCandidate->GetEnd());
aTrackRef->start = aCandidate->end; aTrackRef->start = aCandidate->end;
aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( END_ON_PAD) ); aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( END_ON_PAD) );
aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
return aCandidate; return aCandidate;
} }
else else
@ -695,6 +713,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
aTrackRef->SetStart( aCandidate->GetStart() ); aTrackRef->SetStart( aCandidate->GetStart() );
aTrackRef->start = aCandidate->start; aTrackRef->start = aCandidate->start;
aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( START_ON_PAD) ); aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( START_ON_PAD) );
aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
return aCandidate; return aCandidate;
} }
} }
@ -711,6 +730,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
aTrackRef->SetEnd( aCandidate->GetEnd() ); aTrackRef->SetEnd( aCandidate->GetEnd() );
aTrackRef->end = aCandidate->end; aTrackRef->end = aCandidate->end;
aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( END_ON_PAD) ); aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( END_ON_PAD) );
aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
return aCandidate; return aCandidate;
} }
else else
@ -718,6 +738,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
aTrackRef->SetEnd( aCandidate->GetStart() ); aTrackRef->SetEnd( aCandidate->GetStart() );
aTrackRef->end = aCandidate->start; aTrackRef->end = aCandidate->start;
aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( START_ON_PAD) ); aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( START_ON_PAD) );
aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
return aCandidate; return aCandidate;
} }
} }

View File

@ -34,6 +34,7 @@
#include <wxPcbStruct.h> #include <wxPcbStruct.h>
#include <macros.h> #include <macros.h>
#include <pcbcommon.h> #include <pcbcommon.h>
#include <ratsnest_data.h>
#include <class_board.h> #include <class_board.h>
#include <class_track.h> #include <class_track.h>
@ -124,6 +125,8 @@ TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack )
DLIST<TRACK>* container = (DLIST<TRACK>*)aTrack->GetList(); DLIST<TRACK>* container = (DLIST<TRACK>*)aTrack->GetList();
wxASSERT( container ); wxASSERT( container );
GetBoard()->GetRatsnest()->Remove( aTrack );
aTrack->ViewRelease();
container->Remove( aTrack ); container->Remove( aTrack );
// redraw the area where the track was // redraw the area where the track was
@ -174,6 +177,8 @@ void PCB_EDIT_FRAME::Delete_net( wxDC* DC, TRACK* aTrack )
if( segm->GetNetCode() != net_code_delete ) if( segm->GetNetCode() != net_code_delete )
break; break;
GetBoard()->GetRatsnest()->Remove( segm );
segm->ViewRelease();
GetBoard()->m_Track.Remove( segm ); GetBoard()->m_Track.Remove( segm );
// redraw the area where the track was // redraw the area where the track was
@ -219,6 +224,8 @@ void PCB_EDIT_FRAME::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
<< TO_UTF8( TRACK::ShowState( tracksegment->GetStatus() ) ) \ << TO_UTF8( TRACK::ShowState( tracksegment->GetStatus() ) ) \
<< std::endl; ) << std::endl; )
GetBoard()->GetRatsnest()->Remove( tracksegment );
tracksegment->ViewRelease();
GetBoard()->m_Track.Remove( tracksegment ); GetBoard()->m_Track.Remove( tracksegment );
// redraw the area where the track was // redraw the area where the track was

View File

@ -1,7 +1,27 @@
/** /*
* @file dialog_global_deletion.cpp * This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2014 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 <boost/bind.hpp>
#include <fctsys.h> #include <fctsys.h>
#include <class_drawpanel.h> #include <class_drawpanel.h>
@ -9,6 +29,7 @@
#include <pcbnew.h> #include <pcbnew.h>
#include <wxPcbStruct.h> #include <wxPcbStruct.h>
#include <pcbcommon.h> #include <pcbcommon.h>
#include <ratsnest_data.h>
#include <class_board.h> #include <class_board.h>
#include <class_module.h> #include <class_module.h>
@ -80,14 +101,15 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
} }
else else
{ {
if( !IsOK( this, _( "Are you sure you want to delete the selected items?" ) ) ) if( !IsOK( this, _( "Are you sure you want to delete the selected items?" ) ) )
return; return;
BOARD* pcb = m_Parent->GetBoard(); BOARD* pcb = m_Parent->GetBoard();
PICKED_ITEMS_LIST pickersList; PICKED_ITEMS_LIST pickersList;
ITEM_PICKER itemPicker( NULL, UR_DELETED ); ITEM_PICKER itemPicker( NULL, UR_DELETED );
BOARD_ITEM* item, * nextitem; BOARD_ITEM* item;
BOARD_ITEM* nextitem;
RN_DATA* ratsnest = pcb->GetRatsnest();
LAYER_MSK layers_filter = ALL_LAYERS; LAYER_MSK layers_filter = ALL_LAYERS;
@ -101,12 +123,13 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
while( item != NULL ) while( item != NULL )
{ {
if( GetLayerMask( item->GetLayer() ) & layers_filter ) if( GetLayerMask( item->GetLayer() ) & layers_filter )
{ {
itemPicker.SetItem( item ); itemPicker.SetItem( item );
pickersList.PushItem( itemPicker ); pickersList.PushItem( itemPicker );
pcb->Remove( item ); pcb->Remove( item );
item->ViewRelease();
ratsnest->Remove( item );
gen_rastnest = true; gen_rastnest = true;
} }
else else
@ -138,6 +161,7 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
{ {
itemPicker.SetItem( item ); itemPicker.SetItem( item );
pickersList.PushItem( itemPicker ); pickersList.PushItem( itemPicker );
item->ViewRelease();
item->UnLink(); item->UnLink();
} }
} }
@ -155,6 +179,7 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
{ {
itemPicker.SetItem( item ); itemPicker.SetItem( item );
pickersList.PushItem( itemPicker ); pickersList.PushItem( itemPicker );
item->ViewRelease();
item->UnLink(); item->UnLink();
} }
} }
@ -162,7 +187,6 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
if( m_DelModules->GetValue() ) if( m_DelModules->GetValue() )
{ {
for( item = pcb->m_Modules; item; item = nextitem ) for( item = pcb->m_Modules; item; item = nextitem )
{ {
nextitem = item->Next(); nextitem = item->Next();
@ -173,6 +197,10 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
{ {
itemPicker.SetItem( item ); itemPicker.SetItem( item );
pickersList.PushItem( itemPicker ); pickersList.PushItem( itemPicker );
static_cast<MODULE*>( item )->RunOnChildren(
boost::bind( &KIGFX::VIEW_ITEM::ViewRelease, _1 ) );
ratsnest->Remove( item );
item->ViewRelease();
item->UnLink(); item->UnLink();
gen_rastnest = true; gen_rastnest = true;
} }
@ -189,27 +217,29 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
if( !m_TrackFilterAR->GetValue() ) if( !m_TrackFilterAR->GetValue() )
track_mask_filter |= TRACK_AR; track_mask_filter |= TRACK_AR;
TRACK * nexttrack; TRACK* nexttrack;
for( TRACK *track = pcb->m_Track; track != NULL; track = nexttrack ) for( TRACK *track = pcb->m_Track; track != NULL; track = nexttrack )
{ {
nexttrack = track->Next(); nexttrack = track->Next();
if( (track->GetState( TRACK_LOCKED | TRACK_AR ) & track_mask_filter) != 0 ) if( ( track->GetState( TRACK_LOCKED | TRACK_AR ) & track_mask_filter ) != 0 )
continue; continue;
if( (track->GetState( TRACK_LOCKED | TRACK_AR ) == 0) && if( ( track->GetState( TRACK_LOCKED | TRACK_AR ) == 0 ) &&
!m_TrackFilterNormal->GetValue() ) !m_TrackFilterNormal->GetValue() )
continue; continue;
if( (track->Type() == PCB_VIA_T) && !m_TrackFilterVias->GetValue() ) if( ( track->Type() == PCB_VIA_T ) && !m_TrackFilterVias->GetValue() )
continue; continue;
if( (track->GetLayerMask() & layers_filter) == 0 ) if( ( track->GetLayerMask() & layers_filter ) == 0 )
continue; continue;
itemPicker.SetItem( track ); itemPicker.SetItem( track );
pickersList.PushItem( itemPicker ); pickersList.PushItem( itemPicker );
track->ViewRelease();
ratsnest->Remove( track );
track->UnLink(); track->UnLink();
gen_rastnest = true; gen_rastnest = true;
} }

View File

@ -1,6 +1,25 @@
///////////////////////////////////////////////////////////////////////////// /*
// Name: dialog_global_deletion.h * This program source code file is part of KiCad, a free EDA CAD application.
///////////////////////////////////////////////////////////////////////////// *
* Copyright (C) 1992-2014 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_GLOBAL_DELETION_H_ #ifndef _DIALOG_GLOBAL_DELETION_H_
#define _DIALOG_GLOBAL_DELETION_H_ #define _DIALOG_GLOBAL_DELETION_H_
@ -9,20 +28,20 @@
class DIALOG_GLOBAL_DELETION: public DIALOG_GLOBAL_DELETION_BASE class DIALOG_GLOBAL_DELETION: public DIALOG_GLOBAL_DELETION_BASE
{ {
private:
PCB_EDIT_FRAME * m_Parent;
LAYER_NUM m_currentLayer;
public: public:
DIALOG_GLOBAL_DELETION( PCB_EDIT_FRAME* parent ); DIALOG_GLOBAL_DELETION( PCB_EDIT_FRAME* parent );
void SetCurrentLayer( LAYER_NUM aLayer ); void SetCurrentLayer( LAYER_NUM aLayer );
private: private:
PCB_EDIT_FRAME* m_Parent;
LAYER_NUM m_currentLayer;
void OnOkClick( wxCommandEvent& event ) void OnOkClick( wxCommandEvent& event )
{ {
AcceptPcbDelete(); AcceptPcbDelete();
EndModal(wxID_OK); EndModal(wxID_OK);
} }
void OnCancelClick( wxCommandEvent& event ) void OnCancelClick( wxCommandEvent& event )
{ {
EndModal(wxID_CANCEL); EndModal(wxID_CANCEL);