diff --git a/common/dialogs/dialog_hotkey_list.cpp b/common/dialogs/dialog_hotkey_list.cpp index 44c690b43c..a193e400df 100644 --- a/common/dialogs/dialog_hotkey_list.cpp +++ b/common/dialogs/dialog_hotkey_list.cpp @@ -37,7 +37,7 @@ DIALOG_LIST_HOTKEYS::DIALOG_LIST_HOTKEYS( EDA_BASE_FRAME* aParent, TOOL_MANAGER* auto main_sizer = new wxBoxSizer( wxVERTICAL ); - m_hk_list = new PANEL_HOTKEYS_EDITOR( this, true ); + m_hk_list = new PANEL_HOTKEYS_EDITOR( aParent, this, true ); m_hk_list->AddHotKeys( aToolMgr ); main_sizer->Add( m_hk_list, 1, wxTOP | wxLEFT | wxRIGHT | wxEXPAND, margin ); diff --git a/common/dialogs/panel_hotkeys_editor.cpp b/common/dialogs/panel_hotkeys_editor.cpp index 17236b412a..a6dbbd17f5 100644 --- a/common/dialogs/panel_hotkeys_editor.cpp +++ b/common/dialogs/panel_hotkeys_editor.cpp @@ -27,9 +27,13 @@ #include #include #include +#include #include #include #include +#include +#include +#include static const wxSize default_dialog_size { 500, 350 }; static const wxSize min_dialog_size { -1, 350 }; @@ -55,8 +59,10 @@ static wxSearchCtrl* CreateTextFilterBox( wxWindow* aParent, const wxString& aDe } -PANEL_HOTKEYS_EDITOR::PANEL_HOTKEYS_EDITOR( wxWindow* aWindow, bool aReadOnly ) : +PANEL_HOTKEYS_EDITOR::PANEL_HOTKEYS_EDITOR( EDA_BASE_FRAME* aFrame, wxWindow* aWindow, + bool aReadOnly ) : wxPanel( aWindow, wxID_ANY, wxDefaultPosition, default_dialog_size ), + m_frame( aFrame ), m_readOnly( aReadOnly ), m_hotkeyStore() { @@ -118,8 +124,7 @@ void PANEL_HOTKEYS_EDITOR::installButtons( wxSizer* aSizer ) _( "Import Hotkeys..." ), _( "Import hotkey definitions from an external file, replacing the current values" ), [this]( wxCommandEvent& ){ - // JEY TODO: implement hotkey import.... - /*m_frame->ImportHotkeyConfigFromFile( m_hotkeys, m_nickname );*/ + ImportHotKeys(); } } }; @@ -158,3 +163,34 @@ void PANEL_HOTKEYS_EDITOR::OnFilterSearch( wxCommandEvent& aEvent ) const auto searchStr = aEvent.GetString(); m_hotkeyListCtrl->ApplyFilterString( searchStr ); } + + +void PANEL_HOTKEYS_EDITOR::ImportHotKeys() +{ + wxString ext = DEFAULT_HOTKEY_FILENAME_EXT; + wxString mask = wxT( "*." ) + ext; + wxString filename = EDA_FILE_SELECTOR( _( "Read Hotkeys File:" ), m_frame->GetMruPath(), + wxEmptyString, ext, mask, this, wxFD_OPEN, true ); + + if( filename.IsEmpty() ) + return; + + std::map importedHotKeys; + ReadHotKeyConfig( filename, importedHotKeys ); + m_frame->SetMruPath( wxFileName( filename ).GetPath() ); + + // Overlay the imported hotkeys onto the hotkey store + for( HOTKEY_SECTION& section: m_hotkeyStore.GetSections() ) + { + for( HOTKEY& hotkey: section.m_HotKeys ) + { + if( importedHotKeys.count( hotkey.m_Parent->GetName() ) ) + hotkey.m_EditKeycode = importedHotKeys[ hotkey.m_Parent->GetName() ]; + } + } + + m_hotkeyListCtrl->TransferDataToControl(); +} + + + diff --git a/common/eda_base_frame.cpp b/common/eda_base_frame.cpp index c799669e29..81b36204a1 100644 --- a/common/eda_base_frame.cpp +++ b/common/eda_base_frame.cpp @@ -518,7 +518,7 @@ void EDA_BASE_FRAME::OnPreferences( wxCommandEvent& event ) book->AddPage( new PANEL_COMMON_SETTINGS( &dlg, book ), _( "Common" ) ); - PANEL_HOTKEYS_EDITOR* hotkeysPanel = new PANEL_HOTKEYS_EDITOR( book, false ); + PANEL_HOTKEYS_EDITOR* hotkeysPanel = new PANEL_HOTKEYS_EDITOR( this, book, false ); book->AddPage( hotkeysPanel, _( "Hotkeys" ) ); for( unsigned i = 0; i < KIWAY_PLAYER_COUNT; ++i ) diff --git a/common/hotkeys_basic.cpp b/common/hotkeys_basic.cpp index ba1d616256..070d6a2457 100644 --- a/common/hotkeys_basic.cpp +++ b/common/hotkeys_basic.cpp @@ -55,12 +55,11 @@ wxString g_CommonSectionTag( wxT( "[common]" ) ); * This class allows the real key code changed by user from a key code list * file. */ - -EDA_HOTKEY::EDA_HOTKEY( const wxChar* infomsg, int idcommand, int keycode, int idmenuevent ) : - m_KeyCode( keycode ), m_InfoMsg( infomsg ), m_Idcommand( idcommand ), - m_IdMenuEvent( idmenuevent ) -{ -} +EDA_HOTKEY::EDA_HOTKEY( const wxChar* infomsg, int idcommand, int keycode ) : + m_KeyCode( keycode ), + m_InfoMsg( infomsg ), + m_Idcommand( idcommand ) +{ } /* class to handle the printable name and the keycode @@ -77,7 +76,7 @@ struct hotkey_name_descr * For instance wxT( "F1" ), WXK_F1 handle F1, AltF1, CtrlF1 ... * Key names are: * "Space","Ctrl+Space","Alt+Space" or - * "Alt+A","Ctrl+F1", ... + * "Alt+A","Ctrl+F1", ... */ #define KEY_NON_FOUND -1 static struct hotkey_name_descr hotkeyNameList[] = @@ -320,11 +319,7 @@ wxString KeyNameFromCommandId( EDA_HOTKEY** aList, int aCommandId ) /** * Function KeyCodeFromKeyName - * return the key code from its key name - * Only some wxWidgets key values are handled for function key - * @param keyname = wxString key name to find in hotkeyNameList[], - * like F2 or space or an usual (ascii) char. - * @return the key code + * return the key code from its user-friendly key name (ie: "Ctrl+M") */ int KeyCodeFromKeyName( const wxString& keyname ) { @@ -400,26 +395,25 @@ void DisplayHotkeyList( EDA_BASE_FRAME* aParent, TOOL_MANAGER* aToolManager ) } -int WriteHotKeyConfig( std::map aActionMap ) +void ReadHotKeyConfig( wxString fileName, std::map& aHotKeys ) { - wxFileName fn( "user" ); - - fn.SetExt( DEFAULT_HOTKEY_FILENAME_EXT ); - fn.SetPath( GetKicadConfigPath() ); - - if( !wxFile::Exists( fn.GetFullPath() ) ) - return 0; + if( fileName.IsEmpty() ) + { + wxFileName fn( "user" ); + fn.SetExt( DEFAULT_HOTKEY_FILENAME_EXT ); + fn.SetPath( GetKicadConfigPath() ); + fileName = fn.GetFullPath(); + } + + if( !wxFile::Exists( fileName ) ) + return; - wxFile file( fn.GetFullPath(), wxFile::OpenMode::read ); + wxFile file( fileName, wxFile::OpenMode::read ); if( !file.IsOpened() ) // There is a problem to open file - return 0; - - // Read entire hotkey set into map - // - wxString input; - std::map hotkeys; + return; + wxString input; file.ReadAll( &input ); input.Replace( "\r\n", "\n" ); // Convert Windows files to Unix line-ends wxStringTokenizer fileTokenizer( input, "\n", wxTOKEN_STRTOK ); @@ -432,12 +426,24 @@ int WriteHotKeyConfig( std::map aActionMap ) wxString keyName = lineTokenizer.GetNextToken(); if( !cmdName.IsEmpty() ) - hotkeys[ cmdName ] = KeyCodeFromKeyName( keyName ); + aHotKeys[ cmdName.ToStdString() ] = KeyCodeFromKeyName( keyName ); } +} + + +int WriteHotKeyConfig( std::map aActionMap ) +{ + std::map hotkeys; + wxFileName fn( "user" ); + + fn.SetExt( DEFAULT_HOTKEY_FILENAME_EXT ); + fn.SetPath( GetKicadConfigPath() ); - file.Close(); + // Read the existing config (all hotkeys) + // + ReadHotKeyConfig( fn.GetFullPath(), hotkeys ); - // Overlay this app's hotkey definitions onto the map + // Overlay the current app's hotkey definitions onto the map // for( const auto& ii : aActionMap ) { @@ -447,13 +453,11 @@ int WriteHotKeyConfig( std::map aActionMap ) // Write entire hotkey set // - file.Open( fn.GetFullPath(), wxFile::OpenMode::write ); + wxFile file( fn.GetFullPath(), wxFile::OpenMode::write ); for( const auto& ii : hotkeys ) file.Write( wxString::Format( "%s\t%s\n", ii.first, KeyNameFromKeyCode( ii.second ) ) ); - file.Close(); - return 1; } @@ -545,64 +549,3 @@ int ReadLegacyHotkeyConfigFile( const wxString& aFilename, std::mapGetEditFrame()->ConfigBaseName(), legacyHotKeyMap ); - // JEY TODO: read user hotkey config... + ReadHotKeyConfig( wxEmptyString, userHotKeyMap ); for( const auto& actionName : m_actionNameIndex ) { diff --git a/include/eda_base_frame.h b/include/eda_base_frame.h index ba5a56d16f..dd6a8e7428 100644 --- a/include/eda_base_frame.h +++ b/include/eda_base_frame.h @@ -307,25 +307,15 @@ public: // Read/Save and Import/export hotkeys config /** - * Prompt the user for an old hotkey file to read, and read it. + * Prompt the user for a hotkey file to read, and read it. * - * @param aDescList = current hotkey list descr. to initialize. + * @param aActionMap = current hotkey map (over which the imported hotkeys will be applied) * @param aDefaultShortname = a default short name (extension not needed) * like eechema, kicad... */ - void ImportHotkeyConfigFromFile( EDA_HOTKEY_CONFIG* aDescList, + void ImportHotkeyConfigFromFile( std::map aActionMap, const wxString& aDefaultShortname ); - /** - * Prompt the user for an old hotkey file to read, and read it. - * - * @param aDescList = current hotkey list descr. to initialize. - * @param aDefaultShortname = a default short name (extension not needed) - * like eechema, kicad... - */ - void ExportHotkeyConfigToFile( EDA_HOTKEY_CONFIG* aDescList, - const wxString& aDefaultShortname ); - /** * Fetches the file name from the file history list. * diff --git a/include/hotkeys_basic.h b/include/hotkeys_basic.h index f283068083..c75884f540 100644 --- a/include/hotkeys_basic.h +++ b/include/hotkeys_basic.h @@ -60,10 +60,9 @@ public: int m_KeyCode; // Key code (ascii value for ascii keys or wxWidgets code for function key wxString m_InfoMsg; // info message. int m_Idcommand; // internal id for the corresponding command (see hotkey_id_command list) - int m_IdMenuEvent; // id to call the corresponding event (if any) (see id.h) public: - EDA_HOTKEY( const wxChar* infomsg, int idcommand, int keycode, int idmenuevent = 0 ); + EDA_HOTKEY( const wxChar* infomsg, int idcommand, int keycode ); }; @@ -88,14 +87,17 @@ public: }; +/** + * Function KeyCodeFromKeyName + * return the key code from its user-friendly key name (ie: "Ctrl+M") + */ +int KeyCodeFromKeyName( const wxString& keyname ); + /** * Function KeyNameFromKeyCode - * return the key name from the key code - * * Only some wxWidgets key values are handled for function key ( see - * s_Hotkey_Name_List[] ) + * return the user-friendly key name (ie: "Ctrl+M") from the key code * @param aKeycode = key code (ascii value, or wxWidgets value for function keys) - * @param aIsFound = a pointer to a bool to return true if found, or false. an be NULL default) - * @return the key name in a wxString + * @param aIsFound = a pointer to a bool to return true if found, or false */ wxString KeyNameFromKeyCode( int aKeycode, bool * aIsFound = nullptr ); @@ -155,6 +157,14 @@ wxString AddHotkeyName( const wxString& aText, */ void DisplayHotkeyList( EDA_BASE_FRAME* aFrame, TOOL_MANAGER* aToolMgr ); +/** + * Function ReadotKeyConfig + * Reads a hotkey config file into a map. If aFileName is empty it will read in the defualt + * hotkeys file. + * @param aHotKeys + */ +void ReadHotKeyConfig( wxString aFileName, std::map& aHotKeys ); + /** * Function WriteHotKeyConfig * Updates the hotkeys config file with the hotkeys from the given actions map. diff --git a/include/panel_hotkeys_editor.h b/include/panel_hotkeys_editor.h index 4951eb1406..6d5dbb8753 100644 --- a/include/panel_hotkeys_editor.h +++ b/include/panel_hotkeys_editor.h @@ -40,14 +40,15 @@ class TOOL_MANAGER; class PANEL_HOTKEYS_EDITOR : public wxPanel { protected: + EDA_BASE_FRAME* m_frame; bool m_readOnly; + std::vector m_toolManagers; - HOTKEY_STORE m_hotkeyStore; WIDGET_HOTKEY_LIST* m_hotkeyListCtrl; public: - PANEL_HOTKEYS_EDITOR( wxWindow* aWindow, bool aReadOnly ); + PANEL_HOTKEYS_EDITOR( EDA_BASE_FRAME* aFrame, wxWindow* aWindow, bool aReadOnly ); void AddHotKeys( TOOL_MANAGER* aToolMgr ); @@ -69,6 +70,14 @@ private: * @param aEvent: the search event, used to get the search query */ void OnFilterSearch( wxCommandEvent& aEvent ); + + /** + * Function ImportHotKeys + * Puts up a dialog allowing the user to select a hotkeys file and then overlays those + * hotkeys onto the current hotkey store. + */ + void ImportHotKeys(); + };