Add clear recent files action to the menus

ADDED: Menu item to allow the recent file lists in each program to be
cleared

Fixes: lp:1821685
* https://bugs.launchpad.net/kicad/+bug/1821685
This commit is contained in:
Ian McInerney 2019-11-23 16:54:48 +00:00
parent c34dfc4230
commit 99b9354a51
23 changed files with 434 additions and 157 deletions

View File

@ -289,6 +289,7 @@ set( COMMON_SRCS
exceptions.cpp
executable_names.cpp
filename_resolver.cpp
filehistory.cpp
filter_reader.cpp
footprint_filter.cpp
footprint_info.cpp

View File

@ -24,8 +24,9 @@
#include <bin_mod.h>
#include <common.h>
#include <pgm_base.h>
#include <filehistory.h>
#include <id.h> // for ID_FILE1 and FILE_HISTORY_SIZE
#include <pgm_base.h>
BIN_MOD::BIN_MOD( const char* aName ) :

View File

@ -42,6 +42,7 @@
#include <tool/action_manager.h>
#include <menus_helpers.h>
#include <tool/actions.h>
#include <filehistory.h>
/// The default auto save interval is 10 minutes.
@ -561,10 +562,9 @@ void EDA_BASE_FRAME::PrintMsg( const wxString& text )
}
void EDA_BASE_FRAME::UpdateFileHistory( const wxString& FullFileName,
wxFileHistory* aFileHistory )
void EDA_BASE_FRAME::UpdateFileHistory( const wxString& FullFileName, FILE_HISTORY* aFileHistory )
{
wxFileHistory* fileHistory = aFileHistory;
FILE_HISTORY* fileHistory = aFileHistory;
if( !fileHistory )
fileHistory = &Kiface().GetFileHistory();
@ -574,9 +574,9 @@ void EDA_BASE_FRAME::UpdateFileHistory( const wxString& FullFileName,
wxString EDA_BASE_FRAME::GetFileFromHistory( int cmdId, const wxString& type,
wxFileHistory* aFileHistory )
FILE_HISTORY* aFileHistory )
{
wxFileHistory* fileHistory = aFileHistory;
FILE_HISTORY* fileHistory = aFileHistory;
if( !fileHistory )
fileHistory = &Kiface().GetFileHistory();

View File

@ -51,6 +51,7 @@
#include <tool/grid_menu.h>
#include <tool/common_tools.h>
#include <dialog_shim.h>
#include <filehistory.h>
///@{

145
common/filehistory.cpp Normal file
View File

@ -0,0 +1,145 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <filehistory.h>
#include <id.h>
#include <tool/action_menu.h>
#include <tool/selection_conditions.h>
#include <wx/menu.h>
#include <functional>
using namespace std::placeholders;
FILE_HISTORY::FILE_HISTORY( size_t aMaxFiles, int aBaseFileId ) :
wxFileHistory( std::min( aMaxFiles, (size_t) MAX_FILE_HISTORY_SIZE ) )
{
SetBaseId( aBaseFileId );
}
void FILE_HISTORY::SetMaxFiles( size_t aMaxFiles )
{
m_fileMaxFiles = std::min( aMaxFiles, (size_t) MAX_FILE_HISTORY_SIZE );
size_t numFiles = m_fileHistory.size();
while( numFiles > m_fileMaxFiles )
RemoveFileFromHistory( --numFiles );
}
void FILE_HISTORY::AddFileToHistory( const wxString &aFile )
{
wxFileHistory::AddFileToHistory( aFile );
// Iterate over each menu associated with this file history, and if it is one of our
// FILE_HISTORY_MENUs, we force it to be refreshed (so that the items are all in the
// correct locations).
for( wxList::compatibility_iterator node = m_fileMenus.GetFirst();
node; node = node->GetNext() )
{
wxMenu* menu = static_cast<wxMenu*>( node->GetData() );
FILE_HISTORY_MENU* fileMenu = dynamic_cast<FILE_HISTORY_MENU*>( menu );
if( fileMenu )
fileMenu->RefreshMenu();
}
}
SELECTION_CONDITION FILE_HISTORY::FileHistoryNotEmpty( const FILE_HISTORY& aHistory )
{
return std::bind( &FILE_HISTORY::isHistoryNotEmpty, _1, std::cref( aHistory ) );
}
bool FILE_HISTORY::isHistoryNotEmpty( const SELECTION& aSelection, const FILE_HISTORY& aHistory )
{
return aHistory.GetCount() != 0;
}
FILE_HISTORY_MENU::FILE_HISTORY_MENU( FILE_HISTORY& aHistory, wxString aClearText ) :
ACTION_MENU( false ),
m_fileHistory( aHistory ),
m_clearText( aClearText )
{
m_fileHistory.UseMenu( this );
buildMenu();
}
FILE_HISTORY_MENU::~FILE_HISTORY_MENU()
{
m_fileHistory.RemoveMenu( this );
}
void FILE_HISTORY_MENU::RefreshMenu()
{
// We have to manually delete all menu items before we rebuild the menu
for( int i = GetMenuItemCount() - 1; i >= 0; --i )
Destroy( FindItemByPosition( i ) );
buildMenu();
}
void FILE_HISTORY_MENU::buildMenu()
{
if( m_fileHistory.GetCount() == 0 )
{
// If the history is empty, we create an item to say there are no files
wxMenuItem* item = new wxMenuItem( this, wxID_ANY, _( "No Files" ) );
Append( item );
Enable( item->GetId(), false );
}
else
m_fileHistory.AddFilesToMenu( this );
wxMenuItem* clearItem = new wxMenuItem( this, ID_FILE_LIST_CLEAR, m_clearText );
AppendSeparator();
Append( clearItem );
Connect( ID_FILE_LIST_CLEAR, wxEVT_COMMAND_MENU_SELECTED,
wxMenuEventHandler( FILE_HISTORY_MENU::onClearEntries ), NULL, this );
}
void FILE_HISTORY_MENU::onClearEntries( wxMenuEvent& aEvent )
{
while( m_fileHistory.GetCount() > 0 )
m_fileHistory.RemoveFileFromHistory( 0 );
RefreshMenu();
}
ACTION_MENU* FILE_HISTORY_MENU::create() const
{
return new FILE_HISTORY_MENU( m_fileHistory, m_clearText );
}

View File

@ -110,24 +110,6 @@ LANGUAGE_DESCR LanguagesList[] =
#define _(s) wxGetTranslation((s))
FILE_HISTORY::FILE_HISTORY( size_t aMaxFiles, int aBaseFileId ) :
wxFileHistory( std::min( aMaxFiles, (size_t) MAX_FILE_HISTORY_SIZE ) )
{
SetBaseId( aBaseFileId );
}
void FILE_HISTORY::SetMaxFiles( size_t aMaxFiles )
{
m_fileMaxFiles = std::min( aMaxFiles, (size_t) MAX_FILE_HISTORY_SIZE );
size_t numFiles = m_fileHistory.size();
while( numFiles > m_fileMaxFiles )
RemoveFileFromHistory( --numFiles );
}
PGM_BASE::PGM_BASE()
{
m_pgm_checker = NULL;

View File

@ -24,6 +24,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <filehistory.h>
#include <kiface_i.h>
#include <menus_helpers.h>
#include <pgm_base.h>
@ -52,27 +53,26 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
//-- File menu -----------------------------------------------------------
//
CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, selTool );
static ACTION_MENU* openRecentMenu;
CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, selTool );
static FILE_HISTORY_MENU* openRecentMenu;
if( Kiface().IsSingle() ) // not when under a project mgr
{
// Add this menu to list menu managed by m_fileHistory
// (the file history will be updated when adding/removing files in history)
if( openRecentMenu )
Kiface().GetFileHistory().RemoveMenu( openRecentMenu );
FILE_HISTORY& fileHistory = Kiface().GetFileHistory();
openRecentMenu = new ACTION_MENU( false );
openRecentMenu->SetTool( selTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( recent_xpm );
Kiface().GetFileHistory().UseMenu( openRecentMenu );
Kiface().GetFileHistory().AddFilesToMenu( openRecentMenu );
// Create the menu if it does not exist. Adding a file to/from the history
// will automatically refresh the menu.
if( !openRecentMenu )
{
openRecentMenu = new FILE_HISTORY_MENU( fileHistory );
openRecentMenu->SetTool( selTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( recent_xpm );
}
fileMenu->AddItem( ACTIONS::doNew, EE_CONDITIONS::ShowAlways );
fileMenu->AddItem( ACTIONS::open, EE_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentMenu, EE_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentMenu, FILE_HISTORY::FileHistoryNotEmpty( fileHistory ) );
fileMenu->AddSeparator();
}

View File

@ -317,6 +317,12 @@ SCH_EDIT_FRAME::~SCH_EDIT_FRAME()
g_CurrentSheet = nullptr;
g_ConnectionGraph = nullptr;
g_RootSheet = NULL;
// Since the file menu contains file history menus, we must ensure that the menu
// destructor is called before the file history objects are deleted since their destructor
// unregisters the menu from the history.
wxMenu* fileMenu = GetMenuBar()->Remove( 0 );
delete fileMenu;
}

View File

@ -226,6 +226,12 @@ GERBVIEW_FRAME::~GERBVIEW_FRAME()
GetGerberLayout()->GetImagesList()->DeleteAllImages();
delete m_gerberLayout;
// Since the file menu contains file history menus, we must ensure that the menu
// destructor is called before the file history objects are deleted since their destructor
// unregisters the menu from the history.
wxMenu* fileMenu = GetMenuBar()->Remove( 0 );
delete fileMenu;
}

View File

@ -22,7 +22,7 @@
#ifndef WX_GERBER_STRUCT_H
#define WX_GERBER_STRUCT_H
#include <filehistory.h>
#include <pgm_base.h>
#include <config_params.h>
#include <eda_draw_frame.h>

View File

@ -46,80 +46,77 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
//-- File menu -------------------------------------------------------
//
CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, selTool );
static ACTION_MENU* openRecentGbrMenu;
static ACTION_MENU* openRecentDrlMenu;
static ACTION_MENU* openRecentJobMenu;
static ACTION_MENU* openRecentZipMenu;
CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, selTool );
static FILE_HISTORY_MENU* openRecentGbrMenu;
static FILE_HISTORY_MENU* openRecentDrlMenu;
static FILE_HISTORY_MENU* openRecentJobMenu;
static FILE_HISTORY_MENU* openRecentZipMenu;
FILE_HISTORY& recentGbrFiles = Kiface().GetFileHistory();
// Add this menu to list menu managed by m_fileHistory
// (the file history will be updated when adding/removing files in history)
if( openRecentGbrMenu )
Kiface().GetFileHistory().RemoveMenu( openRecentGbrMenu );
openRecentGbrMenu = new ACTION_MENU( false );
openRecentGbrMenu->SetTool( selTool );
openRecentGbrMenu->SetTitle( _( "Open Recent Gerber" ) );
openRecentGbrMenu->SetIcon( recent_xpm );
// Create the gerber file menu if it does not exist. Adding a file to/from the history
// will automatically refresh the menu.
if( !openRecentGbrMenu )
{
openRecentGbrMenu =
new FILE_HISTORY_MENU( recentGbrFiles, _( "Clear Recent Gerber Files" ) );
openRecentGbrMenu->SetTool( selTool );
openRecentGbrMenu->SetTitle( _( "Open Recent Gerber File" ) );
openRecentGbrMenu->SetIcon( recent_xpm );
}
Kiface().GetFileHistory().UseMenu( openRecentGbrMenu );
Kiface().GetFileHistory().AddFilesToMenu();
// Create the drill file menu if it does not exist. Adding a file to/from the history
// will automatically refresh the menu.
if( !openRecentDrlMenu )
{
openRecentDrlMenu =
new FILE_HISTORY_MENU( m_drillFileHistory, _( "Clear Recent Drill Files" ) );
openRecentDrlMenu->SetTool( selTool );
openRecentDrlMenu->SetTitle( _( "Open Recent Drill File" ) );
openRecentDrlMenu->SetIcon( recent_xpm );
}
// Add drill file menu and the drill file history
if( openRecentDrlMenu )
m_drillFileHistory.RemoveMenu( openRecentDrlMenu );
// Create the job file menu if it does not exist. Adding a file to/from the history
// will automatically refresh the menu.
if( !openRecentJobMenu )
{
openRecentJobMenu =
new FILE_HISTORY_MENU( m_jobFileHistory, _( "Clear Recent Job Files" ) );
openRecentJobMenu->SetTool( selTool );
openRecentJobMenu->SetTitle( _( "Open Recent Job File" ) );
openRecentJobMenu->SetIcon( recent_xpm );
}
openRecentDrlMenu = new ACTION_MENU( false );
openRecentDrlMenu->SetTool( selTool );
openRecentDrlMenu->SetTitle( _( "Open Recent Drill File" ) );
openRecentDrlMenu->SetIcon( recent_xpm );
m_drillFileHistory.UseMenu( openRecentDrlMenu );
m_drillFileHistory.AddFilesToMenu( );
// Add job file menu and the job file history
if( openRecentJobMenu )
m_jobFileHistory.RemoveMenu( openRecentJobMenu );
openRecentJobMenu = new ACTION_MENU( false );
openRecentJobMenu->SetTool( selTool );
openRecentJobMenu->SetTitle( _( "Open Recent Job" ) );
openRecentJobMenu->SetIcon( recent_xpm );
m_jobFileHistory.UseMenu( openRecentJobMenu );
m_jobFileHistory.AddFilesToMenu( );
// Add zip file menu and the zip file history
if( openRecentZipMenu )
m_zipFileHistory.RemoveMenu( openRecentZipMenu );
openRecentZipMenu = new ACTION_MENU( false );
openRecentZipMenu->SetTool( selTool );
openRecentZipMenu->SetTitle( _( "Open Recent Zip" ) );
openRecentZipMenu->SetIcon( recent_xpm );
m_zipFileHistory.UseMenu( openRecentZipMenu );
m_zipFileHistory.AddFilesToMenu( );
// Create the zip file menu if it does not exist. Adding a file to/from the history
// will automatically refresh the menu.
if( !openRecentZipMenu )
{
openRecentZipMenu =
new FILE_HISTORY_MENU( m_zipFileHistory, _( "Clear Recent Zip Files" ) );
openRecentZipMenu->SetTool( selTool );
openRecentZipMenu->SetTitle( _( "Open Recent Zip File" ) );
openRecentZipMenu->SetIcon( recent_xpm );
}
fileMenu->AddItem( wxID_FILE, _( "Open &Gerber File(s)..." ),
_( "Open Gerber file(s) on the current layer. Previous data will be deleted" ),
load_gerber_xpm, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentGbrMenu, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentGbrMenu, FILE_HISTORY::FileHistoryNotEmpty( recentGbrFiles ) );
fileMenu->AddItem( ID_GERBVIEW_LOAD_DRILL_FILE, _( "Open &Excellon Drill File(s)..." ),
_( "Open Excellon drill file(s) on the current layer. Previous data will be deleted" ),
gerbview_drill_file_xpm, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentDrlMenu, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentDrlMenu, FILE_HISTORY::FileHistoryNotEmpty( m_drillFileHistory ) );
fileMenu->AddItem( ID_GERBVIEW_LOAD_JOB_FILE, _( "Open Gerber &Job File..." ),
_( "Open a Gerber job file and its associated gerber files" ),
gerber_job_file_xpm, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentJobMenu, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentJobMenu, FILE_HISTORY::FileHistoryNotEmpty( m_jobFileHistory ) );
fileMenu->AddItem( ID_GERBVIEW_LOAD_ZIP_ARCHIVE_FILE, _( "Open &Zip Archive File..." ),
_( "Open a zipped archive (Gerber and Drill) file" ),
zip_xpm, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentZipMenu, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentZipMenu, FILE_HISTORY::FileHistoryNotEmpty( m_zipFileHistory ) );
fileMenu->AddSeparator();
fileMenu->AddItem( ID_GERBVIEW_ERASE_ALL, _( "Clear &All Layers" ),

View File

@ -75,6 +75,7 @@ class ACTIONS;
class PAGED_DIALOG;
class DIALOG_EDIT_LIBRARY_TABLES;
class PANEL_HOTKEYS_EDITOR;
class FILE_HISTORY;
enum id_librarytype {
@ -328,7 +329,7 @@ public:
virtual void SaveSettings( wxConfigBase* aCfg );
/**
* @return a base name prefix used in Load/Save settings to build the full name of keys
* @return a base name prefix used in Load/Save settings to build the full name of keys
* used in config.
* This is usually the name of the frame set by CTOR, except for frames shown in multiple
* modes in which case the m_configName must be set to the base name so that a single
@ -365,27 +366,27 @@ public:
* Fetches the file name from the file history list.
*
* This removes the selected file, if this file does not exist. The menu is also updated,
* if wxFileHistory::UseMenu was called at init time
* if FILE_HISTORY::UseMenu was called at init time
*
* @param cmdId The command ID associated with the \a aFileHistory object.
* @param type Please document me!
* @param aFileHistory The wxFileHistory in use. If null, the main application file
* @param aFileHistory The FILE_HISTORY in use. If null, the main application file
* history is used
* @return a wxString containing the selected filename
*/
wxString GetFileFromHistory( int cmdId, const wxString& type,
wxFileHistory* aFileHistory = NULL );
FILE_HISTORY* aFileHistory = NULL );
/**
* Update the list of recently opened files.
*
* The menu is also updated, if wxFileHistory::UseMenu was called at init time.
* The menu is also updated, if FILE_HISTORY::UseMenu was called at init time.
*
* @param FullFileName The full file name including the path.
* @param aFileHistory The wxFileHistory in use.
* @param aFileHistory The FILE_HISTORY in use.
* If NULL, the main application file history is used.
*/
void UpdateFileHistory( const wxString& FullFileName, wxFileHistory * aFileHistory = NULL );
void UpdateFileHistory( const wxString& FullFileName, FILE_HISTORY* aFileHistory = NULL );
void SetMruPath( const wxString& aPath ) { m_mruPath = aPath; }
@ -436,14 +437,14 @@ public:
/**
* Update the status bar information.
*
* The status bar can draw itself. This is not a drawing function per se, but rather
* updates lines of text held by the components within the status bar which is owned
* The status bar can draw itself. This is not a drawing function per se, but rather
* updates lines of text held by the components within the status bar which is owned
* by the wxFrame.
*/
virtual void UpdateStatusBar() { }
/**
* Update the toolbars (mostly settings/check buttons/checkboxes) with the current
* Update the toolbars (mostly settings/check buttons/checkboxes) with the current
* controller state.
*/
virtual void SyncToolbars() { };
@ -458,7 +459,7 @@ public:
* Update menus, toolbars, local variables, etc.
*/
virtual void CommonSettingsChanged( bool aEnvVarsChanged );
/**
* Notification to refresh the drawing canvas (if any).
*/

125
include/filehistory.h Normal file
View File

@ -0,0 +1,125 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef FILEHISTORY_H_
#define FILEHISTORY_H_
#include <tool/action_menu.h>
#include <tool/selection_conditions.h>
#include <wx/filehistory.h>
#include <wx/menu.h>
/**
* This class implements a file history object to store a list of files, that can then
* be added to a menu.
*
* This class extends the wxWidgets wxFileHistory class to include KiCad specific items.
*/
class FILE_HISTORY : public wxFileHistory
{
public:
/**
* Create a file history object to store a list of files and add them to a menu.
*
* @param aMaxFiles is the number of files to store in the history
* @param aBaseFileId is the ID to use for the first file menu item
*/
FILE_HISTORY( size_t aMaxFiles, int aBaseFileId );
/**
* Adds a file to the history.
*
* This function overrides the default wxWidgets method to iterate through all
* menus associated with the file history, and if they are of the FILE_HISTORY_MENU
* type, call their RefreshMenu() function to update the menu display.
*
* @param aFile is the filename of the file to add to the history.
*/
void AddFileToHistory( const wxString &aFile ) override;
/**
* Update the number of files that will be contained inside the file history.
*
* @param aMaxFiles is the new number of files for the history
*/
void SetMaxFiles( size_t aMaxFiles );
/**
* Create a SELECTION_CONDITION that can be used to enable a menu item when the
* file history has items in it.
*
* @param aHistory is the file history to check for items
* @return the selection condition function
*/
static SELECTION_CONDITION FileHistoryNotEmpty( const FILE_HISTORY& aHistory );
private:
static bool isHistoryNotEmpty( const SELECTION& aSelection, const FILE_HISTORY& aHistory );
};
/**
* This class implements a menu container for a file history. It adds in the ability to clear
* the file history through a menu item.
*/
class FILE_HISTORY_MENU : public ACTION_MENU
{
public:
/**
* Create the file history menu.
*
* @param aHistory is the file history to use in the menu
* @param aClearText is the text to use for the menu item that clears the history.
*/
FILE_HISTORY_MENU( FILE_HISTORY& aHistory, wxString aClearText = _( "Clear Recent Files" ) );
~FILE_HISTORY_MENU();
/**
* Refresh the menu. This removes all entries from the menu and readds them, to ensure that the
* clear menu item is at the bottom of the menu.
*/
void RefreshMenu();
private:
//! @copydoc ACTION_MENU::create()
ACTION_MENU* create() const override;
/**
* Construct the menu by adding the file history and menu items.
*/
void buildMenu();
/**
* Event handler for when the clear menu item is activated.
*
* @param aEvent the menu event
*/
void onClearEntries( wxMenuEvent& aEvent );
FILE_HISTORY& m_fileHistory;
wxString m_clearText;
};
#endif

View File

@ -88,6 +88,7 @@ enum main_id
ID_FILE,
ID_FILE1,
ID_FILEMAX = ID_FILE + MAX_FILE_HISTORY_SIZE,
ID_FILE_LIST_CLEAR,
ID_MENU_CANVAS_OPENGL,
ID_MENU_CANVAS_CAIRO,

View File

@ -34,7 +34,6 @@
#include <map>
#include <memory>
#include <wx/filename.h>
#include <wx/filehistory.h>
#include <search_stack.h>
#include <wx/gdicmn.h>
#include <bitmaps_png/bitmap_def.h>
@ -94,15 +93,6 @@ struct LANGUAGE_DESCR
};
class FILE_HISTORY : public wxFileHistory
{
public:
FILE_HISTORY( size_t aMaxFiles, int aBaseFileId );
void SetMaxFiles( size_t aMaxFiles );
};
// inter program module calling
#define VTBL_ENTRY virtual

View File

@ -34,11 +34,12 @@
#include <wx/string.h>
#include <common.h>
#include <filehistory.h>
#include <hotkeys_basic.h>
#include <kiway.h>
#include <richio.h>
#include <wildcards_and_files_ext.h>
#include <systemdirsappend.h>
#include <wildcards_and_files_ext.h>
#include <stdexcept>

View File

@ -29,6 +29,7 @@
#include <bitmaps.h>
#include <build_version.h>
#include <executable_names.h>
#include <filehistory.h>
#include <gestfich.h>
#include <kiway.h>
#include <kiway_express.h>
@ -173,6 +174,12 @@ KICAD_MANAGER_FRAME::~KICAD_MANAGER_FRAME()
delete m_toolManager;
m_auimgr.UnInit();
// Since the file menu contains file history menus, we must ensure that the menu
// destructor is called before the file history objects are deleted since their destructor
// unregisters the menu from the history.
wxMenu* fileMenu = GetMenuBar()->Remove( 0 );
delete fileMenu;
}

View File

@ -25,6 +25,7 @@
*/
#include <bitmaps.h>
#include <filehistory.h>
#include <menus_helpers.h>
#include <tool/tool_manager.h>
#include <tool/action_toolbar.h>
@ -45,26 +46,25 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar()
//-- File menu -----------------------------------------------------------
//
CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, controlTool );
static ACTION_MENU* openRecentMenu;
CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, controlTool );
FILE_HISTORY& fileHistory = PgmTop().GetFileHistory();
static FILE_HISTORY_MENU* openRecentMenu;
// Before deleting, remove the menus managed by m_fileHistory
// (the file history will be updated when adding/removing files in history)
if( openRecentMenu )
PgmTop().GetFileHistory().RemoveMenu( openRecentMenu );
openRecentMenu = new ACTION_MENU( false );
openRecentMenu->SetTool( controlTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( recent_xpm );
PgmTop().GetFileHistory().UseMenu( openRecentMenu );
PgmTop().GetFileHistory().AddFilesToMenu( openRecentMenu );
// Create the menu if it does not exist. Adding a file to/from the history
// will automatically refresh the menu.
if( !openRecentMenu )
{
openRecentMenu = new FILE_HISTORY_MENU( fileHistory, _( "Clear Recent Projects" ) );
openRecentMenu->SetTool( controlTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( recent_xpm );
}
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::newProject, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::newFromTemplate, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::openProject, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentMenu, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentMenu,
FILE_HISTORY::FileHistoryNotEmpty( fileHistory ) );
fileMenu->AddSeparator();
fileMenu->AddItem( ACTIONS::saveAs, SELECTION_CONDITIONS::ShowAlways );

View File

@ -23,6 +23,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <filehistory.h>
#include <kiface_i.h>
#include <menus_helpers.h>
#include <pgm_base.h>
@ -47,28 +48,26 @@ void PL_EDITOR_FRAME::ReCreateMenuBar()
return GetScreen() && GetScreen()->IsModify();
};
static ACTION_MENU* openRecentMenu; // Open Recent submenu, static to remember this menu
static FILE_HISTORY_MENU* openRecentMenu; // Open Recent submenu, static to remember this menu
FILE_HISTORY& recentFiles = Kiface().GetFileHistory();
// Before deleting, remove the menus managed by m_fileHistory
// (the file history will be updated when adding/removing files in history
if( openRecentMenu )
Kiface().GetFileHistory().RemoveMenu( openRecentMenu );
// Create the menu if it does not exist. Adding a file to/from the history
// will automatically refresh the menu.
if( !openRecentMenu )
{
openRecentMenu = new FILE_HISTORY_MENU( recentFiles );
openRecentMenu->SetTool( selTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( recent_xpm );
}
//-- File menu -------------------------------------------------------
//
CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, selTool );
openRecentMenu = new ACTION_MENU( false );
openRecentMenu->SetTool( selTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( recent_xpm );
Kiface().GetFileHistory().UseMenu( openRecentMenu );
Kiface().GetFileHistory().AddFilesToMenu();
fileMenu->AddItem( ACTIONS::doNew, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddItem( ACTIONS::open, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentMenu, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentMenu, FILE_HISTORY::FileHistoryNotEmpty( recentFiles ) );
fileMenu->AddSeparator();
fileMenu->AddItem( ACTIONS::save, modifiedDocumentCondition );

View File

@ -198,6 +198,15 @@ PL_EDITOR_FRAME::PL_EDITOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
}
PL_EDITOR_FRAME::~PL_EDITOR_FRAME()
{
// Since the file menu contains file history menus, we must ensure that the menu
// destructor is called before the file history objects are deleted since their destructor
// unregisters the menu from the history.
wxMenu* fileMenu = GetMenuBar()->Remove( 0 );
delete fileMenu;
}
void PL_EDITOR_FRAME::setupTools()
{
// Create the manager and dispatcher & route draw panel events to the dispatcher

View File

@ -66,7 +66,7 @@ private:
public:
PL_EDITOR_FRAME( KIWAY* aKiway, wxWindow* aParent );
~PL_EDITOR_FRAME() {}
~PL_EDITOR_FRAME();
PROPERTIES_FRAME* GetPropertiesFrame() { return m_propertiesPagelayout; }

View File

@ -27,6 +27,7 @@
#include <pcb_edit_frame.h>
#include <advanced_config.h>
#include <filehistory.h>
#include <kiface_i.h>
#include <menus_helpers.h>
#include <pgm_base.h>
@ -58,27 +59,26 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
//-- File menu -----------------------------------------------------------
//
CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, selTool );
static ACTION_MENU* openRecentMenu;
static FILE_HISTORY_MENU* openRecentMenu;
auto& disp_opt = GetDisplayOptions();
if( Kiface().IsSingle() ) // not when under a project mgr
{
// Add this menu to list menu managed by m_fileHistory
// (the file history will be updated when adding/removing files in history)
if( openRecentMenu )
Kiface().GetFileHistory().RemoveMenu( openRecentMenu );
FILE_HISTORY& fileHistory = Kiface().GetFileHistory();
openRecentMenu = new ACTION_MENU( false );
openRecentMenu->SetTool( selTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( recent_xpm );
Kiface().GetFileHistory().UseMenu( openRecentMenu );
Kiface().GetFileHistory().AddFilesToMenu( openRecentMenu );
// Create the menu if it does not exist. Adding a file to/from the history
// will automatically refresh the menu.
if( !openRecentMenu )
{
openRecentMenu = new FILE_HISTORY_MENU( fileHistory );
openRecentMenu->SetTool( selTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( recent_xpm );
}
fileMenu->AddItem( ACTIONS::doNew, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddItem( ACTIONS::open, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentMenu, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentMenu, FILE_HISTORY::FileHistoryNotEmpty( fileHistory ) );
fileMenu->AddItem( PCB_ACTIONS::appendBoard, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddItem( ID_IMPORT_NON_KICAD_BOARD,

View File

@ -336,6 +336,11 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
PCB_EDIT_FRAME::~PCB_EDIT_FRAME()
{
// Since the file menu contains file history menus, we must ensure that the menu
// destructor is called before the file history objects are deleted since their destructor
// unregisters the menu from the history.
wxMenu* fileMenu = GetMenuBar()->Remove( 0 );
delete fileMenu;
}