Fix lexer plugin is sorted unconventionally in language menu issue

Correct the logic when inserting external lexer's language into language menu,
while inserting external lexer's language into language menu, also search in submenu if compact language menu is used.
Fix also a similar issue in Preferences dialog when enabling a previously disabled language.

Fix #9516, close #13660
This commit is contained in:
blu3mania 2023-05-16 11:44:15 -04:00 committed by Don Ho
parent 776a3fb945
commit 406a77a608
2 changed files with 77 additions and 12 deletions

View File

@ -499,21 +499,55 @@ LRESULT Notepad_plus::init(HWND hwnd)
// Add external languages to menu
for (int i = 0; i < nppParam.getNbExternalLang(); ++i)
{
HMENU subMenu = hLangMenu;
ExternalLangContainer & externalLangContainer = nppParam.getELCFromIndex(i);
int numLangs = ::GetMenuItemCount(hLangMenu);
TCHAR buffer[menuItemStrLenMax]{};
int nbItem = ::GetMenuItemCount(subMenu);
TCHAR buffer[MAX_EXTERNAL_LEXER_NAME_LEN]{TEXT('\0')};
const TCHAR* lexerNameW = wmc.char2wchar(externalLangContainer._name.c_str(), CP_ACP);
// Find the first separator which is between IDM_LANG_TEXT and languages
int x = 0;
for (; (x == 0 || lstrcmp(lexerNameW, buffer) > 0) && x < numLangs; ++x)
MENUITEMINFO menuItemInfo
{
::GetMenuString(hLangMenu, x, buffer, menuItemStrLenMax, MF_BYPOSITION);
.cbSize = sizeof(MENUITEMINFO),
.fMask = MIIM_FTYPE
};
for (; x < nbItem; ++x)
{
::GetMenuItemInfo(subMenu, x, TRUE, &menuItemInfo);
if (menuItemInfo.fType & MFT_SEPARATOR)
{
break;
}
}
::InsertMenu(hLangMenu, x - 1, MF_BYPOSITION, IDM_LANG_EXTERNAL + i, lexerNameW);
// Find the location in existing language menu to insert to. This includes submenu if using compact language menu.
TCHAR firstLetter = towupper(lexerNameW[0]);
menuItemInfo.fMask = MIIM_SUBMENU;
for (++x; x < nbItem; ++x)
{
::GetMenuItemInfo(subMenu, x, TRUE, &menuItemInfo);
::GetMenuString(subMenu, x, buffer, MAX_EXTERNAL_LEXER_NAME_LEN, MF_BYPOSITION);
// Check if using compact language menu.
if (menuItemInfo.hSubMenu && buffer[0] == firstLetter)
{
// Found the submenu for the language's first letter. Search in it instead.
subMenu = menuItemInfo.hSubMenu;
nbItem = ::GetMenuItemCount(subMenu);
x = -1;
}
else if (lstrcmp(lexerNameW, buffer) < 0)
{
break;
}
}
::InsertMenu(subMenu, x, MF_BYPOSITION, IDM_LANG_EXTERNAL + i, lexerNameW);
}
if (nppGUI._excludedLangList.size() > 0)
{
for (size_t i = 0, len = nppGUI._excludedLangList.size(); i < len; ++i)

View File

@ -3244,16 +3244,47 @@ intptr_t CALLBACK LanguageSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARA
HMENU menu = HMENU(::SendMessage(grandParent, NPPM_INTERNAL_GETMENU, 0, 0));
HMENU subMenu = ::GetSubMenu(menu, MENUINDEX_LANGUAGE);
// Add back a languge menu item always before the 3 last items:
// 1. -----------------------
// 2. Define your language...
// 3. User-Defined
// Find the first separator which is between IDM_LANG_TEXT and languages
int nbItem = ::GetMenuItemCount(subMenu);
int x = 0;
MENUITEMINFO menuItemInfo
{
.cbSize = sizeof(MENUITEMINFO),
.fMask = MIIM_FTYPE
};
for (; x < nbItem; ++x)
{
::GetMenuItemInfo(subMenu, x, TRUE, &menuItemInfo);
if (menuItemInfo.fType & MFT_SEPARATOR)
{
break;
}
}
if (nbItem < 3)
return FALSE;
// Find the location in existing language menu to insert to. This includes submenu if using compact language menu.
TCHAR firstLetter = lmi._langName.empty() ? TEXT('\0') : towupper(lmi._langName[0]);
TCHAR buffer[MAX_EXTERNAL_LEXER_NAME_LEN]{TEXT('\0')};
menuItemInfo.fMask = MIIM_SUBMENU;
for (++x; x < nbItem; ++x)
{
::GetMenuItemInfo(subMenu, x, TRUE, &menuItemInfo);
::GetMenuString(subMenu, x, buffer, MAX_EXTERNAL_LEXER_NAME_LEN, MF_BYPOSITION);
::InsertMenu(subMenu, nbItem - 3, MF_BYPOSITION, lmi._cmdID, lmi._langName.c_str());
// Check if using compact language menu.
if (menuItemInfo.hSubMenu && buffer[0] == firstLetter)
{
// Found the submenu for the language's first letter. Search in it instead.
subMenu = menuItemInfo.hSubMenu;
nbItem = ::GetMenuItemCount(subMenu);
x = -1;
}
else if (lstrcmp(lmi._langName.c_str(), buffer) < 0)
{
break;
}
}
::InsertMenu(subMenu, x, MF_BYPOSITION, lmi._cmdID, lmi._langName.c_str());
}
::DrawMenuBar(grandParent);
return TRUE;