KiCad PCB EDA Suite
footprint_editor_utils.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) 1992-2020 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 <confirm.h>
26 #include <footprint_edit_frame.h>
27 #include <footprint_tree_pane.h>
28 #include <fp_lib_table.h>
29 #include <functional>
30 #include <kiway_express.h>
31 #include <pcb_layer_box_selector.h>
32 #include <pcbnew_id.h>
33 #include <ratsnest/ratsnest_data.h>
35 #include <tool/tool_manager.h>
36 #include <tools/pcb_actions.h>
38 #include <widgets/lib_tree.h>
39 
40 using namespace std::placeholders;
41 
42 
43 void FOOTPRINT_EDIT_FRAME::LoadFootprintFromBoard( wxCommandEvent& event )
44 {
45  LoadFootprintFromBoard( NULL );
46 }
47 
48 
50 {
51  bool is_last_fp_from_brd = IsCurrentFPFromBoard();
52 
53  FOOTPRINT* footprint = LoadFootprint( aFPID );
54 
55  if( !footprint )
56  return;
57 
58  if( !Clear_Pcb( true ) )
59  return;
60 
61  GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false );
62  AddFootprintToBoard( footprint );
63 
64  footprint->ClearFlags();
65 
66  // if either m_Reference or m_Value are gone, reinstall them -
67  // otherwise you cannot see what you are doing on board
68  FP_TEXT* ref = &footprint->Reference();
69  FP_TEXT* val = &footprint->Value();
70 
71  if( val && ref )
72  {
73  ref->SetType( FP_TEXT::TEXT_is_REFERENCE ); // just in case ...
74 
75  if( ref->GetLength() == 0 )
76  ref->SetText( wxT( "Ref**" ) );
77 
78  val->SetType( FP_TEXT::TEXT_is_VALUE ); // just in case ...
79 
80  if( val->GetLength() == 0 )
81  val->SetText( wxT( "Val**" ) );
82  }
83 
84  if( m_zoomSelectBox->GetSelection() == 0 )
85  Zoom_Automatique( false );
86 
87  Update3DView( true, true );
88 
89  GetScreen()->ClrModify();
90 
91  UpdateView();
92  GetCanvas()->Refresh();
93 
94  // Update the save items if needed.
95  if( is_last_fp_from_brd )
96  {
97  ReCreateMenuBar();
98  ReCreateHToolbar();
99  }
100 
101  m_treePane->GetLibTree()->ExpandLibId( aFPID );
102  m_treePane->GetLibTree()->CenterLibId( aFPID );
103  m_treePane->GetLibTree()->RefreshLibTree(); // update highlighting
104 }
105 
106 
107 void FOOTPRINT_EDIT_FRAME::SelectLayer( wxCommandEvent& event )
108 {
109  SetActiveLayer( ToLAYER_ID( m_selLayerBox->GetLayerSelection() ) );
110 
111  if( GetDisplayOptions().m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL )
112  GetCanvas()->Refresh();
113 }
114 
115 
116 void FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( wxCommandEvent& event )
117 {
118  SaveFootprintToBoard( true );
119 }
120 
121 
123 {
124 public:
126  {
127  m_nickname = aFootprint->GetFPID().GetLibNickname().wx_str();
128  m_fpname = aFootprint->GetFPID().GetLibItemName().wx_str();
129  m_pad_count = aFootprint->GetPadCount( DO_NOT_INCLUDE_NPTH );
130  m_unique_pad_count = aFootprint->GetUniquePadCount( DO_NOT_INCLUDE_NPTH );
131  m_keywords = aFootprint->GetKeywords();
132  m_doc = aFootprint->GetDescription();
133  m_loaded = true;
134  }
135 };
136 
137 
139 {
140  LIB_ID oldFPID = aFootprint->GetFPID();
141 
142  DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR dialog( this, aFootprint );
143  dialog.ShowModal();
144 
145  // Update library tree
146  BASIC_FOOTPRINT_INFO footprintInfo( aFootprint );
147  wxDataViewItem treeItem = m_adapter->FindItem( oldFPID );
148 
149  if( treeItem.IsOk() ) // Can be not found in tree if the current footprint is imported
150  // from file therefore not yet in tree.
151  {
152  static_cast<LIB_TREE_NODE_LIB_ID*>( treeItem.GetID() )->Update( &footprintInfo );
153  m_treePane->GetLibTree()->RefreshLibTree();
154  }
155 
156  UpdateTitle(); // in case of a name change...
157 
158  UpdateMsgPanel();
159 }
160 
161 
163 {
164  switch( aItem->Type() )
165  {
166  case PCB_PAD_T:
167  ShowPadPropertiesDialog( static_cast<PAD*>( aItem ) );
168  break;
169 
170  case PCB_FOOTPRINT_T:
171  editFootprintProperties( static_cast<FOOTPRINT*>( aItem ) );
172  GetCanvas()->Refresh();
173  break;
174 
175  case PCB_FP_TEXT_T:
176  ShowTextPropertiesDialog( aItem );
177  break;
178 
179  case PCB_FP_SHAPE_T :
180  ShowGraphicItemPropertiesDialog( aItem );
181  break;
182 
183  case PCB_FP_ZONE_T:
184  {
185  ZONE* zone = static_cast<ZONE*>( aItem );
186  bool success = false;
187  ZONE_SETTINGS zoneSettings;
188 
189  zoneSettings << *static_cast<ZONE*>( aItem );
190 
191  if( zone->GetIsRuleArea() )
192  {
193  success = InvokeRuleAreaEditor( this, &zoneSettings ) == wxID_OK;
194  }
195  else if( zone->IsOnCopperLayer() )
196  {
197  success = InvokeCopperZonesEditor( this, &zoneSettings ) == wxID_OK;
198  }
199  else
200  {
201  success = InvokeNonCopperZonesEditor( this, &zoneSettings ) == wxID_OK;
202  }
203 
204  if( success )
205  {
206  BOARD_COMMIT commit( this );
207  commit.Modify( zone );
208  commit.Push( _( "Edit Zone" ) );
209  zoneSettings.ExportSetting( *static_cast<ZONE*>( aItem ) );
210  }
211  }
212  break;
213 
214  case PCB_GROUP_T:
215  m_toolManager->RunAction( PCB_ACTIONS::groupProperties, true, aItem );
216  break;
217 
218  default:
219  wxFAIL_MSG( "FOOTPRINT_EDIT_FRAME::OnEditItemRequest: unsupported item type "
220  + aItem->GetClass() );
221  break;
222  }
223 }
224 
225 
227 {
228  return GetColorSettings()->GetColor( LAYER_GRID );
229 }
230 
231 
233 {
235 
236  m_appearancePanel->OnLayerChanged();
237 
238  m_toolManager->RunAction( PCB_ACTIONS::layerChanged ); // notify other tools
239  GetCanvas()->SetFocus(); // allow capture of hotkeys
240  GetCanvas()->SetHighContrastLayer( aLayer );
241  GetCanvas()->Refresh();
242 }
243 
244 bool FOOTPRINT_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
245 {
246  if( !Clear_Pcb( true ) )
247  return false; // this command is aborted
248 
249  GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false );
250  ImportFootprint( aFileSet[ 0 ] );
251 
252  if( GetBoard()->GetFirstFootprint() )
254 
255  GetScreen()->ClrModify();
256  Zoom_Automatique( false );
257  GetCanvas()->Refresh();
258 
259  return true;
260 }
261 
262 
264 {
265  const std::string& payload = mail.GetPayload();
266 
267  switch( mail.Command() )
268  {
269  case MAIL_FP_EDIT:
270  if( !payload.empty() )
271  {
272  wxFileName fpFileName( payload );
273  wxString libNickname;
274  wxString msg;
275 
276  FP_LIB_TABLE* libTable = Prj().PcbFootprintLibs();
277  const LIB_TABLE_ROW* libTableRow = libTable->FindRowByURI( fpFileName.GetPath() );
278 
279  if( !libTableRow )
280  {
281  msg.Printf( _( "The current configuration does not include a library named '%s'.\n"
282  "Use Manage Footprint Libraries to edit the configuration." ),
283  fpFileName.GetPath() );
284  DisplayErrorMessage( this, _( "Library not found in footprint library table." ), msg );
285  break;
286  }
287 
288  libNickname = libTableRow->GetNickName();
289 
290  if( !libTable->HasLibrary( libNickname, true ) )
291  {
292  msg.Printf( _( "The library '%s' is not enabled in the current configuration.\n"
293  "Use Manage Footprint Libraries to edit the configuration." ),
294  libNickname );
295  DisplayErrorMessage( this, _( "Footprint library not enabled." ), msg );
296  break;
297  }
298 
299  LIB_ID fpId( libNickname, fpFileName.GetName() );
300 
301  if( m_treePane )
302  {
303  m_treePane->GetLibTree()->SelectLibId( fpId );
304  wxCommandEvent event( COMPONENT_SELECTED );
305  wxPostEvent( m_treePane, event );
306  }
307  }
308 
309  break;
310 
311  default:
312  ;
313  }
314 }
COMMIT & Modify(EDA_ITEM *aItem)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
const wxString & GetDescription() const
Definition: footprint.h:193
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition: kiway_express.h:38
void OnEditItemRequest(BOARD_ITEM *aItem) override
Install the corresponding dialog editor for the given item.
void LoadFootprintFromLibrary(LIB_ID aFPID)
const UTF8 & GetLibItemName() const
Definition: lib_id.h:106
void SelectLayer(wxCommandEvent &event)
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
void editFootprintProperties(FOOTPRINT *aFootprint)
Run the Footprint Properties dialog and handle changes made in it.
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:265
unsigned GetPadCount(INCLUDE_NPTH_T aIncludeNPTH=INCLUDE_NPTH_T(INCLUDE_NPTH)) const
Return the number of pads.
Definition: footprint.cpp:1004
void SetActiveLayer(PCB_LAYER_ID aLayer) override
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:730
This file is part of the common library.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
COLOR4D GetGridColor() override
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:108
PROJECT & Prj()
Definition: kicad.cpp:403
int InvokeNonCopperZonesEditor(PCB_BASE_FRAME *aParent, ZONE_SETTINGS *aSettings)
Function InvokeNonCopperZonesEditor invokes up a modal dialog window for non-copper zone editing.
Class that computes missing connections on a PCB.
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Load a KiCad board (.kicad_pcb) from aFileName.
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
class PAD, a pad in a footprint
Definition: typeinfo.h:89
void SaveFootprintToBoard(wxCommandEvent &event)
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
void SetType(TEXT_TYPE aType)
Definition: fp_text.h:140
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:462
FP_TEXT & Reference()
Definition: footprint.h:463
const wxString & GetNickName() const
PCB_LAYER_ID
A quick note on layer IDs:
FOOTPRINT * GetFirstFootprint() const
Gets the first footprint on the board or nullptr.
Definition: board.h:382
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:121
#define NULL
VECTOR2< double > VECTOR2D
Definition: vector2d.h:622
void ExportSetting(ZONE &aTarget, bool aFullExport=true) const
Function ExportSetting copy settings to a given zone.
const LIB_TABLE_ROW * FindRowByURI(const wxString &aURI)
Inactive layers are shown normally (no high-contrast mode)
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:92
const LIB_ID & GetFPID() const
Definition: footprint.h:190
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
int GetLength() const
Definition: fp_text.cpp:181
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
const wxString & GetKeywords() const
Definition: footprint.h:196
int InvokeRuleAreaEditor(PCB_BASE_FRAME *aCaller, ZONE_SETTINGS *aSettings)
Function InvokeRuleAreaEditor invokes up a modal dialog window for copper zone editing.
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
ZONE_SETTINGS handles zones parameters.
Definition: zone_settings.h:67
BOARD * GetBoard()
virtual FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:285
BASIC_FOOTPRINT_INFO(FOOTPRINT *aFootprint)
void LoadFootprintFromBoard(wxCommandEvent &event)
Called from the main toolbar to load a footprint from board mainly to edit it.
static TOOL_ACTION layerChanged
Definition: pcb_actions.h:295
virtual wxString GetClass() const =0
Return the class name.
#define _(s)
Definition: 3d_actions.cpp:33
class ZONE, managed by a footprint
Definition: typeinfo.h:94
wxString wx_str() const
Definition: utf8.cpp:51
bool IsOnCopperLayer() const override
Definition: zone.cpp:222
unsigned GetUniquePadCount(INCLUDE_NPTH_T aIncludeNPTH=INCLUDE_NPTH_T(INCLUDE_NPTH)) const
Return the number of unique non-blank pads.
Definition: footprint.cpp:1023
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Revert the commit by restoring the modified items state.
int InvokeCopperZonesEditor(PCB_BASE_FRAME *aCaller, ZONE_SETTINGS *aSettings)
Function InvokeCopperZonesEditor invokes up a modal dialog window for copper zone editing.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:204
MAIL_T Command()
Returns the MAIL_T associated with this mail.
Definition: kiway_express.h:49
std::string & GetPayload()
Return the payload, which can be any text but it typically self identifying s-expression.
Definition: kiway_express.h:57
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:905
void KiwayMailIn(KIWAY_EXPRESS &mail) override
Receive KIWAY_EXPRESS messages from other players.
static TOOL_ACTION groupProperties
Definition: pcb_actions.h:222
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:98