📄 shortcut.h
字号:
//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.
#ifndef SHORTCUTS_H
#define SHORTCUTS_H
//#include "Parameters.h"
#include <vector>
#include <string>
#include <windows.h>
#include "shortcutRc.h"
#include "StaticDialog.h"
#include "Scintilla.h"
using namespace std;
const size_t nameLenMax = 64;
class NppParameters;
void getKeyStrFromVal(unsigned char keyVal, string & str);
void getNameStrFromCmd(DWORD cmd, string & str);
static int keyTranslate(int keyIn) {
switch (keyIn) {
case VK_DOWN: return SCK_DOWN;
case VK_UP: return SCK_UP;
case VK_LEFT: return SCK_LEFT;
case VK_RIGHT: return SCK_RIGHT;
case VK_HOME: return SCK_HOME;
case VK_END: return SCK_END;
case VK_PRIOR: return SCK_PRIOR;
case VK_NEXT: return SCK_NEXT;
case VK_DELETE: return SCK_DELETE;
case VK_INSERT: return SCK_INSERT;
case VK_ESCAPE: return SCK_ESCAPE;
case VK_BACK: return SCK_BACK;
case VK_TAB: return SCK_TAB;
case VK_RETURN: return SCK_RETURN;
case VK_ADD: return SCK_ADD;
case VK_SUBTRACT: return SCK_SUBTRACT;
case VK_DIVIDE: return SCK_DIVIDE;
case VK_OEM_2: return '/';
case VK_OEM_3: return '`';
case VK_OEM_4: return '[';
case VK_OEM_5: return '\\';
case VK_OEM_6: return ']';
default: return keyIn;
}
};
struct KeyCombo {
bool _isCtrl;
bool _isAlt;
bool _isShift;
unsigned char _key;
};
class Shortcut : public StaticDialog {
public:
Shortcut(): _canModifyName(false) {
setName("");
_keyCombo._isCtrl = false;
_keyCombo._isAlt = false;
_keyCombo._isShift = false;
_keyCombo._key = 0;
};
Shortcut(const char *name, bool isCtrl, bool isAlt, bool isShift, unsigned char key) : _canModifyName(false) {
_name[0] = '\0';
if (name) {
setName(name);
} else {
setName("");
}
_keyCombo._isCtrl = isCtrl;
_keyCombo._isAlt = isAlt;
_keyCombo._isShift = isShift;
_keyCombo._key = key;
};
Shortcut(const Shortcut & sc) {
setName(sc.getMenuName());
_keyCombo = sc._keyCombo;
_canModifyName = sc._canModifyName;
}
BYTE getAcceleratorModifiers() {
return ( FVIRTKEY | (_keyCombo._isCtrl?FCONTROL:0) | (_keyCombo._isAlt?FALT:0) | (_keyCombo._isShift?FSHIFT:0) );
};
Shortcut & operator=(const Shortcut & sc) {
//Do not allow setting empty names
//So either we have an empty name or the other name has to be set
if (_name[0] == 0 || sc._name[0] != 0) {
setName(sc.getMenuName());
}
_keyCombo = sc._keyCombo;
this->_canModifyName = sc._canModifyName;
return *this;
}
friend inline const bool operator==(const Shortcut & a, const Shortcut & b) {
return ((strcmp(a.getMenuName(), b.getMenuName()) == 0) &&
(a._keyCombo._isCtrl == b._keyCombo._isCtrl) &&
(a._keyCombo._isAlt == b._keyCombo._isAlt) &&
(a._keyCombo._isShift == b._keyCombo._isShift) &&
(a._keyCombo._key == b._keyCombo._key)
);
};
friend inline const bool operator!=(const Shortcut & a, const Shortcut & b) {
return !(a == b);
};
virtual int doDialog() {
return ::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_SHORTCUT_DLG), _hParent, (DLGPROC)dlgProc, (LPARAM)this);
};
virtual bool isValid() const { //valid should only be used in cases where the shortcut isEnabled().
if (_keyCombo._key == 0)
return true; //disabled _keyCombo always valid, just disabled
//These keys need a modifier, else invalid
if ( ((_keyCombo._key >= 'A') && (_keyCombo._key <= 'Z')) || ((_keyCombo._key >= '0') && (_keyCombo._key <= '9')) || _keyCombo._key == VK_SPACE || _keyCombo._key == VK_CAPITAL || _keyCombo._key == VK_BACK || _keyCombo._key == VK_RETURN) {
return ((_keyCombo._isCtrl) || (_keyCombo._isAlt));
}
// the remaining keys are always valid
return true;
};
virtual bool isEnabled() const { //true if _keyCombo != 0, false if _keyCombo == 0, in which case no accelerator should be made
return (_keyCombo._key != 0);
};
virtual string toString() const; //the hotkey part
string toMenuItemString() const { //string suitable for menu
string str = _menuName;
if(isEnabled())
{
str += "\t";
str += toString();
}
return str;
};
const KeyCombo & getKeyCombo() const {
return _keyCombo;
};
const char * getName() const {
return _name;
};
const char * getMenuName() const {
return _menuName;
}
void setName(const char * name);
protected :
KeyCombo _keyCombo;
virtual BOOL CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam);
bool _canModifyName;
char _name[nameLenMax]; //normal name is plain text (for display purposes)
char _menuName[nameLenMax]; //menu name has ampersands for quick keys
};
class CommandShortcut : public Shortcut {
public:
CommandShortcut(Shortcut sc, long id) : Shortcut(sc), _id(id) {};
unsigned long getID() const {return _id;};
void setID(unsigned long id) { _id = id;};
private :
unsigned long _id;
};
class ScintillaKeyMap : public Shortcut {
public:
ScintillaKeyMap(Shortcut sc, unsigned long scintillaKeyID, unsigned long id): Shortcut(sc), _menuCmdID(id), _scintillaKeyID(scintillaKeyID) {
_keyCombos.clear();
_keyCombos.push_back(_keyCombo);
_keyCombo._key = 0;
size = 1;
};
unsigned long getScintillaKeyID() const {return _scintillaKeyID;};
int getMenuCmdID() const {return _menuCmdID;};
int toKeyDef(int index) const {
KeyCombo kc = _keyCombos[index];
int keymod = (kc._isCtrl?SCMOD_CTRL:0) | (kc._isAlt?SCMOD_ALT:0) | (kc._isShift?SCMOD_SHIFT:0);
return keyTranslate((int)kc._key) + (keymod << 16);
};
KeyCombo getKeyComboByIndex(int index) const;
void ScintillaKeyMap::setKeyComboByIndex(int index, KeyCombo combo);
void removeKeyComboByIndex(int index);
void clearDups() {
if (size > 1)
_keyCombos.erase(_keyCombos.begin()+1, _keyCombos.end());
size = 1;
};
int addKeyCombo(KeyCombo combo);
bool isEnabled() const;
size_t getSize() const;
string toString() const;
string toString(int index) const;
int doDialog() {
return ::DialogBoxParam(_hInst, MAKEINTRESOURCE(IDD_SHORTCUTSCINT_DLG), _hParent, (DLGPROC)dlgProc, (LPARAM)this);
};
//only compares the internal KeyCombos, nothing else
friend inline const bool operator==(const ScintillaKeyMap & a, const ScintillaKeyMap & b) {
bool equal = a.size == b.size;
if (!equal)
return false;
size_t i = 0;
while(equal && (i < a.size)) {
equal =
(a._keyCombos[i]._isCtrl == b._keyCombos[i]._isCtrl) &&
(a._keyCombos[i]._isAlt == b._keyCombos[i]._isAlt) &&
(a._keyCombos[i]._isShift == b._keyCombos[i]._isShift) &&
(a._keyCombos[i]._key == b._keyCombos[i]._key);
i++;
}
return equal;
};
friend inline const bool operator!=(const ScintillaKeyMap & a, const ScintillaKeyMap & b) {
return !(a == b);
};
private:
unsigned long _scintillaKeyID;
int _menuCmdID;
vector<KeyCombo> _keyCombos;
size_t size;
void applyToCurrentIndex();
void validateDialog();
void showCurrentSettings();
void updateListItem(int index);
protected :
BOOL CALLBACK run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam);
};
class Window;
class ScintillaEditView;
struct recordedMacroStep {
enum MacroTypeIndex {mtUseLParameter, mtUseSParameter, mtMenuCommand};
int message;
long wParameter;
long lParameter;
string sParameter;
MacroTypeIndex MacroType;
recordedMacroStep(int iMessage, long wParam, long lParam);
recordedMacroStep(int iCommandID) : message(0), wParameter(iCommandID), lParameter(0), MacroType(mtMenuCommand) {};
recordedMacroStep(int type, int iMessage, long wParam, long lParam, const char *sParam)
: message(iMessage), wParameter(wParam), lParameter(lParam), MacroType(MacroTypeIndex(type)){
sParameter = *reinterpret_cast<const char *>(sParam);
};
bool isValid() const {
return true;
};
void PlayBack(Window* pNotepad, ScintillaEditView *pEditView);
};
typedef vector<recordedMacroStep> Macro;
class MacroShortcut : public CommandShortcut {
friend class NppParameters;
public:
MacroShortcut(Shortcut sc, Macro macro, int id) : CommandShortcut(sc, id), _macro(macro) {_canModifyName = true;};
Macro & getMacro() {return _macro;};
private:
Macro _macro;
};
class UserCommand : public CommandShortcut {
friend class NppParameters;
public:
UserCommand(Shortcut sc, const char *cmd, int id) : CommandShortcut(sc, id), _cmd(cmd) {_canModifyName = true;};
const char* getCmd() const {return _cmd.c_str();};
private:
string _cmd;
};
class PluginCmdShortcut : public CommandShortcut {
//friend class NppParameters;
public:
PluginCmdShortcut(Shortcut sc, int id, const char *moduleName, unsigned short internalID) :\
CommandShortcut(sc, id), _id(id), _internalID(internalID) {
strcpy(_moduleName, moduleName);
};
bool isValid() const {
if (!Shortcut::isValid())
return false;
if ((!_moduleName[0]) || (_internalID == -1))
return false;
return true;
}
const char * getModuleName() const {return _moduleName;};
int getInternalID() const {return _internalID;};
unsigned long getID() const {return _id;};
private :
unsigned long _id;
char _moduleName[nameLenMax];
int _internalID;
};
class Accelerator { //Handles accelerator keys for Notepad++ menu, including custom commands
friend class ShortcutMapper;
public:
Accelerator():_hAccelMenu(NULL), _hMenuParent(NULL), _hAccTable(NULL), _pAccelArray(NULL), _nbAccelItems(0){};
~Accelerator(){
if (_hAccTable)
::DestroyAcceleratorTable(_hAccTable);
if (_pAccelArray)
delete [] _pAccelArray;
};
void init(HMENU hMenu, HWND menuParent) {
_hAccelMenu = hMenu;
_hMenuParent = menuParent;
updateShortcuts();
};
HACCEL getAccTable() const {return _hAccTable;};
void updateShortcuts();
private:
HMENU _hAccelMenu;
HWND _hMenuParent;
HACCEL _hAccTable;
ACCEL *_pAccelArray;
int _nbAccelItems;
void reNew() {
if(_hAccTable)
::DestroyAcceleratorTable(_hAccTable);
_hAccTable = ::CreateAcceleratorTable(_pAccelArray, _nbAccelItems);
};
void updateFullMenu();
void updateMenuItemByCommand(CommandShortcut csc);
};
class ScintillaAccelerator { //Handles accelerator keys for scintilla
public:
ScintillaAccelerator() : _nrScintillas(0) {};
void init(vector<HWND> * vScintillas, HMENU hMenu, HWND menuParent);
void updateKeys();
void updateKey(ScintillaKeyMap skmOld, ScintillaKeyMap skm);
private:
HMENU _hAccelMenu;
HWND _hMenuParent;
vector<HWND> _vScintillas;
int _nrScintillas;
void updateMenuItemByID(ScintillaKeyMap skm, int id);
};
#endif //SHORTCUTS_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -