KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 m_filterSearch = CreateTextFilterBox( this, _( "Type filter text" ) );
79 bMargins->Add( m_filterSearch, 0, wxEXPAND, 0 );
80
82 bMargins->Add( m_hotkeyListCtrl, 1, wxEXPAND | wxTOP, 5 );
83
84 if( !m_readOnly )
85 installButtons( bMargins );
86
87 mainSizer->Add( bMargins, 1, wxEXPAND, 0 );
88
89#ifdef __WXGTK__
90
91 // It appears that this may have been fixed in wxWidgets 3.2.3.
92#if wxVERSION_NUMBER < 3203
93
94 // Work around a bug that clips the text vertically in the wxSearchCtrl on GTK
95 m_filterSearch->SetMinSize(
96 wxSize( m_filterSearch->GetSize().x, int( m_filterSearch->GetSize().y * 1.6 ) ) );
97#endif
98
99#endif
100
101 SetSizer( mainSizer );
102 Layout();
103 mainSizer->Fit( this );
104
105 // Connect Events
106 m_filterSearch->Bind( wxEVT_COMMAND_TEXT_UPDATED, &PANEL_HOTKEYS_EDITOR::OnFilterSearch, this );
107}
108
109
111{
112 m_filterSearch->Unbind( wxEVT_COMMAND_TEXT_UPDATED, &PANEL_HOTKEYS_EDITOR::OnFilterSearch,
113 this );
114}
115
116
118{
120}
121
122
124{
125 BUTTON_ROW_PANEL::BTN_DEF_LIST l_btn_defs = {
126 {
127 wxID_RESET,
128 _( "Undo All Changes" ),
129 _( "Undo all changes made so far in this dialog" ),
130 [this]( wxCommandEvent& )
131 {
133 }
134 },
135 {
136 wxID_ANY,
137 _( "Import Hotkeys..." ),
138 _( "Import hotkey definitions from an external file, replacing the current values" ),
139 [this]( wxCommandEvent& )
140 {
142 }
143 }
144 };
145
146 if( ADVANCED_CFG::GetCfg().m_HotkeysDumper )
147 {
148 // Add hotkeys dumper (does not need translation, it's a dev tool only)
149 l_btn_defs.push_back( {
150 wxID_ANY, wxT( "Dump Hotkeys" ), wxEmptyString,
151 [this]( wxCommandEvent& )
152 {
153 dumpHotkeys();
154 }
155 } );
156 }
157
158 const BUTTON_ROW_PANEL::BTN_DEF_LIST r_btn_defs = {
159 };
160
161 auto btnPanel = std::make_unique<BUTTON_ROW_PANEL>( this, l_btn_defs, r_btn_defs );
162
163 aSizer->Add( btnPanel.release(), 0, wxEXPAND | wxALL, KIUI::GetStdMargin() * 2 );
164}
165
166
168{
170
172 return false;
173
174 return true;
175}
176
177
179{
180 if( m_readOnly )
181 return true;
182
184 return false;
185
187
188 return true;
189}
190
191
192void PANEL_HOTKEYS_EDITOR::OnFilterSearch( wxCommandEvent& aEvent )
193{
194 const auto searchStr = aEvent.GetString();
196}
197
198
200{
201 wxString filename = wxFileSelector( _( "Import Hotkeys File:" ), m_frame->GetMruPath(),
202 wxEmptyString, HotkeyFileExtension,
203 HotkeyFileWildcard(), wxFD_OPEN, this );
204
205 if( filename.IsEmpty() )
206 return;
207
208 std::map<std::string, std::pair<int, int>> importedHotKeys;
209 ReadHotKeyConfig( filename, importedHotKeys );
210 m_frame->SetMruPath( wxFileName( filename ).GetPath() );
211
212 // Overlay the imported hotkeys onto the hotkey store
213 for( HOTKEY_SECTION& section: m_hotkeyStore.GetSections() )
214 {
215 for( HOTKEY& hotkey: section.m_HotKeys )
216 {
217 if( importedHotKeys.count( hotkey.m_Actions[ 0 ]->GetName() ) )
218 {
219 hotkey.m_EditKeycode = importedHotKeys[ hotkey.m_Actions[ 0 ]->GetName() ].first;
220 hotkey.m_EditKeycodeAlt = importedHotKeys[ hotkey.m_Actions[ 0 ]->GetName() ].second;
221 }
222 }
223 }
224
226}
227
228
230{
231 wxString filename = wxFileSelector( wxT( "Hotkeys File" ), m_frame->GetMruPath(),
232 wxEmptyString, TextFileExtension, TextFileWildcard(),
233 wxFD_SAVE, this );
234
235 if( filename.IsEmpty() )
236 return;
237
238 wxFileName fn( filename );
239
240 wxFFileOutputStream fileStream( fn.GetFullPath(), "w" );
241 wxTextOutputStream stream( fileStream );
242
243 if( !fn.IsDirWritable() || ( fn.Exists() && !fn.IsFileWritable() ) )
244 return;
245
246 for( HOTKEY_SECTION& section : m_hotkeyStore.GetSections() )
247 {
248 stream << wxT( "=== " ) << section.m_SectionName << endl << endl;
249
250 stream << wxT( "[width=\"100%\",options=\"header\",cols=\"20%,15%,65%\"]" ) << endl;
251 stream << wxT( "|===" ) << endl;
252 stream << _( "| Action | Default Hotkey | Description" ) << endl;
253
254 for( HOTKEY& hk : section.m_HotKeys )
255 {
256 stream << wxT( "| " ) << hk.m_Actions[0]->GetFriendlyName() << endl;
257
258 if( hk.m_EditKeycode > 0 )
259 {
260 stream << wxT( " | kbd:[" ) << KeyNameFromKeyCode( hk.m_EditKeycode ) << ']'
261 << endl;
262 }
263 else
264 {
265 stream << wxT( " |" ) << endl;
266 }
267
268 stream << wxT( " | " ) << hk.m_Actions[0]->GetDescription() << endl;
269 }
270
271 stream << wxT( "|===" ) << endl << endl;
272 }
273
274 stream.Flush();
275 fileStream.Close();
276}
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.
wxSearchCtrl * m_filterSearch
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()
void ReadHotKeyConfig(const wxString &aFileName, std::map< std::string, std::pair< int, int > > &aHotKeys)
Reads a hotkey config file into a map.
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.
int GetStdMargin()
Get the standard margin around a widget in the KiCad UI.
Definition: ui_common.cpp:45
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_EditKeycodeAlt
Definition: hotkey_store.h:38
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.