From aaa1cc3e0296abcb7413b594841789bb823249e3 Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Sun, 26 Feb 2012 13:39:39 -0500 Subject: [PATCH] Eeschema object list and other minor improvements. * Convert Eeschema from manually linked list to DLIST for storing SCH_ITEM objects. * Add helper functions to SCH_SCREEN for appending list of SCH_ITEM objects. * Fix bug in wire editing code for accurate undo/redo behavior. * Add member to DLIST to append another DLIST. * Other minor code cleaning. --- common/base_struct.cpp | 8 +- common/dlist.cpp | 30 ++ common/sch_item_struct.cpp | 18 -- eeschema/block.cpp | 3 +- eeschema/bus-wire-junction.cpp | 387 +++++++++++-------------- eeschema/edit_label.cpp | 6 +- eeschema/erc.cpp | 6 +- eeschema/load_one_schematic_file.cpp | 18 +- eeschema/operations_on_items_lists.cpp | 13 +- eeschema/sch_bus_entry.cpp | 1 - eeschema/sch_bus_entry.h | 1 - eeschema/sch_component.cpp | 1 - eeschema/sch_component.h | 1 - eeschema/sch_field.cpp | 1 - eeschema/sch_field.h | 1 - eeschema/sch_junction.cpp | 1 - eeschema/sch_junction.h | 1 - eeschema/sch_line.cpp | 1 - eeschema/sch_line.h | 1 - eeschema/sch_marker.h | 1 - eeschema/sch_no_connect.cpp | 1 - eeschema/sch_no_connect.h | 1 - eeschema/sch_polyline.cpp | 1 - eeschema/sch_polyline.h | 3 +- eeschema/sch_screen.cpp | 227 +++++---------- eeschema/sch_sheet.cpp | 1 - eeschema/sch_sheet.h | 1 - eeschema/sch_sheet_pin.cpp | 1 - eeschema/sch_text.cpp | 1 - eeschema/sch_text.h | 1 - eeschema/schedit.cpp | 21 +- eeschema/schematic_undo_redo.cpp | 120 ++++---- eeschema/schframe.cpp | 3 +- eeschema/sheet.cpp | 5 +- include/class_sch_screen.h | 52 ++-- include/dlist.h | 37 ++- include/sch_item_struct.h | 3 - 37 files changed, 431 insertions(+), 548 deletions(-) diff --git a/common/base_struct.cpp b/common/base_struct.cpp index e171a04045..97abdc851b 100644 --- a/common/base_struct.cpp +++ b/common/base_struct.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-20011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -217,15 +216,14 @@ EDA_ITEM& EDA_ITEM::operator=( const EDA_ITEM& aItem ) { if( &aItem != this ) { - m_StructType = aItem.Type(); - Pnext = aItem.Pnext; - Pback = aItem.Pback; + m_Image = aItem.m_Image; m_StructType = aItem.m_StructType; m_Parent = aItem.m_Parent; m_Son = aItem.m_Son; m_Flags = aItem.m_Flags; - SetTimeStamp( aItem.m_TimeStamp ); + m_TimeStamp = aItem.m_TimeStamp; m_Status = aItem.m_Status; + m_forceVisible = aItem.m_forceVisible; } return *this; diff --git a/common/dlist.cpp b/common/dlist.cpp index aae531fd61..55ed137fd3 100644 --- a/common/dlist.cpp +++ b/common/dlist.cpp @@ -85,6 +85,36 @@ void DHEAD::append( EDA_ITEM* aNewElement ) } +void DHEAD::append( DHEAD& aList ) +{ + wxCHECK_RET( aList.GetCount() != 0, wxT( "Attempt to append empty list." ) ); + + // Change the item's list to me. + for( EDA_ITEM* item = aList.first; item != NULL; item = item->Next() ) + item->SetList( this ); + + if( first ) // list is not empty, set last item's next to the first item in aList + { + wxCHECK_RET( last != NULL, wxT( "Last list element not set." ) ); + + last->SetNext( aList.first ); + aList.first->SetBack( last ); + last = aList.last; + } + else // list is empty, first and last are same as aList + { + first = aList.first; + last = aList.last; + } + + count += aList.count; + + aList.count = 0; + aList.first = NULL; + aList.last = NULL; +} + + void DHEAD::insert( EDA_ITEM* aNewElement, EDA_ITEM* aAfterMe ) { wxASSERT( aNewElement != NULL ); diff --git a/common/sch_item_struct.cpp b/common/sch_item_struct.cpp index b0f8a2244a..baccf7d7cf 100644 --- a/common/sch_item_struct.cpp +++ b/common/sch_item_struct.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2006 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -102,23 +101,6 @@ bool SCH_ITEM::operator < ( const SCH_ITEM& aItem ) const } -SCH_ITEM& SCH_ITEM::operator=( const SCH_ITEM& aItem ) -{ - wxCHECK_MSG( Type() == aItem.Type(), *this, - wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) + - GetClass() ); - - if( &aItem != this ) - { - EDA_ITEM::operator=( aItem ); - m_Layer = aItem.m_Layer; - m_connections = aItem.m_connections; - } - - return *this; -} - - void SCH_ITEM::doPlot( PLOTTER* aPlotter ) { wxFAIL_MSG( wxT( "doPlot() method not implemented for class " ) + GetClass() ); diff --git a/eeschema/block.cpp b/eeschema/block.cpp index a2bdec1dfd..d62b4d74bf 100644 --- a/eeschema/block.cpp +++ b/eeschema/block.cpp @@ -559,8 +559,7 @@ void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC ) SetSchItemParent( Struct, GetScreen() ); Struct->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); - Struct->SetNext( GetScreen()->GetDrawItems() ); - GetScreen()->SetDrawItems( Struct ); + GetScreen()->Append( Struct ); } SaveCopyInUndoList( picklist, UR_NEW ); diff --git a/eeschema/bus-wire-junction.cpp b/eeschema/bus-wire-junction.cpp index ad990cec55..b20d6639ac 100644 --- a/eeschema/bus-wire-junction.cpp +++ b/eeschema/bus-wire-junction.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -51,8 +50,10 @@ static void AbortCreateNewLine( EDA_DRAW_PANEL* Panel, wxDC* DC ); static void ComputeBreakPoint( SCH_LINE* segment, const wxPoint& new_pos ); -SCH_ITEM* s_OldWiresList; -wxPoint s_ConnexionStartPoint; +static DLIST< SCH_ITEM > s_wires; +static DLIST< SCH_ITEM > s_oldWires; + +static wxPoint s_startPoint; /** @@ -61,19 +62,17 @@ wxPoint s_ConnexionStartPoint; static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, bool aErase ) { - SCH_LINE* CurrentLine = (SCH_LINE*) aPanel->GetScreen()->GetCurItem(); SCH_LINE* segment; int color; - if( CurrentLine == NULL ) + if( s_wires.GetCount() == 0 ) return; - color = ReturnLayerColor( CurrentLine->GetLayer() ) ^ HIGHLIGHT_FLAG; + segment = (SCH_LINE*) s_wires.begin(); + color = ReturnLayerColor( segment->GetLayer() ) ^ HIGHLIGHT_FLAG; if( aErase ) { - segment = CurrentLine; - while( segment ) { if( !segment->IsNull() ) // Redraw if segment length != 0 @@ -86,11 +85,11 @@ static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosi wxPoint endpos = aPanel->GetScreen()->GetCrossHairPosition(); if( g_HVLines ) /* Coerce the line to vertical or horizontal one: */ - ComputeBreakPoint( CurrentLine, endpos ); + ComputeBreakPoint( (SCH_LINE*) s_wires.GetLast()->Back(), endpos ); else - CurrentLine->SetEndPoint( endpos ); + ( (SCH_LINE*) s_wires.GetLast() )->SetEndPoint( endpos ); - segment = CurrentLine; + segment = (SCH_LINE*) s_wires.begin(); while( segment ) { @@ -104,259 +103,195 @@ static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosi void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type ) { - SCH_LINE* oldsegment, * newsegment, * nextsegment; + SCH_LINE* segment; + SCH_LINE* nextSegment; wxPoint cursorpos = GetScreen()->GetCrossHairPosition(); - if( GetScreen()->GetCurItem() && (GetScreen()->GetCurItem()->GetFlags() == 0) ) - GetScreen()->SetCurItem( NULL ); + segment = (SCH_LINE*) GetScreen()->GetCurItem(); - if( GetScreen()->GetCurItem() ) + if( !segment ) /* first point : Create first wire or bus */ { - switch( GetScreen()->GetCurItem()->Type() ) - { - case SCH_LINE_T: - case SCH_POLYLINE_T: - break; - - default: - return; - } - } - - oldsegment = newsegment = (SCH_LINE*) GetScreen()->GetCurItem(); - - if( !newsegment ) /* first point : Create first wire or bus */ - { - s_ConnexionStartPoint = cursorpos; - s_OldWiresList = GetScreen()->ExtractWires( true ); + s_startPoint = cursorpos; + GetScreen()->ExtractWires( s_oldWires, true ); GetScreen()->SchematicCleanUp( m_canvas ); switch( type ) { default: - newsegment = new SCH_LINE( cursorpos, LAYER_NOTES ); + segment = new SCH_LINE( cursorpos, LAYER_NOTES ); break; case LAYER_WIRE: - newsegment = new SCH_LINE( cursorpos, LAYER_WIRE ); + segment = new SCH_LINE( cursorpos, LAYER_WIRE ); /* A junction will be created later, when we'll know the * segment end position, and if the junction is really needed */ break; case LAYER_BUS: - newsegment = new SCH_LINE( cursorpos, LAYER_BUS ); + segment = new SCH_LINE( cursorpos, LAYER_BUS ); break; } - newsegment->SetFlags( IS_NEW ); + segment->SetFlags( IS_NEW ); + s_wires.PushBack( segment ); + GetScreen()->SetCurItem( segment ); - if( g_HVLines ) // We need 2 segments to go from a given start pin to an end point + // We need 2 segments to go from a given start pin to an end point when the horizontal + // and vertical lines only switch is on. + if( g_HVLines ) { - nextsegment = new SCH_LINE( *newsegment ); - nextsegment->SetFlags( IS_NEW ); - newsegment->SetNext( nextsegment ); - nextsegment->SetBack( newsegment ); + nextSegment = new SCH_LINE( *segment ); + nextSegment->SetFlags( IS_NEW ); + s_wires.PushBack( nextSegment ); + GetScreen()->SetCurItem( nextSegment ); } - GetScreen()->SetCurItem( newsegment ); m_canvas->SetMouseCapture( DrawSegment, AbortCreateNewLine ); m_itemToRepeat = NULL; } else // A segment is in progress: terminates the current segment and add a new segment. { - nextsegment = oldsegment->Next(); + SCH_LINE* prevSegment = (SCH_LINE*) segment->Back(); + + wxLogDebug( wxT( "Adding new segment after " ) + segment->GetSelectMenuText() ); if( !g_HVLines ) { - // if only one segment is needed and it has length = 0, do not create a new one. - if( oldsegment->IsNull() ) + // If only one segment is needed and it has a zero length, do not create a new one. + if( segment->IsNull() ) return; } else { - /* if we want 2 segment and the last two have len = 0, do not - * create a new one */ - if( oldsegment->IsNull() && nextsegment && nextsegment->IsNull() ) + wxCHECK_RET( prevSegment != NULL, wxT( "Failed to create second line segment." ) ); + + // If two segments are required and they both have zero length, do not + // create a new one. + if( prevSegment && prevSegment->IsNull() && segment->IsNull() ) return; } m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); - /* Creates the new segment, or terminates the command - * if the end point is on a pin, junction or an other wire or bus */ - if( GetScreen()->IsTerminalPoint( cursorpos, oldsegment->GetLayer() ) ) + // Terminate the command if the end point is on a pin, junction, or another wire or bus. + if( GetScreen()->IsTerminalPoint( cursorpos, segment->GetLayer() ) ) { EndSegment( DC ); return; } - oldsegment->SetNext( GetScreen()->GetDrawItems() ); - GetScreen()->SetDrawItems( oldsegment ); - m_canvas->CrossHairOff( DC ); // Erase schematic cursor - oldsegment->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); - m_canvas->CrossHairOn( DC ); // Display schematic cursor + // Create a new segment, and chain it after the current new segment. + nextSegment = new SCH_LINE( *segment ); + nextSegment->SetStartPoint( cursorpos ); + s_wires.PushBack( nextSegment ); - /* Create a new segment, and chain it after the current new segment */ - if( nextsegment ) - { - newsegment = new SCH_LINE( *nextsegment ); - nextsegment->SetStartPoint( newsegment->GetEndPoint() ); - nextsegment->SetNext( NULL ); - nextsegment->SetBack( newsegment ); - newsegment->SetNext( nextsegment ); - newsegment->SetBack( NULL ); - } - else - { - newsegment = new SCH_LINE( *oldsegment ); - newsegment->SetStartPoint( oldsegment->GetEndPoint() ); - } - - newsegment->SetEndPoint( cursorpos ); - oldsegment->ClearFlags( IS_NEW ); - oldsegment->SetFlags( SELECTED ); - newsegment->SetFlags( IS_NEW ); - GetScreen()->SetCurItem( newsegment ); + segment->SetEndPoint( cursorpos ); + segment->ClearFlags( IS_NEW ); + segment->SetFlags( SELECTED ); + nextSegment->SetFlags( IS_NEW ); + GetScreen()->SetCurItem( nextSegment ); m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); - - /* This is the first segment: Now we know the start segment position. - * Create a junction if needed. Note: a junction can be needed later, - * if the new segment is merged (after a cleanup) with an older one - * (tested when the connection will be finished)*/ - if( oldsegment->GetStartPoint() == s_ConnexionStartPoint ) - { - if( GetScreen()->IsJunctionNeeded( s_ConnexionStartPoint ) ) - AddJunction( DC, s_ConnexionStartPoint ); - } } } void SCH_EDIT_FRAME::EndSegment( wxDC* DC ) { - SCH_LINE* firstsegment = (SCH_LINE*) GetScreen()->GetCurItem(); - SCH_LINE* lastsegment = firstsegment; - SCH_LINE* segment; + SCH_SCREEN* screen = GetScreen(); + SCH_LINE* segment = (SCH_LINE*) screen->GetCurItem(); - if( firstsegment == NULL ) + if( segment == NULL || segment->Type() != SCH_LINE_T || !segment->IsNew() ) return; - if( !firstsegment->IsNew() ) - return; - - /* Delete Null segments and Put line it in Drawlist */ - lastsegment = firstsegment; - - while( lastsegment ) - { - SCH_LINE* nextsegment = lastsegment->Next(); - - if( lastsegment->IsNull() ) - { - SCH_LINE* previous_segment = lastsegment->Back(); - - if( firstsegment == lastsegment ) - firstsegment = nextsegment; - - if( nextsegment ) - nextsegment->SetBack( NULL ); - - if( previous_segment ) - previous_segment->SetNext( nextsegment ); - - delete lastsegment; - } - - lastsegment = nextsegment; - } - - /* put the segment list to the main linked list */ - segment = lastsegment = firstsegment; - - while( segment ) - { - lastsegment = segment; - segment = segment->Next(); - lastsegment->SetNext( GetScreen()->GetDrawItems() ); - GetScreen()->SetDrawItems( lastsegment ); - } - - m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false ); - GetScreen()->SetCurItem( NULL ); - - wxPoint end_point, alt_end_point; - - /* A junction can be needed to connect the last segment - * usually to m_end coordinate. - * But if the last segment is removed by a cleanup, because of redundancy, - * a junction can be needed to connect the previous segment m_end - * coordinate with is also the lastsegment->m_start coordinate */ - if( lastsegment ) - { - end_point = lastsegment->GetEndPoint(); - alt_end_point = lastsegment->GetStartPoint(); - } - - GetScreen()->SchematicCleanUp( m_canvas ); - - /* clear flags and find last segment entered, for repeat function */ - segment = (SCH_LINE*) GetScreen()->GetDrawItems(); - - while( segment ) - { - if( segment->GetFlags() ) - { - if( !m_itemToRepeat ) - m_itemToRepeat = segment; - } - - segment->ClearFlags(); - segment = segment->Next(); - } - - // Automatic place of a junction on the end point, if needed - if( lastsegment ) - { - if( GetScreen()->IsJunctionNeeded( end_point ) ) - AddJunction( DC, end_point ); - else if( GetScreen()->IsJunctionNeeded( alt_end_point ) ) - AddJunction( DC, alt_end_point ); - } - - /* Automatic place of a junction on the start point if necessary because - * the cleanup can suppress intermediate points by merging wire segments */ - if( GetScreen()->IsJunctionNeeded( s_ConnexionStartPoint ) ) - AddJunction( DC, s_ConnexionStartPoint ); - - GetScreen()->TestDanglingEnds( m_canvas, DC ); - - /* Redraw wires and junctions which can be changed by TestDanglingEnds() */ - m_canvas->CrossHairOff( DC ); // Erase schematic cursor - EDA_ITEM* item = GetScreen()->GetDrawItems(); + // Delete zero length segments and clear item flags. + SCH_ITEM* item = s_wires.begin(); while( item ) { - switch( item->Type() ) - { - case SCH_JUNCTION_T: - case SCH_LINE_T: - m_canvas->RefreshDrawingRect( item->GetBoundingBox() ); - break; + item->ClearFlags(); - default: - break; + wxCHECK_RET( item->Type() == SCH_LINE_T, wxT( "Unexpected object type in wire list." ) ); + + segment = (SCH_LINE*) item; + + if( segment->IsNull() ) + { + wxLogDebug( wxT( "Removing null segment: " ) + segment->GetSelectMenuText() ); + + SCH_ITEM* previousSegment = item->Back(); + + delete s_wires.Remove( item ); + + if( previousSegment == NULL ) + item = s_wires.begin(); + else + item = previousSegment; } item = item->Next(); } - m_canvas->CrossHairOn( DC ); // Display schematic cursor + if( s_wires.GetCount() == 0 ) + return; - SaveCopyInUndoList( s_OldWiresList, UR_WIRE_IMAGE ); - s_OldWiresList = NULL; + // Get the last non-null wire. + m_itemToRepeat = segment = (SCH_LINE*) s_wires.GetLast(); + screen->SetCurItem( NULL ); + m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false ); - OnModify( ); + DLIST< SCH_ITEM > tmp; + + for( item = s_wires.begin(); item != NULL; item = item->Next() ) + tmp.PushBack( (SCH_ITEM*) item->Clone() ); + + // Temporarily add the new segments to the schematic item list to test if any + // junctions are required. + screen->Append( tmp ); + + // Correct and remove segments that need merged. + screen->SchematicCleanUp( m_canvas, DC ); + + // A junction may be needed to connect the last segment. If the last segment was + // removed by a cleanup, a junction may be needed to connect the segment's end point + // which is also the same as the previous segment's start point. + if( screen->IsJunctionNeeded( segment->GetEndPoint() ) ) + s_wires.Append( AddJunction( DC, segment->GetEndPoint() ) ); + else if( screen->IsJunctionNeeded( segment->GetStartPoint() ) ) + s_wires.Append( AddJunction( DC, segment->GetStartPoint() ) ); + + // Automatically place a junction on the start point if necessary because the cleanup + // can suppress intermediate points by merging wire segments. + if( screen->IsJunctionNeeded( s_startPoint ) ) + s_wires.Append( AddJunction( DC, s_startPoint ) ); + + // Make a copy of the original wires, buses, and junctions. + for( item = s_oldWires.begin(); item != NULL; item = item->Next() ) + tmp.PushBack( (SCH_ITEM*) item->Clone() ); + + // Restore the old wires. + if( tmp.GetCount() != 0 ) + screen->ReplaceWires( tmp ); + + // Now add the new wires and any required junctions to the schematic item list. + screen->Append( s_wires ); + + screen->SchematicCleanUp( m_canvas, DC ); + + // Put the snap shot of the previous wire, buses, and junctions in the undo/redo list. + PICKED_ITEMS_LIST oldItems; + + oldItems.m_Status = UR_WIRE_IMAGE; + + while( s_oldWires.GetCount() != 0 ) + { + ITEM_PICKER picker = ITEM_PICKER( s_oldWires.PopFront(), UR_WIRE_IMAGE ); + oldItems.PushItem( picker ); + } + + SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE ); + + OnModify(); } @@ -364,45 +299,53 @@ void SCH_EDIT_FRAME::EndSegment( wxDC* DC ) * Function ComputeBreakPoint * computes the middle coordinate for 2 segments from the start point to \a aPosition * with the segments kept in the horizontal or vertical axis only. + * + * @param aSegment A pointer to a #SCH_LINE object containing the first line break point + * to compute. + * @param aPosition A reference to a wxPoint object containing the coordinates of the + * position used to calculate the line break point. */ static void ComputeBreakPoint( SCH_LINE* aSegment, const wxPoint& aPosition ) { - SCH_LINE* nextsegment = aSegment->Next(); - wxPoint middle_position = aPosition; + wxCHECK_RET( aSegment != NULL, wxT( "Cannot compute break point of NULL line segment." ) ); + + SCH_LINE* nextSegment = aSegment->Next(); + wxPoint midPoint = aPosition; + + wxCHECK_RET( nextSegment != NULL, + wxT( "Cannot compute break point of NULL second line segment." ) ); - if( nextsegment == NULL ) - return; #if 0 - if( ABS( middle_position.x - aSegment->GetStartPoint().x ) < - ABS( middle_position.y - aSegment->GetStartPoint().y ) ) - middle_position.x = aSegment->GetStartPoint().x; + if( ABS( midPoint.x - aSegment->GetStartPoint().x ) < + ABS( midPoint.y - aSegment->GetStartPoint().y ) ) + midPoint.x = aSegment->GetStartPoint().x; else - middle_position.y = aSegment->GetStartPoint().y; + midPoint.y = aSegment->GetStartPoint().y; #else int iDx = aSegment->GetEndPoint().x - aSegment->GetStartPoint().x; int iDy = aSegment->GetEndPoint().y - aSegment->GetStartPoint().y; if( iDy != 0 ) // keep the first segment orientation (currently horizontal) { - middle_position.x = aSegment->GetStartPoint().x; + midPoint.x = aSegment->GetStartPoint().x; } else if( iDx != 0 ) // keep the first segment orientation (currently vertical) { - middle_position.y = aSegment->GetStartPoint().y; + midPoint.y = aSegment->GetStartPoint().y; } else { - if( ABS( middle_position.x - aSegment->GetStartPoint().x ) < - ABS( middle_position.y - aSegment->GetStartPoint().y ) ) - middle_position.x = aSegment->GetStartPoint().x; + if( ABS( midPoint.x - aSegment->GetStartPoint().x ) < + ABS( midPoint.y - aSegment->GetStartPoint().y ) ) + midPoint.x = aSegment->GetStartPoint().x; else - middle_position.y = aSegment->GetStartPoint().y; + midPoint.y = aSegment->GetStartPoint().y; } #endif - aSegment->SetEndPoint( middle_position ); - nextsegment->SetStartPoint( middle_position ); - nextsegment->SetEndPoint( aPosition ); + aSegment->SetEndPoint( midPoint ); + nextSegment->SetStartPoint( midPoint ); + nextSegment->SetEndPoint( aPosition ); } @@ -443,7 +386,7 @@ void SCH_EDIT_FRAME::DeleteCurrentSegment( wxDC* DC ) DrawSegment( m_canvas, DC, wxDefaultPosition, false ); } - screen->RemoveFromDrawList( screen->GetCurItem() ); + screen->Remove( screen->GetCurItem() ); m_canvas->SetMouseCaptureCallback( NULL ); screen->SetCurItem( NULL ); } @@ -460,12 +403,12 @@ SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( wxDC* aDC, const wxPoint& aPosition, junction->Draw( m_canvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); m_canvas->CrossHairOn( aDC ); // Display schematic cursor - junction->SetNext( GetScreen()->GetDrawItems() ); - GetScreen()->SetDrawItems( junction ); - OnModify(); - if( aPutInUndoList ) + { + GetScreen()->Append( junction ); SaveCopyInUndoList( junction, UR_NEW ); + OnModify(); + } return junction; } @@ -482,8 +425,7 @@ SCH_NO_CONNECT* SCH_EDIT_FRAME::AddNoConnect( wxDC* aDC, const wxPoint& aPositio NewNoConnect->Draw( m_canvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); m_canvas->CrossHairOn( aDC ); // Display schematic cursor - NewNoConnect->SetNext( GetScreen()->GetDrawItems() ); - GetScreen()->SetDrawItems( NewNoConnect ); + GetScreen()->Append( NewNoConnect ); OnModify(); SaveCopyInUndoList( NewNoConnect, UR_NEW ); return NewNoConnect; @@ -498,9 +440,9 @@ static void AbortCreateNewLine( EDA_DRAW_PANEL* Panel, wxDC* DC ) if( screen->GetCurItem() ) { - screen->RemoveFromDrawList( (SCH_ITEM*) screen->GetCurItem() ); + s_wires.DeleteAll(); + s_oldWires.DeleteAll(); screen->SetCurItem( NULL ); - screen->ReplaceWires( s_OldWiresList ); Panel->Refresh(); } else @@ -540,8 +482,7 @@ void SCH_EDIT_FRAME::RepeatDrawItem( wxDC* DC ) if( m_itemToRepeat ) { - m_itemToRepeat->SetNext( GetScreen()->GetDrawItems() ); - GetScreen()->SetDrawItems( m_itemToRepeat ); + GetScreen()->Append( m_itemToRepeat ); GetScreen()->TestDanglingEnds(); m_itemToRepeat->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); SaveCopyInUndoList( m_itemToRepeat, UR_NEW ); diff --git a/eeschema/edit_label.cpp b/eeschema/edit_label.cpp index 04b64de408..75f9b259e7 100644 --- a/eeschema/edit_label.cpp +++ b/eeschema/edit_label.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -224,9 +223,8 @@ void SCH_EDIT_FRAME::OnConvertTextType( wxCommandEvent& aEvent ) m_canvas->CrossHairOff( &dc ); // Erase schematic cursor text->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode ); - screen->RemoveFromDrawList( text ); - screen->AddToDrawList( newtext ); - GetScreen()->SetCurItem( newtext ); + screen->Remove( text ); + screen->Append( newtext ); m_itemToRepeat = NULL; OnModify(); newtext->Draw( m_canvas, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); diff --git a/eeschema/erc.cpp b/eeschema/erc.cpp index a9698faf45..e3379d1350 100644 --- a/eeschema/erc.cpp +++ b/eeschema/erc.cpp @@ -211,8 +211,7 @@ int TestDuplicateSheetNames( bool aCreateMarker ) ( (SCH_SHEET*) test_item )->GetPosition() ); marker->SetMarkerType( MARK_ERC ); marker->SetErrorLevel( ERR ); - marker->SetNext( screen->GetDrawItems() ); - screen->SetDrawItems( marker ); + screen->Append( marker ); } err_count++; @@ -242,8 +241,7 @@ void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst, marker->SetMarkerType( MARK_ERC ); marker->SetErrorLevel( WAR ); screen = aNetItemRef->m_SheetList.LastScreen(); - marker->SetNext( screen->GetDrawItems() ); - screen->SetDrawItems( marker ); + screen->Append( marker ); wxString msg; diff --git a/eeschema/load_one_schematic_file.cpp b/eeschema/load_one_schematic_file.cpp index 3ea0e57d49..a8a2bfa4ce 100644 --- a/eeschema/load_one_schematic_file.cpp +++ b/eeschema/load_one_schematic_file.cpp @@ -57,8 +57,6 @@ bool SCH_EDIT_FRAME::LoadOneEEFile( SCH_SCREEN* aScreen, const wxString& aFullFi { char Name1[256]; bool itemLoaded = false; - SCH_ITEM* Phead; - SCH_ITEM* Pnext; SCH_ITEM* item; wxString MsgDiag; // Error and log messages char* line; @@ -228,8 +226,7 @@ again." ); } else { - item->SetNext( aScreen->GetDrawItems() ); - aScreen->SetDrawItems( item ); + aScreen->Append( item ); } } @@ -240,19 +237,6 @@ again." ); } } - /* GetDrawItems() was constructed in reverse order - reverse it back: */ - Phead = NULL; - - while( aScreen->GetDrawItems() ) - { - Pnext = aScreen->GetDrawItems(); - aScreen->SetDrawItems( aScreen->GetDrawItems()->Next() ); - Pnext->SetNext( Phead ); - Phead = Pnext; - } - - aScreen->SetDrawItems( Phead ); - #if 0 && defined (DEBUG) aScreen->Show( 0, std::cout ); #endif diff --git a/eeschema/operations_on_items_lists.cpp b/eeschema/operations_on_items_lists.cpp index 1c8f5a0270..6703b03032 100644 --- a/eeschema/operations_on_items_lists.cpp +++ b/eeschema/operations_on_items_lists.cpp @@ -126,11 +126,9 @@ void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList ) } else { - screen->RemoveFromDrawList( item ); + screen->Remove( item ); /* Unlink the structure */ - item->SetNext( 0 ); - item->SetBack( 0 ); itemsList.PushItem( itemWrapper ); } } @@ -160,11 +158,7 @@ void SCH_EDIT_FRAME::DeleteItem( SCH_ITEM* aItem ) } else { - screen->RemoveFromDrawList( aItem ); - - aItem->SetNext( NULL ); - aItem->SetBack( NULL ); // Only one struct -> no link - + screen->Remove( aItem ); SaveCopyInUndoList( aItem, UR_DELETED ); m_canvas->RefreshDrawingRect( aItem->GetBoundingBox() ); } @@ -220,8 +214,7 @@ void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList, } SetSchItemParent( newitem, screen ); - newitem->SetNext( screen->GetDrawItems() ); - screen->SetDrawItems( newitem ); + screen->Append( newitem ); } } diff --git a/eeschema/sch_bus_entry.cpp b/eeschema/sch_bus_entry.cpp index 7037e8f756..83ee22ac3a 100644 --- a/eeschema/sch_bus_entry.cpp +++ b/eeschema/sch_bus_entry.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_bus_entry.h b/eeschema/sch_bus_entry.h index 57dd258aa8..f2e7417a4a 100644 --- a/eeschema/sch_bus_entry.h +++ b/eeschema/sch_bus_entry.h @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index b277bba634..46f186b60b 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index 8c2114c896..4035f57d8b 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index 38e7e27077..7ea9cbc608 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_field.h b/eeschema/sch_field.h index d48af7fbea..df8bf3f7d8 100644 --- a/eeschema/sch_field.h +++ b/eeschema/sch_field.h @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_junction.cpp b/eeschema/sch_junction.cpp index 4088e2b46b..fe9d7c547d 100644 --- a/eeschema/sch_junction.cpp +++ b/eeschema/sch_junction.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_junction.h b/eeschema/sch_junction.h index 1ca58a6b7d..92ca5c977a 100644 --- a/eeschema/sch_junction.h +++ b/eeschema/sch_junction.h @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_line.cpp b/eeschema/sch_line.cpp index d3b49d8b6f..6169f53d69 100644 --- a/eeschema/sch_line.cpp +++ b/eeschema/sch_line.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_line.h b/eeschema/sch_line.h index 57b8e80a5c..dfa0b92032 100644 --- a/eeschema/sch_line.h +++ b/eeschema/sch_line.h @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_marker.h b/eeschema/sch_marker.h index 2446e41656..0696c3a711 100644 --- a/eeschema/sch_marker.h +++ b/eeschema/sch_marker.h @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_no_connect.cpp b/eeschema/sch_no_connect.cpp index c87dd6d669..7a7226385b 100644 --- a/eeschema/sch_no_connect.cpp +++ b/eeschema/sch_no_connect.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_no_connect.h b/eeschema/sch_no_connect.h index c6c77d4667..544782934c 100644 --- a/eeschema/sch_no_connect.h +++ b/eeschema/sch_no_connect.h @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_polyline.cpp b/eeschema/sch_polyline.cpp index 1663f3aeab..e314733a36 100644 --- a/eeschema/sch_polyline.cpp +++ b/eeschema/sch_polyline.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_polyline.h b/eeschema/sch_polyline.h index a997c4842f..30dba3d850 100644 --- a/eeschema/sch_polyline.h +++ b/eeschema/sch_polyline.h @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -37,7 +36,7 @@ class SCH_POLYLINE : public SCH_ITEM { - int m_width; /* Thickness */ + int m_width; // Thickness std::vector m_points; // list of points (>= 2) public: diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index bd49d17a3e..3747e97718 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2010 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -103,8 +102,6 @@ SCH_SCREEN::SCH_SCREEN() : { size_t i; - SetDrawItems( NULL ); // Schematic items list - SetZoom( 32 ); for( i = 0; i < SCHEMATIC_ZOOM_LIST_CNT; i++ ) @@ -158,46 +155,19 @@ void SCH_SCREEN::Clear() void SCH_SCREEN::FreeDrawList() { - SCH_ITEM* item; - - while( GetDrawItems() != NULL ) - { - item = GetDrawItems(); - SetDrawItems( GetDrawItems()->Next() ); - SAFE_DELETE( item ); - } - - SetDrawItems( NULL ); + m_drawList.DeleteAll(); } -void SCH_SCREEN::RemoveFromDrawList( SCH_ITEM* aItem ) +void SCH_SCREEN::Remove( SCH_ITEM* aItem ) { - if( aItem == GetDrawItems() ) - { - SetDrawItems( GetDrawItems()->Next() ); - } - else - { - EDA_ITEM* DrawList = GetDrawItems(); - - while( DrawList && DrawList->Next() ) - { - if( DrawList->Next() == aItem ) - { - DrawList->SetNext( DrawList->Next()->Next() ); - break; - } - - DrawList = DrawList->Next(); - } - } + m_drawList.Remove( aItem ); } void SCH_SCREEN::DeleteItem( SCH_ITEM* aItem ) { - wxCHECK_RET( aItem != NULL, wxT( "Cannot delete invaled item from screen." ) ); + wxCHECK_RET( aItem != NULL, wxT( "Cannot delete invalid item from screen." ) ); SetModify(); @@ -213,34 +183,14 @@ void SCH_SCREEN::DeleteItem( SCH_ITEM* aItem ) } else { - if( aItem == GetDrawItems() ) - { - SetDrawItems( aItem->Next() ); - SAFE_DELETE( aItem ); - } - else - { - SCH_ITEM* itemList = GetDrawItems(); - - while( itemList && itemList->Next() ) - { - if( itemList->Next() == aItem ) - { - itemList->SetNext( aItem->Next() ); - SAFE_DELETE( aItem ); - return; - } - - itemList = itemList->Next(); - } - } + delete m_drawList.Remove( aItem ); } } bool SCH_SCREEN::CheckIfOnDrawList( SCH_ITEM* aItem ) { - SCH_ITEM* itemList = GetDrawItems(); + SCH_ITEM* itemList = m_drawList.begin(); while( itemList ) { @@ -254,19 +204,9 @@ bool SCH_SCREEN::CheckIfOnDrawList( SCH_ITEM* aItem ) } -void SCH_SCREEN::AddToDrawList( SCH_ITEM* aItem ) -{ - if( aItem == NULL ) - return; - - aItem->SetNext( GetDrawItems() ); - SetDrawItems( aItem ); -} - - SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T aType ) const { - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->HitTest( aPosition, aAccuracy ) && (aType == NOT_USED) ) return item; @@ -302,11 +242,12 @@ SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T } -SCH_ITEM* SCH_SCREEN::ExtractWires( bool CreateCopy ) +void SCH_SCREEN::ExtractWires( DLIST< SCH_ITEM >& aList, bool aCreateCopy ) { - SCH_ITEM* item, * next_item, * new_item, * List = NULL; + SCH_ITEM* item; + SCH_ITEM* next_item; - for( item = GetDrawItems(); item != NULL; item = next_item ) + for( item = m_drawList.begin(); item != NULL; item = next_item ) { next_item = item->Next(); @@ -314,33 +255,27 @@ SCH_ITEM* SCH_SCREEN::ExtractWires( bool CreateCopy ) { case SCH_JUNCTION_T: case SCH_LINE_T: - RemoveFromDrawList( item ); - item->SetNext( List ); - List = item; + m_drawList.Remove( item ); + aList.Append( item ); + + if( aCreateCopy ) + m_drawList.Insert( item->Clone(), next_item ); - if( CreateCopy ) - { - new_item = item->Clone(); - new_item->SetNext( GetDrawItems() ); - SetDrawItems( new_item ); - } break; default: break; } } - - return List; } -void SCH_SCREEN::ReplaceWires( SCH_ITEM* aWireList ) +void SCH_SCREEN::ReplaceWires( DLIST< SCH_ITEM >& aWireList ) { SCH_ITEM* item; SCH_ITEM* next_item; - for( item = GetDrawItems(); item != NULL; item = next_item ) + for( item = m_drawList.begin(); item != NULL; item = next_item ) { next_item = item->Next(); @@ -348,7 +283,7 @@ void SCH_SCREEN::ReplaceWires( SCH_ITEM* aWireList ) { case SCH_JUNCTION_T: case SCH_LINE_T: - RemoveFromDrawList( item ); + Remove( item ); delete item; break; @@ -357,14 +292,7 @@ void SCH_SCREEN::ReplaceWires( SCH_ITEM* aWireList ) } } - while( aWireList ) - { - next_item = aWireList->Next(); - - aWireList->SetNext( GetDrawItems() ); - SetDrawItems( aWireList ); - aWireList = next_item; - } + m_drawList.Append( aWireList ); } @@ -373,7 +301,7 @@ void SCH_SCREEN::MarkConnections( SCH_LINE* aSegment ) wxCHECK_RET( (aSegment != NULL) && (aSegment->Type() == SCH_LINE_T), wxT( "Invalid object pointer." ) ); - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->GetFlags() & CANDIDATE ) continue; @@ -498,50 +426,50 @@ bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer ) bool SCH_SCREEN::SchematicCleanUp( EDA_DRAW_PANEL* aCanvas, wxDC* aDC ) { - SCH_ITEM* DrawList, * TstDrawList; - bool Modify = false; + SCH_ITEM* item, * testItem; + bool modified = false; - DrawList = GetDrawItems(); + item = m_drawList.begin(); - for( ; DrawList != NULL; DrawList = DrawList->Next() ) + for( ; item != NULL; item = item->Next() ) { - if( DrawList->Type() == SCH_LINE_T ) + if( item->Type() != SCH_LINE_T ) + continue; + + testItem = item->Next(); + + while( testItem ) { - TstDrawList = DrawList->Next(); - - while( TstDrawList ) + if( testItem->Type() == SCH_LINE_T ) { - if( TstDrawList->Type() == SCH_LINE_T ) - { - SCH_LINE* line = (SCH_LINE*) DrawList; + SCH_LINE* line = (SCH_LINE*) item; - if( line->MergeOverlap( (SCH_LINE*) TstDrawList ) ) - { - // Keep the current flags, because the deleted segment can be flagged. - DrawList->SetFlags( TstDrawList->GetFlags() ); - DeleteItem( TstDrawList ); - TstDrawList = GetDrawItems(); - Modify = true; - } - else - { - TstDrawList = TstDrawList->Next(); - } + if( line->MergeOverlap( (SCH_LINE*) testItem ) ) + { + // Keep the current flags, because the deleted segment can be flagged. + item->SetFlags( testItem->GetFlags() ); + DeleteItem( testItem ); + testItem = m_drawList.begin(); + modified = true; } else { - TstDrawList = TstDrawList->Next(); + testItem = testItem->Next(); } } + else + { + testItem = testItem->Next(); + } } } TestDanglingEnds( aCanvas, aDC ); - if( aCanvas && Modify ) + if( aCanvas && modified ) aCanvas->Refresh(); - return Modify; + return modified; } @@ -590,7 +518,7 @@ bool SCH_SCREEN::Save( FILE* aFile ) const || fprintf( aFile, "$EndDescr\n" ) < 0 ) return false; - for( SCH_ITEM* item = GetDrawItems(); item; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( !item->Save( aFile ) ) return false; @@ -605,7 +533,7 @@ bool SCH_SCREEN::Save( FILE* aFile ) const void SCH_SCREEN::Draw( EDA_DRAW_PANEL* aCanvas, wxDC* aDC, int aDrawMode, int aColor ) { - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->IsMoving() || item->IsResized() ) continue; @@ -621,7 +549,7 @@ void SCH_SCREEN::Draw( EDA_DRAW_PANEL* aCanvas, wxDC* aDC, int aDrawMode, int aC void SCH_SCREEN::Plot( PLOTTER* aPlotter ) { - for( SCH_ITEM* item = GetDrawItems(); item; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { aPlotter->set_current_line_width( item->GetPenSize() ); item->Plot( aPlotter ); @@ -655,7 +583,7 @@ void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount void SCH_SCREEN::ClearDrawingState() { - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) item->ClearFlags(); } @@ -667,7 +595,7 @@ LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponen SCH_COMPONENT* component = NULL; LIB_PIN* pin = NULL; - for( item = GetDrawItems(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->Type() != SCH_COMPONENT_T ) continue; @@ -717,7 +645,7 @@ LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponen SCH_SHEET* SCH_SCREEN::GetSheet( const wxString& aName ) { - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->Type() != SCH_SHEET_T ) continue; @@ -736,7 +664,7 @@ SCH_SHEET_PIN* SCH_SCREEN::GetSheetLabel( const wxPoint& aPosition ) { SCH_SHEET_PIN* sheetPin = NULL; - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->Type() != SCH_SHEET_T ) continue; @@ -757,7 +685,7 @@ int SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) SCH_ITEM* item; int count = 0; - for( item = GetDrawItems(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->Type() == SCH_JUNCTION_T && !aTestJunctions ) continue; @@ -772,7 +700,7 @@ int SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) void SCH_SCREEN::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) { - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->Type() == SCH_COMPONENT_T ) { @@ -786,7 +714,7 @@ void SCH_SCREEN::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) void SCH_SCREEN::GetHierarchicalItems( EDA_ITEMS& aItems ) { - SCH_ITEM* item = GetDrawItems(); + SCH_ITEM* item = m_drawList.begin(); while( item ) { @@ -869,7 +797,7 @@ void SCH_SCREEN::addConnectedItemsToBlock( const wxPoint& position ) ITEM_PICKER picker; bool addinlist = true; - for( item = GetDrawItems(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item != NULL; item = item->Next() ) { picker.SetItem( item ); @@ -915,7 +843,7 @@ int SCH_SCREEN::UpdatePickList() area.SetSize( m_BlockLocate.GetSize() ); area.Normalize(); - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { // An item is picked if its bounding box intersects the reference area. if( item->HitTest( area ) ) @@ -935,10 +863,10 @@ bool SCH_SCREEN::TestDanglingEnds( EDA_DRAW_PANEL* aCanvas, wxDC* aDC ) std::vector< DANGLING_END_ITEM > endPoints; bool hasDanglingEnds = false; - for( item = GetDrawItems(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item != NULL; item = item->Next() ) item->GetEndPoints( endPoints ); - for( item = GetDrawItems(); item; item = item->Next() ) + for( item = m_drawList.begin(); item; item = item->Next() ) { if( item->IsDanglingStateChanged( endPoints ) && ( aCanvas != NULL ) && ( aDC != NULL ) ) { @@ -960,7 +888,7 @@ bool SCH_SCREEN::BreakSegment( const wxPoint& aPoint ) SCH_LINE* newSegment; bool brokenSegments = false; - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( (item->Type() != SCH_LINE_T) || (item->GetLayer() == LAYER_NOTES) ) continue; @@ -974,8 +902,7 @@ bool SCH_SCREEN::BreakSegment( const wxPoint& aPoint ) newSegment = new SCH_LINE( *segment ); newSegment->SetStartPoint( aPoint ); segment->SetEndPoint( aPoint ); - newSegment->SetNext( segment->Next() ); - segment->SetNext( newSegment ); + m_drawList.Insert( newSegment, segment->Next() ); item = newSegment; brokenSegments = true; } @@ -988,7 +915,7 @@ bool SCH_SCREEN::BreakSegmentsOnJunctions() { bool brokenSegments = false; - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->Type() == SCH_JUNCTION_T ) { @@ -1013,7 +940,7 @@ bool SCH_SCREEN::BreakSegmentsOnJunctions() int SCH_SCREEN::GetNode( const wxPoint& aPosition, EDA_ITEMS& aList ) { - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->Type() == SCH_LINE_T && item->HitTest( aPosition ) && (item->GetLayer() == LAYER_BUS || item->GetLayer() == LAYER_WIRE) ) @@ -1032,7 +959,7 @@ int SCH_SCREEN::GetNode( const wxPoint& aPosition, EDA_ITEMS& aList ) SCH_LINE* SCH_SCREEN::GetWireOrBus( const wxPoint& aPosition ) { - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( (item->Type() == SCH_LINE_T) && item->HitTest( aPosition ) && (item->GetLayer() == LAYER_BUS || item->GetLayer() == LAYER_WIRE) ) @@ -1048,7 +975,7 @@ SCH_LINE* SCH_SCREEN::GetWireOrBus( const wxPoint& aPosition ) SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer, SCH_LINE_TEST_T aSearchType ) { - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->Type() != SCH_LINE_T ) continue; @@ -1081,7 +1008,7 @@ SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLay SCH_TEXT* SCH_SCREEN::GetLabel( const wxPoint& aPosition, int aAccuracy ) { - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { switch( item->Type() ) { @@ -1106,7 +1033,7 @@ bool SCH_SCREEN::SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxStri SCH_COMPONENT* component; bool found = false; - for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->Type() != SCH_COMPONENT_T ) continue; @@ -1179,7 +1106,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis { SCH_LINE* segment; - for( item = GetDrawItems(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( !(item->GetFlags() & SELECTEDNODE) ) continue; @@ -1191,7 +1118,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis } // Search all attached wires (i.e wire with one new dangling end ) - for( item = GetDrawItems(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item != NULL; item = item->Next() ) { bool noconnect = false; @@ -1210,7 +1137,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis /* If the wire start point is connected to a wire that was already found * and now is not connected, add the wire to the list. */ - for( tmp = GetDrawItems(); tmp != NULL; tmp = tmp->Next() ) + for( tmp = m_drawList.begin(); tmp != NULL; tmp = tmp->Next() ) { // Ensure tmp is a previously deleted segment: if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 ) @@ -1234,7 +1161,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis /* If the wire end point is connected to a wire that has already been found * and now is not connected, add the wire to the list. */ - for( tmp = GetDrawItems(); tmp != NULL; tmp = tmp->Next() ) + for( tmp = m_drawList.begin(); tmp != NULL; tmp = tmp->Next() ) { // Ensure tmp is a previously deleted segment: if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 ) @@ -1265,13 +1192,13 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis ITEM_PICKER picker( item, UR_DELETED ); aList.PushItem( picker ); - item = GetDrawItems(); + item = m_drawList.begin(); } } // Get redundant junctions (junctions which connect < 3 end wires // and no pin) - for( item = GetDrawItems(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->GetFlags() & STRUCT_DELETED ) continue; @@ -1293,7 +1220,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis } } - for( item = GetDrawItems(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item != NULL; item = item->Next() ) { if( item->GetFlags() & STRUCT_DELETED ) continue; @@ -1560,7 +1487,7 @@ void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const // for now, make it look like XML, expand on this later. NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n"; - for( EDA_ITEM* item = m_drawList; item; item = item->Next() ) + for( EDA_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) { item->Show( nestLevel+1, os ); } diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp index 79a732a225..2dcaa4ea70 100644 --- a/eeschema/sch_sheet.cpp +++ b/eeschema/sch_sheet.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 Kicad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_sheet.h b/eeschema/sch_sheet.h index 53c861b996..7159641347 100644 --- a/eeschema/sch_sheet.h +++ b/eeschema/sch_sheet.h @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_sheet_pin.cpp b/eeschema/sch_sheet_pin.cpp index b2231ed893..470516b6dc 100644 --- a/eeschema/sch_sheet_pin.cpp +++ b/eeschema/sch_sheet_pin.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2006 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_text.cpp b/eeschema/sch_text.cpp index 13747dcab0..9a886d74fa 100644 --- a/eeschema/sch_text.cpp +++ b/eeschema/sch_text.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/sch_text.h b/eeschema/sch_text.h index a25c4b09ec..7bce16f1e7 100644 --- a/eeschema/sch_text.h +++ b/eeschema/sch_text.h @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp index a549a3a673..3f44b9ef34 100644 --- a/eeschema/schedit.cpp +++ b/eeschema/schedit.cpp @@ -178,12 +178,27 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_POPUP_SCH_BREAK_WIRE: { + DLIST< SCH_ITEM > oldWires; + + oldWires.SetOwnership( false ); // Prevent DLIST for deleting items in destructor. m_canvas->MoveCursorToCrossHair(); - SCH_ITEM* oldWiresList = screen->ExtractWires( true ); + screen->ExtractWires( oldWires, true ); screen->BreakSegment( screen->GetCrossHairPosition() ); - if( oldWiresList ) - SaveCopyInUndoList( oldWiresList, UR_WIRE_IMAGE ); + if( oldWires.GetCount() != 0 ) + { + PICKED_ITEMS_LIST oldItems; + + oldItems.m_Status = UR_WIRE_IMAGE; + + while( oldWires.GetCount() != 0 ) + { + ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE ); + oldItems.PushItem( picker ); + } + + SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE ); + } screen->TestDanglingEnds( m_canvas, &dc ); } diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp index 18351647c3..28936e3376 100644 --- a/eeschema/schematic_undo_redo.cpp +++ b/eeschema/schematic_undo_redo.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -112,13 +111,11 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem, UNDO_REDO_T aCommandType, const wxPoint& aTransformPoint ) { - /* Does not save a null item. - * but if aCommandType == UR_WIRE_IMAGE, we must save null item. - * It happens for the first wire entered in schematic: - * To undo this first command, the previous state is a NULL item, - * and we accept this + /* Does not save a null item or a UR_WIRE_IMAGE command type. UR_WIRE_IMAGE commands + * are handled by the overloaded version of SaveCopyInUndoList that takes a reference + * to a PICKED_ITEMS_LIST. */ - if( aItem == NULL && ( aCommandType != UR_WIRE_IMAGE ) ) + if( aItem == NULL || aCommandType == UR_WIRE_IMAGE ) return; PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST(); @@ -137,7 +134,6 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem, break; case UR_NEW: - case UR_WIRE_IMAGE: case UR_DELETED: case UR_ROTATED: case UR_MOVED: @@ -145,13 +141,9 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem, break; default: - { - wxString msg; - msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), - aCommandType ); - wxMessageBox( msg ); - } - break; + wxFAIL_MSG( wxString::Format( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), + aCommandType ) ); + break; } if( commandToUndo->GetCount() ) @@ -163,7 +155,9 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem, GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); } else + { delete commandToUndo; + } } @@ -174,6 +168,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST(); commandToUndo->m_TransformPoint = aTransformPoint; + commandToUndo->m_Status = aTypeCommand; // Copy picker list: commandToUndo->CopyList( aItemsList ); @@ -202,6 +197,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, */ if( commandToUndo->GetPickedItemLink( ii ) == NULL ) commandToUndo->SetPickedItemLink( DuplicateStruct( item, true ), ii ); + wxASSERT( commandToUndo->GetPickedItemLink( ii ) ); break; @@ -212,6 +208,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, case UR_NEW: case UR_DELETED: case UR_EXCHANGE_T: + case UR_WIRE_IMAGE: break; default: @@ -220,7 +217,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, } } - if( commandToUndo->GetCount() ) + if( commandToUndo->GetCount() || aTypeCommand == UR_WIRE_IMAGE ) { /* Save the copy in undo list */ GetScreen()->PushCommandToUndoList( commandToUndo ); @@ -229,7 +226,9 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); } else // Should not occur + { delete commandToUndo; + } } @@ -238,9 +237,36 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed SCH_ITEM* item; SCH_ITEM* alt_item; - // 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 + // Exchange the current wires, buses, and junctions with the copy save by the last edit. + if( aList->m_Status == UR_WIRE_IMAGE ) + { + DLIST< SCH_ITEM > oldWires; + + // Prevent items from being deleted when the DLIST goes out of scope. + oldWires.SetOwnership( false ); + + // Remove all of the wires, buses, and junctions from the current screen. + GetScreen()->ExtractWires( oldWires, false ); + + // Copy the saved wires, buses, and junctions to the current screen. + for( unsigned int i = 0; i < aList->GetCount(); i++ ) + GetScreen()->Append( (SCH_ITEM*) aList->GetPickedItem( i ) ); + + aList->ClearItemsList(); + + // Copy the previous wires, buses, and junctions to the picked item list for the + // redo operation. + while( oldWires.GetCount() != 0 ) + { + ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE ); + aList->PushItem( picker ); + } + + return; + } + + // 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. for( int ii = aList->GetCount() - 1; ii >= 0; ii-- ) { item = (SCH_ITEM*) aList->GetPickedItem( ii ); @@ -253,18 +279,21 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed switch( aList->GetPickedItemStatus( ii ) ) { case UR_CHANGED: /* Exchange old and new data for each item */ + // tmp = item->Clone(); + // *item = *image; + // *image = *tmp; + // delete tmp; item->SwapData( image ); break; case UR_NEW: /* new items are deleted */ aList->SetPickedItemStatus( UR_DELETED, ii ); - GetScreen()->RemoveFromDrawList( item ); + GetScreen()->Remove( item ); break; - case UR_DELETED: /* deleted items are put in EEdrawList, as new items */ + case UR_DELETED: /* deleted items are put in the draw item list, as new items */ aList->SetPickedItemStatus( UR_NEW, ii ); - item->SetNext( GetScreen()->GetDrawItems() ); - GetScreen()->SetDrawItems( item ); + GetScreen()->Append( item ); break; case UR_MOVED: @@ -275,55 +304,32 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed break; case UR_MIRRORED_Y: - { - wxPoint mirrorPoint = aList->m_TransformPoint; - item->Mirror_Y( mirrorPoint.x ); - } - break; + item->Mirror_Y( aList->m_TransformPoint.x ); + break; case UR_MIRRORED_X: - { - wxPoint mirrorPoint = aList->m_TransformPoint; - item->Mirror_X( mirrorPoint.y ); - } - break; + item->Mirror_X( aList->m_TransformPoint.y ); + break; case UR_ROTATED: - { // To undo a rotate 90 deg transform we must rotate 270 deg to undo // and 90 deg to redo: - wxPoint RotationPoint = aList->m_TransformPoint; - item->Rotate( RotationPoint ); + item->Rotate( aList->m_TransformPoint ); + if( aRedoCommand ) break; // A only one rotate transform is OK + // Make 3 rotate 90 deg transforms is this is actually an undo command - item->Rotate( RotationPoint ); - item->Rotate( RotationPoint ); - } - break; - - case UR_WIRE_IMAGE: - /* Exchange the current wires and the old wires */ - alt_item = GetScreen()->ExtractWires( false ); - aList->SetPickedItem( alt_item, ii ); - - while( item ) - { - SCH_ITEM* nextitem = item->Next(); - item->SetNext( GetScreen()->GetDrawItems() ); - GetScreen()->SetDrawItems( item ); - item->ClearFlags(); - item = nextitem; - } - + item->Rotate( aList->m_TransformPoint ); + item->Rotate( aList->m_TransformPoint ); break; case UR_EXCHANGE_T: alt_item = (SCH_ITEM*) aList->GetPickedItemLink( ii ); alt_item->SetNext( NULL ); alt_item->SetBack( NULL ); - GetScreen()->RemoveFromDrawList( item ); - GetScreen()->AddToDrawList( alt_item ); + GetScreen()->Remove( item ); + GetScreen()->Append( alt_item ); aList->SetPickedItem( alt_item, ii ); aList->SetPickedItemLink( item, ii ); break; diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index e0efa4fd90..6022d6d391 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -930,7 +929,7 @@ void SCH_EDIT_FRAME::addCurrentItemToList( wxDC* aDC ) if( undoItem == item ) { if( !screen->CheckIfOnDrawList( item ) ) // don't want a loop! - screen->AddToDrawList( item ); + screen->Append( item ); SetRepeatItem( item ); diff --git a/eeschema/sheet.cpp b/eeschema/sheet.cpp index 78a06d69cd..669060cb8c 100644 --- a/eeschema/sheet.cpp +++ b/eeschema/sheet.cpp @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2006 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2009-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -282,14 +281,14 @@ static void ExitSheet( EDA_DRAW_PANEL* aPanel, wxDC* aDC ) } else if( item->IsMoving() || item->IsResized() ) { - screen->RemoveFromDrawList( item ); + screen->Remove( item ); delete item; item = parent->GetUndoItem(); wxCHECK_RET( item != NULL, wxT( "Cannot restore undefined last sheet item." ) ); - screen->AddToDrawList( item ); + screen->Append( item ); // the owner of item is no more parent, this is the draw list of screen: parent->SetUndoItem( NULL ); diff --git a/include/class_sch_screen.h b/include/class_sch_screen.h index 94e8b97a8e..d50c3243df 100644 --- a/include/class_sch_screen.h +++ b/include/class_sch_screen.h @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -32,6 +31,7 @@ #define CLASS_SCREEN_H #include +#include #include #include #include @@ -73,8 +73,8 @@ class SCH_SCREEN : public BASE_SCREEN /// Position of the origin axis, which is used in exports mostly, but not yet in EESCHEMA wxPoint m_originAxisPosition; - SCH_ITEM* m_drawList; ///< Object list for the screen. - /// @todo use DLIST or superior container + DLIST< SCH_ITEM > m_drawList; ///< Object list for the screen. + /// @todo use DLIST or superior container /** * Function addConnectedItemsToBlock @@ -122,8 +122,17 @@ public: * Function GetDrawItems(). * @return - A pointer to the first item in the linked list of draw items. */ - SCH_ITEM* GetDrawItems() const { return m_drawList; } - void SetDrawItems( SCH_ITEM* aItem ) { m_drawList = aItem; } + SCH_ITEM* GetDrawItems() const { return m_drawList.begin(); } + + void Append( SCH_ITEM* aItem ) { m_drawList.Append( aItem ); } + + /** + * Function Append + * adds \a aList of SCH_ITEM objects to the list for draw items for the sheet. + * + * @param aList A reference to a #DLIST containing the #SCH_ITEM to add to the sheet. + */ + void Append( DLIST< SCH_ITEM >& aList ) { m_drawList.Append( aList ); } /** * Function GetCurItem @@ -184,11 +193,13 @@ public: void Plot( PLOTTER* aPlotter ); /** - * Remove \a aItem from the schematic associated with this screen. + * Function Remove + * removes \a aItem from the schematic associated with this screen. * - * @param aItem - Item to be removed from schematic. + * @note The removed item is not deleted. It is only unlinked from the item list. + * @param aItem Item to be removed from schematic. */ - void RemoveFromDrawList( SCH_ITEM* aItem ); + void Remove( SCH_ITEM* aItem ); /** * Function DeleteItem @@ -201,8 +212,6 @@ public: bool CheckIfOnDrawList( SCH_ITEM* st ); - void AddToDrawList( SCH_ITEM* st ); - /** * Function SchematicCleanUp * performs routine schematic cleaning including breaking wire and buses and @@ -226,23 +235,24 @@ public: /** * Function ExtractWires * extracts the old wires, junctions and buses. If \a aCreateCopy is true, replace - * them with a copy. Old item must be put in undo list, and the new ones can be - * modified by clean up safely. If an abort command is made, old wires must be put - * in GetDrawItems(), and copies must be deleted. This is because previously stored - * undo commands can handle pointers on wires or buses, and we do not delete wires or - * buss-es, we must put they in undo list. + * extracted items with a copy of the original. Old items are to be put in undo list, + * and the new ones can be modified by clean up safely. If an abort draw segmat command + * is made, the old wires must be put back into #m_drawList, and the copies must be + * deleted. This is because previously stored undo commands can handle pointers on wires + * or buses, and we do not delete wires or buses, we must put them in undo list. * - * Because cleanup delete and/or modify bus and wires, the it is easier is to put - * all wires in undo list and use a new copy of wires for cleanup. + * Because cleanup deletes and/or modify bus and wires, it is easier is to put + * all the existing wires in undo list and use a new copy of wires for cleanup. */ - SCH_ITEM* ExtractWires( bool aCreateCopy ); + void ExtractWires( DLIST< SCH_ITEM >& aList, bool aCreateCopy ); /** * Function ReplaceWires - * replaces all of the wires and junction in the screen with \a aWireList. - * @param aWireList List of wire to replace the existing wires with. + * replaces all of the wires, buses, and junctions in the screen with \a aWireList. + * + * @param aWireList List of wires to replace the existing wires with. */ - void ReplaceWires( SCH_ITEM* aWireList ); + void ReplaceWires( DLIST< SCH_ITEM >& aWireList ); /** * Function MarkConnections diff --git a/include/dlist.h b/include/dlist.h index fcdb8f37af..2acf80271c 100644 --- a/include/dlist.h +++ b/include/dlist.h @@ -63,22 +63,31 @@ protected: /** * Function append * adds \a aNewElement to the end of the list. + * @param aNewElement The element to insert. */ void append( EDA_ITEM* aNewElement ); + /** + * Function append + * adds \a aList to the end of the list. + * @param aList The list to aList. + */ + void append( DHEAD& aList ); + /** * Function insert - * puts aNewElement just in front of aElementAfterMe in the list sequence. - * If aElementAfterMe is NULL, then simply append(). + * puts \a aNewElement just in front of \a aElementAfterMe in the list sequence. + * If \a aElementAfterMe is NULL, then simply append(). * @param aNewElement The element to insert. * @param aElementAfterMe The element to insert \a aNewElement before, - * if NULL then append aNewElement onto end of list. + * if NULL then append \a aNewElement onto end of list. */ void insert( EDA_ITEM* aNewElement, EDA_ITEM* aElementAfterMe ); /** * Function insert - * puts aNewElement in front of list sequence. + * puts \a aNewElement in front of list sequence. + * @param aNewElement The element to insert. */ void insert( EDA_ITEM* aNewElement ) { @@ -88,6 +97,7 @@ protected: /** * Function remove * removes \a aElement from the list, but does not delete it. + * @param aElement The element to remove. */ void remove( EDA_ITEM* aElement ); @@ -162,16 +172,30 @@ public: /** * Function Append * adds \a aNewElement to the end of the list. + * @param aNewElement The element to insert. */ void Append( T* aNewElement ) { append( aNewElement ); } + /** + * Function Append + * adds \a aList to the end of the list. + * @param aList The list to append to the end of the list. + */ + void Append( DLIST& aList ) + { + append( aList ); + } + /** * Function Insert - * puts aNewElement just in front of aElementAfterMe in the list sequence. + * puts \a aNewElement just in front of \a aElementAfterMe in the list sequence. * If aElementAfterMe is NULL, then simply Append() + * @param aNewElement The element to insert. + * @param aElementAfterMe The element to insert \a aNewElement before, + * if NULL then append \a aNewElement onto end of list. */ void Insert( T* aNewElement, T* aElementAfterMe ) { @@ -181,6 +205,7 @@ public: /** * Function Remove * removes \a aElement from the list, but does not delete it. + * @param aElement The element to remove from the list. * @return T* - the removed element, so you can easily delete it upon return. */ T* Remove( T* aElement ) @@ -210,6 +235,7 @@ public: /** * Function PushFront * puts aNewElement at front of list sequence. + * @param aNewElement The element to insert at the front of the list. */ void PushFront( T* aNewElement ) { @@ -219,6 +245,7 @@ public: /** * Function PushBack * puts aNewElement at the end of the list sequence. + * @param aNewElement The element to push to the end of the list. */ void PushBack( T* aNewElement ) { diff --git a/include/sch_item_struct.h b/include/sch_item_struct.h index a794824aea..e412f0c39a 100644 --- a/include/sch_item_struct.h +++ b/include/sch_item_struct.h @@ -2,7 +2,6 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -352,8 +351,6 @@ public: virtual bool operator <( const SCH_ITEM& aItem ) const; - virtual SCH_ITEM& operator=( const SCH_ITEM& aItem ); - /** * @note - The DoXXX() functions below are used to enforce the interface while retaining * the ability of change the implementation behavior of derived classes. See