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 // Add external languages to menu
for (int i = 0; i < nppParam.getNbExternalLang(); ++i) for (int i = 0; i < nppParam.getNbExternalLang(); ++i)
{ {
HMENU subMenu = hLangMenu;
ExternalLangContainer & externalLangContainer = nppParam.getELCFromIndex(i); ExternalLangContainer & externalLangContainer = nppParam.getELCFromIndex(i);
int numLangs = ::GetMenuItemCount(hLangMenu); int nbItem = ::GetMenuItemCount(subMenu);
TCHAR buffer[menuItemStrLenMax]{}; TCHAR buffer[MAX_EXTERNAL_LEXER_NAME_LEN]{TEXT('\0')};
const TCHAR* lexerNameW = wmc.char2wchar(externalLangContainer._name.c_str(), CP_ACP); 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; 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) if (nppGUI._excludedLangList.size() > 0)
{ {
for (size_t i = 0, len = nppGUI._excludedLangList.size(); i < len; ++i) 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 menu = HMENU(::SendMessage(grandParent, NPPM_INTERNAL_GETMENU, 0, 0));
HMENU subMenu = ::GetSubMenu(menu, MENUINDEX_LANGUAGE); HMENU subMenu = ::GetSubMenu(menu, MENUINDEX_LANGUAGE);
// Add back a languge menu item always before the 3 last items: // Find the first separator which is between IDM_LANG_TEXT and languages
// 1. -----------------------
// 2. Define your language...
// 3. User-Defined
int nbItem = ::GetMenuItemCount(subMenu); 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) // Find the location in existing language menu to insert to. This includes submenu if using compact language menu.
return FALSE; 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); ::DrawMenuBar(grandParent);
return TRUE; return TRUE;