Make tab context menu customizable

Use tabContextMenu_example.xml for the customization:

1. rename to tabContextMenu.xml
2. modify it
3. copy it beside notepad++.exe or to %APPDATA%\Notepad++\ according to your Notepad++ conf
4. relaunch Notepad++

Note for the localization:

1. You have to use the newest localization file (or modify your existing localization file with the newest english.xml).
2. The customized sub-menu entry cannot be translated. User can use his/her native language as value of attribute "FolderName" in tabContextMenu.xml file.
3. User can always add any command beyond the default commands in tabContextMenu.xml file. But such command won't be translated.

Fix #12170, close #12576
This commit is contained in:
Don Ho 2022-11-28 02:14:48 +01:00
parent 785b3417b6
commit aa8ae48b99
9 changed files with 303 additions and 225 deletions

View File

@ -386,41 +386,41 @@ The comments are here for explanation, it's not necessary to translate them.
<Splitter>
</Splitter>
<TabBar>
<Item CMID="0" name="Close"/>
<Item CMID="1" name="Close All BUT This"/>
<Item CMID="2" name="Save"/>
<Item CMID="3" name="Save As..."/>
<Item CMID="4" name="Print..."/>
<Item CMID="5" name="Move to Other View"/>
<Item CMID="6" name="Clone to Other View"/>
<Item CMID="7" name="Copy Full File Path"/>
<Item CMID="8" name="Copy Filename"/>
<Item CMID="9" name="Copy Current Dir. Path"/>
<Item CMID="10" name="Rename..."/>
<Item CMID="11" name="Move to Recycle Bin"/>
<Item CMID="12" name="Read-Only"/>
<Item CMID="13" name="Clear Read-Only Flag"/>
<Item CMID="14" name="Move to New Instance"/>
<Item CMID="15" name="Open in New Instance"/>
<Item CMID="16" name="Reload"/>
<Item CMID="17" name="Close All to the Left"/>
<Item CMID="18" name="Close All to the Right"/>
<Item CMID="19" name="Open Containing Folder in Explorer"/>
<Item CMID="20" name="Open Containing Folder in cmd"/>
<Item CMID="21" name="Open in Default Viewer"/>
<Item CMID="22" name="Close All Unchanged"/>
<Item CMID="23" name="Open Containing Folder as Workspace"/>
<Item CMID="24" name="Apply Color 1"/>
<Item CMID="25" name="Apply Color 2"/>
<Item CMID="26" name="Apply Color 3"/>
<Item CMID="27" name="Apply Color 4"/>
<Item CMID="28" name="Apply Color 5"/>
<Item CMID="29" name="Remove Color"/>
<Item CMID="30" name="Close Multiple Tabs"/>
<Item CMID="31" name="Open into"/>
<Item CMID="32" name="Copy to Clipboard"/>
<Item CMID="33" name="Move Document"/>
<Item CMID="34" name="Apply Color to Tab"/>
<Item CMDID="41003" name="Close"/>
<Item CMDID="0" name="Close Multiple Tabs"/>
<Item CMDID="41005" name="Close All BUT This"/>
<Item CMDID="41009" name="Close All to the Left"/>
<Item CMDID="41018" name="Close All to the Right"/>
<Item CMDID="41024" name="Close All Unchanged"/>
<Item CMDID="41006" name="Save"/>
<Item CMDID="41008" name="Save As..."/>
<Item CMDID="1" name="Open into"/>
<Item CMDID="41019" name="Open Containing Folder in Explorer"/>
<Item CMDID="41020" name="Open Containing Folder in cmd"/>
<Item CMDID="41025" name="Open Containing Folder as Workspace"/>
<Item CMDID="41023" name="Open in Default Viewer"/>
<Item CMDID="41017" name="Rename..."/>
<Item CMDID="41016" name="Move to Recycle Bin"/>
<Item CMDID="41014" name="Reload"/>
<Item CMDID="41010" name="Print..."/>
<Item CMDID="42028" name="Read-Only"/>
<Item CMDID="42033" name="Clear Read-Only Flag"/>
<Item CMDID="2" name="Copy to Clipboard"/>
<Item CMDID="42029" name="Copy Full File Path"/>
<Item CMDID="42030" name="Copy Filename"/>
<Item CMDID="42031" name="Copy Current Dir. Path"/>
<Item CMDID="3" name="Move Document"/>
<Item CMDID="10001" name="Move to Other View"/>
<Item CMDID="10002" name="Clone to Other View"/>
<Item CMDID="10003" name="Move to New Instance"/>
<Item CMDID="10004" name="Open in New Instance"/>
<Item CMDID="4" name="Apply Color to Tab"/>
<Item CMDID="44111" name="Apply Color 1"/>
<Item CMDID="44112" name="Apply Color 2"/>
<Item CMDID="44113" name="Apply Color 3"/>
<Item CMDID="44114" name="Apply Color 4"/>
<Item CMDID="44115" name="Apply Color 5"/>
<Item CMDID="44110" name="Remove Color"/>
</TabBar>
</Menu>

View File

@ -386,41 +386,41 @@ The comments are here for explanation, it's not necessary to translate them.
<Splitter>
</Splitter>
<TabBar>
<Item CMID="0" name="Fermer"/>
<Item CMID="1" name="Fermer tout sauf ce fichier"/>
<Item CMID="2" name="Enregistrer"/>
<Item CMID="3" name="Enregistrer sous..."/>
<Item CMID="4" name="Imprimer"/>
<Item CMID="5" name="Déplacer vers l'autre vue"/>
<Item CMID="6" name="Cloner dans l'autre vue"/>
<Item CMID="7" name="Copier le chemin complet du document actuel"/>
<Item CMID="8" name="Copier le nom du fichier actuel"/>
<Item CMID="9" name="Copier le dossier du fichier actuel"/>
<Item CMID="10" name="Renommer le fichier actuel"/>
<Item CMID="11" name="Supprimer le fichier actuel"/>
<Item CMID="12" name="Lecture seule pour le document actuel"/>
<Item CMID="13" name="Enlever lattribut de lecture seule du fichier"/>
<Item CMID="14" name="Déplacer vers une nouvelle fenêtre"/>
<Item CMID="15" name="Ouvrir dans une nouvelle fenêtre"/>
<Item CMID="16" name="Recharger"/>
<Item CMID="17" name="Fermer les onglets sur la gauche"/>
<Item CMID="18" name="Fermer les onglets sur la droite"/>
<Item CMID="19" name="Ouvrir le répertoire du fichier en cours dans l'explorateur"/>
<Item CMID="20" name="Ouvrir le répertoire du fichier en cours dans l'invite de commande"/>
<Item CMID="21" name="Ouvrir dans l'application par défaut"/>
<Item CMID="22" name="Fermer tous les documents non-modifiés"/>
<Item CMID="23" name="Ouvrir le répertoire du fichier en cours en tant qu'espace de travail"/>
<Item CMID="24" name="Appliquer la couleur 1"/>
<Item CMID="25" name="Appliquer la couleur 2"/>
<Item CMID="26" name="Appliquer la couleur 3"/>
<Item CMID="27" name="Appliquer la couleur 4"/>
<Item CMID="28" name="Appliquer la couleur 5"/>
<Item CMID="29" name="Enlever la couleur"/>
<Item CMID="30" name="Fermer plusieurs onglets"/>
<Item CMID="31" name="Ouvrir dans"/>
<Item CMID="32" name="Copier dans le presse-papiers"/>
<Item CMID="33" name="Déplacer le document"/>
<Item CMID="34" name="Appliquer la Couleur à l'onglet"/>
<Item CMDID="41003" name="Fermer"/>
<Item CMDID="0" name="Fermer plusieurs onglets"/>
<Item CMDID="41005" name="Fermer tout sauf ce fichier"/>
<Item CMDID="41009" name="Fermer les onglets sur la gauche"/>
<Item CMDID="41018" name="Fermer les onglets sur la droite"/>
<Item CMDID="41024" name="Fermer tous les documents non-modifiés"/>
<Item CMDID="41006" name="Enregistrer"/>
<Item CMDID="41008" name="Enregistrer sous..."/>
<Item CMDID="1" name="Ouvrir dans"/>
<Item CMDID="41019" name="Ouvrir le répertoire du fichier en cours dans l'explorateur"/>
<Item CMDID="41020" name="Ouvrir le répertoire du fichier en cours dans l'invite de commande"/>
<Item CMDID="41025" name="Ouvrir le répertoire du fichier en cours en tant qu'espace de travail"/>
<Item CMDID="41023" name="Ouvrir dans l'application par défaut"/>
<Item CMDID="41017" name="Renommer le fichier actuel"/>
<Item CMDID="41016" name="Supprimer le fichier actuel"/>
<Item CMDID="41014" name="Recharger"/>
<Item CMDID="41010" name="Imprimer"/>
<Item CMDID="42028" name="Lecture seule pour le document actuel"/>
<Item CMDID="42033" name="Enlever lattribut de lecture seule du fichier"/>
<Item CMDID="2" name="Copier dans le presse-papiers"/>
<Item CMDID="42029" name="Copier le chemin complet du document actuel"/>
<Item CMDID="42030" name="Copier le nom du fichier actuel"/>
<Item CMDID="42031" name="Copier le dossier du fichier actuel"/>
<Item CMDID="3" name="Déplacer le document"/>
<Item CMDID="10001" name="Déplacer vers l'autre vue"/>
<Item CMDID="10002" name="Cloner dans l'autre vue"/>
<Item CMDID="10003" name="Déplacer vers une nouvelle fenêtre"/>
<Item CMDID="10004" name="Ouvrir dans une nouvelle fenêtre"/>
<Item CMDID="4" name="Appliquer la Couleur à l'onglet"/>
<Item CMDID="44111" name="Appliquer la couleur 1"/>
<Item CMDID="44112" name="Appliquer la couleur 2"/>
<Item CMDID="44113" name="Appliquer la couleur 3"/>
<Item CMDID="44114" name="Appliquer la couleur 4"/>
<Item CMDID="44115" name="Appliquer la couleur 5"/>
<Item CMDID="44110" name="Enlever la couleur"/>
</TabBar>
</Menu>

View File

@ -375,41 +375,41 @@
<Splitter>
</Splitter>
<TabBar>
<Item CMID="0" name="關閉"/>
<Item CMID="1" name="除此之外全部關閉"/>
<Item CMID="2" name="儲存"/>
<Item CMID="3" name="另存新檔..."/>
<Item CMID="4" name="列印"/>
<Item CMID="5" name="移動到另一檢視"/>
<Item CMID="6" name="仿製到另一檢視"/>
<Item CMID="7" name="複製完整路徑檔名"/>
<Item CMID="8" name="複製檔名"/>
<Item CMID="9" name="複製路徑"/>
<Item CMID="10" name="重新命名..."/>
<Item CMID="11" name="移至回收筒"/>
<Item CMID="12" name="唯讀"/>
<Item CMID="13" name="取消唯讀"/>
<Item CMID="14" name="移到新執行個體"/>
<Item CMID="15" name="在新執行個體開啟"/>
<Item CMID="16" name="重新載入"/>
<Item CMID="17" name="關閉左側所有檔案"/>
<Item CMID="18" name="關閉右側所有檔案"/>
<Item CMID="19" name="在檔案總管開啟資料夾路徑"/>
<Item CMID="20" name="在 CMD 開啟資料夾路徑"/>
<Item CMID="21" name="在預設檢視中開啟"/>
<Item CMID="22" name="關閉所有未更改的檔案"/>
<Item CMID="23" name="在工作區開啟此檔資料夾"/>
<Item CMID="24" name="顏色一"/>
<Item CMID="25" name="顏色二"/>
<Item CMID="26" name="顏色三"/>
<Item CMID="27" name="顏色四"/>
<Item CMID="28" name="顏色五"/>
<Item CMID="29" name="移除顏色"/>
<Item CMID="30" name="關閉多個檔案"/>
<Item CMID="31" name="開啟至"/>
<Item CMID="32" name="複製到剪貼簿"/>
<Item CMID="33" name="文件移至"/>
<Item CMID="34" name="頁籤使用顏色"/>
<Item CMDID="41003" name="關閉"/>
<Item CMDID="0" name="關閉多個檔案"/>
<Item CMDID="41005" name="除此之外全部關閉"/>
<Item CMDID="41009" name="關閉左側所有檔案"/>
<Item CMDID="41018" name="關閉右側所有檔案"/>
<Item CMDID="41024" name="關閉所有未更改的檔案"/>
<Item CMDID="41006" name="儲存"/>
<Item CMDID="41008" name="另存新檔..."/>
<Item CMDID="1" name="開啟至"/>
<Item CMDID="41019" name="在檔案總管開啟資料夾路徑"/>
<Item CMDID="41020" name="在 CMD 開啟資料夾路徑"/>
<Item CMDID="41025" name="在工作區開啟此檔資料夾"/>
<Item CMDID="41023" name="在預設檢視中開啟"/>
<Item CMDID="41017" name="重新命名..."/>
<Item CMDID="41016" name="移至回收筒"/>
<Item CMDID="41014" name="重新載入"/>
<Item CMDID="41010" name="列印"/>
<Item CMDID="42028" name="唯讀"/>
<Item CMDID="42033" name="取消唯讀"/>
<Item CMDID="2" name="複製到剪貼簿"/>
<Item CMDID="42029" name="複製完整路徑檔名"/>
<Item CMDID="42030" name="複製檔名"/>
<Item CMDID="42031" name="複製路徑"/>
<Item CMDID="3" name="文件移至"/>
<Item CMDID="10001" name="移動到另一檢視"/>
<Item CMDID="10002" name="仿製到另一檢視"/>
<Item CMDID="10003" name="移到新執行個體"/>
<Item CMDID="10004" name="在新執行個體開啟"/>
<Item CMDID="4" name="頁籤使用顏色"/>
<Item CMDID="44111" name="顏色一"/>
<Item CMDID="44112" name="顏色二"/>
<Item CMDID="44113" name="顏色三"/>
<Item CMDID="44114" name="顏色四"/>
<Item CMDID="44115" name="顏色五"/>
<Item CMDID="44110" name="移除顏色"/>
</TabBar>
</Menu>
<Dialog>
@ -454,14 +454,14 @@
<Item id="1703" name="「.」包含換行字元"/>
<Item id="1721" name="▲"/>
<Item id="1723" name="▼ 找下一個"/>
<Item id="1725" name="複製標記文字"/>
<Item id="1725" name="複製標記文字"/>
</Find>
<IncrementalFind title="">
<Item id="1681" name="搜尋:"/>
<Item id="1685" name="區分大小寫"/>
<Item id="1690" name="醒目提示所有"/>
</IncrementalFind>
<FindCharsInRange title="以字元編號搜尋字元">
<FindCharsInRange title="以字元編號搜尋字元">
<Item id="2" name="關閉"/>
<Item id="2901" name="非 ASCII 字元128-255"/>
<Item id="2902" name="ASCII 字元0-127"/>
@ -1142,7 +1142,7 @@
<Item id="6162" name="使用預設的單字字元集(建議)"/>
<Item id="6163" name="添加字元(不了解此選項的話不建議選取)"/>
</Delimiter>
<Performance title="性能">
<Item id="7141" name="大型檔案限制"/>
<Item id="7143" name="啟動大型檔案限制(沒有語法醒目提示)"/>
@ -1446,7 +1446,7 @@
<default-open-save-select-folder value="選擇一個你要設定為內定資料夾的資料夾"/>
<shift-change-direction-tip value="使用「Shift + Enter」以相反方向進行搜尋"/>
<two-find-buttons-tip value="顯示「找上一個」按鈕"/>
<find-in-files-filter-tip value="只在 cpp, cxx, h, hxx &amp;&amp; hpp :
<find-in-files-filter-tip value="只在 cpp, cxx, h, hxx &amp;&amp; hpp :
*.cpp *.cxx *.h *.hxx *.hpp
所有檔案除了 exe, obj &amp;&amp; log 之外:

View File

@ -577,9 +577,12 @@ LRESULT Notepad_plus::init(HWND hwnd)
//disable "Search Results Window" under Search Menu
::EnableMenuItem(_mainMenuHandle, IDM_FOCUS_ON_FOUND_RESULTS, MF_DISABLED | MF_GRAYED | MF_BYCOMMAND);
//Main menu is loaded, now load context menu items
//Main menu is loaded, now load editor context menu items
nppParam.getContextMenuFromXmlTree(_mainMenuHandle, _pluginsManager.getMenuHandle());
//Main menu is loaded, now load tab context menu items
nppParam.getContextMenuFromXmlTree(_mainMenuHandle, _pluginsManager.getMenuHandle(), false);
if (nppParam.hasCustomContextMenu())
{
_mainEditView.execute(SCI_USEPOPUP, FALSE);
@ -593,7 +596,7 @@ LRESULT Notepad_plus::init(HWND hwnd)
//Windows menu
_windowsMenu.init(_mainMenuHandle);
// Update context menu strings (translated)
// Update Scintilla context menu strings (translated)
vector<MenuItemUnit> & tmp = nppParam.getContextMenuItems();
size_t len = tmp.size();
TCHAR menuName[64];
@ -606,6 +609,19 @@ LRESULT Notepad_plus::init(HWND hwnd)
}
}
// Update tab context menu strings (translated)
vector<MenuItemUnit>& tmp2 = nppParam.getTabContextMenuItems();
size_t len2 = tmp2.size();
for (size_t i = 0; i < len2; ++i)
{
if (tmp2[i]._itemName.empty())
{
::GetMenuString(_mainMenuHandle, tmp2[i]._cmdID, menuName, 64, MF_BYCOMMAND);
tmp2[i]._itemName = purgeMenuItemString(menuName);
}
}
updateCommandShortcuts();
//Translate non-menu shortcuts

View File

@ -518,45 +518,54 @@ BOOL Notepad_plus::notify(SCNotification *notification)
if (!_tabPopupMenu.isCreated())
{
// IMPORTANT: If list below is modified, you have to change the value of tabContextMenuItemPos[] in localization.cpp file
std::vector<MenuItemUnit> itemUnitArray;
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSE, TEXT("Close")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_BUT_CURRENT, TEXT("Close All BUT This"), TEXT("Close Multiple Tabs")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_TOLEFT, TEXT("Close All to the Left"), TEXT("Close Multiple Tabs")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_TORIGHT, TEXT("Close All to the Right"), TEXT("Close Multiple Tabs")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_UNCHANGED, TEXT("Close All Unchanged"), TEXT("Close Multiple Tabs")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_SAVE, TEXT("Save")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_SAVEAS, TEXT("Save As...")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_FOLDER, TEXT("Open Containing Folder in Explorer"), TEXT("Open into")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_CMD, TEXT("Open Containing Folder in cmd"), TEXT("Open into")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CONTAININGFOLDERASWORKSPACE, TEXT("Open Containing Folder as Workspace"), TEXT("Open into")));
itemUnitArray.push_back(MenuItemUnit(0, NULL, TEXT("Open into")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_DEFAULT_VIEWER, TEXT("Open in Default Viewer"), TEXT("Open into")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_RENAME, TEXT("Rename")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_DELETE, TEXT("Move to Recycle Bin")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_RELOAD, TEXT("Reload")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_PRINT, TEXT("Print")));
itemUnitArray.push_back(MenuItemUnit(0, NULL));
itemUnitArray.push_back(MenuItemUnit(0, NULL));
itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_SETREADONLY, TEXT("Read-Only")));
itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_CLEARREADONLY, TEXT("Clear Read-Only Flag")));
itemUnitArray.push_back(MenuItemUnit(0, NULL));
itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_FULLPATHTOCLIP, TEXT("Copy Full File Path"), TEXT("Copy to Clipboard")));
itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_FILENAMETOCLIP, TEXT("Copy Filename"), TEXT("Copy to Clipboard")));
itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_CURRENTDIRTOCLIP, TEXT("Copy Current Dir. Path"), TEXT("Copy to Clipboard")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_GOTO_ANOTHER_VIEW, TEXT("Move to Other View"), TEXT("Move Document")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_CLONE_TO_ANOTHER_VIEW, TEXT("Clone to Other View"), TEXT("Move Document")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_GOTO_NEW_INSTANCE, TEXT("Move to New Instance"), TEXT("Move Document")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_LOAD_IN_NEW_INSTANCE, TEXT("Open in New Instance"), TEXT("Move Document")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_1, TEXT("Apply Color 1"), TEXT("Apply Color to Tab")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_2, TEXT("Apply Color 2"), TEXT("Apply Color to Tab")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_3, TEXT("Apply Color 3"), TEXT("Apply Color to Tab")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_4, TEXT("Apply Color 4"), TEXT("Apply Color to Tab")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_5, TEXT("Apply Color 5"), TEXT("Apply Color to Tab")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_NONE, TEXT("Remove Color"), TEXT("Apply Color to Tab")));
// IMPORTANT: If list above is modified, you have to change the value of tabContextMenuItemPos[] in localization.cpp file
std::vector<MenuItemUnit> itemUnitArray;
NppParameters& nppParam = NppParameters::getInstance();
_tabPopupMenu.create(_pPublicInterface->getHSelf(), itemUnitArray);
if (nppParam.hasCustomTabContextMenu())
{
itemUnitArray = nppParam.getTabContextMenuItems();
}
else // default tab context menu
{
// IMPORTANT: If any submenu entry is added/moved/removed, you have to change the value of tabCmSubMenuEntryPos[] in localization.cpp file
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSE, TEXT("Close")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_BUT_CURRENT, TEXT("Close All BUT This"), TEXT("Close Multiple Tabs")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_TOLEFT, TEXT("Close All to the Left"), TEXT("Close Multiple Tabs")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_TORIGHT, TEXT("Close All to the Right"), TEXT("Close Multiple Tabs")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_UNCHANGED, TEXT("Close All Unchanged"), TEXT("Close Multiple Tabs")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_SAVE, TEXT("Save")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_SAVEAS, TEXT("Save As...")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_FOLDER, TEXT("Open Containing Folder in Explorer"), TEXT("Open into")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_CMD, TEXT("Open Containing Folder in cmd"), TEXT("Open into")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CONTAININGFOLDERASWORKSPACE, TEXT("Open Containing Folder as Workspace"), TEXT("Open into")));
itemUnitArray.push_back(MenuItemUnit(0, NULL, TEXT("Open into")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_DEFAULT_VIEWER, TEXT("Open in Default Viewer"), TEXT("Open into")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_RENAME, TEXT("Rename")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_DELETE, TEXT("Move to Recycle Bin")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_RELOAD, TEXT("Reload")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_PRINT, TEXT("Print")));
itemUnitArray.push_back(MenuItemUnit(0, NULL));
itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_SETREADONLY, TEXT("Read-Only")));
itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_CLEARREADONLY, TEXT("Clear Read-Only Flag")));
itemUnitArray.push_back(MenuItemUnit(0, NULL));
itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_FULLPATHTOCLIP, TEXT("Copy Full File Path"), TEXT("Copy to Clipboard")));
itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_FILENAMETOCLIP, TEXT("Copy Filename"), TEXT("Copy to Clipboard")));
itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_CURRENTDIRTOCLIP, TEXT("Copy Current Dir. Path"), TEXT("Copy to Clipboard")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_GOTO_ANOTHER_VIEW, TEXT("Move to Other View"), TEXT("Move Document")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_CLONE_TO_ANOTHER_VIEW, TEXT("Clone to Other View"), TEXT("Move Document")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_GOTO_NEW_INSTANCE, TEXT("Move to New Instance"), TEXT("Move Document")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_LOAD_IN_NEW_INSTANCE, TEXT("Open in New Instance"), TEXT("Move Document")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_1, TEXT("Apply Color 1"), TEXT("Apply Color to Tab")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_2, TEXT("Apply Color 2"), TEXT("Apply Color to Tab")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_3, TEXT("Apply Color 3"), TEXT("Apply Color to Tab")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_4, TEXT("Apply Color 4"), TEXT("Apply Color to Tab")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_5, TEXT("Apply Color 5"), TEXT("Apply Color to Tab")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_NONE, TEXT("Remove Color"), TEXT("Apply Color to Tab")));
// IMPORTANT: If any submenu entry is added/moved/removed, you have to change the value of tabCmSubMenuEntryPos[] in localization.cpp file
}
_tabPopupMenu.create(_pPublicInterface->getHSelf(), itemUnitArray, _mainMenuHandle);
_nativeLangSpeaker.changeLangTabContextMenu(_tabPopupMenu.getMenuHandle());
}

View File

@ -1390,6 +1390,20 @@ bool NppParameters::load()
isAllLaoded = false;
}
//---------------------------------------------//
// tabContextMenu.xml : for per user, optional //
//---------------------------------------------//
_tabContextMenuPath = _userPath;
pathAppend(_tabContextMenuPath, TEXT("tabContextMenu.xml"));
_pXmlTabContextMenuDocA = new TiXmlDocumentA();
loadOkay = _pXmlTabContextMenuDocA->LoadUnicodeFilePath(_tabContextMenuPath.c_str());
if (!loadOkay)
{
delete _pXmlTabContextMenuDocA;
_pXmlTabContextMenuDocA = nullptr;
}
//----------------------------//
// session.xml : for per user //
//----------------------------//
@ -1478,6 +1492,7 @@ void NppParameters::destroyInstance()
delete _pXmlToolIconsDoc;
delete _pXmlShortcutDoc;
delete _pXmlContextMenuDocA;
delete _pXmlTabContextMenuDocA;
delete _pXmlBlacklistDoc;
delete getInstancePointer();
}
@ -1979,18 +1994,22 @@ int NppParameters::getPluginCmdIdFromMenuEntryItemName(HMENU pluginsMenu, const
return -1;
}
bool NppParameters::getContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU pluginsMenu)
bool NppParameters::getContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU pluginsMenu, bool isEditCM)
{
if (!_pXmlContextMenuDocA)
std::vector<MenuItemUnit>& contextMenuItems = isEditCM ? _contextMenuItems : _tabContextMenuItems;
TiXmlDocumentA* pXmlContextMenuDocA = isEditCM ? _pXmlContextMenuDocA : _pXmlTabContextMenuDocA;
std::string cmName = isEditCM ? "ScintillaContextMenu" : "TabContextMenu";
if (!pXmlContextMenuDocA)
return false;
TiXmlNodeA *root = _pXmlContextMenuDocA->FirstChild("NotepadPlus");
TiXmlNodeA *root = pXmlContextMenuDocA->FirstChild("NotepadPlus");
if (!root)
return false;
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
NativeLangSpeaker* pNativeSpeaker = (NppParameters::getInstance()).getNativeLangSpeaker();
TiXmlNodeA *contextMenuRoot = root->FirstChildElement("ScintillaContextMenu");
TiXmlNodeA *contextMenuRoot = root->FirstChildElement(cmName.c_str());
if (contextMenuRoot)
{
for (TiXmlNodeA *childNode = contextMenuRoot->FirstChildElement("Item");
@ -2015,7 +2034,7 @@ bool NppParameters::getContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU plugins
const char *idStr = (childNode->ToElement())->Attribute("id", &id);
if (idStr)
{
_contextMenuItems.push_back(MenuItemUnit(id, displayAs.c_str(), folderName.c_str()));
contextMenuItems.push_back(MenuItemUnit(id, displayAs.c_str(), folderName.c_str()));
}
else
{
@ -2031,7 +2050,7 @@ bool NppParameters::getContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU plugins
{
int cmd = getCmdIdFromMenuEntryItemName(mainMenuHadle, menuEntryName, menuItemName);
if (cmd != -1)
_contextMenuItems.push_back(MenuItemUnit(cmd, displayAs.c_str(), folderName.c_str()));
contextMenuItems.push_back(MenuItemUnit(cmd, displayAs.c_str(), folderName.c_str()));
}
else
{
@ -2048,7 +2067,7 @@ bool NppParameters::getContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU plugins
{
int pluginCmdId = getPluginCmdIdFromMenuEntryItemName(pluginsMenu, pluginName, pluginCmdName);
if (pluginCmdId != -1)
_contextMenuItems.push_back(MenuItemUnit(pluginCmdId, displayAs.c_str(), folderName.c_str()));
contextMenuItems.push_back(MenuItemUnit(pluginCmdId, displayAs.c_str(), folderName.c_str()));
}
}
}

View File

@ -1552,10 +1552,12 @@ public:
std::vector<int> & getScintillaModifiedKeyIndices() { return _scintillaModifiedKeyIndices; };
void addScintillaModifiedIndex(int index);
std::vector<MenuItemUnit> & getContextMenuItems() { return _contextMenuItems; };
const Session & getSession() const {return _session;};
std::vector<MenuItemUnit>& getContextMenuItems() { return _contextMenuItems; };
std::vector<MenuItemUnit>& getTabContextMenuItems() { return _tabContextMenuItems; };
bool hasCustomContextMenu() const {return !_contextMenuItems.empty();};
bool hasCustomTabContextMenu() const {return !_tabContextMenuItems.empty();};
void setAccelerator(Accelerator *pAccel) {_pAccelerator = pAccel;};
Accelerator * getAccelerator() {return _pAccelerator;};
@ -1628,7 +1630,7 @@ public:
return getPluginCmdsFromXmlTree();
}
bool getContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU pluginsMenu);
bool getContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU pluginsMenu, bool isEditCM = true);
bool reloadContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU pluginsMenu);
winVer getWinVersion() const {return _winVersion;};
generic_string getWinVersionStr() const;
@ -1751,6 +1753,7 @@ private:
TiXmlDocumentA *_pXmlNativeLangDocA = nullptr; // nativeLang.xml
TiXmlDocumentA *_pXmlContextMenuDocA = nullptr; // contextMenu.xml
TiXmlDocumentA *_pXmlTabContextMenuDocA = nullptr; // tabContextMenu.xml
std::vector<TiXmlDocument *> _pXmlExternalLexerDoc; // External lexer plugins' XMLs
@ -1827,12 +1830,13 @@ private:
ThemeSwitcher _themeSwitcher;
//vector<generic_string> _noMenuCmdNames;
std::vector<MenuItemUnit> _contextMenuItems;
std::vector<MenuItemUnit> _tabContextMenuItems;
Session _session;
generic_string _shortcutsPath;
generic_string _contextMenuPath;
generic_string _tabContextMenuPath;
generic_string _sessionPath;
generic_string _nppPath;
generic_string _userPath;

View File

@ -377,57 +377,25 @@ void NativeLangSpeaker::changeMenuLang(HMENU menuHandle)
}
static const std::pair<int, int> tabContextMenuItemPos[] =
static const int tabCmSubMenuEntryPos[] =
{
// +-------------- The item position on the top level of tab context menu
// +-------------- The submenu entry item position on the top level of tab context menu
// |
// | +-------------- The item position in sub-menu of tab context menu. The item is on top level if -1, otherwise it's in the sub-menu
// | |
// | | +--------- Index order (CMID: Context Menu ID) in <TabBar> of english.xml - the number and the order of this array should be synchronized with <TabBar>
// | | |
{0, -1}, // 0: Close
{1, 0}, // 1: Close ALL BUT This
{2, -1}, // 2: Save
{3, -1}, // 3: Save As
{8, -1}, // 4: Print
{14, 0}, // 5: Move to Other View
{14, 1}, // 6: Clone to Other View
{13, 0}, // 7: Copy Full File Path
{13, 1}, // 8: Copy Filename
{13, 2}, // 9: Copy Current Dir. Path
{5, -1}, // 10: Rename
{6, -1}, // 11: Move to Recycle Bin
{10, -1}, // 12: Read-Only
{11, -1}, // 13: Clear Read-Only Flag
{14, 2}, // 14: Move to New Instance
{14, 3}, // 15: Open to New Instance
{7, -1}, // 16: Reload
{1, 1}, // 17: Close ALL to the Left
{1, 2}, // 18: Close ALL to the Right
{4, 0}, // 19: Open Containing Folder in Explorer
{4, 1}, // 20: Open Containing Folder in cmd
{4, 4}, // 21: Open in Default Viewer
{1, 3}, // 22: Close ALL Unchanged
{4, 2}, // 23: Open Containing Folder as Workspace
{15, 0}, // 24: Apply Color
{15, 1}, // 25: Apply Color
{15, 2}, // 26: Apply Color
{15, 3}, // 27: Apply Color
{15, 4}, // 28: Apply Color
{15, 5}, // 29: Remove Color
{1, -1}, // 30: Close Multiple Tabs
{4, -1}, // 31: Open into
{13, -1}, // 32: Copy to Clipboard
{14, -1}, // 33: Move Document
{15, -1}, // Apply Color to Tab
{-1, -1}, //-------End
// | +------- Index order (CMDID: Context Menu submenu entry ID): in <TabBar> of english.xml - the number and the order of this array should be synchronized with <TabBar>
// | |
// | |
// | |
1, // 0 Close Multiple Tabs
4, // 1 Open into
13, // 2 Copy to Clipboard
14, // 3 Move Document
15, // 4 Apply Color to Tab
};
void NativeLangSpeaker::changeLangTabContextMenu(HMENU hCM)
{
if (nullptr != _nativeLangA)
if (_nativeLangA != nullptr)
{
TiXmlNodeA *tabBarMenu = _nativeLangA->FirstChild("Menu");
if (tabBarMenu)
@ -436,37 +404,37 @@ void NativeLangSpeaker::changeLangTabContextMenu(HMENU hCM)
if (tabBarMenu)
{
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
int nbCMItems = sizeof(tabContextMenuItemPos)/sizeof(std::pair<int, int>);
int nbSubEntry = sizeof(tabCmSubMenuEntryPos)/sizeof(int);
for (TiXmlNodeA *childNode = tabBarMenu->FirstChildElement("Item");
childNode ;
childNode = childNode->NextSibling("Item") )
{
TiXmlElementA *element = childNode->ToElement();
int index;
const char *indexStr = element->Attribute("CMID", &index);
if (!indexStr || (index < 0 || index >= nbCMItems-1))
int cmd;
const char *cmdStr = element->Attribute("CMDID", &cmd);
if (!cmdStr || (cmd < 0))
continue;
std::pair<int, int> pos = tabContextMenuItemPos[index];
const char *pName = element->Attribute("name");
if (pName)
{
const wchar_t *pNameW = wmc.char2wchar(pName, _nativeLangEncoding);
if (pos.second == -1) // the 1st level
{
int cmdID = ::GetMenuItemID(hCM, pos.first);
::ModifyMenu(hCM, pos.first, MF_BYPOSITION, cmdID, pNameW);
}
else // it's the sub-menu item
{
HMENU hSubMenu = ::GetSubMenu(hCM, pos.first);
if (!hSubMenu)
continue;
const char* pName = element->Attribute("name");
const wchar_t* pNameW = wmc.char2wchar(pName, _nativeLangEncoding);
int cmdID = ::GetMenuItemID(hSubMenu, pos.second);
::ModifyMenu(hSubMenu, pos.second, MF_BYPOSITION, cmdID, pNameW);
if (cmd > nbSubEntry) // menu item CMD
{
::ModifyMenu(hCM, cmd, MF_BYCOMMAND, cmd, pNameW);
// Here CMDID are default Tab Context Menu commands.
// User can always add any command beyond the default commands in tabContextMenu.xml file.
// But such command won't be translated.
}
else // sub-menu entry id.
{
if (!NppParameters::getInstance().hasCustomTabContextMenu()) // The customized sub-menu entry cannot be translated.
// User can use his/her native language as value of attribute "FolderName" in tabContextMenu.xml file.
{
int subEntryIndex = cmd;
int subEntrypos = tabCmSubMenuEntryPos[subEntryIndex];
::ModifyMenu(hCM, subEntrypos, MF_BYPOSITION, cmd, pNameW);
}
}
}

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
By modifying this file, you can customize your context menu popuped as right clicking on the tab zone.
It may be more convinient to access to your frequent used commands via context menu than via the top menu.
Please check "How to Customize the Context Menu" on:
https://npp-user-manual.org/docs/config-files/#the-context-menu-contextmenu-xml
-->
<NotepadPlus>
<TabContextMenu>
<!--
Use MenuEntryName and MenuItemName to localize your commands to add.
The values should be in English but not in translated language.
(You can set Notepad++ language back to English from Preferences dialog via menu "Settings->Preferences...")
-->
<Item MenuEntryName="File" MenuItemName="Close"/>
<!--
Use FolderName (optional) to create sub-menu. FolderName value can be in any language (French, Japanese...).
-->
<Item FolderName="Close Multiple Tabs" MenuEntryName="File" MenuItemName="Close All but Active Document"/>
<Item FolderName="Close Multiple Tabs" MenuEntryName="File" MenuItemName="Close All to the Left"/>
<Item FolderName="Close Multiple Tabs" MenuEntryName="File" MenuItemName="Close All to the Right"/>
<Item FolderName="Close Multiple Tabs" MenuEntryName="File" MenuItemName="Close All Unchanged"/>
<Item MenuEntryName="File" MenuItemName="Save"/>
<Item MenuEntryName="File" MenuItemName="Save As..."/>
<Item FolderName="Open into" MenuEntryName="File" MenuItemName="Explorer"/>
<Item FolderName="Open into" MenuEntryName="File" MenuItemName="cmd"/>
<Item FolderName="Open into" MenuEntryName="File" MenuItemName="Folder as Workspace"/>
<Item FolderName="Open into" id="0"/>
<Item FolderName="Open into" MenuEntryName="File" MenuItemName="Open in Default Viewer"/>
<Item MenuEntryName="File" MenuItemName="Rename..."/>
<Item MenuEntryName="File" MenuItemName="Reload from Disk"/>
<Item MenuEntryName="File" MenuItemName="Print..."/>
<!-- id="0" is the separator -->
<Item id="0"/>
<Item MenuEntryName="Edit" MenuItemName="Set Read-Only"/>
<Item MenuEntryName="Edit" MenuItemName="Clear Read-Only Flag"/>
<Item id="0"/>
<Item FolderName="Copy to Clipboard" MenuEntryName="Edit" MenuItemName="Copy Current Full File Path"/>
<Item FolderName="Copy to Clipboard" MenuEntryName="Edit" MenuItemName="Copy Current Filename"/>
<Item FolderName="Copy to Clipboard" MenuEntryName="Edit" MenuItemName="Copy Current Dir. Path"/>
<Item FolderName="Move Document" MenuEntryName="View" MenuItemName="Move to Other View"/>
<Item FolderName="Move Document" MenuEntryName="View" MenuItemName="Clone to Other View"/>
<Item FolderName="Move Document" MenuEntryName="View" MenuItemName="Move to New Instance"/>
<Item FolderName="Move Document" MenuEntryName="View" MenuItemName="Open in New Instance"/>
<Item FolderName="Apply Color to Tab" MenuEntryName="View" MenuItemName="Apply Color 1"/>
<Item FolderName="Apply Color to Tab" MenuEntryName="View" MenuItemName="Apply Color 2"/>
<Item FolderName="Apply Color to Tab" MenuEntryName="View" MenuItemName="Apply Color 3"/>
<Item FolderName="Apply Color to Tab" MenuEntryName="View" MenuItemName="Apply Color 4"/>
<Item FolderName="Apply Color to Tab" MenuEntryName="View" MenuItemName="Apply Color 5"/>
<Item FolderName="Apply Color to Tab" MenuEntryName="View" MenuItemName="Remove Color"/>
</TabContextMenu>
</NotepadPlus>