KiCad PCB EDA Suite
pad_edit_functions.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) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
7  * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
27 #include <fctsys.h>
28 #include <class_drawpanel.h>
29 #include <confirm.h>
30 #include <trigo.h>
31 #include <macros.h>
32 #include <pcb_base_frame.h>
33 #include <pcb_edit_frame.h>
34 #include <footprint_edit_frame.h>
35 #include <pcbnew.h>
36 #include <class_board.h>
37 #include <class_module.h>
38 #include <class_pad.h>
39 #include <board_design_settings.h>
41 
42 /*
43  * Exports the current pad settings to board design settings.
44  */
46 {
47  if( aPad == NULL )
48  return;
49 
50  SetMsgPanel( aPad );
51 
52  D_PAD& masterPad = GetDesignSettings().m_Pad_Master;
53 
54  masterPad.ImportSettingsFromMaster( *aPad );
55 }
56 
57 
58 /*
59  * Imports the board design settings to aPad
60  * - The position, names, and keys are not modifed.
61  * The parameters are expected to be correct (i.e. settings are valid)
62  */
63 void PCB_BASE_FRAME::Import_Pad_Settings( D_PAD* aPad, bool aDraw )
64 {
65  if( aDraw )
66  {
67  aPad->SetFlags( DO_NOT_DRAW );
69  aPad->ClearFlags( DO_NOT_DRAW );
70  }
71 
72  const D_PAD& mp = GetDesignSettings().m_Pad_Master;
73 
74  aPad->ImportSettingsFromMaster( mp );
75 
76  if( aDraw )
78 
79  aPad->GetParent()->SetLastEditTime();
80 
81  OnModify();
82 }
83 
84 /*
85  * Compute the 'next' pad number for autoincrement
86  * aPadName is the last pad name used
87  * */
88 static wxString GetNextPadName( wxString aPadName )
89 {
90  // Automatically increment the current pad number.
91  int num = 0;
92  int ponder = 1;
93 
94  // Trim and extract the trailing numeric part
95  while( aPadName.Len() && aPadName.Last() >= '0' && aPadName.Last() <= '9' )
96  {
97  num += ( aPadName.Last() - '0' ) * ponder;
98  aPadName.RemoveLast();
99  ponder *= 10;
100  }
101 
102  num++; // Use next number for the new pad
103  aPadName << num;
104 
105  return aPadName;
106 }
107 
108 /*
109  * Add a new pad to aModule.
110  */
111 void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw )
112 {
113  m_Pcb->m_Status_Pcb = 0;
114  aModule->SetLastEditTime();
115 
116  D_PAD* pad = new D_PAD( aModule );
117 
118  // Add the new pad to end of the module pad list.
119  aModule->PadsList().PushBack( pad );
120 
121  // Update the pad properties,
122  // and keep NETINFO_LIST::ORPHANED as net info
123  // which is the default when nets cannot be handled.
124  Import_Pad_Settings( pad, false );
125 
127 
128  // Set the relative pad position
129  // ( pad position for module orient, 0, and relative to the module position)
130 
131  wxPoint pos0 = pad->GetPosition() - aModule->GetPosition();
132  RotatePoint( &pos0, -aModule->GetOrientation() );
133  pad->SetPos0( pos0 );
134 
135  /* NPTH pads take empty pad number (since they can't be connected),
136  * other pads get incremented from the last one edited */
137  wxString padName;
138 
141 
142  pad->SetName( padName );
144 
145  aModule->CalculateBoundingBox();
146  SetMsgPanel( pad );
147 
148  if( draw )
150 }
151 
152 
153 void PCB_BASE_FRAME::DeletePad( D_PAD* aPad, bool aQuery )
154 {
155  if( aPad == NULL )
156  return;
157 
158  MODULE* module = aPad->GetParent();
159  module->SetLastEditTime();
160 
161  // aQuery = true to prompt for confirmation, false to delete silently
162  if( aQuery )
163  {
164  wxString msg = wxString::Format( _( "Delete pad (footprint %s %s)?" ),
165  module->GetReference(),
166  module->GetValue() );
167 
168  if( !IsOK( this, msg ) )
169  return;
170  }
171 
172  // Stores the initial bounding box to refresh the old area
173  EDA_RECT bbox = module->GetBoundingBox();
174 
175  m_Pcb->m_Status_Pcb = 0;
176 
177  GetBoard()->PadDelete( aPad );
178 
179  // Update the bounding box
180  module->CalculateBoundingBox();
181 
182  // Refresh the modified screen area, using the initial bounding box
183  // which is perhaps larger than the new bounding box
184  m_canvas->RefreshDrawingRect( bbox );
185 
186  OnModify();
187 }
188 
189 
190 /*
191  * PCB_EDIT_FRAME::Function PushPadProperties
192  * Function to change pad caracteristics for the given footprint or all identical footprints
193  * Options are set by the opened dialog.
194  */
196 {
197  if( !aPad )
198  return;
199 
200  MODULE* module = aPad->GetParent();
201 
202  if( !module )
203  return;
204 
205  SetMsgPanel( module );
206 
207  DIALOG_PUSH_PAD_PROPERTIES dlg( this );
208  int retCode = dlg.ShowModal();
209 
210  if( retCode == wxID_CANCEL )
211  return;
212 
213  bool edit_Same_Modules = ( retCode == 1 );
214 
215  DoPushPadProperties( aPad, edit_Same_Modules,
219  true );
220 }
221 
222 /*
223  * FOOTPRINT_EDIT_FRAME::Function PushPadProperties
224  * Function to change pad caracteristics for the footprint.
225  * Options are set by the opened dialog.
226  */
228 {
229  if( !aPad )
230  return;
231 
232  MODULE* module = aPad->GetParent();
233 
234  if( !module )
235  return;
236 
237  SetMsgPanel( module );
238 
239  DIALOG_PUSH_PAD_PROPERTIES dlg( this );
240  int retCode = dlg.ShowModal();
241 
242  if( retCode == wxID_CANCEL )
243  return;
244 
245  bool edit_Same_Modules = ( retCode == 1 );
246 
247  DoPushPadProperties( aPad, edit_Same_Modules,
251  false );
252 }
253 
254 /*
255  * Function DoPushPadProperties
256  * Function to change pad properties for the given footprint or all identical footprints
257  * aPad is the pattern. The given footprint is the parent of this pad
258  * aSameFootprints: if true, make changes on all identical footprints
259  * aPadShapeFilter: if true, make changes only on pads having the same shape as aPad
260  * aPadOrientFilter: if true, make changes only on pads having the same orientation as aPad
261  * aPadLayerFilter: if true, make changes only on pads having the same layers as aPad
262  * aSaveForUndo: if true: create an entry in the Undo/Redo list
263  * (usually: true in Schematic editor, false in Module editor)
264  */
265 void PCB_BASE_FRAME::DoPushPadProperties( D_PAD* aPad, bool aSameFootprints,
266  bool aPadShapeFilter,
267  bool aPadOrientFilter,
268  bool aPadLayerFilter,
269  bool aSaveForUndo )
270 {
271  MODULE* Module_Ref = aPad->GetParent();
272  double pad_orient = aPad->GetOrientation() - Module_Ref->GetOrientation();
273 
274  // Prepare an undo list:
275  if( aSaveForUndo )
276  {
277  PICKED_ITEMS_LIST itemsList;
278 
279  if( aSameFootprints )
280  {
281  for( MODULE* module = m_Pcb->m_Modules; module; module = module->Next() )
282  {
283  if( module->GetFPID() == Module_Ref->GetFPID() )
284  {
285  ITEM_PICKER itemWrapper( module, UR_CHANGED );
286  itemsList.PushItem( itemWrapper );
287  }
288  }
289  }
290  else
291  {
292  ITEM_PICKER itemWrapper( Module_Ref, UR_CHANGED );
293  itemsList.PushItem( itemWrapper );
294  }
295 
296  SaveCopyInUndoList( itemsList, UR_CHANGED );
297  }
298 
299  // Update the current module and same others modules if requested.
300  for( MODULE* module = m_Pcb->m_Modules; module; module = module->Next() )
301  {
302  if( !aSameFootprints && (module != Module_Ref) )
303  continue;
304 
305  if( module->GetFPID() != Module_Ref->GetFPID() )
306  continue;
307 
308  // Erase module on screen
309  module->SetFlags( DO_NOT_DRAW );
310  m_canvas->RefreshDrawingRect( module->GetBoundingBox() );
311  module->ClearFlags( DO_NOT_DRAW );
312 
313  for( D_PAD* pad = module->PadsList(); pad; pad = pad->Next() )
314  {
315  if( aPadShapeFilter && ( pad->GetShape() != aPad->GetShape() ) )
316  continue;
317 
318  double currpad_orient = pad->GetOrientation() - module->GetOrientation();
319 
320  if( aPadOrientFilter && ( currpad_orient != pad_orient ) )
321  continue;
322 
323  if( aPadLayerFilter && ( pad->GetLayerSet() != aPad->GetLayerSet() ) )
324  continue;
325 
326  // Do not copy pad to itself, it can create issues with custom pad primitives.
327  if( pad == aPad )
328  continue;
329 
330  pad->ImportSettingsFromMaster( *aPad );
331  }
332 
333  module->CalculateBoundingBox();
334  m_canvas->RefreshDrawingRect( module->GetBoundingBox() );
335  }
336 
337  OnModify();
338 }
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:405
void PadDelete(D_PAD *aPad)
Function PadDelete deletes a given bad from the BOARD by removing it from its module and from the m_N...
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
This file is part of the common library.
void CalculateBoundingBox()
Function CalculateBoundingBox calculates the bounding box in board coordinates.
Class BOARD to handle a board.
MODULE * Next() const
Definition: class_module.h:123
MODULE * GetParent() const
Definition: class_pad.h:162
BOARD * GetBoard() const
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:219
const wxString & GetValue() const
Function GetValue.
Definition: class_module.h:497
virtual void RefreshDrawingRect(const EDA_RECT &aRect, bool aEraseBackground=true)
Function RefreshDrawingRect redraws the contents of aRect in drawing units.
void PushItem(const ITEM_PICKER &aItem)
Function PushItem pushes aItem to the top of the list.
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:216
Definition of class FOOTPRINT_EDIT_FRAME.
This file contains miscellaneous commonly used macros and functions.
void DeletePad(D_PAD *aPad, bool aQuery=true)
Function DeletePad Delete the pad aPad.
void PushBack(T *aNewElement)
Function PushBack puts aNewElement at the end of the list sequence.
Definition: dlist.h:250
Classes used in Pcbnew, CvPcb and GerbView.
void Export_Pad_Settings(D_PAD *aPad)
const LIB_ID & GetFPID() const
Definition: class_module.h:193
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:256
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
void SetName(const wxString &aName)
Set the pad name (sometimes called pad number, although it can be an array reference like AA12)...
Definition: class_pad.h:182
double GetOrientation() const
Definition: class_module.h:189
void SetPos0(const wxPoint &aPos)
Definition: class_pad.h:262
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:402
void SetLastEditTime(timestamp_t aTime)
Definition: class_module.h:314
D_PAD * Next() const
Definition: class_pad.h:160
const wxString & GetName() const
Definition: class_pad.h:190
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame...
void AddPad(MODULE *Module, bool draw)
void ImportSettingsFromMaster(const D_PAD &aMasterPad)
Imports the pad settings from aMasterPad.
Definition: class_pad.cpp:1399
Class PICKED_ITEMS_LIST is a holder to handle information on schematic or board items.
Pad object description.
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:123
virtual void OnModify()
Function OnModify Virtual Must be called after a change in order to set the "modify" flag of the curr...
void PushPadProperties(D_PAD *aPad)
Change pad characteristics for the given footprint or all footprints which look like the given footpr...
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:463
DLIST< MODULE > m_Modules
Definition: class_board.h:248
void DoPushPadProperties(D_PAD *aPad, bool aSameFootprints, bool aPadShapeFilter, bool aPadOrientFilter, bool aPadLayerFilter, bool aSaveForUndo)
Function DoPushPadProperties Function to change pad settings for the given footprint or all identical...
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:382
D_PAD m_Pad_Master
A dummy pad to store all default parameters.
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
virtual void SaveCopyInUndoList(BOARD_ITEM *aItemToCopy, UNDO_REDO_T aTypeCommand, const wxPoint &aTransformPoint=wxPoint(0, 0))=0
Function SaveCopyInUndoList (virtual pure) Creates a new entry in undo list of commands.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:257
void PushPadProperties(D_PAD *aPad)
Function PushPadProperties Function to change pad caracteristics for the given footprint or all footp...
DLIST< D_PAD > & PadsList()
Definition: class_module.h:163
Module description (excepted pads)
const wxPoint GetPosition() const override
Definition: class_pad.h:220
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Return the current cross hair position in logical (drawing) coordinates.
static wxString GetNextPadName(wxString aPadName)
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Function IsOK displays a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:295
const wxPoint GetPosition() const override
Definition: class_module.h:184
void Import_Pad_Settings(D_PAD *aPad, bool aDraw)
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Definition: class_pad.cpp:216
#define DO_NOT_DRAW
Used to disable draw function.
Definition: base_struct.h:126
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:240