kicad/eeschema/block.cpp

1594 lines
47 KiB
C++
Raw Normal View History

2007-05-06 16:03:28 +00:00
/****************************************************/
/* BLOCK.CPP */
/* Gestion des Operations sur Blocks et Effacements */
/****************************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "program.h"
#include "libcmp.h"
#include "general.h"
#include "protos.h"
/* Variables Locales */
/* Fonctions exportees */
/* Fonctions Locales */
static EDA_BaseStruct * CopyStruct(WinEDA_DrawPanel * panel, wxDC * DC, BASE_SCREEN * screen,
EDA_BaseStruct *DrawStruct);
static void CollectStructsToDrag(SCH_SCREEN * screen);
static void AddPickedItem(SCH_SCREEN * screen, int px, int py );
static LibEDA_BaseStruct * GetNextPinPosition( EDA_SchComponentStruct * DrawLibItem,
int * px, int * py );
static void DrawMovingBlockOutlines(WinEDA_DrawPanel * panel, wxDC * DC, bool erase);
static EDA_BaseStruct * SaveStructListForPaste(EDA_BaseStruct *DrawStruct);
static bool MirrorStruct(WinEDA_DrawPanel * panel, wxDC * DC, EDA_BaseStruct *DrawStruct, wxPoint & Center);
static void MirrorOneStruct(EDA_BaseStruct *DrawStruct, wxPoint & Center);
/*************************************************************************/
int WinEDA_SchematicFrame::ReturnBlockCommand(int key)
/*************************************************************************/
/* Return the block command (BLOCK_MOVE, BLOCK_COPY...) corresponding to
the key (ALT, SHIFT ALT ..)
*/
{
int cmd;
switch ( key )
{
default:
cmd = key & 0xFF;
break;
case 0:
cmd = BLOCK_MOVE;
break;
case GR_KB_ALT:
case GR_KB_SHIFT:
cmd = BLOCK_COPY;
break;
case GR_KB_CTRL:
cmd = BLOCK_DRAG;
break;
case GR_KB_SHIFTCTRL:
cmd = BLOCK_DELETE;
break;
case MOUSE_MIDDLE:
cmd = BLOCK_ZOOM;
break;
}
return cmd;
}
/*************************************************/
void WinEDA_SchematicFrame::InitBlockPasteInfos()
/*************************************************/
/* Init the parameters used by the block paste command
*/
{
DrawBlockStruct * block = & GetScreen()->BlockLocate;
block->m_BlockDrawStruct = g_BlockSaveDataList;
DrawPanel->ManageCurseur = DrawMovingBlockOutlines;
}
/******************************************************/
void WinEDA_SchematicFrame::HandleBlockPlace(wxDC * DC)
/******************************************************/
/* Routine to handle the BLOCK PLACE commande
Last routine for block operation for:
- block move & drag
- block copie & paste
*/
{
bool err = FALSE;
DrawBlockStruct * block = & GetScreen()->BlockLocate;
EDA_BaseStruct * NewStruct = NULL;
if(DrawPanel->ManageCurseur == NULL)
{
err = TRUE;
DisplayError(this, wxT("HandleBlockPLace() : ManageCurseur = NULL") );
}
if(block->m_BlockDrawStruct == NULL)
{
wxString msg;
err = TRUE;
msg.Printf( wxT("HandleBlockPLace() : m_BlockDrawStruct = NULL (cmd %d, state %d)"),
block->m_Command, block->m_State);
DisplayError(this, msg );
}
block->m_State = STATE_BLOCK_STOP;
switch(block->m_Command )
{
case BLOCK_IDLE:
err = TRUE;
break;
case BLOCK_DRAG: /* Drag */
case BLOCK_MOVE: /* Move */
if ( DrawPanel->ManageCurseur )
DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
SaveCopyInUndoList(block->m_BlockDrawStruct, IS_CHANGED);
MoveStruct(DrawPanel, DC, block->m_BlockDrawStruct);
block->m_BlockDrawStruct = NULL;
break;
case BLOCK_COPY: /* Copy */
case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/
if ( DrawPanel->ManageCurseur )
DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
NewStruct = CopyStruct(DrawPanel, DC, GetScreen(), block->m_BlockDrawStruct);
SaveCopyInUndoList(NewStruct,
(block->m_Command == BLOCK_PRESELECT_MOVE) ? IS_CHANGED : IS_NEW);
block->m_BlockDrawStruct = NULL;
break;
case BLOCK_PASTE: /* Paste (recopie du dernier bloc sauve */
if ( DrawPanel->ManageCurseur )
DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
PasteStruct(DC);
block->m_BlockDrawStruct = NULL;
break;
case BLOCK_ZOOM: // Handled by HandleBlockEnd()
case BLOCK_DELETE:
case BLOCK_SAVE:
case BLOCK_ROTATE:
case BLOCK_MIRROR_X:
case BLOCK_MIRROR_Y:
case BLOCK_INVERT:
case BLOCK_ABORT:
case BLOCK_SELECT_ITEMS_ONLY:
break;
}
GetScreen()->SetModify();
/* clear struct.m_Flags */
EDA_BaseStruct * Struct;
for(Struct = GetScreen()->EEDrawList; Struct != NULL; Struct=Struct->Pnext)
Struct->m_Flags = 0;
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
block->m_Flags = 0;
block->m_State = STATE_NO_BLOCK;
block->m_Command = BLOCK_IDLE;
GetScreen()->m_CurrentItem = NULL;
TestDanglingEnds(GetScreen()->EEDrawList, DC);
if ( block->m_BlockDrawStruct )
{
DisplayError(this, wxT("HandleBlockPLace() error: DrawStruct != Null") );
block->m_BlockDrawStruct = NULL;
}
SetToolID(m_ID_current_state, DrawPanel->m_PanelDefaultCursor, wxEmptyString );
}
/****************************************************/
int WinEDA_SchematicFrame::HandleBlockEnd(wxDC * DC)
/****************************************************/
/* Routine de gestion de la commande BLOCK END
retourne :
0 si aucun composant selectionne
1 sinon
-1 si commande termin<EFBFBD>e et composants trouv<EFBFBD>s (block delete, block save)
*/
{
int ii = 0;
bool zoom_command = FALSE;
DrawBlockStruct * block = & GetScreen()->BlockLocate;
if ( block->m_BlockDrawStruct )
{
BlockState state = block->m_State;
CmdBlockType command = block->m_Command;
if ( DrawPanel->ForceCloseManageCurseur )
DrawPanel->ForceCloseManageCurseur(DrawPanel, DC);
block->m_State = state;
block->m_Command = command;
DrawPanel->ManageCurseur = DrawAndSizingBlockOutlines;
DrawPanel->ForceCloseManageCurseur = AbortBlockCurrentCommand;
GetScreen()->m_Curseur.x = block->GetRight();
GetScreen()->m_Curseur.y = block->GetBottom();
if ( block->m_Command != BLOCK_ABORT )
DrawPanel->MouseToCursorSchema();
}
if(DrawPanel->ManageCurseur != NULL)
switch( block->m_Command )
{
case BLOCK_IDLE:
DisplayError(this, wxT("Error in HandleBlockPLace()") );
break;
case BLOCK_DRAG: /* Drag */
BreakSegmentOnJunction(GetScreen() );
case BLOCK_MOVE: /* Move */
case BLOCK_COPY: /* Copy */
block->m_BlockDrawStruct =
PickStruct(GetScreen()->BlockLocate, GetScreen()->EEDrawList, SEARCHALL);
case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/
if( block->m_BlockDrawStruct != NULL)
{
ii = 1;
CollectStructsToDrag(GetScreen());
DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
DrawPanel->ManageCurseur = DrawMovingBlockOutlines;
DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
block->m_State = STATE_BLOCK_MOVE;
}
else
{
DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
}
break;
case BLOCK_DELETE: /* Delete */
block->m_BlockDrawStruct =
PickStruct(GetScreen()->BlockLocate,
GetScreen()->EEDrawList, SEARCHALL);
DrawAndSizingBlockOutlines(DrawPanel, DC, FALSE);
if( block->m_BlockDrawStruct != NULL)
{
ii = -1;
DeleteStruct(DrawPanel, DC, block->m_BlockDrawStruct);
GetScreen()->SetModify();
}
block->m_BlockDrawStruct = NULL;
TestDanglingEnds(GetScreen()->EEDrawList, DC);
break;
case BLOCK_SAVE: /* Save */
block->m_BlockDrawStruct =
PickStruct(GetScreen()->BlockLocate,
GetScreen()->EEDrawList, SEARCHALL);
DrawAndSizingBlockOutlines(DrawPanel, DC, FALSE);
if( block->m_BlockDrawStruct != NULL)
{
wxPoint oldpos = GetScreen()->m_Curseur;
GetScreen()->m_Curseur = wxPoint(0,0);
EDA_BaseStruct *DrawStructCopy =
SaveStructListForPaste(block->m_BlockDrawStruct);
PlaceStruct( GetScreen(), DrawStructCopy);
GetScreen()->m_Curseur = oldpos;
ii = -1;
}
block->m_BlockDrawStruct = NULL;
break;
case BLOCK_PASTE:
block->m_State = STATE_BLOCK_MOVE;
break;
case BLOCK_INVERT: /* pcbnew only! */
break;
case BLOCK_ROTATE:
case BLOCK_MIRROR_X:
case BLOCK_MIRROR_Y:
break;
case BLOCK_ZOOM: /* Window Zoom */
zoom_command = TRUE;
break;
case BLOCK_SELECT_ITEMS_ONLY: /* Not used */
case BLOCK_ABORT: /* not executed here */
break;
}
if ( block->m_Command == BLOCK_ABORT )
{ /* clear struct.m_Flags */
EDA_BaseStruct * Struct;
for(Struct = GetScreen()->EEDrawList; Struct != NULL; Struct=Struct->Pnext)
Struct->m_Flags = 0;
}
if ( ii <= 0 )
{
block->m_Flags = 0;
block->m_State = STATE_NO_BLOCK;
block->m_Command = BLOCK_IDLE;
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
GetScreen()->m_CurrentItem = NULL;
SetToolID(m_ID_current_state, DrawPanel->m_PanelDefaultCursor, wxEmptyString );
}
if ( zoom_command)
Window_Zoom( GetScreen()->BlockLocate);
return(ii);
}
/***********************************************************************/
void WinEDA_SchematicFrame::HandleBlockEndByPopUp(int Command, wxDC * DC)
/***********************************************************************/
/* Routine de gestion de la commande BLOCK END by PopUp
Appelee apres HandleBlockEnd.
A partir de la commande bloc move, peut executer une commande autre que bloc move.
*/
{
int ii = 0;
DrawBlockStruct * block = & GetScreen()->BlockLocate;
if( block->m_Command != BLOCK_MOVE ) return;
if( Command == BLOCK_MOVE ) return;
block->m_Command = (CmdBlockType) Command;
block->SetMessageBlock(this);
switch( block->m_Command )
{
case BLOCK_COPY: /* move to copy */
block->m_State = STATE_BLOCK_MOVE;
ii = 1;
break;
case BLOCK_DRAG: /* move to Drag */
/* Effacement de la liste des structures de pointage,
qui est devenue erronnee */
if(DrawPanel->ManageCurseur)
DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
if( block->m_BlockDrawStruct )
{
if(block->m_BlockDrawStruct->m_StructType == DRAW_PICK_ITEM_STRUCT_TYPE)
{ /* Delete the picked wrapper if this is a picked list. */
DrawPickedStruct * PickedList;
PickedList = (DrawPickedStruct*)block->m_BlockDrawStruct;
PickedList->DeleteWrapperList();
}
block->m_BlockDrawStruct = NULL;
}
BreakSegmentOnJunction(GetScreen() );
block->m_BlockDrawStruct =
PickStruct(GetScreen()->BlockLocate,
GetScreen()->EEDrawList, SEARCHALL);
if( block->m_BlockDrawStruct != NULL)
{
ii = 1;
CollectStructsToDrag(GetScreen());
if(DrawPanel->ManageCurseur)
DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
block->m_State = STATE_BLOCK_MOVE;
}
break;
case BLOCK_DELETE: /* move to Delete */
if(DrawPanel->ManageCurseur)
DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
if( block->m_BlockDrawStruct != NULL)
{
ii = -1;
DeleteStruct(DrawPanel, DC, block->m_BlockDrawStruct);
GetScreen()->SetModify();
}
TestDanglingEnds(GetScreen()->EEDrawList, DC);
break;
case BLOCK_SAVE: /* Save */
if(DrawPanel->ManageCurseur)
DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
if( block->m_BlockDrawStruct != NULL)
{
wxPoint oldpos = GetScreen()->m_Curseur;
GetScreen()->m_Curseur = wxPoint(0,0);
EDA_BaseStruct *DrawStructCopy =
SaveStructListForPaste(block->m_BlockDrawStruct);
PlaceStruct( GetScreen(), DrawStructCopy);
GetScreen()->m_Curseur = oldpos;
ii = -1;
}
break;
case BLOCK_ZOOM: /* Window Zoom */
DrawPanel->ForceCloseManageCurseur(DrawPanel, DC);
DrawPanel->SetCursor(DrawPanel->m_PanelCursor = DrawPanel->m_PanelDefaultCursor);
Window_Zoom( GetScreen()->BlockLocate);
break;
case BLOCK_ROTATE:
break;
case BLOCK_MIRROR_X:
case BLOCK_MIRROR_Y:
if(DrawPanel->ManageCurseur)
DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
if( block->m_BlockDrawStruct != NULL)
{
SaveCopyInUndoList(block->m_BlockDrawStruct, IS_CHANGED);
ii = -1;
/* Compute the mirror centre and put it on grid */
wxPoint Center = block->Centre();
PutOnGrid(&Center);
MirrorStruct(DrawPanel, DC, block->m_BlockDrawStruct, Center);
GetScreen()->SetModify();
}
TestDanglingEnds(GetScreen()->EEDrawList, DC);
break;
default:
break;
}
if ( ii <= 0 )
{
block->m_BlockDrawStruct = NULL;
block->m_Flags = 0;
block->m_State = STATE_NO_BLOCK;
block->m_Command = BLOCK_IDLE;
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
GetScreen()->m_CurrentItem = NULL;
SetToolID(m_ID_current_state, DrawPanel->m_PanelDefaultCursor, wxEmptyString );
}
}
/************************************************************************/
static void DrawMovingBlockOutlines(WinEDA_DrawPanel * panel, wxDC * DC,
bool erase )
/************************************************************************/
/* Retrace le contour du block de recherche de structures
L'ensemble du block suit le curseur
*/
{
DrawBlockStruct * PtBlock;
DrawPickedStruct *PickedList;
BASE_SCREEN * screen = panel->m_Parent->GetScreen();
PtBlock = &panel->GetScreen()->BlockLocate;
GRSetDrawMode(DC, g_XorMode);
/* Effacement ancien cadre */
if( erase && PtBlock->m_BlockDrawStruct)
{
PtBlock->Offset(PtBlock->m_MoveVector);
PtBlock->Draw(panel, DC);
PtBlock->Offset( -PtBlock->m_MoveVector.x, -PtBlock->m_MoveVector.y);
/* Effacement ancien affichage */
if(PtBlock->m_BlockDrawStruct->m_StructType == DRAW_PICK_ITEM_STRUCT_TYPE)
{
PickedList = (DrawPickedStruct *) PtBlock->m_BlockDrawStruct;
while (PickedList)
{
DrawStructsInGhost(panel, DC, PickedList->m_PickedStruct, PtBlock->m_MoveVector.x, PtBlock->m_MoveVector.y);
PickedList = (DrawPickedStruct *)PickedList->Pnext;
}
}
else DrawStructsInGhost(panel, DC, PtBlock->m_BlockDrawStruct, PtBlock->m_MoveVector.x, PtBlock->m_MoveVector.y);
}
/* Redessin nouvel affichage */
PtBlock->m_MoveVector.x = screen->m_Curseur.x - PtBlock->m_BlockLastCursorPosition.x;
PtBlock->m_MoveVector.y = screen->m_Curseur.y - PtBlock->m_BlockLastCursorPosition.y;
GRSetDrawMode(DC, g_XorMode);
PtBlock->Offset(PtBlock->m_MoveVector);
PtBlock->Draw(panel, DC);
PtBlock->Offset( -PtBlock->m_MoveVector.x, -PtBlock->m_MoveVector.y);
if(PtBlock->m_BlockDrawStruct )
{
if(PtBlock->m_BlockDrawStruct->m_StructType == DRAW_PICK_ITEM_STRUCT_TYPE)
{
PickedList = (DrawPickedStruct *) PtBlock->m_BlockDrawStruct;
while (PickedList)
{
DrawStructsInGhost(panel, DC, PickedList->m_PickedStruct, PtBlock->m_MoveVector.x, PtBlock->m_MoveVector.y);
PickedList = (DrawPickedStruct *)PickedList->Pnext;
}
}
else DrawStructsInGhost(panel, DC, PtBlock->m_BlockDrawStruct, PtBlock->m_MoveVector.x, PtBlock->m_MoveVector.y);
}
}
/*****************************************************************************
* Routine to move an object(s) to a new position. *
* If DrawStruct is of type DrawPickedStruct, a list of objects picked is *
* assumed, otherwise exactly one structure is assumed been picked. *
*****************************************************************************/
bool MoveStruct(WinEDA_DrawPanel * panel, wxDC * DC, EDA_BaseStruct *DrawStruct)
{
DrawPickedStruct *PickedList = NULL;
if ( !DrawStruct ) return FALSE;
if(DrawStruct->m_StructType == DRAW_PICK_ITEM_STRUCT_TYPE)
{
if ( DC )
RedrawStructList(panel, DC, DrawStruct, g_XorMode);
PlaceStruct(panel->GetScreen(), DrawStruct); /* Place it in its new position. */
if ( DC )
RedrawStructList(panel, DC, DrawStruct, GR_DEFAULT_DRAWMODE);
/* Free the wrapper DrawPickedStruct chain: */
PickedList = (DrawPickedStruct *) DrawStruct;
PickedList->DeleteWrapperList();
}
else
{
if ( DC )
RedrawOneStruct(panel, DC, DrawStruct, g_XorMode);
PlaceStruct(panel->GetScreen(), DrawStruct); /* Place it in its new position. */
if ( DC )
RedrawOneStruct(panel, DC, DrawStruct, GR_DEFAULT_DRAWMODE);
}
return TRUE;
}
static void MirrorYPoint(wxPoint & point, wxPoint & Center)
{
point.x -= Center.x;
point.x = - point.x;
point.x += Center.x;
}
/**************************************************************/
void MirrorOneStruct(EDA_BaseStruct *DrawStruct, wxPoint & Center)
/**************************************************************/
/* Given a structure rotate it to 90 degrees refer to the Center point.
*/
{
int dx, ii, *Points;
DrawPolylineStruct *DrawPoly;
DrawJunctionStruct *DrawConnect;
EDA_DrawLineStruct *DrawSegment;
DrawBusEntryStruct *DrawRaccord;
EDA_SchComponentStruct *DrawLibItem;
DrawSheetStruct *DrawSheet;
DrawSheetLabelStruct *DrawSheetLabel;
DrawMarkerStruct * DrawMarker;
DrawNoConnectStruct * DrawNoConnect;
DrawTextStruct * DrawText;
wxPoint px;
if ( !DrawStruct ) return;
switch (DrawStruct->m_StructType)
{
case TYPE_NOT_INIT:
break;
case DRAW_POLYLINE_STRUCT_TYPE:
DrawPoly = (DrawPolylineStruct *) DrawStruct;
Points = DrawPoly->m_Points;
for (ii = 0; ii < DrawPoly->m_NumOfPoints; ii++)
{
wxPoint point;
point.x = Points[ii * 2]; point.y = Points[ii * 2 + 1];
MirrorYPoint(point, Center);
Points[ii * 2] = point.x; Points[ii * 2 + 1] = point.y;
}
break;
case DRAW_SEGMENT_STRUCT_TYPE:
DrawSegment = (EDA_DrawLineStruct *) DrawStruct;
if( (DrawSegment->m_Flags & STARTPOINT) == 0 )
{
MirrorYPoint(DrawSegment->m_Start, Center);
}
if( (DrawSegment->m_Flags & ENDPOINT) == 0 )
{
MirrorYPoint(DrawSegment->m_End, Center);
}
break;
case DRAW_BUSENTRY_STRUCT_TYPE:
DrawRaccord = (DrawBusEntryStruct *) DrawStruct;
MirrorYPoint(DrawRaccord->m_Pos, Center);
break;
case DRAW_JUNCTION_STRUCT_TYPE:
DrawConnect = (DrawJunctionStruct *) DrawStruct;
MirrorYPoint(DrawConnect->m_Pos, Center);
break;
case DRAW_MARKER_STRUCT_TYPE:
DrawMarker = (DrawMarkerStruct *) DrawStruct;
MirrorYPoint(DrawMarker->m_Pos, Center);
break;
case DRAW_NOCONNECT_STRUCT_TYPE:
DrawNoConnect = (DrawNoConnectStruct *) DrawStruct;
MirrorYPoint(DrawNoConnect->m_Pos, Center);
break;
case DRAW_TEXT_STRUCT_TYPE:
case DRAW_LABEL_STRUCT_TYPE:
// Text is not really mirrored; it is moved to a suitable position
// which is the closest position for a true mirrored text
// The center position is mirrored and the text is moved for half horizontal len
DrawText = (DrawTextStruct *) DrawStruct;
px = DrawText->m_Pos;
if( DrawText->m_Orient == 0 ) /* horizontal text */
dx = DrawText->Len_Size() / 2;
else if( DrawText->m_Orient == 2 ) /* invert horizontal text*/
dx = - DrawText->Len_Size() / 2;
else dx = 0;
px.x += dx;
MirrorYPoint(px, Center);
px.x -= dx;
EDA_Appl->SchematicFrame->PutOnGrid(&px);
DrawText->m_Pos.x = px.x;
break;
case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
// Text is not really mirrored: Orientation is changed
DrawText = (DrawGlobalLabelStruct *) DrawStruct;
if( DrawText->m_Orient == 0 ) /* horizontal text */
DrawText->m_Orient = 2;
else if( DrawText->m_Orient == 2 ) /* invert horizontal text*/
DrawText->m_Orient = 0;
px = DrawText->m_Pos;
MirrorYPoint(px, Center);
EDA_Appl->SchematicFrame->PutOnGrid(&px);
DrawText->m_Pos.x = px.x;
break;
case DRAW_LIB_ITEM_STRUCT_TYPE:
DrawLibItem = (EDA_SchComponentStruct *) DrawStruct;
dx = DrawLibItem->m_Pos.x;
EDA_Appl->SchematicFrame->CmpRotationMiroir( DrawLibItem,
NULL, CMP_MIROIR_Y );
MirrorYPoint(DrawLibItem->m_Pos, Center);
dx -= DrawLibItem->m_Pos.x;
for( ii = 0; ii < NUMBER_OF_FIELDS; ii++ )
{ /* move the fields to the new position because the component itself has moved */
DrawLibItem->m_Field[ii].m_Pos.x -= dx;
}
break;
case DRAW_SHEET_STRUCT_TYPE:
DrawSheet = (DrawSheetStruct *) DrawStruct;
MirrorYPoint(DrawSheet->m_Pos, Center);
DrawSheet->m_Pos.x -= DrawSheet->m_Size.x;
DrawSheetLabel = DrawSheet->m_Label;
while( DrawSheetLabel != NULL )
{
MirrorYPoint(DrawSheetLabel->m_Pos, Center);
DrawSheetLabel->m_Edge = DrawSheetLabel->m_Edge ? 0 : 1;
DrawSheetLabel = (DrawSheetLabelStruct*)DrawSheetLabel->Pnext;
}
break;
case DRAW_SHEETLABEL_STRUCT_TYPE:
DrawSheetLabel = (DrawSheetLabelStruct *) DrawStruct;
MirrorYPoint(DrawSheetLabel->m_Pos, Center);
break;
case DRAW_PICK_ITEM_STRUCT_TYPE : break;
default: break;
}
}
/*****************************************************************************
* Routine to Mirror an object(s). *
* If DrawStruct is of type DrawPickedStruct, a list of objects picked is *
* assumed, otherwise exactly one structure is assumed been picked. *
*****************************************************************************/
bool MirrorStruct(WinEDA_DrawPanel * panel, wxDC * DC, EDA_BaseStruct *DrawStruct, wxPoint & Center)
{
DrawPickedStruct *PickedList = NULL;
DrawPickedStruct *DrawStructs;
if ( !DrawStruct ) return FALSE;
if(DrawStruct->m_StructType == DRAW_PICK_ITEM_STRUCT_TYPE)
{
if ( DC )
RedrawStructList(panel, DC, DrawStruct, g_XorMode);
DrawStructs = (DrawPickedStruct *) DrawStruct;
while (DrawStructs)
{
MirrorOneStruct(DrawStructs->m_PickedStruct, Center);
DrawStructs->m_PickedStruct->m_Flags = 0;
DrawStructs = (DrawPickedStruct *)DrawStructs->Pnext;
}
if ( DC )
RedrawStructList(panel, DC, DrawStruct, GR_DEFAULT_DRAWMODE);
/* Free the wrapper DrawPickedStruct chain: */
PickedList = (DrawPickedStruct *) DrawStruct;
PickedList->DeleteWrapperList();
}
else
{
if ( DC )
RedrawOneStruct(panel, DC, DrawStruct, g_XorMode);
MirrorOneStruct(DrawStruct, Center); /* Place it in its new position. */
if ( DC )
RedrawOneStruct(panel, DC, DrawStruct, GR_DEFAULT_DRAWMODE);
DrawStruct->m_Flags = 0;
}
return TRUE;
}
/*****************************************************************************/
static EDA_BaseStruct * CopyStruct(WinEDA_DrawPanel * panel, wxDC * DC, BASE_SCREEN * screen,
EDA_BaseStruct *DrawStruct)
/*****************************************************************************/
/* Routine to copy a new entity of an object and reposition it.
If DrawStruct is of type DrawPickedStruct, a list of objects picked is
assumed, otherwise exactly one structure is assumed been picked.
Return the new created struct
*/
{
EDA_BaseStruct *NewDrawStruct;
DrawPickedStruct *PickedList = NULL;
if ( !DrawStruct ) return FALSE;
NewDrawStruct = DuplicateStruct(DrawStruct);
if ( NewDrawStruct == NULL ) return NULL;
PlaceStruct( screen, NewDrawStruct);
/* Draw the new structure and chain it in: */
if (NewDrawStruct->m_StructType == DRAW_PICK_ITEM_STRUCT_TYPE)
{
PickedList = (DrawPickedStruct *) NewDrawStruct;
while (PickedList) // Clear annotation for new components
{
EDA_BaseStruct * Struct = PickedList->m_PickedStruct;
switch ( Struct->m_StructType )
{
case DRAW_LIB_ITEM_STRUCT_TYPE:
{
((EDA_SchComponentStruct*)Struct)->m_TimeStamp = GetTimeStamp();
((EDA_SchComponentStruct*)Struct)->ClearAnnotation();
}
break;
case DRAW_SHEET_STRUCT_TYPE:
{
DrawSheetStruct * sheet = (DrawSheetStruct*)Struct;
sheet->m_TimeStamp = GetTimeStamp();
sheet->m_UndoList = NULL;
sheet->m_RedoList = NULL;
sheet->EEDrawList = NULL;
sheet->m_Son = NULL;
sheet->m_SheetName.Printf(wxT("%8.8lX"), sheet->m_TimeStamp);
sheet->m_FileName = sheet->m_SheetName + wxT(".sch");
break;
}
}
SetStructFather(Struct, screen);
PickedList = (DrawPickedStruct *)PickedList->Pnext;
}
RedrawStructList(panel, DC, NewDrawStruct, GR_DEFAULT_DRAWMODE);
/* Chain the new items */
PickedList = (DrawPickedStruct *) NewDrawStruct;
while (PickedList)
{
PickedList->m_PickedStruct->Pnext = screen->EEDrawList;
screen->EEDrawList = PickedList->m_PickedStruct;
PickedList = PickedList->Next();
}
}
else
{
switch(NewDrawStruct->m_StructType)
{
case DRAW_POLYLINE_STRUCT_TYPE:
case DRAW_JUNCTION_STRUCT_TYPE:
case DRAW_SEGMENT_STRUCT_TYPE:
case DRAW_BUSENTRY_STRUCT_TYPE:
case DRAW_TEXT_STRUCT_TYPE:
case DRAW_LABEL_STRUCT_TYPE:
case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
case DRAW_SHEETLABEL_STRUCT_TYPE:
case DRAW_PICK_ITEM_STRUCT_TYPE:
case DRAW_MARKER_STRUCT_TYPE:
case DRAW_NOCONNECT_STRUCT_TYPE:
default:
break;
case DRAW_SHEET_STRUCT_TYPE:
{
DrawSheetStruct * sheet = (DrawSheetStruct*)NewDrawStruct;
sheet->m_TimeStamp = GetTimeStamp();
sheet->m_UndoList = NULL;
sheet->m_RedoList = NULL;
sheet->EEDrawList = NULL;
sheet->m_Son = NULL;
sheet->m_SheetName.Printf(wxT("%8.8lX"), sheet->m_TimeStamp);
sheet->m_FileName = sheet->m_SheetName + wxT(".sch");
break;
}
case DRAW_LIB_ITEM_STRUCT_TYPE:
((EDA_SchComponentStruct*)NewDrawStruct)->m_TimeStamp = GetTimeStamp();
((EDA_SchComponentStruct*)NewDrawStruct)->ClearAnnotation();
break;
}
RedrawOneStruct(panel, DC, NewDrawStruct, GR_DEFAULT_DRAWMODE);
SetStructFather(NewDrawStruct, screen);
NewDrawStruct->Pnext = screen->EEDrawList;
screen->EEDrawList = NewDrawStruct;
}
/* Free the original DrawPickedStruct chain: */
if (DrawStruct->m_StructType == DRAW_PICK_ITEM_STRUCT_TYPE)
{
PickedList = (DrawPickedStruct *) DrawStruct;
PickedList->DeleteWrapperList();
}
return NewDrawStruct;
}
/*********************************************************************************/
void DeleteStruct(WinEDA_DrawPanel * panel, wxDC * DC, EDA_BaseStruct *DrawStruct)
/*********************************************************************************/
/* Routine to delete an object from global drawing object list.
Object is put in Undo list
*/
{
SCH_SCREEN * screen = (SCH_SCREEN *)panel->GetScreen();
DrawPickedStruct *PickedList = NULL;
WinEDA_SchematicFrame * frame = (WinEDA_SchematicFrame *) panel->m_Parent;
if ( !DrawStruct ) return;
if (DrawStruct->m_StructType == DRAW_SHEETLABEL_STRUCT_TYPE)
{ /* Cette stucture est rattachee a une feuille, et n'est pas
accessible par la liste globale directement */
frame->SaveCopyInUndoList(((DrawSheetLabelStruct*) DrawStruct)->m_Parent, IS_CHANGED);
frame->DeleteSheetLabel(DC, (DrawSheetLabelStruct*) DrawStruct);
return;
}
if (DrawStruct->m_StructType == DRAW_PICK_ITEM_STRUCT_TYPE)
{
/* Unlink all picked structs from current EEDrawList */
PickedList = (DrawPickedStruct *) DrawStruct;
while (PickedList)
{
screen->RemoveFromDrawList(PickedList->m_PickedStruct);
PickedList->m_PickedStruct->Pnext =
PickedList->m_PickedStruct->Pback = NULL;
PickedList->m_PickedStruct->m_Flags = IS_DELETED;
PickedList = PickedList->Next();
}
RedrawStructList(panel, DC, DrawStruct, g_XorMode);
/* Removed items are put to the Undo list */
frame->SaveCopyInUndoList(DrawStruct, IS_DELETED);
}
else /* structure classique */
{
screen->RemoveFromDrawList(DrawStruct);
RedrawOneStruct(panel, DC, DrawStruct, g_XorMode);
/* Unlink the structure */
DrawStruct->Pnext = DrawStruct->Pback = NULL; // Only one struct -> no link
frame->SaveCopyInUndoList(DrawStruct, IS_DELETED);
}
}
/*****************************************************************/
EDA_BaseStruct * SaveStructListForPaste(EDA_BaseStruct *DrawStruct)
/*****************************************************************/
/* Routine to Save an object from global drawing object list.
This routine is the same as delete but:
- the original list is NOT removed.
- List is saved in g_BlockSaveDataList
*/
{
DrawPickedStruct *PickedList;
EDA_BaseStruct *DrawStructCopy;
if ( !DrawStruct ) return NULL;
/* Make a copy of the original picked item. */
DrawStructCopy = DuplicateStruct(DrawStruct);
if (DrawStruct->m_StructType == DRAW_PICK_ITEM_STRUCT_TYPE)
{
/* Delete the picked wrapper if this is a picked list. */
PickedList = (DrawPickedStruct *) DrawStruct;
PickedList->DeleteWrapperList();
}
/* And delete old list and save the new list: */
if (g_BlockSaveDataList ) /* Delete last deleted item or item list */
{
EDA_BaseStruct * item = g_BlockSaveDataList, * next_item;
while (item)
{
next_item = item->Pnext;
delete item;
item = next_item;
}
}
g_BlockSaveDataList = DrawStructCopy;
DrawStructCopy->m_Parent = NULL;
return DrawStructCopy;
}
/*****************************************************************************
* Routine to paste a structure from the g_BlockSaveDataList stack. *
* This routine is the same as undelete but original list is NOT removed. *
*****************************************************************************/
void WinEDA_SchematicFrame::PasteStruct(wxDC * DC)
{
EDA_BaseStruct *DrawStruct;
DrawPickedStruct *PickedList = NULL;
if (g_BlockSaveDataList == NULL)
{
DisplayError(this, wxT("No struct to paste") );
return;
}
DrawStruct = DuplicateStruct(g_BlockSaveDataList);
PlaceStruct( GetScreen(), DrawStruct);
RedrawStructList(DrawPanel, DC, DrawStruct, GR_DEFAULT_DRAWMODE);
// Clear annotation and init new time stamp for the new components:
if (DrawStruct->m_StructType == DRAW_PICK_ITEM_STRUCT_TYPE)
{
for(PickedList = (DrawPickedStruct *) DrawStruct; PickedList != NULL; ) // Clear annotation for new components
{
EDA_BaseStruct * Struct = PickedList->m_PickedStruct;
if ( Struct->m_StructType == DRAW_LIB_ITEM_STRUCT_TYPE )
{
((EDA_SchComponentStruct*)Struct)->m_TimeStamp = GetTimeStamp();
((EDA_SchComponentStruct*)Struct)->ClearAnnotation();
SetStructFather(Struct, GetScreen());
}
PickedList = (DrawPickedStruct *)PickedList->Pnext;
}
RedrawStructList(DrawPanel, DC, DrawStruct, GR_DEFAULT_DRAWMODE);
for(PickedList = (DrawPickedStruct *) DrawStruct; PickedList != NULL; )
{
EDA_BaseStruct * Struct = PickedList->m_PickedStruct;
Struct->Pnext = GetScreen()->EEDrawList;
SetStructFather(Struct, GetScreen());
GetScreen()->EEDrawList = Struct;
PickedList = (DrawPickedStruct *)PickedList->Pnext;
}
/* Save wrapper list in undo stack */
SaveCopyInUndoList(DrawStruct, IS_NEW);
}
else
{
if ( DrawStruct->m_StructType == DRAW_LIB_ITEM_STRUCT_TYPE )
{
((EDA_SchComponentStruct*)DrawStruct)->m_TimeStamp = GetTimeStamp();
((EDA_SchComponentStruct*)DrawStruct)->ClearAnnotation();
}
SetStructFather(DrawStruct, GetScreen());
RedrawOneStruct(DrawPanel, DC, DrawStruct, GR_DEFAULT_DRAWMODE);
DrawStruct->Pnext = GetScreen()->EEDrawList;
GetScreen()->EEDrawList = DrawStruct;
SaveCopyInUndoList(DrawStruct, IS_NEW);
}
/* clear .m_Flags member for all items */
EDA_BaseStruct * Struct;
for(Struct = GetScreen()->EEDrawList; Struct != NULL; Struct=Struct->Pnext)
Struct->m_Flags = 0;
GetScreen()->SetModify();
return;
}
/*****************************************************************************
* Routine to place a given object. *
*****************************************************************************/
bool PlaceStruct( BASE_SCREEN * screen, EDA_BaseStruct *DrawStruct)
{
DrawPickedStruct * DrawStructs;
wxPoint move_vector;
if ( !DrawStruct ) return FALSE;
move_vector.x = screen->m_Curseur.x -
screen->BlockLocate.m_BlockLastCursorPosition.x;
move_vector.y = screen->m_Curseur.y -
screen->BlockLocate.m_BlockLastCursorPosition.y;
switch (DrawStruct->m_StructType)
{
default:
case TYPE_NOT_INIT:
return FALSE;
case DRAW_POLYLINE_STRUCT_TYPE:
case DRAW_JUNCTION_STRUCT_TYPE:
case DRAW_SEGMENT_STRUCT_TYPE:
case DRAW_BUSENTRY_STRUCT_TYPE:
case DRAW_TEXT_STRUCT_TYPE:
case DRAW_LABEL_STRUCT_TYPE:
case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
case DRAW_LIB_ITEM_STRUCT_TYPE:
case DRAW_SHEET_STRUCT_TYPE:
case DRAW_SHEETLABEL_STRUCT_TYPE:
case DRAW_MARKER_STRUCT_TYPE:
case DRAW_NOCONNECT_STRUCT_TYPE:
MoveOneStruct(DrawStruct, move_vector);
break;
case DRAW_PICK_ITEM_STRUCT_TYPE:
DrawStructs = (DrawPickedStruct *) DrawStruct;
while (DrawStructs)
{
MoveOneStruct(DrawStructs->m_PickedStruct, move_vector);
DrawStructs = (DrawPickedStruct *)DrawStructs->Pnext;
}
break;
}
return TRUE;
}
/**************************************************************************/
void MoveOneStruct(EDA_BaseStruct *DrawStruct, const wxPoint & move_vector)
/*************************************************************************/
/* Given a structure move it by Dx, Dy.
*/
{
int ii, *Points;
DrawPolylineStruct *DrawPoly;
DrawJunctionStruct *DrawConnect;
EDA_DrawLineStruct *DrawSegment;
DrawBusEntryStruct *DrawRaccord;
EDA_SchComponentStruct *DrawLibItem;
DrawSheetStruct *DrawSheet;
DrawSheetLabelStruct *DrawSheetLabel;
DrawMarkerStruct * DrawMarker;
DrawNoConnectStruct * DrawNoConnect;
if ( !DrawStruct ) return;
switch (DrawStruct->m_StructType)
{
case TYPE_NOT_INIT:
break;
case DRAW_POLYLINE_STRUCT_TYPE:
DrawPoly = (DrawPolylineStruct *) DrawStruct;
Points = DrawPoly->m_Points;
for (ii = 0; ii < DrawPoly->m_NumOfPoints; ii++)
{
Points[ii * 2] += move_vector.x;
Points[ii * 2 + 1] += move_vector.y;
}
break;
case DRAW_SEGMENT_STRUCT_TYPE:
DrawSegment = (EDA_DrawLineStruct *) DrawStruct;
if( (DrawSegment->m_Flags & STARTPOINT) == 0 )
{
DrawSegment->m_Start += move_vector;
}
if( (DrawSegment->m_Flags & ENDPOINT) == 0 )
{
DrawSegment->m_End += move_vector;
}
break;
case DRAW_BUSENTRY_STRUCT_TYPE:
DrawRaccord = (DrawBusEntryStruct *) DrawStruct;
DrawRaccord->m_Pos += move_vector;
break;
case DRAW_JUNCTION_STRUCT_TYPE:
DrawConnect = (DrawJunctionStruct *) DrawStruct;
DrawConnect->m_Pos += move_vector;
break;
case DRAW_MARKER_STRUCT_TYPE:
DrawMarker = (DrawMarkerStruct *) DrawStruct;
DrawMarker->m_Pos += move_vector;
break;
case DRAW_NOCONNECT_STRUCT_TYPE:
DrawNoConnect = (DrawNoConnectStruct *) DrawStruct;
DrawNoConnect->m_Pos += move_vector;
break;
case DRAW_TEXT_STRUCT_TYPE:
#define DrawText ((DrawTextStruct *) DrawStruct)
DrawText->m_Pos += move_vector;
break;
case DRAW_LABEL_STRUCT_TYPE:
#define DrawLabel ((DrawLabelStruct *) DrawStruct)
DrawLabel->m_Pos += move_vector;
break;
case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
#define DrawGlobalLabel ((DrawGlobalLabelStruct *) DrawStruct)
DrawGlobalLabel->m_Pos += move_vector;
break;
case DRAW_LIB_ITEM_STRUCT_TYPE:
DrawLibItem = (EDA_SchComponentStruct *) DrawStruct;
DrawLibItem->m_Pos += move_vector;
for( ii = 0; ii < NUMBER_OF_FIELDS; ii++ )
{
DrawLibItem->m_Field[ii].m_Pos += move_vector;
}
break;
case DRAW_SHEET_STRUCT_TYPE:
DrawSheet = (DrawSheetStruct *) DrawStruct;
DrawSheet->m_Pos += move_vector;
DrawSheetLabel = DrawSheet->m_Label;
while( DrawSheetLabel != NULL )
{
DrawSheetLabel->m_Pos += move_vector;
DrawSheetLabel = DrawSheetLabel->Next();
}
break;
case DRAW_SHEETLABEL_STRUCT_TYPE:
DrawSheetLabel = (DrawSheetLabelStruct *) DrawStruct;
DrawSheetLabel->m_Pos += move_vector;
break;
case DRAW_PICK_ITEM_STRUCT_TYPE : break;
default: break;
}
}
/************************************************************/
EDA_BaseStruct * DuplicateStruct(EDA_BaseStruct *DrawStruct)
/************************************************************/
/* Routine to create a new copy of given struct.
The new object is not put in draw list (not linked)
*/
{
EDA_BaseStruct *NewDrawStruct = NULL;
if ( DrawStruct == NULL )
{
DisplayError(NULL, wxT("DuplicateStruct error: NULL struct") );
return NULL;
}
switch (DrawStruct->m_StructType)
{
case DRAW_POLYLINE_STRUCT_TYPE:
NewDrawStruct = ((DrawPolylineStruct*)DrawStruct)->GenCopy();
break;
case DRAW_SEGMENT_STRUCT_TYPE:
NewDrawStruct = ((EDA_DrawLineStruct*)DrawStruct)->GenCopy();
break;
case DRAW_BUSENTRY_STRUCT_TYPE:
NewDrawStruct = ((DrawBusEntryStruct*)DrawStruct)->GenCopy();
break;
case DRAW_JUNCTION_STRUCT_TYPE:
NewDrawStruct = ((DrawJunctionStruct*)DrawStruct)->GenCopy();
break;
case DRAW_MARKER_STRUCT_TYPE:
NewDrawStruct = ((DrawMarkerStruct*)DrawStruct)->GenCopy();
break;
case DRAW_NOCONNECT_STRUCT_TYPE:
NewDrawStruct = ((DrawNoConnectStruct*)DrawStruct)->GenCopy();
break;
case DRAW_TEXT_STRUCT_TYPE:
NewDrawStruct = ((DrawTextStruct*)DrawStruct)->GenCopy();
break;
case DRAW_LABEL_STRUCT_TYPE:
NewDrawStruct = ((DrawLabelStruct*)DrawStruct)->GenCopy();
break;
case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
NewDrawStruct = ((DrawGlobalLabelStruct*)DrawStruct)->GenCopy();
break;
case DRAW_LIB_ITEM_STRUCT_TYPE:
NewDrawStruct = ((EDA_SchComponentStruct*)DrawStruct)->GenCopy();
break;
case DRAW_SHEET_STRUCT_TYPE:
NewDrawStruct = ((DrawSheetStruct*)DrawStruct)->GenCopy();
break;
case DRAW_PICK_ITEM_STRUCT_TYPE:
{
DrawPickedStruct *NewPickedItem, *PickedList = NULL,
*LastPickedItem = NULL;
PickedList = (DrawPickedStruct *) DrawStruct;
while (PickedList)
{
NewPickedItem = new DrawPickedStruct();
if (NewDrawStruct == NULL) NewDrawStruct = NewPickedItem;
if (LastPickedItem ) LastPickedItem->Pnext = NewPickedItem;
LastPickedItem = NewPickedItem;
NewPickedItem->m_PickedStruct =
DuplicateStruct(PickedList->m_PickedStruct);
PickedList = (DrawPickedStruct *)PickedList->Pnext;
}
break;
}
case DRAW_SHEETLABEL_STRUCT_TYPE:
case DRAW_PART_TEXT_STRUCT_TYPE:
case SCREEN_STRUCT_TYPE:
default:
{
wxString msg;
msg << wxT("DuplicateStruct error: unexpected StructType ") <<
DrawStruct->m_StructType << wxT(" ") << DrawStruct->ReturnClassName();
DisplayError(NULL, msg);
}
break;
}
NewDrawStruct->m_Image = DrawStruct;
return NewDrawStruct;
}
/****************************************************/
static void CollectStructsToDrag(SCH_SCREEN * screen)
/****************************************************/
{
DrawPickedStruct * DrawStructs, *FirstPicked;
EDA_BaseStruct * Struct;
EDA_DrawLineStruct* SegmStruct;
int ox, oy, fx, fy;
/* Set membre .m_Flags des segments */
for(Struct = screen->EEDrawList; Struct != NULL; Struct=Struct->Pnext)
Struct->m_Flags = 0;
if(screen->BlockLocate.m_BlockDrawStruct->m_StructType == DRAW_SEGMENT_STRUCT_TYPE )
screen->BlockLocate.m_BlockDrawStruct->m_Flags = SELECTED;
else if (screen->BlockLocate.m_BlockDrawStruct->m_StructType == DRAW_PICK_ITEM_STRUCT_TYPE )
{
DrawStructs = (DrawPickedStruct *) screen->BlockLocate.m_BlockDrawStruct;
while (DrawStructs)
{
Struct = DrawStructs->m_PickedStruct;
DrawStructs = (DrawPickedStruct *)DrawStructs->Pnext;
Struct->m_Flags = SELECTED;
}
}
if( screen->BlockLocate.m_Command != BLOCK_DRAG ) return;
ox = screen->BlockLocate.GetX();
oy = screen->BlockLocate.GetY();
fx = screen->BlockLocate.GetRight();
fy = screen->BlockLocate.GetBottom();
if (fx < ox) EXCHG(fx, ox);
if (fy < oy) EXCHG(fy, oy);
/* Pour Drag Block: remise sous forme de liste de structure, s'il n'y
a qu'un seul element ( pour homogeneiser les traitements ulterieurs */
if(screen->BlockLocate.m_BlockDrawStruct->m_StructType != DRAW_PICK_ITEM_STRUCT_TYPE )
{
DrawStructs = new DrawPickedStruct(screen->BlockLocate.m_BlockDrawStruct);
screen->BlockLocate.m_BlockDrawStruct = DrawStructs;
}
/* Suppression du deplacement des extremites de segments hors cadre
de selection */
DrawStructs = (DrawPickedStruct *) screen->BlockLocate.m_BlockDrawStruct;
while (DrawStructs)
{
Struct = DrawStructs->m_PickedStruct;
DrawStructs = (DrawPickedStruct *)DrawStructs->Pnext;
if( Struct->m_StructType == DRAW_SEGMENT_STRUCT_TYPE)
{
SegmStruct = (EDA_DrawLineStruct*)Struct;
if( (SegmStruct->m_Start.x < ox) || (SegmStruct->m_Start.x > fx) ||
(SegmStruct->m_Start.y < oy) || (SegmStruct->m_Start.y > fy) )
SegmStruct->m_Flags |= STARTPOINT;
if( (SegmStruct->m_End.x < ox) || (SegmStruct->m_End.x > fx) ||
(SegmStruct->m_End.y < oy) || (SegmStruct->m_End.y > fy) )
SegmStruct->m_Flags |= ENDPOINT;
}
}
/* Recherche des elements complementaires a "dragger", c'est a dire les
fils et connexions hors bloc relies a des pins ou entries elles meme
draggees */
FirstPicked = DrawStructs = (DrawPickedStruct*)screen->BlockLocate.m_BlockDrawStruct;
while (DrawStructs)
{
Struct = DrawStructs->m_PickedStruct;
DrawStructs = (DrawPickedStruct * )DrawStructs->Pnext;
if( Struct->m_StructType == DRAW_LIB_ITEM_STRUCT_TYPE)
{
LibEDA_BaseStruct *DrawItem;
int x, y;
DrawItem = GetNextPinPosition( (EDA_SchComponentStruct*)Struct, &x, &y);
while ( DrawItem )
{
if( (x < ox) || (x > fx) || (y < oy) || (y > fy) )
AddPickedItem(screen, x, y);
DrawItem = GetNextPinPosition( NULL, &x, &y);
}
}
if( Struct->m_StructType == DRAW_SHEET_STRUCT_TYPE)
{
DrawSheetLabelStruct * SLabel = ((DrawSheetStruct*)Struct)->m_Label;
while(SLabel)
{
if( SLabel->m_StructType == DRAW_SHEETLABEL_STRUCT_TYPE )
AddPickedItem(screen, SLabel->m_Pos.x, SLabel->m_Pos.y);
SLabel = (DrawSheetLabelStruct*)SLabel->Pnext;
}
}
if( Struct->m_StructType == DRAW_BUSENTRY_STRUCT_TYPE)
{
DrawBusEntryStruct * item = (DrawBusEntryStruct*)Struct;
AddPickedItem(screen, item->m_Pos.x, item->m_Pos.y);
AddPickedItem(screen, item->m_End().x, item->m_End().y);
}
}
}
/******************************************************************/
static void AddPickedItem( SCH_SCREEN * screen, int px, int py )
/******************************************************************/
{
DrawPickedStruct * DrawStructs;
EDA_BaseStruct * Struct;
/* Examen de la liste des elements deja selectionnes */
DrawStructs = (DrawPickedStruct *) screen->BlockLocate.m_BlockDrawStruct;
while (DrawStructs)
{
Struct = DrawStructs->m_PickedStruct;
DrawStructs = (DrawPickedStruct *)DrawStructs->Pnext;
switch( Struct->m_StructType )
{
case DRAW_SEGMENT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ((EDA_DrawLineStruct*)Struct)
if( (STRUCT->m_Start.x == px) && (STRUCT->m_Start.y == py) )
STRUCT->m_Flags &= ~STARTPOINT;
if( (STRUCT->m_End.x == px) && (STRUCT->m_End.y == py) )
STRUCT->m_Flags &= ~ENDPOINT;
break;
default: break;
}
}
/* Examen de la liste des elements non selectionnes */
Struct = screen->EEDrawList;
while ( Struct )
{
switch (Struct->m_StructType)
{
case TYPE_NOT_INIT:
break;
case DRAW_POLYLINE_STRUCT_TYPE:
if( Struct->m_Flags & SELECTED ) break; /* Deja en liste */
break;
case DRAW_JUNCTION_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ((DrawJunctionStruct*)Struct)
if( Struct->m_Flags & SELECTED ) break; /* Deja en liste */
if( STRUCT->m_Pos.x != px ) break;
if( STRUCT->m_Pos.y != py ) break;
DrawStructs = new DrawPickedStruct(Struct);
DrawStructs->Pnext =
(DrawPickedStruct*) screen->BlockLocate.m_BlockDrawStruct;
screen->BlockLocate.m_BlockDrawStruct = (EDA_BaseStruct*) DrawStructs;
break;
case DRAW_SEGMENT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ((EDA_DrawLineStruct*)Struct)
if( Struct->m_Flags & SELECTED ) break; /* Deja en liste */
if( (STRUCT->m_Start.x == px ) && ( STRUCT->m_Start.y == py ) )
{
DrawStructs = new DrawPickedStruct(Struct);
DrawStructs->Pnext =
(DrawPickedStruct*) screen->BlockLocate.m_BlockDrawStruct;
screen->BlockLocate.m_BlockDrawStruct = (EDA_BaseStruct*)DrawStructs;
Struct->m_Flags = SELECTED | ENDPOINT | STARTPOINT;
Struct->m_Flags &= ~STARTPOINT;
}
else if( (STRUCT->m_End.x == px ) && ( STRUCT->m_End.y == py ) )
{
DrawStructs = new DrawPickedStruct(Struct);
DrawStructs->Pnext =
(DrawPickedStruct*) screen->BlockLocate.m_BlockDrawStruct;
screen->BlockLocate.m_BlockDrawStruct = (EDA_BaseStruct*) DrawStructs;
Struct->m_Flags = SELECTED | ENDPOINT | STARTPOINT;
Struct->m_Flags &= ~ENDPOINT;
}
break;
case DRAW_BUSENTRY_STRUCT_TYPE:
break;
case DRAW_TEXT_STRUCT_TYPE:
break;
case DRAW_LABEL_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ((DrawLabelStruct*)Struct)
if( Struct->m_Flags & SELECTED ) break; /* Deja en liste */
if( STRUCT->m_Pos.x != px ) break;
if( STRUCT->m_Pos.y != py ) break;
DrawStructs = new DrawPickedStruct(Struct);
DrawStructs->Pnext =
(DrawPickedStruct*) screen->BlockLocate.m_BlockDrawStruct;
screen->BlockLocate.m_BlockDrawStruct = (EDA_BaseStruct*) DrawStructs;
Struct->m_Flags |= SELECTED;
break;
case DRAW_GLOBAL_LABEL_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ((DrawGlobalLabelStruct*)Struct)
if( Struct->m_Flags & SELECTED ) break; /* Deja en liste */
if( STRUCT->m_Pos.x != px ) break;
if( STRUCT->m_Pos.y != py ) break;
DrawStructs = new DrawPickedStruct(Struct);
DrawStructs->Pnext =
(DrawPickedStruct*) screen->BlockLocate.m_BlockDrawStruct;
screen->BlockLocate.m_BlockDrawStruct = (EDA_BaseStruct*) DrawStructs;
Struct->m_Flags |= SELECTED;
break;
case DRAW_LIB_ITEM_STRUCT_TYPE:
break;
case DRAW_SHEET_STRUCT_TYPE:
break;
case DRAW_SHEETLABEL_STRUCT_TYPE:
break;
case DRAW_PICK_ITEM_STRUCT_TYPE:
break;
case DRAW_MARKER_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ((DrawMarkerStruct*)Struct)
if( Struct->m_Flags & SELECTED ) break; /* Deja en liste */
if( STRUCT->m_Pos.x != px ) break;
if( STRUCT->m_Pos.y != py ) break;
DrawStructs = new DrawPickedStruct(Struct);
DrawStructs->Pnext =
(DrawPickedStruct*) screen->BlockLocate.m_BlockDrawStruct;
screen->BlockLocate.m_BlockDrawStruct = (EDA_BaseStruct*) DrawStructs;
Struct->m_Flags |= SELECTED;
break;
case DRAW_NOCONNECT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ((DrawNoConnectStruct*)Struct)
if( Struct->m_Flags & SELECTED ) break; /* Deja en liste */
if( STRUCT->m_Pos.x != px ) break;
if( STRUCT->m_Pos.y != py ) break;
DrawStructs = new DrawPickedStruct(Struct);
DrawStructs->Pnext =
(DrawPickedStruct*) screen->BlockLocate.m_BlockDrawStruct;
screen->BlockLocate.m_BlockDrawStruct = (EDA_BaseStruct*) DrawStructs;
Struct->m_Flags |= SELECTED;
break;
default:
break;
}
Struct = Struct->Pnext;
}
}
/*********************************************************************************/
static LibEDA_BaseStruct * GetNextPinPosition( EDA_SchComponentStruct * DrawLibItem,
int * px, int * py )
/*********************************************************************************/
{
EDA_LibComponentStruct *Entry;
static LibEDA_BaseStruct *NextItem;
static int Multi, convert, PartX, PartY, TransMat[2][2];
LibEDA_BaseStruct *DEntry;
int x2, y2, orient;
LibDrawPin * Pin;
if( DrawLibItem )
{
NextItem = NULL;
if((Entry = FindLibPart(DrawLibItem->m_ChipName.GetData(),wxEmptyString,FIND_ROOT)) == NULL)
return(NULL);
DEntry = Entry->m_Drawings;
Multi = DrawLibItem->m_Multi;
convert = DrawLibItem->m_Convert;
PartX = DrawLibItem->m_Pos.x;
PartY = DrawLibItem->m_Pos.y;
memcpy(TransMat, DrawLibItem->m_Transform, sizeof(TransMat) );
}
else DEntry = NextItem;
for( ; DEntry != NULL; DEntry = DEntry->Next())
{
/* Elimination des elements non relatifs a l'unite */
if( Multi && DEntry->m_Unit && (DEntry->m_Unit != Multi) ) continue;
if( convert && DEntry->m_Convert && (DEntry->m_Convert != convert) )
continue;
if( DEntry->m_StructType != COMPONENT_PIN_DRAW_TYPE ) continue;
Pin = (LibDrawPin * ) DEntry;
/* Calcul de l'orientation reelle de la Pin */
orient = Pin->ReturnPinDrawOrient(TransMat);
/* Calcul de la position du point de reference */
x2 = PartX + (TransMat[0][0] * Pin->m_Pos.x)
+ (TransMat[0][1] * Pin->m_Pos.y);
y2 = PartY + (TransMat[1][0] * Pin->m_Pos.x)
+ (TransMat[1][1] * Pin->m_Pos.y);
*px = x2; *py = y2;
NextItem = DEntry->Next();
return(DEntry);
}
NextItem = NULL;
return(NULL);
}