KiCad PCB EDA Suite
Loading...
Searching...
No Matches
load_select_footprint.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) 2018 Jean-Pierre Charras, [email protected]
5 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <functional>
23using namespace std::placeholders;
24
25#include <board.h>
26#include <footprint.h>
27#include <confirm.h>
29#include <eda_list_dialog.h>
35#include <pcb_io/pcb_io_mgr.h>
36#include <string_utils.h>
37#include <kiway.h>
38#include <lib_id.h>
39#include <macros.h>
41#include <pcb_edit_frame.h>
42#include <pcbnew_settings.h>
44#include <drc/drc_item.h>
45#include <view/view_controls.h>
47#include <widgets/lib_tree.h>
50#include <project_pcb.h>
51#include <locale_io.h>
52
53
54static wxArrayString s_FootprintHistoryList;
55static unsigned s_FootprintHistoryMaxCount = 8;
56
57static void AddFootprintToHistory( const wxString& aName )
58{
59 // Remove duplicates
60 for( int ii = s_FootprintHistoryList.GetCount() - 1; ii >= 0; --ii )
61 {
62 if( s_FootprintHistoryList[ ii ] == aName )
63 s_FootprintHistoryList.RemoveAt((size_t) ii );
64 }
65
66 // Add the new name at the beginning of the history list
67 s_FootprintHistoryList.Insert( aName, 0 );
68
69 // Remove extra names
71 s_FootprintHistoryList.RemoveAt( s_FootprintHistoryList.GetCount() - 1 );
72}
73
74
75#include <bitmaps.h>
77{
78 bool is_last_fp_from_brd = IsCurrentFPFromBoard();
79
80 FOOTPRINT* newFootprint = nullptr;
82
83 if( frame == nullptr ) // happens if no board editor opened
84 return false;
85
86 if( aFootprint == nullptr )
87 {
88 if( !frame->GetBoard() || !frame->GetBoard()->GetFirstFootprint() )
89 return false;
90
91 aFootprint = SelectFootprintFromBoard( frame->GetBoard() );
92 }
93
94 if( aFootprint == nullptr )
95 return false;
96
97 // Ensure we do not have the pad editor open (that is apseudo modal dlg).
98 // LoadFootprintFromBoard() can be called from the board editor, and we must ensure
99 // no footprint item is currently in edit
100 if( wxWindow::FindWindowByName( PAD_PROPERTIES_DLG_NAME ) )
101 wxWindow::FindWindowByName( PAD_PROPERTIES_DLG_NAME )->Close();
102
103 // Open the placed footprint as a session-only instance tab over its own fp-holder board instead
104 // of replacing the working document; re-editing the same footprint focuses the existing tab.
105 wxCHECK( m_tabsPanel, false );
106
107 const wxString instanceKey = FOOTPRINT_EDITOR_TAB_CONTEXT::MakeInstanceTabKey( aFootprint->m_Uuid );
108 const bool createdNewTab = m_tabsPanel->FindTab( instanceKey ) < 0;
109
111
112 if( !ctx )
113 return false;
114
115 newFootprint = ctx->GetBoard()->GetFirstFootprint();
116
117 // A board-sourced footprint follows the board, not the library, so do not watch a lib file.
118 setFPWatcher( nullptr );
119
120 // Show a scaled placement in its library (unscaled) frame in the editor. The board scale is
121 // re-applied on save via ExchangeFootprint. Only a freshly opened tab needs this reset.
122 if( createdNewTab )
123 newFootprint->SetTransformScale( 1.0, 1.0 );
124
125 Zoom_Automatique( false );
126
127 m_adapter->SetPreselectNode( newFootprint->GetFPID(), 0 );
128
129 // A re-focused instance tab keeps its live edit history; only a freshly opened tab starts clean.
130 if( createdNewTab )
131 {
132 // For revert:
133 m_originalFootprintCopy.reset( static_cast<FOOTPRINT*>( aFootprint->Clone() ) );
134 m_originalFootprintCopy->SetParent( nullptr );
135
136 // For undo/redo:
138 GetScreen()->SetContentModified( false );
139 }
140
141 // Update the save items if needed.
142 if( !is_last_fp_from_brd )
143 {
146
147 if( IsLibraryTreeShown() )
149 }
150
151 Update3DView( true, true );
152 UpdateView();
153 GetCanvas()->Refresh();
154 m_treePane->GetLibTree()->RefreshLibTree(); // update any previously-highlighted items
155
156 return true;
157}
158
159
161{
162 wxString footprintName = aPreselect.Format().wx_str();
163 LIB_ID fpid;
164 FOOTPRINT* footprint = nullptr;
165
166 static wxString lastComponentName;
167
168 if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, this ) )
169 {
170 if( frame->ShowModal( &footprintName, this ) )
171 fpid.Parse( UTF8( footprintName ) );
172
173 frame->Destroy();
174 }
175
176 if( !fpid.IsValid() )
177 return nullptr;
178
179 footprint = LoadFootprint( fpid );
180
181 if( footprint )
182 {
183 lastComponentName = footprintName;
184 AddFootprintToHistory( footprintName );
185 }
186
187 return footprint;
188}
189
190
192{
193 // When loading a footprint from a library in the footprint editor
194 // the items UUIDs must be keep and not reinitialized
195 bool keepUUID = IsType( FRAME_FOOTPRINT_EDITOR );
196
197 return LoadFootprintFromProject( m_pcb, aFootprintId, keepUUID );
198}
199
200
202{
203 static wxString oldName; // Save name of last footprint selected.
204
205 wxString fpname;
206 wxString msg;
207 wxArrayString listnames;
208
209 for( FOOTPRINT* footprint : aPcb->Footprints() )
210 listnames.Add( footprint->GetReference() );
211
212 msg.Printf( _( "Footprints [%u items]" ), (unsigned) listnames.GetCount() );
213
214 wxArrayString headers;
215
216 headers.Add( _( "Footprint" ) );
217
218 std::vector<wxArrayString> itemsToDisplay;
219
220 // Conversion from wxArrayString to vector of ArrayString
221 for( unsigned i = 0; i < listnames.GetCount(); i++ )
222 {
223 wxArrayString item;
224
225 item.Add( listnames[i] );
226 itemsToDisplay.push_back( item );
227 }
228
229 EDA_LIST_DIALOG dlg( this, msg, headers, itemsToDisplay, wxEmptyString );
230
231 if( dlg.ShowModal() == wxID_OK )
232 fpname = dlg.GetTextSelection();
233 else
234 return nullptr;
235
236 oldName = fpname;
237
238 for( FOOTPRINT* fp : aPcb->Footprints() )
239 {
240 if( fpname == fp->GetReference() )
241 return fp;
242 }
243
244 return nullptr;
245}
246
247
248bool FOOTPRINT_EDIT_FRAME::SaveLibraryAs( const wxString& aLibraryPath )
249{
250 const wxString& curLibPath = aLibraryPath;
251 wxString dstLibPath = CreateNewLibrary( _( "Save Footprint Library As" ), aLibraryPath );
252
253 if( !dstLibPath )
254 return false; // user aborted in CreateNewLibrary()
255
256 wxBusyCursor dummy;
257 wxString msg;
258
259 LOCALE_IO toggle_locale;
262
263 if( dstType == PCB_IO_MGR::FILE_TYPE_NONE )
264 dstType = PCB_IO_MGR::KICAD_SEXP;
265
266 try
267 {
270
271 if( !cur )
272 {
273 msg = wxString::Format( _( "Unable to find a reader for '%s'." ), curLibPath );
274 DisplayError( this, msg );
275 return false;
276 }
277
278 if( !dst )
279 {
280 msg = wxString::Format( _( "Unable to find a writer for '%s'." ), dstLibPath );
281 DisplayError( this, msg );
282 return false;
283 }
284
285 wxArrayString footprints;
286
287 cur->FootprintEnumerate( footprints, curLibPath, false );
288
289 for( const wxString& fp : footprints )
290 {
291 const FOOTPRINT* footprint = cur->GetEnumeratedFootprint( curLibPath, fp );
292 dst->FootprintSave( dstLibPath, footprint );
293
294 msg = wxString::Format( _( "Footprint '%s' saved." ), fp );
295 SetStatusText( msg );
296 }
297 }
298 catch( const IO_ERROR& ioe )
299 {
300 DisplayErrorMessage( this, _( "Error saving footprint library" ), ioe.What() );
301 return false;
302 }
303
304 msg = wxString::Format( _( "Footprint library '%s' saved as '%s'." ),
305 curLibPath,
306 dstLibPath );
307
308 DisplayInfoMessage( this, msg );
309
310 SetStatusText( wxEmptyString );
311 return true;
312}
313
314
315static FOOTPRINT* s_FootprintInitialCopy = nullptr; // Copy of footprint for abort/undo command
316
317static PICKED_ITEMS_LIST s_PickedList; // A pick-list to save initial footprint
318 // and dragged tracks
319
320void PCB_BASE_FRAME::PlaceFootprint( FOOTPRINT* aFootprint, bool aRecreateRatsnest, std::optional<VECTOR2I> aPosition )
321{
322 if( aFootprint == nullptr )
323 return;
324
325 OnModify();
326
327 if( aFootprint->IsNew() )
328 {
330 }
331 else if( aFootprint->IsMoving() )
332 {
333 ITEM_PICKER picker( nullptr, aFootprint, UNDO_REDO::CHANGED );
335 s_PickedList.PushItem( picker );
336 s_FootprintInitialCopy = nullptr; // the picker is now owner of s_ModuleInitialCopy.
337 }
338
339 if( s_PickedList.GetCount() )
340 {
342
343 // Clear list, but DO NOT delete items, because they are owned by the saved undo
344 // list and they therefore in use
345 s_PickedList.ClearItemsList();
346 }
347
348 if( aPosition.has_value() )
349 aFootprint->SetPosition( aPosition.value() );
350 else
351 aFootprint->SetPosition( GetCanvas()->GetViewControls()->GetCursorPosition() );
352
353 aFootprint->ClearFlags();
354
356 s_FootprintInitialCopy = nullptr;
357
358 if( aRecreateRatsnest )
359 m_pcb->GetConnectivity()->Update( aFootprint );
360
361 if( aRecreateRatsnest )
362 m_pcb->CompileRatsnest();
363
364 SetMsgPanel( aFootprint );
365}
366
void SetContentModified(bool aModified=true)
Definition base_screen.h:55
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:411
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition board.h:713
const FOOTPRINTS & Footprints() const
Definition board.h:465
int ShowModal() override
virtual void ClearUndoRedoList()
Clear the undo and redo list using ClearUndoORRedoList()
bool IsType(FRAME_T aType) const
void ReCreateMenuBar()
Recreate the menu bar.
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
virtual void ReCreateHToolbar()
virtual void Zoom_Automatique(bool aWarpPointer)
Redraw the screen with best zoom level and the best centering that shows all the page or the board.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
const KIID m_Uuid
Definition eda_item.h:599
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition eda_item.h:160
bool IsMoving() const
Definition eda_item.h:132
bool IsNew() const
Definition eda_item.h:131
A dialog which shows:
wxString GetTextSelection(int aColumn=0)
Return the selected text from aColumn in the wxListCtrl in the dialog.
One open footprint tab owning its fp-holder board, lent to the frame by raw pointer while active.
BOARD * GetBoard() const
The fp-holder board owned by this context.
static wxString MakeInstanceTabKey(const KIID &aSourceUuid)
De-duplication key for a placed board footprint, in a namespace disjoint from library keys.
bool SaveLibraryAs(const wxString &aLibraryPath)
Save a library to a new name and/or library type.
EDITOR_TABS_PANEL * m_tabsPanel
FOOTPRINT_EDITOR_TAB_CONTEXT * findOrCreateFootprintInstanceTab(FOOTPRINT *aBoardFootprint)
Find or create the instance tab for a placed board footprint and make it the active tab.
FOOTPRINT * SelectFootprintFromBoard(BOARD *aPcb)
Display the list of footprints currently existing on the BOARD.
wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > m_adapter
bool IsLibraryTreeShown() const override
void UpdateView()
Reload displayed items and sets view.
FOOTPRINT_TREE_PANE * m_treePane
std::unique_ptr< FOOTPRINT > m_originalFootprintCopy
bool LoadFootprintFromBoard(FOOTPRINT *aFootprint)
Load a footprint from the main board into the Footprint Editor.
void SetPosition(const VECTOR2I &aPos) override
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
const LIB_ID & GetFPID() const
Definition footprint.h:417
void SetTransformScale(double aScaleX, double aScaleY)
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Adds an item to the container.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
void SetLink(EDA_ITEM *aItem)
KIWAY_PLAYER(KIWAY *aKiway, wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aFrameName, const EDA_IU_SCALE &aIuScale)
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:401
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition lib_id.cpp:65
bool IsValid() const
Check if this LID_ID is valid.
Definition lib_id.h:168
UTF8 Format() const
Definition lib_id.cpp:132
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
wxString CreateNewLibrary(const wxString &aDialogTitle, const wxString &aInitialPath=wxEmptyString)
If a library name is given, creates a new footprint library in the project folder with the given name...
void setFPWatcher(FOOTPRINT *aFootprint)
Create or removes a watcher on the specified footprint.
void OnModify() override
Must be called after a change in order to set the "modify" flag and update other data structures and ...
virtual void SaveCopyInUndoList(EDA_ITEM *aItemToCopy, UNDO_REDO aTypeCommand)
Create a new entry in undo list of commands.
FOOTPRINT * SelectFootprintFromLibrary(LIB_ID aPreselect=LIB_ID())
Open a dialog to select a footprint.
FOOTPRINT * LoadFootprint(const LIB_ID &aFootprintId)
Attempt to load aFootprintId from the footprint library table.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
BOARD * GetBoard() const
void PlaceFootprint(FOOTPRINT *aFootprint, bool aRecreateRatsnest=true, std::optional< VECTOR2I > aPosition=std::nullopt)
Place aFootprint at the current cursor position (or provided one) and updates footprint coordinates w...
virtual void Update3DView(bool aMarkDirty, bool aRefresh, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
The main frame for Pcbnew.
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
Definition pcb_io_mgr.h:52
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition pcb_io_mgr.h:54
static PCB_IO * FindPlugin(PCB_FILE_T aFileType)
Return a PCB_IO which the caller can use to import, export, save, or load design documents.
static PCB_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
Return a plugin type given a footprint library's libPath.
A holder to handle information on schematic or board items.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition utf8.h:67
wxString wx_str() const
Definition utf8.cpp:41
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition confirm.cpp:245
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:192
This file is part of the common library.
#define PAD_PROPERTIES_DLG_NAME
DIALOG_PAD_PROPERTIES, derived from DIALOG_PAD_PROPERTIES_BASE, created by wxFormBuilder.
#define _(s)
static wxArrayString s_FootprintHistoryList
static unsigned s_FootprintHistoryMaxCount
static void AddFootprintToHistory(const wxString &aName)
@ FRAME_PCB_EDITOR
Definition frame_type.h:38
@ FRAME_FOOTPRINT_CHOOSER
Definition frame_type.h:40
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:39
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition io_mgr.h:33
static PICKED_ITEMS_LIST s_PickedList
static FOOTPRINT * s_FootprintInitialCopy
static void AddFootprintToHistory(const wxString &aName)
This file contains miscellaneous commonly used macros and functions.
FOOTPRINT * LoadFootprintFromProject(BOARD *aBoard, const LIB_ID &aFootprintId, bool aKeepUuid)
Load a footprint from the project library table and apply board default settings.
KIWAY Kiway(KFCTL_STANDALONE)
std::vector< FAB_LAYER_COLOR > dummy