/*********************/ /* hotkeys_basic.cpp */ /*********************/ /* Some functions to handle hotkeys in kicad */ #include "fctsys.h" #include "common.h" #include "wxstruct.h" #include "hotkeys_basic.h" #include "macros.h" /* Class to handle hotkey commnands. hotkeys have a default value This class allows (for the future..) the real key code changed by user(from a key code list file, TODO) */ Ki_HotkeyInfo::Ki_HotkeyInfo(const wxChar * infomsg, int idcommand, int keycode) { m_KeyCode = keycode; // Key code (ascii value for ascii keys or wxWidgets code for function key m_InfoMsg = infomsg; // info message. m_Idcommand = idcommand; // internal id for the corresponding command (see hotkey_id_commnand list) } /* class to handle the printable name and the keycode */ struct hotkey_name_descr { wxChar * m_Name; int m_KeyCode; }; struct hotkey_name_descr s_Notkey_Name_List[] = { {wxT("F1"), WXK_F1}, {wxT("F2"), WXK_F2}, {wxT("F3"), WXK_F3}, {wxT("F4"), WXK_F4}, {wxT("F5"), WXK_F5}, {wxT("F6"), WXK_F6}, {wxT("F7"), WXK_F7}, {wxT("F8"), WXK_F8}, {wxT("F9"), WXK_F9}, {wxT("F10"), WXK_F10}, {wxT("F11"), WXK_F11}, {wxT("F12"), WXK_F12}, {wxT("Esc"), WXK_ESCAPE}, {wxT("Delete"), WXK_DELETE}, {wxT("Esc"), WXK_ESCAPE}, {wxT("Tab"), '\t'}, {wxT("Backspace"), WXK_BACK}, {wxT("Insert"), WXK_INSERT}, {wxT("End"), WXK_END}, {wxT("Page Up"), WXK_PAGEUP}, {wxT("Page Down"), WXK_PAGEDOWN}, {wxT("+"), WXK_ADD}, {wxT("-"), WXK_SUBTRACT}, {wxT("space"), ' '}, {wxT("?"), '?'}, {wxT("A"), 'A'}, {wxT("B"), 'B'}, {wxT("C"), 'C'}, {wxT("D"), 'D'}, {wxT("E"), 'E'}, {wxT("F"), 'F'}, {wxT("G"), 'G'}, {wxT("H"), 'H'}, {wxT("I"), 'I'}, {wxT("J"), 'J'}, {wxT("K"), 'K'}, {wxT("L"), 'L'}, {wxT("M"), 'M'}, {wxT("N"), 'N'}, {wxT("O"), 'O'}, {wxT("P"), 'P'}, {wxT("Q"), 'Q'}, {wxT("R"), 'R'}, {wxT("S"), 'S'}, {wxT("T"), 'T'}, {wxT("U"), 'U'}, {wxT("V"), 'V'}, {wxT("W"), 'W'}, {wxT("X"), 'X'}, {wxT("Y"), 'Y'}, {wxT("Z"), 'Z'}, {wxT("Ctrl A"), GR_KB_CTRL + 'A'}, {wxT("Ctrl B"), GR_KB_CTRL + 'B'}, {wxT("Ctrl C"), GR_KB_CTRL + 'C'}, {wxT("Ctrl D"), GR_KB_CTRL + 'D'}, {wxT("Ctrl E"), GR_KB_CTRL + 'E'}, {wxT("Ctrl F"), GR_KB_CTRL + 'F'}, {wxT("Ctrl G"), GR_KB_CTRL + 'G'}, {wxT("Ctrl H"), GR_KB_CTRL + 'H'}, {wxT("Ctrl I"), GR_KB_CTRL + 'I'}, {wxT("Ctrl J"), GR_KB_CTRL + 'J'}, {wxT("Ctrl K"), GR_KB_CTRL + 'K'}, {wxT("Ctrl L"), GR_KB_CTRL + 'L'}, {wxT("Ctrl M"), GR_KB_CTRL + 'M'}, {wxT("Ctrl N"), GR_KB_CTRL + 'N'}, {wxT("Ctrl O"), GR_KB_CTRL + 'O'}, {wxT("Ctrl P"), GR_KB_CTRL + 'P'}, {wxT("Ctrl Q"), GR_KB_CTRL + 'Q'}, {wxT("Ctrl R"), GR_KB_CTRL + 'R'}, {wxT("Ctrl S"), GR_KB_CTRL + 'S'}, {wxT("Ctrl T"), GR_KB_CTRL + 'T'}, {wxT("Ctrl U"), GR_KB_CTRL + 'U'}, {wxT("Ctrl V"), GR_KB_CTRL + 'V'}, {wxT("Ctrl W"), GR_KB_CTRL + 'W'}, {wxT("Ctrl X"), GR_KB_CTRL + 'X'}, {wxT("Ctrl Y"), GR_KB_CTRL + 'Y'}, {wxT("Ctrl Z"), GR_KB_CTRL + 'Z'}, {wxT(""), 0} // Do not change: end of list }; /****************************************************/ wxString ReturnKeyNameFromKeyCode(int keycode) /****************************************************/ /* * return the key name from the key code * Only some wxWidgets key values are handled for function key * @param key = key code (ascii value, or wxWidgets value for function keys) * @return the key name in a wxString */ { wxString keyname, modifier, fullkeyname; int ii; if ( (keycode & GR_KB_CTRL) != 0 ) modifier << wxT("Ctrl "); if ( (keycode & GR_KB_ALT) != 0 ) modifier << wxT("Alt "); if ( (keycode & GR_KB_SHIFT) != 0 ) modifier << wxT("Shift "); keycode &= ~(GR_KB_CTRL|GR_KB_ALT|GR_KB_SHIFT); for ( ii = 0; ; ii++) { if ( s_Notkey_Name_List[ii].m_KeyCode == 0 ) { keyname = wxT(""); break; } if ( s_Notkey_Name_List[ii].m_KeyCode == keycode) { keyname = s_Notkey_Name_List[ii].m_Name; break; } } fullkeyname = modifier + keyname; return fullkeyname; } /************************************************************/ static int ReturnKeyCodeFromKeyName(const wxString & keyname) /************************************************************/ /* * return the key code from its key name * Only some wxWidgets key values are handled for function key * @param keyname = wxString key name to find in s_Notkey_Name_List[] * @return the key code */ { int ii, keycode = 0; for ( ii = 0; ; ii++) { if ( s_Notkey_Name_List[ii].m_KeyCode == 0 ) break; if ( s_Notkey_Name_List[ii].m_Name == keyname) { keycode = s_Notkey_Name_List[ii].m_KeyCode; break; } } return keycode; } /****************************************************************************/ void DisplayHotkeyList(WinEDA_DrawFrame * frame, Ki_HotkeyInfo ** List) /*****************************************************************************/ /* * Displays the current hotkey list * @param frame = current open frame * @param List = pointer to a Ki_HotkeyInfo list of commands * @return none */ { wxString keyname; wxString msg = _("Current hotkey list:\n\n"); for ( ; * List != NULL; List++ ) { Ki_HotkeyInfo * hk_decr = * List; msg += _("key "); keyname = ReturnKeyNameFromKeyCode(hk_decr->m_KeyCode); msg += keyname + wxT(": ") + hk_decr->m_InfoMsg + wxT("\n"); } DisplayInfo(frame, msg); } /******************************************************************/ int GetCommandCodeFromHotkey(int key, Ki_HotkeyInfo ** List) /******************************************************************/ /* * Return an id identifier fron a key code for OnHotKey() function * @param key = key code (ascii value, or wxWidgets value for function keys * @param List = pointer to a Ki_HotkeyInfo list of commands * @return the corresponding function identifier from the Ki_HotkeyInfo List */ { for ( ; * List != NULL; List++ ) { Ki_HotkeyInfo * hk_decr = * List; if ( hk_decr->m_KeyCode == key ) return hk_decr->m_Idcommand; } return 0; } /*************************************************************************/ int WinEDA_BasicFrame::WriteHotkeyConfigFile(const wxString & Filename, Ki_HotkeyInfo ** List, bool verbose) /*************************************************************************/ /* * Create a configuration file (*.key) from the current hotkey list * @param Filename = default full file name to create. If void, A filename will be asked * @param List = pointer to the current hotkey list. * the ouput format is: shortcut "key" "function" * lines starting by # are comments * */ { wxString FullFilename = Filename; FILE * cfgfile; wxString msg; if ( FullFilename.IsEmpty() || verbose) { wxString Mask, Path, Ext; Ext = DEFAULT_HOTKEY_FILENAME_EXT; Mask = wxT("*") + Ext; Path = DEFAULT_HOTKEY_FILENAME_PATH; FullFilename = EDA_FileSelector( _("Hotkey configuration file:"), Path, /* Chemin par defaut */ FullFilename, /* nom fichier par defaut */ Ext, /* extension par defaut */ Mask, /* Masque d'affichage */ this, wxFD_SAVE, TRUE ); } if ( FullFilename.IsEmpty() ) return 0; cfgfile = wxFopen(FullFilename, wxT("wt")); if ( cfgfile == NULL ) { if ( verbose ) { msg = _("Unable to create ") + FullFilename; DisplayError(this, msg); } return 0; } wxString keyname, infokey; msg = wxT("$hotkey list\n"); fprintf(cfgfile, CONV_TO_UTF8(msg)); /* print the allowed keys, for info */ msg = wxT("# "); msg += _("Allowed keys:\n"); fprintf(cfgfile, CONV_TO_UTF8(msg)); msg.Empty(); for ( int ii = 0; ; ii ++ ) { if ( s_Notkey_Name_List[ii].m_KeyCode == 0 ) break;; if ( msg.IsEmpty() ) msg = wxT("# "); else msg += wxT(", "); msg += s_Notkey_Name_List[ii].m_Name; if ( msg.Len() > 60 ) { msg += wxT("\n"); fprintf(cfgfile, CONV_TO_UTF8(msg)); msg.Empty(); } } /* print the last line */ if ( ! msg.IsEmpty() ) msg += wxT("\n"); msg += wxT("#\n#\n"); fprintf(cfgfile, CONV_TO_UTF8(msg)); /* Print the current list */ for ( ; * List != NULL; List++ ) { Ki_HotkeyInfo * hk_decr = * List; msg = wxT("shortcut "); keyname = ReturnKeyNameFromKeyCode(hk_decr->m_KeyCode); AddDelimiterString( keyname ); infokey = hk_decr->m_InfoMsg; AddDelimiterString( infokey ); msg += keyname + wxT(": ") + infokey + wxT("\n"); fprintf(cfgfile, CONV_TO_UTF8(msg)); } msg = wxT("$Endlist\n"); fprintf(cfgfile, CONV_TO_UTF8(msg)); fclose(cfgfile); return 1; } /********************************************************************************************/ int WinEDA_BasicFrame::ReadHotkeyConfigFile(const wxString & Filename, Ki_HotkeyInfo ** CurrentHotkeyList, bool verbose) /********************************************************************************************/ /* * Read a configuration file (.key) and fill the current hotkey list with hotkeys * @param Filename = default full file name to create. If void, A filename will be asked * @param CurrentHotkeyList = current hotkey list to initialise. * the input format is: shortcut "key" "function" * lines starting by # are ignored (comments) * */ { wxString FullFilename = Filename; FILE * cfgfile; wxString msg; if ( FullFilename.IsEmpty() || verbose ) { wxString Mask, Path, Ext; Ext = DEFAULT_HOTKEY_FILENAME_EXT; Mask = wxT("*") + Ext; Path = DEFAULT_HOTKEY_FILENAME_PATH; FullFilename = EDA_FileSelector( _("Hotkey configuration file:"), Path, /* Chemin par defaut */ FullFilename, /* nom fichier par defaut */ Ext, /* extension par defaut */ Mask, /* Masque d'affichage */ this, wxFD_OPEN, TRUE ); if ( FullFilename.IsEmpty() ) return 0; } cfgfile = wxFopen(FullFilename, wxT("rt")); if ( cfgfile == NULL ) { if ( verbose ) { msg = _("Unable to read ") + FullFilename; DisplayError(this, msg); } return 0; } wxString keyname; char Line[1024]; int LineNum = 0; /* Read the file */ while( GetLine( cfgfile, Line, &LineNum ) != NULL ) { char * line_type, * keyname, *fctname; line_type = strtok(Line, " \t\n\r"); msg = CONV_FROM_UTF8(line_type); if( msg != wxT("shortcut") ) continue; if( msg == wxT("$Endlist") ) break; /* Get the key name */ strtok(NULL, "\"\n\r"); keyname = strtok(NULL, "\"\n\r"); strtok(NULL, "\"\n\r"); /* Get the command name */ fctname = strtok(NULL, "\"\n\r"); msg = CONV_FROM_UTF8(fctname); /* search the hotkey in current hotkey list */ for (Ki_HotkeyInfo ** List = CurrentHotkeyList; * List != NULL; List++ ) { Ki_HotkeyInfo * hk_decr = * List; if (hk_decr->m_InfoMsg == msg ) { msg = CONV_FROM_UTF8(keyname); int code = ReturnKeyCodeFromKeyName(msg); if ( code ) hk_decr->m_KeyCode = code; break; } } } fclose(cfgfile); return 1; }