📄 shortcutmapper.cpp
字号:
/*
this file is part of notepad++
Copyright (C)2003 Don HO ( donho@altern.org )
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "ShortcutMapper.h"
#include "Notepad_plus.h"
void ShortcutMapper::initBabyGrid() {
RECT rect;
getClientRect(rect);
_babygrid.init(_hInst, _hSelf, IDD_BABYGRID_ID1);
_babygrid.reSizeTo(rect);
_babygrid.hideCursor();
_babygrid.makeColAutoWidth();
_babygrid.setColsNumbered(false);
_babygrid.setColWidth(0, 30);
_babygrid.setColWidth(1, 250);
}
void ShortcutMapper::fillOutBabyGrid()
{
NppParameters *nppParam = NppParameters::getInstance();
vector<ScintillaKeyMap> &skms = nppParam->getScintillaKeyList();
int nbScitillaMsg = skms.size();
_pAccel = nppParam->getAccelerator();
_babygrid.setLineColNumber(_pAccel->_nbAccelItems + nbScitillaMsg, 2);
_babygrid.setText(0, 1, "Name");
_babygrid.setText(0, 2, "Shortcut");
int i = 0 ;
for ( ; i < _pAccel->_nbAccelItems ; i++)
{
unsigned char vFlg = _pAccel->_pAccelArray[i].fVirt;
string shortcut = (vFlg & FCONTROL)?"Ctrl+":"";
shortcut += (vFlg & FALT)?"Alt+":"";
shortcut += (vFlg & FSHIFT)?"Shift+":"";
string key;
getKeyStrFromVal((unsigned char)_pAccel->_pAccelArray[i].key, key);
shortcut += key;
_babygrid.setText(i+1, 2, shortcut.c_str());
string shortcutName;
getNameStrFromCmd(_pAccel->_pAccelArray[i].cmd, shortcutName);
_babygrid.setText(i+1, 1, shortcutName.c_str());
}
for (size_t j = 0 ; i < _pAccel->_nbAccelItems + nbScitillaMsg ; i++, j++)
{
_babygrid.setText(i+1, 1, skms[j]._name);
_babygrid.setText(i+1, 2, skms[j].toString().c_str());
}
}
BOOL CALLBACK ShortcutMapper::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG :
{
initBabyGrid();
fillOutBabyGrid();
_babygrid.display();
goToCenter();
return TRUE;
}
case WM_COMMAND :
{
switch (wParam)
{
case IDCANCEL :
{
::EndDialog(_hSelf, -1);
return TRUE;
}
case IDOK :
{
::EndDialog(_hSelf, 0);
return TRUE;
}
case IDM_BABYGRID_MODIFY :
{
NppParameters *nppParam = NppParameters::getInstance();
int row = _babygrid.getSelectedRow();
if (row <= _pAccel->_nbAccelItems)
{
ACCEL accel = _pAccel->_pAccelArray[row-1];
string shortcutName;
DWORD cmdID = _pAccel->_pAccelArray[row-1].cmd;
ShortcutType st = getNameStrFromCmd(cmdID, shortcutName);
Shortcut shortcut(shortcutName.c_str(), (accel.fVirt & FCONTROL) != 0, (accel.fVirt & FALT) != 0, (accel.fVirt & FSHIFT) != 0, (unsigned char)accel.key);
shortcut.init(_hInst, _hSelf);
shortcut.setNameReadOnly((st != TYPE_CMD) && (st != TYPE_PLUGINCMD));
Shortcut oldSc = shortcut;
if ((shortcut.doDialog() != -1) && (oldSc != shortcut))
{
// Update the key map
_pAccel->_pAccelArray[row-1].fVirt = FVIRTKEY | (shortcut._isCtrl?FCONTROL:0) | (shortcut._isAlt?FALT:0) | (shortcut._isShift?FSHIFT:0);
_pAccel->_pAccelArray[row-1].key = shortcut._key;
_pAccel->reNew();
// Update the GUI
string sc = shortcut.toString();
_babygrid.setText(row, 2, sc.c_str());
// Add (or update) shortcut to vector in order to save what we have done
if (st == TYPE_CMD)
{
int index = -1;
vector<CommandShortcut> & shortcutList = nppParam->getUserShortcuts();
for (size_t i = 0 ; i < shortcutList.size() ; i++)
{
if (cmdID == shortcutList[i].getID())
{
index = i;
break;
}
}
if (index != -1)
shortcutList[index].copyShortcut(shortcut);
else
shortcutList.push_back(CommandShortcut(cmdID, shortcut));
::SendMessage(_hParent, NPPM_INTERNAL_CMDLIST_MODIFIED, (WPARAM)sc.c_str(), cmdID);
}
else if (st == TYPE_MACRO)
{
vector<MacroShortcut> & theMacros = nppParam->getMacroList();
const int i = cmdID - ID_MACRO;
theMacros[i].copyShortcut(shortcut);
HMENU hMenu = ::GetSubMenu(::GetMenu(_hParent), MENUINDEX_MACRO);
::ModifyMenu(hMenu, cmdID, MF_BYCOMMAND, cmdID, theMacros[i].toMenuItemString().c_str());
::SendMessage(_hParent, NPPM_INTERNAL_MACROLIST_MODIFIED, 0, 0);
}
else if (st == TYPE_USERCMD)
{
vector<UserCommand> & theUserCmds = nppParam->getUserCommandList();
const int i = cmdID - ID_USER_CMD;
theUserCmds[i].copyShortcut(shortcut);
HMENU hMenu = ::GetSubMenu(::GetMenu(_hParent), MENUINDEX_RUN);
::ModifyMenu(hMenu, cmdID, MF_BYCOMMAND, cmdID, theUserCmds[i].toMenuItemString().c_str());
::SendMessage(_hParent, NPPM_INTERNAL_USERCMDLIST_MODIFIED, 0, 0);
}
else if (st == TYPE_PLUGINCMD)
{
vector<PluginCmdShortcut> & thePluginCmds = (NppParameters::getInstance())->getPluginCommandList();
int i = -1;
for (size_t j = 0 ; j < thePluginCmds.size() ; j++)
{
if (cmdID == thePluginCmds[j].getID())
{
i = j;
break;
}
}
thePluginCmds[i].copyShortcut(shortcut);
HMENU hMenu = ::GetMenu(_hParent);
::ModifyMenu(hMenu, cmdID, MF_BYCOMMAND, cmdID, thePluginCmds[i].toMenuItemString().c_str());
vector<PluginCmdShortcut> & theModifyedPluginCmds = (NppParameters::getInstance())->getPluginCustomizedCmds();
int k = -1;
for (size_t j = 0 ; j < theModifyedPluginCmds.size() ; j++)
{
if (cmdID == theModifyedPluginCmds[j].getID())
{
k = j;
break;
}
}
if (k != -1)
theModifyedPluginCmds[k].copyShortcut(thePluginCmds[i]);
else
theModifyedPluginCmds.push_back(thePluginCmds[i]);
::SendMessage(_hParent, NPPM_INTERNAL_PLUGINCMDLIST_MODIFIED, 0, 0);
}
_babygrid.setText(row, 1, shortcut._name);
}
}
else // Scintilla Key shortcut
{
vector<ScintillaKeyMap> & scintillaShortcuts = nppParam->getScintillaKeyList();
const int index = row - _pAccel->_nbAccelItems - 1;
ScintillaKeyMap scintillaSc = scintillaShortcuts[index];
scintillaSc.init(_hInst, _hSelf);
scintillaSc.setNameReadOnly(false);
if (scintillaSc.doDialog() != -1)
{
// Add this modification into the list to save it later
bool found = false;
vector<ScintillaKeyMap> & userDefScintillaKeys = nppParam->getScintillaModifiedKeys();
for (size_t i = 0 ; i < userDefScintillaKeys.size() ; i++)
{
if (scintillaSc.getID() == userDefScintillaKeys[i].getID())
{
userDefScintillaKeys[i].copyShortcut(scintillaSc);
found = true;
}
}
if (!found)
userDefScintillaKeys.push_back(scintillaSc);
// remap the key
::SendMessage(_hParent, NPPM_INTERNAL_BINDSCINTILLAKEY, scintillaSc.toKeyDef(), scintillaSc.getScintillaKey());
::SendMessage(_hParent, NPPM_INTERNAL_CLEARSCINTILLAKEY, scintillaShortcuts[index].toKeyDef(), 0);
// update the key in the scintilla key list
scintillaShortcuts[index].copyShortcut(scintillaSc);
// if this shortcut is linked to a menu item, change to shortcut string in menu item
if (int cmdID = scintillaShortcuts[index].getMenuCmdID())
{
HMENU hMenu = ::GetMenu(_hParent);
::ModifyMenu(hMenu, cmdID, MF_BYCOMMAND, cmdID, scintillaShortcuts[index].toMenuItemString(cmdID).c_str());
}
// Update UI
_babygrid.setText(row, 2, scintillaSc.toString().c_str());
::SendMessage(_hParent, NPPM_INTERNAL_SCINTILLAKEYMODIFIED, 0, 0);
}
}
return TRUE;
}
case IDM_BABYGRID_DELETE :
{
NppParameters *nppParam = NppParameters::getInstance();
if (::MessageBox(_hSelf, "Are you sure to delete this shortcut?", "Are you sure?", MB_OKCANCEL) == IDOK)
{
const int row = _babygrid.getSelectedRow();
DWORD cmdID = _pAccel->_pAccelArray[row-1].cmd;
// Menu data
int erasePos;
size_t posBase;
size_t nbElem;
HMENU hMenu;
if ((cmdID >= ID_MACRO) && (cmdID < ID_MACRO_LIMIT))
{
vector<MacroShortcut> & theMacros = nppParam->getMacroList();
vector<MacroShortcut>::iterator it = theMacros.begin();
erasePos = cmdID - ID_MACRO;
theMacros.erase(it + erasePos);
_pAccel->uptdateShortcuts();
_babygrid.clear();
fillOutBabyGrid();
// preparing to remove from menu
posBase = 3;
nbElem = theMacros.size();
hMenu = ::GetSubMenu(::GetMenu(_hParent), MENUINDEX_MACRO);
::SendMessage(_hParent, NPPM_INTERNAL_MACROLIST_MODIFIED, 0, 0);
}
else if ((cmdID >= ID_USER_CMD) && (cmdID < ID_USER_CMD_LIMIT))
{
vector<UserCommand> & theUserCmds = nppParam->getUserCommandList();
vector<UserCommand>::iterator it = theUserCmds.begin();
erasePos = cmdID - ID_USER_CMD;
theUserCmds.erase(it + erasePos);
_pAccel->uptdateShortcuts();
_babygrid.clear();
fillOutBabyGrid();
// preparing to remove from menu
posBase = 0;
nbElem = theUserCmds.size();
hMenu = ::GetSubMenu(::GetMenu(_hParent), MENUINDEX_RUN);
::SendMessage(_hParent, NPPM_INTERNAL_USERCMDLIST_MODIFIED, 0, 0);
}
else // should never happen
{
return FALSE;
}
// remove from menu
::RemoveMenu(hMenu, cmdID++, MF_BYCOMMAND);
for (size_t i = erasePos ; i < nbElem ; i++)
{
char cmdName[64];
::GetMenuString(hMenu, cmdID, cmdName, sizeof(cmdName), MF_BYCOMMAND);
::ModifyMenu(hMenu, cmdID, MF_BYCOMMAND, cmdID-1, cmdName);
cmdID++;
}
if (nbElem == 0)
::RemoveMenu(hMenu, posBase + 1, MF_BYPOSITION);
}
return TRUE;
}
default :
if (LOWORD(wParam) == IDD_BABYGRID_ID1)
{
if(HIWORD(wParam) == BGN_CELLDBCLICKED) //a cell was clicked in the properties grid
{
return ::SendMessage(_hSelf, WM_COMMAND, IDM_BABYGRID_MODIFY, LOWORD(lParam));
}
else if(HIWORD(wParam) == BGN_CELLRCLICKED) //a cell was clicked in the properties grid
{
int row = LOWORD(lParam);
DWORD cmdID = _pAccel->_pAccelArray[row-1].cmd;
POINT p;
::GetCursorPos(&p);
if (!_rightClickMenu.isCreated())
{
vector<MenuItemUnit> itemUnitArray;
itemUnitArray.push_back(MenuItemUnit(IDM_BABYGRID_MODIFY, "Modify"));
itemUnitArray.push_back(MenuItemUnit(IDM_BABYGRID_DELETE, "Delete"));
_rightClickMenu.create(_hSelf, itemUnitArray);
}
bool b = (!((cmdID >= ID_MACRO) && (cmdID < ID_MACRO_LIMIT))) && (!((cmdID >= ID_USER_CMD) && (cmdID < ID_USER_CMD_LIMIT)));
_rightClickMenu.enableItem(IDM_BABYGRID_DELETE, !b);
_rightClickMenu.display(p);
return TRUE;
}
}
}
}
default:
return FALSE;
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -