KiCad PCB EDA Suite
panel_hotkeys_editor.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KICAD, a free EDA CAD application.
3 *
4 * Copyright (C) 1992-2023 Kicad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <advanced_config.h>
25#include <gestfich.h>
26#include <hotkeys_basic.h>
27#include <kiway_player.h>
28#include <locale_io.h>
31#include <tool/tool_manager.h>
33#include <widgets/ui_common.h>
34#include <wx/filedlg.h>
35#include <wx/sizer.h>
36#include <wx/srchctrl.h>
37#include <wx/txtstrm.h>
38#include <wx/wfstream.h>
39
40
49static wxSearchCtrl* CreateTextFilterBox( wxWindow* aParent, const wxString& aDescriptiveText )
50{
51 wxSearchCtrl* search_widget = new wxSearchCtrl( aParent, wxID_ANY );
52
53 search_widget->ShowSearchButton( false );
54 search_widget->ShowCancelButton( true );
55
56 search_widget->SetDescriptiveText( aDescriptiveText );
57
58#ifdef __WXGTK__
59 // wxSearchCtrl vertical height is not calculated correctly on some GTK setups
60 // See https://gitlab.com/kicad/code/kicad/-/issues/9019
61 search_widget->SetMinSize( wxSize( -1, aParent->GetTextExtent( wxT( "qb" ) ).y + 10 ) );
62#endif
63
64 return search_widget;
65}
66
67
69 bool aReadOnly ) :
70 RESETTABLE_PANEL( aWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize ),
71 m_frame( aFrame ),
72 m_readOnly( aReadOnly ),
73 m_hotkeyStore()
74{
75 wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
76 wxBoxSizer* bMargins = new wxBoxSizer( wxVERTICAL );
77
78 wxSearchCtrl* filterSearch = CreateTextFilterBox( this, _( "Type filter text" ) );
79 bMargins->Add( filterSearch, 0, wxEXPAND, 0 );
80
82 bMargins->Add( m_hotkeyListCtrl, 1, wxEXPAND, 0 );
83
84 if( !m_readOnly )
85 installButtons( bMargins );
86
87 mainSizer->Add( bMargins, 1, wxEXPAND, 0 );
88
89#ifdef __WXGTK__
90 // Work around a bug that clips the text vertically in the wxSearchCtrl on GTK
91 filterSearch->SetMinSize( wxSize( filterSearch->GetSize().x,
92 int( filterSearch->GetSize().y * 1.6 ) ) );
93#endif
94
95 SetSizer( mainSizer );
96 Layout();
97
98 // Connect Events
99 filterSearch->Bind( wxEVT_COMMAND_TEXT_UPDATED, &PANEL_HOTKEYS_EDITOR::OnFilterSearch, this );
100}
101
102
104{
106}
107
108
110{
111 BUTTON_ROW_PANEL::BTN_DEF_LIST l_btn_defs = {
112 {
113 wxID_RESET,
114 _( "Undo All Changes" ),
115 _( "Undo all changes made so far in this dialog" ),
116 [this]( wxCommandEvent& )
117 {
119 }
120 },
121 {
122 wxID_ANY,
123 _( "Import Hotkeys..." ),
124 _( "Import hotkey definitions from an external file, replacing the current values" ),
125 [this]( wxCommandEvent& )
126 {
128 }
129 }
130 };
131
132 if( ADVANCED_CFG::GetCfg().m_HotkeysDumper )
133 {
134 // Add hotkeys dumper (does not need translation, it's a dev tool only)
135 l_btn_defs.push_back( {
136 wxID_ANY, wxT( "Dump Hotkeys" ), wxEmptyString,
137 [this]( wxCommandEvent& )
138 {
139 dumpHotkeys();
140 }
141 } );
142 }
143
144 const BUTTON_ROW_PANEL::BTN_DEF_LIST r_btn_defs = {
145 };
146
147 auto btnPanel = std::make_unique<BUTTON_ROW_PANEL>( this, l_btn_defs, r_btn_defs );
148
149 aSizer->Add( btnPanel.release(), 0, wxEXPAND | wxALL, KIUI::GetStdMargin() * 2 );
150}
151
152
154{
156
158 return false;
159
160 return true;
161}
162
163
165{
166 if( m_readOnly )
167 return true;
168
170 return false;
171
173
174 return true;
175}
176
177
178void PANEL_HOTKEYS_EDITOR::OnFilterSearch( wxCommandEvent& aEvent )
179{
180 const auto searchStr = aEvent.GetString();
182}
183
184
186{
187 wxString filename = wxFileSelector( _( "Import Hotkeys File:" ), m_frame->GetMruPath(),
188 wxEmptyString, HotkeyFileExtension,
189 HotkeyFileWildcard(), wxFD_OPEN, this );
190
191 if( filename.IsEmpty() )
192 return;
193
194 std::map<std::string, int> importedHotKeys;
195 ReadHotKeyConfig( filename, importedHotKeys );
196 m_frame->SetMruPath( wxFileName( filename ).GetPath() );
197
198 // Overlay the imported hotkeys onto the hotkey store
199 for( HOTKEY_SECTION& section: m_hotkeyStore.GetSections() )
200 {
201 for( HOTKEY& hotkey: section.m_HotKeys )
202 {
203 if( importedHotKeys.count( hotkey.m_Actions[ 0 ]->GetName() ) )
204 hotkey.m_EditKeycode = importedHotKeys[ hotkey.m_Actions[ 0 ]->GetName() ];
205 }
206 }
207
209}
210
211
213{
214 wxString filename = wxFileSelector( wxT( "Hotkeys File" ), m_frame->GetMruPath(),
215 wxEmptyString, TextFileExtension, TextFileWildcard(),
216 wxFD_SAVE, this );
217
218 if( filename.IsEmpty() )
219 return;
220
221 wxFileName fn( filename );
222
223 wxFFileOutputStream fileStream( fn.GetFullPath(), "w" );
224 wxTextOutputStream stream( fileStream );
225
226 if( !fn.IsDirWritable() || ( fn.Exists() && !fn.IsFileWritable() ) )
227 return;
228
229 for( HOTKEY_SECTION& section : m_hotkeyStore.GetSections() )
230 {
231 stream << wxT( "=== " ) << section.m_SectionName << endl << endl;
232
233 stream << wxT( "[width=\"100%\",options=\"header\",cols=\"20%,15%,65%\"]" ) << endl;
234 stream << wxT( "|===" ) << endl;
235 stream << _( "| Action | Default Hotkey | Description" ) << endl;
236
237 for( HOTKEY& hk : section.m_HotKeys )
238 {
239 stream << wxT( "| " ) << hk.m_Actions[0]->GetLabel() << endl;
240
241 if( hk.m_EditKeycode > 0 )
242 {
243 stream << wxT( " | kbd:[" ) << KeyNameFromKeyCode( hk.m_EditKeycode ) << ']'
244 << endl;
245 }
246 else
247 {
248 stream << wxT( " |" ) << endl;
249 }
250
251 stream << wxT( " | " ) << hk.m_Actions[0]->GetDescription( false ) << endl;
252 }
253
254 stream << wxT( "|===" ) << endl << endl;
255 }
256
257 stream.Flush();
258 fileStream.Close();
259}
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
std::vector< BTN_DEF > BTN_DEF_LIST
A list of BTN_DEFs, used to group buttons into the left/right groups.
The base frame for deriving all KiCad main window classes.
wxString GetMruPath() const
void SetMruPath(const wxString &aPath)
void Init(std::vector< TOOL_ACTION * > aActionsList, bool aIncludeReadOnlyCmds)
std::vector< HOTKEY_SECTION > & GetSections()
Get the list of sections managed by this store.
PANEL_HOTKEYS_EDITOR(EDA_BASE_FRAME *aFrame, wxWindow *aWindow, bool aReadOnly)
void OnFilterSearch(wxCommandEvent &aEvent)
Handle a change in the hotkey filter text.
void ResetPanel() override
Reset the contents of this panel.
std::vector< TOOL_ACTION * > m_actions
void installButtons(wxSizer *aSizer)
Install the button panel (global reset/default, import/export)
WIDGET_HOTKEY_LIST * m_hotkeyListCtrl
EDA_BASE_FRAME * m_frame
bool TransferDataToWindow() override
void ImportHotKeys()
Put up a dialog allowing the user to select a hotkeys file and then overlays those hotkeys onto the c...
void dumpHotkeys()
Dump all actions and their hotkeys to a text file for inclusion in documentation.
bool TransferDataFromWindow() override
A wxPanel that is designed to be reset in a standard manner.
void ResetAllHotkeys(bool aResetToDefault)
Set hotkeys in the control to default or original values.
bool TransferDataToControl()
Method TransferDataToControl Load the hotkey data from the store into the control.
bool TransferDataFromControl()
Method TransferDataFromControl Save the hotkey data from the control.
void ApplyFilterString(const wxString &aFilterStr)
Method ApplyFilterString Apply a filter string to the hotkey list, selecting which hotkeys to show.
#define _(s)
const std::string HotkeyFileExtension
const std::string TextFileExtension
wxString TextFileWildcard()
wxString HotkeyFileWildcard()
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Return the key name from the key code.
int WriteHotKeyConfig(const std::vector< TOOL_ACTION * > &aActions)
Update the hotkeys config file with the hotkeys from the given actions map.
void ReadHotKeyConfig(const wxString &aFileName, std::map< std::string, int > &aHotKeys)
Reads a hotkey config file into a map.
int GetStdMargin()
Get the standard margin around a widget in the KiCad UI.
Definition: ui_common.cpp:41
static wxSearchCtrl * CreateTextFilterBox(wxWindow *aParent, const wxString &aDescriptiveText)
Helper function to add a filter box to a panel, with some sensible defaults for that purpose.
int m_EditKeycode
Definition: hotkey_store.h:37
std::vector< TOOL_ACTION * > m_Actions
Definition: hotkey_store.h:36
Functions to provide common constants and other functions to assist in making a consistent UI.
Definition of file extensions used in Kicad.