1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2009-2015 Jean-Pierre Charras, jp.charras wanadoo.fr
5  * Copyright (C) 2011 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 eda_base_frame.h
28  * @brief Base window classes and related definitions.
29  */
30 
31 #ifndef  EDA_BASE_FRAME_H_
32 #define  EDA_BASE_FRAME_H_
33 
34 
35 #include <vector>
36 
37 #include <wx/aui/aui.h>
38 #include <layer_ids.h>
39 #include <frame_type.h>
40 #include <hotkeys_basic.h>
41 #include <kiway_holder.h>
42 #include <tool/tools_holder.h>
43 #include <widgets/ui_common.h>
44 #include <widgets/infobar.h>
45 #include <undo_redo_container.h>
46 #include <eda_units.h>
47 
48 // Option for main frames
49 #define KICAD_DEFAULT_DRAWFRAME_STYLE wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS
50 
51 
52 #define VIEWER3D_FRAMENAME wxT( "Viewer3DFrameName" )
53 #define QUALIFIED_VIEWER3D_FRAMENAME( parent ) \
54                     ( wxString( VIEWER3D_FRAMENAME ) + wxT( ":" ) + parent->GetName() )
55 
56 #define KICAD_MANAGER_FRAME_NAME   wxT( "KicadFrame" )
57 
58 
59 class wxChoice;
60 class wxEvent;
61 class wxFileName;
62 class EDA_ITEM;
63 class EDA_RECT;
64 class EDA_DRAW_PANEL_GAL;
65 class EDA_MSG_PANEL;
66 class BASE_SCREEN;
67 class PARAM_CFG;
68 class PAGE_INFO;
69 class PLOTTER;
70 class TITLE_BLOCK;
71 class MSG_PANEL_ITEM;
72 class TOOL_MANAGER;
73 class TOOL_DISPATCHER;
74 class ACTIONS;
75 class PAGED_DIALOG;
76 class DIALOG_EDIT_LIBRARY_TABLES;
77 class PANEL_HOTKEYS_EDITOR;
78 class FILE_HISTORY;
79 class SETTINGS_MANAGER;
80 class SEARCH_STACK;
81 class APP_SETTINGS_BASE;
82 struct WINDOW_SETTINGS;
83 struct WINDOW_STATE;
84 
85 #define DEFAULT_MAX_UNDO_ITEMS 0
86 #define ABS_MAX_UNDO_ITEMS (INT_MAX / 2)
87 
88 /// This is the handler functor for the update UI events
89 typedef std::function< void( wxUpdateUIEvent& ) > UIUpdateHandler;
90 
91 wxDECLARE_EVENT( UNITS_CHANGED, wxCommandEvent );
92 
93 
94 /**
95  * The base frame for deriving all KiCad main window classes.
96  *
97  * This class is not intended to be used directly.  It provides support for automatic calls
98  * to SaveSettings() function.  SaveSettings() for a derived class can choose to do nothing,
99  * or rely on basic SaveSettings() support in this base class to do most of the work by
100  * calling it from the derived class's SaveSettings().  This class is not a #KIWAY_PLAYER
101  * because #KICAD_MANAGER_FRAME is derived from it and that class is not a player.
102  */
103 class EDA_BASE_FRAME : public wxFrame, public TOOLS_HOLDER, public KIWAY_HOLDER
104 {
105 public:
106     /**
107      * Specifies whether we are interacting with the undo or redo stacks
108      */
109     enum UNDO_REDO_LIST
110     {
111         UNDO_LIST,
112         REDO_LIST
113     };
114 
115     EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle,
116                     const wxPoint& aPos, const wxSize& aSize, long aStyle,
117                     const wxString& aFrameName, KIWAY* aKiway );
118 
119     EDA_BASE_FRAME( FRAME_T aFrameType, KIWAY* aKiway );
120 
121     ~EDA_BASE_FRAME();
122 
123     /**
124      * Return the user units currently in use.
125      */
GetUserUnits()126     EDA_UNITS GetUserUnits() const
127     {
128         return m_userUnits;
129     }
130 
SetUserUnits(EDA_UNITS aUnits)131     void SetUserUnits( EDA_UNITS aUnits )
132     {
133         m_userUnits = aUnits;
134     }
135 
136     void ChangeUserUnits( EDA_UNITS aUnits );
137 
ToggleUserUnits()138     virtual void ToggleUserUnits() { }
139 
GetSettingsManager()140     SETTINGS_MANAGER* GetSettingsManager() const { return m_settingsManager; }
141 
GetSeverity(int aErrorCode)142     virtual SEVERITY GetSeverity( int aErrorCode ) const { return RPT_SEVERITY_UNDEFINED; }
143 
144     /**
145      * Override the default process event handler to implement the auto save feature.
146      *
147      * @warning If you override this function in a derived class, make sure you call down to
148      *          this or the auto save feature will be disabled.
149      */
150     bool ProcessEvent( wxEvent& aEvent ) override;
151 
152     /**
153      * Capture the key event before it is sent to the GUI.
154      *
155      * The basic frame does not capture this event.  Editor frames should override this event
156      * function to capture and filter these keys when they are used as hotkeys, and skip it if
157      * the key is not used as hotkey (otherwise the key events will be not sent to menus).
158      */
159     virtual void OnCharHook( wxKeyEvent& aKeyEvent );
160 
161     /**
162      * The #TOOL_DISPATCHER needs these to work around some issues in wxWidgets where the menu
163      * events aren't captured by the menus themselves.
164      */
165     void OnMenuEvent( wxMenuEvent& event );
166 
167     /**
168      * Register a UI update handler for the control with ID @c aID
169      *
170      * @param aID is the control ID to register the handler for
171      * @param aConditions are the UI conditions to use for the control states
172      */
173     virtual void RegisterUIUpdateHandler( int aID, const ACTION_CONDITIONS& aConditions ) override;
174 
175     /**
176      * Unregister a UI handler for a given ID that was registered using @c RegisterUIUpdateHandler
177      *
178      * @param aID is the control ID to unregister the handler for
179      */
180     virtual void UnregisterUIUpdateHandler( int aID ) override;
181 
182     /**
183      * Handle events generated when the UI is trying to figure out the current state of the
184      * UI controls related to #TOOL_ACTIONS (e.g. enabled, checked, etc.).
185      *
186      * @param aEvent is the wxUpdateUIEvent to be processed.
187      * @param aFrame is the frame to get the selection from
188      * @param aCond are the #UI SELECTION_CONDITIONS used
189      */
190     static void HandleUpdateUIEvent( wxUpdateUIEvent& aEvent, EDA_BASE_FRAME* aFrame,
191                                      ACTION_CONDITIONS aCond );
192 
OnMove(wxMoveEvent & aEvent)193     virtual void OnMove( wxMoveEvent& aEvent )
194     {
195         aEvent.Skip();
196     }
197 
198     virtual void OnSize( wxSizeEvent& aEvent );
199 
200     void OnMaximize( wxMaximizeEvent& aEvent );
201 
202     void SetAutoSaveInterval( int aInterval );
203 
GetAutoSaveInterval()204     int GetAutoSaveInterval() const { return m_autoSaveInterval; }
205 
IsType(FRAME_T aType)206     bool IsType( FRAME_T aType ) const { return m_ident == aType; }
GetFrameType()207     FRAME_T GetFrameType() const { return m_ident; }
208 
209     /**
210      * Return a #SEARCH_STACK pertaining to entire program.
211      *
212      * This is overloaded in #KICAD_MANAGER_FRAME
213      */
214     virtual const SEARCH_STACK& sys_search();
215 
216     virtual wxString help_name();
217 
218     void OnKicadAbout( wxCommandEvent& event );
219 
220     /**
221      * Displays the preferences and settings of all opened editors paged dialog
222      */
223     void OnPreferences( wxCommandEvent& event );
224 
225     void PrintMsg( const wxString& text );
226 
227     void CreateInfoBar();
228 
229     void FinishAUIInitialization();
230 
231     /**
232      * @return the #WX_INFOBAR that can be displayed on the top of the canvas.
233      */
GetInfoBar()234     WX_INFOBAR* GetInfoBar() { return m_infoBar; }
235 
236     /**
237      * Show the #WX_INFOBAR displayed on the top of the canvas with a message and an error
238      * icon on the left of the infobar, and an optional closebox to the right.
239      *
240      * The infobar will be closed after a timeout.
241      *
242      * @param aErrorMsg is the message to display.
243      * @param aShowCloseButton true to show a close button on the right of the #WX_INFOBAR.
244      */
245     void ShowInfoBarError( const wxString& aErrorMsg, bool aShowCloseButton = false,
246                            WX_INFOBAR::MESSAGE_TYPE aType = WX_INFOBAR::MESSAGE_TYPE::GENERIC );
247 
248     /**
249      * Show the #WX_INFOBAR displayed on the top of the canvas with a message and an error
250      * icon on the left of the infobar, and an optional closebox to the right.
251      *
252      * The infobar will be closed after a timeout.
253      *
254      * This version accepts a callback which will be called when the infobar is dismissed
255      * (either as a result of user action or a timeout).  This can be useful when the caller
256      * wants to make other decorations in the canvas to highlight the error.
257      *
258      * @param aErrorMsg is the message to display.
259      * @param aShowCloseButton true to show a close button on the right of the #WX_INFOBAR.
260      * @param aCallback a callback to be called when the infobar is dismissed.
261      */
262     void ShowInfoBarError( const wxString& aErrorMsg, bool aShowCloseButton,
263                            std::function<void(void)> aCallback );
264 
265     /**
266      * Show the #WX_INFOBAR displayed on the top of the canvas with a message and a warning
267      * icon on the left of the infobar.
268      *
269      * The infobar will be closed after a timeout.
270      *
271      * @param aErrorMsg is the message to display.
272      * @param aShowCloseButton true to show a close button on the right of the #WX_INFOBAR.
273      */
274     void ShowInfoBarWarning( const wxString& aWarningMsg, bool aShowCloseButton = false );
275 
276     /**
277      * Show the #WX_INFOBAR displayed on the top of the canvas with a message and an info
278      * icon on the left of the infobar.
279      *
280      * The infobar will be closed after a timeout.
281      *
282      * @param aErrorMsg is the message to display.
283      * @param aShowCloseButton true to show a close button on the right of the #WX_INFOBAR.
284      */
285     void ShowInfoBarMsg( const wxString& aMsg, bool aShowCloseButton = false );
286 
287     /**
288      * Returns the settings object used in SaveSettings(), and is overloaded in
289      * #KICAD_MANAGER_FRAME.
290      */
291     virtual APP_SETTINGS_BASE* config() const;
292 
293     /**
294      * Allow a frame to load its preference panels (if any) into the preferences dialog.
295      *
296      * @param aParent a paged dialog into which the preference panels should be installed.
297      */
InstallPreferences(PAGED_DIALOG *,PANEL_HOTKEYS_EDITOR *)298     virtual void InstallPreferences( PAGED_DIALOG* , PANEL_HOTKEYS_EDITOR* ) { }
299 
300 
301     void LoadWindowState( const wxString& aFileName );
302     /**
303      * Load window settings from the given settings object.
304      *
305      * Normally called by #LoadSettings() unless the window in question is a child window
306      * that* stores its settings somewhere other than #APP_SETTINGS_BASE::m_Window.
307      */
308     void LoadWindowSettings( const WINDOW_SETTINGS* aCfg );
309 
310     /**
311      * Save window settings to the given settings object.
312      *
313      * Normally called by #SaveSettings unless the window in question is a child window that
314      * stores its settings somewhere other than #APP_SETTINGS_BASE::m_Window.
315      */
316     void SaveWindowSettings( WINDOW_SETTINGS* aCfg );
317 
318     /**
319      * Load common frame parameters from a configuration file.
320      *
321      * Don't forget to call the base method or your frames won't remember their positions
322      * and sizes.
323      */
324     virtual void LoadSettings( APP_SETTINGS_BASE* aCfg );
325 
326     /**
327      * Save common frame parameters to a configuration data file.
328      *
329      * Don't forget to call the base class's SaveSettings() from your derived
330      * #SaveSettings() otherwise the frames won't remember their positions and sizes.
331      */
332     virtual void SaveSettings( APP_SETTINGS_BASE* aCfg );
333 
334     /**
335      * Return a pointer to the window settings for this frame.
336      *
337      * By default, points to aCfg->m_Window for top-level frames.
338      *
339      * @param aCfg is this frame's config object
340      */
341     virtual WINDOW_SETTINGS* GetWindowSettings( APP_SETTINGS_BASE* aCfg );
342 
343     /**
344      * Load frame state info from a configuration file
345      */
346     virtual void LoadWindowState( const WINDOW_STATE& aState );
347 
348     /**
349      * Get the configuration base name.
350      *
351      * This is usually the name of the frame set by CTOR, except for frames shown in
352      * multiple modes in which case the m_configName must be set to the base name so
353      * that a single configuration can be used.
354      *
355      * @return a base name prefix used in Load/Save settings to build the full name of keys
356      *         used in configuration.
357      */
ConfigBaseName()358     wxString ConfigBaseName() override
359     {
360         wxString baseCfgName = m_configName.IsEmpty() ? GetName() : m_configName;
361         return baseCfgName;
362     }
363 
364     /**
365      * Save changes to the project settings to the project (.pro) file.
366      *
367      * The method is virtual so you can override it to call the suitable save method.
368      * The base method does nothing.
369      *
370      * @param aAskForSave true to open a dialog before saving the settings.
371      */
SaveProjectSettings()372     virtual void SaveProjectSettings() {};
373 
374     /**
375      * Prompt the user for a hotkey file to read, and read it.
376      *
377      * @param aActionMap current hotkey map (over which the imported hotkeys will be applied).
378      * @param aDefaultShortname a default short name (extension not needed) like
379      *                          Eeschema, KiCad...
380      */
381     void ImportHotkeyConfigFromFile( std::map<std::string, TOOL_ACTION*> aActionMap,
382                                      const wxString& aDefaultShortname );
383 
384     /**
385      * Fetches the file name from the file history list.
386      *
387      * This removes the selected file, if this file does not exist.  The menu is also updated,
388      * if #FILE_HISTORY::UseMenu was called at initialization time.
389      *
390      * @param cmdId The command ID associated with the \a aFileHistory object.
391      * @param type Please document me!
392      * @param aFileHistory The FILE_HISTORY in use. If null, the main application file
393      *                     history is used
394      * @return a wxString containing the selected filename
395      */
396     wxString GetFileFromHistory( int cmdId, const wxString& type,
397                                  FILE_HISTORY* aFileHistory = nullptr );
398 
399     /**
400      * Removes all files from the file history.
401      *
402      * @param aFileHistory The FILE_HISTORY in use. If null, the main application file
403      *                     history is used
404      */
405     void ClearFileHistory( FILE_HISTORY* aFileHistory = nullptr );
406 
407     /**
408      * Update the list of recently opened files.
409      *
410      * The menu is also updated, if FILE_HISTORY::UseMenu was called at init time.
411      *
412      * @param FullFileName The full file name including the path.
413      * @param aFileHistory The FILE_HISTORY in use.  If NULL, the main application file
414      *                     history is used.
415      */
416     void UpdateFileHistory( const wxString& FullFileName, FILE_HISTORY* aFileHistory = nullptr );
417 
418     /**
419      * Get the frame's main file history.
420      *
421      * @return the main file history
422      */
GetFileHistory()423     FILE_HISTORY& GetFileHistory()
424     {
425         return *m_fileHistory;
426     }
427 
SetMruPath(const wxString & aPath)428     void SetMruPath( const wxString& aPath ) { m_mruPath = aPath; }
429 
GetMruPath()430     wxString GetMruPath() const { return m_mruPath; }
431 
432     /**
433      * Get the full filename + path of the currently opened file in the frame.
434      *
435      * If no file is open, an empty string is returned.
436      *
437      * @return the filename and full path to the open file
438      */
GetCurrentFileName()439     virtual wxString GetCurrentFileName() const { return wxEmptyString; }
440 
441     /**
442      * Recreates the menu bar.
443      *
444      * Needed when the language or icons are changed
445      */
446     virtual void ReCreateMenuBar();
447 
448     /**
449      * Adds the standard KiCad help menu to the menubar.
450      */
451     void AddStandardHelpMenu( wxMenuBar* aMenuBar );
452 
453     /**
454      * Checks if \a aFileName can be written.
455      *
456      * The function performs a number of tests on \a aFileName to verify that it can be saved.
457      * If \a aFileName defines a path with no file name, them the path is tested for user write
458      * permission.  If \a aFileName defines a file name that does not exist in the path, the
459      * path is tested for user write permission.  If \a aFileName defines a file that already
460      * exits, the file name is tested for user write permissions.
461      *>
462      * @note The file name path must be set or an assertion will be raised on debug builds and
463      *       return false on release builds.
464      * @param aFileName The full path and/or file name of the file to test.
465      * @param aVerbose If true will show an error dialog if the file is not writable
466      * @return False if \a aFileName cannot be written.
467      */
468     bool IsWritable( const wxFileName& aFileName, bool aVerbose = true );
469 
470     /**
471      * Check if an auto save file exists for \a aFileName and takes the appropriate action
472      * depending on the user input.
473      *
474      * If an auto save file exists for \a aFileName, the user is prompted if they wish to
475      * replace file \a aFileName with the auto saved file.  If the user chooses to replace the
476      * file, the backup file of \a aFileName is removed, \a aFileName is renamed to the backup
477      * file name, and the auto save file is renamed to \a aFileName.  If user chooses to keep
478      * the existing version of \a aFileName, the auto save file is removed.
479      *
480      * @param aFileName A wxFileName object containing the file name to check.
481      */
482     virtual void CheckForAutoSaveFile( const wxFileName& aFileName );
483 
484     /**
485      * Update the status bar information.
486      *
487      * The status bar can draw itself.  This is not a drawing function per se, but rather
488      * updates lines of text held by the components within the status bar which is owned
489      * by the wxFrame.
490      */
UpdateStatusBar()491     virtual void UpdateStatusBar() { }
492 
493     /**
494      * Redraw the menus and what not in current language.
495      */
496     void ShowChangedLanguage() override;
497 
498     /**
499      * Notification event that some of the common (suite-wide) settings have changed.
500      * Update menus, toolbars, local variables, etc.
501      */
502     void CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged ) override;
503 
504     /**
505      * Process light/dark theme change.
506      */
507     virtual void ThemeChanged();
508 
509     /**
510      * Notification event that the project has changed.
511      */
ProjectChanged()512     virtual void ProjectChanged() {}
513 
GetAboutTitle()514     const wxString& GetAboutTitle() const { return m_aboutTitle; }
515 
516     /**
517      * Get if the contents of the frame have been modified since the last save.
518      *
519      * @return true if the contents of the frame have not been saved
520      */
521     virtual bool IsContentModified() const;
522 
523     /**
524      * Get the undecorated window size that can be used for restoring the window size.
525      *
526      * This is needed for GTK, since the normal wxWidgets GetSize() call will return
527      * a window size that includes the window decorations added by the window manager.
528      *
529      * @return the undecorated window size
530      */
531     wxSize GetWindowSize();
532 
533     /**
534      * Remove the \a aItemCount of old commands from \a aList and delete commands, pickers
535      * and picked items if needed.
536      *
537      * Because picked items must be deleted only if they are not in use, this is a virtual
538      * pure function that must be created for #SCH_SCREEN and #PCB_SCREEN.  Commands are
539      * deleted from the older to the last.
540      *
541      * @param aList = the #UNDO_REDO_CONTAINER of commands.
542      * @param aItemCount number of old commands to delete. -1 to remove all old commands
543      *                   this will empty the list of commands.
544      */
545     virtual void ClearUndoORRedoList( UNDO_REDO_LIST aList, int aItemCount = -1 )
546     { }
547 
548     /**
549      * Clear the undo and redo list using #ClearUndoORRedoList()
550      *
551      * Picked items are deleted by ClearUndoORRedoList() according to their status.
552      */
553     virtual void ClearUndoRedoList();
554 
555     /**
556      * Add a command to undo in the undo list.
557      *
558      * Delete the very old commands when the max count of undo commands is reached.
559      */
560     virtual void PushCommandToUndoList( PICKED_ITEMS_LIST* aItem );
561 
562     /**
563      * Add a command to redo in the redo list.
564      *
565      * Delete the very old commands when the max count of redo commands is reached.
566      */
567     virtual void PushCommandToRedoList( PICKED_ITEMS_LIST* aItem );
568 
569     /**
570      * Return the last command to undo and remove it from list, nothing is deleted.
571      */
572     virtual PICKED_ITEMS_LIST* PopCommandFromUndoList();
573 
574     /**
575      * Return the last command to undo and remove it from list, nothing is deleted.
576      */
577     virtual PICKED_ITEMS_LIST* PopCommandFromRedoList();
578 
GetUndoCommandCount()579     virtual int GetUndoCommandCount() const { return m_undoList.m_CommandsList.size(); }
GetRedoCommandCount()580     virtual int GetRedoCommandCount() const { return m_redoList.m_CommandsList.size(); }
581 
GetMaxUndoItems()582     int GetMaxUndoItems() const { return m_undoRedoCountMax; }
583 
NonUserClose(bool aForce)584     bool NonUserClose( bool aForce )
585     {
586         m_isNonUserClose = true;
587         return Close( aForce );
588     }
589 
590     /**
591      * Update the UI in response to a change in the system colors.
592      */
593     virtual void HandleSystemColorChange();
594 
595 protected:
596     ///< Default style flags used for wxAUI toolbars.
597     static constexpr int KICAD_AUI_TB_STYLE = wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_PLAIN_BACKGROUND;
598 
599     /**
600      * @return the string to prepend to a file name for automatic save.
601      */
GetAutoSaveFilePrefix()602     static wxString GetAutoSaveFilePrefix()
603     {
604         return wxT( "_autosave-" );
605     }
606 
607     /**
608      * Handle the auto save timer event.
609      */
610     void onAutoSaveTimer( wxTimerEvent& aEvent );
611 
612     /**
613      * Return the auto save status of the application.
614      *
615      * Override this function if your derived frame supports automatic file saving.
616      */
isAutoSaveRequired()617     virtual bool isAutoSaveRequired() const { return false; }
618 
619     /**
620      * This should be overridden by the derived class to handle the auto save feature.
621      *
622      * @return true if the auto save was successful otherwise false.
623      */
624     virtual bool doAutoSave();
625 
canCloseWindow(wxCloseEvent & aCloseEvent)626     virtual bool canCloseWindow( wxCloseEvent& aCloseEvent ) { return true; }
doCloseWindow()627     virtual void doCloseWindow() { }
628 
629     void onSystemColorChange( wxSysColourChangedEvent& aEvent );
630 
631     /**
632      * Called when when the units setting has changed to allow for any derived classes
633      * to handle refreshing and controls that have units based measurements in them.
634      *
635      * The default version only updates the status bar.  Don't forget to call the default
636      * in your derived class or the status bar will not get updated properly.
637      */
unitsChangeRefresh()638     virtual void unitsChangeRefresh() { }
639 
640     /**
641      * Setup the UI conditions for the various actions and their controls in this frame.
642      */
643     virtual void setupUIConditions();
644 
645     /**
646      * Sets the common key-pair for exiting the application (Ctrl-Q) and ties it
647      * to the wxID_EXIT event id.
648      *
649      * This is useful in sub-applications to pass the event up to a non-owning window.
650      */
651     void initExitKey();
652 
653     void ensureWindowIsOnScreen();
654 
655     DECLARE_EVENT_TABLE()
656 
657 private:
658     /**
659      * (with its unexpected name so it does not collide with the real OnWindowClose()
660      * function provided in derived classes) is called just before a window
661      * closing, and is used to call a derivation specific SaveSettings().
662      *
663      * #SaveSettings() is called for all derived wxFrames in this base class overload.
664      * Calling it from a destructor is deprecated since the wxFrame's position is not
665      * available in the destructor on linux.  In other words, you should not need to
666      * call #SaveSettings() anywhere, except in this one function found only in this class.
667      */
668     void windowClosing( wxCloseEvent& event );
669 
670     /**
671      * Collect common initialization functions used in all CTORs
672      */
673     void commonInit( FRAME_T aFrameType );
674 
675     wxWindow* findQuasiModalDialog();
676 
677     /**
678      * Return true if the frame is shown in our modal mode and false  if the frame is
679      * shown as an usual frame.
680      *
681      * In modal mode, the caller that created the frame is responsible to Destroy()
682      * this frame after closing.
683      */
IsModal()684     virtual bool IsModal() const { return false; }
685 
686 #ifdef _WIN32
687     /**
688      * Windows specific override of the wxWidgets message handler for a window
689      */
690     WXLRESULT MSWWindowProc( WXUINT message, WXWPARAM wParam, WXLPARAM lParam ) override;
691 #endif
692 
693  protected:
694     FRAME_T         m_ident;                // Id Type (pcb, schematic, library..)
695     wxPoint         m_framePos;
696     wxSize          m_frameSize;
697     bool            m_maximizeByDefault;
698     int             m_displayIndex;
699 
700     // These contain the frame size and position for when it is not maximized
701     wxPoint         m_normalFramePos;
702     wxSize          m_normalFrameSize;
703 
704     wxString        m_aboutTitle;           // Name of program displayed in About.
705 
706     wxAuiManager    m_auimgr;
707     wxString        m_perspective;          // wxAuiManager perspective.
708 
709     WX_INFOBAR*     m_infoBar;              // Infobar for the frame
710 
711     wxString        m_configName;           // Prefix used to identify some params (frame size...)
712                                             // and to name some config files (legacy hotkey files)
713 
714     SETTINGS_MANAGER* m_settingsManager;
715 
716     FILE_HISTORY*   m_fileHistory;          // The frame's recently opened file list
717 
718     bool            m_hasAutoSave;
719     bool            m_autoSaveState;
720     int             m_autoSaveInterval;     // The auto save interval time in seconds.
721     wxTimer*        m_autoSaveTimer;
722 
723     int             m_undoRedoCountMax;     // undo/Redo command Max depth
724 
725     UNDO_REDO_CONTAINER m_undoList;         // Objects list for the undo command (old data)
726     UNDO_REDO_CONTAINER m_redoList;         // Objects list for the redo command (old data)
727 
728     wxString        m_mruPath;              // Most recently used path.
729 
730     EDA_UNITS       m_userUnits;
731 
732     ///< Map containing the UI update handlers registered with wx for each action.
733     std::map<int, UIUpdateHandler> m_uiUpdateMap;
734 
735     ///< Set by the close window event handler after frames are asked if they can close.
736     ///< Allows other functions when called to know our state is cleanup.
737     bool            m_isClosing;
738 
739     ///< Set by #NonUserClose() to indicate that the user did not request the current close.
740     bool            m_isNonUserClose;
741 
742 };
743 
744 
745 /**
746  * Specialization of the wxAuiPaneInfo class for KiCad panels.
747  *
748  * Documentation for wxAui is poor at this time. The following notes spring from errors made in
749  * previous KiCad implementations:
750  *
751  * wxAuiPaneInfo.ToolbarPane() and .Defaults() are used to clear and then prepare the objects so
752  * only use them once at the beginning of configuration..
753  *
754  * Panels are organized in layers, from 0 (close to the center) and increasing outward. Note
755  * that for ToolbarPanes, layer 0 considered a special default value, and ToolbarPanes on
756  * layer 0 are pushed to layer 10 automatically. Use Layer 1 for the inner layer as a work-
757  * around.
758  *
759  * Each panel has rows, starting at 0. Each row has positions starting at 0. Each item in a panel
760  * can have its row and position set.
761  *
762  * Eventually panels will be movable. Each initialization function sets up the panel for this,
763  * then after a //==// break has additional calls to anchor toolbars in a way that matches
764  * present functionality.
765  */
766 class EDA_PANE : public wxAuiPaneInfo
767 {
768 public:
EDA_PANE()769     EDA_PANE()
770     {
771         Gripper( false );
772         CloseButton( false );
773         PaneBorder( false );
774     }
775 
776     /**
777      * Turn *this to a horizontal toolbar for KiCad.
778      */
HToolbar()779     EDA_PANE& HToolbar()
780     {
781         SetFlag( optionToolbar, true );
782         CaptionVisible( false );
783         TopDockable().BottomDockable();
784         DockFixed( true );
785         Movable( false );
786         Resizable( true );      // expand to fit available space
787         return *this;
788     }
789 
790     /**
791      * Turn *this into a vertical toolbar for KiCad.
792      */
VToolbar()793     EDA_PANE& VToolbar()
794     {
795         SetFlag( optionToolbar, true );
796         CaptionVisible( false );
797         LeftDockable().RightDockable();
798         DockFixed( true );
799         Movable( false );
800         Resizable( true );      // expand to fit available space
801         return *this;
802     }
803 
804     /**
805      * Turn *this into a captioned palette suitable for a symbol tree, layers manager, etc.
806      */
Palette()807     EDA_PANE& Palette()
808     {
809         CaptionVisible( true );
810         PaneBorder( true );
811         return *this;
812     }
813 
814     /**
815      * Turn *this into an undecorated pane suitable for a drawing canvas.
816      */
Canvas()817     EDA_PANE& Canvas()
818     {
819         CaptionVisible( false );
820         Layer( 0 );
821         PaneBorder( true );
822         Resizable( true );      // expand to fit available space
823         return *this;
824     }
825 
826     /**
827      * Turn *this into a messages pane for KiCad.
828      */
Messages()829     EDA_PANE& Messages()
830     {
831         CaptionVisible( false );
832         BottomDockable( true );
833         DockFixed( true );
834         Movable( false );
835         Resizable( true );      // expand to fit available space
836         return *this;
837     }
838 
839     /**
840      * Turn *this into a infobar for KiCad.
841      */
InfoBar()842     EDA_PANE& InfoBar()
843     {
844         CaptionVisible( false );
845         Movable( false );
846         Resizable( true );
847         PaneBorder( false );
848         DockFixed( true );
849         return *this;
850     }
851 };
852 
853 #endif  // EDA_BASE_FRAME_H_
854