1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/**
* @file operations_on_items_lists.cpp
* @brief Functions used in block commands, or undo/redo, to move, mirror, delete, copy ...
* lists of schematic items.
*/
#include <fctsys.h>
#include <appl_wxstruct.h>
#include <class_drawpanel.h>
#include <wxEeschemaStruct.h>
#include <general.h>
#include <protos.h>
#include <sch_bus_entry.h>
#include <sch_marker.h>
#include <sch_line.h>
#include <sch_no_connect.h>
#include <sch_polyline.h>
#include <sch_sheet.h>
#include <sch_component.h>
#include <sch_junction.h>
void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen )
{
switch( Struct->Type() )
{
case SCH_POLYLINE_T:
case SCH_JUNCTION_T:
case SCH_TEXT_T:
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
case SCH_HIERARCHICAL_LABEL_T:
case SCH_COMPONENT_T:
case SCH_LINE_T:
case SCH_BUS_ENTRY_T:
case SCH_SHEET_T:
case SCH_MARKER_T:
case SCH_NO_CONNECT_T:
Struct->SetParent( Screen );
break;
case SCH_SHEET_PIN_T:
break;
default:
break;
}
}
void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& rotationPoint )
{
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
item->Rotate( rotationPoint ); // Place it in its new position.
item->ClearFlags();
}
}
void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList );
void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
const wxPoint aMoveVector );
void MirrorY( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint )
{
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
item->MirrorY( aMirrorPoint.x ); // Place it in its new position.
item->ClearFlags();
}
}
void MirrorX( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint )
{
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
item->MirrorX( aMirrorPoint.y ); // Place it in its new position.
item->ClearFlags();
}
}
/**
* Function MoveItemsInList
* Move a list of items to a given move vector
* @param aItemsList = list of picked items
* @param aMoveVector = the move vector value
*/
void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint aMoveVector )
{
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
item->Move( aMoveVector );
}
}
/**
* Function DeleteItemsInList
* delete schematic items in aItemsList
* deleted items are put in undo list
*/
void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList )
{
SCH_SCREEN* screen = (SCH_SCREEN*) panel->GetScreen();
SCH_EDIT_FRAME* frame = (SCH_EDIT_FRAME*) panel->GetParent();
PICKED_ITEMS_LIST itemsList;
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
ITEM_PICKER itemWrapper( item, UR_DELETED );
if( item->Type() == SCH_SHEET_PIN_T )
{
/* this item is depending on a sheet, and is not in global list */
wxMessageBox( wxT( "DeleteItemsInList() err: unexpected SCH_SHEET_PIN_T" ) );
}
else
{
screen->Remove( item );
/* Unlink the structure */
itemsList.PushItem( itemWrapper );
}
}
frame->SaveCopyInUndoList( itemsList, UR_DELETED );
}
void SCH_EDIT_FRAME::DeleteItem( SCH_ITEM* aItem )
{
wxCHECK_RET( aItem != NULL, wxT( "Cannot delete invalid item." ) );
if( aItem == NULL )
return;
SCH_SCREEN* screen = GetScreen();
if( aItem->Type() == SCH_SHEET_PIN_T )
{
// This iten is attached to a node, and is not accessible by the global list directly.
SCH_SHEET* sheet = (SCH_SHEET*) aItem->GetParent();
wxCHECK_RET( (sheet != NULL) && (sheet->Type() == SCH_SHEET_T),
wxT( "Sheet label has invalid parent item." ) );
SaveCopyInUndoList( (SCH_ITEM*) sheet, UR_CHANGED );
sheet->RemovePin( (SCH_SHEET_PIN*) aItem );
m_canvas->RefreshDrawingRect( sheet->GetBoundingBox() );
}
else
{
screen->Remove( aItem );
SaveCopyInUndoList( aItem, UR_DELETED );
m_canvas->RefreshDrawingRect( aItem->GetBoundingBox() );
}
}
/* Routine to copy a new entity of an object for each object in list and
* reposition it.
* Return the new created object list in aItemsList
*/
void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
const wxPoint aMoveVector )
{
SCH_ITEM* newitem;
if( aItemsList.GetCount() == 0 )
return;
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
newitem = DuplicateStruct( (SCH_ITEM*) aItemsList.GetPickedItem( ii ) );
aItemsList.SetPickedItem( newitem, ii );
aItemsList.SetPickedItemStatus( UR_NEW, ii );
{
switch( newitem->Type() )
{
case SCH_POLYLINE_T:
case SCH_JUNCTION_T:
case SCH_LINE_T:
case SCH_BUS_ENTRY_T:
case SCH_TEXT_T:
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
case SCH_HIERARCHICAL_LABEL_T:
case SCH_SHEET_PIN_T:
case SCH_MARKER_T:
case SCH_NO_CONNECT_T:
default:
break;
case SCH_SHEET_T:
{
SCH_SHEET* sheet = (SCH_SHEET*) newitem;
sheet->SetTimeStamp( GetNewTimeStamp() );
sheet->SetSon( NULL );
break;
}
case SCH_COMPONENT_T:
( (SCH_COMPONENT*) newitem )->SetTimeStamp( GetNewTimeStamp() );
( (SCH_COMPONENT*) newitem )->ClearAnnotation( NULL );
break;
}
SetSchItemParent( newitem, screen );
screen->Append( newitem );
}
}
MoveItemsInList( aItemsList, aMoveVector );
}
/**
* Function DuplicateStruct
* Routine to create a new copy of given struct.
* The new object is not put in draw list (not linked)
* @param aDrawStruct = the SCH_ITEM to duplicate
* @param aClone (default = false)
* if true duplicate also some parameters that must be unique
* (timestamp and sheet name)
* aClone must be false. use true only is undo/redo duplications
*/
SCH_ITEM* DuplicateStruct( SCH_ITEM* aDrawStruct, bool aClone )
{
wxCHECK_MSG( aDrawStruct != NULL, NULL,
wxT( "Cannot duplicate NULL schematic item! Bad programmer." ) );
SCH_ITEM* NewDrawStruct = (SCH_ITEM*) aDrawStruct->Clone();
if( aClone )
NewDrawStruct->SetTimeStamp( aDrawStruct->GetTimeStamp() );
NewDrawStruct->SetImage( aDrawStruct );
return NewDrawStruct;
}