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-2021 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 <board_commit.h>
25 #include <confirm.h>
27 #include <footprint_edit_frame.h>
28 #include <footprint_tree_pane.h>
29 #include <fp_lib_table.h>
30 #include <functional>
31 #include <kiway_express.h>
32 #include <pcb_layer_box_selector.h>
33 #include <pcbnew_id.h>
34 #include <ratsnest/ratsnest_data.h>
36 #include <tool/tool_manager.h>
37 #include <tools/pcb_actions.h>
39 #include <widgets/lib_tree.h>
40 
41 using namespace std::placeholders;
42 
43 
44 void FOOTPRINT_EDIT_FRAME::LoadFootprintFromBoard( wxCommandEvent& event )
45 {
46  LoadFootprintFromBoard( nullptr );
47 }
48 
49 
51 {
52  bool is_last_fp_from_brd = IsCurrentFPFromBoard();
53 
54  FOOTPRINT* footprint = LoadFootprint( aFPID );
55 
56  if( !footprint )
57  return;
58 
59  if( !Clear_Pcb( true ) )
60  return;
61 
62  GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false );
63  AddFootprintToBoard( footprint );
64 
65  footprint->ClearFlags();
66 
67  // if either m_Reference or m_Value are gone, reinstall them -
68  // otherwise you cannot see what you are doing on board
69  FP_TEXT* ref = &footprint->Reference();
70  FP_TEXT* val = &footprint->Value();
71 
72  if( val && ref )
73  {
74  ref->SetType( FP_TEXT::TEXT_is_REFERENCE ); // just in case ...
75 
76  if( ref->GetLength() == 0 )
77  ref->SetText( wxT( "Ref**" ) );
78 
79  val->SetType( FP_TEXT::TEXT_is_VALUE ); // just in case ...
80 
81  if( val->GetLength() == 0 )
82  val->SetText( wxT( "Val**" ) );
83  }
84 
85  if( m_zoomSelectBox->GetSelection() == 0 )
86  Zoom_Automatique( false );
87 
88  Update3DView( true, true );
89 
90  GetScreen()->SetContentModified( false );
91 
92  UpdateView();
93  GetCanvas()->Refresh();
94 
95  // Update the save items if needed.
96  if( is_last_fp_from_brd )
97  {
98  ReCreateMenuBar();
99  ReCreateHToolbar();
100  }
101 
102  m_treePane->GetLibTree()->ExpandLibId( aFPID );
103 
104  m_centerItemOnIdle = aFPID;
105  Bind( wxEVT_IDLE, &FOOTPRINT_EDIT_FRAME::centerItemIdleHandler, this );
106 
107  m_treePane->GetLibTree()->RefreshLibTree(); // update highlighting
108 }
109 
110 
112 {
113  m_treePane->GetLibTree()->CenterLibId( m_centerItemOnIdle );
114  Unbind( wxEVT_IDLE, &FOOTPRINT_EDIT_FRAME::centerItemIdleHandler, this );
115 }
116 
117 
118 
119 void FOOTPRINT_EDIT_FRAME::SelectLayer( wxCommandEvent& event )
120 {
121  SetActiveLayer( ToLAYER_ID( m_selLayerBox->GetLayerSelection() ) );
122 
123  if( GetDisplayOptions().m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL )
124  GetCanvas()->Refresh();
125 }
126 
127 
128 void FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( wxCommandEvent& event )
129 {
130  SaveFootprintToBoard( true );
131 }
132 
133 
135 {
136 public:
138  {
139  m_nickname = aFootprint->GetFPID().GetLibNickname().wx_str();
140  m_fpname = aFootprint->GetFPID().GetLibItemName().wx_str();
141  m_pad_count = aFootprint->GetPadCount( DO_NOT_INCLUDE_NPTH );
142  m_unique_pad_count = aFootprint->GetUniquePadCount( DO_NOT_INCLUDE_NPTH );
143  m_keywords = aFootprint->GetKeywords();
144  m_doc = aFootprint->GetDescription();
145  m_loaded = true;
146  }
147 };
148 
149 
151 {
152  LIB_ID oldFPID = aFootprint->GetFPID();
153 
154  DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR dialog( this, aFootprint );
155  dialog.ShowModal();
156 
157  // Update library tree
158  BASIC_FOOTPRINT_INFO footprintInfo( aFootprint );
159  wxDataViewItem treeItem = m_adapter->FindItem( oldFPID );
160 
161  if( treeItem.IsOk() ) // Can be not found in tree if the current footprint is imported
162  // from file therefore not yet in tree.
163  {
164  static_cast<LIB_TREE_NODE_LIB_ID*>( treeItem.GetID() )->Update( &footprintInfo );
165  m_treePane->GetLibTree()->RefreshLibTree();
166  }
167 
168  UpdateTitle(); // in case of a name change...
169 
170  UpdateMsgPanel();
171 }
172 
173 
175 {
176  switch( aItem->Type() )
177  {
178  case PCB_PAD_T:
179  ShowPadPropertiesDialog( static_cast<PAD*>( aItem ) );
180  break;
181 
182  case PCB_FOOTPRINT_T:
183  editFootprintProperties( static_cast<FOOTPRINT*>( aItem ) );
184  GetCanvas()->Refresh();
185  break;
186 
187  case PCB_FP_TEXT_T:
188  ShowTextPropertiesDialog( aItem );
189  break;
190 
191  case PCB_FP_SHAPE_T :
192  ShowGraphicItemPropertiesDialog( aItem );
193  break;
194 
195  case PCB_FP_ZONE_T:
196  {
197  ZONE* zone = static_cast<ZONE*>( aItem );
198  bool success = false;
199  ZONE_SETTINGS zoneSettings;
200 
201  zoneSettings << *static_cast<ZONE*>( aItem );
202 
203  if( zone->GetIsRuleArea() )
204  {
205  success = InvokeRuleAreaEditor( this, &zoneSettings ) == wxID_OK;
206  }
207  else if( zone->IsOnCopperLayer() )
208  {
209  success = InvokeCopperZonesEditor( this, &zoneSettings ) == wxID_OK;
210  }
211  else
212  {
213  success = InvokeNonCopperZonesEditor( this, &zoneSettings ) == wxID_OK;
214  }
215 
216  if( success )
217  {
218  BOARD_COMMIT commit( this );
219  commit.Modify( zone );
220  commit.Push( _( "Edit Zone" ) );
221  zoneSettings.ExportSetting( *static_cast<ZONE*>( aItem ) );
222  }
223 
224  break;
225  }
226 
227  case PCB_GROUP_T:
228  m_toolManager->RunAction( PCB_ACTIONS::groupProperties, true, aItem );
229  break;
230 
231  default:
232  wxFAIL_MSG( "FOOTPRINT_EDIT_FRAME::OnEditItemRequest: unsupported item type "
233  + aItem->GetClass() );
234  break;
235  }
236 }
237 
238 
240 {
241  return GetColorSettings()->GetColor( LAYER_GRID );
242 }
243 
244 
246 {
248 
249  m_appearancePanel->OnLayerChanged();
250 
251  m_toolManager->RunAction( PCB_ACTIONS::layerChanged ); // notify other tools
252  GetCanvas()->SetFocus(); // allow capture of hotkeys
253  GetCanvas()->SetHighContrastLayer( aLayer );
254  GetCanvas()->Refresh();
255 }
256 
257 bool FOOTPRINT_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
258 {
259  if( !Clear_Pcb( true ) )
260  return false; // this command is aborted
261 
262  GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false );
263  ImportFootprint( aFileSet[ 0 ] );
264 
265  if( GetBoard()->GetFirstFootprint() )
267 
268  GetScreen()->SetContentModified( false );
269  Zoom_Automatique( false );
270  GetCanvas()->Refresh();
271 
272  return true;
273 }
274 
275 
277 {
278  const std::string& payload = mail.GetPayload();
279 
280  switch( mail.Command() )
281  {
282  case MAIL_FP_EDIT:
283  if( !payload.empty() )
284  {
285  wxFileName fpFileName( payload );
286  wxString libNickname;
287  wxString msg;
288 
289  FP_LIB_TABLE* libTable = Prj().PcbFootprintLibs();
290  const LIB_TABLE_ROW* libTableRow = libTable->FindRowByURI( fpFileName.GetPath() );
291 
292  if( !libTableRow )
293  {
294  msg.Printf( _( "The current configuration does not include a library named '%s'.\n"
295  "Use Manage Footprint Libraries to edit the configuration." ),
296  fpFileName.GetPath() );
297  DisplayErrorMessage( this, _( "Library not found in footprint library table." ),
298  msg );
299  break;
300  }
301 
302  libNickname = libTableRow->GetNickName();
303 
304  if( !libTable->HasLibrary( libNickname, true ) )
305  {
306  msg.Printf( _( "The library '%s' is not enabled in the current configuration.\n"
307  "Use Manage Footprint Libraries to edit the configuration." ),
308  libNickname );
309  DisplayErrorMessage( this, _( "Footprint library not enabled." ), msg );
310  break;
311  }
312 
313  LIB_ID fpId( libNickname, fpFileName.GetName() );
314 
315  if( m_treePane )
316  {
317  m_treePane->GetLibTree()->SelectLibId( fpId );
318  wxCommandEvent event( SYMBOL_SELECTED );
319  wxPostEvent( m_treePane, event );
320  }
321  }
322 
323  break;
324 
325  default:
326  ;
327  }
328 }
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:197
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:104
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:292
unsigned GetPadCount(INCLUDE_NPTH_T aIncludeNPTH=INCLUDE_NPTH_T(INCLUDE_NPTH)) const
Return the number of pads.
Definition: footprint.cpp:1111
void SetActiveLayer(PCB_LAYER_ID aLayer) override
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:733
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:49
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:499
FP_TEXT & Reference()
Definition: footprint.h:500
const wxString & GetNickName() const
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:317
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:124
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)
#define _(s)
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:90
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:154
const LIB_ID & GetFPID() const
Definition: footprint.h:194
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
int GetLength() const
Definition: fp_text.cpp:184
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
const wxString & GetKeywords() const
Definition: footprint.h:200
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:283
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:291
void centerItemIdleHandler(wxIdleEvent &aEvent)
virtual wxString GetClass() const =0
Return the class name.
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
class ZONE, managed by a footprint
Definition: typeinfo.h:94
wxString wx_str() const
Definition: utf8.cpp:46
bool IsOnCopperLayer() const override
Definition: zone.cpp:228
unsigned GetUniquePadCount(INCLUDE_NPTH_T aIncludeNPTH=INCLUDE_NPTH_T(INCLUDE_NPTH)) const
Return the number of unique non-blank pads.
Definition: footprint.cpp:1130
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.
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:216
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103