2007-08-20 11:33:45 +00:00
|
|
|
/*********************/
|
|
|
|
/* hotkeys_basic.cpp */
|
|
|
|
/*********************/
|
|
|
|
|
|
|
|
/* Some functions to handle hotkeys in kicad
|
|
|
|
*/
|
|
|
|
#include "fctsys.h"
|
|
|
|
#include "common.h"
|
2007-08-21 19:37:31 +00:00
|
|
|
#include "wxstruct.h"
|
2007-08-20 11:33:45 +00:00
|
|
|
#include "hotkeys_basic.h"
|
2007-08-21 19:37:31 +00:00
|
|
|
#include "macros.h"
|
2007-08-20 11:33:45 +00:00
|
|
|
|
|
|
|
/* 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)
|
|
|
|
}
|
|
|
|
|
2007-08-21 19:37:31 +00:00
|
|
|
/* 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
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2007-08-20 11:33:45 +00:00
|
|
|
/****************************************************/
|
|
|
|
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;
|
2007-08-21 19:37:31 +00:00
|
|
|
int ii;
|
|
|
|
|
2007-08-20 11:33:45 +00:00
|
|
|
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 ");
|
|
|
|
|
2007-08-21 19:37:31 +00:00
|
|
|
keycode &= ~(GR_KB_CTRL|GR_KB_ALT|GR_KB_SHIFT);
|
|
|
|
for ( ii = 0; ; ii++)
|
2007-08-20 11:33:45 +00:00
|
|
|
{
|
2007-08-21 19:37:31 +00:00
|
|
|
if ( s_Notkey_Name_List[ii].m_KeyCode == 0 )
|
|
|
|
{
|
|
|
|
keyname = wxT("<unknown>");
|
2007-08-20 11:33:45 +00:00
|
|
|
break;
|
2007-08-21 19:37:31 +00:00
|
|
|
}
|
|
|
|
if ( s_Notkey_Name_List[ii].m_KeyCode == keycode)
|
|
|
|
{
|
|
|
|
keyname = s_Notkey_Name_List[ii].m_Name;
|
2007-08-20 11:33:45 +00:00
|
|
|
break;
|
2007-08-21 19:37:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fullkeyname = modifier + keyname;
|
|
|
|
return fullkeyname;
|
|
|
|
}
|
2007-08-20 11:33:45 +00:00
|
|
|
|
2007-08-21 19:37:31 +00:00
|
|
|
/************************************************************/
|
|
|
|
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;
|
2007-08-20 11:33:45 +00:00
|
|
|
|
2007-08-21 19:37:31 +00:00
|
|
|
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;
|
2007-08-20 11:33:45 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-08-21 19:37:31 +00:00
|
|
|
}
|
2007-08-20 11:33:45 +00:00
|
|
|
|
2007-08-21 19:37:31 +00:00
|
|
|
return keycode;
|
2007-08-20 11:33:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2007-08-21 19:37:31 +00:00
|
|
|
/*************************************************************************/
|
|
|
|
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 (<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;
|
|
|
|
}
|