Bug 94345 -- remove unused native context menu. r=pavlov, sr=blizzard.

This commit is contained in:
bryner%netscape.com 2001-08-10 00:58:52 +00:00
Родитель ebd2e13b32
Коммит d3a3edda15
14 изменённых файлов: 0 добавлений и 2867 удалений

Просмотреть файл

@ -28,6 +28,5 @@ nsIMenuItem.h
nsIPopUpMenu.h
nsIKeyBindMgr.h
nsStringUtil.h
nsIContextMenu.h
nsWidgetAtoms.h
nsWidgetAtomList.h

Просмотреть файл

@ -63,7 +63,6 @@ EXPORTS = \
nsIFontNameIterator.h \
nsIFontSizeIterator.h \
nsIFontRetrieverService.h \
nsIContextMenu.h \
nsIDragSessionGTK.h \
nsIDragSessionXlib.h \
nsIDragSessionMac.h \

Просмотреть файл

@ -70,7 +70,6 @@ EXPORTS=\
nsIMenuBar.h \
nsIMenu.h \
nsIMenuItem.h \
nsIContextMenu.h \
nsIPopUpMenu.h \
$(NULL)

Просмотреть файл

@ -1,147 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsIContextMenu_h__
#define nsIContextMenu_h__
#include "nsISupports.h"
#include "nsString.h"
#include "nsIDOMNode.h"
#include "nsIDOMElement.h"
#include "nsIWebShell.h"
class nsIMenuBar;
class nsIMenu;
class nsIMenuItem;
class nsIMenuListener;
// {ab6cea80-00ff-11d5-bb6f-f432a43ead7c}
#define NS_ICONTEXTMENU_IID \
{ 0xab6cea80, 0x00ff, 0x11d5, \
{ 0xbb, 0x6f, 0xf4, 0x32, 0xa4, 0x3e, 0xad, 0x7c } };
/**
* Menu widget
*/
class nsIContextMenu : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICONTEXTMENU_IID)
/**
* Creates the context menu
*
*/
NS_IMETHOD Create(nsISupports * aParent, const nsString& anAlignment, const nsString& anAnchorAlignment) = 0;
/**
* Get the context menu's Parent
*
*/
NS_IMETHOD GetParent(nsISupports *&aParent) = 0;
/**
* Adds a context menu Item
*
*/
NS_IMETHOD AddItem(nsISupports* aItem) = 0;
/**
* Adds a separator
*
*/
NS_IMETHOD AddSeparator() = 0;
/**
* Returns the number of context menu items
* This does count separators as items
*/
NS_IMETHOD GetItemCount(PRUint32 &aCount) = 0;
/**
* Returns a Menu or Menu Item at a specified Index
*
*/
NS_IMETHOD GetItemAt(const PRUint32 aPos, nsISupports *& aMenuItem) = 0;
/**
* Inserts a Menu Item at a specified Index
*
*/
NS_IMETHOD InsertItemAt(const PRUint32 aPos, nsISupports * aMenuItem) = 0;
/**
* Removes an Menu Item from a specified Index
*
*/
NS_IMETHOD RemoveItem(const PRUint32 aPos) = 0;
/**
* Removes all the Menu Items
*
*/
NS_IMETHOD RemoveAll() = 0;
/**
* Gets Native MenuHandle
*
*/
NS_IMETHOD GetNativeData(void** aData) = 0;
/**
* Adds menu listener for dynamic construction
*
*/
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener) = 0;
/**
* Removes menu listener for dynamic construction
*
*/
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener) = 0;
/**
* Set location
*
*/
NS_IMETHOD SetLocation(PRInt32 aX, PRInt32 aY) = 0;
/**
* Set DOMNode
*
*/
NS_IMETHOD SetDOMNode(nsIDOMNode * aMenuNode) = 0;
/**
* Set DOMElement
*
*/
NS_IMETHOD SetDOMElement(nsIDOMElement * aMenuElement) = 0;
/**
* Set WebShell
*
*/
NS_IMETHOD SetWebShell(nsIWebShell * aWebShell) = 0;
};
#endif

Просмотреть файл

@ -1,747 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include <gtk/gtk.h>
#include "nsContextMenu.h"
#include "nsIComponentManager.h"
#include "nsIDOMElement.h"
#include "nsIDOMNode.h"
#include "nsIMenuBar.h"
#include "nsIMenuItem.h"
#include "nsIMenuListener.h"
#include "nsString.h"
#include "nsGtkEventHandler.h"
#include "nsCOMPtr.h"
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
static NS_DEFINE_CID(kMenuItemCID, NS_MENUITEM_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
//-------------------------------------------------------------------------
nsresult nsContextMenu::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
if (aIID.Equals(NS_GET_IID(nsIMenu))) {
*aInstancePtr = (void*)(nsIMenu*) this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIMenu*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsIMenuListener))) {
*aInstancePtr = (void*)(nsIMenuListener*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
//-------------------------------------------------------------------------
NS_IMPL_ADDREF(nsContextMenu)
NS_IMPL_RELEASE(nsContextMenu)
//-------------------------------------------------------------------------
//
// nsContextMenu constructor
//
//-------------------------------------------------------------------------
nsContextMenu::nsContextMenu()
{
NS_INIT_REFCNT();
mNumMenuItems = 0;
mMenu = nsnull;
mParent = nsnull;
mListener = nsnull;
mConstructCalled = PR_FALSE;
mDOMNode = nsnull;
mWebShell = nsnull;
mDOMElement = nsnull;
mAlignment = "topleft";
mAnchorAlignment = "none";
}
//-------------------------------------------------------------------------
//
// nsContextMenu destructor
//
//-------------------------------------------------------------------------
nsContextMenu::~nsContextMenu()
{
}
//-------------------------------------------------------------------------
//
// Create the proper widget
//
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::Create(nsISupports *aParent,
const nsString& anAlignment,
const nsString& anAnchorAlignment)
{
if(aParent)
{
nsIWidget *parent = nsnull;
aParent->QueryInterface(NS_GET_IID(nsIWidget), (void**) &parent);
if(parent)
{
mParent = parent;
NS_RELEASE(parent);
}
}
mAlignment = anAlignment;
mAnchorAlignment = anAnchorAlignment;
mMenu = gtk_menu_new();
gtk_signal_connect (GTK_OBJECT (mMenu), "map",
GTK_SIGNAL_FUNC(menu_map_handler),
this);
gtk_signal_connect (GTK_OBJECT (mMenu), "unmap",
GTK_SIGNAL_FUNC(menu_unmap_handler),
this);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetParent(nsISupports*& aParent)
{
aParent = nsnull;
if (nsnull != mParent) {
return mParent->QueryInterface(kISupportsIID,
(void**)&aParent);
}
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddItem(nsISupports * aItem)
{
if(aItem)
{
nsIMenuItem * menuitem = nsnull;
aItem->QueryInterface(NS_GET_IID(nsIMenuItem),
(void**)&menuitem);
if(menuitem)
{
AddMenuItem(menuitem); // nsMenu now owns this
NS_RELEASE(menuitem);
}
else
{
nsIMenu * menu = nsnull;
aItem->QueryInterface(NS_GET_IID(nsIMenu),
(void**)&menu);
if(menu)
{
AddMenu(menu); // nsMenu now owns this
NS_RELEASE(menu);
}
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddMenuItem(nsIMenuItem * aMenuItem)
{
GtkWidget *widget;
void *voidData;
aMenuItem->GetNativeData(voidData);
widget = GTK_WIDGET(voidData);
gtk_menu_shell_append (GTK_MENU_SHELL (mMenu), widget);
// XXX add aMenuItem to internal data structor list
// Need to be adding an nsISupports *, not nsIMenuItem *
nsISupports * supports = nsnull;
aMenuItem->QueryInterface(kISupportsIID,
(void**)&supports);
{
mMenuItemVoidArray.AppendElement(supports);
mNumMenuItems++;
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddMenu(nsIMenu * aMenu)
{
nsString Label;
GtkWidget *newmenu=nsnull;
char *labelStr;
void *voidData=NULL;
aMenu->GetLabel(Label);
labelStr = Label.ToNewCString();
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuItemCID,
nsnull,
NS_GET_IID(nsIMenuItem),
(void**)&pnsMenuItem);
if (NS_OK == rv) {
nsISupports * supports = nsnull;
QueryInterface(kISupportsIID, (void**) &supports);
pnsMenuItem->Create(supports, labelStr, PR_FALSE); //PR_TRUE);
NS_RELEASE(supports);
pnsMenuItem->QueryInterface(kISupportsIID, (void**) &supports);
AddItem(supports); // Parent should now own menu item
NS_RELEASE(supports);
void * menuitem = nsnull;
pnsMenuItem->GetNativeData(menuitem);
voidData = NULL;
aMenu->GetNativeData(&voidData);
newmenu = GTK_WIDGET(voidData);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), newmenu);
NS_RELEASE(pnsMenuItem);
}
nsCRT::free(labelStr);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddSeparator()
{
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(
kMenuItemCID, nsnull, NS_GET_IID(nsIMenuItem), (void**)&pnsMenuItem);
if (NS_OK == rv) {
nsString tmp = "separator";
nsISupports * supports = nsnull;
QueryInterface(kISupportsIID, (void**) &supports);
pnsMenuItem->Create(supports, tmp, PR_TRUE);
NS_RELEASE(supports);
pnsMenuItem->QueryInterface(kISupportsIID, (void**) &supports);
AddItem(supports); // Parent should now own menu item
NS_RELEASE(supports);
NS_RELEASE(pnsMenuItem);
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetItemCount(PRUint32 &aCount)
{
// this should be right.. does it need to be +1 ?
aCount = g_list_length(GTK_MENU_SHELL(mMenu)->children);
//g_print("nsMenu::GetItemCount = %i\n", aCount);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetItemAt(const PRUint32 aCount, nsISupports *& aMenuItem)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::InsertItemAt(const PRUint32 aCount, nsISupports * aMenuItem)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::InsertSeparator(const PRUint32 aCount)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::RemoveItem(const PRUint32 aCount)
{
#if 0
// this may work here better than Removeall(), but i'm not sure how to test this one
nsISupports *item = mMenuItemVoidArray[aPos];
delete item;
mMenuItemVoidArray.RemoveElementAt(aPos);
#endif
/*
gtk_menu_shell_remove (GTK_MENU_SHELL (mMenu), item);
nsCRT::free(labelStr);
voidData = NULL;
aMenu->GetNativeData(&voidData);
newmenu = GTK_WIDGET(voidData);
gtk_menu_item_remove_submenu (GTK_MENU_ITEM (item));
*/
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::RemoveAll()
{
//g_print("nsMenu::RemoveAll()\n");
#undef DEBUG_pavlov
#ifdef DEBUG_pavlov
// this doesn't work quite right, but this is about all that should really be needed
int i=0;
nsIMenu *menu = nsnull;
nsIMenuItem *menuitem = nsnull;
nsISupports *item = nsnull;
for (i=mMenuItemVoidArray.Count(); i>0; i--)
{
item = (nsISupports*)mMenuItemVoidArray[i-1];
if(nsnull != item)
{
if (NS_OK == item->QueryInterface(NS_GET_IID(nsIMenuItem), (void**)&menuitem))
{
// we do this twice because we have to do it once for QueryInterface,
// then we want to get rid of it.
// g_print("remove nsMenuItem\n");
NS_RELEASE(menuitem);
NS_RELEASE(item);
menuitem = nsnull;
} else if (NS_OK == item->QueryInterface(NS_GET_IID(nsIMenu), (void**)&menu)) {
#ifdef NOISY_MENUS
g_print("remove nsMenu\n");
#endif
NS_RELEASE(menu);
NS_RELEASE(item);
menu = nsnull;
}
// mMenuItemVoidArray.RemoveElementAt(i-1);
}
}
mMenuItemVoidArray.Clear();
return NS_OK;
#else
for (int i = mMenuItemVoidArray.Count(); i > 0; i--) {
if(nsnull != mMenuItemVoidArray[i-1]) {
nsIMenuItem * menuitem = nsnull;
((nsISupports*)mMenuItemVoidArray[i-1])->QueryInterface(NS_GET_IID(nsIMenuItem),
(void**)&menuitem);
if(menuitem) {
void *gtkmenuitem = nsnull;
menuitem->GetNativeData(gtkmenuitem);
if (gtkmenuitem) {
gtk_widget_ref(GTK_WIDGET(gtkmenuitem));
//gtk_widget_destroy(GTK_WIDGET(gtkmenuitem));
#ifdef DEBUG
g_print("%p, %p\n",
GTK_WIDGET(GTK_CONTAINER(GTK_MENU_SHELL(GTK_MENU(mMenu)))),
GTK_WIDGET(GTK_WIDGET(gtkmenuitem)->parent));
#endif
gtk_container_remove(GTK_CONTAINER(GTK_MENU_SHELL(GTK_MENU(mMenu))),
GTK_WIDGET(gtkmenuitem));
}
} else {
nsIMenu * menu= nsnull;
((nsISupports*)mMenuItemVoidArray[i-1])->QueryInterface(NS_GET_IID(nsIMenu),
(void**)&menu);
if(menu)
{
void * gtkmenu = nsnull;
menu->GetNativeData(&gtkmenu);
if(gtkmenu){
#ifdef DEBUG
g_print("nsMenu::RemoveAll() trying to remove nsMenu");
#endif
//gtk_menu_item_remove_submenu (GTK_MENU_ITEM (item));
}
}
}
}
}
//g_print("end RemoveAll\n");
return NS_OK;
#endif
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetNativeData(void ** aData)
{
*aData = (void *)mMenu;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddMenuListener(nsIMenuListener * aMenuListener)
{
mListener = aMenuListener;
NS_ADDREF(mListener);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::RemoveMenuListener(nsIMenuListener * aMenuListener)
{
if (aMenuListener == mListener) {
NS_IF_RELEASE(mListener);
}
return NS_OK;
}
//-------------------------------------------------------------------------
// nsIMenuListener interface
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
if (nsnull != mListener) {
mListener->MenuSelected(aMenuEvent);
}
return nsEventStatus_eIgnore;
}
void menu_popup_position(GtkMenu *menu,
gint *x,
gint *y,
gpointer data)
{
nsContextMenu *cm = (nsContextMenu*)data;
*x = cm->GetX();
*y = cm->GetY();
}
nsEventStatus nsContextMenu::MenuSelected(const nsMenuEvent & aMenuEvent)
{
MenuConstruct(aMenuEvent,
mParent,
mDOMNode,
mWebShell);
//GtkWidget *parent = GTK_WIDGET(mParent->GetNativeData(NS_NATIVE_WIDGET));
gtk_menu_popup (GTK_MENU(mMenu),
(GtkWidget*)nsnull, (GtkWidget*)nsnull,
menu_popup_position,
this, 1, GDK_CURRENT_TIME);
/*
if (nsnull != mListener) {
mListener->MenuSelected(aMenuEvent);
}
*/
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsIMenuItem * nsContextMenu::FindMenuItem(nsIContextMenu * aMenu, PRUint32 aId)
{
return nsnull;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuDeselected(const nsMenuEvent & aMenuEvent)
{
if (nsnull != mListener) {
mListener->MenuDeselected(aMenuEvent);
}
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuConstruct(const nsMenuEvent &aMenuEvent,
nsIWidget *aParentWindow,
void *menuNode,
void *aWebShell)
{
//g_print("nsMenu::MenuConstruct called \n");
if(menuNode){
SetDOMNode((nsIDOMNode*)menuNode);
}
if(!aWebShell){
aWebShell = mWebShell;
}
// First open the menu.
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode);
if (domElement)
domElement->SetAttribute("open", "true");
// Begin menuitem inner loop
nsCOMPtr<nsIDOMNode> menuitemNode;
((nsIDOMNode*)mDOMNode)->GetFirstChild(getter_AddRefs(menuitemNode));
unsigned short menuIndex = 0;
while (menuitemNode) {
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
if (menuitemElement) {
nsString menuitemNodeType;
nsString menuitemName;
menuitemElement->GetNodeName(menuitemNodeType);
if (menuitemNodeType.Equals("menuitem")) {
// LoadMenuItem
LoadMenuItem(this,
menuitemElement,
menuitemNode,
menuIndex,
(nsIWebShell*)aWebShell);
} else if (menuitemNodeType.Equals("separator")) {
AddSeparator();
} else if (menuitemNodeType.Equals("menu")) {
// Load a submenu
LoadSubMenu(this, menuitemElement, menuitemNode);
}
}
++menuIndex;
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
} // end menu item innner loop
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuDestruct(const nsMenuEvent & aMenuEvent)
{
// Close the node.
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mDOMNode);
if (domElement)
domElement->RemoveAttribute("open");
//g_print("nsMenu::MenuDestruct called \n");
mConstructCalled = PR_FALSE;
RemoveAll();
return nsEventStatus_eIgnore;
}
//----------------------------------------
void nsContextMenu::LoadMenuItem(nsIMenu *pParentMenu,
nsIDOMElement *menuitemElement,
nsIDOMNode *menuitemNode,
unsigned short menuitemIndex,
nsIWebShell *aWebShell)
{
static const char* NS_STRING_TRUE = "true";
nsString disabled;
nsString menuitemName;
nsString menuitemCmd;
menuitemElement->GetAttribute(nsAutoString("disabled"), disabled);
menuitemElement->GetAttribute(nsAutoString("name"), menuitemName);
menuitemElement->GetAttribute(nsAutoString("cmd"), menuitemCmd);
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuItemCID,
nsnull,
NS_GET_IID(nsIMenuItem),
(void**)&pnsMenuItem);
if (NS_OK == rv) {
pnsMenuItem->Create(pParentMenu, menuitemName, PR_FALSE);
nsISupports * supports = nsnull;
pnsMenuItem->QueryInterface(kISupportsIID, (void**) &supports);
pParentMenu->AddItem(supports); // Parent should now own menu item
NS_RELEASE(supports);
if(disabled == NS_STRING_TRUE) {
pnsMenuItem->SetEnabled(PR_FALSE);
}
// Create MenuDelegate - this is the intermediator inbetween
// the DOM node and the nsIMenuItem
// The nsWebShellWindow wacthes for Document changes and then notifies the
// the appropriate nsMenuDelegate object
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(menuitemNode));
if (!domElement) {
//return NS_ERROR_FAILURE;
return;
}
nsAutoString cmdAtom("onclick");
nsString cmdName;
domElement->GetAttribute(cmdAtom, cmdName);
pnsMenuItem->SetCommand(cmdName);
// DO NOT use passed in webshell because of messed up windows dynamic loading
// code.
pnsMenuItem->SetWebShell(mWebShell);
pnsMenuItem->SetDOMElement(domElement);
NS_RELEASE(pnsMenuItem);
}
return;
}
//----------------------------------------
void nsContextMenu::LoadSubMenu(nsIMenu *pParentMenu,
nsIDOMElement *menuElement,
nsIDOMNode *menuNode)
{
nsString menuName;
menuElement->GetAttribute(nsAutoString("name"), menuName);
//printf("Creating Menu [%s] \n", menuName.ToNewCString()); // this leaks
// Create nsMenu
nsIMenu * pnsMenu = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuCID,
nsnull,
NS_GET_IID(nsIMenu),
(void**)&pnsMenu);
if (NS_OK == rv) {
// Call Create
nsISupports * supports = nsnull;
pParentMenu->QueryInterface(kISupportsIID, (void**) &supports);
pnsMenu->Create(supports, menuName);
NS_RELEASE(supports); // Balance QI
// Set nsMenu Name
pnsMenu->SetLabel(menuName);
supports = nsnull;
pnsMenu->QueryInterface(kISupportsIID, (void**) &supports);
pParentMenu->AddItem(supports); // parent takes ownership
NS_RELEASE(supports);
pnsMenu->SetWebShell(mWebShell);
pnsMenu->SetDOMNode(menuNode);
/*
// Begin menuitem inner loop
unsigned short menuIndex = 0;
nsCOMPtr<nsIDOMNode> menuitemNode;
menuNode->GetFirstChild(getter_AddRefs(menuitemNode));
while (menuitemNode) {
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
if (menuitemElement) {
nsString menuitemNodeType;
menuitemElement->GetNodeName(menuitemNodeType);
#ifdef DEBUG_saari
printf("Type [%s] %d\n", menuitemNodeType.ToNewCString(), menuitemNodeType.Equals("separator"));
#endif
if (menuitemNodeType.Equals("menuitem")) {
// Load a menuitem
LoadMenuItem(pnsMenu, menuitemElement, menuitemNode, menuIndex, mWebShell);
} else if (menuitemNodeType.Equals("separator")) {
pnsMenu->AddSeparator();
} else if (menuitemNodeType.Equals("menu")) {
// Add a submenu
LoadSubMenu(pnsMenu, menuitemElement, menuitemNode);
}
}
++menuIndex;
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
} // end menu item innner loop
*/
}
}
//----------------------------------------
void nsContextMenu::LoadMenuItem(nsIContextMenu *pParentMenu,
nsIDOMElement *menuitemElement,
nsIDOMNode *menuitemNode,
unsigned short menuitemIndex,
nsIWebShell *aWebShell)
{
}
//----------------------------------------
void nsContextMenu::LoadSubMenu(nsIContextMenu *pParentMenu,
nsIDOMElement *menuElement,
nsIDOMNode *menuNode)
{
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::SetLocation(PRInt32 aX, PRInt32 aY)
{
mX = aX;
mY = aY;
return NS_OK;
}
// local methods
gint nsContextMenu::GetX(void)
{
return mX;
}
gint nsContextMenu::GetY(void)
{
return mY;
}
// end silly local methods
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::SetDOMNode(nsIDOMNode *aMenuNode)
{
mDOMNode = aMenuNode;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::SetDOMElement(nsIDOMElement *aMenuElement)
{
mDOMElement = aMenuElement;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::SetWebShell(nsIWebShell *aWebShell)
{
mWebShell = aWebShell;
return NS_OK;
}

Просмотреть файл

@ -1,139 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsContextMenu_h__
#define nsContextMenu_h__
#include "nsIContextMenu.h"
#include "nsISupportsArray.h"
#include "nsVoidArray.h"
#include "nsIDOMElement.h"
#include "nsIWebShell.h"
class nsIMenuListener;
/**
* Native Win32 button wrapper
*/
class nsContextMenu : public nsIContextMenu, public nsIMenuListener
{
public:
nsContextMenu();
virtual ~nsContextMenu();
NS_DECL_ISUPPORTS
//nsIMenuListener interface
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuConstruct(const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menubarNode,
void * aWebShell);
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
// nsIMenu Methods
NS_IMETHOD Create(nsISupports * aParent,
const nsString& anAlignment,
const nsString& aAnchorAlign);
NS_IMETHOD GetParent(nsISupports *&aParent);
NS_IMETHOD AddItem(nsISupports * aItem);
NS_IMETHOD AddSeparator();
NS_IMETHOD GetItemCount(PRUint32 &aCount);
NS_IMETHOD GetItemAt(const PRUint32 aPos, nsISupports *& aMenuItem);
NS_IMETHOD InsertItemAt(const PRUint32 aPos, nsISupports * aMenuItem);
NS_IMETHOD RemoveItem(const PRUint32 aPos);
NS_IMETHOD RemoveAll();
NS_IMETHOD GetNativeData(void** aData);
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener);
//
NS_IMETHOD AddMenuItem(nsIMenuItem * aMenuItem);
NS_IMETHOD AddMenu(nsIMenu * aMenu);
NS_IMETHOD InsertSeparator(const PRUint32 aCount);
NS_IMETHOD SetDOMNode(nsIDOMNode * menuNode);
NS_IMETHOD SetDOMElement(nsIDOMElement * menuElement);
NS_IMETHOD SetWebShell(nsIWebShell * aWebShell);
NS_IMETHOD SetLocation(PRInt32 aX, PRInt32 aY);
gint GetX(void);
gint GetY(void);
protected:
nsIMenuBar * GetMenuBar(nsIMenu * aMenu);
nsIWidget * GetParentWidget();
char* GetACPString(nsString& aStr);
void LoadMenuItem(nsIMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
unsigned short menuitemIndex,
nsIWebShell * aWebShell);
void LoadSubMenu(nsIMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode);
void LoadMenuItem(nsIContextMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
unsigned short menuitemIndex,
nsIWebShell * aWebShell);
void LoadSubMenu(nsIContextMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode);
nsIMenuItem * FindMenuItem(nsIContextMenu * aMenu, PRUint32 aId);
nsString mLabel;
PRUint32 mNumMenuItems;
GtkWidget *mMenu;
nsVoidArray mMenuItemVoidArray;
nsIWidget *mParent;
nsIMenuListener * mListener;
PRBool mConstructCalled;
nsIDOMNode * mDOMNode;
nsIWebShell * mWebShell;
nsIDOMElement * mDOMElement;
nsString mAlignment;
nsString mAnchorAlignment;
PRInt32 mX;
PRInt32 mY;
};
#endif // nsContextMenu_h__

Просмотреть файл

@ -1,652 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsContextMenu.h"
#include "nsIContextMenu.h"
#include "nsIMenu.h"
#include "nsIMenuItem.h"
#include "nsIMenuListener.h"
#include "nsCOMPtr.h"
#include "nsIComponentManager.h"
#include "nsMenu.h" // for mMacMenuIDCount
#include "nsString.h"
#include "nsStringUtil.h"
#include <TextUtils.h>
#include <ToolUtils.h>
#include <Devices.h>
#include <Menus.h>
// CIDs
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kMenuBarCID, NS_MENUBAR_CID);
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
static NS_DEFINE_CID(kMenuItemCID, NS_MENUITEM_CID);
NS_IMPL_ISUPPORTS2(nsContextMenu, nsIContextMenu, nsIMenuListener)
//-------------------------------------------------------------------------
//
// nsContextMenu constructor
//
//-------------------------------------------------------------------------
nsContextMenu::nsContextMenu() : nsIContextMenu()
{
NS_INIT_REFCNT();
mNumMenuItems = 0;
mMenuParent = nsnull;
mMacMenuID = 0;
mMacMenuHandle = nsnull;
mListener = nsnull;
mX = 0;
mY = 0;
mDOMNode = nsnull;
mWebShell = nsnull;
//
// create a multi-destination Unicode converter which can handle all of the installed
// script systems
//
OSErr err = ::CreateUnicodeToTextRunInfoByScriptCode(0,NULL,&mUnicodeTextRunConverter);
NS_ASSERTION(err==noErr,"nsMenu::nsMenu: CreateUnicodeToTextRunInfoByScriptCode failed.");
}
//-------------------------------------------------------------------------
//
// nsContextMenu destructor
//
//-------------------------------------------------------------------------
nsContextMenu::~nsContextMenu()
{
NS_IF_RELEASE(mListener);
while(mNumMenuItems)
{
--mNumMenuItems;
if(mMenuItemVoidArray[mNumMenuItems]) {
// Figure out what we're releasing
nsIMenuItem * menuitem = nsnull;
((nsISupports*)mMenuItemVoidArray[mNumMenuItems])->QueryInterface(NS_GET_IID(nsIMenuItem), (void**) &menuitem);
if(menuitem)
{
// case menuitem
menuitem->Release(); // Release our hold
NS_IF_RELEASE(menuitem); // Balance QI
}
else
{
nsIMenu * menu = nsnull;
((nsISupports*)mMenuItemVoidArray[mNumMenuItems])->QueryInterface(NS_GET_IID(nsIMenu), (void**) &menu);
if(menu)
{
// case menu
menu->Release(); // Release our hold
NS_IF_RELEASE(menu); // Balance QI
}
}
}
}
mMacMenuIDCount--;
OSErr err = ::DisposeUnicodeToTextRunInfo(&mUnicodeTextRunConverter);
NS_ASSERTION(err==noErr,"nsMenu::~nsMenu: DisposeUnicodeToTextRunInfo failed.");
}
//-------------------------------------------------------------------------
//
// Create the proper widget
//
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::Create(nsISupports *aParent, const nsString& anAlignment,
const nsString& anAnchorAlignment)
{
mParent = aParent;
mMacMenuHandle = ::NewMenu(mMacMenuIDCount, "\p");
mMacMenuID = mMacMenuIDCount;
mMacMenuIDCount++;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetParent(nsISupports*& aParent)
{
aParent = nsnull;
if (mParent) {
return mParent->QueryInterface(NS_GET_IID(nsISupports),(void**)&aParent);
}
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddItem(nsISupports* aItem)
{
if(aItem)
{
// Figure out what we're adding
nsIMenuItem * menuitem = nsnull;
aItem->QueryInterface(NS_GET_IID(nsIMenuItem), (void**) &menuitem);
if(menuitem)
{
// case menuitem
AddMenuItem(menuitem);
NS_RELEASE(menuitem);
}
else
{
nsIMenu * menu = nsnull;
aItem->QueryInterface(NS_GET_IID(nsIMenu), (void**) &menu);
if(menu)
{
// case menu
AddMenu(menu);
NS_RELEASE(menu);
}
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddMenuItem(nsIMenuItem * aMenuItem)
{
if(aMenuItem) {
nsISupports * supports = nsnull;
aMenuItem->QueryInterface(NS_GET_IID(nsISupports), (void**)&supports);
if(supports) {
mMenuItemVoidArray.AppendElement(supports);
nsString label;
nsString labelHack; labelHack.AssignWithConversion(" ");
aMenuItem->GetLabel(label);
mNumMenuItems++;
::InsertMenuItem(mMacMenuHandle, (const unsigned char *)" ", mNumMenuItems);
if(label[0] == PRUnichar('-')) {
labelHack.Append(label);
NSStringSetMenuItemText(mMacMenuHandle, mNumMenuItems, labelHack);
} else {
NSStringSetMenuItemText(mMacMenuHandle, mNumMenuItems, label);
}
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddMenu(nsIMenu * aMenu)
{
// Add a submenu
if(aMenu) {
nsISupports * supports = nsnull;
aMenu->QueryInterface(NS_GET_IID(nsISupports), (void**)&supports);
if(supports) {
mMenuItemVoidArray.AppendElement(supports);
// We have to add it as a menu item and then associate it with the item
nsString label;
aMenu->GetLabel(label);
mNumMenuItems++;
::InsertMenuItem(mMacMenuHandle, "\p ", mNumMenuItems);
NSStringSetMenuItemText(mMacMenuHandle, mNumMenuItems,label);
MenuHandle menuHandle;
aMenu->GetNativeData((void**)&menuHandle);
::InsertMenu(menuHandle, hierMenu);
PRInt16 temp = mMacMenuIDCount;
::SetMenuItemHierarchicalID((MenuHandle) mMacMenuHandle, mNumMenuItems, --temp);
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddSeparator()
{
// HACK - We're not really appending an nsMenuItem but it
// needs to be here to make sure that event dispatching isn't off by one.
mMenuItemVoidArray.AppendElement(nsnull);
::InsertMenuItem(mMacMenuHandle, "\p(-", mNumMenuItems );
mNumMenuItems++;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetItemCount(PRUint32 &aCount)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetItemAt(const PRUint32 aPos, nsISupports *& aMenuItem)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::InsertItemAt(const PRUint32 aPos, nsISupports * aMenuItem)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::RemoveItem(const PRUint32 aPos)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::RemoveAll()
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetNativeData(void ** aData)
{
*aData = mMacMenuHandle;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddMenuListener(nsIMenuListener * aMenuListener)
{
mListener = aMenuListener;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::RemoveMenuListener(nsIMenuListener * aMenuListener)
{
if (aMenuListener == mListener) {
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// nsIMenuListener interface
//
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
nsEventStatus eventStatus = nsEventStatus_eIgnore;
// Determine if this is the correct menu to handle the event
//PRInt16 menuID = HiWord(((nsMenuEvent)aMenuEvent).mCommand);
PRInt16 menuID = mSelectedMenuID;
#ifdef APPLE_MENU_HACK
if(kAppleMenuID == menuID)
{
//PRInt16 menuItemID = LoWord(((nsMenuEvent)aMenuEvent).mCommand);
PRInt16 menuItemID = mSelectedMenuItem;
if (menuItemID > 2) // don't handle the about or separator items yet
{
Str255 itemStr;
::GetMenuItemText(GetMenuHandle(menuID), menuItemID, itemStr);
#if !TARGET_CARBON
::OpenDeskAcc(itemStr);
#endif
eventStatus = nsEventStatus_eConsumeNoDefault;
}
}
else
#endif
if(mMacMenuID == menuID)
{
// Call MenuSelected on the correct nsMenuItem
//PRInt16 menuItemID = LoWord(((nsMenuEvent)aMenuEvent).mCommand);
PRInt16 menuItemID = mSelectedMenuItem;
nsIMenuListener * menuListener = nsnull;
((nsIMenuItem*)mMenuItemVoidArray[menuItemID-1])->QueryInterface(NS_GET_IID(nsIMenuListener), (void**)&menuListener);
if(menuListener) {
eventStatus = menuListener->MenuSelected(aMenuEvent);
NS_IF_RELEASE(menuListener);
}
}
else
{
// Make sure none of our submenus are the ones that should be handling this
for (int i = mMenuItemVoidArray.Count(); i > 0; i--)
{
if(nsnull != mMenuItemVoidArray[i-1])
{
nsIMenu * submenu = nsnull;
((nsISupports*)mMenuItemVoidArray[i-1])->QueryInterface(NS_GET_IID(nsIMenu), (void**)&submenu);
if(submenu)
{
nsIMenuListener * menuListener = nsnull;
((nsISupports*)mMenuItemVoidArray[i-1])->QueryInterface(NS_GET_IID(nsIMenuListener), (void**)&menuListener);
if(menuListener){
eventStatus = menuListener->MenuSelected(aMenuEvent);
NS_IF_RELEASE(menuListener);
if(nsEventStatus_eIgnore != eventStatus)
return eventStatus;
}
}
}
}
}
return eventStatus;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuSelected(const nsMenuEvent & aMenuEvent)
{
nsEventStatus eventStatus = nsEventStatus_eIgnore;
// Put context menu in the menu list
::InsertMenu(mMacMenuHandle, -1);
// Call MenuConstruct
MenuConstruct(
aMenuEvent,
mParentWindow,
mDOMNode,
mWebShell);
// Display and track the menu
Point location;
location.h = mX;
location.v = mY;
UInt32 outUserSelectionType;
Str255 inHelpItemString = "\p";
::ContextualMenuSelect (
mMacMenuHandle,
location,
false,
kCMHelpItemNoHelp,
inHelpItemString,
0, //const AEDesc* inSelection, We should really be constructing this
& outUserSelectionType,
& mSelectedMenuID,
& mSelectedMenuItem);
//ContextualMenuSelect (MenuHandle inMenu,
// Point inGlobalLocation,
// Boolean inReserved,
// UInt32 inHelpType,
// ConstStr255Param inHelpItemString,
// const AEDesc * inSelection,
// UInt32 * outUserSelectionType,
// SInt16 * outMenuID,
// UInt16 * outMenuItem) TWOWORDINLINE(0x7003, 0xAA72);
if(outUserSelectionType != kCMNothingSelected) {
MenuItemSelected(aMenuEvent);
}
return eventStatus;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuDeselected(const nsMenuEvent & aMenuEvent)
{
// Remove the context menu from the menu list
::DeleteMenu(mMacMenuID);
// Call MenuDestruct
MenuDestruct(aMenuEvent);
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuConstruct(
const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menuNode,
void * aWebShell)
{
// Construct the menu
nsCOMPtr<nsIDOMNode> menuitemNode;
((nsIDOMNode*)mDOMNode)->GetFirstChild(getter_AddRefs(menuitemNode));
unsigned short menuIndex = 0;
while (menuitemNode) {
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
if (menuitemElement) {
nsString menuitemNodeType;
nsString menuitemName;
menuitemElement->GetNodeName(menuitemNodeType);
if (menuitemNodeType.EqualsWithConversion("menuitem")) {
// LoadMenuItem
LoadMenuItem(this, menuitemElement, menuitemNode, menuIndex, (nsIWebShell*)aWebShell);
} else if (menuitemNodeType.EqualsWithConversion("menuseparator")) {
AddSeparator();
} else if (menuitemNodeType.EqualsWithConversion("menu")) {
// Load a submenu
LoadSubMenu(this, menuitemElement, menuitemNode);
}
}
++menuIndex;
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
} // end menu item innner loop
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuDestruct(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
/**
* Set Location
*
*/
NS_METHOD nsContextMenu::SetLocation(PRInt32 aX, PRInt32 aY)
{
mX = aX;
mY = aY;
return NS_OK;
}
//-------------------------------------------------------------------------
/**
* Set DOMNode
*
*/
NS_METHOD nsContextMenu::SetDOMNode(nsIDOMNode * aMenuNode)
{
mDOMNode = aMenuNode;
return NS_OK;
}
//-------------------------------------------------------------------------
/**
* Set DOMElement
*
*/
NS_METHOD nsContextMenu::SetDOMElement(nsIDOMElement * aMenuElement)
{
return NS_OK;
}
//-------------------------------------------------------------------------
/**
* Set WebShell
*
*/
NS_METHOD nsContextMenu::SetWebShell(nsIWebShell * aWebShell)
{
mWebShell = aWebShell;
return NS_OK;
}
//----------------------------------------
void nsContextMenu::LoadMenuItem(
nsIContextMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
unsigned short menuitemIndex,
nsIWebShell * aWebShell)
{
static const char* NS_STRING_TRUE = "true";
nsString disabled;
nsString menuitemName;
nsString menuitemCmd;
menuitemElement->GetAttribute(NS_ConvertASCIItoUCS2("disabled"), disabled);
menuitemElement->GetAttribute(NS_ConvertASCIItoUCS2("label"), menuitemName);
menuitemElement->GetAttribute(NS_ConvertASCIItoUCS2("cmd"), menuitemCmd);
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuItemCID, nsnull, NS_GET_IID(nsIMenuItem), (void**)&pnsMenuItem);
if (NS_OK == rv) {
pnsMenuItem->Create(pParentMenu, menuitemName, 0);
nsISupports * supports = nsnull;
pnsMenuItem->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pParentMenu->AddItem(supports); // Parent should now own menu item
NS_RELEASE(supports);
// Create MenuDelegate - this is the intermediator inbetween
// the DOM node and the nsIMenuItem
// The nsWebShellWindow wacthes for Document changes and then notifies the
// the appropriate nsMenuDelegate object
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(menuitemNode));
if (!domElement) {
return;
}
nsAutoString cmdAtom; cmdAtom.AssignWithConversion("oncommand");
nsString cmdName;
domElement->GetAttribute(cmdAtom, cmdName);
pnsMenuItem->SetCommand(cmdName);
// DO NOT use passed in wehshell because of messed up windows dynamic loading
// code.
pnsMenuItem->SetWebShell(mWebShell);
pnsMenuItem->SetDOMElement(domElement);
pnsMenuItem->SetDOMNode(menuitemNode);
if(disabled.EqualsWithConversion(NS_STRING_TRUE) )
::DisableMenuItem(mMacMenuHandle, menuitemIndex + 1);
else
::EnableMenuItem(mMacMenuHandle, menuitemIndex + 1);
NS_RELEASE(pnsMenuItem);
}
return;
}
//----------------------------------------
void nsContextMenu::LoadSubMenu(
nsIContextMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode)
{
nsString menuName;
menuElement->GetAttribute(NS_ConvertASCIItoUCS2("label"), menuName);
//printf("Creating Menu [%s] \n", menuName.ToNewCString()); // this leaks
// Create nsMenu
nsIMenu * pnsMenu = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuCID, nsnull, NS_GET_IID(nsIMenu), (void**)&pnsMenu);
if (NS_OK == rv) {
// Call Create
nsISupports * supports = nsnull;
pParentMenu->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pnsMenu->Create(supports, menuName);
NS_RELEASE(supports); // Balance QI
// Set nsMenu Name
pnsMenu->SetLabel(menuName);
// Make nsMenu a child of parent nsMenu. The parent takes ownership
supports = nsnull;
pnsMenu->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pParentMenu->AddItem(supports);
NS_RELEASE(supports);
pnsMenu->SetWebShell(mWebShell);
pnsMenu->SetDOMNode(menuNode);
pnsMenu->SetDOMElement(menuElement);
// We're done with the menu
NS_RELEASE(pnsMenu);
}
}
void nsContextMenu::NSStringSetMenuItemText(MenuHandle macMenuHandle, short menuItem, nsString& menuString)
{
OSErr err;
const PRUnichar* unicodeText;
char* scriptRunText;
size_t unicodeTextLengthInBytes, unicdeTextReadInBytes,
scriptRunTextSizeInBytes, scriptRunTextLengthInBytes,
scriptCodeRunListLength;
ScriptCodeRun convertedTextScript;
long scriptMgrVariable;
//
// extract the Unicode text from the nsString and convert it into a single script run
//
unicodeText = menuString.get();
unicodeTextLengthInBytes = menuString.Length() * sizeof(PRUnichar);
scriptRunTextSizeInBytes = unicodeTextLengthInBytes * 2;
scriptRunText = new char[scriptRunTextSizeInBytes];
err = ::ConvertFromUnicodeToScriptCodeRun(mUnicodeTextRunConverter,
unicodeTextLengthInBytes,unicodeText,
0, /* no flags*/
0,NULL,NULL,NULL, /* no offset arrays */
scriptRunTextSizeInBytes,&unicdeTextReadInBytes,&scriptRunTextLengthInBytes,
scriptRunText,
1 /* count of script runs*/,&scriptCodeRunListLength,&convertedTextScript);
NS_ASSERTION(err==noErr,"nsMenu::NSStringSetMenuItemText: ConvertFromUnicodeToScriptCodeRun failed.");
if (err!=noErr) { delete [] scriptRunText; return; }
scriptRunText[scriptRunTextLengthInBytes] = 0; // null terminate
//
// get a font from the script code
//
scriptMgrVariable = ::GetScriptVariable(convertedTextScript.script,smScriptAppFondSize);
::SetMenuItemText(macMenuHandle,menuItem,c2pstr(scriptRunText));
err = ::SetMenuItemFontID(macMenuHandle,menuItem,HiWord(scriptMgrVariable));
NS_ASSERTION(err==noErr,"nsMenu::NSStringSetMenuItemText: SetMenuItemFontID failed.");
//
// clean up and exit
//
delete [] scriptRunText;
}

Просмотреть файл

@ -1,143 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsContextMenu_h__
#define nsContextMenu_h__
#include "nsMenu.h"
#include "nsIContextMenu.h"
#include "nsIMenu.h"
#include "nsVoidArray.h"
#include "nsIMenuListener.h"
#include "nsIDOMNode.h"
#include "nsIWebShell.h"
#include <Menus.h>
#include <UnicodeConverter.h>
class nsIMenuBar;
class nsIMenuListener;
// temporary hack to get apple menu -- sfraser, approved saari
#define APPLE_MENU_HACK 1
#ifdef APPLE_MENU_HACK
extern const PRInt16 kMacMenuID;
extern const PRInt16 kAppleMenuID;
#endif /* APPLE_MENU_HACK */
class nsContextMenu : public nsIContextMenu, public nsIMenuListener
{
public:
nsContextMenu();
virtual ~nsContextMenu();
NS_DECL_ISUPPORTS
// nsIMenuListener methods
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuConstruct(
const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menuNode,
void * aWebShell);
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
// nsIMenu Methods
NS_IMETHOD Create(nsISupports * aParent, const nsString& anAlignment, const nsString& aAnchorAlign);
NS_IMETHOD GetParent(nsISupports *&aParent);
NS_IMETHOD AddItem(nsISupports* aText);
NS_IMETHOD AddSeparator();
NS_IMETHOD GetItemCount(PRUint32 &aCount);
NS_IMETHOD GetItemAt(const PRUint32 aPos, nsISupports *& aMenuItem);
NS_IMETHOD InsertItemAt(const PRUint32 aPos, nsISupports * aMenuItem);
NS_IMETHOD RemoveItem(const PRUint32 aPos);
NS_IMETHOD RemoveAll();
NS_IMETHOD GetNativeData(void** aData);
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD SetLocation(PRInt32 aX, PRInt32 aY);
NS_IMETHOD SetDOMNode(nsIDOMNode * aMenuNode);
NS_IMETHOD SetDOMElement(nsIDOMElement * aMenuElement);
NS_IMETHOD SetWebShell(nsIWebShell * aWebShell);
//
NS_IMETHOD AddMenuItem(nsIMenuItem * aMenuItem);
NS_IMETHOD AddMenu(nsIMenu * aMenu);
// MacSpecific
static PRInt16 GetUniqueMenuID() {
if (mMacMenuIDCount == 32767)
mMacMenuIDCount = 256;
return mMacMenuIDCount++;
}
protected:
void LoadMenuItem(
nsIContextMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
unsigned short menuitemIndex,
nsIWebShell * aWebShell);
void LoadSubMenu(
nsIContextMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode);
void NSStringSetMenuItemText(MenuHandle macMenuHandle, short menuItem, nsString& menuString);
nsString mLabel;
PRUint32 mNumMenuItems;
nsVoidArray mMenuItemVoidArray;
nsIWidget * mParentWindow;
nsISupports * mParent;
nsIMenu * mMenuParent;
nsIMenuBar * mMenuBarParent;
// MacSpecific
PRInt16 mMacMenuID;
MenuHandle mMacMenuHandle;
nsIMenuListener * mListener;
SInt16 mSelectedMenuID;
UInt16 mSelectedMenuItem;
PRInt32 mX;
PRInt32 mY;
nsIDOMNode * mDOMNode;
nsIWebShell * mWebShell;
UnicodeToTextRunInfo mUnicodeTextRunConverter;
private:
};
#endif // nsMenu_h__

Просмотреть файл

@ -60,7 +60,6 @@
#include "nsHashtable.h"
//#include "nsMenu.h"
#include "nsDragService.h"
//#include "nsContextMenu.h"
#include "nsIRollupListener.h"
#include "nsIMenuRollup.h"

Просмотреть файл

@ -42,7 +42,6 @@
#include "nsSwitchToUIThread.h"
class nsIMenuBar;
//class nsContextMenu;
// Base widget class.
// This is abstract. Controls (labels, radio buttons, listboxen) derive
@ -161,7 +160,6 @@ class nsWindow : public nsBaseWidget,
void NS2PM_PARENT( POINTL &ptl);
void NS2PM( POINTL &ptl);
void NS2PM( RECTL &rcl);
// void SetContextMenu( nsContextMenu *aMenu);
protected:
static BOOL DealWithPopups ( ULONG inMsg, MRESULT* outResult ) ;
@ -246,7 +244,6 @@ protected:
nsToolkit *mOS2Toolkit;
nsFont *mFont;
nsIMenuBar *mMenuBar;
// nsContextMenu *mActiveMenu; // record this so we can send it events
// State of the window, used to emulate windows better...
enum nsWindowState

Просмотреть файл

@ -1,838 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsContextMenu.h"
#include "nsIContextMenu.h"
#include "nsIMenu.h"
#include "nsIMenuItem.h"
#include "nsToolkit.h"
#include "nsColor.h"
#include "nsGUIEvent.h"
#include "nsString.h"
#include "nsStringUtil.h"
#include <windows.h>
#include <winuser.h>
#include "nsIAppShell.h"
#include "nsGUIEvent.h"
#include "nsIDeviceContext.h"
#include "nsRect.h"
#include "nsGfxCIID.h"
#include "nsMenuItem.h"
#include "nsCOMPtr.h"
#include "nsIMenuListener.h"
#include "nsIComponentManager.h"
// CIDs
#include "nsWidgetsCID.h"
static NS_DEFINE_IID(kContextMenuCID, NS_CONTEXTMENU_CID);
static NS_DEFINE_IID(kMenuCID, NS_MENU_CID);
static NS_DEFINE_IID(kMenuItemCID, NS_MENUITEM_CID);
//-------------------------------------------------------------------------
nsresult nsContextMenu::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
if (aIID.Equals(NS_GET_IID(nsIContextMenu))) {
*aInstancePtr = (void*)(nsIContextMenu*) this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsIMenuListener))) {
*aInstancePtr = (void*)(nsIMenuListener*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsISupports))) {
*aInstancePtr = (void*)(nsISupports*)(nsIContextMenu*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
//-------------------------------------------------------------------------
NS_IMPL_ADDREF(nsContextMenu)
NS_IMPL_RELEASE(nsContextMenu)
//-------------------------------------------------------------------------
//
// nsContextMenu constructor
//
//-------------------------------------------------------------------------
nsContextMenu::nsContextMenu()
{
NS_INIT_REFCNT();
mMenu = nsnull;
mListener = nsnull;
nsresult result = NS_NewISupportsArray(&mItems);
mDOMNode = nsnull;
mDOMElement = nsnull;
mWebShell = nsnull;
mConstructed = false;
mAlignment = "topleft";
mAnchorAlignment = "none";
}
//-------------------------------------------------------------------------
//
// nsContextMenu destructor
//
//-------------------------------------------------------------------------
nsContextMenu::~nsContextMenu()
{
NS_IF_RELEASE(mListener);
// Remove all references to the items
mItems->Clear();
}
//-------------------------------------------------------------------------
//
// Create the proper widget
//
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::Create(nsISupports *aParent, const nsString& anAlignment,
const nsString& anAnchorAlignment)
{
if(aParent)
{
nsIWidget * parent = nsnull;
aParent->QueryInterface(NS_GET_IID(nsIWidget), (void**) &parent); // This does the addref
if(parent)
{
mParentWindow = parent;
}
}
mAlignment = anAlignment;
mAnchorAlignment = anAnchorAlignment;
mMenu = CreatePopupMenu();
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetParent(nsISupports*& aParent)
{
aParent = nsnull;
if (nsnull != mParentWindow) {
return mParentWindow->QueryInterface(NS_GET_IID(nsISupports),(void**)&aParent);
}
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddItem(nsISupports * aItem)
{
if(aItem)
{
// Figure out what we're adding
nsIMenuItem * menuitem = nsnull;
aItem->QueryInterface(NS_GET_IID(nsIMenuItem), (void**) &menuitem);
if(menuitem)
{
// case menuitem
AddMenuItem(menuitem);
NS_RELEASE(menuitem);
}
else
{
nsIMenu * menu = nsnull;
aItem->QueryInterface(NS_GET_IID(nsIMenu), (void**) &menu);
if(menu)
{
// case menu
AddMenu(menu);
NS_RELEASE(menu);
}
}
}
return NS_OK;
}
//-------------------------------------------------------------------------
// This does not return a ref counted object
// This is NOT an nsIMenu method
nsIWidget * nsContextMenu::GetParentWidget()
{
return mParentWindow;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddMenuItem(nsIMenuItem * aMenuItem)
{
PRUint32 cnt;
mItems->Count(&cnt);
return InsertItemAt(cnt, (nsISupports *)aMenuItem);
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddMenu(nsIMenu * aMenu)
{
PRUint32 cnt;
mItems->Count(&cnt);
return InsertItemAt(cnt, (nsISupports *)aMenu);
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddSeparator()
{
PRUint32 cnt;
mItems->Count(&cnt);
InsertSeparator(cnt);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetItemCount(PRUint32 &aCount)
{
PRUint32 cnt;
mItems->Count(&cnt);
aCount = cnt;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetItemAt(const PRUint32 aCount, nsISupports *& aMenuItem)
{
aMenuItem = (nsISupports *)mItems->ElementAt(aCount);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::InsertItemAt(const PRUint32 aCount, nsISupports * aMenuItem)
{
nsString name;
BOOL status = FALSE;
mItems->InsertElementAt(aMenuItem, (PRInt32)aCount);
nsCOMPtr<nsIMenuItem> menuItem(do_QueryInterface(aMenuItem));
if (menuItem) {
menuItem->GetLabel(name);
nsIWidget * win = GetParentWidget();
PRInt32 id = ((nsWindow *)win)->GetNewCmdMenuId();
((nsMenuItem *)((nsIMenuItem *)menuItem))->SetCmdId(id);
char * nameStr = GetACPString(name);
MENUITEMINFO menuInfo;
menuInfo.cbSize = sizeof(menuInfo);
menuInfo.fMask = MIIM_TYPE | MIIM_ID;
menuInfo.fType = MFT_STRING;
menuInfo.dwTypeData = nameStr;
menuInfo.wID = (DWORD)id;
menuInfo.cch = strlen(nameStr);
status = ::InsertMenuItem(mMenu, aCount, TRUE, &menuInfo);
delete[] nameStr;
} else {
nsCOMPtr<nsIMenu> menu(do_QueryInterface(aMenuItem));
if (menu) {
nsString name;
menu->GetLabel(name);
//mItems->AppendElement((nsISupports *)(nsIMenu *)menu);
char * nameStr = GetACPString(name);
HMENU nativeMenuHandle;
void * voidData;
menu->GetNativeData(&voidData);
nativeMenuHandle = (HMENU)voidData;
MENUITEMINFO menuInfo;
menuInfo.cbSize = sizeof(menuInfo);
menuInfo.fMask = MIIM_SUBMENU | MIIM_TYPE;
menuInfo.hSubMenu = nativeMenuHandle;
menuInfo.fType = MFT_STRING;
menuInfo.dwTypeData = nameStr;
BOOL status = ::InsertMenuItem(mMenu, aCount, TRUE, &menuInfo);
delete[] nameStr;
}
}
return (status ? NS_OK : NS_ERROR_FAILURE);
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::InsertSeparator(const PRUint32 aCount)
{
nsISupports * supports = nsnull;
QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
nsMenuItem * item = new nsMenuItem();
if(supports) {
item->Create(supports, "", PR_FALSE);
NS_RELEASE(supports);
}
mItems->InsertElementAt((nsISupports *)(nsIMenuItem *)item, (PRInt32)aCount);
MENUITEMINFO menuInfo;
menuInfo.cbSize = sizeof(menuInfo);
menuInfo.fMask = MIIM_TYPE;
menuInfo.fType = MFT_SEPARATOR;
BOOL status = ::InsertMenuItem(mMenu, aCount, TRUE, &menuInfo);
return (status ? NS_OK : NS_ERROR_FAILURE);
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::RemoveItem(const PRUint32 aCount)
{
//nsISupports * supports = (nsISupports *)mItems->ElementAt(aCount);
mItems->RemoveElementAt(aCount);
return (::RemoveMenu(mMenu, aCount, MF_BYPOSITION) ? NS_OK:NS_ERROR_FAILURE);
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::RemoveAll()
{
PRUint32 cnt;
mItems->Count(&cnt);
while (cnt) {
mItems->RemoveElementAt(0);
::RemoveMenu(mMenu, 0, MF_BYPOSITION);
mItems->Count(&cnt);
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::GetNativeData(void ** aData)
{
*aData = (void *)mMenu;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::AddMenuListener(nsIMenuListener * aMenuListener)
{
NS_IF_RELEASE(mListener);
mListener = aMenuListener;
NS_IF_ADDREF(mListener);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::RemoveMenuListener(nsIMenuListener * aMenuListener)
{
if (aMenuListener == mListener) {
NS_IF_RELEASE(mListener);
}
return NS_OK;
}
//-------------------------------------------------------------------------
// nsIMenuListener interface
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
#ifdef DEBUG_saari
char* menuLabel = GetACPString(mLabel);
printf("Menu Item Selected %s\n", menuLabel);
delete[] menuLabel;
#endif
if (nsnull != mListener) {
NS_ASSERTION(false, "get debugger");
mListener->MenuSelected(aMenuEvent);
}
return nsEventStatus_eIgnore;
}
nsEventStatus nsContextMenu::MenuSelected(const nsMenuEvent & aMenuEvent)
{
#ifdef DEBUG
//printf("nsMenu::MenuSelected called\n");
#endif
if(mConstructed){
MenuDestruct(aMenuEvent);
mConstructed = false;
}
if(!mConstructed) {
MenuConstruct(
aMenuEvent,
mParentWindow,
mDOMNode,
mWebShell);
mConstructed = true;
}
HWND pWnd = (HWND)mParentWindow->GetNativeData(NS_NATIVE_WIDGET);
// Track the menu
UINT alignFlags = TPM_LEFTALIGN | TPM_TOPALIGN;
if (mAlignment == "topright") {
alignFlags = TPM_RIGHTALIGN | TPM_TOPALIGN;
}
else if (mAlignment == "bottomleft") {
alignFlags = TPM_BOTTOMALIGN | TPM_LEFTALIGN;
}
else if (mAlignment == "bottomright") {
alignFlags = TPM_BOTTOMALIGN | TPM_RIGHTALIGN;
}
alignFlags |= TPM_RETURNCMD;
/* Commented out.
Ok, this animation SHOULD be used. It is different
from the ballooning outward animation used by default.
Causes NT to screw up.
XXX Need to query for the OS (95 vs. 98 vs. NT) and only enable for 98
- Dave
#define TPM_VERPOSANIMATION 0x1000L
#define TPM_VERNEGANIMATION 0x2000L
#define TPM_HORPOSANIMATION 0x0800L
#define TPM_HORNEGANIMATION 0x0400L
if (mAnchorAlignment == "topleft") {
// Fancy animation in this case matters for
// bottomleft and topright
if (mAlignment == "topright") {
// Sliding from right to left
alignFlags |= TPM_HORPOSANIMATION;
}
else if (mAlignment == "bottomleft") {
// Sliding from bottom to top
alignFlags |= TPM_VERNEGANIMATION;
}
}
else if (mAnchorAlignment == "topright") {
if (mAlignment == "topleft") {
// Sliding from left to right
alignFlags |= TPM_HORNEGANIMATION;
}
else if (mAlignment == "bottomright") {
// Sliding from bottom to top
alignFlags |= TPM_VERNEGANIMATION;
}
}
else if (mAnchorAlignment == "bottomright") {
if (mAlignment == "bottomleft") {
// Sliding from left to right
alignFlags |= TPM_HORNEGANIMATION;
}
else if (mAlignment == "topright") {
// Sliding from top to bottom
alignFlags |= TPM_VERPOSANIMATION;
}
}
else if (mAnchorAlignment == "bottomleft") {
if (mAlignment == "topleft") {
// Sliding from top to bottom
alignFlags |= TPM_VERPOSANIMATION;
}
else if (mAlignment == "bottomright") {
// Sliding from right to left
alignFlags |= TPM_HORPOSANIMATION;
}
}
*/
PRInt32 identifier = ::TrackPopupMenu(
mMenu,
alignFlags,
mX, mY, 0, pWnd, NULL);
if (identifier > 0) {
// Dispatch to MenuItemSelected
nsIContextMenu * menu;
QueryInterface(NS_GET_IID(nsIContextMenu), (void**) &menu);
nsIMenuItem * menuItem = FindMenuItem(menu, identifier);
NS_RELEASE(menu);
if (menuItem) {
nsIMenuListener * listener;
if (NS_OK == menuItem->QueryInterface(NS_GET_IID(nsIMenuListener), (void **)&listener)) {
listener->MenuItemSelected(aMenuEvent);
NS_RELEASE(listener);
}
}
}
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsIMenuItem * nsContextMenu::FindMenuItem(nsIContextMenu * aMenu, PRUint32 aId)
{
PRUint32 i, count;
aMenu->GetItemCount(count);
for (i=0;i<count;i++) {
nsISupports * item;
nsIMenuItem * menuItem;
nsIContextMenu * menu;
aMenu->GetItemAt(i, item);
if (NS_OK == item->QueryInterface(NS_GET_IID(nsIMenuItem), (void **)&menuItem)) {
if (((nsMenuItem *)menuItem)->GetCmdId() == (PRInt32)aId) {
NS_RELEASE(item);
return menuItem;
}
} else if (NS_OK == item->QueryInterface(nsIContextMenu), (void **)&menu)) {
nsIMenuItem * fndItem = FindMenuItem(menu, aId);
NS_RELEASE(menu);
if (nsnull != fndItem) {
NS_RELEASE(item);
return fndItem;
}
}
NS_RELEASE(item);
}
return nsnull;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuDeselected(const nsMenuEvent & aMenuEvent)
{
#ifdef DEBUG
//printf("nsMenu::MenuDeselected called\n");
#endif
//MenuDestruct(aMenuEvent);
//mConstructed = false;
if (nsnull != mListener) {
NS_ASSERTION(false, "get debugger");
mListener->MenuDeselected(aMenuEvent);
}
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuConstruct(
const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menuNode,
void * aWebShell)
{
#ifdef DEBUG
//printf("nsMenu::MenuConstruct called \n");
#endif
// Begin menuitem inner loop
nsCOMPtr<nsIDOMNode> menuitemNode;
((nsIDOMNode*)mDOMNode)->GetFirstChild(getter_AddRefs(menuitemNode));
unsigned short menuIndex = 0;
while (menuitemNode) {
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
if (menuitemElement) {
nsString menuitemNodeType;
nsString menuitemName;
menuitemElement->GetNodeName(menuitemNodeType);
if (menuitemNodeType.Equals("menuitem")) {
// LoadMenuItem
LoadMenuItem(this, menuitemElement, menuitemNode, menuIndex, (nsIWebShell*)aWebShell);
} else if (menuitemNodeType.Equals("menuseparator")) {
AddSeparator();
} else if (menuitemNodeType.Equals("menu")) {
// Load a submenu
LoadSubMenu(this, menuitemElement, menuitemNode);
}
}
++menuIndex;
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
} // end menu item innner loop
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsContextMenu::MenuDestruct(const nsMenuEvent & aMenuEvent)
{
#ifdef DEBUG
//printf("nsMenu::MenuDestruct called \n");
#endif
// We cannot call RemoveAll() yet because menu item selection may need it
//RemoveAll();
PRUint32 cnt;
mItems->Count(&cnt);
while (cnt) {
mItems->RemoveElementAt(0);
::RemoveMenu(mMenu, 0, MF_BYPOSITION);
mItems->Count(&cnt);
}
return nsEventStatus_eIgnore;
}
//----------------------------------------
void nsContextMenu::LoadMenuItem(
nsIMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
unsigned short menuitemIndex,
nsIWebShell * aWebShell)
{
static const char* NS_STRING_TRUE = "true";
nsString disabled;
nsString menuitemName;
nsString menuitemCmd;
menuitemElement->GetAttribute(nsAutoString("disabled"), disabled);
menuitemElement->GetAttribute(nsAutoString("name"), menuitemName);
menuitemElement->GetAttribute(nsAutoString("cmd"), menuitemCmd);
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuItemCID, nsnull, NS_GET_IID(nsIMenuItem), (void**)&pnsMenuItem);
if (NS_OK == rv) {
pnsMenuItem->Create(pParentMenu, menuitemName, 0);
nsISupports * supports = nsnull;
pnsMenuItem->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pParentMenu->AddItem(supports); // Parent should now own menu item
NS_RELEASE(supports);
// Create MenuDelegate - this is the intermediator inbetween
// the DOM node and the nsIMenuItem
// The nsWebShellWindow wacthes for Document changes and then notifies the
// the appropriate nsMenuDelegate object
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(menuitemNode));
if (!domElement) {
return;
}
nsAutoString cmdAtom("oncommand");
nsString cmdName;
domElement->GetAttribute(cmdAtom, cmdName);
pnsMenuItem->SetCommand(cmdName);
// DO NOT use passed in wehshell because of messed up windows dynamic loading
// code.
pnsMenuItem->SetWebShell(mWebShell);
pnsMenuItem->SetDOMElement(domElement);
if(disabled == NS_STRING_TRUE )
::EnableMenuItem(mMenu, menuitemIndex, MF_BYPOSITION | MF_GRAYED);
NS_RELEASE(pnsMenuItem);
}
return;
}
//----------------------------------------
void nsContextMenu::LoadSubMenu(
nsIMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode)
{
nsString menuName;
menuElement->GetAttribute(nsAutoString("label"), menuName);
#ifdef DEBUG
//printf("Creating Menu [%s] \n", NS_ConvertUCS2toUTF8(menuName).get());
#endif
// Create nsMenu
nsIMenu * pnsMenu = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuCID, nsnull, NS_GET_IID(nsIMenu), (void**)&pnsMenu);
if (NS_OK == rv) {
// Call Create
nsISupports * supports = nsnull;
pParentMenu->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pnsMenu->Create(supports, menuName);
NS_RELEASE(supports); // Balance QI
// Set nsMenu Name
pnsMenu->SetLabel(menuName);
// Make nsMenu a child of parent nsMenu. The parent takes ownership
supports = nsnull;
pnsMenu->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pParentMenu->AddItem(supports);
NS_RELEASE(supports);
pnsMenu->SetWebShell(mWebShell);
pnsMenu->SetDOMNode(menuNode);
pnsMenu->SetDOMElement(menuElement);
// We're done with the menu
NS_RELEASE(pnsMenu);
}
}
//----------------------------------------
void nsContextMenu::LoadMenuItem(
nsIContextMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
unsigned short menuitemIndex,
nsIWebShell * aWebShell)
{
static const char* NS_STRING_TRUE = "true";
nsString disabled;
nsString menuitemName;
nsString menuitemCmd;
menuitemElement->GetAttribute(nsAutoString("disabled"), disabled);
menuitemElement->GetAttribute(nsAutoString("label"), menuitemName);
menuitemElement->GetAttribute(nsAutoString("cmd"), menuitemCmd);
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuItemCID, nsnull, NS_GET_IID(nsIMenuItem), (void**)&pnsMenuItem);
if (NS_OK == rv) {
pnsMenuItem->Create(pParentMenu, menuitemName, 0);
nsISupports * supports = nsnull;
pnsMenuItem->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pParentMenu->AddItem(supports); // Parent should now own menu item
NS_RELEASE(supports);
// Create MenuDelegate - this is the intermediator inbetween
// the DOM node and the nsIMenuItem
// The nsWebShellWindow wacthes for Document changes and then notifies the
// the appropriate nsMenuDelegate object
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(menuitemNode));
if (!domElement) {
return;
}
nsAutoString cmdAtom("oncommand");
nsString cmdName;
domElement->GetAttribute(cmdAtom, cmdName);
pnsMenuItem->SetCommand(cmdName);
// DO NOT use passed in wehshell because of messed up windows dynamic loading
// code.
pnsMenuItem->SetWebShell(mWebShell);
pnsMenuItem->SetDOMElement(domElement);
if(disabled == NS_STRING_TRUE )
::EnableMenuItem(mMenu, menuitemIndex, MF_BYPOSITION | MF_GRAYED);
NS_RELEASE(pnsMenuItem);
}
return;
}
//----------------------------------------
void nsContextMenu::LoadSubMenu(
nsIContextMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode)
{
nsString menuName;
menuElement->GetAttribute(nsAutoString("label"), menuName);
#ifdef DEBUG
//printf("Creating Menu [%s] \n", NS_ConvertUCS2toUTF8(menuName).get());
#endif
// Create nsMenu
nsIMenu * pnsMenu = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuCID, nsnull, NS_GET_IID(nsIMenu), (void**)&pnsMenu);
if (NS_OK == rv) {
// Call Create
nsISupports * supports = nsnull;
pParentMenu->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pnsMenu->Create(supports, menuName);
NS_RELEASE(supports); // Balance QI
// Set nsMenu Name
pnsMenu->SetLabel(menuName);
// Make nsMenu a child of parent nsMenu. The parent takes ownership
supports = nsnull;
pnsMenu->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pParentMenu->AddItem(supports);
NS_RELEASE(supports);
pnsMenu->SetWebShell(mWebShell);
pnsMenu->SetDOMNode(menuNode);
pnsMenu->SetDOMElement(menuElement);
// We're done with the menu
NS_RELEASE(pnsMenu);
}
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::SetLocation(PRInt32 aX, PRInt32 aY)
{
mX = aX;
mY = aY;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::SetDOMNode(nsIDOMNode * menuNode)
{
mDOMNode = menuNode;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::SetDOMElement(nsIDOMElement * menuElement)
{
mDOMElement = menuElement;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsContextMenu::SetWebShell(nsIWebShell * aWebShell)
{
mWebShell = aWebShell;
return NS_OK;
}
char* nsContextMenu::GetACPString(nsString& aStr)
{
int acplen = aStr.Length() * 2 + 1;
char * acp = new char[acplen];
if(acp)
{
int outlen = ::WideCharToMultiByte( CP_ACP, 0,
aStr.get(), aStr.Length(),
acp, acplen, NULL, NULL);
if ( outlen >= 0)
acp[outlen] = '\0'; // null terminate
}
return acp;
}

Просмотреть файл

@ -1,142 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsContextMenu_h__
#define nsContextMenu_h__
#include "nsdefs.h"
#include "nsWindow.h"
#include "nsSwitchToUIThread.h"
#include "nsIContextMenu.h"
#include "nsISupportsArray.h"
#include "nsIDOMElement.h"
#include "nsIWebShell.h"
class nsIMenuListener;
/**
* Native Win32 button wrapper
*/
class nsContextMenu : public nsIContextMenu, public nsIMenuListener
{
public:
nsContextMenu();
virtual ~nsContextMenu();
NS_DECL_ISUPPORTS
//nsIMenuListener interface
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuConstruct(
const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menubarNode,
void * aWebShell);
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
// nsIMenu Methods
NS_IMETHOD Create(nsISupports * aParent, const nsString& anAlignment, const nsString& aAnchorAlign);
NS_IMETHOD GetParent(nsISupports *&aParent);
NS_IMETHOD AddItem(nsISupports * aItem);
NS_IMETHOD AddSeparator();
NS_IMETHOD GetItemCount(PRUint32 &aCount);
NS_IMETHOD GetItemAt(const PRUint32 aPos, nsISupports *& aMenuItem);
NS_IMETHOD InsertItemAt(const PRUint32 aPos, nsISupports * aMenuItem);
NS_IMETHOD RemoveItem(const PRUint32 aPos);
NS_IMETHOD RemoveAll();
NS_IMETHOD GetNativeData(void** aData);
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener);
//
NS_IMETHOD AddMenuItem(nsIMenuItem * aMenuItem);
NS_IMETHOD AddMenu(nsIMenu * aMenu);
NS_IMETHOD InsertSeparator(const PRUint32 aCount);
NS_IMETHOD SetDOMNode(nsIDOMNode * menuNode);
NS_IMETHOD SetDOMElement(nsIDOMElement * menuElement);
NS_IMETHOD SetWebShell(nsIWebShell * aWebShell);
NS_IMETHOD SetLocation(PRInt32 aX, PRInt32 aY);
// Native Impl Methods
// These are not ref counted
HMENU GetNativeMenu() { return mMenu; }
protected:
nsIMenuBar * GetMenuBar(nsIMenu * aMenu);
nsIWidget * GetParentWidget();
char* GetACPString(nsString& aStr);
void LoadMenuItem(
nsIMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
unsigned short menuitemIndex,
nsIWebShell * aWebShell);
void LoadSubMenu(
nsIMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode);
void LoadMenuItem(
nsIContextMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode,
unsigned short menuitemIndex,
nsIWebShell * aWebShell);
void LoadSubMenu(
nsIContextMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode);
nsIMenuItem * FindMenuItem(nsIContextMenu * aMenu, PRUint32 aId);
HMENU mMenu;
nsISupportsArray * mItems;
nsIMenuListener * mListener;
nsIWidget * mParentWindow;
nsIDOMNode * mDOMNode;
nsIDOMElement * mDOMElement;
nsIWebShell * mWebShell;
bool mConstructed;
nsString mAlignment;
nsString mAnchorAlignment;
PRInt32 mX;
PRInt32 mY;
};
#endif // nsContextMenu_h__

Просмотреть файл

@ -68,7 +68,6 @@
#include "nsIMenu.h"
#include "nsIMenuItem.h"
#include "nsIMenuListener.h"
#include "nsIContextMenu.h"
#include "nsITimer.h"
// For JS Execution
@ -989,48 +988,6 @@ void nsWebShellWindow::LoadMenus(nsIDOMDocument * aDOMDoc, nsIWidget * aParentWi
} // end if (menuBar)
} // nsWebShellWindow::LoadMenus
//------------------------------------------------------------------------------
void nsWebShellWindow::DoContextMenu(
nsMenuEvent * aMenuEvent,
nsIDOMNode * aMenuNode,
nsIWidget * aParentWindow,
PRInt32 aX,
PRInt32 aY,
const nsString& aPopupAlignment,
const nsString& aAnchorAlignment)
{
if (aMenuNode) {
nsIContextMenu * pnsContextMenu;
nsresult rv = nsComponentManager::CreateInstance(kContextMenuCID, nsnull, NS_GET_IID(nsIContextMenu), (void**)&pnsContextMenu);
if (NS_SUCCEEDED(rv) && pnsContextMenu) {
nsISupports * supports;
aParentWindow->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pnsContextMenu->Create(supports, aPopupAlignment, aAnchorAlignment);
NS_RELEASE(supports);
pnsContextMenu->SetLocation(aX,aY);
// Set webshell
pnsContextMenu->SetWebShell( mWebShell );
// Set DOM node
pnsContextMenu->SetDOMNode( aMenuNode );
// Construct and show menu
nsIMenuListener * listener;
pnsContextMenu->QueryInterface(NS_GET_IID(nsIMenuListener), (void**) &listener);
// Dynamically construct and track the menu
listener->MenuSelected(*aMenuEvent);
// Destroy the menu
listener->MenuDeselected(*aMenuEvent);
// The parent owns the context menu, so we can release it
NS_RELEASE(listener);
NS_RELEASE(pnsContextMenu);
}
} // end if (aMenuNode)
}
#endif
//------------------------------------------------------------------------------

Просмотреть файл

@ -95,15 +95,6 @@ public:
PRBool aIsHiddenWindow, nsWidgetInitData& widgetInitData);
nsIWidget* GetWidget(void) { return mWindow; }
void DoContextMenu(
nsMenuEvent * aMenuEvent,
nsIDOMNode * aMenuNode,
nsIWidget * aParentWindow,
PRInt32 aX,
PRInt32 aY,
const nsString& aPopupAlignment,
const nsString& aAnchorAlignment);
// nsIWebProgressListener
NS_DECL_NSIWEBPROGRESSLISTENER