1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2008-2016 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 1992-2021 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, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
24  */
25 
26 /**
27  * @file pcb_base_frame.h
28  * @brief Classes used in Pcbnew, CvPcb and GerbView.
29  */
30 
31 #ifndef  PCB_BASE_FRAME_H
32 #define  PCB_BASE_FRAME_H
33 
34 
35 #include <eda_item.h>
36 #include <board.h>
37 #include <eda_draw_frame.h>
38 #include <outline_mode.h>
39 #include <lib_id.h>
40 #include <pcb_display_options.h>
41 #include <pcb_draw_panel_gal.h>
42 #include <pcb_origin_transforms.h>
43 #include <pcb_screen.h>
44 #include <richio.h>
45 #include <vector>
46 
47 
48 /* Forward declarations of classes. */
49 class APP_SETTINGS_BASE;
50 class BOARD;
51 class BOARD_CONNECTED_ITEM;
52 class COLOR_SETTINGS;
53 class FOOTPRINT;
54 class PAD;
55 class EDA_3D_VIEWER_FRAME;
56 class GENERAL_COLLECTOR;
57 class GENERAL_COLLECTORS_GUIDE;
58 class BOARD_DESIGN_SETTINGS;
59 class ZONE_SETTINGS;
60 class PCB_PLOT_PARAMS;
61 class FP_LIB_TABLE;
62 class PCBNEW_SETTINGS;
63 class FOOTPRINT_EDITOR_SETTINGS;
64 struct MAGNETIC_SETTINGS;
65 class PROGRESS_REPORTER;
66 
67 
68 wxDECLARE_EVENT( BOARD_CHANGED, wxCommandEvent );
69 
70 /**
71  * Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
72  */
73 class PCB_BASE_FRAME : public EDA_DRAW_FRAME
74 {
75 public:
76     PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
77                     const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
78                     long aStyle, const wxString& aFrameName );
79 
80     ~PCB_BASE_FRAME();
81 
82     /**
83      * @return a reference to the child 3D viewer frame, when exists, or NULL
84      */
85     EDA_3D_VIEWER_FRAME* Get3DViewerFrame();
86 
87     /**
88      * Update the 3D view, if the viewer is opened by this frame.
89      *
90      * @param aMarkDirty alerts the 3D view that data is stale (it may not refresh instantly)
91      * @param aRefresh will tell the 3D view to refresh immediately
92      * @param aTitle is the new title of the 3D frame, or nullptr to do not change the
93      *               frame title
94      */
95     virtual void Update3DView( bool aMarkDirty, bool aRefresh,
96                                const wxString* aTitle = nullptr );
97 
98     /**
99      * Attempt to load \a aFootprintId from the footprint library table.
100      *
101      * @param aFootprintId is the #LIB_ID of component footprint to load.
102      * @return the #FOOTPRINT if found or NULL if \a aFootprintId not found in any of the
103      *         libraries in table returned from #Prj().PcbFootprintLibs().
104      */
105     FOOTPRINT* LoadFootprint( const LIB_ID& aFootprintId );
106 
107     /**
108      * Calculate the bounding box containing all board items (or board edge segments).
109      *
110      * @param aBoardEdgesOnly is true if we are interested in board edge segments only.
111      * @return the board's bounding box.
112      */
113     EDA_RECT GetBoardBoundingBox( bool aBoardEdgesOnly = false ) const;
114 
115     const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const override
116     {
117         /* "Zoom to Fit" calls this with "aIncludeAllVisible" as true.  Since that feature
118          * always ignored the page and border, this function returns a bbox without them
119          * as well when passed true.  This technically is not all things visible, but it
120          * keeps behavior consistent.
121          *
122          * When passed false, this function returns a bbox of just the board edge. This
123          * allows things like fabrication text or anything else outside the board edge to
124          * be ignored, and just zooms up to the board itself.
125          *
126          * Calling "GetBoardBoundingBox(true)" when edge cuts are turned off will return
127          * the entire page and border, so we call "GetBoardBoundingBox(false)" instead.
128          */
129         if( aIncludeAllVisible || !m_pcb->IsLayerVisible( Edge_Cuts ) )
130             return GetBoardBoundingBox( false );
131         else
132             return GetBoardBoundingBox( true );
133     }
134 
135     virtual void SetPageSettings( const PAGE_INFO& aPageSettings ) override;
136     const PAGE_INFO& GetPageSettings() const override;
137     const wxSize GetPageSizeIU() const override;
138 
139     const wxPoint& GetGridOrigin() const override;
140     void SetGridOrigin( const wxPoint& aPoint ) override;
141 
142     const wxPoint& GetAuxOrigin() const;
143 
144     const wxPoint GetUserOrigin() const;
145 
146     /**
147      * Return a reference to the default ORIGIN_TRANSFORMS object
148      */
149     ORIGIN_TRANSFORMS& GetOriginTransforms() override;
150 
151     const TITLE_BLOCK& GetTitleBlock() const override;
152     void SetTitleBlock( const TITLE_BLOCK& aTitleBlock ) override;
153 
154     /**
155      * Returns the BOARD_DESIGN_SETTINGS for the open project.
156      *
157      * Overloaded in FOOTPRINT_EDIT_FRAME.
158      */
159     virtual BOARD_DESIGN_SETTINGS& GetDesignSettings() const;
160 
161     /**
162      * Helper to retrieve the current color settings.
163      *
164      * @return a pointer to the active COLOR_SETTINGS.
165      */
GetColorSettings()166     virtual COLOR_SETTINGS* GetColorSettings() const override
167     {
168         wxFAIL_MSG( "Color settings requested for a PCB_BASE_FRAME that does not override!" );
169         return nullptr;
170     }
171 
Settings()172     PCBNEW_SETTINGS& Settings() { return *m_settings; }
173 
174     void SetDrawBgColor( const COLOR4D& aColor ) override;
175 
176     /**
177      * Display options control the way tracks, vias, outlines and other things are shown
178      * (for instance solid or sketch mode).
179      */
GetDisplayOptions()180     const PCB_DISPLAY_OPTIONS& GetDisplayOptions() const { return m_displayOptions; }
181 
182     /**
183      * Updates the current display options from the given options struct
184      * @param aOptions is the options struct to apply
185      * @param aRefresh will refresh the view after updating
186      */
187     void SetDisplayOptions( const PCB_DISPLAY_OPTIONS& aOptions, bool aRefresh = true );
188 
189     const ZONE_SETTINGS& GetZoneSettings() const;
190     void SetZoneSettings( const ZONE_SETTINGS& aSettings );
191 
192     /**
193      * Return the #PCB_PLOT_PARAMS for the BOARD owned by this frame.
194      *
195      * Overloaded in FOOTPRINT_EDIT_FRAME.
196      */
197     virtual const PCB_PLOT_PARAMS& GetPlotSettings() const;
198     virtual void SetPlotSettings( const PCB_PLOT_PARAMS& aSettings );
199 
200     /**
201      * Set the #m_Pcb member in such as way as to ensure deleting any previous #BOARD.
202      *
203      * @param aBoard is the #BOARD to put into the frame.
204      */
205     virtual void SetBoard( BOARD* aBoard, PROGRESS_REPORTER* aReporter = nullptr );
206 
GetBoard()207     BOARD* GetBoard() const
208     {
209         wxASSERT( m_pcb );
210         return m_pcb;
211     }
212 
213     /**
214      * @return the primary data model.
215      */
216     virtual BOARD_ITEM_CONTAINER* GetModel() const = 0;
217 
218     EDA_ITEM* GetItem( const KIID& aId ) const override;
219 
220     void FocusOnItem( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer = UNDEFINED_LAYER );
221 
222     // General
ReCreateOptToolbar()223     virtual void ReCreateOptToolbar() override { }
224     virtual void ShowChangedLanguage() override;
225     virtual void ReCreateMenuBar() override;
226     virtual void UpdateStatusBar() override;
227 
GetScreen()228     PCB_SCREEN* GetScreen() const override { return (PCB_SCREEN*) EDA_DRAW_FRAME::GetScreen(); }
229 
230     /**
231      * Shows the 3D view frame.
232      *
233      * If it does not exist, it is created.  If it exists, it is brought to the foreground.
234      */
235     EDA_3D_VIEWER_FRAME* CreateAndShow3D_Frame();
236 
237     /**
238      * @return global configuration options.
239      */
240     GENERAL_COLLECTORS_GUIDE GetCollectorsGuide();
241 
242     /**
243      * Put up a dialog and allows the user to pick a library, for unspecified use.
244      *
245      * @param aNicknameExisting is the current choice to highlight.
246      * @return the library or wxEmptyString on abort.
247      */
248     wxString SelectLibrary( const wxString& aNicknameExisting );
249 
250     /**
251      * @return a reference to the footprint found by its reference on the current board. The
252      *         reference is entered by the user from a dialog (by awxTextCtlr, or a list of
253      *         available references)
254      */
255     FOOTPRINT* GetFootprintFromBoardByReference();
256 
257     /**
258      * Must be called after a change in order to set the "modify" flag of the current screen
259      * and update the date in frame reference.
260      *
261      * Do not forget to call this basic OnModify function to update info in derived OnModify
262      * functions.
263      */
264     virtual void OnModify();
265 
266     /**
267      * Creates a new footprint, at position 0,0.
268      *
269      * The new footprint contains only 2 texts: a reference and a value:
270      *  Reference = REF**
271      *  Value = "VAL**" or Footprint name in lib
272      *
273      * @note They are dummy texts, which will be replaced by the actual texts when the
274      *       footprint is placed on a board and a netlist is read.
275      *
276      * @param aFootprintName is the name of the new footprint in library.
277      * @param aQuiet prevents user dialogs from being shown
278      */
279     FOOTPRINT* CreateNewFootprint( const wxString& aFootprintName, bool aQuiet = false );
280 
281     /**
282      * Places \a aFootprint at the current cursor position and updates footprint coordinates
283      * with the new position.
284      *
285      * @param aRecreateRatsnest A bool true redraws the footprint ratsnest.
286      */
287     void PlaceFootprint( FOOTPRINT* aFootprint, bool aRecreateRatsnest = true );
288 
289     void ShowPadPropertiesDialog( PAD* aPad );
290 
291     /**
292      * Open a dialog to select a footprint.
293      *
294      * @param aPreslect if valid, the #LIB_ID to select (otherwise the global history is used).
295      */
296     FOOTPRINT* SelectFootprintFromLibTree( LIB_ID aPreselect = LIB_ID() );
297 
298     /**
299      * Add the given footprint to the board.
300      *
301      * @param aDC is the current Device Context, to draw the new footprint (can be NULL ).
302      */
303     virtual void AddFootprintToBoard( FOOTPRINT* aFootprint );
304 
305     /**
306      * Launch the footprint viewer to select the name of a footprint to load.
307      *
308      * @return the selected footprint name or an empty string if no selection was made.
309      */
310     wxString SelectFootprintFromLibBrowser();
311 
312     /**
313      * Create the entire board ratsnest.
314      *
315      * This must be called after a board change (changes for pads, footprints or a read
316      * netlist ).
317      *
318      * @param aDC is the current device context (can be NULL).
319      * @param aDisplayStatus  if true, display the computation results.
320      */
321     void Compile_Ratsnest( bool aDisplayStatus );
322 
323     /**
324      * Create a new entry in undo list of commands.
325      *
326      * @param aItemToCopy is the board item modified by the command to undo.
327      * @param aTypeCommand is the command type (see enum #UNDO_REDO).
328      */
329     virtual void SaveCopyInUndoList( EDA_ITEM* aItemToCopy, UNDO_REDO aTypeCommand ) = 0;
330 
331     /**
332      * Creates a new entry in undo list of commands.
333      *
334      * @param aItemsList is the list of items modified by the command to undo.
335      * @param aTypeCommand is the command type (see enum #UNDO_REDO)
336      */
337     virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
338                                      UNDO_REDO aTypeCommand ) = 0;
339 
340 
341     /**
342      * Show the dialog box for a layer selection.
343      *
344      * @param aDefaultLayer is the default layer to select.  Use UNDEFINED_LAYER if no selection
345      *                      is desired.
346      * @param aNotAllowedLayersMask is a layer mask for not allowed layers.  Use 0 to show all
347      *                              layers in use.
348      * @param aDlgPosition is the position of dialog (default is centered).
349      * @return the selected layer id.
350      */
351     PCB_LAYER_ID SelectOneLayer( PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask = LSET(),
352                               wxPoint aDlgPosition = wxDefaultPosition );
353 
354     /**
355      * Change the active layer in the frame
356      *
357      * @param aLayer New layer to make active
358      */
359     virtual void SwitchLayer( PCB_LAYER_ID aLayer );
360 
SetActiveLayer(PCB_LAYER_ID aLayer)361     virtual void SetActiveLayer( PCB_LAYER_ID aLayer ) { GetScreen()->m_Active_Layer = aLayer; }
GetActiveLayer()362     virtual PCB_LAYER_ID GetActiveLayer() const { return GetScreen()->m_Active_Layer; }
363 
364     SEVERITY GetSeverity( int aErrorCode ) const override;
365 
OnDisplayOptionsChanged()366     virtual void OnDisplayOptionsChanged() {}
367 
368     void LoadSettings( APP_SETTINGS_BASE* aCfg ) override;
369     void SaveSettings( APP_SETTINGS_BASE* aCfg ) override;
370 
371     PCBNEW_SETTINGS* GetPcbNewSettings() const;
372 
373     FOOTPRINT_EDITOR_SETTINGS* GetFootprintEditorSettings() const;
374 
375     virtual MAGNETIC_SETTINGS* GetMagneticItemsSettings();
376 
377     void CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged ) override;
378 
379     /**
380      * Display the current grid pane on the status bar.
381      */
382     void DisplayGridMsg() override;
383 
384     PCB_DRAW_PANEL_GAL* GetCanvas() const override;
385 
386     virtual void ActivateGalCanvas() override;
387 
388 protected:
389     bool canCloseWindow( wxCloseEvent& aCloseEvent ) override;
390 
391     /**
392      * Attempts to load \a aFootprintId from the footprint library table.
393      *
394      * @param aFootprintId is the #LIB_ID of component footprint to load.
395      * @return the #FOOTPRINT if found or NULL if \a aFootprintId not found in any of the
396      *         libraries in the table returned from #Prj().PcbFootprintLibs().
397      * @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error
398      *                 occurs while reading footprint library files.
399      */
400     FOOTPRINT* loadFootprint( const LIB_ID& aFootprintId );
401 
402     virtual void unitsChangeRefresh() override;
403 
404 protected:
405     BOARD*                  m_pcb;
406     PCB_DISPLAY_OPTIONS     m_displayOptions;
407     PCB_ORIGIN_TRANSFORMS   m_originTransforms;
408     PCBNEW_SETTINGS*        m_settings; // No ownership, just a shortcut
409 };
410 
411 #endif  // PCB_BASE_FRAME_H
412