KiCad PCB EDA Suite
hotkeys_basic.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) 2015 Jean-Pierre Charras, j-p.charras at wanadoo.fr
5  * Copyright (C) 2010-2011 Wayne Stambaugh <stambaughw@verizon.net>
6  * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
31 #include <fctsys.h>
32 #include <kiface_i.h>
33 #include <hotkeys_basic.h>
34 #include <id.h>
35 #include <confirm.h>
36 #include <kicad_string.h>
37 #include <gestfich.h>
38 #include <eda_base_frame.h>
39 #include <macros.h>
40 #include <dialog_hotkeys_editor.h>
41 #include <menus_helpers.h>
42 #include <draw_frame.h>
43 #include <tool/tool_manager.h>
44 
45 #include <wx/apptrait.h>
46 #include <wx/stdpaths.h>
47 #include <wx/tokenzr.h>
48 
49 #define HOTKEYS_CONFIG_KEY wxT( "Keys" )
50 
51 wxString g_CommonSectionTag( wxT( "[common]" ) );
52 
53 
54 /* Class to handle hotkey commands hotkeys have a default value
55  * This class allows the real key code changed by user from a key code list
56  * file.
57  */
58 
59 EDA_HOTKEY::EDA_HOTKEY( const wxChar* infomsg, int idcommand, int keycode, int idmenuevent ) :
60  m_defaultKeyCode( keycode ), m_KeyCode( keycode ), m_InfoMsg( infomsg ),
61  m_Idcommand( idcommand ), m_IdMenuEvent( idmenuevent )
62 {
63 }
64 
65 
67 {
68  m_defaultKeyCode = base->m_defaultKeyCode; // initialize default key code
69  m_KeyCode = base->m_KeyCode;
70  m_InfoMsg = base->m_InfoMsg;
71  m_Idcommand = base->m_Idcommand;
73 }
74 
75 
77 {
78 }
79 
80 
81 /* class to handle the printable name and the keycode
82  */
84 {
85  const wxChar* m_Name;
86  int m_KeyCode;
87 };
88 
89 /* table giving the hotkey name from the hotkey code, for special keys
90  * Note : when modifiers (ATL, SHIFT, CTRL) do not modify
91  * the code of the key, do need to enter the modified key code
92  * For instance wxT( "F1" ), WXK_F1 handle F1, AltF1, CtrlF1 ...
93  * Key names are:
94  * "Space","Ctrl+Space","Alt+Space" or
95  * "Alt+A","Ctrl+F1", ...
96  */
98 {
99  { wxT( "F1" ), WXK_F1 },
100  { wxT( "F2" ), WXK_F2 },
101  { wxT( "F3" ), WXK_F3 },
102  { wxT( "F4" ), WXK_F4 },
103  { wxT( "F5" ), WXK_F5 },
104  { wxT( "F6" ), WXK_F6 },
105  { wxT( "F7" ), WXK_F7 },
106  { wxT( "F8" ), WXK_F8 },
107  { wxT( "F9" ), WXK_F9 },
108  { wxT( "F10" ), WXK_F10 },
109  { wxT( "F11" ), WXK_F11 },
110  { wxT( "F12" ), WXK_F12 },
111 
112  { wxT( "Esc" ), WXK_ESCAPE },
113  { wxT( "Del" ), WXK_DELETE },
114  { wxT( "Tab" ), WXK_TAB },
115  { wxT( "BkSp" ), WXK_BACK },
116  { wxT( "Ins" ), WXK_INSERT },
117 
118  { wxT( "Home" ), WXK_HOME },
119  { wxT( "End" ), WXK_END },
120  { wxT( "PgUp" ), WXK_PAGEUP },
121  { wxT( "PgDn" ), WXK_PAGEDOWN },
122 
123  { wxT( "Up" ), WXK_UP },
124  { wxT( "Down" ), WXK_DOWN },
125  { wxT( "Left" ), WXK_LEFT },
126  { wxT( "Right" ), WXK_RIGHT },
127 
128  { wxT( "Return" ), WXK_RETURN },
129 
130  { wxT( "Space" ), WXK_SPACE },
131 
132  // Do not change this line: end of list
133  { wxT( "" ), 0 }
134 };
135 
136 // name of modifier keys.
137 // Note: the Ctrl key is Cmd key on Mac OS X.
138 // However, in wxWidgets defs, the key WXK_CONTROL is the Cmd key,
139 // so the code using WXK_CONTROL should be ok on any system.
140 // (on Mac OS X the actual Ctrl key code is WXK_RAW_CONTROL)
141 #ifdef __WXMAC__
142 #define USING_MAC_CMD
143 #endif
144 
145 #ifdef USING_MAC_CMD
146 #define MODIFIER_CTRL wxT( "Cmd+" )
147 #else
148 #define MODIFIER_CTRL wxT( "Ctrl+" )
149 #endif
150 #define MODIFIER_CMD_MAC wxT( "Cmd+" )
151 #define MODIFIER_CTRL_BASE wxT( "Ctrl+" )
152 #define MODIFIER_ALT wxT( "Alt+" )
153 #define MODIFIER_SHIFT wxT( "Shift+" )
154 
155 
165 wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound )
166 {
167  wxString keyname, modifier, fullkeyname;
168  int ii;
169  bool found = false;
170 
171  // Assume keycode of 0 is "unassigned"
172  if( aKeycode == 0 )
173  return wxT( "<unassigned>");
174 
175  if( (aKeycode & GR_KB_CTRL) != 0 )
176  modifier << MODIFIER_CTRL;
177 
178  if( (aKeycode & GR_KB_ALT) != 0 )
179  modifier << MODIFIER_ALT;
180 
181  if( (aKeycode & GR_KB_SHIFT) != 0 )
182  modifier << MODIFIER_SHIFT;
183 
184  aKeycode &= ~( GR_KB_CTRL | GR_KB_ALT | GR_KB_SHIFT );
185 
186  if( (aKeycode > ' ') && (aKeycode < 0x7F ) )
187  {
188  found = true;
189  keyname.Append( (wxChar)aKeycode );
190  }
191  else
192  {
193  for( ii = 0; ; ii++ )
194  {
195  if( hotkeyNameList[ii].m_KeyCode == 0 ) // End of list
196  {
197  keyname = wxT( "<unknown>" );
198  break;
199  }
200 
201  if( hotkeyNameList[ii].m_KeyCode == aKeycode )
202  {
203  keyname = hotkeyNameList[ii].m_Name;
204  found = true;
205  break;
206  }
207  }
208  }
209 
210  if( aIsFound )
211  *aIsFound = found;
212 
213  fullkeyname = modifier + keyname;
214  return fullkeyname;
215 }
216 
217 
218 /*
219  * helper function use in AddHotkeyName to calculate an accelerator string
220  * In some menus, accelerators do not perform exactly the same action as
221  * the hotkey that perform a similar action.
222  * this is usually the case when this action uses the current mouse position
223  * for instance zoom action is ran from the F1 key or the Zoom menu.
224  * a zoom uses the mouse position from a hot key and not from the menu
225  * In this case, the accelerator if Shift+<hotkey>
226  * But for many keys, the Shift modifier is not usable, and the accelerator is Alt+<hotkey>
227  */
228 static void AddModifierToKey( wxString& aFullKey, const wxString & aKey )
229 {
230  if( (aKey.Length() == 1) && (aKey[0] >= 'A') && (aKey[0] <= 'Z'))
231  // We can use Shift+<key> as accelerator and <key> for hot key
232  aFullKey << wxT( "\t" ) << MODIFIER_SHIFT << aKey;
233  else
234  // We must use Alt+<key> as accelerator and <key> for hot key
235  aFullKey << wxT( "\t" ) << MODIFIER_ALT << aKey;
236 }
237 
238 
239 /* AddHotkeyName
240  * Add the key name from the Command id value ( m_Idcommand member value)
241  * aText = a wxString. returns aText + key name
242  * aList = pointer to a EDA_HOTKEY list of commands
243  * aCommandId = Command Id value
244  * aShortCutType = IS_HOTKEY to add <tab><keyname> (shortcuts in menus, same as hotkeys)
245  * IS_ACCELERATOR to add <tab><Shift+keyname> (accelerators in menus, not hotkeys)
246  * IS_COMMENT to add <spaces><(keyname)> mainly in tool tips
247  * Return a wxString (aTest + key name) if key found or aText without modification
248  */
249 wxString AddHotkeyName( const wxString& aText, EDA_HOTKEY** aList,
250  int aCommandId, HOTKEY_ACTION_TYPE aShortCutType )
251 {
252  wxString msg = aText;
253  wxString keyname;
254 
255  if( aList )
256  keyname = KeyNameFromCommandId( aList, aCommandId );
257 
258  if( !keyname.IsEmpty() )
259  {
260  switch( aShortCutType )
261  {
262  case IS_HOTKEY:
263  msg << wxT( "\t" ) << keyname;
264  break;
265 
266  case IS_ACCELERATOR:
267  AddModifierToKey( msg, keyname );
268  break;
269 
270  case IS_COMMENT:
271  msg << wxT( " (" ) << keyname << wxT( ")" );
272  break;
273  }
274  }
275 
276 #ifdef USING_MAC_CMD
277  // On OSX, the modifier equivalent to the Ctrl key of PCs
278  // is the Cmd key, but in code we should use Ctrl as prefix in menus
279  msg.Replace( MODIFIER_CMD_MAC, MODIFIER_CTRL_BASE );
280 #endif
281 
282  return msg;
283 }
284 
285 
286 /* AddHotkeyName
287  * Add the key name from the Command id value ( m_Idcommand member value)
288  * aText = a wxString. returns aText + key name
289  * aList = pointer to a EDA_HOTKEY_CONFIG DescrList of commands
290  * aCommandId = Command Id value
291  * aShortCutType = IS_HOTKEY to add <tab><keyname> (active shortcuts in menus)
292  * IS_ACCELERATOR to add <tab><Shift+keyname> (active accelerators in menus)
293  * IS_COMMENT to add <spaces><(keyname)>
294  * Return a wxString (aText + key name) if key found or aText without modification
295  */
296 wxString AddHotkeyName( const wxString& aText,
297  struct EDA_HOTKEY_CONFIG* aDescList,
298  int aCommandId,
299  HOTKEY_ACTION_TYPE aShortCutType )
300 {
301  wxString msg = aText;
302  wxString keyname;
303  EDA_HOTKEY** list;
304 
305  if( aDescList )
306  {
307  for( ; aDescList->m_HK_InfoList != nullptr; aDescList++ )
308  {
309  list = aDescList->m_HK_InfoList;
310  keyname = KeyNameFromCommandId( list, aCommandId );
311 
312  if( !keyname.IsEmpty() )
313  {
314  switch( aShortCutType )
315  {
316  case IS_HOTKEY:
317  msg << wxT( "\t" ) << keyname;
318  break;
319 
320  case IS_ACCELERATOR:
321  AddModifierToKey( msg, keyname );
322  break;
323 
324  case IS_COMMENT:
325  msg << wxT( " (" ) << keyname << wxT( ")" );
326  break;
327  }
328 
329  break;
330  }
331  }
332  }
333 
334 #ifdef USING_MAC_CMD
335  // On OSX, the modifier equivalent to the Ctrl key of PCs
336  // is the Cmd key, but in code we should use Ctrl as prefix in menus
337  msg.Replace( MODIFIER_CMD_MAC, MODIFIER_CTRL_BASE );
338 #endif
339 
340  return msg;
341 }
342 
343 
351 wxString KeyNameFromCommandId( EDA_HOTKEY** aList, int aCommandId )
352 {
353  wxString keyname;
354 
355  for( ; *aList != nullptr; aList++ )
356  {
357  EDA_HOTKEY* hk_decr = *aList;
358 
359  if( hk_decr->m_Idcommand == aCommandId )
360  {
361  keyname = KeyNameFromKeyCode( hk_decr->m_KeyCode );
362  break;
363  }
364  }
365 
366  return keyname;
367 }
368 
369 
378 int KeyCodeFromKeyName( const wxString& keyname )
379 {
380  int ii, keycode = 0;
381 
382  // Search for modifiers: Ctrl+ Alt+ and Shift+
383  // Note: on Mac OSX, the Cmd key is equiv here to Ctrl
384  wxString key = keyname;
385  wxString prefix;
386  int modifier = 0;
387 
388  while( 1 )
389  {
390  prefix.Empty();
391 
392  if( key.StartsWith( MODIFIER_CTRL_BASE ) )
393  {
394  modifier |= GR_KB_CTRL;
395  prefix = MODIFIER_CTRL_BASE;
396  }
397  else if( key.StartsWith( MODIFIER_CMD_MAC ) )
398  {
399  modifier |= GR_KB_CTRL;
400  prefix = MODIFIER_CMD_MAC;
401  }
402  else if( key.StartsWith( MODIFIER_ALT ) )
403  {
404  modifier |= GR_KB_ALT;
405  prefix = MODIFIER_ALT;
406  }
407  else if( key.StartsWith( MODIFIER_SHIFT ) )
408  {
409  modifier |= GR_KB_SHIFT;
410  prefix = MODIFIER_SHIFT;
411  }
412  else
413  {
414  break;
415  }
416 
417  if( !prefix.IsEmpty() )
418  key.Remove( 0, prefix.Len() );
419  }
420 
421  if( (key.length() == 1) && (key[0] > ' ') && (key[0] < 0x7F) )
422  {
423  keycode = key[0];
424  keycode += modifier;
425  return keycode;
426  }
427 
428  for( ii = 0; hotkeyNameList[ii].m_KeyCode != 0; ii++ )
429  {
430  if( key.CmpNoCase( hotkeyNameList[ii].m_Name ) == 0 )
431  {
432  keycode = hotkeyNameList[ii].m_KeyCode + modifier;
433  break;
434  }
435  }
436 
437  return keycode;
438 }
439 
440 
441 /* DisplayHotkeyList
442  * Displays the current hotkey list
443  * aList = a EDA_HOTKEY_CONFIG list(Null terminated)
444  */
445 #include <html_messagebox.h>
446 
447 void DisplayHotkeyList( EDA_BASE_FRAME* aFrame, struct EDA_HOTKEY_CONFIG* aDescList )
448 {
449  wxString keyname;
450  wxString keymessage;
451  EDA_HOTKEY** list;
452 
453  wxString msg = wxT( "<html><body bgcolor=\"#E2E2E2\">" );
454 
455  msg += wxT( "<H3>" );
456  msg += _( "Hotkeys List" );
457  msg += wxT( "</H3> <table cellpadding=\"0\">" );
458 
459  for( ; aDescList->m_HK_InfoList != nullptr; aDescList++ )
460  {
461  list = aDescList->m_HK_InfoList;
462 
463  for( ; *list != nullptr; list++ )
464  {
465  EDA_HOTKEY* hk_decr = *list;
466 
467  if( !hk_decr->m_InfoMsg.Contains( wxT( "Macros" ) ) )
468  {
469  keyname = KeyNameFromKeyCode( hk_decr->m_KeyCode );
470  keymessage = wxGetTranslation( hk_decr->m_InfoMsg );
471 
472  // Some chars are modified, using html encoding, to be
473  // displayed by DisplayHtmlInfoMessage()
474  keyname.Replace( wxT( "<" ), wxT( "&lt;" ) );
475  keyname.Replace( wxT( ">" ), wxT( "&gt;" ) );
476  msg += wxT( "<tr><td>" ) + keymessage + wxT( "</td>" );
477  msg += wxT( "<td><b>&nbsp;&nbsp;" ) + keyname + wxT( "</b></td></tr>" );
478  }
479  }
480  }
481 
482  msg += wxT( "</table></html></body>" );
483 
484  // Create a non modal dialog, which shows the list of hotkeys until dismissed
485  // but does not block the parent window
486  HTML_MESSAGE_BOX *dlg = new HTML_MESSAGE_BOX( aFrame, _( "Hotkeys List" ) );
487  dlg->SetDialogSizeInDU( 300, 250 );
488 
489  dlg->AddHTML_Text( msg );
490  dlg->Show( true );
491 }
492 
493 
502 {
503  for( ; *aList != nullptr; aList++ )
504  {
505  EDA_HOTKEY* hk_decr = *aList;
506 
507  if( hk_decr->m_KeyCode == aKey )
508  return hk_decr;
509  }
510 
511  return nullptr;
512 }
513 
514 
516 {
517  for( ; *aList != nullptr; aList++ )
518  {
519  EDA_HOTKEY* hk_decr = *aList;
520 
521  if( hk_decr->m_Idcommand == aCommand )
522  return hk_decr;
523  }
524 
525  return nullptr;
526 }
527 
528 
530  wxString* aFullFileName )
531 {
532  wxString msg;
533  wxString keyname, infokey;
534  FILE* file;
535 
536  msg = wxT( "$hotkey list\n" );
537 
538  // Print the current hotkey list
539  EDA_HOTKEY** list;
540 
541  for( ; aDescList->m_HK_InfoList != nullptr; aDescList++ )
542  {
543  if( aDescList->m_Title )
544  {
545  msg += wxT( "# " );
546  msg += *aDescList->m_Title;
547  msg += wxT( "\n" );
548  }
549 
550  msg += *aDescList->m_SectionTag;
551  msg += wxT( "\n" );
552 
553  list = aDescList->m_HK_InfoList;
554 
555  for( ; *list != nullptr; list++ )
556  {
557  EDA_HOTKEY* hk_decr = *list;
558  msg += wxT( "shortcut " );
559  keyname = KeyNameFromKeyCode( hk_decr->m_KeyCode );
560  AddDelimiterString( keyname );
561  infokey = hk_decr->m_InfoMsg;
562  AddDelimiterString( infokey );
563  msg += keyname + wxT( ": " ) + infokey + wxT( "\n" );
564  }
565  }
566 
567  msg += wxT( "$Endlist\n" );
568 
569  if( aFullFileName )
570  file = wxFopen( *aFullFileName, wxT( "wt" ) );
571  else
572  {
573  wxString configName( ConfigBaseName() );
574  if( configName == SCH_EDIT_FRAME_NAME || configName == LIB_EDIT_FRAME_NAME )
575  configName = EESCHEMA_HOTKEY_NAME;
576  else if( configName == PCB_EDIT_FRAME_NAME ||
577  configName == FOOTPRINT_EDIT_FRAME_NAME )
578  configName = PCBNEW_HOTKEY_NAME;
579 
580  wxFileName fn( configName );
581  fn.SetExt( DEFAULT_HOTKEY_FILENAME_EXT );
582  fn.SetPath( GetKicadConfigPath() );
583  file = wxFopen( fn.GetFullPath(), wxT( "wt" ) );
584  }
585 
586  if( file )
587  {
588  wxFputs( msg, file );
589  fclose( file );
590  }
591  else
592  {
593  msg.Printf( wxT( "Unable to write file %s" ), GetChars( *aFullFileName ) );
594  return 0;
595  }
596 
597  return 1;
598 }
599 
600 
601 int ReadHotkeyConfigFile( const wxString& aFilename, struct EDA_HOTKEY_CONFIG* aDescList,
602  const bool aDefaultLocation )
603 {
604  wxFileName fn( aFilename );
605 
606  if( aDefaultLocation )
607  {
608  fn.SetExt( DEFAULT_HOTKEY_FILENAME_EXT );
609  fn.SetPath( GetKicadConfigPath() );
610  }
611 
612  if( !wxFile::Exists( fn.GetFullPath() ) )
613  return 0;
614 
615  wxFile cfgfile( fn.GetFullPath() );
616  if( !cfgfile.IsOpened() ) // There is a problem to open file
617  return 0;
618 
619  // get length
620  cfgfile.SeekEnd();
621  wxFileOffset size = cfgfile.Tell();
622  cfgfile.Seek( 0 );
623 
624  // read data
625  std::vector<char> buffer( size );
626  cfgfile.Read( buffer.data(), size );
627  wxString data( buffer.data(), wxConvUTF8 );
628 
629  // Is this the wxConfig format? If so, remove "Keys=" and parse the newlines.
630  if( data.StartsWith( wxT("Keys="), &data ) )
631  data.Replace( "\\n", "\n", true );
632 
633  // parse
634  ParseHotkeyConfig( data, aDescList, aFilename );
635 
636  // cleanup
637  cfgfile.Close();
638  return 1;
639 }
640 
641 
642 int ReadHotkeyConfig( const wxString& aAppname, struct EDA_HOTKEY_CONFIG* aDescList )
643 {
644  // For Eeschema and Pcbnew frames, we try twice.
645  // The first time, we try to read the new combined file. If it doesn't exist,
646  // we fall back to reading the old, frame-based file
647  if( aAppname == LIB_EDIT_FRAME_NAME || aAppname == SCH_EDIT_FRAME_NAME )
648  {
649  if( ReadHotkeyConfigFile( EESCHEMA_HOTKEY_NAME, aDescList ) )
650  return 1;
651  }
652  else if( aAppname == PCB_EDIT_FRAME_NAME || aAppname == FOOTPRINT_EDIT_FRAME_NAME )
653  {
654  if( ReadHotkeyConfigFile( PCBNEW_HOTKEY_NAME, aDescList ) )
655  return 1;
656  }
657 
658  return ReadHotkeyConfigFile( aAppname, aDescList );
659 }
660 
661 
662 /* Function ParseHotkeyConfig
663  * the input format is: shortcut "key" "function"
664  * lines starting by # are ignored (comments)
665  * lines like [xxx] are tags (example: [common] or [libedit] which identify sections
666  */
667 void ParseHotkeyConfig( const wxString& data,
668  struct EDA_HOTKEY_CONFIG* aDescList,
669  const wxString& aAppname )
670 {
671  // Read the config
672  wxStringTokenizer tokenizer( data, L"\r\n", wxTOKEN_STRTOK );
673  EDA_HOTKEY** CurrentHotkeyList = nullptr;
674 
675  while( tokenizer.HasMoreTokens() )
676  {
677  wxString line = tokenizer.GetNextToken();
678  wxStringTokenizer lineTokenizer( line );
679 
680  wxString line_type = lineTokenizer.GetNextToken();
681 
682  if( line_type[0] == '#' ) //comment
683  continue;
684 
685  if( line_type[0] == '[' ) // A tag is found. search infos in list
686  {
687  CurrentHotkeyList = nullptr;
688  EDA_HOTKEY_CONFIG* DList = aDescList;
689 
690  for( ; DList->m_HK_InfoList; DList++ )
691  {
692  if( *DList->m_SectionTag == line_type )
693  {
694  CurrentHotkeyList = DList->m_HK_InfoList;
695  break;
696  }
697  }
698 
699  continue;
700  }
701 
702  // Do not accept hotkey assignments from hotkey files that don't match the application
703  if( aAppname == LIB_EDIT_FRAME_NAME && line_type == wxT( "[eeschema]" ) )
704  CurrentHotkeyList = nullptr;
705 
706  if( aAppname == SCH_EDIT_FRAME_NAME && line_type == wxT( "[libedit]" ) )
707  CurrentHotkeyList = nullptr;
708 
709  if( aAppname == PCB_EDIT_FRAME_NAME && line_type == wxT( "[footprinteditor]" ) )
710  CurrentHotkeyList = nullptr;
711 
712  if( aAppname == FOOTPRINT_EDIT_FRAME_NAME && line_type == wxT( "[pcbnew]" ) )
713  CurrentHotkeyList = nullptr;
714 
715  if( line_type == wxT( "$Endlist" ) )
716  break;
717 
718  if( line_type != wxT( "shortcut" ) )
719  continue;
720 
721  if( CurrentHotkeyList == nullptr )
722  continue;
723 
724  // Get the key name
725  lineTokenizer.SetString( lineTokenizer.GetString(), L"\"\r\n\t ", wxTOKEN_STRTOK );
726  wxString keyname = lineTokenizer.GetNextToken();
727 
728  wxString remainder = lineTokenizer.GetString();
729 
730  // Get the command name
731  wxString fctname = remainder.AfterFirst( '\"' ).BeforeFirst( '\"' );
732 
733  // search the hotkey in current hotkey list
734  for( EDA_HOTKEY** list = CurrentHotkeyList; *list != nullptr; list++ )
735  {
736  EDA_HOTKEY* hk_decr = *list;
737 
738  if( hk_decr->m_InfoMsg == fctname )
739  {
740  hk_decr->m_KeyCode = KeyCodeFromKeyName( keyname );
741  break;
742  }
743  }
744  }
745 }
746 
747 
749  const wxString& aDefaultShortname )
750 {
751  wxString ext = DEFAULT_HOTKEY_FILENAME_EXT;
752  wxString mask = wxT( "*." ) + ext;
753 
754 
755  wxString path = GetMruPath();
756  wxFileName fn( aDefaultShortname );
757  fn.SetExt( DEFAULT_HOTKEY_FILENAME_EXT );
758 
759  wxString filename = EDA_FILE_SELECTOR( _( "Read Hotkey Configuration File:" ),
760  path,
761  fn.GetFullPath(),
762  ext,
763  mask,
764  this,
765  wxFD_OPEN,
766  true );
767 
768  if( filename.IsEmpty() )
769  return;
770 
771  ::ReadHotkeyConfigFile( filename, aDescList, false );
772  WriteHotkeyConfig( aDescList );
773  SetMruPath( wxFileName( filename ).GetPath() );
774 }
775 
776 
778  const wxString& aDefaultShortname )
779 {
780  wxString ext = DEFAULT_HOTKEY_FILENAME_EXT;
781  wxString mask = wxT( "*." ) + ext;
782 
783 #if 0
784  wxString path = wxPathOnly( Prj().GetProjectFullName() );
785 #else
786  wxString path = GetMruPath();
787 #endif
788  wxFileName fn( aDefaultShortname );
789  fn.SetExt( DEFAULT_HOTKEY_FILENAME_EXT );
790 
791  wxString filename = EDA_FILE_SELECTOR( _( "Write Hotkey Configuration File:" ),
792  path,
793  fn.GetFullPath(),
794  ext,
795  mask,
796  this,
797  wxFD_SAVE,
798  true );
799 
800  if( filename.IsEmpty() )
801  return;
802 
803  WriteHotkeyConfig( aDescList, &filename );
804  SetMruPath( wxFileName( filename ).GetPath() );
805 }
806 
807 
808 /* add hotkey config options submenu to aMenu
809  */
810 void AddHotkeyConfigMenu( wxMenu* aMenu )
811 {
812  if( aMenu == nullptr )
813  return;
814 
815  wxMenu* HotkeySubmenu = new wxMenu();
816 
817  // Call hotkeys editor
819  _( "&Edit Hotkeys..." ),
820  _( "Edit hotkeys list" ),
821  KiBitmap( config_xpm ) );
822 
823  HotkeySubmenu->AppendSeparator();
824 
825  // create hotkey file to export current hotkeys config
827  _( "E&xport Hotkeys..." ),
828  _( "Export current hotkeys into configuration file" ),
829  KiBitmap( hotkeys_export_xpm ) );
830 
831  // Reload hotkey file
833  _( "&Import Hotkeys..." ),
834  _( "Load existing hotkey configuration file" ),
835  KiBitmap( hotkeys_import_xpm ) );
836 
837  // Append HotkeySubmenu to menu
838  AddMenuItem( aMenu, HotkeySubmenu,
839  wxID_ANY, _( "&Hotkeys Options" ),
840  _( "Edit hotkeys configuration and preferences" ),
841  KiBitmap( hotkeys_xpm ) );
842 }
const wxChar * m_Name
#define LIB_EDIT_FRAME_NAME
Definition: draw_frame.h:49
Structure EDA_HOTKEY_CONFIG contains the information required to save hot key information to a config...
Definition: hotkeys_basic.h:89
#define MODIFIER_CTRL_BASE
wxString KeyNameFromCommandId(EDA_HOTKEY **aList, int aCommandId)
Function KeyNameFromCommandId return the key name from the Command id value ( m_Idcommand member valu...
This file is part of the common library TODO brief description.
static void AddModifierToKey(wxString &aFullKey, const wxString &aKey)
This file is part of the common library.
wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmap &aImage, wxItemKind aType=wxITEM_NORMAL)
Function AddMenuItem is an inline helper function to create and insert a menu item with an icon into ...
Definition: bitmap.cpp:174
PROJECT & Prj()
Definition: kicad.cpp:287
EDA_HOTKEY ** m_HK_InfoList
Definition: hotkeys_basic.h:93
void ExportHotkeyConfigToFile(EDA_HOTKEY_CONFIG *aDescList, const wxString &aDefaultShortname)
Function ExportHotkeyConfigToFile Prompt the user for an old hotkey file to read, and read it...
int ReadHotkeyConfigFile(const wxString &aFilename, struct EDA_HOTKEY_CONFIG *aDescList, const bool aDefaultLocation)
Function ReadHotkeyConfig Read hotkey configuration for a given app, possibly before the frame for th...
#define GR_KB_ALT
Definition: common.h:65
This file contains miscellaneous commonly used macros and functions.
#define PCB_EDIT_FRAME_NAME
Definition: draw_frame.h:56
#define SCH_EDIT_FRAME_NAME
Definition: draw_frame.h:50
EDA_HOTKEY * GetDescriptorFromHotkey(int aKey, EDA_HOTKEY **aList)
Function GetDescriptorFromHotkey Return a EDA_HOTKEY * pointer from a key code for OnHotKey() functio...
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Function KiBitmap constructs a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:78
void DisplayHotkeyList(EDA_BASE_FRAME *aFrame, struct EDA_HOTKEY_CONFIG *aDescList)
Function DisplayHotkeyList Displays the current hotkey list.
wxString g_CommonSectionTag(wxT("[common]"))
#define MODIFIER_CTRL
#define FOOTPRINT_EDIT_FRAME_NAME
Definition: draw_frame.h:53
#define GR_KB_SHIFT
Definition: common.h:66
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
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)
Function EDA_FILE_SELECTOR.
Definition: gestfich.cpp:82
int KeyCodeFromKeyName(const wxString &keyname)
Function KeyCodeFromKeyName return the key code from its key name Only some wxWidgets key values are ...
#define MODIFIER_SHIFT
Base window classes and related definitions.
void AddDelimiterString(wxString &string)
Function AddDelimiterString Add un " to the start and the end of string (if not already done)...
Definition: gestfich.cpp:44
Class HTML_MESSAGE_BOX.
wxString GetKicadConfigPath()
Return the user configuration path used to store KiCad&#39;s configuration files.
Definition: common.cpp:211
bool Show(bool show) override
wxString * m_SectionTag
Definition: hotkeys_basic.h:92
int ReadHotkeyConfig(const wxString &aAppname, struct EDA_HOTKEY_CONFIG *aDescList)
Function ReadHotkeyConfig Read configuration data and fill the current hotkey list with hotkeys...
EDA_HOTKEY(const wxChar *infomsg, int idcommand, int keycode, int idmenuevent=0)
void SetDialogSizeInDU(int aWidth, int aHeight)
set the dialog size, using a "logical value.
void AddHotkeyConfigMenu(wxMenu *aMenu)
void ParseHotkeyConfig(const wxString &data, struct EDA_HOTKEY_CONFIG *aDescList, const wxString &aAppname)
Function ParseHotkeyConfig Translates hotkey string data into application hotkeys.
wxString m_InfoMsg
Definition: hotkeys_basic.h:66
int m_defaultKeyCode
Definition: hotkeys_basic.h:62
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
wxString AddHotkeyName(const wxString &aText, EDA_HOTKEY **aList, int aCommandId, HOTKEY_ACTION_TYPE aShortCutType)
Function AddHotkeyName Add the key name from the Command id value ( m_Idcommand member value) ...
class EDA_HOTKEY is a class to handle hot key commands.
Definition: hotkeys_basic.h:59
virtual int WriteHotkeyConfig(struct EDA_HOTKEY_CONFIG *aDescList, wxString *aFullFileName=NULL)
Function WriteHotkeyConfig Store the current hotkey list It is stored using the standard wxConfig mec...
wxString * m_Title
Definition: hotkeys_basic.h:94
void AddHTML_Text(const wxString &message)
Function AddHTML_Text adds html text (without any change) to message list.
Class EDA_BASE_FRAME is the base frame for deriving all KiCad main window classes.
#define MODIFIER_ALT
#define MODIFIER_CMD_MAC
#define EESCHEMA_HOTKEY_NAME
Definition: hotkeys_basic.h:35
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Function KeyNameFromKeyCode return the key name from the key code Only some wxWidgets key values are ...
Some functions to handle hotkeys in KiCad.
#define DEFAULT_HOTKEY_FILENAME_EXT
Definition: hotkeys_basic.h:34
void ImportHotkeyConfigFromFile(EDA_HOTKEY_CONFIG *aDescList, const wxString &aDefaultShortname)
Function ImportHotkeyConfigFromFile Prompt the user for an old hotkey file to read, and read it.
#define GR_KB_CTRL
Definition: common.h:64
HOTKEY_ACTION_TYPE
An helper enum for AddHotkeyName function In menus we can add a hot key, or an accelerator ...
#define PCBNEW_HOTKEY_NAME
Definition: hotkeys_basic.h:36
int m_IdMenuEvent
Definition: hotkeys_basic.h:68
static struct hotkey_name_descr hotkeyNameList[]
EDA_HOTKEY * GetDescriptorFromCommand(int aCommand, EDA_HOTKEY **aList)
Function GetDescriptorFromCommand Returns a EDA_HOTKEY* pointer from a hot key identifier.