|
|
/************************************//* delete.cpp *//************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "program.h"
#include "general.h"
#include "protos.h"
#include "class_marker_sch.h"
// Imported function:
void DeleteItemsInList( WinEDA_DrawPanel* panel, PICKED_ITEMS_LIST& aItemsList );
/*
* Count number of items connected to point pos : * pins, end wire or bus, and junctions if TstJunction == TRUE * Return this count * * Used by WinEDA_SchematicFrame::DeleteConnection() */static int CountConnectedItems( WinEDA_SchematicFrame* frame, SCH_ITEM* ListStruct, wxPoint pos, bool TstJunction ){ SCH_ITEM* Struct; int count = 0;
if( frame->LocatePinEnd( ListStruct, pos ) ) count++;
for( Struct = ListStruct; Struct != NULL; Struct = Struct->Next() ) { if( Struct->m_Flags & STRUCT_DELETED ) continue; if( Struct->m_Flags & SKIP_STRUCT ) continue;
if( TstJunction && ( Struct->Type() == DRAW_JUNCTION_STRUCT_TYPE ) ) { #define JUNCTION ( (SCH_JUNCTION*) Struct )
if( JUNCTION->m_Pos == pos ) count++; #undef JUNCTION
}
if( Struct->Type() != DRAW_SEGMENT_STRUCT_TYPE ) continue;
#define SEGM ( (SCH_LINE*) Struct )
if( SEGM->IsOneEndPointAt( pos ) ) count++; #undef SEGM
}
return count;}
/*
* Mark to "CANDIDATE" all wires or junction connected to "segment" in list * "ListStruct" * Search wire stop at an any pin * * Used by WinEDA_SchematicFrame::DeleteConnection() */static bool MarkConnected( WinEDA_SchematicFrame* frame, SCH_ITEM* ListStruct, SCH_LINE* segment ){ EDA_BaseStruct* Struct;
for( Struct = ListStruct; Struct != NULL; Struct = Struct->Next() ) { if( Struct->m_Flags ) continue; if( Struct->Type() == DRAW_JUNCTION_STRUCT_TYPE ) { #define JUNCTION ( (SCH_JUNCTION*) Struct )
if( segment->IsOneEndPointAt( JUNCTION->m_Pos ) ) Struct->m_Flags |= CANDIDATE; continue; #undef JUNCTION
}
if( Struct->Type() != DRAW_SEGMENT_STRUCT_TYPE ) continue;
#define SEGM ( (SCH_LINE*) Struct )
if( segment->IsOneEndPointAt( SEGM->m_Start ) ) { if( !frame->LocatePinEnd( ListStruct, SEGM->m_Start ) ) { Struct->m_Flags |= CANDIDATE; MarkConnected( frame, ListStruct, SEGM ); } } if( segment->IsOneEndPointAt( SEGM->m_End ) ) { if( !frame->LocatePinEnd( ListStruct, SEGM->m_End ) ) { Struct->m_Flags |= CANDIDATE; MarkConnected( frame, ListStruct, SEGM ); } } #undef SEGM
}
return TRUE;}
/*
* Delete a connection, i.e wires or bus connected * stop on a node (more than 2 wires (bus) connected) */void WinEDA_SchematicFrame::DeleteConnection( bool DeleteFullConnection ){ wxPoint refpos = GetScreen()->m_Curseur; SCH_ITEM* DelStruct; PICKED_ITEMS_LIST pickList;
/* Clear .m_Flags member for all items */ for( DelStruct = GetScreen()->EEDrawList; DelStruct != NULL; DelStruct = DelStruct->Next() ) DelStruct->m_Flags = 0;
BreakSegmentOnJunction( (SCH_SCREEN*) GetScreen() );
/* Locate all the wires, bus or junction under the mouse cursor, and put
* them in a list of items to delete */ ITEM_PICKER picker(NULL, UR_DELETED); SCH_SCREEN* screen = (SCH_SCREEN*) GetScreen(); // Save the list entry point of this screen
SCH_ITEM* savedEEDrawList = screen->EEDrawList; DelStruct = GetScreen()->EEDrawList; while( DelStruct && ( DelStruct = PickStruct( screen->m_Curseur, screen, JUNCTIONITEM | WIREITEM | BUSITEM ) ) != NULL ) { DelStruct->m_Flags = SELECTEDNODE | STRUCT_DELETED;
/* Put this structure in the picked list: */ picker.m_PickedItem = DelStruct; picker.m_PickedItemType = DelStruct->Type(); pickList.PushItem(picker);
DelStruct = DelStruct->Next(); screen->EEDrawList = DelStruct; }
GetScreen()->EEDrawList = savedEEDrawList;
/* Mark all wires, junctions, .. connected to one of the item to delete
*/ if( DeleteFullConnection ) { for( DelStruct = GetScreen()->EEDrawList; DelStruct != NULL; DelStruct = DelStruct->Next() ) { if( !(DelStruct->m_Flags & SELECTEDNODE) ) continue;
#define SEGM ( (SCH_LINE*) DelStruct )
if( DelStruct->Type() != DRAW_SEGMENT_STRUCT_TYPE ) continue;
MarkConnected( this, GetScreen()->EEDrawList, SEGM ); #undef SEGM
}
// Search all removable wires (i.e wire with one new dangling end )
for( DelStruct = GetScreen()->EEDrawList; DelStruct != NULL; DelStruct = DelStruct->Next() ) { bool noconnect = FALSE;
if( DelStruct->m_Flags & STRUCT_DELETED ) continue; // Already seen
if( !(DelStruct->m_Flags & CANDIDATE) ) continue; // Already seen
if( DelStruct->Type() != DRAW_SEGMENT_STRUCT_TYPE ) continue;
DelStruct->m_Flags |= SKIP_STRUCT; #define SEGM ( (SCH_LINE*) DelStruct )
/* Test the SEGM->m_Start point: if this point was connected to
* an STRUCT_DELETED wire, and now is not connected, the wire can * be deleted */ EDA_BaseStruct* removed_struct; for( removed_struct = GetScreen()->EEDrawList; removed_struct != NULL; removed_struct = removed_struct->Next() ) { if( ( removed_struct->m_Flags & STRUCT_DELETED ) == 0 ) continue;
if( removed_struct->Type() != DRAW_SEGMENT_STRUCT_TYPE ) continue;
#define WIRE ( (SCH_LINE*) removed_struct )
if( WIRE->IsOneEndPointAt( SEGM->m_Start ) ) break; }
if( WIRE && !CountConnectedItems( this, GetScreen()->EEDrawList, SEGM->m_Start, TRUE ) ) noconnect = TRUE;
/* Test the SEGM->m_End point: if this point was connected to
* an STRUCT_DELETED wire, and now is not connected, the wire * can be deleted */ for( removed_struct = GetScreen()->EEDrawList; removed_struct != NULL; removed_struct = removed_struct->Next() ) { if( ( removed_struct->m_Flags & STRUCT_DELETED ) == 0 ) continue; if( removed_struct->Type() != DRAW_SEGMENT_STRUCT_TYPE ) continue; if( WIRE->IsOneEndPointAt( SEGM->m_End ) ) break; }
if( removed_struct && !CountConnectedItems( this, GetScreen()->EEDrawList, SEGM->m_End, TRUE ) ) noconnect = TRUE;
DelStruct->m_Flags &= ~SKIP_STRUCT;
if( noconnect ) { DelStruct->m_Flags |= STRUCT_DELETED; /* Put this structure in the picked list: */ picker.m_PickedItem = DelStruct; picker.m_PickedItemType = DelStruct->Type(); pickList.PushItem(picker);
DelStruct = GetScreen()->EEDrawList; } #undef SEGM
}
// Delete redundant junctions (junctions which connect < 3 end wires
// and no pin are removed)
for( DelStruct = GetScreen()->EEDrawList; DelStruct != NULL; DelStruct = DelStruct->Next() ) { int count; if( DelStruct->m_Flags & STRUCT_DELETED ) continue;
if( !(DelStruct->m_Flags & CANDIDATE) ) continue;
if( DelStruct->Type() == DRAW_JUNCTION_STRUCT_TYPE ) { #define JUNCTION ( (SCH_JUNCTION*) DelStruct )
count = CountConnectedItems( this, GetScreen()->EEDrawList, JUNCTION->m_Pos, FALSE ); if( count <= 2 ) { DelStruct->m_Flags |= STRUCT_DELETED;
/* Put this structure in the picked list: */ picker.m_PickedItem = DelStruct; picker.m_PickedItemType = DelStruct->Type(); pickList.PushItem(picker); } #undef JUNCTION
} }
// Delete labels attached to wires
wxPoint pos = GetScreen()->m_Curseur; for( DelStruct = GetScreen()->EEDrawList; DelStruct != NULL; DelStruct = DelStruct->Next() ) { if( DelStruct->m_Flags & STRUCT_DELETED ) continue;
if( DelStruct->Type() != TYPE_SCH_LABEL ) continue;
GetScreen()->m_Curseur = ( (SCH_TEXT*) DelStruct )->m_Pos; EDA_BaseStruct* TstStruct = PickStruct( GetScreen()->m_Curseur, GetScreen(), WIREITEM | BUSITEM );
if( TstStruct && TstStruct->m_Flags & STRUCT_DELETED ) { DelStruct->m_Flags |= STRUCT_DELETED;
/* Put this structure in the picked list: */ picker.m_PickedItem = DelStruct; picker.m_PickedItemType = DelStruct->Type(); pickList.PushItem(picker); } }
GetScreen()->m_Curseur = pos; }
for( DelStruct = GetScreen()->EEDrawList; DelStruct != NULL; DelStruct = DelStruct->Next() ) DelStruct->m_Flags = 0;
if( pickList.GetCount() ) { DeleteItemsInList( DrawPanel, pickList ); GetScreen()->SetModify(); }}
/*
* Locate and delete the item found under the mouse cursor * If more than one item found: the priority order is: * 1 : MARKER * 2 : JUNCTION * 2 : NOCONNECT * 3 : WIRE or BUS * 4 : DRAWITEM * 5 : TEXT * 6 : COMPOSANT * 7 : SHEET * * return TRUE if an item was deleted */bool LocateAndDeleteItem( WinEDA_SchematicFrame* frame, wxDC* DC ){ SCH_ITEM* DelStruct; SCH_SCREEN* screen = (SCH_SCREEN*) ( frame->GetScreen() ); bool item_deleted = FALSE;
DelStruct = PickStruct( screen->m_Curseur, screen, MARKERITEM ); if( DelStruct == NULL ) DelStruct = PickStruct( screen->m_Curseur, screen, JUNCTIONITEM ); if( DelStruct == NULL ) DelStruct = PickStruct( screen->m_Curseur, screen, NOCONNECTITEM ); if( DelStruct == NULL ) DelStruct = PickStruct( screen->m_Curseur, screen, RACCORDITEM ); if( DelStruct == NULL ) DelStruct = PickStruct( screen->m_Curseur, screen, WIREITEM | BUSITEM ); if( DelStruct == NULL ) DelStruct = PickStruct( screen->m_Curseur, screen, DRAWITEM ); if( DelStruct == NULL ) DelStruct = PickStruct( screen->m_Curseur, screen, TEXTITEM | LABELITEM ); if( DelStruct == NULL ) DelStruct = PickStruct( screen->m_Curseur, screen, LIBITEM ); if( DelStruct == NULL ) DelStruct = PickStruct( screen->m_Curseur, screen, SHEETITEM );
if( DelStruct ) { g_ItemToRepeat = NULL; DeleteStruct( frame->DrawPanel, DC, DelStruct ); frame->TestDanglingEnds( frame->GetScreen()->EEDrawList, DC ); frame->GetScreen()->SetModify(); item_deleted = TRUE; }
return item_deleted;}
/*
* Remove definition of a structure in a linked list * Elements of Drawing * DrawStruct * = pointer to the structure * Screen = pointer on the screen of belonging * * Note: * DRAW_SHEET_STRUCT_TYPE structures for the screen and structures * Corresponding keys are not. * They must be treated separately */void EraseStruct( SCH_ITEM* DrawStruct, SCH_SCREEN* Screen ){ EDA_BaseStruct* DrawList; SCH_SHEET_PIN* SheetLabel, * NextLabel;
if( DrawStruct == NULL ) return;
if( Screen == NULL ) return;
Screen->SetModify();
if( DrawStruct->Type() == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE ) { //this structure is attached to a sheet , which we must find.
DrawList = Screen->EEDrawList; for( ; DrawList != NULL; DrawList = DrawList->Next() ) { if( DrawList->Type() != DRAW_SHEET_STRUCT_TYPE ) continue;
/* See if our item is in this Sheet */ SheetLabel = ( (SCH_SHEET*) DrawList )->m_Label; if( SheetLabel == NULL ) continue;
if( SheetLabel == (SCH_SHEET_PIN*) DrawStruct ) { ( (SCH_SHEET*) DrawList )->m_Label = (SCH_SHEET_PIN*) SheetLabel->Next();
SAFE_DELETE( DrawStruct ); return; } else { while( SheetLabel->Next() ) { NextLabel = (SCH_SHEET_PIN*) SheetLabel->Next();
if( NextLabel == (SCH_SHEET_PIN*) DrawStruct ) { SheetLabel->SetNext( (EDA_BaseStruct*) NextLabel->Next() ); SAFE_DELETE( DrawStruct ); return;
} SheetLabel = NextLabel; } } }
return; } else { if( DrawStruct == Screen->EEDrawList ) { Screen->EEDrawList = DrawStruct->Next(); SAFE_DELETE( DrawStruct ); } else { DrawList = Screen->EEDrawList; while( DrawList && DrawList->Next() ) { if( DrawList->Next() == DrawStruct ) { DrawList->SetNext( DrawStruct->Next() ); SAFE_DELETE( DrawStruct ); return; } DrawList = DrawList->Next(); } } }}
void DeleteAllMarkers( int type ){ SCH_SCREEN* screen; SCH_ITEM * DrawStruct, * NextStruct; SCH_MARKER* Marker;
EDA_ScreenList ScreenList;
for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() ) { for( DrawStruct = screen->EEDrawList; DrawStruct != NULL; DrawStruct = NextStruct ) { NextStruct = DrawStruct->Next(); if( DrawStruct->Type() != TYPE_SCH_MARKER ) continue;
Marker = (SCH_MARKER*) DrawStruct; if( Marker->GetMarkerType() != type ) continue;
/* Remove marker */ EraseStruct( DrawStruct, screen ); } }}
|