KiCad PCB EDA Suite
lib_pin_tool.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) 2019 CERN
5  * Copyright (C) 2019 KiCad Developers, see AUTHORS.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 
25 #include <tool/tool_manager.h>
27 #include <lib_edit_frame.h>
28 #include <confirm.h>
29 #include <ee_actions.h>
33 #include <pgm_base.h>
34 #include "lib_pin_tool.h"
35 
36 
40 static bool g_LastPinCommonConvert = false;
41 static bool g_LastPinCommonUnit = false;
42 static bool g_LastPinVisible = true;
43 
44 // The -1 is a non-valid value to trigger delayed initialization
45 static int g_LastPinLength = -1;
46 static int g_LastPinNameSize = -1;
47 static int g_LastPinNumSize = -1;
48 
49 static int GetLastPinLength()
50 {
51  if( g_LastPinLength == -1 )
52  {
53  LIBEDIT_SETTINGS* settings = Pgm().GetSettingsManager().GetAppSettings<LIBEDIT_SETTINGS>();
54  g_LastPinLength = Mils2iu( settings->m_Defaults.pin_length );
55  }
56 
57  return g_LastPinLength;
58 }
59 
60 static int GetLastPinNameSize()
61 {
62  if( g_LastPinNameSize == -1 )
63  {
64  LIBEDIT_SETTINGS* settings = Pgm().GetSettingsManager().GetAppSettings<LIBEDIT_SETTINGS>();
65  g_LastPinNameSize = Mils2iu( settings->m_Defaults.pin_name_size );
66  }
67 
68  return g_LastPinNameSize;
69 }
70 
71 static int GetLastPinNumSize()
72 {
73  if( g_LastPinNumSize == -1 )
74  {
75  LIBEDIT_SETTINGS* settings = Pgm().GetSettingsManager().GetAppSettings<LIBEDIT_SETTINGS>();
76  g_LastPinNumSize = Mils2iu( settings->m_Defaults.pin_num_size );
77  }
78 
79  return g_LastPinNumSize;
80 }
81 
82 
83 extern void IncrementLabelMember( wxString& name, int aIncrement );
84 
85 
87  EE_TOOL_BASE<LIB_EDIT_FRAME>( "eeschema.PinEditing" )
88 {
89 }
90 
91 
93 {
95 
96  auto singlePinCondition = EE_CONDITIONS::Count( 1 ) && EE_CONDITIONS::OnlyType( LIB_PIN_T );
97 
99 
100  selToolMenu.AddSeparator( 400 );
101  selToolMenu.AddItem( EE_ACTIONS::pushPinLength, singlePinCondition, 400 );
102  selToolMenu.AddItem( EE_ACTIONS::pushPinNameSize, singlePinCondition, 400 );
103  selToolMenu.AddItem( EE_ACTIONS::pushPinNumSize, singlePinCondition, 400 );
104 
105  return true;
106 }
107 
108 
110 {
111  aPin->EnableEditMode( true, !m_frame->SynchronizePins() );
112 
113  DIALOG_LIB_EDIT_PIN dlg( m_frame, aPin );
114 
115  if( dlg.ShowModal() == wxID_CANCEL )
116  {
117  return false;
118  }
119 
120  m_frame->RefreshItem( aPin );
121  m_frame->OnModify( );
122 
123  MSG_PANEL_ITEMS items;
124  aPin->GetMsgPanelInfo( m_frame, items );
125  m_frame->SetMsgPanel( items );
126 
127  aPin->EnableEditMode( false );
128 
129  // Save the pin properties to use for the next new pin.
133  g_LastPinLength = aPin->GetLength();
134  g_LastPinShape = aPin->GetShape();
135  g_LastPinType = aPin->GetType();
136  g_LastPinCommonConvert = aPin->GetConvert() == 0;
137  g_LastPinCommonUnit = aPin->GetUnit() == 0;
138  g_LastPinVisible = aPin->IsVisible();
139 
140  return true;
141 }
142 
143 
145 {
146  LIB_PART* part = m_frame->GetCurPart();
147  bool ask_for_pin = true; // Test for another pin in same position in other units
148 
149  for( LIB_PIN* test = part->GetNextPin(); test; test = part->GetNextPin( test ) )
150  {
151  if( test == aPin || aPin->GetPosition() != test->GetPosition() || test->GetEditFlags() )
152  continue;
153 
154  // test for same body style
155  if( test->GetConvert() && test->GetConvert() != aPin->GetConvert() )
156  continue;
157 
158  if( ask_for_pin && m_frame->SynchronizePins() )
159  {
160  wxString msg;
161  msg.Printf( _( "This position is already occupied by another pin, in unit %d." ),
162  test->GetUnit() );
163 
164  KIDIALOG dlg( m_frame, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
165  dlg.SetOKLabel( _( "Place Pin Anyway" ) );
166  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
167 
168  bool status = dlg.ShowModal() == wxID_OK;
169 
170  if( !status )
171  {
172  if( aPin->IsNew() )
173  delete aPin;
174 
175  return false;
176  }
177  else
178  {
179  ask_for_pin = false;
180  }
181  }
182  }
183 
184  if( aPin->IsNew() && !aPin->HasFlag( IS_PASTED ) )
185  {
187  g_LastPinType = aPin->GetType();
188  g_LastPinShape = aPin->GetShape();
189 
190  if( m_frame->SynchronizePins() )
191  CreateImagePins( aPin );
192 
193  part->AddDrawItem( aPin );
194  aPin->ClearFlags( IS_NEW );
195  }
196 
197  // Put linked pins in new position, and clear flags
198  for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
199  {
200  if( ( pin->GetEditFlags() & IS_LINKED ) == 0 )
201  continue;
202 
203  pin->MoveTo( aPin->GetPosition() );
204  pin->ClearFlags();
205  }
206 
207  m_frame->RebuildView();
208  m_frame->OnModify();
209 
210  return true;
211 }
212 
213 
214 /*
215  * Create a new pin.
216  */
217 LIB_PIN* LIB_PIN_TOOL::CreatePin( const VECTOR2I& aPosition, LIB_PART* aPart )
218 {
219  aPart->ClearTempFlags();
220 
221  LIB_PIN* pin = new LIB_PIN( aPart );
222 
223  pin->SetFlags( IS_NEW );
224 
225  // Flag pins to consider
226  if( m_frame->SynchronizePins() )
227  pin->SetFlags( IS_LINKED );
228 
229  pin->MoveTo((wxPoint) aPosition );
230  pin->SetLength( GetLastPinLength() );
232  pin->SetType( g_LastPinType );
233  pin->SetShape( g_LastPinShape );
237  pin->SetUnit( g_LastPinCommonUnit ? 0 : m_frame->GetUnit() );
239 
240  if( !EditPinProperties( pin ) )
241  {
242  delete pin;
243  pin = nullptr;
244  }
245 
246  return pin;
247 }
248 
249 
251 {
252  int ii;
253  LIB_PIN* newPin;
254 
255  // if "synchronize pins editing" option is off, do not create any similar pin for other
256  // units and/or shapes: each unit is edited regardless other units or body
257  if( !m_frame->SynchronizePins() )
258  return;
259 
260  if( aPin->GetUnit() == 0 ) // Pin common to all units: no need to create similar pins.
261  return;
262 
263  // When units are interchangeable, all units are expected to have similar pins
264  // at the same position
265  // to facilitate pin editing, create pins for all other units for the current body style
266  // at the same position as aPin
267 
268  for( ii = 1; ii <= aPin->GetParent()->GetUnitCount(); ii++ )
269  {
270  if( ii == aPin->GetUnit() )
271  continue;
272 
273  newPin = (LIB_PIN*) aPin->Clone();
274 
275  // To avoid mistakes, gives this pin a new pin number because
276  // it does no have the save pin number as the master pin
277  // Because we do not know the actual number, give it a temporary number
278  wxString unknownNum;
279  unknownNum.Printf( "%s-U%c", aPin->GetNumber(), wxChar( 'A' + ii - 1 ) );
280  newPin->SetNumber( unknownNum );
281 
282  newPin->SetUnit( ii );
283  aPin->GetParent()->AddDrawItem( newPin );
284  }
285 }
286 
287 
289 {
290  LIB_PART* part = m_frame->GetCurPart();
291  EE_SELECTION& selection = m_selectionTool->GetSelection();
292  LIB_PIN* sourcePin = dynamic_cast<LIB_PIN*>( selection.Front() );
293 
294  if( !sourcePin )
295  return 0;
296 
298 
299  for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
300  {
301  if( pin->GetConvert() && pin->GetConvert() != m_frame->GetConvert() )
302  continue;
303 
304  if( pin == sourcePin )
305  continue;
306 
307  if( aEvent.IsAction( &EE_ACTIONS::pushPinLength ) )
308  pin->SetLength( sourcePin->GetLength() );
309  else if( aEvent.IsAction( &EE_ACTIONS::pushPinNameSize ) )
310  pin->SetNameTextSize( sourcePin->GetNameTextSize() );
311  else if( aEvent.IsAction( &EE_ACTIONS::pushPinNumSize ) )
312  pin->SetNumberTextSize( sourcePin->GetNumberTextSize() );
313  }
314 
315  m_frame->RebuildView();
316  m_frame->OnModify();
317 
318  return 0;
319 }
320 
321 
322 // Create a new pin based on the previous pin with an incremented pin number.
324 {
325  LIB_PIN* pin = (LIB_PIN*) aSourcePin->Clone();
326  wxPoint step;
327 
328  pin->ClearFlags();
329  pin->SetFlags( IS_NEW );
330 
331  LIBEDIT_SETTINGS* settings = Pgm().GetSettingsManager().GetAppSettings<LIBEDIT_SETTINGS>();
332 
333  switch( pin->GetOrientation() )
334  {
335  case PIN_UP: step.x = settings->m_Repeat.pin_step; break;
336  case PIN_DOWN: step.x = settings->m_Repeat.pin_step; break;
337  case PIN_LEFT: step.y = -settings->m_Repeat.pin_step; break;
338  case PIN_RIGHT: step.y = -settings->m_Repeat.pin_step; break;
339  }
340 
341  pin->Offset( step );
342 
343  wxString nextName = pin->GetName();
344  IncrementLabelMember( nextName, settings->m_Repeat.label_delta );
345  pin->SetName( nextName );
346 
347  wxString nextNumber = pin->GetNumber();
348  IncrementLabelMember( nextNumber, settings->m_Repeat.label_delta );
349  pin->SetNumber( nextNumber );
350 
351  if( m_frame->SynchronizePins() )
352  pin->SetFlags( IS_LINKED );
353 
354  if( PlacePin( pin ) )
355  return pin;
356 
357  return nullptr;
358 }
359 
360 
362 {
366 }
367 
#define IS_LINKED
Used in calculation to mark linked items (temporary use)
Definition: base_struct.h:114
void SetLength(int aLength, bool aTestOtherPins=true)
Set the pin length.
Definition: lib_pin.cpp:380
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: lib_pin.cpp:1266
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox
Definition: confirm.cpp:53
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:104
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
int GetConvert() const
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:44
This file is part of the common library.
int GetOrientation() const
Definition: lib_pin.h:206
static bool g_LastPinCommonConvert
LIB_PART * GetParent() const
Definition: lib_item.h:182
void SetShape(GRAPHIC_PINSHAPE aShape)
Set the shape of the pin to aShape.
Definition: lib_pin.cpp:325
GRAPHIC_PINSHAPE GetShape() const
Definition: lib_pin.h:218
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:46
void SetName(const wxString &aName, bool aTestOtherPins=true)
Set the pin name.
Definition: lib_pin.cpp:188
Implementing DIALOG_LIB_EDIT_PIN_BASE.
TOOL_MENU & GetToolMenu()
static int GetLastPinLength()
static int g_LastPinNameSize
static int g_LastPinNumSize
LIB_PART * GetCurPart()
Return the current part being edited or NULL if none selected.
Definition: lib_pin.h:58
void EnableEditMode(bool aEnable, bool aEditPinByPin=false)
Enable or clear pin editing mode.
Definition: lib_pin.cpp:531
static SELECTION_CONDITION Count(int aNumber)
Function Count Creates a functor that tests if the number of selected items is equal to the value giv...
static TOOL_ACTION pushPinNameSize
Definition: ee_actions.h:188
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
void ClearTempFlags()
Clears the status flag all draw objects in this part.
bool IsAction(const TOOL_ACTION *aAction) const
Function IsAction() Tests if the event contains an action issued upon activation of the given TOOL_AC...
Definition: tool_event.cpp:67
bool IsNew() const
Definition: base_struct.h:199
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
Definition: ee_tool_base.h:69
void AddDrawItem(LIB_ITEM *aItem)
Add a new draw aItem to the draw object list.
EE_SELECTION & GetSelection()
Function GetSelection()
#define IS_NEW
New item, just created.
Definition: base_struct.h:117
void SetNumber(const wxString &aNumber)
Set the pin number.
Definition: lib_pin.cpp:249
int GetUnit() const
Definition: lib_item.h:295
GRAPHIC_PINSHAPE
Definition: pin_shape.h:35
static int g_LastPinOrient
int GetUnit() const
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:232
static int g_LastPinLength
int GetUnitCount() const override
For items with units, return the number of units.
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
const wxString & GetName() const
Definition: lib_pin.h:151
TOOL_EVENT.
Definition: tool_event.h:171
bool EditPinProperties(LIB_PIN *aPin)
Define a library symbol object.
void SetVisible(bool aVisible)
Set or clear the visibility flag for the pin.
Definition: lib_pin.cpp:498
static TOOL_ACTION pushPinLength
Definition: ee_actions.h:187
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:153
void IncrementLabelMember(wxString &name, int aIncrement)
Definition: sch_text.cpp:55
bool IsVisible() const
Return the visibility status of the draw object.
Definition: lib_pin.h:345
int GetNameTextSize() const
Definition: lib_pin.h:177
const wxPoint GetPosition() const override
Definition: lib_pin.h:430
int GetConvert() const
Definition: lib_item.h:298
LIB_PIN * RepeatPin(const LIB_PIN *aSourcePin)
static int GetLastPinNameSize()
void CreateImagePins(LIB_PIN *aPin)
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
void AddSeparator(int aOrder=ANY_ORDER)
Function AddSeparator()
void SetConvert(int aConvert)
Definition: lib_item.h:297
static GRAPHIC_PINSHAPE g_LastPinShape
LIB_PIN * GetNextPin(LIB_PIN *aItem=NULL)
Return the next pin object from the draw list.
const wxString & GetNumber() const
Definition: lib_pin.h:179
ELECTRICAL_PINTYPE GetType() const
Get the electrical type of the pin.
Definition: lib_pin.h:234
void SetUnit(int aUnit)
Definition: lib_item.h:294
void MoveTo(const wxPoint &aPosition) override
Move a draw object to aPosition.
Definition: lib_pin.cpp:1333
static int GetLastPinNumSize()
int GetNumberTextSize() const
Definition: lib_pin.h:204
The symbol library editor main window.
see class PGM_BASE
const char * name
Definition: DXF_plotter.cpp:60
ELECTRICAL_PINTYPE
The component library pin object electrical types used in ERC tests.
Definition: pin_type.h:37
void RefreshItem(EDA_ITEM *aItem, bool isAddOrDelete=false)
Mark an item for refresh.
#define _(s)
Definition: 3d_actions.cpp:33
usual pin input: must be connected
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Function OnlyType Creates a functor that tests if the selected items are only of given type.
void SetType(ELECTRICAL_PINTYPE aType, bool aTestOtherPins=true)
Set the electrical type of the pin.
Definition: lib_pin.cpp:352
void saveCopyInUndoList(EDA_ITEM *aItem, UNDO_REDO_T aType, bool aAppend=false)
Similar to m_frame->SaveCopyInUndoList(), but handles items that are owned by their parents.
Definition: ee_tool_base.h:117
int PushPinProperties(const TOOL_EVENT &aEvent)
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current symbol.
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:102
void setTransitions() override
Sets up handlers for various events.
int ShowModal() override
Definition: confirm.cpp:95
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:233
static TOOL_ACTION pushPinNumSize
Definition: ee_actions.h:189
void SetOrientation(int aOrientation, bool aTestOtherPins=true)
Set orientation on the pin.
Definition: lib_pin.cpp:296
EE_TOOL_BASE.
Definition: ee_tool_base.h:50
bool HasFlag(STATUS_FLAGS aFlag)
Definition: base_struct.h:235
LIB_PIN * CreatePin(const VECTOR2I &aPosition, LIB_PART *aPart)
void SetNameTextSize(int aSize, bool aTestOtherPins=true)
Set the aSize of the pin name text.
Definition: lib_pin.cpp:221
void Offset(const wxPoint &aOffset) override
Set the drawing object by aOffset from the current position.
Definition: lib_pin.cpp:1327
int GetLength()
Definition: lib_pin.h:284
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Function AddItem()
bool PlacePin(LIB_PIN *aPin)
static ELECTRICAL_PINTYPE g_LastPinType
static bool g_LastPinCommonUnit
#define IS_PASTED
Modifier on IS_NEW which indicates it came from clipboard.
Definition: base_struct.h:130
EDA_ITEM * Front() const
Definition: selection.h:184
void SetNumberTextSize(int aSize, bool aTestOtherPins=true)
Set the size of the pin number text.
Definition: lib_pin.cpp:268
static bool g_LastPinVisible