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 modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef FOOTPRINT_EDIT_FRAME_H
21 #define FOOTPRINT_EDIT_FRAME_H
22 
23 #include <pcb_base_frame.h>
24 #include <pcb_base_edit_frame.h>
25 #include <io_mgr.h>
26 #include <config_params.h>
27 #include <fp_tree_synchronizing_adapter.h>
28 
29 class PCB_LAYER_BOX_SELECTOR;
30 class FP_LIB_TABLE;
31 class FOOTPRINT_TREE_PANE;
32 class SYMBOL_LIBRARY_MANAGER;
33 class FOOTPRINT_EDITOR_SETTINGS;
34 
35 namespace PCB { struct IFACE; }     // A KIFACE coded in pcbnew.cpp
36 
37 
38 class FOOTPRINT_EDIT_FRAME : public PCB_BASE_EDIT_FRAME
39 {
40 public:
41     ~FOOTPRINT_EDIT_FRAME();
42 
43     /**
44      * @return the frame name used when creating the frame used to get a reference to this
45      *         frame, if exists
46      */
47     static const wxChar* GetFootprintEditorFrameName();
48 
49     ///< @copydoc PCB_BASE_FRAME::GetModel()
50     BOARD_ITEM_CONTAINER* GetModel() const override;
51     SELECTION&            GetCurrentSelection() override;
52 
53     /**
54      * Get if any footprints or libraries have been modified but not saved.
55      *
56      * @return true if the any changes have not been saved
57      */
58     bool IsContentModified() const override;
59 
60     bool IsCurrentFPFromBoard() const;
61 
62     FOOTPRINT_EDITOR_SETTINGS* GetSettings();
63 
64     APP_SETTINGS_BASE* config() const override;
65 
66     BOARD_DESIGN_SETTINGS& GetDesignSettings() const override;
67 
68     const PCB_PLOT_PARAMS& GetPlotSettings() const override;
69     void SetPlotSettings( const PCB_PLOT_PARAMS& aSettings ) override;
70 
71     MAGNETIC_SETTINGS* GetMagneticItemsSettings() override;
72 
73     void LoadSettings( APP_SETTINGS_BASE* aCfg ) override;
74     void SaveSettings( APP_SETTINGS_BASE* aCfg ) override;
75 
76     COLOR_SETTINGS* GetColorSettings() const override;
77 
78     const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const override;
79 
80     bool canCloseWindow( wxCloseEvent& Event ) override;
81     void doCloseWindow() override;
82     void CloseFootprintEditor( wxCommandEvent& Event );
83     void OnExitKiCad( wxCommandEvent& aEvent );
84 
85     /**
86      * Switch the currently used canvas (Cairo / OpenGL).
87      *
88      * It also reinitializes the layer manager that slightly changes with canvases.
89      */
90     void SwitchCanvas( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) override;
91 
92     /**
93      * Update the layer manager and other widgets from the board setup (layer and items
94      * visibility, colors ...).
95      */
96     void UpdateUserInterface();
97 
98     /**
99      * Refresh the library tree and redraw the window
100      */
101     void HardRedraw() override;
102 
103     /**
104      * Create the main horizontal toolbar for the footprint editor.
105      */
106     void ReCreateHToolbar() override;
107 
108     void ReCreateVToolbar() override;
109     void ReCreateOptToolbar() override;
110     void UpdateToolbarControlSizes() override;
111 
112     /**
113      * @brief (Re)Create the menubar for the Footprint Editor frame
114      */
115     void ReCreateMenuBar() override;
116 
117     /**
118      * Re create the layer Box by clearing the old list, and building a new one from the new
119      * layers names and layer colors..
120      *
121      * @param aForceResizeToolbar true to resize the parent toolbar or false if not needed
122      *                            (mainly in parent toolbar creation or when the layers names
123      *                            are not modified).
124      */
125     void ReCreateLayerBox( bool aForceResizeToolbar = true );
126 
127     void OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent );
128 
129     void SelectLayer( wxCommandEvent& event );
130 
131     // The Tool Framework initialization, for GAL mode
132     void setupTools();
133 
134     void OnSaveFootprintAsPng( wxCommandEvent& event );
135 
136     bool IsSearchTreeShown() const;
137     void ToggleSearchTree();
138     void ToggleLayersManager();
139 
140     /**
141      * Save a library to a new name and/or library type.
142      *
143      * @see #PLUGIN::FootprintSave and #PLUGIN::FootprintLibCreate
144      *
145      * @note Saving as a new library type requires the plug-in to support saving libraries
146      */
147     bool SaveLibraryAs( const wxString& aLibraryPath );
148 
149     void OnUpdateLoadFootprintFromBoard( wxUpdateUIEvent& aEvent );
150     void OnUpdateSaveFootprintToBoard( wxUpdateUIEvent& aEvent );
151 
152     ///< @copydoc PCB_BASE_EDIT_FRAME::OnEditItemRequest()
153     void OnEditItemRequest( BOARD_ITEM* aItem ) override;
154 
155     /**
156      * Called from the main toolbar to load a footprint from board mainly to edit it.
157      */
158     void LoadFootprintFromBoard( wxCommandEvent& event );
159 
160     void SaveFootprintToBoard( wxCommandEvent& event );
161 
162     void LoadFootprintFromLibrary( LIB_ID aFPID );
163 
164     /**
165      * Return the adapter object that provides the stored data.
166      */
GetLibTreeAdapter()167     wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>& GetLibTreeAdapter() { return m_adapter; }
168 
169     /**
170      * Save in an existing library a given footprint.
171      *
172      * @param aFootprint = the given footprint
173      * @return : true if OK, false if abort
174      */
175     bool SaveFootprint( FOOTPRINT* aFootprint );
176     bool SaveFootprintAs( FOOTPRINT* aFootprint );
177     bool SaveFootprintToBoard( bool aAddNew );
178     bool SaveFootprintInLibrary( FOOTPRINT* aFootprint, const wxString& aLibraryName );
179     bool RevertFootprint();
180 
181     /**
182      * Must be called after a footprint change in order to set the "modify" flag of the
183      * current screen and prepare, if needed the refresh of the 3D frame showing the footprint.
184      *
185      * Do not forget to call the basic OnModify function to update auxiliary info.
186      */
187     void OnModify() override;
188 
189     /**
190      * Delete all and reinitialize the current board.
191      *
192      * @param aQuery = true to prompt user for confirmation, false to initialize silently
193      */
194     bool Clear_Pcb( bool aQuery );
195 
196     /// Return the LIB_ID of the part or library selected in the footprint tree.
197     LIB_ID GetTreeFPID() const;
198 
199     LIB_TREE_NODE* GetCurrentTreeNode() const;
200 
201     /// Return the LIB_ID of the part being edited.
202     LIB_ID GetLoadedFPID() const;
203 
204     /// Return the LIB_ID of the part selected in the footprint tree, or the loaded part if
205     /// there is no selection in the tree.
206     LIB_ID GetTargetFPID() const;
207 
208     void ClearModify();
209 
210     /**
211      * Create a file containing only one footprint.
212      */
213     void ExportFootprint( FOOTPRINT* aFootprint );
214 
215     /**
216      * Read a file containing only one footprint.
217      *
218      * The import function can also read gpcb footprint file, in Newlib format.
219      * (One footprint per file, Newlib files have no special ext.)
220      */
221     FOOTPRINT* ImportFootprint( const wxString& aName = wxT( "" ) );
222 
223     /**
224      * Load a footprint from the main board into the Footprint Editor.
225      *
226      * @param aFootprint = the footprint to load. If NULL, the user will be asked for a
227      *                     footprint reference.
228      * @return true if a footprint is loaded.
229      */
230     bool LoadFootprintFromBoard( FOOTPRINT* aFootprint );
231 
232     /**
233      * Display the list of footprints currently existing on the BOARD.
234      *
235      * @return the selected footprint or nullptr
236      */
237     FOOTPRINT* SelectFootprintFromBoard( BOARD* aPcb );
238 
239     /**
240      * Delete the given footprint from its library.
241      */
242     bool DeleteFootprintFromLibrary( const LIB_ID& aFPID, bool aConfirm );
243 
244     /**
245      * @return the color of the grid
246      */
247     COLOR4D GetGridColor() override;
248 
249     ///< @copydoc PCB_BASE_FRAME::SetActiveLayer()
250     void SetActiveLayer( PCB_LAYER_ID aLayer ) override;
251 
252     void OnDisplayOptionsChanged() override;
253 
254     ///< @copydoc EDA_DRAW_FRAME::UseGalCanvas()
255     void ActivateGalCanvas() override;
256 
257     /**
258      * Load a KiCad board (.kicad_pcb) from \a aFileName.
259      *
260      * @param aFileSet is the BOARD file to load, a vector of one element.
261      * @param aCtl is the KICTL_ bits, one to indicate that an append of the board file
262      *             \a  aFileName to the currently loaded file is desired.  @see #KIWAY_PLAYER
263      *             for bit defines.
264      * @return false if file load fails, otherwise true.
265      */
266     bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl = 0 ) override;
267 
268     /**
269      * Override from PCB_BASE_EDIT_FRAME which adds a footprint to the editor's dummy board,
270      * NOT to the user's PCB.
271      */
272     void AddFootprintToBoard( FOOTPRINT* aFootprint ) override;
273 
274     /**
275      * Allow footprint editor to install its preferences panel into the preferences dialog.
276      */
277     void InstallPreferences( PAGED_DIALOG* aParent, PANEL_HOTKEYS_EDITOR* aHotkeysPanel ) override;
278 
279     /**
280      * Update visible items after a language change.
281      */
282     void ShowChangedLanguage() override;
283 
284     /**
285      * Called after the preferences dialog is run.
286      */
287     void CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged ) override;
288 
289     /**
290      * Synchronize the footprint library tree to the current state of the footprint library
291      * table.
292      */
293     void SyncLibraryTree( bool aProgress );
294 
295     /**
296      * Filter, sort, and redisplay the library tree.  Does NOT synchronize it with libraries
297      * in disk.
298      */
299     void RegenerateLibraryTree();
300 
301     /**
302      * Redisplay the library tree.  Used after changing modified states, descriptions, etc.
303      */
304     void RefreshLibraryTree();
305 
306     ///< Reload displayed items and sets view.
307     void UpdateView();
308 
309     void UpdateTitle();
310 
311     void FocusOnLibID( const LIB_ID& aLibID );
312 
313     void KiwayMailIn( KIWAY_EXPRESS& mail ) override;
314 
315     DECLARE_EVENT_TABLE()
316 
317 protected:
318     /// protected so only friend PCB::IFACE::CreateWindow() can act as sole factory.
319     FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );
320 
321     /**
322      * Make sure the footprint info list is loaded (with a progress dialog) and then initialize
323      * the footprint library tree.
324      */
325     void initLibraryTree();
326 
327     void restoreLastFootprint();
328     void retainLastFootprint();
329 
330     /**
331      * Run the Footprint Properties dialog and handle changes made in it.
332      */
333     void editFootprintProperties( FOOTPRINT* aFootprint );
334 
335     void setupUIConditions() override;
336 
337     void centerItemIdleHandler( wxIdleEvent& aEvent );
338 
339 protected:
340     PCB_LAYER_BOX_SELECTOR*     m_selLayerBox;  // a combo box to display and select active layer
341     FOOTPRINT_EDITOR_SETTINGS*  m_editorSettings;
342 
343 private:
344     friend struct PCB::IFACE;
345 
346     FOOTPRINT_TREE_PANE*        m_treePane;
347     LIB_ID                      m_centerItemOnIdle;
348 
349     wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> m_adapter;
350 
351     bool                        m_show_layer_manager_tools;
352 
353     std::unique_ptr<FOOTPRINT>  m_revertModule;
354     wxString                    m_footprintNameWhenLoaded;
355     std::map<KIID, KIID>        m_boardFootprintUuids;
356 };
357 
358 #endif      // FOOTPRINT_EDIT_FRAME_H
359