KiCad PCB EDA Suite
hotkeys_basic.cpp File Reference
#include <kiface_base.h>
#include <hotkeys_basic.h>
#include <id.h>
#include <string_utils.h>
#include <eda_base_frame.h>
#include <eda_draw_frame.h>
#include <wildcards_and_files_ext.h>
#include <settings/settings_manager.h>
#include <tool/tool_manager.h>
#include "dialogs/dialog_hotkey_list.h"
#include <wx/apptrait.h>
#include <wx/stdpaths.h>
#include <wx/tokenzr.h>
#include <wx/txtstrm.h>
#include <wx/wfstream.h>
#include <tool/tool_action.h>

Go to the source code of this file.

Classes

struct  hotkey_name_descr
 

Macros

#define KEY_NON_FOUND   -1
 
#define MODIFIER_CTRL   wxT( "Ctrl+" )
 
#define MODIFIER_ALT   wxT( "Alt+" )
 
#define MODIFIER_CMD_MAC   wxT( "Cmd+" )
 
#define MODIFIER_CTRL_BASE   wxT( "Ctrl+" )
 
#define MODIFIER_SHIFT   wxT( "Shift+" )
 

Functions

wxString KeyNameFromKeyCode (int aKeycode, bool *aIsFound)
 Return the key name from the key code. More...
 
wxString AddHotkeyName (const wxString &aText, int aHotKey, HOTKEY_ACTION_TYPE aStyle)
 
int KeyCodeFromKeyName (const wxString &keyname)
 Return the key code from its user-friendly key name (ie: "Ctrl+M"). More...
 
void DisplayHotkeyList (EDA_BASE_FRAME *aParent, TOOL_MANAGER *aToolManager)
 Display the current hotkey list. More...
 
void ReadHotKeyConfig (const wxString &aFileName, std::map< std::string, int > &aHotKeys)
 Reads a hotkey config file into a map. More...
 
int WriteHotKeyConfig (const std::map< std::string, TOOL_ACTION * > &aActionMap)
 Update the hotkeys config file with the hotkeys from the given actions map. More...
 
int ReadLegacyHotkeyConfig (const wxString &aAppname, std::map< std::string, int > &aMap)
 Read configuration data and fill the current hotkey list with hotkeys. More...
 
int ReadLegacyHotkeyConfigFile (const wxString &aFilename, std::map< std::string, int > &aMap)
 Read hotkey configuration for a given app. More...
 

Variables

static struct hotkey_name_descr hotkeyNameList []
 

Macro Definition Documentation

◆ KEY_NON_FOUND

#define KEY_NON_FOUND   -1

Definition at line 63 of file hotkeys_basic.cpp.

◆ MODIFIER_ALT

#define MODIFIER_ALT   wxT( "Alt+" )

Definition at line 140 of file hotkeys_basic.cpp.

◆ MODIFIER_CMD_MAC

#define MODIFIER_CMD_MAC   wxT( "Cmd+" )

Definition at line 142 of file hotkeys_basic.cpp.

◆ MODIFIER_CTRL

#define MODIFIER_CTRL   wxT( "Ctrl+" )

Definition at line 139 of file hotkeys_basic.cpp.

◆ MODIFIER_CTRL_BASE

#define MODIFIER_CTRL_BASE   wxT( "Ctrl+" )

Definition at line 143 of file hotkeys_basic.cpp.

◆ MODIFIER_SHIFT

#define MODIFIER_SHIFT   wxT( "Shift+" )

Definition at line 144 of file hotkeys_basic.cpp.

Function Documentation

◆ AddHotkeyName()

wxString AddHotkeyName ( const wxString &  aText,
int  aHotKey,
HOTKEY_ACTION_TYPE  aStyle 
)
Parameters
aTextthe base text on which to append the hotkey.
aHotKeythe hotkey keycode.
aStyleIS_HOTKEY to add <tab><keyname> (shortcuts in menus, same as hotkeys). IS_COMMENT to add <spaces><(keyname)> mainly in tool tips.

Definition at line 212 of file hotkeys_basic.cpp.

213 {
214  wxString msg = aText;
215  wxString keyname = KeyNameFromKeyCode( aHotKey );
216 
217  if( !keyname.IsEmpty() )
218  {
219  switch( aStyle )
220  {
221  case IS_HOTKEY:
222  {
223  // Don't add a suffix for unassigned hotkeys:
224  // WX spews debug from wxAcceleratorEntry::ParseAccel if it doesn't
225  // recognize the keyname, which is the case for <unassigned>.
226  if( aHotKey != 0 )
227  {
228  msg << wxT( "\t" ) << keyname;
229  }
230  break;
231  }
232  case IS_COMMENT:
233  {
234  msg << wxT( " (" ) << keyname << wxT( ")" );
235  break;
236  }
237  }
238  }
239 
240 #ifdef USING_MAC_CMD
241  // On OSX, the modifier equivalent to the Ctrl key of PCs
242  // is the Cmd key, but in code we should use Ctrl as prefix in menus
243  msg.Replace( MODIFIER_CMD_MAC, MODIFIER_CTRL_BASE );
244 #endif
245 
246  return msg;
247 }
#define MODIFIER_CTRL_BASE
#define MODIFIER_CMD_MAC
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Return the key name from the key code.

References IS_COMMENT, IS_HOTKEY, KeyNameFromKeyCode(), MODIFIER_CMD_MAC, and MODIFIER_CTRL_BASE.

Referenced by TOOL_ACTION::GetMenuItem(), and PCB_LAYER_BOX_SELECTOR::Resync().

◆ DisplayHotkeyList()

void DisplayHotkeyList ( EDA_BASE_FRAME aFrame,
TOOL_MANAGER aToolMgr 
)

Display the current hotkey list.

Parameters
aFramecurrent active frame.
aToolMgrthe tool manager holding the registered actions from which the hotkeys will be harvested.

Definition at line 319 of file hotkeys_basic.cpp.

320 {
321  DIALOG_LIST_HOTKEYS dlg( aParent, aToolManager );
322  dlg.ShowModal();
323 }
A dialog that presents the user with a read-only list of hotkeys and their current bindings.

Referenced by COMMON_CONTROL::ListHotKeys().

◆ KeyCodeFromKeyName()

int KeyCodeFromKeyName ( const wxString &  keyname)

Return the key code from its user-friendly key name (ie: "Ctrl+M").

Definition at line 253 of file hotkeys_basic.cpp.

254 {
255  int ii, keycode = KEY_NON_FOUND;
256 
257  // Search for modifiers: Ctrl+ Alt+ and Shift+
258  // Note: on Mac OSX, the Cmd key is equiv here to Ctrl
259  wxString key = keyname;
260  wxString prefix;
261  int modifier = 0;
262 
263  while( true )
264  {
265  prefix.Empty();
266 
267  if( key.StartsWith( MODIFIER_CTRL_BASE ) )
268  {
269  modifier |= MD_CTRL;
270  prefix = MODIFIER_CTRL_BASE;
271  }
272  else if( key.StartsWith( MODIFIER_CMD_MAC ) )
273  {
274  modifier |= MD_CTRL;
275  prefix = MODIFIER_CMD_MAC;
276  }
277  else if( key.StartsWith( MODIFIER_ALT ) )
278  {
279  modifier |= MD_ALT;
280  prefix = MODIFIER_ALT;
281  }
282  else if( key.StartsWith( MODIFIER_SHIFT ) )
283  {
284  modifier |= MD_SHIFT;
285  prefix = MODIFIER_SHIFT;
286  }
287  else
288  {
289  break;
290  }
291 
292  if( !prefix.IsEmpty() )
293  key.Remove( 0, prefix.Len() );
294  }
295 
296  if( (key.length() == 1) && (key[0] > ' ') && (key[0] < 0x7F) )
297  {
298  keycode = key[0];
299  keycode += modifier;
300  return keycode;
301  }
302 
303  for( ii = 0; hotkeyNameList[ii].m_KeyCode != KEY_NON_FOUND; ii++ )
304  {
305  if( key.CmpNoCase( hotkeyNameList[ii].m_Name ) == 0 )
306  {
307  keycode = hotkeyNameList[ii].m_KeyCode + modifier;
308  break;
309  }
310  }
311 
312  return keycode;
313 }
const wxChar * m_Name
#define MODIFIER_CTRL_BASE
#define KEY_NON_FOUND
#define MODIFIER_SHIFT
#define MODIFIER_ALT
#define MODIFIER_CMD_MAC
static struct hotkey_name_descr hotkeyNameList[]

References hotkeyNameList, KEY_NON_FOUND, hotkey_name_descr::m_KeyCode, hotkey_name_descr::m_Name, MD_ALT, MD_CTRL, MD_SHIFT, MODIFIER_ALT, MODIFIER_CMD_MAC, MODIFIER_CTRL_BASE, and MODIFIER_SHIFT.

Referenced by ReadHotKeyConfig(), ReadLegacyHotkeyConfigFile(), and WIDGET_HOTKEY_LIST::WIDGET_HOTKEY_LIST().

◆ KeyNameFromKeyCode()

wxString KeyNameFromKeyCode ( int  aKeycode,
bool *  aIsFound 
)

Return the key name from the key code.

Return the user friendly key name (ie: "Ctrl+M") from the key code.

Only some wxWidgets key values are handled for function key ( see hotkeyNameList[] )

Parameters
aKeycodekey code (ASCII value, or wxWidgets value for function keys).
aIsFounda pointer to a bool to return true if found, or false. an be nullptr default).
Returns
the key name in a wxString.

Definition at line 156 of file hotkeys_basic.cpp.

157 {
158  wxString keyname, modifier, fullkeyname;
159  int ii;
160  bool found = false;
161 
162  // Assume keycode of 0 is "unassigned"
163  if( (aKeycode & MD_CTRL) != 0 )
164  modifier << MODIFIER_CTRL;
165 
166  if( (aKeycode & MD_ALT) != 0 )
167  modifier << MODIFIER_ALT;
168 
169  if( (aKeycode & MD_SHIFT) != 0 )
170  modifier << MODIFIER_SHIFT;
171 
172  aKeycode &= ~( MD_CTRL | MD_ALT | MD_SHIFT );
173 
174  if( (aKeycode > ' ') && (aKeycode < 0x7F ) )
175  {
176  found = true;
177  keyname.Append( (wxChar)aKeycode );
178  }
179  else
180  {
181  for( ii = 0; ; ii++ )
182  {
183  if( hotkeyNameList[ii].m_KeyCode == KEY_NON_FOUND ) // End of list
184  {
185  keyname = wxT( "<unknown>" );
186  break;
187  }
188 
189  if( hotkeyNameList[ii].m_KeyCode == aKeycode )
190  {
191  keyname = hotkeyNameList[ii].m_Name;
192  found = true;
193  break;
194  }
195  }
196  }
197 
198  if( aIsFound )
199  *aIsFound = found;
200 
201  fullkeyname = modifier + keyname;
202  return fullkeyname;
203 }
const wxChar * m_Name
#define KEY_NON_FOUND
#define MODIFIER_CTRL
#define MODIFIER_SHIFT
#define MODIFIER_ALT
static struct hotkey_name_descr hotkeyNameList[]

References hotkeyNameList, KEY_NON_FOUND, hotkey_name_descr::m_KeyCode, hotkey_name_descr::m_Name, MD_ALT, MD_CTRL, MD_SHIFT, MODIFIER_ALT, MODIFIER_CTRL, and MODIFIER_SHIFT.

Referenced by AddHotkeyName(), WIDGET_HOTKEY_LIST::changeHotkey(), APPEARANCE_CONTROLS::createControls(), PANEL_HOTKEYS_EDITOR::dumpHotkeys(), PAD_TOOL::EditPad(), HOTKEY_FILTER::FilterMatches(), TOOL_ACTION::GetDescription(), WIDGET_HOTKEY_LIST::resolveKeyConflicts(), ACTION_MANAGER::RunHotKey(), DIALOG_GRID_SETTINGS::TransferDataToWindow(), PCB_CONTROL::unfilledZoneCheck(), WIDGET_HOTKEY_LIST::updateFromClientData(), and WriteHotKeyConfig().

◆ ReadHotKeyConfig()

void ReadHotKeyConfig ( const wxString &  aFileName,
std::map< std::string, int > &  aHotKeys 
)

Reads a hotkey config file into a map.

If aFileName is empty it will read in the default hotkeys file.

Definition at line 326 of file hotkeys_basic.cpp.

327 {
328  wxString fileName = aFileName;
329 
330  if( fileName.IsEmpty() )
331  {
332  wxFileName fn( "user" );
333  fn.SetExt( HotkeyFileExtension );
335  fileName = fn.GetFullPath();
336  }
337 
338  if( !wxFile::Exists( fileName ) )
339  return;
340 
341  wxFFile file( fileName, "rb" );
342 
343  if( !file.IsOpened() ) // There is a problem to open file
344  return;
345 
346  wxString input;
347  file.ReadAll( &input );
348  input.Replace( "\r\n", "\n" ); // Convert Windows files to Unix line-ends
349  wxStringTokenizer fileTokenizer( input, "\n", wxTOKEN_STRTOK );
350 
351  while( fileTokenizer.HasMoreTokens() )
352  {
353  wxStringTokenizer lineTokenizer( fileTokenizer.GetNextToken(), "\t" );
354 
355  wxString cmdName = lineTokenizer.GetNextToken();
356  wxString keyName = lineTokenizer.GetNextToken();
357 
358  if( !cmdName.IsEmpty() )
359  aHotKeys[ cmdName.ToStdString() ] = KeyCodeFromKeyName( keyName );
360  }
361 }
int KeyCodeFromKeyName(const wxString &keyname)
Return the key code from its user-friendly key name (ie: "Ctrl+M").
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
const std::string HotkeyFileExtension

References SETTINGS_MANAGER::GetUserSettingsPath(), HotkeyFileExtension, and KeyCodeFromKeyName().

Referenced by PANEL_HOTKEYS_EDITOR::ImportHotKeys(), ACTION_MANAGER::UpdateHotKeys(), and WriteHotKeyConfig().

◆ ReadLegacyHotkeyConfig()

int ReadLegacyHotkeyConfig ( const wxString &  aAppname,
std::map< std::string, int > &  aMap 
)

Read configuration data and fill the current hotkey list with hotkeys.

Parameters
aAppnamethe value of the app's m_FrameName.
aMapThe list of keycodes mapped by legacy property names.

Definition at line 394 of file hotkeys_basic.cpp.

395 {
396  // For Eeschema and Pcbnew frames, we read the new combined file.
397  // For other kifaces, we read the frame-based file
398  if( aAppname == LIB_EDIT_FRAME_NAME || aAppname == SCH_EDIT_FRAME_NAME )
399  {
401  }
402  else if( aAppname == PCB_EDIT_FRAME_NAME || aAppname == FOOTPRINT_EDIT_FRAME_NAME )
403  {
405  }
406 
407  return ReadLegacyHotkeyConfigFile( aAppname, aMap );
408 }
int ReadLegacyHotkeyConfigFile(const wxString &aFilename, std::map< std::string, int > &aMap)
Read hotkey configuration for a given app.
#define LIB_EDIT_FRAME_NAME
#define SCH_EDIT_FRAME_NAME
#define FOOTPRINT_EDIT_FRAME_NAME
#define EESCHEMA_HOTKEY_NAME
Definition: hotkeys_basic.h:30
#define PCB_EDIT_FRAME_NAME
#define PCBNEW_HOTKEY_NAME
Definition: hotkeys_basic.h:31

References EESCHEMA_HOTKEY_NAME, FOOTPRINT_EDIT_FRAME_NAME, LIB_EDIT_FRAME_NAME, PCB_EDIT_FRAME_NAME, PCBNEW_HOTKEY_NAME, ReadLegacyHotkeyConfigFile(), and SCH_EDIT_FRAME_NAME.

Referenced by ACTION_MANAGER::UpdateHotKeys().

◆ ReadLegacyHotkeyConfigFile()

int ReadLegacyHotkeyConfigFile ( const wxString &  aFilename,
std::map< std::string, int > &  aMap 
)

Read hotkey configuration for a given app.

Parameters
aFilenamethe filename to save the hotkeys as.
aMapThe list of keycodes mapped by legacy property names.
Returns
1 on success, 0 on failure.

Definition at line 411 of file hotkeys_basic.cpp.

412 {
413  wxFileName fn( aFilename );
414 
415  fn.SetExt( HotkeyFileExtension );
417 
418  if( !wxFile::Exists( fn.GetFullPath() ) )
419  return 0;
420 
421  wxFFile cfgfile( fn.GetFullPath(), "rb" );
422 
423  if( !cfgfile.IsOpened() ) // There is a problem to open file
424  return 0;
425 
426  // get length
427  wxFileOffset size = cfgfile.Length();
428 
429  // read data
430  std::vector<char> buffer( size );
431  cfgfile.Read( buffer.data(), size );
432  wxString data( buffer.data(), wxConvUTF8, size );
433 
434  // Is this the wxConfig format? If so, remove "Keys=" and parse the newlines.
435  if( data.StartsWith( wxT("Keys="), &data ) )
436  data.Replace( "\\n", "\n", true );
437 
438  // parse
439  wxStringTokenizer tokenizer( data, L"\r\n", wxTOKEN_STRTOK );
440 
441  while( tokenizer.HasMoreTokens() )
442  {
443  wxString line = tokenizer.GetNextToken();
444  wxStringTokenizer lineTokenizer( line );
445 
446  wxString line_type = lineTokenizer.GetNextToken();
447 
448  if( line_type[0] == '#' ) // comment
449  continue;
450 
451  if( line_type[0] == '[' ) // tags ignored reading legacy hotkeys
452  continue;
453 
454  if( line_type == wxT( "$Endlist" ) )
455  break;
456 
457  if( line_type != wxT( "shortcut" ) )
458  continue;
459 
460  // Get the key name
461  lineTokenizer.SetString( lineTokenizer.GetString(), L"\"\r\n\t ", wxTOKEN_STRTOK );
462  wxString keyname = lineTokenizer.GetNextToken();
463 
464  wxString remainder = lineTokenizer.GetString();
465 
466  // Get the command name
467  wxString fctname = remainder.AfterFirst( '\"' ).BeforeFirst( '\"' );
468 
469  // Add the pair to the map
470  aMap[ fctname.ToStdString() ] = KeyCodeFromKeyName( keyname );
471  }
472 
473  // cleanup
474  cfgfile.Close();
475  return 1;
476 }
int KeyCodeFromKeyName(const wxString &keyname)
Return the key code from its user-friendly key name (ie: "Ctrl+M").
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
const std::string HotkeyFileExtension

References SETTINGS_MANAGER::GetUserSettingsPath(), HotkeyFileExtension, and KeyCodeFromKeyName().

Referenced by ReadLegacyHotkeyConfig().

◆ WriteHotKeyConfig()

int WriteHotKeyConfig ( const std::map< std::string, TOOL_ACTION * > &  aActionMap)

Update the hotkeys config file with the hotkeys from the given actions map.

Definition at line 364 of file hotkeys_basic.cpp.

365 {
366  std::map<std::string, int> hotkeys;
367  wxFileName fn( "user" );
368 
369  fn.SetExt( HotkeyFileExtension );
371 
372  // Read the existing config (all hotkeys)
373  ReadHotKeyConfig( fn.GetFullPath(), hotkeys );
374 
375  // Overlay the current app's hotkey definitions onto the map
376  for( const auto& ii : aActionMap )
377  hotkeys[ ii.first ] = ii.second->GetHotKey();
378 
379  // Write entire hotkey set
380  wxFFileOutputStream outStream( fn.GetFullPath() );
381  wxTextOutputStream txtStream( outStream, wxEOL_UNIX );
382 
383  for( const auto& ii : hotkeys )
384  txtStream << wxString::Format( "%s\t%s", ii.first,
385  KeyNameFromKeyCode( ii.second ) ) << endl;
386 
387  txtStream.Flush();
388  outStream.Close();
389 
390  return 1;
391 }
void ReadHotKeyConfig(const wxString &aFileName, std::map< std::string, int > &aHotKeys)
Reads a hotkey config file into a map.
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
const std::string HotkeyFileExtension
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Return the key name from the key code.

References Format(), SETTINGS_MANAGER::GetUserSettingsPath(), HotkeyFileExtension, hotkeys, KeyNameFromKeyCode(), and ReadHotKeyConfig().

Referenced by PANEL_HOTKEYS_EDITOR::TransferDataFromWindow().

Variable Documentation

◆ hotkeyNameList

struct hotkey_name_descr hotkeyNameList[]
static

Definition at line 64 of file hotkeys_basic.cpp.

Referenced by KeyCodeFromKeyName(), and KeyNameFromKeyCode().