KiCad PCB EDA Suite
operations_on_items_lists.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
31 #include <fctsys.h>
32 #include <pgm_base.h>
33 #include <class_drawpanel.h>
34 #include <schframe.h>
35 
36 #include <general.h>
37 #include <list_operations.h>
38 #include <sch_bus_entry.h>
39 #include <sch_marker.h>
40 #include <sch_line.h>
41 #include <sch_no_connect.h>
42 #include <sch_sheet.h>
43 #include <sch_component.h>
44 #include <sch_junction.h>
45 
46 
47 void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen )
48 {
49  switch( Struct->Type() )
50  {
51  case SCH_JUNCTION_T:
52  case SCH_TEXT_T:
53  case SCH_LABEL_T:
54  case SCH_GLOBAL_LABEL_T:
56  case SCH_COMPONENT_T:
57  case SCH_LINE_T:
60  case SCH_SHEET_T:
61  case SCH_MARKER_T:
62  case SCH_NO_CONNECT_T:
63  Struct->SetParent( Screen );
64  break;
65 
66  case SCH_SHEET_PIN_T:
67  break;
68 
69  default:
70  break;
71  }
72 }
73 
74 
75 void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, const wxPoint& rotationPoint )
76 {
77  for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
78  {
79  SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
80  item->Rotate( rotationPoint ); // Place it in its new position.
81  item->ClearFlags();
82  }
83 }
84 
85 
86 void MirrorY( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMirrorPoint )
87 {
88  for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
89  {
90  SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
91  item->MirrorY( aMirrorPoint.x ); // Place it in its new position.
92  item->ClearFlags();
93  }
94 }
95 
96 
97 void MirrorX( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMirrorPoint )
98 {
99  for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
100  {
101  SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
102  item->MirrorX( aMirrorPoint.y ); // Place it in its new position.
103  item->ClearFlags();
104  }
105 }
106 
107 
108 void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMoveVector )
109 {
110  for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
111  {
112  SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
113  item->Move( aMoveVector );
114  }
115 }
116 
117 
119 {
120  std::vector< wxPoint > pts;
121  std::vector< wxPoint > connections;
122 
123  GetSchematicConnections( connections );
124  for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
125  {
126  SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
127  std::vector< wxPoint > new_pts;
128 
129  if( !item->IsConnectable() )
130  continue;
131 
132  item->GetConnectionPoints( new_pts );
133  pts.insert( pts.end(), new_pts.begin(), new_pts.end() );
134 
135  // If the item is a line, we also add any connection points from the rest of the schematic
136  // that terminate on the line after it is moved.
137  if( item->Type() == SCH_LINE_T )
138  {
139  SCH_LINE* line = (SCH_LINE*) item;
140  for( auto i : connections )
141  if( IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), i ) )
142  pts.push_back( i );
143  }
144  else
145  {
146  // Clean up any wires that short non-wire connections in the list
147  for( auto point = new_pts.begin(); point != new_pts.end(); point++ )
148  {
149  for( auto second_point = point + 1; second_point != new_pts.end(); second_point++ )
150  {
151  aAppend |= TrimWire( *point, *second_point, aAppend );
152  }
153  }
154  }
155  }
156 
157  // We always have some overlapping connection points. Drop duplicates here
158  std::sort( pts.begin(), pts.end(),
159  []( const wxPoint& a, const wxPoint& b ) -> bool
160  { return a.x < b.x || (a.x == b.x && a.y < b.y); } );
161  pts.erase( unique( pts.begin(), pts.end() ), pts.end() );
162 
163  for( auto point : pts )
164  {
165  if( GetScreen()->IsJunctionNeeded( point, true ) )
166  {
167  AddJunction( point, aAppend );
168  aAppend = true;
169  }
170  }
171 }
172 
173 
174 void SCH_EDIT_FRAME::DeleteItemsInList( PICKED_ITEMS_LIST& aItemsList, bool aAppend )
175 {
176  PICKED_ITEMS_LIST itemsList;
177 
178  for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
179  {
180  SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
181  ITEM_PICKER itemWrapper( item, UR_DELETED );
182 
183  if( item->GetFlags() & STRUCT_DELETED )
184  continue;
185 
186  DeleteItem( item, aAppend );
187  aAppend = true;
188  }
189 
191 }
192 
193 
194 void SCH_EDIT_FRAME::DeleteItem( SCH_ITEM* aItem, bool aAppend )
195 {
196  wxCHECK_RET( aItem != NULL, wxT( "Cannot delete invalid item." ) );
197  wxCHECK_RET( !( aItem->GetFlags() & STRUCT_DELETED ),
198  wxT( "Cannot delete item that is already deleted." ) );
199 
200  // Here, aItem is not null.
201  SCH_SCREEN* screen = GetScreen();
202 
203  if( aItem->Type() == SCH_SHEET_PIN_T )
204  {
205  // This item is attached to a node, and is not accessible by the global list directly.
206  SCH_SHEET* sheet = (SCH_SHEET*) aItem->GetParent();
207  wxCHECK_RET( (sheet != NULL) && (sheet->Type() == SCH_SHEET_T),
208  wxT( "Sheet label has invalid parent item." ) );
209  SaveCopyInUndoList( (SCH_ITEM*) sheet, UR_CHANGED, aAppend );
210  sheet->RemovePin( (SCH_SHEET_PIN*) aItem );
212  }
213  else
214  {
215  PICKED_ITEMS_LIST itemsList;
216  ITEM_PICKER picker( aItem, UR_DELETED );
217 
218  aItem->SetFlags( STRUCT_DELETED );
219  itemsList.PushItem( picker );
220  screen->Remove( aItem );
221 
222  if( aItem->IsConnectable() && aItem->Type() != SCH_JUNCTION_T )
223  {
224  std::vector< wxPoint > pts;
225  aItem->GetConnectionPoints( pts );
226  for( auto point : pts )
227  {
228  SCH_ITEM* junction;
229  if( !screen->IsJunctionNeeded( point )
230  && ( junction = screen->GetItem( point, 0, SCH_JUNCTION_T ) ) )
231  {
232  ITEM_PICKER picker_juction( junction, UR_DELETED );
233  junction->SetFlags( STRUCT_DELETED );
234  itemsList.PushItem( picker_juction );
235  screen->Remove( junction );
236  }
237  }
238  }
239 
240  SaveCopyInUndoList( itemsList, UR_DELETED, aAppend );
242  }
243 }
244 
245 
247  const wxPoint& aMoveVector )
248 {
249  SCH_ITEM* newitem;
250 
251  if( aItemsList.GetCount() == 0 )
252  return;
253 
254  for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
255  {
256  newitem = DuplicateStruct( (SCH_ITEM*) aItemsList.GetPickedItem( ii ) );
257  aItemsList.SetPickedItem( newitem, ii );
258  aItemsList.SetPickedItemStatus( UR_NEW, ii );
259  {
260  switch( newitem->Type() )
261  {
262  case SCH_JUNCTION_T:
263  case SCH_LINE_T:
264  case SCH_BUS_BUS_ENTRY_T:
266  case SCH_TEXT_T:
267  case SCH_LABEL_T:
268  case SCH_GLOBAL_LABEL_T:
270  case SCH_SHEET_PIN_T:
271  case SCH_MARKER_T:
272  case SCH_NO_CONNECT_T:
273  default:
274  break;
275 
276  case SCH_SHEET_T:
277  {
278  SCH_SHEET* sheet = (SCH_SHEET*) newitem;
279  sheet->SetTimeStamp( GetNewTimeStamp() );
280  break;
281  }
282 
283  case SCH_COMPONENT_T:
284  ( (SCH_COMPONENT*) newitem )->SetTimeStamp( GetNewTimeStamp() );
285  ( (SCH_COMPONENT*) newitem )->ClearAnnotation( NULL );
286  break;
287  }
288 
289  SetSchItemParent( newitem, screen );
290  screen->Append( newitem );
291  }
292  }
293 
294  MoveItemsInList( aItemsList, aMoveVector );
295 }
296 
297 
298 SCH_ITEM* DuplicateStruct( SCH_ITEM* aDrawStruct, bool aClone )
299 {
300  wxCHECK_MSG( aDrawStruct != NULL, NULL,
301  wxT( "Cannot duplicate NULL schematic item! Bad programmer." ) );
302 
303  SCH_ITEM* NewDrawStruct = (SCH_ITEM*) aDrawStruct->Clone();
304 
305  if( aClone )
306  NewDrawStruct->SetTimeStamp( aDrawStruct->GetTimeStamp() );
307 
308  return NewDrawStruct;
309 }
Definition of the SCH_SHEET class for Eeschema.
SCH_JUNCTION * AddJunction(const wxPoint &aPosition, bool aPutInUndoList=false)
Add a new junction at aPosition.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:225
bool IsPointOnSegment(const wxPoint &aSegStart, const wxPoint &aSegEnd, const wxPoint &aTestPoint)
Function IsPointOnSegment.
Definition: trigo.cpp:39
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:282
virtual const EDA_RECT GetBoundingBox() const
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
void GetSchematicConnections(std::vector< wxPoint > &aConnections)
Collects a unique list of all possible connection points in the schematic.
bool IsJunctionNeeded(const wxPoint &aPosition, bool aNew=false)
Test if a junction is required for the items at aPosition on the screen.
Definition: sch_screen.cpp:348
virtual EDA_ITEM * Clone() const
Function Clone creates a duplicate of this item with linked list members set to NULL.
void MirrorX(PICKED_ITEMS_LIST &aItemsList, const wxPoint &aMirrorPoint)
void MoveItemsInList(PICKED_ITEMS_LIST &aItemsList, const wxPoint &aMoveVector)
Function MoveItemsInList Move a list of items to a given move vector.
EDA_ITEM * GetParent() const
Definition: base_struct.h:235
void RefreshDrawingRect(const EDA_RECT &aRect, bool aEraseBackground=true)
Function RefreshDrawingRect redraws the contents of aRect in drawing units.
Definition: draw_panel.cpp:312
void PushItem(const ITEM_PICKER &aItem)
Function PushItem pushes aItem to the top of the list.
wxPoint GetEndPoint() const
Definition: sch_line.h:80
void SetSchItemParent(SCH_ITEM *Struct, SCH_SCREEN *Screen)
wxPoint GetStartPoint() const
Definition: sch_line.h:76
virtual void Rotate(wxPoint aPosition)=0
Function Rotate rotates the item around aPosition 90 degrees in the clockwise direction.
SCH_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
Definition: schframe.cpp:533
void RotateListOfItems(PICKED_ITEMS_LIST &aItemsList, const wxPoint &rotationPoint)
timestamp_t GetNewTimeStamp()
Definition: common.cpp:166
void RemovePin(SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:186
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:280
EDA_RECT const GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Definition: sch_sheet.cpp:498
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:240
bool SetPickedItem(EDA_ITEM *aItem, unsigned aIdx)
Function SetPickedItem.
void DuplicateItemsInList(SCH_SCREEN *screen, PICKED_ITEMS_LIST &aItemsList, const wxPoint &aMoveVector)
Routine to copy a new entity of an object for each object in list and reposition it.
virtual bool IsConnectable() const
Function IsConnectable returns true if the schematic item can connect to another schematic item...
void SaveCopyInUndoList(SCH_ITEM *aItemToCopy, UNDO_REDO_T aTypeCommand, bool aAppend=false, const wxPoint &aTransformPoint=wxPoint(0, 0))
Create a copy of the current schematic item, and put it in the undo list.
#define STRUCT_DELETED
flag indication structures to be erased
Definition: base_struct.h:136
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:61
virtual void MirrorX(int aXaxis_position)=0
Function MirrorX mirrors item relative to the X axis about aXaxis_position.
Class PICKED_ITEMS_LIST is a holder to handle information on schematic or board items.
virtual void MirrorY(int aYaxis_position)=0
Function MirrorY mirrors item relative to the Y axis about aYaxis_position.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:209
unsigned GetCount() const
Function GetCount.
virtual void GetConnectionPoints(std::vector< wxPoint > &aPoints) const
Function GetConnectionPoints add all the connection points for this item to aPoints.
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:93
Definition the SCH_COMPONENT class for Eeschema.
see class PGM_BASE
void CheckListConnections(PICKED_ITEMS_LIST &aItemsList, bool aAppend=false)
Adds junctions if needed to each item in the list after they have been moved.
bool SetPickedItemStatus(UNDO_REDO_T aStatus, unsigned aIdx)
Function SetPickedItemStatus sets the type of undo/redo operation for a given picked item...
Segment description base class to describe items which have 2 end points (track, wire, draw line ...)
Definition: sch_line.h:41
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
Function GetPickedItem.
void Append(SCH_ITEM *aItem)
void DeleteItemsInList(PICKED_ITEMS_LIST &aItemsList, bool aAppend=false)
Removes all items (and unused junctions that connect to them) and saves each in the undo list...
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
bool TrimWire(const wxPoint &aStart, const wxPoint &aEnd, bool aAppend=true)
If any single wire passes through both points, remove the portion between the two points...
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:281
void ClearDrawingState()
Clear the state flags of all the items in the screen.
Definition: sch_screen.cpp:584
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
void MirrorY(PICKED_ITEMS_LIST &aItemsList, const wxPoint &aMirrorPoint)
void DeleteItem(SCH_ITEM *aItem, bool aAppend=false)
Remove aItem from the current screen and saves it in the undo list.
timestamp_t GetTimeStamp() const
Definition: base_struct.h:231
SCH_ITEM * DuplicateStruct(SCH_ITEM *aDrawStruct, bool aClone)
Routine to create a new copy of given struct.
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:230
virtual void Move(const wxPoint &aMoveVector)=0
Function Move moves the item by aMoveVector to a new position.