Pcbnew: Fix incorrect behavior of undo/redo command (this issue happens only when a new track is created, and an old redundant track is deleted)

Minor code cleaning
This commit is contained in:
jean-pierre charras 2012-02-04 21:30:00 +01:00
parent 716d21d88a
commit 8e846082bb
8 changed files with 55 additions and 70 deletions

View File

@ -98,6 +98,7 @@ public:
* copy of an active item) and m_Link points the active * copy of an active item) and m_Link points the active
* item in schematic */ * item in schematic */
public:
ITEM_PICKER( EDA_ITEM* aItem = NULL, UNDO_REDO_T aUndoRedoStatus = UR_UNSPECIFIED ); ITEM_PICKER( EDA_ITEM* aItem = NULL, UNDO_REDO_T aUndoRedoStatus = UR_UNSPECIFIED );
EDA_ITEM* GetItem() const { return m_PickedItem; } EDA_ITEM* GetItem() const { return m_PickedItem; }
@ -106,6 +107,8 @@ public:
KICAD_T GetItemType() const { return m_PickedItemType; } KICAD_T GetItemType() const { return m_PickedItemType; }
void SetStatus( UNDO_REDO_T aStatus ) { m_UndoRedoStatus = aStatus; }
void SetItemType( KICAD_T aType ) { m_PickedItemType = aType; } void SetItemType( KICAD_T aType ) { m_PickedItemType = aType; }
void SetLink( EDA_ITEM* aItem ) { m_Link = aItem; } void SetLink( EDA_ITEM* aItem ) { m_Link = aItem; }

View File

@ -399,10 +399,6 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
*/ */
if( commandToUndo->GetPickedItemLink( ii ) == NULL ) if( commandToUndo->GetPickedItemLink( ii ) == NULL )
commandToUndo->SetPickedItemLink( item->Clone(), ii ); commandToUndo->SetPickedItemLink( item->Clone(), ii );
if( commandToUndo->GetPickedItemLink( ii ) == NULL )
wxMessageBox( wxT( "SaveCopyInUndoList() in UR_CHANGED mode: NULL link" ) );
break; break;
case UR_MOVED: case UR_MOVED:
@ -459,7 +455,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
// Undo in the reverse order of list creation: (this can allow stacked changes // Undo in the reverse order of list creation: (this can allow stacked changes
// like the same item can be changes and deleted in the same complex command // like the same item can be changes and deleted in the same complex command
TestForExistingItem( GetBoard(), NULL ); // Build list of existing items, for integrity test bool build_item_list = true; // if true the list of esiting items must be rebuilt
for( int ii = aList->GetCount()-1; ii >= 0 ; ii-- ) for( int ii = aList->GetCount()-1; ii >= 0 ; ii-- )
{ {
item = (BOARD_ITEM*) aList->GetPickedItem( ii ); item = (BOARD_ITEM*) aList->GetPickedItem( ii );
@ -470,9 +466,16 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
* - if a call to SaveCopyInUndoList was forgotten in Pcbnew * - if a call to SaveCopyInUndoList was forgotten in Pcbnew
* - in zones outlines, when a change in one zone merges this zone with an other * - in zones outlines, when a change in one zone merges this zone with an other
* This test avoids a Pcbnew crash * This test avoids a Pcbnew crash
* the test is made only to avoid crashes, so it is not needed for deleted or new items
*/ */
if( aList->GetPickedItemStatus( ii ) != UR_DELETED ) UNDO_REDO_T status = aList->GetPickedItemStatus( ii );
if( status != UR_DELETED && status != UR_NEW )
{ {
if( build_item_list )
// Build list of existing items, for integrity test
TestForExistingItem( GetBoard(), NULL );
build_item_list = false;
if( !TestForExistingItem( GetBoard(), item ) ) if( !TestForExistingItem( GetBoard(), item ) )
{ {
// Remove this non existant item // Remove this non existant item
@ -517,6 +520,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
case UR_DELETED: /* deleted items are put in List, as new items */ case UR_DELETED: /* deleted items are put in List, as new items */
aList->SetPickedItemStatus( UR_NEW, ii ); aList->SetPickedItemStatus( UR_NEW, ii );
GetBoard()->Add( item ); GetBoard()->Add( item );
build_item_list = true;
break; break;
case UR_MOVED: case UR_MOVED:

View File

@ -2074,6 +2074,11 @@ BOARD_CONNECTED_ITEM* BOARD::GetLockPoint( const wxPoint& aPosition, int aLayerM
TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS_LIST* aList ) TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS_LIST* aList )
{ {
/* creates an intermediate point on aSegment and break it into two segments
* at aPosition.
* The new segment starts from aPosition and ends at the end point of
* aSegment. The original segment now ends at aPosition.
*/
if( aSegment->m_Start == aPosition || aSegment->m_End == aPosition ) if( aSegment->m_Start == aPosition || aSegment->m_End == aPosition )
return NULL; return NULL;
@ -2087,43 +2092,26 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS
// Calculation coordinate of intermediate point relative to the start point of aSegment // Calculation coordinate of intermediate point relative to the start point of aSegment
wxPoint delta = aSegment->m_End - aSegment->m_Start; wxPoint delta = aSegment->m_End - aSegment->m_Start;
// Not yet in use:
#if 0
int ox, oy, fx, fy;
if( aRefSegm )
{
ox = aRefSegm->m_Start.x - aSegment->m_Start.x;
oy = aRefSegm->m_Start.y - aSegment->m_Start.y;
fx = aRefSegm->m_End.x - aSegment->m_Start.x;
fy = aRefSegm->m_End.y - aSegment->m_Start.y;
}
#endif
// calculate coordinates of aPosition relative to aSegment->m_Start // calculate coordinates of aPosition relative to aSegment->m_Start
wxPoint newPoint = aPosition - aSegment->m_Start; wxPoint lockPoint = aPosition - aSegment->m_Start;
// newPoint must be on aSegment: // lockPoint must be on aSegment:
// Ensure newPoint.y/newPoint.y = delta.y/delta.x // Ensure lockPoint.y/lockPoint.y = delta.y/delta.x
if( delta.x == 0 ) if( delta.x == 0 )
newPoint.x = 0; /* horizontal segment*/ lockPoint.x = 0; /* horizontal segment*/
else else
newPoint.y = wxRound( ( (double)newPoint.x * delta.y ) / delta.x ); lockPoint.y = wxRound( ( (double)lockPoint.x * delta.y ) / delta.x );
/* Create the intermediate point (that is to say creation of a new /* Create the intermediate point (that is to say creation of a new
* segment, beginning at the intermediate point. * segment, beginning at the intermediate point.
*/ */
newPoint.x += aSegment->m_Start.x; lockPoint += aSegment->m_Start;
newPoint.y += aSegment->m_Start.y;
TRACK* newTrack = (TRACK*)aSegment->Clone(); TRACK* newTrack = (TRACK*)aSegment->Clone();
// The new segment begins at the new point,
if( aList ) newTrack->m_Start = lockPoint;
{ newTrack->start = aSegment;
ITEM_PICKER picker( newTrack, UR_NEW ); newTrack->SetState( BEGIN_ONPAD, OFF );
aList->PushItem( picker );
}
DLIST<TRACK>* list = (DLIST<TRACK>*)aSegment->GetList(); DLIST<TRACK>* list = (DLIST<TRACK>*)aSegment->GetList();
wxASSERT( list ); wxASSERT( list );
@ -2131,28 +2119,22 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS
if( aList ) if( aList )
{ {
ITEM_PICKER picker( aSegment, UR_CHANGED ); // Prepare the undo command for the now track segment
picker.m_Link = aSegment->Clone(); ITEM_PICKER picker( newTrack, UR_NEW );
aList->PushItem( picker );
// Prepare the undo command for the old track segment
// before modifications
picker.SetItem( aSegment );
picker.SetStatus( UR_CHANGED );
picker.SetLink( aSegment->Clone() );
aList->PushItem( picker ); aList->PushItem( picker );
} }
/* Correct pointer at the end of the new segment. */ // Old track segment now ends at new point.
newTrack->end = aSegment->end; aSegment->m_End = lockPoint;
newTrack->SetState( END_ONPAD, aSegment->GetState( END_ONPAD ) );
/* Set connections info relative to the new point
*/
/* Old segment now ends at new point. */
aSegment->m_End = newPoint;
aSegment->end = newTrack; aSegment->end = newTrack;
aSegment->SetState( END_ONPAD, OFF ); aSegment->SetState( END_ONPAD, OFF );
/* The new segment begins at the new point. */
newTrack->m_Start = newPoint;
newTrack->start = aSegment;
newTrack->SetState( BEGIN_ONPAD, OFF );
D_PAD * pad = GetPad( newTrack, START ); D_PAD * pad = GetPad( newTrack, START );
if ( pad ) if ( pad )
@ -2163,7 +2145,7 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS
aSegment->SetState( END_ONPAD, ON ); aSegment->SetState( END_ONPAD, ON );
} }
aPosition = newPoint; aPosition = lockPoint;
return newTrack; return newTrack;
} }

View File

@ -1308,10 +1308,10 @@ public:
/** /**
* Function CreateLockPoint * Function CreateLockPoint
* creates an intermediate point on \a aSegment and break it into two segments * creates an intermediate point on \a aSegment and break it into two segments
* at \a aPoition. * at \a aPosition.
* <p> * <p>
* The new segment starts from \a aPosition and ends at the end point of \a * The new segment starts from \a aPosition and ends at the end point of \a
* aSegement. The original segment now ends at \a aPosition. * aSegment. The original segment now ends at \a aPosition.
* </p> * </p>
* *
* @param aPosition A wxPoint object containing the position to test and the new * @param aPosition A wxPoint object containing the position to test and the new

View File

@ -215,9 +215,6 @@ void PCB_EDIT_FRAME::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
next_track = tracksegment->Next(); next_track = tracksegment->Next();
tracksegment->SetState( BUSY, OFF ); tracksegment->SetState( BUSY, OFF );
//D( printf( "%s: track %p status=\"%s\"\n", __func__, tracksegment,
// TO_UTF8( TRACK::ShowState( tracksegment->GetState( -1 ) ) )
// ); )
D( std::cout << __func__ << ": track " << tracksegment << " status=" \ D( std::cout << __func__ << ": track " << tracksegment << " status=" \
<< TO_UTF8( TRACK::ShowState( tracksegment->GetState( -1 ) ) ) \ << TO_UTF8( TRACK::ShowState( tracksegment->GetState( -1 ) ) ) \
<< std::endl; ) << std::endl; )

View File

@ -50,6 +50,8 @@ static void ComputeBreakPoint( TRACK* track, int n, wxPoint end );
static void DeleteNullTrackSegments( BOARD* pcb, DLIST<TRACK>& aTrackList ); static void DeleteNullTrackSegments( BOARD* pcb, DLIST<TRACK>& aTrackList );
static void EnsureEndTrackOnPad( D_PAD* Pad ); static void EnsureEndTrackOnPad( D_PAD* Pad );
// A PICKED_ITEMS_LIST to store tracks which are modified/added/deleted
// during a track edition:
static PICKED_ITEMS_LIST s_ItemsListPicker; static PICKED_ITEMS_LIST s_ItemsListPicker;
@ -456,12 +458,9 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
else // If end point of is on a different track, else // If end point of is on a different track,
// creates a lock point if not exists // creates a lock point if not exists
{ {
TRACK* adr_buf = (TRACK*) LockPoint; // Creates a lock point, if not already exists:
GetBoard()->SetHighLightNet( adr_buf->GetNet() );
// Creates a lock point (if not already exists):
LockPoint = GetBoard()->CreateLockPoint( g_CurrentTrackSegment->m_End, LockPoint = GetBoard()->CreateLockPoint( g_CurrentTrackSegment->m_End,
adr_buf, (TRACK*) LockPoint,
&s_ItemsListPicker ); &s_ItemsListPicker );
} }
} }

View File

@ -25,7 +25,8 @@
/** /**
* @file tr_modif.cpp * @file tr_modif.cpp
* @brief Trace editing. * @brief Trace editing: detects an removes a track which is become redunding,
* after a new track is craeted.
*/ */
#include <fctsys.h> #include <fctsys.h>
@ -42,6 +43,10 @@
static void ListSetState( EDA_ITEM* Start, int NbItem, int State, int onoff ); static void ListSetState( EDA_ITEM* Start, int NbItem, int State, int onoff );
/*
* This function try to remove an old track, when a new track is created,
* and the old track is no more needed
*/
int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC,
TRACK* aNewTrack, TRACK* aNewTrack,
int aNewTrackSegmentsCount, int aNewTrackSegmentsCount,
@ -292,14 +297,11 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC,
} }
/* Set the bits of .m_State member to on off value, using bit mask State /* Set the bits of .m_State member to on/off value, using bit mask State
* of a list of EDA_ITEM * of a list of EDA_ITEM
*/ */
static void ListSetState( EDA_ITEM* Start, int NbItem, int State, int onoff ) static void ListSetState( EDA_ITEM* Start, int NbItem, int State, int onoff )
{ {
if( Start == NULL )
return;
for( ; (Start != NULL ) && ( NbItem > 0 ); NbItem--, Start = Start->Next() ) for( ; (Start != NULL ) && ( NbItem > 0 ); NbItem--, Start = Start->Next() )
{ {
Start->SetState( State, onoff ); Start->SetState( State, onoff );

View File

@ -152,7 +152,6 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference,
FILE* FichCmp, * NewFile; FILE* FichCmp, * NewFile;
char line[1024]; char line[1024];
wxString msg; wxString msg;
char* ignore;
if( old_name == new_name ) if( old_name == new_name )
return 0; return 0;
@ -190,9 +189,9 @@ int DIALOG_EXCHANGE_MODULE::Maj_ListeCmp( const wxString& reference,
return 1; return 1;
} }
ignore = fgets( line, sizeof(line), FichCmp ); fgets( line, sizeof(line), FichCmp );
fprintf( NewFile, "Cmp-Mod V01 Genere par PcbNew le %s\n", TO_UTF8( DateAndTime() ) ); fprintf( NewFile, "Cmp-Mod V01 Created by PcbNew date = %s\n", TO_UTF8( DateAndTime() ) );
bool start_descr = false; bool start_descr = false;
@ -588,7 +587,6 @@ void PCB_EDIT_FRAME::RecreateCmpFileFromBoard( wxCommandEvent& aEvent )
MODULE* Module = GetBoard()->m_Modules; MODULE* Module = GetBoard()->m_Modules;
wxString msg; wxString msg;
wxString wildcard; wxString wildcard;
char* ignore;
if( Module == NULL ) if( Module == NULL )
{ {
@ -619,7 +617,7 @@ void PCB_EDIT_FRAME::RecreateCmpFileFromBoard( wxCommandEvent& aEvent )
return; return;
} }
ignore = fgets( line, sizeof(line), FichCmp ); fgets( line, sizeof(line), FichCmp );
fprintf( FichCmp, "Cmp-Mod V01 Genere par PcbNew le %s\n", TO_UTF8( DateAndTime() ) ); fprintf( FichCmp, "Cmp-Mod V01 Genere par PcbNew le %s\n", TO_UTF8( DateAndTime() ) );
for( ; Module != NULL; Module = Module->Next() ) for( ; Module != NULL; Module = Module->Next() )