[NEW_FEATURE] Add a new capacity in context menu: the commands can be in the sub-menu.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@690 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2010-10-30 11:25:17 +00:00
parent a86096b84b
commit 25755fd810
6 changed files with 141 additions and 67 deletions

View File

@ -446,7 +446,7 @@ LRESULT Notepad_plus::init(HWND hwnd)
//Windows menu
_windowsMenu.init(_pPublicInterface->getHinst(), _mainMenuHandle, windowTrans.c_str());
// Update context menu strings
// Update context menu strings (translated)
vector<MenuItemUnit> & tmp = pNppParam->getContextMenuItems();
size_t len = tmp.size();
TCHAR menuName[64];

View File

@ -1376,11 +1376,12 @@ bool NppParameters::getContextMenuFromXmlTree(HMENU mainMenuHadle)
childNode ;
childNode = childNode->NextSibling(TEXT("Item")) )
{
const TCHAR *folderName = (childNode->ToElement())->Attribute(TEXT("FolderName"));
int id;
const TCHAR *idStr = (childNode->ToElement())->Attribute(TEXT("id"), &id);
if (idStr)
{
_contextMenuItems.push_back(MenuItemUnit(id, TEXT("")));
_contextMenuItems.push_back(MenuItemUnit(id, TEXT(""), folderName));
}
else
{
@ -1419,7 +1420,7 @@ bool NppParameters::getContextMenuFromXmlTree(HMENU mainMenuHadle)
if (generic_stricmp(menuItemName, purgeMenuItemString(cmdStr).c_str()) == 0)
{
int cmdId = ::GetMenuItemID(currMenu, currMenuPos);
_contextMenuItems.push_back(MenuItemUnit(cmdId, TEXT("")));
_contextMenuItems.push_back(MenuItemUnit(cmdId, TEXT(""), folderName));
break;
}
@ -1466,7 +1467,7 @@ bool NppParameters::getContextMenuFromXmlTree(HMENU mainMenuHadle)
if (generic_stricmp(pluginCmdName, purgeMenuItemString(pluginCmdStr).c_str()) == 0)
{
int pluginCmdId = ::GetMenuItemID(pluginMenu, j);
_contextMenuItems.push_back(MenuItemUnit(pluginCmdId, TEXT("")));
_contextMenuItems.push_back(MenuItemUnit(pluginCmdId, TEXT(""), folderName));
break;
}
}

View File

@ -0,0 +1,103 @@
/*
this file is part of notepad++
Copyright (C)2010 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.
*/
#include "precompiledHeaders.h"
#include "ContextMenu.h"
MenuItemUnit::MenuItemUnit(unsigned long cmdID, const TCHAR *itemName, const TCHAR *parentFolderName) : _cmdID(cmdID)
{
if (!itemName)
_itemName = TEXT("");
else
_itemName = itemName;
if (!parentFolderName)
_parentFolderName = TEXT("");
else
_parentFolderName = parentFolderName;
}
ContextMenu::~ContextMenu()
{
if (isCreated())
{
for (size_t i = 0 ; i < _subMenus.size() ; i++)
::DestroyMenu(_subMenus[i]);
::DestroyMenu(_hMenu);
}
}
void ContextMenu::create(HWND hParent, const vector<MenuItemUnit> & menuItemArray)
{
_hParent = hParent;
_hMenu = ::CreatePopupMenu();
bool lastIsSep = false;
HMENU hParentFolder = NULL;
generic_string currentParentFolderStr = TEXT("");
int j = 0;
for (size_t i = 0 ; i < menuItemArray.size() ; i++)
{
const MenuItemUnit & item = menuItemArray[i];
if (item._parentFolderName == TEXT(""))
{
currentParentFolderStr = TEXT("");
hParentFolder = NULL;
j = 0;
}
else
{
if (item._parentFolderName != currentParentFolderStr)
{
currentParentFolderStr = item._parentFolderName;
hParentFolder = ::CreateMenu();
j = 0;
_subMenus.push_back(hParentFolder);
::InsertMenu(_hMenu, 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 == menuItemArray.size() - 1) && item._cmdID == 0)
{
lastIsSep = true;
}
else if (item._cmdID != 0)
{
::InsertMenu(_hMenu, i, flag, item._cmdID, item._itemName.c_str());
lastIsSep = false;
}
else if (item._cmdID == 0 && !lastIsSep)
{
::InsertMenu(_hMenu, i, flag, item._cmdID, item._itemName.c_str());
lastIsSep = true;
}
else // last item is separator and current item is separator
{
lastIsSep = true;
}
}
}

View File

@ -1,6 +1,6 @@
/*
this file is part of notepad++
Copyright (C)2003 Don HO ( donho@altern.org )
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
@ -25,56 +25,19 @@ using namespace std;
struct MenuItemUnit {
unsigned long _cmdID;
generic_string _itemName;
generic_string _subMenuName;
MenuItemUnit() : _cmdID(0), _itemName(TEXT("")), _subMenuName(TEXT("")) {};
MenuItemUnit(unsigned long cmdID, generic_string itemName, generic_string subMenuName=TEXT("")) : _cmdID(cmdID), _itemName(itemName), _subMenuName(subMenuName) {};
MenuItemUnit(unsigned long cmdID, const TCHAR *itemName, const TCHAR *subMenuName=NULL) : _cmdID(cmdID){
if (!itemName)
_itemName = TEXT("");
else
_itemName = itemName;
if (!subMenuName)
_subMenuName = TEXT("");
else
_subMenuName = subMenuName;
};
generic_string _parentFolderName;
MenuItemUnit() : _cmdID(0), _itemName(TEXT("")), _parentFolderName(TEXT("")){};
MenuItemUnit(unsigned long cmdID, generic_string itemName, generic_string parentFolderName=TEXT(""))
: _cmdID(cmdID), _itemName(itemName), _parentFolderName(parentFolderName){};
MenuItemUnit(unsigned long cmdID, const TCHAR *itemName, const TCHAR *parentFolderName=NULL);
};
class ContextMenu {
public:
ContextMenu() : _hParent(NULL), _hMenu(NULL) {};
~ContextMenu() {
if (isCreated())
::DestroyMenu(_hMenu);
};
void create(HWND hParent, const vector<MenuItemUnit> & menuItemArray) {
_hParent = hParent;
_hMenu = ::CreatePopupMenu();
bool lastIsSep = false;
for (size_t i = 0 ; i < menuItemArray.size() ; i++)
{
unsigned int flag = MF_BYPOSITION | ((menuItemArray[i]._cmdID == 0)?MF_SEPARATOR:0);
if ((i == 0 || i == menuItemArray.size() - 1) && menuItemArray[i]._cmdID == 0)
{
lastIsSep = true;
}
else if (menuItemArray[i]._cmdID != 0)
{
::InsertMenu(_hMenu, i, flag, menuItemArray[i]._cmdID, menuItemArray[i]._itemName.c_str());
lastIsSep = false;
}
else if (menuItemArray[i]._cmdID == 0 && !lastIsSep)
{
::InsertMenu(_hMenu, i, flag, menuItemArray[i]._cmdID, menuItemArray[i]._itemName.c_str());
lastIsSep = true;
}
else // last item is separator and current item is separator
{
lastIsSep = true;
}
}
};
~ContextMenu();
void create(HWND hParent, const vector<MenuItemUnit> & menuItemArray);
bool isCreated() const {return _hMenu != NULL;};
void display(const POINT & p) const {
@ -97,6 +60,7 @@ public:
private:
HWND _hParent;
HMENU _hMenu;
vector<HMENU> _subMenus;
};

View File

@ -19,24 +19,26 @@ http://sourceforge.net/apps/mediawiki/notepad-plus/index.php?title=Context_Menu
<!-- You can use command id to add the commands you want.
Check english.xml to get commands id:
http://notepad-plus.svn.sourceforge.net/viewvc/notepad-plus/trunk/PowerEditor/installer/nativeLang/english.xml
Use FolderName (optional) to create sub-menu. FolderName can be used in any item.
-->
<Item id="43022"/>
<Item id="43024"/>
<Item id="43026"/>
<Item id="43028"/>
<Item id="43030"/>
<Item id="0"/>
<Item id="43023"/>
<Item id="43025"/>
<Item id="43027"/>
<Item id="43029"/>
<Item id="43031"/>
<Item id="43032"/>
<Item FolderName="Style token" id="43022"/>
<Item FolderName="Style token" id="43024"/>
<Item FolderName="Style token" id="43026"/>
<Item FolderName="Style token" id="43028"/>
<Item FolderName="Style token" id="43030"/>
<Item FolderName="Remove style" id="43023"/>
<Item FolderName="Remove style" id="43025"/>
<Item FolderName="Remove style" id="43027"/>
<Item FolderName="Remove style" id="43029"/>
<Item FolderName="Remove style" id="43031"/>
<Item FolderName="Remove style" id="43032"/>
<Item id="0"/>
<!-- To add plugin commands, you have to use PluginEntryName and PluginCommandItemName to localize the plugin commands -->
<Item PluginEntryName="MIME Tools" PluginCommandItemName="Base64 Encode"/>
<Item PluginEntryName="MIME Tools" PluginCommandItemName="Base64 Decode"/>
<Item PluginEntryName="NppExport" PluginCommandItemName="Copy all formats to clipboard"/>
<Item FolderName="Plugin commands" PluginEntryName="MIME Tools" PluginCommandItemName="Base64 Encode"/>
<Item FolderName="Plugin commands" PluginEntryName="MIME Tools" PluginCommandItemName="Base64 Decode"/>
<Item FolderName="Plugin commands" PluginEntryName="NppExport" PluginCommandItemName="Copy all formats to clipboard"/>
<Item id="0"/>
<Item MenuEntryName="Edit" MenuItemName="UPPERCASE"/>

View File

@ -434,6 +434,10 @@
RelativePath="..\src\MISC\Common\Common.cpp"
>
</File>
<File
RelativePath="..\src\WinControls\ContextMenu\ContextMenu.cpp"
>
</File>
<File
RelativePath="..\src\WinControls\TabBar\ControlsTab.cpp"
>
@ -892,11 +896,11 @@
>
</File>
<File
RelativePath="..\src\resource.h"
RelativePath="..\src\WinControls\Preference\resource.h"
>
</File>
<File
RelativePath="..\src\WinControls\Preference\resource.h"
RelativePath="..\src\resource.h"
>
</File>
<File