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)
 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...
 
void ReadHotKeyConfigIntoActions (const wxString &aFileName, std::vector< TOOL_ACTION * > &aActions)
 Reads a hotkey config file into a list of actions. More...
 
int WriteHotKeyConfig (const std::vector< TOOL_ACTION * > &aActions)
 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 156 of file hotkeys_basic.cpp.

◆ MODIFIER_CMD_MAC

#define MODIFIER_CMD_MAC   wxT( "Cmd+" )

Definition at line 158 of file hotkeys_basic.cpp.

◆ MODIFIER_CTRL

#define MODIFIER_CTRL   wxT( "Ctrl+" )

Definition at line 155 of file hotkeys_basic.cpp.

◆ MODIFIER_CTRL_BASE

#define MODIFIER_CTRL_BASE   wxT( "Ctrl+" )

Definition at line 159 of file hotkeys_basic.cpp.

◆ MODIFIER_SHIFT

#define MODIFIER_SHIFT   wxT( "Shift+" )

Definition at line 160 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 237 of file hotkeys_basic.cpp.

238{
239 wxString msg = aText;
240 wxString keyname = KeyNameFromKeyCode( aHotKey );
241
242 if( !keyname.IsEmpty() )
243 {
244 switch( aStyle )
245 {
246 case IS_HOTKEY:
247 {
248 // Don't add a suffix for unassigned hotkeys:
249 // WX spews debug from wxAcceleratorEntry::ParseAccel if it doesn't
250 // recognize the keyname, which is the case for <unassigned>.
251 if( aHotKey != 0 )
252 {
253 msg << wxT( "\t" ) << keyname;
254 }
255 break;
256 }
257 case IS_COMMENT:
258 {
259 msg << wxT( " (" ) << keyname << wxT( ")" );
260 break;
261 }
262 }
263 }
264
265#ifdef USING_MAC_CMD
266 // On OSX, the modifier equivalent to the Ctrl key of PCs
267 // is the Cmd key, but in code we should use Ctrl as prefix in menus
268 msg.Replace( MODIFIER_CMD_MAC, MODIFIER_CTRL_BASE );
269#endif
270
271 return msg;
272}
#define MODIFIER_CMD_MAC
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Return the key name from the key code.
#define MODIFIER_CTRL_BASE
@ IS_HOTKEY
Definition: hotkeys_basic.h:77
@ IS_COMMENT
Definition: hotkeys_basic.h:78

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)

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 344 of file hotkeys_basic.cpp.

345{
346 DIALOG_LIST_HOTKEYS dlg( aParent );
347 dlg.ShowModal();
348}
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 278 of file hotkeys_basic.cpp.

279{
280 int ii, keycode = KEY_NON_FOUND;
281
282 // Search for modifiers: Ctrl+ Alt+ and Shift+
283 // Note: on Mac OSX, the Cmd key is equiv here to Ctrl
284 wxString key = keyname;
285 wxString prefix;
286 int modifier = 0;
287
288 while( true )
289 {
290 prefix.Empty();
291
292 if( key.StartsWith( MODIFIER_CTRL_BASE ) )
293 {
294 modifier |= MD_CTRL;
295 prefix = MODIFIER_CTRL_BASE;
296 }
297 else if( key.StartsWith( MODIFIER_CMD_MAC ) )
298 {
299 modifier |= MD_CTRL;
300 prefix = MODIFIER_CMD_MAC;
301 }
302 else if( key.StartsWith( MODIFIER_ALT ) )
303 {
304 modifier |= MD_ALT;
305 prefix = MODIFIER_ALT;
306 }
307 else if( key.StartsWith( MODIFIER_SHIFT ) )
308 {
309 modifier |= MD_SHIFT;
310 prefix = MODIFIER_SHIFT;
311 }
312 else
313 {
314 break;
315 }
316
317 if( !prefix.IsEmpty() )
318 key.Remove( 0, prefix.Len() );
319 }
320
321 if( (key.length() == 1) && (key[0] > ' ') && (key[0] < 0x7F) )
322 {
323 keycode = key[0];
324 keycode += modifier;
325 return keycode;
326 }
327
328 for( ii = 0; hotkeyNameList[ii].m_KeyCode != KEY_NON_FOUND; ii++ )
329 {
330 if( key.CmpNoCase( hotkeyNameList[ii].m_Name ) == 0 )
331 {
332 keycode = hotkeyNameList[ii].m_KeyCode + modifier;
333 break;
334 }
335 }
336
337 return keycode;
338}
#define MODIFIER_ALT
#define MODIFIER_SHIFT
static struct hotkey_name_descr hotkeyNameList[]
#define KEY_NON_FOUND
const wxChar * m_Name
@ MD_ALT
Definition: tool_event.h:140
@ MD_CTRL
Definition: tool_event.h:139
@ MD_SHIFT
Definition: tool_event.h:138

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 172 of file hotkeys_basic.cpp.

173{
174 wxString keyname, modifier, fullkeyname;
175 int ii;
176 bool found = false;
177
178 if( aKeycode == WXK_CONTROL )
179 return wxString( MODIFIER_CTRL ).BeforeFirst( '+' );
180 else if( aKeycode == WXK_RAW_CONTROL )
181 return wxString( MODIFIER_CTRL_BASE ).BeforeFirst( '+' );
182 else if( aKeycode == WXK_SHIFT )
183 return wxString( MODIFIER_SHIFT ).BeforeFirst( '+' );
184 else if( aKeycode == WXK_ALT )
185 return wxString( MODIFIER_ALT ).BeforeFirst( '+' );
186
187 // Assume keycode of 0 is "unassigned"
188 if( (aKeycode & MD_CTRL) != 0 )
189 modifier << MODIFIER_CTRL;
190
191 if( (aKeycode & MD_ALT) != 0 )
192 modifier << MODIFIER_ALT;
193
194 if( (aKeycode & MD_SHIFT) != 0 )
195 modifier << MODIFIER_SHIFT;
196
197 aKeycode &= ~( MD_CTRL | MD_ALT | MD_SHIFT );
198
199 if( (aKeycode > ' ') && (aKeycode < 0x7F ) )
200 {
201 found = true;
202 keyname.Append( (wxChar)aKeycode );
203 }
204 else
205 {
206 for( ii = 0; ; ii++ )
207 {
208 if( hotkeyNameList[ii].m_KeyCode == KEY_NON_FOUND ) // End of list
209 {
210 keyname = wxT( "<unknown>" );
211 break;
212 }
213
214 if( hotkeyNameList[ii].m_KeyCode == aKeycode )
215 {
216 keyname = hotkeyNameList[ii].m_Name;
217 found = true;
218 break;
219 }
220 }
221 }
222
223 if( aIsFound )
224 *aIsFound = found;
225
226 fullkeyname = modifier + keyname;
227 return fullkeyname;
228}
#define MODIFIER_CTRL

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, MODIFIER_CTRL_BASE, and MODIFIER_SHIFT.

Referenced by AddHotkeyName(), APPEARANCE_CONTROLS::APPEARANCE_CONTROLS(), WIDGET_HOTKEY_LIST::changeHotkey(), APPEARANCE_CONTROLS::createControls(), DIALOG_GRID_SETTINGS::DIALOG_GRID_SETTINGS(), PANEL_HOTKEYS_EDITOR::dumpHotkeys(), PAD_TOOL::EditPad(), HOTKEY_FILTER::FilterMatches(), TOOL_ACTION::GetDescription(), APPEARANCE_CONTROLS::rebuildLayerPresetsWidget(), APPEARANCE_CONTROLS::rebuildLayers(), APPEARANCE_CONTROLS::rebuildNets(), APPEARANCE_CONTROLS::rebuildViewportsWidget(), EDA_3D_VIEWER_FRAME::ReCreateMainToolbar(), WIDGET_HOTKEY_LIST::resolveKeyConflicts(), ACTION_MANAGER::RunHotKey(), 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 351 of file hotkeys_basic.cpp.

352{
353 wxString fileName = aFileName;
354
355 if( fileName.IsEmpty() )
356 {
357 wxFileName fn( "user" );
358 fn.SetExt( HotkeyFileExtension );
360 fileName = fn.GetFullPath();
361 }
362
363 if( !wxFile::Exists( fileName ) )
364 return;
365
366 wxFFile file( fileName, "rb" );
367
368 if( !file.IsOpened() ) // There is a problem to open file
369 return;
370
371 wxString input;
372 file.ReadAll( &input );
373 input.Replace( "\r\n", "\n" ); // Convert Windows files to Unix line-ends
374 wxStringTokenizer fileTokenizer( input, "\n", wxTOKEN_STRTOK );
375
376 while( fileTokenizer.HasMoreTokens() )
377 {
378 wxStringTokenizer lineTokenizer( fileTokenizer.GetNextToken(), "\t" );
379
380 wxString cmdName = lineTokenizer.GetNextToken();
381 wxString keyName = lineTokenizer.GetNextToken();
382
383 if( !cmdName.IsEmpty() )
384 aHotKeys[ cmdName.ToStdString() ] = KeyCodeFromKeyName( keyName );
385 }
386}
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
const std::string HotkeyFileExtension
int KeyCodeFromKeyName(const wxString &keyname)
Return the key code from its user-friendly key name (ie: "Ctrl+M").

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

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

◆ ReadHotKeyConfigIntoActions()

void ReadHotKeyConfigIntoActions ( const wxString &  aFileName,
std::vector< TOOL_ACTION * > &  aActions 
)

Reads a hotkey config file into a list of actions.

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

Definition at line 389 of file hotkeys_basic.cpp.

390{
391 std::map<std::string, int> hotkeys;
392
393 // Read the existing config (all hotkeys)
394 ReadHotKeyConfig( aFileName, hotkeys );
395
396 // Set each tool action hotkey to the config file hotkey if present
397 for( TOOL_ACTION* action : aActions )
398 if( hotkeys.find( action->GetName() ) != hotkeys.end() )
399 action->SetHotKey( hotkeys[action->GetName()] );
400}
Represent a single user action.
Definition: tool_action.h:68
void ReadHotKeyConfig(const wxString &aFileName, std::map< std::string, int > &aHotKeys)
Reads a hotkey config file into a map.

References hotkeys, and ReadHotKeyConfig().

Referenced by DIALOG_LIST_HOTKEYS::DIALOG_LIST_HOTKEYS(), and EDA_BASE_FRAME::ShowPreferences().

◆ 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 432 of file hotkeys_basic.cpp.

433{
434 // For Eeschema and Pcbnew frames, we read the new combined file.
435 // For other kifaces, we read the frame-based file
436 if( aAppname == LIB_EDIT_FRAME_NAME || aAppname == SCH_EDIT_FRAME_NAME )
437 {
439 }
440 else if( aAppname == PCB_EDIT_FRAME_NAME || aAppname == FOOTPRINT_EDIT_FRAME_NAME )
441 {
443 }
444
445 return ReadLegacyHotkeyConfigFile( aAppname, aMap );
446}
#define LIB_EDIT_FRAME_NAME
#define FOOTPRINT_EDIT_FRAME_NAME
#define SCH_EDIT_FRAME_NAME
#define PCB_EDIT_FRAME_NAME
int ReadLegacyHotkeyConfigFile(const wxString &aFilename, std::map< std::string, int > &aMap)
Read hotkey configuration for a given app.
#define EESCHEMA_HOTKEY_NAME
Definition: hotkeys_basic.h:31
#define PCBNEW_HOTKEY_NAME
Definition: hotkeys_basic.h:32

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 449 of file hotkeys_basic.cpp.

450{
451 wxFileName fn( aFilename );
452
453 fn.SetExt( HotkeyFileExtension );
455
456 if( !wxFile::Exists( fn.GetFullPath() ) )
457 return 0;
458
459 wxFFile cfgfile( fn.GetFullPath(), "rb" );
460
461 if( !cfgfile.IsOpened() ) // There is a problem to open file
462 return 0;
463
464 // get length
465 wxFileOffset size = cfgfile.Length();
466
467 // read data
468 std::vector<char> buffer( size );
469 cfgfile.Read( buffer.data(), size );
470 wxString data( buffer.data(), wxConvUTF8, size );
471
472 // Is this the wxConfig format? If so, remove "Keys=" and parse the newlines.
473 if( data.StartsWith( wxT("Keys="), &data ) )
474 data.Replace( "\\n", "\n", true );
475
476 // parse
477 wxStringTokenizer tokenizer( data, L"\r\n", wxTOKEN_STRTOK );
478
479 while( tokenizer.HasMoreTokens() )
480 {
481 wxString line = tokenizer.GetNextToken();
482 wxStringTokenizer lineTokenizer( line );
483
484 wxString line_type = lineTokenizer.GetNextToken();
485
486 if( line_type[0] == '#' ) // comment
487 continue;
488
489 if( line_type[0] == '[' ) // tags ignored reading legacy hotkeys
490 continue;
491
492 if( line_type == wxT( "$Endlist" ) )
493 break;
494
495 if( line_type != wxT( "shortcut" ) )
496 continue;
497
498 // Get the key name
499 lineTokenizer.SetString( lineTokenizer.GetString(), L"\"\r\n\t ", wxTOKEN_STRTOK );
500 wxString keyname = lineTokenizer.GetNextToken();
501
502 wxString remainder = lineTokenizer.GetString();
503
504 // Get the command name
505 wxString fctname = remainder.AfterFirst( '\"' ).BeforeFirst( '\"' );
506
507 // Add the pair to the map
508 aMap[ fctname.ToStdString() ] = KeyCodeFromKeyName( keyname );
509 }
510
511 // cleanup
512 cfgfile.Close();
513 return 1;
514}

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

Referenced by ReadLegacyHotkeyConfig().

◆ WriteHotKeyConfig()

int WriteHotKeyConfig ( const std::vector< TOOL_ACTION * > &  aActions)

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

Definition at line 403 of file hotkeys_basic.cpp.

404{
405 std::map<std::string, int> hotkeys;
406 wxFileName fn( "user" );
407
408 fn.SetExt( HotkeyFileExtension );
410
411 // Read the existing config (all hotkeys)
412 ReadHotKeyConfig( fn.GetFullPath(), hotkeys );
413
414 // Overlay the current app's hotkey definitions onto the map
415 for( const TOOL_ACTION* action : aActions )
416 hotkeys[ action->GetName() ] = action->GetHotKey();
417
418 // Write entire hotkey set
419 wxFFileOutputStream outStream( fn.GetFullPath() );
420 wxTextOutputStream txtStream( outStream, wxEOL_UNIX );
421
422 for( const std::pair<const std::string, int>& entry : hotkeys )
423 txtStream << entry.first << "\t" << KeyNameFromKeyCode( entry.second ) << endl;
424
425 txtStream.Flush();
426 outStream.Close();
427
428 return 1;
429}

References 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().