Make macro menu organizable with submenu

This PR allows users to add one level of submenu manually for macro command in shortcuts.xml, in order to better organize macro menu commands.
For doing it, `FolderName="my menu 1"` attribut should be added in <Macro> node. Only 1 level of submenu is allowed.

Here is an example:

```xml
    <Macros>
        <Macro name="aa" Ctrl="no" Alt="no" Shift="no" Key="0">
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="A" />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="A" />
        </Macro>
		<Macro name="azerty" Ctrl="no" Alt="no" Shift="no" Key="0" FolderName="words">
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="a" />
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="z" />
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="e" />
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="r" />
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="t" />
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="y" />
		</Macro>
		<Macro name="qwerty" Ctrl="no" Alt="no" Shift="no" Key="0" FolderName="words">
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="q" />
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="w" />
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="e" />
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="r" />
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="t" />
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="y" />
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="&#x000D;" />
			<Action type="1" message="2170" wParam="0" lParam="0" sParam="&#x000A;" />
		</Macro>
        <Macro name="BB" Ctrl="no" Alt="no" Shift="no" Key="0">
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="&#x000D;" />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="&#x000A;" />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="B" />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="B" />
        </Macro>
        <Macro name="Trim Trailing Space and Save" Ctrl="no" Alt="yes" Shift="yes" Key="83" FolderName="func">
			<Action type="2" message="0" wParam="42024" lParam="0" sParam="" />
			<Action type="2" message="0" wParam="41006" lParam="0" sParam="" />
		</Macro>
        <Macro name="azerty2" Ctrl="no" Alt="no" Shift="no" Key="0">
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="a" />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="z" />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="e" />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="r" />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="t" />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="y" />
            <Action type="1" message="2170" wParam="0" lParam="0" sParam="2" />
        </Macro>
    </Macros>

```

Fix #5349, close #12605
This commit is contained in:
Don Ho 2022-12-05 23:32:59 +01:00
parent 8785b29e21
commit 8e85110b5e
6 changed files with 233 additions and 44 deletions

View File

@ -190,6 +190,8 @@ Notepad_plus::~Notepad_plus()
delete _pFileBrowser; delete _pFileBrowser;
} }
LRESULT Notepad_plus::init(HWND hwnd) LRESULT Notepad_plus::init(HWND hwnd)
{ {
NppParameters& nppParam = NppParameters::getInstance(); NppParameters& nppParam = NppParameters::getInstance();
@ -461,21 +463,15 @@ LRESULT Notepad_plus::init(HWND hwnd)
setupColorSampleBitmapsOnMainMenuItems(); setupColorSampleBitmapsOnMainMenuItems();
// Macro Menu // Macro Menu
std::vector<MacroShortcut> & macros = nppParam.getMacroList();
HMENU hMacroMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_MACRO); HMENU hMacroMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_MACRO);
size_t const posBase = 6; size_t const posBase = 6;
size_t nbMacro = macros.size(); size_t nbTopLevelItem = nppParam.getMacroMenuItems().getTopLevelItemNumber();
if (nbMacro >= 1) if (nbTopLevelItem >= 1)
::InsertMenu(hMacroMenu, posBase - 1, MF_BYPOSITION, static_cast<UINT>(-1), 0); ::InsertMenu(hMacroMenu, posBase - 1, MF_BYPOSITION, static_cast<UINT>(-1), 0);
for (size_t i = 0; i < nbMacro; ++i) DynamicMenu& macroMenuItems = nppParam.getMacroMenuItems();
::InsertMenu(hMacroMenu, static_cast<UINT>(posBase + i), MF_BYPOSITION, ID_MACRO + i, macros[i].toMenuItemString().c_str()); macroMenuItems.attach(hMacroMenu, posBase);
if (nbMacro >= 1)
{
::InsertMenu(hMacroMenu, static_cast<UINT>(posBase + nbMacro + 1), MF_BYPOSITION, static_cast<UINT>(-1), 0);
::InsertMenu(hMacroMenu, static_cast<UINT>(posBase + nbMacro + 2), MF_BYCOMMAND, IDM_SETTING_SHORTCUT_MAPPER_MACRO, TEXT("Modify Shortcut/Delete Macro..."));
}
// Run Menu // Run Menu
std::vector<UserCommand> & userCommands = nppParam.getUserCommandList(); std::vector<UserCommand> & userCommands = nppParam.getUserCommandList();
@ -5189,6 +5185,8 @@ bool Notepad_plus::addCurrentMacro()
int nbMacro = static_cast<int32_t>(theMacros.size()); int nbMacro = static_cast<int32_t>(theMacros.size());
DynamicMenu& macroMenu = nppParams.getMacroMenuItems();
int nbTopLevelItem = macroMenu.getTopLevelItemNumber();
int cmdID = ID_MACRO + nbMacro; int cmdID = ID_MACRO + nbMacro;
MacroShortcut ms(Shortcut(), _macro, cmdID); MacroShortcut ms(Shortcut(), _macro, cmdID);
ms.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf()); ms.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf());
@ -5197,22 +5195,23 @@ bool Notepad_plus::addCurrentMacro()
{ {
HMENU hMacroMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_MACRO); HMENU hMacroMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_MACRO);
int const posBase = 6; //separator at index 5 int const posBase = 6; //separator at index 5
if (nbMacro == 0) if (nbTopLevelItem == 0)
{ {
::InsertMenu(hMacroMenu, posBase-1, MF_BYPOSITION, static_cast<UINT>(-1), 0); //no separator yet, add one ::InsertMenu(hMacroMenu, posBase-1, MF_BYPOSITION, static_cast<UINT>(-1), 0); //no separator yet, add one
// Insert the separator and modify/delete command // Insert the separator and modify/delete command
::InsertMenu(hMacroMenu, posBase + nbMacro + 1, MF_BYPOSITION, static_cast<UINT>(-1), 0); ::InsertMenu(hMacroMenu, posBase + nbTopLevelItem + 1, MF_BYPOSITION, static_cast<UINT>(-1), 0);
NativeLangSpeaker *pNativeLangSpeaker = nppParams.getNativeLangSpeaker(); NativeLangSpeaker *pNativeLangSpeaker = nppParams.getNativeLangSpeaker();
generic_string nativeLangShortcutMapperMacro = pNativeLangSpeaker->getNativeLangMenuString(IDM_SETTING_SHORTCUT_MAPPER_MACRO); generic_string nativeLangShortcutMapperMacro = pNativeLangSpeaker->getNativeLangMenuString(IDM_SETTING_SHORTCUT_MAPPER_MACRO);
if (nativeLangShortcutMapperMacro == TEXT("")) if (nativeLangShortcutMapperMacro == TEXT(""))
nativeLangShortcutMapperMacro = TEXT("Modify Shortcut/Delete Macro..."); nativeLangShortcutMapperMacro = TEXT("Modify Shortcut/Delete Macro...");
::InsertMenu(hMacroMenu, posBase + nbMacro + 2, MF_BYCOMMAND, IDM_SETTING_SHORTCUT_MAPPER_MACRO, nativeLangShortcutMapperMacro.c_str()); ::InsertMenu(hMacroMenu, posBase + nbTopLevelItem + 2, MF_BYCOMMAND, IDM_SETTING_SHORTCUT_MAPPER_MACRO, nativeLangShortcutMapperMacro.c_str());
} }
theMacros.push_back(ms); theMacros.push_back(ms);
::InsertMenu(hMacroMenu, posBase + nbMacro, MF_BYPOSITION, cmdID, ms.toMenuItemString().c_str()); macroMenu.push_back(MenuItemUnit(cmdID, ms.getName()));
::InsertMenu(hMacroMenu, posBase + nbTopLevelItem, MF_BYPOSITION, cmdID, ms.toMenuItemString().c_str());
_accelerator.updateShortcuts(); _accelerator.updateShortcuts();
nppParams.setShortcutDirty(); nppParams.setShortcutDirty();
return true; return true;

View File

@ -711,6 +711,135 @@ generic_string ThemeSwitcher::getThemeFromXmlFileName(const TCHAR *xmlFullPath)
return fn; return fn;
} }
int DynamicMenu::getTopLevelItemNumber() const
{
int nb = 0;
generic_string previousFolderName;
for (const MenuItemUnit& i : _menuItems)
{
if (i._parentFolderName.empty())
{
++nb;
}
else
{
if (previousFolderName.empty())
{
++nb;
previousFolderName = i._parentFolderName;
}
else // previousFolderName is not empty
{
if (i._parentFolderName.empty())
{
++nb;
previousFolderName = i._parentFolderName;
}
else if (previousFolderName == i._parentFolderName)
{
// maintain the number and do nothinh
}
else
{
++nb;
previousFolderName = i._parentFolderName;
}
}
}
}
return nb;
}
bool DynamicMenu::attach(HMENU hMenu, size_t posBase)
{
if (!hMenu) return false;
_hMenu = hMenu;
_posBase = posBase;
return createMenu();
}
bool DynamicMenu::clearMenu() const
{
if (!_hMenu) return false;
int nbTopItem = getTopLevelItemNumber();
for (int i = nbTopItem + 1; i >= 0 ; --i)
{
::DeleteMenu(_hMenu, static_cast<int32_t>(_posBase) + i, MF_BYPOSITION);
}
return true;
}
bool DynamicMenu::createMenu() const
{
if (!_hMenu) return false;
bool lastIsSep = false;
HMENU hParentFolder = NULL;
generic_string currentParentFolderStr;
int j = 0;
size_t nb = _menuItems.size();
size_t i = 0;
for (; i < nb; ++i)
{
const MenuItemUnit& item = _menuItems[i];
if (item._parentFolderName.empty())
{
currentParentFolderStr.clear();
hParentFolder = NULL;
j = 0;
}
else
{
if (item._parentFolderName != currentParentFolderStr)
{
currentParentFolderStr = item._parentFolderName;
hParentFolder = ::CreateMenu();
j = 0;
::InsertMenu(_hMenu, static_cast<UINT>(_posBase + i), MF_BYPOSITION | MF_POPUP, (UINT_PTR)hParentFolder, currentParentFolderStr.c_str());
}
}
unsigned int flag = MF_BYPOSITION | ((item._cmdID == 0) ? MF_SEPARATOR : 0);
if (hParentFolder)
{
::InsertMenu(hParentFolder, j++, flag, item._cmdID, item._itemName.c_str());
lastIsSep = false;
}
else if ((i == 0 || i == _menuItems.size() - 1) && item._cmdID == 0)
{
lastIsSep = true;
}
else if (item._cmdID != 0)
{
::InsertMenu(_hMenu, static_cast<UINT>(_posBase + i), flag, item._cmdID, item._itemName.c_str());
lastIsSep = false;
}
else if (item._cmdID == 0 && !lastIsSep)
{
::InsertMenu(_hMenu, static_cast<int32_t>(_posBase + i), flag, item._cmdID, item._itemName.c_str());
lastIsSep = true;
}
else // last item is separator and current item is separator
{
lastIsSep = true;
}
}
if (nb > 0)
{
::InsertMenu(_hMenu, static_cast<int32_t>(_posBase + i), MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
::InsertMenu(_hMenu, static_cast<UINT>(_posBase + i + 2), MF_BYCOMMAND, IDM_SETTING_SHORTCUT_MAPPER_MACRO, TEXT("Modify Shortcut/Delete Macro..."));
}
return true;
}
winVer NppParameters::getWindowsVersion() winVer NppParameters::getWindowsVersion()
{ {
@ -2611,13 +2740,18 @@ void NppParameters::feedMacros(TiXmlNode *node)
childNode = childNode->NextSibling(TEXT("Macro")) ) childNode = childNode->NextSibling(TEXT("Macro")) )
{ {
Shortcut sc; Shortcut sc;
if (getShortcuts(childNode, sc))// && sc.isValid()) generic_string fdnm;
if (getShortcuts(childNode, sc, &fdnm))
{ {
Macro macro; Macro macro;
getActions(childNode, macro); getActions(childNode, macro);
int cmdID = ID_MACRO + static_cast<int32_t>(_macros.size()); int cmdID = ID_MACRO + static_cast<int32_t>(_macros.size());
MacroShortcut ms(sc, macro, cmdID); MacroShortcut ms(sc, macro, cmdID);
_macros.push_back(ms); _macros.push_back(ms);
MenuItemUnit miu(cmdID, sc.getName(), fdnm);
_macroMenuItems.push_back(miu);
} }
} }
} }
@ -2797,7 +2931,7 @@ bool NppParameters::feedBlacklist(TiXmlNode *node)
return true; return true;
} }
bool NppParameters::getShortcuts(TiXmlNode *node, Shortcut & sc) bool NppParameters::getShortcuts(TiXmlNode *node, Shortcut & sc, generic_string* folderName)
{ {
if (!node) return false; if (!node) return false;
@ -2825,6 +2959,12 @@ bool NppParameters::getShortcuts(TiXmlNode *node, Shortcut & sc)
if (!keyStr) if (!keyStr)
return false; return false;
if (folderName)
{
const TCHAR* fn = (node->ToElement())->Attribute(TEXT("FolderName"));
*folderName = fn ? fn : L"";
}
sc = Shortcut(name, isCtrl, isAlt, isShift, static_cast<unsigned char>(key)); sc = Shortcut(name, isCtrl, isAlt, isShift, static_cast<unsigned char>(key));
return true; return true;
} }
@ -3221,7 +3361,7 @@ void NppParameters::insertCmd(TiXmlNode *shortcutsRoot, const CommandShortcut &
} }
void NppParameters::insertMacro(TiXmlNode *macrosRoot, const MacroShortcut & macro) void NppParameters::insertMacro(TiXmlNode *macrosRoot, const MacroShortcut & macro, const generic_string& folderName)
{ {
const KeyCombo & key = macro.getKeyCombo(); const KeyCombo & key = macro.getKeyCombo();
TiXmlNode *macroRoot = macrosRoot->InsertEndChild(TiXmlElement(TEXT("Macro"))); TiXmlNode *macroRoot = macrosRoot->InsertEndChild(TiXmlElement(TEXT("Macro")));
@ -3230,6 +3370,8 @@ void NppParameters::insertMacro(TiXmlNode *macrosRoot, const MacroShortcut & mac
macroRoot->ToElement()->SetAttribute(TEXT("Alt"), key._isAlt?TEXT("yes"):TEXT("no")); macroRoot->ToElement()->SetAttribute(TEXT("Alt"), key._isAlt?TEXT("yes"):TEXT("no"));
macroRoot->ToElement()->SetAttribute(TEXT("Shift"), key._isShift?TEXT("yes"):TEXT("no")); macroRoot->ToElement()->SetAttribute(TEXT("Shift"), key._isShift?TEXT("yes"):TEXT("no"));
macroRoot->ToElement()->SetAttribute(TEXT("Key"), key._key); macroRoot->ToElement()->SetAttribute(TEXT("Key"), key._key);
if (!folderName.empty())
macroRoot->ToElement()->SetAttribute(TEXT("FolderName"), folderName);
for (size_t i = 0, len = macro._macro.size(); i < len ; ++i) for (size_t i = 0, len = macro._macro.size(); i < len ; ++i)
{ {
@ -3442,7 +3584,7 @@ void NppParameters::writeShortcuts()
for (size_t i = 0, len = _macros.size(); i < len ; ++i) for (size_t i = 0, len = _macros.size(); i < len ; ++i)
{ {
insertMacro(macrosRoot, _macros[i]); insertMacro(macrosRoot, _macros[i], _macroMenuItems.getItemFromIndex(i)._parentFolderName);
} }
TiXmlNode *userCmdRoot = root->FirstChild(TEXT("UserDefinedCommands")); TiXmlNode *userCmdRoot = root->FirstChild(TEXT("UserDefinedCommands"));

View File

@ -1331,6 +1331,31 @@ const int NB_LANG = 100;
const int RECENTFILES_SHOWFULLPATH = -1; const int RECENTFILES_SHOWFULLPATH = -1;
const int RECENTFILES_SHOWONLYFILENAME = 0; const int RECENTFILES_SHOWONLYFILENAME = 0;
class DynamicMenu final
{
public:
bool attach(HMENU hMenu, size_t posBase);
bool createMenu() const;
bool clearMenu() const;
int getTopLevelItemNumber() const;
void push_back(const MenuItemUnit& m) {
_menuItems.push_back(m);
};
MenuItemUnit& getItemFromIndex(size_t i) {
return _menuItems[i];
};
void erase(size_t i) {
_menuItems.erase(_menuItems.begin() + i);
}
private:
std::vector<MenuItemUnit> _menuItems;
HMENU _hMenu = nullptr;
size_t _posBase = 0;
};
class NppParameters final class NppParameters final
{ {
private: private:
@ -1556,6 +1581,7 @@ public:
std::vector<MenuItemUnit>& getContextMenuItems() { return _contextMenuItems; }; std::vector<MenuItemUnit>& getContextMenuItems() { return _contextMenuItems; };
std::vector<MenuItemUnit>& getTabContextMenuItems() { return _tabContextMenuItems; }; std::vector<MenuItemUnit>& getTabContextMenuItems() { return _tabContextMenuItems; };
DynamicMenu& getMacroMenuItems() { return _macroMenuItems; };
bool hasCustomContextMenu() const {return !_contextMenuItems.empty();}; bool hasCustomContextMenu() const {return !_contextMenuItems.empty();};
bool hasCustomTabContextMenu() const {return !_tabContextMenuItems.empty();}; bool hasCustomTabContextMenu() const {return !_tabContextMenuItems.empty();};
@ -1832,6 +1858,7 @@ private:
std::vector<MenuItemUnit> _contextMenuItems; std::vector<MenuItemUnit> _contextMenuItems;
std::vector<MenuItemUnit> _tabContextMenuItems; std::vector<MenuItemUnit> _tabContextMenuItems;
DynamicMenu _macroMenuItems;
Session _session; Session _session;
generic_string _shortcutsPath; generic_string _shortcutsPath;
@ -1936,12 +1963,12 @@ private:
bool feedBlacklist(TiXmlNode *node); bool feedBlacklist(TiXmlNode *node);
void getActions(TiXmlNode *node, Macro & macro); void getActions(TiXmlNode *node, Macro & macro);
bool getShortcuts(TiXmlNode *node, Shortcut & sc); bool getShortcuts(TiXmlNode *node, Shortcut & sc, generic_string* folderName = nullptr);
void writeStyle2Element(const Style & style2Write, Style & style2Sync, TiXmlElement *element); void writeStyle2Element(const Style & style2Write, Style & style2Sync, TiXmlElement *element);
void insertUserLang2Tree(TiXmlNode *node, UserLangContainer *userLang); void insertUserLang2Tree(TiXmlNode *node, UserLangContainer *userLang);
void insertCmd(TiXmlNode *cmdRoot, const CommandShortcut & cmd); void insertCmd(TiXmlNode *cmdRoot, const CommandShortcut & cmd);
void insertMacro(TiXmlNode *macrosRoot, const MacroShortcut & macro); void insertMacro(TiXmlNode *macrosRoot, const MacroShortcut & macro, const generic_string& folderName);
void insertUserCmd(TiXmlNode *userCmdRoot, const UserCommand & userCmd); void insertUserCmd(TiXmlNode *userCmdRoot, const UserCommand & userCmd);
void insertScintKey(TiXmlNode *scintKeyRoot, const ScintillaKeyMap & scintKeyMap); void insertScintKey(TiXmlNode *scintKeyRoot, const ScintillaKeyMap & scintKeyMap);
void insertPluginCmd(TiXmlNode *pluginCmdRoot, const PluginCmdShortcut & pluginCmd); void insertPluginCmd(TiXmlNode *pluginCmdRoot, const PluginCmdShortcut & pluginCmd);

View File

@ -101,6 +101,7 @@ void ContextMenu::create(HWND hParent, const std::vector<MenuItemUnit> & menuIte
{ {
lastIsSep = true; lastIsSep = true;
} }
if (mainMenuHandle) if (mainMenuHandle)
{ {
UINT s = ::GetMenuState(mainMenuHandle, item._cmdID, MF_BYCOMMAND); UINT s = ::GetMenuState(mainMenuHandle, item._cmdID, MF_BYCOMMAND);

View File

@ -951,7 +951,6 @@ intptr_t CALLBACK ShortcutMapper::run_dlgProc(UINT message, WPARAM wParam, LPARA
int32_t posBase = 0; int32_t posBase = 0;
size_t nbElem = 0; size_t nbElem = 0;
HMENU hMenu = NULL; HMENU hMenu = NULL;
int modifCmd = IDM_SETTING_SHORTCUT_MAPPER_RUN;
switch(_currentState) switch(_currentState)
{ {
case STATE_MENU: case STATE_MENU:
@ -967,6 +966,8 @@ intptr_t CALLBACK ShortcutMapper::run_dlgProc(UINT message, WPARAM wParam, LPARA
vector<MacroShortcut>::iterator it = theMacros.begin(); vector<MacroShortcut>::iterator it = theMacros.begin();
theMacros.erase(it + shortcutIndex); theMacros.erase(it + shortcutIndex);
//save the current view //save the current view
_lastHomeRow[_currentState] = _babygrid.getHomeRow(); _lastHomeRow[_currentState] = _babygrid.getHomeRow();
_lastCursorRow[_currentState] = _babygrid.getSelectedRow(); _lastCursorRow[_currentState] = _babygrid.getSelectedRow();
@ -979,18 +980,38 @@ intptr_t CALLBACK ShortcutMapper::run_dlgProc(UINT message, WPARAM wParam, LPARA
fillOutBabyGrid(); fillOutBabyGrid();
// preparing to remove from menu // clear all menu
posBase = 6; DynamicMenu& macroMenu = nppParam.getMacroMenuItems();
nbElem = theMacros.size(); macroMenu.clearMenu();
HMENU m = reinterpret_cast<HMENU>(::SendMessage(_hParent, NPPM_INTERNAL_GETMENU, 0, 0));
hMenu = ::GetSubMenu(m, MENUINDEX_MACRO);
modifCmd = IDM_SETTING_SHORTCUT_MAPPER_MACRO; // Erase the menu item
macroMenu.erase(shortcutIndex);
nbElem = theMacros.size();
for (size_t i = shortcutIndex; i < nbElem; ++i) //lower the IDs of the remaining items so there are no gaps for (size_t i = shortcutIndex; i < nbElem; ++i) //lower the IDs of the remaining items so there are no gaps
{ {
MacroShortcut ms = theMacros[i]; MacroShortcut ms = theMacros[i];
ms.setID(ms.getID() - 1); //shift all IDs ms.setID(ms.getID() - 1); //shift all IDs
theMacros[i] = ms; theMacros[i] = ms;
// Ajust menu items
MenuItemUnit& miu = macroMenu.getItemFromIndex(i);
miu._cmdID -= 1; //shift all IDs
}
// create from scratch according the new menu items structure
macroMenu.createMenu();
HMENU m = reinterpret_cast<HMENU>(::SendMessage(_hParent, NPPM_INTERNAL_GETMENU, 0, 0));
hMenu = ::GetSubMenu(m, MENUINDEX_MACRO);
posBase = 6;
if (nbElem == 0)
{
::RemoveMenu(hMenu, IDM_SETTING_SHORTCUT_MAPPER_MACRO, MF_BYCOMMAND);
//remove separator
::RemoveMenu(hMenu, posBase - 1, MF_BYPOSITION);
::RemoveMenu(hMenu, posBase - 1, MF_BYPOSITION);
} }
} }
break; break;
@ -1019,20 +1040,12 @@ intptr_t CALLBACK ShortcutMapper::run_dlgProc(UINT message, WPARAM wParam, LPARA
HMENU m = reinterpret_cast<HMENU>(::SendMessage(_hParent, NPPM_INTERNAL_GETMENU, 0, 0)); HMENU m = reinterpret_cast<HMENU>(::SendMessage(_hParent, NPPM_INTERNAL_GETMENU, 0, 0));
hMenu = ::GetSubMenu(m, MENUINDEX_RUN); hMenu = ::GetSubMenu(m, MENUINDEX_RUN);
modifCmd = IDM_SETTING_SHORTCUT_MAPPER_RUN;
for (size_t i = shortcutIndex; i < nbElem; ++i) //lower the IDs of the remaining items so there are no gaps for (size_t i = shortcutIndex; i < nbElem; ++i) //lower the IDs of the remaining items so there are no gaps
{ {
UserCommand uc = theUserCmds[i]; UserCommand uc = theUserCmds[i];
uc.setID(uc.getID() - 1); //shift all IDs uc.setID(uc.getID() - 1); //shift all IDs
theUserCmds[i] = uc; theUserCmds[i] = uc;
} }
}
break;
}
// updateShortcuts() will update all menu item - the menu items will be shifted
nppParam.getAccelerator()->updateShortcuts();
nppParam.setShortcutDirty();
if (!hMenu) return FALSE; if (!hMenu) return FALSE;
@ -1041,13 +1054,20 @@ intptr_t CALLBACK ShortcutMapper::run_dlgProc(UINT message, WPARAM wParam, LPARA
if (nbElem == 0) if (nbElem == 0)
{ {
::RemoveMenu(hMenu, modifCmd, MF_BYCOMMAND); ::RemoveMenu(hMenu, IDM_SETTING_SHORTCUT_MAPPER_RUN, MF_BYCOMMAND);
//remove separator //remove separator
::RemoveMenu(hMenu, posBase-1, MF_BYPOSITION); ::RemoveMenu(hMenu, posBase - 1, MF_BYPOSITION);
::RemoveMenu(hMenu, posBase-1, MF_BYPOSITION); ::RemoveMenu(hMenu, posBase - 1, MF_BYPOSITION);
} }
} }
break;
}
// updateShortcuts() will update all menu item - the menu items will be shifted
nppParam.getAccelerator()->updateShortcuts();
nppParam.setShortcutDirty();
}
return TRUE; return TRUE;
} }

View File

@ -546,7 +546,7 @@ void Accelerator::updateShortcuts()
size_t nbPluginCmd = pluginCommands.size(); size_t nbPluginCmd = pluginCommands.size();
delete [] _pAccelArray; delete [] _pAccelArray;
_pAccelArray = new ACCEL[nbMenu + nbMacro+nbUserCmd + nbPluginCmd]; _pAccelArray = new ACCEL[nbMenu + nbMacro + nbUserCmd + nbPluginCmd];
vector<ACCEL> incrFindAcc; vector<ACCEL> incrFindAcc;
vector<ACCEL> findReplaceAcc; vector<ACCEL> findReplaceAcc;
int offset = 0; int offset = 0;