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 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <tool/tool_manager.h>
26 #include <lib_edit_frame.h>
27 #include <eeschema_id.h>
28 #include <confirm.h>
29 #include <ee_actions.h>
30 #include <sch_view.h>
33 #include "lib_pin_tool.h"
34 
35 
36 TOOL_ACTION EE_ACTIONS::pushPinLength( "libedit.PinEditing.pushPinLength",
37  AS_GLOBAL, 0, _( "Push Pin Length" ), _( "Copy pin length to other pins in symbol" ),
38  pin_size_to_xpm );
39 
40 TOOL_ACTION EE_ACTIONS::pushPinNameSize( "libedit.PinEditing.pushPinNameSize",
41  AS_GLOBAL, 0, _( "Push Pin Name Size" ), _( "Copy pin name size to other pins in symbol" ),
42  pin_size_to_xpm );
43 
44 TOOL_ACTION EE_ACTIONS::pushPinNumSize( "libedit.PinEditing.pushPinNumSize",
45  AS_GLOBAL, 0, _( "Push Pin Number Size" ), _( "Copy pin number size to other pins in symbol" ),
46  pin_size_to_xpm );
47 
48 
52 static bool g_LastPinCommonConvert = false;
53 static bool g_LastPinCommonUnit = false;
54 static bool g_LastPinVisible = true;
55 
56 // The -1 is a non-valid value to trigger delayed initialization
57 static int g_LastPinLength = -1;
58 static int g_LastPinNameSize = -1;
59 static int g_LastPinNumSize = -1;
60 
61 static int GetLastPinLength()
62 {
63  if( g_LastPinLength == -1 )
65 
66  return g_LastPinLength;
67 }
68 
69 static int GetLastPinNameSize()
70 {
71  if( g_LastPinNameSize == -1 )
73 
74  return g_LastPinNameSize;
75 }
76 
77 static int GetLastPinNumSize()
78 {
79  if( g_LastPinNumSize == -1 )
81 
82  return g_LastPinNumSize;
83 }
84 
85 
86 extern void IncrementLabelMember( wxString& name, int aIncrement );
87 
88 
90  EE_TOOL_BASE<LIB_EDIT_FRAME>( "eeschema.PinEditing" )
91 {
92 }
93 
94 
96 {
97 }
98 
99 
101 {
103 
104  auto singlePinCondition = EE_CONDITIONS::Count( 1 ) && EE_CONDITIONS::OnlyType( LIB_PIN_T );
105 
107 
108  selToolMenu.AddSeparator( singlePinCondition, 400 );
109  selToolMenu.AddItem( EE_ACTIONS::pushPinLength, singlePinCondition, 400 );
110  selToolMenu.AddItem( EE_ACTIONS::pushPinNameSize, singlePinCondition, 400 );
111  selToolMenu.AddItem( EE_ACTIONS::pushPinNumSize, singlePinCondition, 400 );
112 
113  return true;
114 }
115 
116 
118 {
119  aPin->EnableEditMode( true, !m_frame->SynchronizePins() );
120 
121  DIALOG_LIB_EDIT_PIN dlg( m_frame, aPin );
122 
123  if( dlg.ShowModal() == wxID_CANCEL )
124  {
125  return false;
126  }
127 
128  m_frame->RefreshItem( aPin );
129  m_frame->OnModify( );
130 
131  MSG_PANEL_ITEMS items;
132  aPin->GetMsgPanelInfo( m_frame->GetUserUnits(), items );
133  m_frame->SetMsgPanel( items );
134 
135  aPin->EnableEditMode( false );
136 
137  // Save the pin properties to use for the next new pin.
141  g_LastPinLength = aPin->GetLength();
142  g_LastPinShape = aPin->GetShape();
143  g_LastPinType = aPin->GetType();
144  g_LastPinCommonConvert = aPin->GetConvert() == 0;
145  g_LastPinCommonUnit = aPin->GetUnit() == 0;
146  g_LastPinVisible = aPin->IsVisible();
147 
148  return true;
149 }
150 
151 
153 {
154  LIB_PART* part = m_frame->GetCurPart();
155  bool ask_for_pin = true; // Test for another pin in same position in other units
156 
157  for( LIB_PIN* test = part->GetNextPin(); test; test = part->GetNextPin( test ) )
158  {
159  if( test == aPin || aPin->GetPosition() != test->GetPosition() || test->GetEditFlags() )
160  continue;
161 
162  // test for same body style
163  if( test->GetConvert() && test->GetConvert() != aPin->GetConvert() )
164  continue;
165 
166  if( ask_for_pin && m_frame->SynchronizePins() )
167  {
169  wxString msg;
170  msg.Printf( _( "This position is already occupied by another pin, in unit %d." ),
171  test->GetUnit() );
172 
173  KIDIALOG dlg( m_frame, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
174  dlg.SetOKLabel( _( "Create Pin Anyway" ) );
175  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
176 
177  bool status = dlg.ShowModal() == wxID_OK;
178 
181 
182  if( !status )
183  {
184  if( aPin->IsNew() )
185  delete aPin;
186 
187  return false;
188  }
189  else
190  {
191  ask_for_pin = false;
192  }
193  }
194  }
195 
196  if( aPin->IsNew() )
197  {
199  g_LastPinType = aPin->GetType();
200  g_LastPinShape = aPin->GetShape();
201 
202  if( m_frame->SynchronizePins() )
203  CreateImagePins( aPin );
204 
205  part->AddDrawItem( aPin );
206  }
207 
208  // Put linked pins in new position, and clear flags
209  for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
210  {
211  if( pin->GetEditFlags() == 0 )
212  continue;
213 
214  pin->MoveTo( aPin->GetPosition() );
215  pin->ClearFlags();
216  }
217 
218  m_frame->RebuildView();
219  m_frame->OnModify();
220 
221  return true;
222 }
223 
224 
225 /*
226  * Create a new pin.
227  */
228 LIB_PIN* LIB_PIN_TOOL::CreatePin( const VECTOR2I& aPosition, LIB_PART* aPart )
229 {
230  aPart->ClearTempFlags();
231 
232  LIB_PIN* pin = new LIB_PIN( aPart );
233 
234  pin->SetFlags( IS_NEW );
235 
236  // Flag pins to consider
237  if( m_frame->SynchronizePins() )
238  pin->SetFlags( IS_LINKED );
239 
240  pin->MoveTo((wxPoint) aPosition );
241  pin->SetLength( GetLastPinLength() );
243  pin->SetType( g_LastPinType );
244  pin->SetShape( g_LastPinShape );
248  pin->SetUnit( g_LastPinCommonUnit ? 0 : m_frame->GetUnit() );
250 
251  if( !EditPinProperties( pin ) )
252  {
253  delete pin;
254  pin = nullptr;
255  }
256 
257  return pin;
258 }
259 
260 
262 {
263  int ii;
264  LIB_PIN* newPin;
265 
266  // if "synchronize pins editing" option is off, do not create any similar pin for other
267  // units and/or shapes: each unit is edited regardless other units or body
268  if( !m_frame->SynchronizePins() )
269  return;
270 
271  if( aPin->GetUnit() == 0 ) // Pin common to all units: no need to create similar pins.
272  return;
273 
274  // When units are interchangeable, all units are expected to have similar pins
275  // at the same position
276  // to facilitate pin editing, create pins for all other units for the current body style
277  // at the same position as aPin
278 
279  for( ii = 1; ii <= aPin->GetParent()->GetUnitCount(); ii++ )
280  {
281  if( ii == aPin->GetUnit() )
282  continue;
283 
284  newPin = (LIB_PIN*) aPin->Clone();
285 
286  // To avoid mistakes, gives this pin a new pin number because
287  // it does no have the save pin number as the master pin
288  // Because we do not know the actual number, give it a temporary number
289  wxString unknownNum;
290  unknownNum.Printf( "%s-U%c", aPin->GetNumber(), wxChar( 'A' + ii - 1 ) );
291  newPin->SetNumber( unknownNum );
292 
293  newPin->SetUnit( ii );
294  aPin->GetParent()->AddDrawItem( newPin );
295  }
296 }
297 
298 
300 {
301  LIB_PART* part = m_frame->GetCurPart();
302  SELECTION& selection = m_selectionTool->GetSelection();
303  LIB_PIN* sourcePin = dynamic_cast<LIB_PIN*>( selection.Front() );
304 
305  if( !sourcePin )
306  return 0;
307 
309 
310  for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
311  {
312  if( pin->GetConvert() && pin->GetConvert() != m_frame->GetConvert() )
313  continue;
314 
315  if( pin == sourcePin )
316  continue;
317 
318  if( aEvent.IsAction( &EE_ACTIONS::pushPinLength ) )
319  pin->SetLength( sourcePin->GetLength() );
320  else if( aEvent.IsAction( &EE_ACTIONS::pushPinNameSize ) )
321  pin->SetNameTextSize( sourcePin->GetNameTextSize() );
322  else if( aEvent.IsAction( &EE_ACTIONS::pushPinNumSize ) )
323  pin->SetNumberTextSize( sourcePin->GetNumberTextSize() );
324  }
325 
326  m_frame->RebuildView();
327  m_frame->OnModify();
328 
329  return 0;
330 }
331 
332 
333 // Create a new pin based on the previous pin with an incremented pin number.
335 {
336  LIB_PIN* pin = (LIB_PIN*) aSourcePin->Clone();
337  wxPoint step;
338 
339  pin->ClearFlags();
340  pin->SetFlags( IS_NEW );
341 
342  switch( pin->GetOrientation() )
343  {
344  case PIN_UP: step.x = m_frame->GetRepeatPinStep(); break;
345  case PIN_DOWN: step.x = m_frame->GetRepeatPinStep(); break;
346  case PIN_LEFT: step.y = -m_frame->GetRepeatPinStep(); break;
347  case PIN_RIGHT: step.y = -m_frame->GetRepeatPinStep(); break;
348  }
349 
350  pin->Offset( step );
351 
352  wxString nextName = pin->GetName();
354  pin->SetName( nextName );
355 
356  wxString nextNumber = pin->GetNumber();
358  pin->SetNumber( nextNumber );
359 
360  if( m_frame->SynchronizePins() )
361  pin->SetFlags( IS_LINKED );
362 
363  PlacePin( pin );
364 
365  return pin;
366 }
367 
368 
370 {
374 }
375 
#define IS_LINKED
Used in calculation to mark linked items (temporary use)
Definition: base_struct.h:111
SELECTION & GetSelection()
Function GetSelection()
LIB_PART * GetCurPart() const
Return the current part being edited or NULL if none selected.
int GetUnitCount() const
void SetLength(int aLength, bool aTestOtherPins=true)
Set the pin length.
Definition: lib_pin.cpp:364
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: lib_pin.cpp:1287
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox
Definition: confirm.cpp:61
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:44
TOOL_MENU & GetToolMenu()
This file is part of the common library.
int GetOrientation() const
Definition: lib_pin.h:205
static bool g_LastPinCommonConvert
LIB_PART * GetParent() const
void AddSeparator(const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddSeparator()
void SetShape(GRAPHIC_PINSHAPE aShape)
Set the shape of the pin to aShape.
Definition: lib_pin.cpp:299
GRAPHIC_PINSHAPE GetShape() const
Definition: lib_pin.h:219
virtual void MoveCursorToCrossHair() override
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:46
static int GetDefaultPinLength()
void SetName(const wxString &aName, bool aTestOtherPins=true)
Set the pin name.
Definition: lib_pin.cpp:162
Implementing DIALOG_LIB_EDIT_PIN_BASE.
static int GetLastPinLength()
static int g_LastPinNameSize
static int g_LastPinNumSize
Definition: lib_pin.h:55
void EnableEditMode(bool aEnable, bool aEditPinByPin=false)
Enable or clear pin editing mode.
Definition: lib_pin.cpp:515
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:171
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:54
bool IsNew() const
Definition: base_struct.h:222
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.
#define IS_NEW
New item, just created.
Definition: base_struct.h:114
void SetNumber(const wxString &aNumber)
Set the pin number.
Definition: lib_pin.cpp:223
static int GetPinNumDefaultSize()
int GetUnit() const
GRAPHIC_PINSHAPE
Definition: pin_shape.h:35
static int g_LastPinOrient
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:259
static int g_LastPinLength
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:150
EDA_UNITS_T GetUserUnits() const override
Return the user units currently in use.
Definition: draw_frame.h:289
SCH_DRAW_PANEL * GetCanvas() const override
Class TOOL_EVENT.
Definition: tool_event.h:167
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:482
static TOOL_ACTION pushPinLength
Definition: ee_actions.h:170
EE_SELECTION_TOOL * m_selectionTool
Definition: ee_tool_base.h:143
void IncrementLabelMember(wxString &name, int aIncrement)
Definition: edit_label.cpp:167
void GetMsgPanelInfo(EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
bool IsVisible() const
Return the visibility status of the draw object.
Definition: lib_pin.h:346
int GetNameTextSize() const
Definition: lib_pin.h:176
All active tools
Definition: tool_event.h:143
int GetConvert() const
LIB_PIN * RepeatPin(const LIB_PIN *aSourcePin)
static int GetLastPinNameSize()
void CreateImagePins(LIB_PIN *aPin)
void SetConvert(int aConvert)
wxPoint GetPosition() const override
Return the current draw object position.
Definition: lib_pin.h:432
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:178
ELECTRICAL_PINTYPE GetType() const
Get the electrical type of the pin.
Definition: lib_pin.h:235
void SetUnit(int aUnit)
void MoveTo(const wxPoint &aPosition) override
Move a draw object to aPosition.
Definition: lib_pin.cpp:1331
static int GetLastPinNumSize()
int GetNumberTextSize() const
Definition: lib_pin.h:203
The symbol library editor main window.
const char * name
Definition: DXF_plotter.cpp:61
static int GetPinNameDefaultSize()
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.
Class TOOL_ACTION.
Definition: tool_action.h:46
void SetIgnoreMouseEvents(bool aIgnore)
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:328
int GetRepeatDeltaLabel() const
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:120
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:103
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:260
bool SynchronizePins()
Pin editing (add, delete, move...) can be synchronized between units when units are interchangeable b...
static TOOL_ACTION pushPinNumSize
Definition: ee_actions.h:172
void SetOrientation(int aOrientation, bool aTestOtherPins=true)
Set orientation on the pin.
Definition: lib_pin.cpp:270
Class EE_TOOL_BASE.
Definition: ee_tool_base.h:49
LIB_PIN * CreatePin(const VECTOR2I &aPosition, LIB_PART *aPart)
int GetRepeatPinStep() const
void SetNameTextSize(int aSize, bool aTestOtherPins=true)
Set the aSize of the pin name text.
Definition: lib_pin.cpp:195
void Offset(const wxPoint &aOffset) override
Set the drawing object by aOffset from the current position.
Definition: lib_pin.cpp:1317
int GetLength()
Definition: lib_pin.h:285
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
EDA_ITEM * Front() const
Definition: selection.h:155
void SetNumberTextSize(int aSize, bool aTestOtherPins=true)
Set the size of the pin number text.
Definition: lib_pin.cpp:242
static bool g_LastPinVisible