void PCB_EDIT_FRAME::Start_Move_Zone_Outlines( wxDC* DC, ZONE_CONTAINER* aZone ) { // Show the Net if( aZone->IsOnCopperLayer() ) // Show the Net { if( GetBoard()->IsHighLightNetON() ) { HighLight( DC ); // Remove old highlight selection } ZONE_SETTINGS zoneInfo = GetZoneSettings(); zoneInfo.m_NetcodeSelection = aZone->GetNet(); SetZoneSettings( zoneInfo ); GetBoard()->SetHighLightNet( aZone->GetNet() ); HighLight( DC ); } s_PickedList.ClearListAndDeleteItems(); s_AuxiliaryList.ClearListAndDeleteItems(); SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNet(), aZone->GetLayer() ); aZone->SetFlags( IS_MOVED ); m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse, Abort_Zone_Move_Corner_Or_Outlines ); s_CursorLastPosition = s_CornerInitialPosition = GetScreen()->GetCrossHairPosition(); s_CornerIsNew = false; s_AddCutoutToCurrentZone = false; s_CurrentZone = NULL; }
void PCB_EDIT_FRAME::duplicateZone( wxDC* aDC, ZONE_CONTAINER* aZone ) { ZONE_CONTAINER* newZone = new ZONE_CONTAINER( GetBoard() ); newZone->Copy( aZone ); newZone->UnFill(); ZONE_SETTINGS zoneSettings; zoneSettings << *aZone; bool success; if( aZone->GetIsKeepout() ) success = InvokeKeepoutAreaEditor( this, &zoneSettings ); else if( aZone->IsOnCopperLayer() ) success = InvokeCopperZonesEditor( this, &zoneSettings ); else success = InvokeNonCopperZonesEditor( this, aZone, &zoneSettings ); if( success ) { zoneSettings.ExportSetting( *newZone ); newZone->m_Poly->Hatch(); s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems(); SaveCopyOfZones( s_PickedList, GetBoard(), newZone->GetNet(), newZone->GetLayer() ); GetBoard()->Add( newZone ); ITEM_PICKER picker( newZone, UR_NEW ); s_PickedList.PushItem( picker ); GetScreen()->SetCurItem( NULL ); // This outline may be deleted when merging outlines // Combine zones if possible GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, newZone ); // Redraw zones GetBoard()->RedrawAreasOutlines( m_canvas, aDC, GR_OR, newZone->GetLayer() ); GetBoard()->RedrawFilledAreas( m_canvas, aDC, GR_OR, newZone->GetLayer() ); if( GetBoard()->GetAreaIndex( newZone ) >= 0 && GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( newZone, true ) ) { DisplayError( this, _( "Duplicate Zone: The outline of the duplicated zone fails DRC check!" ) ); } UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() ); SaveCopyInUndoList( s_PickedList, UR_UNSPECIFIED ); s_PickedList.ClearItemsList(); OnModify(); } else delete newZone; }
/** Abort function for drag or move track */ static void Abort_MoveTrack( EDA_DRAW_PANEL* aPanel, wxDC* aDC ) { PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) aPanel->GetParent(); BOARD * pcb = frame->GetBoard(); pcb->HighLightOFF(); pcb->PopHighLight(); frame->SetCurItem( NULL ); aPanel->SetMouseCapture( NULL, NULL ); // Undo move and redraw trace segments. for( unsigned jj=0 ; jj < g_DragSegmentList.size(); jj++ ) { TRACK* track = g_DragSegmentList[jj].m_Track; g_DragSegmentList[jj].RestoreInitialValues(); track->SetState( IN_EDIT, false ); track->ClearFlags(); } // Clear the undo picker list: s_ItemsListPicker.ClearListAndDeleteItems(); EraseDragList(); aPanel->Refresh(); }
/* Function called to abort a track creation */ static void Abort_Create_Track( EDA_DRAW_PANEL* Panel, wxDC* DC ) { PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Panel->GetParent(); BOARD* pcb = frame->GetBoard(); TRACK* track = (TRACK*) frame->GetCurItem(); if( track && ( track->Type()==PCB_VIA_T || track->Type()==PCB_TRACE_T ) ) { // Erase the current drawing ShowNewTrackWhenMovingCursor( Panel, DC, wxDefaultPosition, false ); if( pcb->IsHighLightNetON() ) frame->HighLight( DC ); pcb->PopHighLight(); if( pcb->IsHighLightNetON() ) pcb->DrawHighLight( Panel, DC, pcb->GetHighLightNetCode() ); frame->ClearMsgPanel(); // Undo pending changes (mainly a lock point creation) and clear the // undo picker list: frame->PutDataInPreviousState( &s_ItemsListPicker, false, false ); s_ItemsListPicker.ClearListAndDeleteItems(); // Delete current (new) track g_CurrentTrackList.DeleteAll(); } frame->SetCurItem( NULL ); }
void PCB_EDIT_FRAME::Start_Move_Zone_Drag_Outline_Edge( wxDC* DC, ZONE_CONTAINER* aZone, int corner_id ) { aZone->SetFlags( IS_DRAGGED ); aZone->SetSelectedCorner( corner_id ); m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse, Abort_Zone_Move_Corner_Or_Outlines ); s_CursorLastPosition = s_CornerInitialPosition = GetCrossHairPosition(); s_AddCutoutToCurrentZone = false; s_CurrentZone = NULL; s_PickedList.ClearListAndDeleteItems(); s_AuxiliaryList.ClearListAndDeleteItems(); SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() ); }
void PCB_EDIT_FRAME::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone, int corner_id, bool IsNewCorner ) { if( aZone->IsOnCopperLayer() ) // Show the Net { if( GetBoard()->IsHighLightNetON() && DC ) { HighLight( DC ); // Remove old highlight selection } ZONE_SETTINGS zoneInfo = GetZoneSettings(); zoneInfo.m_NetcodeSelection = aZone->GetNet(); SetZoneSettings( zoneInfo ); GetBoard()->SetHighLightNet( aZone->GetNet() ); if( DC ) HighLight( DC ); } // Prepare copy of old zones, for undo/redo. // if the corner is new, remove it from list, save and insert it in list int cx = aZone->m_Poly->GetX( corner_id ); int cy = aZone->m_Poly->GetY( corner_id ); if ( IsNewCorner ) aZone->m_Poly->DeleteCorner( corner_id ); s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems(); SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNet(), aZone->GetLayer() ); if ( IsNewCorner ) aZone->m_Poly->InsertCorner(corner_id-1, cx, cy ); aZone->SetFlags( IN_EDIT ); m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse, Abort_Zone_Move_Corner_Or_Outlines ); s_CornerInitialPosition = aZone->GetCornerPosition( corner_id ); s_CornerIsNew = IsNewCorner; s_AddCutoutToCurrentZone = false; s_CurrentZone = NULL; }
void PCB_EDIT_FRAME::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone ) { OnModify(); if( aZone->m_Poly->GetNumCorners() <= 3 ) { m_canvas->RefreshDrawingRect( aZone->GetBoundingBox() ); if( DC ) { // Remove the full zone because this is no more an area aZone->UnFill(); aZone->DrawFilledArea( m_canvas, DC, GR_XOR ); } GetBoard()->Delete( aZone ); return; } int layer = aZone->GetLayer(); if( DC ) { GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_XOR, layer ); GetBoard()->RedrawFilledAreas( m_canvas, DC, GR_XOR, layer ); } s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList. ClearListAndDeleteItems(); SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNet(), aZone->GetLayer() ); aZone->m_Poly->DeleteCorner( aZone->m_CornerSelection ); // modify zones outlines according to the new aZone shape GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone ); if( DC ) { GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_OR, layer ); GetBoard()->RedrawFilledAreas( m_canvas, DC, GR_OR, layer ); } UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() ); SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED); s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items int ii = GetBoard()->GetAreaIndex( aZone ); // test if aZone exists if( ii < 0 ) aZone = NULL; // aZone does not exist anymore, after combining zones int error_count = GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( aZone, true ); if( error_count ) { DisplayError( this, _( "Area: DRC outline error" ) ); } }
/** * Function Abort_Zone_Move_Corner_Or_Outlines * cancels the Begin_Zone state if at least one EDGE_ZONE has been created. */ void Abort_Zone_Move_Corner_Or_Outlines( EDA_DRAW_PANEL* Panel, wxDC* DC ) { PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Panel->GetParent(); ZONE_CONTAINER* zone = (ZONE_CONTAINER*) pcbframe->GetCurItem(); if( zone->IsMoving() ) { wxPoint offset; offset = s_CornerInitialPosition - s_CursorLastPosition; zone->Move( offset ); } else if( zone->IsDragging() ) { wxPoint offset; offset = s_CornerInitialPosition - s_CursorLastPosition; zone->MoveEdge( offset ); } else { if( s_CornerIsNew ) { zone->m_Poly->DeleteCorner( zone->m_CornerSelection ); } else { wxPoint pos = s_CornerInitialPosition; zone->m_Poly->MoveCorner( zone->m_CornerSelection, pos.x, pos.y ); } } Panel->SetMouseCapture( NULL, NULL ); s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList. ClearListAndDeleteItems(); Panel->Refresh(); pcbframe->SetCurItem( NULL ); zone->ClearFlags(); s_AddCutoutToCurrentZone = false; s_CurrentZone = NULL; }
/* Route all traces * : * 1 if OK * -1 if escape (stop being routed) request * -2 if default memory allocation */ int PCB_EDIT_FRAME::Solve( wxDC* DC, int aLayersCount ) { int current_net_code; int row_source, col_source, row_target, col_target; int success, nbsucces = 0, nbunsucces = 0; NETINFO_ITEM* net; bool stop = false; wxString msg; int routedCount = 0; // routed ratsnest count bool two_sides = aLayersCount == 2; m_canvas->SetAbortRequest( false ); s_Clearance = GetBoard()->GetDesignSettings().GetDefault()->GetClearance(); // Prepare the undo command info s_ItemsListPicker.ClearListAndDeleteItems(); // Should not be necessary, but... // go until no more work to do GetWork( &row_source, &col_source, ¤t_net_code, &row_target, &col_target, &pt_cur_ch ); // First net to route. for( ; row_source != ILLEGAL; GetWork( &row_source, &col_source, ¤t_net_code, &row_target, &col_target, &pt_cur_ch ) ) { // Test to stop routing ( escape key pressed ) wxYield(); if( m_canvas->GetAbortRequest() ) { if( IsOK( this, _( "Abort routing?" ) ) ) { success = STOP_FROM_ESC; stop = true; break; } else { m_canvas->SetAbortRequest( false ); } } EraseMsgBox(); routedCount++; net = GetBoard()->FindNet( current_net_code ); if( net ) { msg.Printf( wxT( "[%8.8s]" ), GetChars( net->GetNetname() ) ); AppendMsgPanel( wxT( "Net route" ), msg, BROWN ); msg.Printf( wxT( "%d / %d" ), routedCount, RoutingMatrix.m_RouteCount ); AppendMsgPanel( wxT( "Activity" ), msg, BROWN ); } segm_oX = GetBoard()->GetBoundingBox().GetX() + (RoutingMatrix.m_GridRouting * col_source); segm_oY = GetBoard()->GetBoundingBox().GetY() + (RoutingMatrix.m_GridRouting * row_source); segm_fX = GetBoard()->GetBoundingBox().GetX() + (RoutingMatrix.m_GridRouting * col_target); segm_fY = GetBoard()->GetBoundingBox().GetY() + (RoutingMatrix.m_GridRouting * row_target); // Draw segment. GRLine( m_canvas->GetClipBox(), DC, segm_oX, segm_oY, segm_fX, segm_fY, 0, WHITE ); pt_cur_ch->m_PadStart->Draw( m_canvas, DC, GR_OR | GR_HIGHLIGHT ); pt_cur_ch->m_PadEnd->Draw( m_canvas, DC, GR_OR | GR_HIGHLIGHT ); success = Autoroute_One_Track( this, DC, two_sides, row_source, col_source, row_target, col_target, pt_cur_ch ); switch( success ) { case NOSUCCESS: pt_cur_ch->m_Status |= CH_UNROUTABLE; nbunsucces++; break; case STOP_FROM_ESC: stop = true; break; case ERR_MEMORY: stop = true; break; default: nbsucces++; break; } msg.Printf( wxT( "%d" ), nbsucces ); AppendMsgPanel( wxT( "OK" ), msg, GREEN ); msg.Printf( wxT( "%d" ), nbunsucces ); AppendMsgPanel( wxT( "Fail" ), msg, RED ); msg.Printf( wxT( " %d" ), GetBoard()->GetUnconnectedNetCount() ); AppendMsgPanel( wxT( "Not Connected" ), msg, CYAN ); // Delete routing from display. pt_cur_ch->m_PadStart->Draw( m_canvas, DC, GR_AND ); pt_cur_ch->m_PadEnd->Draw( m_canvas, DC, GR_AND ); if( stop ) break; } SaveCopyInUndoList( s_ItemsListPicker, UR_UNSPECIFIED ); s_ItemsListPicker.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items return SUCCESS; }
void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone ) { ZONE_EDIT_T edited; ZONE_SETTINGS zoneInfo = GetZoneSettings(); m_canvas->SetIgnoreMouseEvents( true ); // Save initial zones configuration, for undo/redo, before adding new zone // note the net name and the layer can be changed, so we must save all zones s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems(); SaveCopyOfZones(s_PickedList, GetBoard(), -1, -1 ); if( aZone->GetIsKeepout() ) { // edit a keepout area on a copper layer zoneInfo << *aZone; edited = InvokeKeepoutAreaEditor( this, &zoneInfo ); } else if( aZone->GetLayer() < FIRST_NO_COPPER_LAYER ) { // edit a zone on a copper layer zoneInfo << *aZone; edited = InvokeCopperZonesEditor( this, &zoneInfo ); } else { edited = InvokeNonCopperZonesEditor( this, aZone, &zoneInfo ); } m_canvas->MoveCursorToCrossHair(); m_canvas->SetIgnoreMouseEvents( false ); if( edited == ZONE_ABORT ) { s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems(); return; } SetZoneSettings( zoneInfo ); if( edited == ZONE_EXPORT_VALUES ) { UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() ); SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED); s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items return; } // Undraw old zone outlines for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ ) { ZONE_CONTAINER* edge_zone = GetBoard()->GetArea( ii ); edge_zone->Draw( m_canvas, DC, GR_XOR ); } zoneInfo.ExportSetting( *aZone ); NETINFO_ITEM* net = GetBoard()->FindNet( zoneInfo.m_NetcodeSelection ); if( net ) // net == NULL should not occur aZone->SetNetName( net->GetNetname() ); // Combine zones if possible GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone ); // Redraw the real new zone outlines GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_OR, -1 ); UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() ); SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED); s_PickedList.ClearItemsList(); // s_ItemsListPicker is no longer owner of picked items OnModify(); }
bool PCB_EDIT_FRAME::End_Zone( wxDC* DC ) { ZONE_CONTAINER* zone = GetBoard()->m_CurrentZoneContour; if( !zone ) return true; // Validate the current outline: if( zone->GetNumCorners() <= 2 ) // An outline must have 3 corners or more { Abort_Zone_Create_Outline( m_canvas, DC ); return true; } // Remove the last corner if is is at the same location as the prevoius corner zone->m_Poly->RemoveNullSegments(); // Validate the current edge: int icorner = zone->GetNumCorners() - 1; if( zone->IsOnCopperLayer() ) { if( Drc_On && m_drc->Drc( zone, icorner - 1 ) == BAD_DRC ) // we can't validate last edge return false; if( Drc_On && m_drc->Drc( zone, icorner ) == BAD_DRC ) // we can't validate the closing edge { DisplayError( this, _( "DRC error: closing this area creates a drc error with an other area" ) ); m_canvas->MoveCursorToCrossHair(); return false; } } zone->ClearFlags(); zone->DrawWhileCreateOutline( m_canvas, DC, GR_XOR ); m_canvas->SetMouseCapture( NULL, NULL ); // Undraw old drawings, because they can have important changes int layer = zone->GetLayer(); GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_XOR, layer ); GetBoard()->RedrawFilledAreas( m_canvas, DC, GR_XOR, layer ); // Save initial zones configuration, for undo/redo, before adding new zone s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems(); SaveCopyOfZones(s_PickedList, GetBoard(), zone->GetNet(), zone->GetLayer() ); // Put new zone in list if( !s_CurrentZone ) { zone->m_Poly->CloseLastContour(); // Close the current corner list GetBoard()->Add( zone ); GetBoard()->m_CurrentZoneContour = NULL; // Add this zone in picked list, as new item ITEM_PICKER picker( zone, UR_NEW ); s_PickedList.PushItem( picker ); } else // Append this outline as a cutout to an existing zone { for( int ii = 0; ii < zone->GetNumCorners(); ii++ ) { s_CurrentZone->AppendCorner( zone->GetCornerPosition( ii ) ); } s_CurrentZone->m_Poly->CloseLastContour(); // Close the current corner list zone->RemoveAllContours(); // All corners are copied in s_CurrentZone. Free corner list. zone = s_CurrentZone; } s_AddCutoutToCurrentZone = false; s_CurrentZone = NULL; GetScreen()->SetCurItem( NULL ); // This outline can be deleted when merging outlines // Combine zones if possible : GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, zone ); // Redraw the real edge zone : GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_OR, layer ); GetBoard()->RedrawFilledAreas( m_canvas, DC, GR_OR, layer ); int ii = GetBoard()->GetAreaIndex( zone ); // test if zone exists if( ii < 0 ) zone = NULL; // was removed by combining zones int error_count = GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( zone, true ); if( error_count ) { DisplayError( this, _( "Area: DRC outline error" ) ); } UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() ); SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED); s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items OnModify(); return true; }
/* * This function starts a new track segment. * If a new track segment is in progress, ends this current new segment, * and created a new one. */ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC ) { TRACK* TrackOnStartPoint = NULL; int layerMask = GetLayerMask( GetScreen()->m_Active_Layer ); BOARD_CONNECTED_ITEM* LockPoint; wxPoint pos = GetScreen()->GetCrossHairPosition(); if( aTrack == NULL ) // Starting a new track segment { m_canvas->SetMouseCapture( ShowNewTrackWhenMovingCursor, Abort_Create_Track ); // Prepare the undo command info s_ItemsListPicker.ClearListAndDeleteItems(); // Should not be necessary, but... GetBoard()->PushHighLight(); // erase old highlight if( GetBoard()->IsHighLightNetON() ) HighLight( aDC ); g_CurrentTrackList.PushBack( new TRACK( GetBoard() ) ); g_CurrentTrackSegment->SetFlags( IS_NEW ); GetBoard()->SetHighLightNet( 0 ); // Search for a starting point of the new track, a track or pad LockPoint = GetBoard()->GetLockPoint( pos, layerMask ); D_PAD* pad = NULL; if( LockPoint ) // An item (pad or track) is found { if( LockPoint->Type() == PCB_PAD_T ) { pad = (D_PAD*) LockPoint; // A pad is found: put the starting point on pad center pos = pad->GetPosition(); GetBoard()->SetHighLightNet( pad->GetNet() ); } else // A track segment is found { TrackOnStartPoint = (TRACK*) LockPoint; GetBoard()->SetHighLightNet( TrackOnStartPoint->GetNet() ); GetBoard()->CreateLockPoint( pos, TrackOnStartPoint, &s_ItemsListPicker ); } } else { // Not a starting point, but a filled zone area can exist. This is also a // good starting point. ZONE_CONTAINER* zone; zone = GetBoard()->HitTestForAnyFilledArea( pos, GetScreen()-> m_Active_Layer ); if( zone ) GetBoard()->SetHighLightNet( zone->GetNet() ); } D( g_CurrentTrackList.VerifyListIntegrity() ); BuildAirWiresTargetsList( LockPoint, wxPoint( 0, 0 ), true ); D( g_CurrentTrackList.VerifyListIntegrity() ); GetBoard()->HighLightON(); GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() ); // Display info about track Net class, and init track and vias sizes: g_CurrentTrackSegment->SetNet( GetBoard()->GetHighLightNetCode() ); GetBoard()->SetCurrentNetClass( g_CurrentTrackSegment->GetNetClassName() ); g_CurrentTrackSegment->SetLayer( GetScreen()->m_Active_Layer ); g_CurrentTrackSegment->SetWidth( GetBoard()->GetCurrentTrackWidth() ); if( GetBoard()->GetDesignSettings().m_UseConnectedTrackWidth ) { if( TrackOnStartPoint && TrackOnStartPoint->Type() == PCB_TRACE_T ) g_CurrentTrackSegment->SetWidth( TrackOnStartPoint->GetWidth()); } g_CurrentTrackSegment->SetStart( pos ); g_CurrentTrackSegment->SetEnd( pos ); if( pad ) { g_CurrentTrackSegment->m_PadsConnected.push_back( pad ); // Useful to display track length, if the pad has a die length: g_CurrentTrackSegment->SetState( BEGIN_ONPAD, ON ); g_CurrentTrackSegment->start = pad; } if( g_TwoSegmentTrackBuild ) { // Create 2nd segment g_CurrentTrackList.PushBack( (TRACK*)g_CurrentTrackSegment->Clone() ); D( g_CurrentTrackList.VerifyListIntegrity(); ); g_CurrentTrackSegment->start = g_FirstTrackSegment; g_FirstTrackSegment->end = g_CurrentTrackSegment; g_FirstTrackSegment->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); }