kicad/pcbnew/deltrack.cpp

224 lines
6.7 KiB
C++
Raw Normal View History

/******************************************/
/* Edit Track: Erase Routines */
/* Delete segments, tracks, and net areas */
/******************************************/
#include "fctsys.h"
2009-07-30 11:04:07 +00:00
#include "common.h"
#include "class_drawpanel.h"
#include "confirm.h"
#include "pcbnew.h"
2009-07-30 11:04:07 +00:00
#include "wxPcbStruct.h"
#include "protos.h"
/* Removes 1 segment of track.
* 2 cases:
* If There is evidence of new track: delete new segment.
* Otherwise, delete segment under the cursor.
*/
TRACK* WinEDA_PcbFrame::Delete_Segment( wxDC* DC, TRACK* aTrack )
{
int current_net_code;
if( aTrack == NULL )
return NULL;
2008-03-04 21:39:46 +00:00
if( aTrack->GetState( DELETED ) )
2007-11-02 18:21:43 +00:00
{
D( printf( "WinEDA_PcbFrame::Delete_Segment(): bug deleted already deleted TRACK\n" ); )
2007-11-02 18:21:43 +00:00
return NULL;
}
if( aTrack->m_Flags & IS_NEW ) // Trace in progress, erase the last
// segment
{
if( g_CurrentTrackList.GetCount() > 0 )
{
int previous_layer = ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer;
D( g_CurrentTrackList.VerifyListIntegrity(); )
// Delete the current trace
ShowNewTrackWhenMovingCursor( DrawPanel, DC, FALSE );
// delete the most recently entered
delete g_CurrentTrackList.PopBack();
if( g_TwoSegmentTrackBuild )
2008-03-04 21:39:46 +00:00
{
// if in 2 track mode, and the next most recent is a segment
// not a via, and the one previous to that is a via, then
// delete up to the via.
if( g_CurrentTrackList.GetCount() >= 2
&& g_CurrentTrackSegment->Type() != TYPE_VIA
&& g_CurrentTrackSegment->Back()->Type() == TYPE_VIA )
{
delete g_CurrentTrackList.PopBack();
}
}
while( g_CurrentTrackSegment && g_CurrentTrackSegment->Type() ==
TYPE_VIA )
{
delete g_CurrentTrackList.PopBack();
if( g_CurrentTrackSegment && g_CurrentTrackSegment->Type() !=
TYPE_VIA )
2007-08-23 04:28:46 +00:00
previous_layer = g_CurrentTrackSegment->GetLayer();
}
// Correct active layer which could change if a via
// has been erased
( (PCB_SCREEN*) GetScreen() )->m_Active_Layer = previous_layer;
UpdateStatusBar();
if( g_TwoSegmentTrackBuild ) // We must have 2 segments or more,
// or 0
{
if( g_CurrentTrackList.GetCount() == 1
&& g_CurrentTrackSegment->Type() != TYPE_VIA )
{
delete g_CurrentTrackList.PopBack();
}
}
if( g_CurrentTrackList.GetCount() == 0 )
{
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
if( g_HightLigt_Status )
Hight_Light( DC );
SetCurItem( NULL );
return NULL;
}
else
{
if( DrawPanel->ManageCurseur )
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
return g_CurrentTrackSegment;
}
}
return NULL;
}
current_net_code = aTrack->GetNet();
2008-03-04 21:39:46 +00:00
DLIST<TRACK>* container = (DLIST<TRACK>*)aTrack->GetList();
wxASSERT( container );
container->Remove( aTrack );
2008-03-06 01:46:13 +00:00
// redraw the area where the track was
DrawPanel->PostDirtyRect( aTrack->GetBoundingBox() );
SaveCopyInUndoList( aTrack, UR_DELETED );
GetScreen()->SetModify();
test_1_net_connexion( DC, current_net_code );
GetBoard()->DisplayInfo( this );
return NULL;
}
void WinEDA_PcbFrame::Delete_Track( wxDC* DC, TRACK* aTrack )
{
if( aTrack != NULL )
{
int current_net_code = aTrack->GetNet();
Remove_One_Track( DC, aTrack );
GetScreen()->SetModify();
test_1_net_connexion( DC, current_net_code );
}
}
void WinEDA_PcbFrame::Delete_net( wxDC* DC, TRACK* aTrack )
{
if( aTrack == NULL )
return;
if( !IsOK( this, _( "Delete NET?" ) ) )
return;
2008-03-10 15:51:44 +00:00
PICKED_ITEMS_LIST itemsList;
ITEM_PICKER picker( NULL, UR_DELETED );
int net_code_delete = aTrack->GetNet();
/* Search the first item for the given net code */
TRACK* trackList = GetBoard()->m_Track->GetStartNetCode( net_code_delete );
2008-03-10 15:51:44 +00:00
/* Remove all segments having the given net code */
int ii = 0;
TRACK* next_track;
for( TRACK* segm = trackList; segm; segm = next_track, ++ii )
{
next_track = segm->Next();
if( segm->GetNet() != net_code_delete )
break;
GetBoard()->m_Track.Remove( segm );
// redraw the area where the track was
DrawPanel->PostDirtyRect( segm->GetBoundingBox() );
picker.m_PickedItem = segm;
picker.m_PickedItemType = segm->Type();
itemsList.PushItem( picker );
}
2008-03-10 15:51:44 +00:00
SaveCopyInUndoList( itemsList, UR_DELETED );
GetScreen()->SetModify();
test_1_net_connexion( DC, net_code_delete );
GetBoard()->DisplayInfo( this );
}
/* Remove 1 track:
* The leading segment is removed and all adjacent segments
* until a pad or a junction point of more than 2 segments is found
*/
void WinEDA_PcbFrame::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
{
int segments_to_delete_count;
if( pt_segm == NULL )
return;
TRACK* trackList = Marque_Une_Piste( GetBoard(), pt_segm,
&segments_to_delete_count, NULL, true );
if( segments_to_delete_count == 0 )
return;
int net_code = pt_segm->GetNet();
PICKED_ITEMS_LIST itemsList;
ITEM_PICKER picker( NULL, UR_DELETED );
int ii = 0;
TRACK* tracksegment = trackList;
TRACK* next_track;
for( ; ii < segments_to_delete_count; ii++, tracksegment = next_track )
{
next_track = tracksegment->Next();
tracksegment->SetState( BUSY, OFF );
D( printf( "%s: track %p status=\"%s\"\n", __func__, tracksegment,
CONV_TO_UTF8( TRACK::ShowState( tracksegment->GetState( -1 ) ) )
); )
GetBoard()->m_Track.Remove( tracksegment );
// redraw the area where the track was
DrawPanel->PostDirtyRect( tracksegment->GetBoundingBox() );
picker.m_PickedItem = tracksegment;
picker.m_PickedItemType = tracksegment->Type();
itemsList.PushItem( picker );
}
SaveCopyInUndoList( itemsList, UR_DELETED );
if( net_code > 0 )
test_1_net_connexion( DC, net_code );
}