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-2020 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>
29 #include <panel_hotkeys_editor.h>
30 #include <tool/tool_manager.h>
32 #include <widgets/ui_common.h>
33 #include <wx/panel.h>
34 #include <wx/sizer.h>
35 #include <wx/srchctrl.h>
36 #include <wx/tokenzr.h>
37 #include <wx/txtstrm.h>
38 #include <wx/wfstream.h>
39 
40 static const wxSize default_dialog_size { 500, 350 };
41 
50 static wxSearchCtrl* CreateTextFilterBox( wxWindow* aParent, const wxString& aDescriptiveText )
51 {
52  wxSearchCtrl* search_widget = new wxSearchCtrl( aParent, wxID_ANY );
53 
54  search_widget->ShowSearchButton( false );
55  search_widget->ShowCancelButton( true );
56 
57  search_widget->SetDescriptiveText( aDescriptiveText );
58 
59  return search_widget;
60 }
61 
62 
64  bool aReadOnly ) :
65  RESETTABLE_PANEL( aWindow, wxID_ANY, wxDefaultPosition, default_dialog_size ),
66  m_frame( aFrame ),
67  m_readOnly( aReadOnly ),
68  m_hotkeyStore()
69 {
70  const auto margin = KIUI::GetStdMargin();
71  wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
72 
73  const int side_margins = margin * 2;
74  wxBoxSizer* bMargins = new wxBoxSizer( wxVERTICAL );
75 
76  wxSearchCtrl* filterSearch = CreateTextFilterBox( this, _( "Type filter text" ) );
77  bMargins->Add( filterSearch, 0, wxALL | wxEXPAND, margin );
78 
80  bMargins->Add( m_hotkeyListCtrl, 1, wxALL | wxEXPAND, margin );
81 
82  if( !m_readOnly )
83  installButtons( bMargins );
84 
85  mainSizer->Add( bMargins, 1, wxEXPAND | wxRIGHT | wxLEFT, side_margins );
86 
87 #ifdef __WXGTK__
88  // Work around a bug that clips the text vertically in the wxSearchCtrl on GTK
89  filterSearch->SetMinSize( wxSize( filterSearch->GetSize().x,
90  int( filterSearch->GetSize().y * 1.6 ) ) );
91 #endif
92 
93  SetSizer( mainSizer );
94  Layout();
95 
96  // Connect Events
97  filterSearch->Bind( wxEVT_COMMAND_TEXT_UPDATED, &PANEL_HOTKEYS_EDITOR::OnFilterSearch, this );
98 }
99 
100 
102 {
103  m_toolManagers.push_back( aToolMgr );
104 }
105 
106 
108 {
110 }
111 
112 
114 {
115  BUTTON_ROW_PANEL::BTN_DEF_LIST l_btn_defs = {
116  {
117  wxID_RESET,
118  _( "Undo All Changes" ),
119  _( "Undo all changes made so far in this dialog" ),
120  [this]( wxCommandEvent& )
121  {
123  }
124  },
125  {
126  wxID_ANY,
127  _( "Import Hotkeys..." ),
128  _( "Import hotkey definitions from an external file, replacing the current values" ),
129  [this]( wxCommandEvent& )
130  {
131  ImportHotKeys();
132  }
133  }
134  };
135 
136 
137  if( ADVANCED_CFG::GetCfg().m_HotkeysDumper )
138  {
139  // Add hotkeys dumper (does not need translation, it's a dev tool only)
140  l_btn_defs.push_back( {
141  wxID_ANY, wxT( "Dump Hotkeys" ), wxEmptyString,
142  [this]( wxCommandEvent& )
143  {
144  dumpHotkeys();
145  }
146  } );
147  }
148 
149  const BUTTON_ROW_PANEL::BTN_DEF_LIST r_btn_defs = {
150  };
151 
152  auto btnPanel = std::make_unique<BUTTON_ROW_PANEL>( this, l_btn_defs, r_btn_defs );
153 
154  aSizer->Add( btnPanel.release(), 0, wxEXPAND | wxTOP, KIUI::GetStdMargin() );
155 }
156 
157 
159 {
162 }
163 
164 
166 {
168  return false;
169 
170  if( m_readOnly )
171  return true;
172 
173  // save the hotkeys
174  for( TOOL_MANAGER* toolMgr : m_toolManagers )
175  WriteHotKeyConfig( toolMgr->GetActions() );
176 
177  return true;
178 }
179 
180 
181 void PANEL_HOTKEYS_EDITOR::OnFilterSearch( wxCommandEvent& aEvent )
182 {
183  const auto searchStr = aEvent.GetString();
184  m_hotkeyListCtrl->ApplyFilterString( searchStr );
185 }
186 
187 
189 {
190  wxString ext = DEFAULT_HOTKEY_FILENAME_EXT;
191  wxString mask = wxT( "*." ) + ext;
192  wxString filename = EDA_FILE_SELECTOR( _( "Import Hotkeys File:" ), m_frame->GetMruPath(),
193  wxEmptyString, ext, mask, this, wxFD_OPEN, true );
194 
195  if( filename.IsEmpty() )
196  return;
197 
198  std::map<std::string, int> importedHotKeys;
199  ReadHotKeyConfig( filename, importedHotKeys );
200  m_frame->SetMruPath( wxFileName( filename ).GetPath() );
201 
202  // Overlay the imported hotkeys onto the hotkey store
203  for( HOTKEY_SECTION& section: m_hotkeyStore.GetSections() )
204  {
205  for( HOTKEY& hotkey: section.m_HotKeys )
206  {
207  if( importedHotKeys.count( hotkey.m_Actions[ 0 ]->GetName() ) )
208  hotkey.m_EditKeycode = importedHotKeys[ hotkey.m_Actions[ 0 ]->GetName() ];
209  }
210  }
211 
213 }
214 
215 
217 {
218  wxString filename = EDA_FILE_SELECTOR( wxT( "Dump Hotkeys File:" ), m_frame->GetMruPath(),
219  wxEmptyString, wxT( "txt" ), wxT( "*.txt" ), this,
220  wxFD_SAVE, true );
221 
222  if( filename.IsEmpty() )
223  return;
224 
225  wxFileName fn( filename );
226 
227  wxFFileOutputStream fileStream( fn.GetFullPath(), "w" );
228  wxTextOutputStream stream( fileStream );
229 
230  if( !fn.IsDirWritable() || ( fn.Exists() && !fn.IsFileWritable() ) )
231  return;
232 
233  for( HOTKEY_SECTION& section : m_hotkeyStore.GetSections() )
234  {
235  stream << wxT( "=== " ) << section.m_SectionName << endl << endl;
236 
237  stream << wxT( "[width=\"100%\",options=\"header\",cols=\"20%,15%,65%\"]" ) << endl;
238  stream << wxT( "|===" ) << endl;
239  stream << _( "| Action | Default Hotkey | Description" ) << endl;
240 
241  for( HOTKEY& hk : section.m_HotKeys )
242  {
243  stream << wxT( "| " ) << hk.m_Actions[0]->GetLabel() << endl;
244 
245  if( hk.m_EditKeycode > 0 )
246  stream << wxT( " | `" ) << KeyNameFromKeyCode( hk.m_EditKeycode ) << '`' << endl;
247  else
248  stream << wxT( " |" ) << endl;
249 
250  stream << wxT( " | " ) << hk.m_Actions[0]->GetDescription( false ) << endl;
251  }
252 
253  stream << wxT( "|===" ) << endl << endl;
254  }
255 
256  stream.Flush();
257  fileStream.Close();
258 }
void OnFilterSearch(wxCommandEvent &aEvent)
Handle a change in the hotkey filter text.
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.
void SetMruPath(const wxString &aPath)
static const wxSize default_dialog_size
This file is part of the common library TODO brief description.
void ImportHotKeys()
Put up a dialog allowing the user to select a hotkeys file and then overlays those hotkeys onto the c...
void ResetPanel() override
Reset the contents of this panel.
bool TransferDataToControl()
Method TransferDataToControl Load the hotkey data from the store into the control.
void ReadHotKeyConfig(const wxString &aFileName, std::map< std::string, int > &aHotKeys)
Reads a hotkey config file into a map.
void AddHotKeys(TOOL_MANAGER *aToolMgr)
int GetStdMargin()
Get the standard margin around a widget in the KiCad UI.
Definition: ui_common.cpp:29
std::vector< TOOL_MANAGER * > m_toolManagers
EDA_BASE_FRAME * m_frame
Master controller class:
Definition: tool_manager.h:52
wxString GetMruPath() const
void installButtons(wxSizer *aSizer)
Install the button panel (global reset/default, import/export)
wxString EDA_FILE_SELECTOR(const wxString &aTitle, const wxString &aPath, const wxString &aFileName, const wxString &aExtension, const wxString &aWildcard, wxWindow *aParent, int aStyle, const bool aKeepWorkingDirectory, const wxPoint &aPosition, wxString *aMruPath)
A helper function that wraps a call to wxFileSelector.
Definition: gestfich.cpp:52
Functions to provide common constants and other functions to assist in making a consistent UI.
void ApplyFilterString(const wxString &aFilterStr)
Method ApplyFilterString Apply a filter string to the hotkey list, selecting which hotkeys to show.
void dumpHotkeys()
Dumps all actions and their hotkeys to a text file for inclusion in documentation.
bool TransferDataFromWindow() override
std::vector< TOOL_ACTION * > m_Actions
Definition: hotkey_store.h:36
bool TransferDataToWindow() override
std::vector< HOTKEY_SECTION > & GetSections()
Get the list of sections managed by this store.
#define _(s)
Definition: 3d_actions.cpp:33
The base frame for deriving all KiCad main window classes.
std::vector< BTN_DEF > BTN_DEF_LIST
A list of BTN_DEFs, used to group buttons into the left/right groups.
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Return the key name from the key code.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
PANEL_HOTKEYS_EDITOR(EDA_BASE_FRAME *aFrame, wxWindow *aWindow, bool aReadOnly)
WIDGET_HOTKEY_LIST * m_hotkeyListCtrl
#define DEFAULT_HOTKEY_FILENAME_EXT
Definition: hotkeys_basic.h:30
void Init(std::vector< TOOL_MANAGER * > aToolManagerList, bool aIncludeGestures)
int m_EditKeycode
Definition: hotkey_store.h:37
A wxPanel that is designed to be reset in a standard manner.
int WriteHotKeyConfig(const std::map< std::string, TOOL_ACTION * > &aActionMap)
Update the hotkeys config file with the hotkeys from the given actions map.
void ResetAllHotkeys(bool aResetToDefault)
Set hotkeys in the control to default or original values.
bool TransferDataFromControl()
Method TransferDataFromControl Save the hotkey data from the control.