зеркало из https://github.com/mozilla/pjs.git
Re-landing. Decomtaminate native menu system. Add new native menu API. Lots of cleanup for the native menu system code. Memory usage and speed improvements. b=433952 r=bent r=kreeger sr=roc
This commit is contained in:
Родитель
5e7f902e4c
Коммит
b499ac5fe0
|
@ -47,7 +47,7 @@
|
|||
|
||||
interface nsIDOMElement;
|
||||
|
||||
[scriptable, uuid(993da427-2ac3-4766-8485-21a236d258e4)]
|
||||
[scriptable, uuid(ef136142-9925-45f4-a3e4-6f0d275c6aa8)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
|
@ -160,6 +160,15 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||
in AString aCharacters,
|
||||
in AString aUnmodifiedCharacters);
|
||||
|
||||
/**
|
||||
* See nsIWidget::ActivateNativeMenuItemAt
|
||||
*
|
||||
* Cannot be accessed from unprivileged context (not content-accessible)
|
||||
* Will throw a DOM security error if called without UniversalXPConnect
|
||||
* privileges.
|
||||
*/
|
||||
void activateNativeMenuItemAt(in AString indexString);
|
||||
|
||||
/**
|
||||
* Focus the element aElement. The element should be in the same document
|
||||
* that the window is displaying. Pass null to blur the element, if any,
|
||||
|
|
|
@ -308,6 +308,22 @@ nsDOMWindowUtils::SendNativeKeyEvent(PRInt32 aNativeKeyboardLayout,
|
|||
aModifiers, aCharacters, aUnmodifiedCharacters);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::ActivateNativeMenuItemAt(const nsAString& indexString)
|
||||
{
|
||||
PRBool hasCap = PR_FALSE;
|
||||
if (NS_FAILED(nsContentUtils::GetSecurityManager()->IsCapabilityEnabled("UniversalXPConnect", &hasCap))
|
||||
|| !hasCap)
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
// get the widget to send the event to
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return widget->ActivateNativeMenuItemAt(indexString);
|
||||
}
|
||||
|
||||
nsIWidget*
|
||||
nsDOMWindowUtils::GetWidget()
|
||||
{
|
||||
|
|
|
@ -64,7 +64,7 @@ EXPORTS = \
|
|||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||
EXPORTS += nsIMenuBar.h
|
||||
EXPORTS += nsINativeMenuService.h
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
|
||||
|
|
|
@ -1,141 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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 the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsIMenuBar_h__
|
||||
#define nsIMenuBar_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIMenu.h"
|
||||
|
||||
class nsIWidget;
|
||||
|
||||
// F81C6D64-B260-44ED-9289-2E410A130E35
|
||||
#define NS_IMENUBAR_IID \
|
||||
{ 0xF81C6D64, 0xB260, 0x44ED, \
|
||||
{ 0x92, 0x89, 0x2E, 0x41, 0x0A, 0x13, 0x0E, 0x35 } }
|
||||
|
||||
/**
|
||||
* MenuBar widget
|
||||
*/
|
||||
class nsIMenuBar : public nsISupports {
|
||||
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMENUBAR_IID)
|
||||
|
||||
/**
|
||||
* Creates the MenuBar
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD Create(nsIWidget * aParent) = 0;
|
||||
|
||||
/**
|
||||
* Get the MenuBar's Parent. This addrefs.
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetParent(nsIWidget *&aParent) = 0;
|
||||
|
||||
/**
|
||||
* Set the MenuBar's Parent
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD SetParent(nsIWidget *aParent) = 0;
|
||||
|
||||
/**
|
||||
* Adds the Menu
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD AddMenu(nsIMenu * aMenu) = 0;
|
||||
|
||||
/**
|
||||
* Returns the number of menus
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetMenuCount(PRUint32 &aCount) = 0;
|
||||
|
||||
/**
|
||||
* Returns a Menu Item at a specified Index
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetMenuAt(const PRUint32 aCount, nsIMenu *& aMenu) = 0;
|
||||
|
||||
/**
|
||||
* Inserts a Menu at a specified Index
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD InsertMenuAt(const PRUint32 aCount, nsIMenu *& aMenu) = 0;
|
||||
|
||||
/**
|
||||
* Removes an Menu from a specified Index
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD RemoveMenu(const PRUint32 aCount) = 0;
|
||||
|
||||
/**
|
||||
* Removes all the Menus
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD RemoveAll() = 0;
|
||||
|
||||
/**
|
||||
* Gets Native MenuHandle
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetNativeData(void*& aData) = 0;
|
||||
|
||||
/**
|
||||
* Sets Native MenuHandle. Temporary hack for mac until
|
||||
* nsMenuBar does it's own construction
|
||||
*/
|
||||
NS_IMETHOD SetNativeData(void* aData) = 0;
|
||||
|
||||
/**
|
||||
* Draw the menubar
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD Paint() = 0;
|
||||
|
||||
/**
|
||||
* Construct the menubar
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD MenuConstruct(const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow, void * aMenuNode) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMenuBar, NS_IMENUBAR_IID)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Josh Aas <josh@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsINativeMenuService_h_
|
||||
#define nsINativeMenuService_h_
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsIWidget;
|
||||
class nsIContent;
|
||||
|
||||
// {90DF88F9-F084-4EF3-829A-49496E636DED}
|
||||
#define NS_INATIVEMENUSERVICE_IID \
|
||||
{ 0x90DF88F9, 0xF084, 0x4EF3, \
|
||||
{ 0x82, 0x9A, 0x49, 0x49, 0x6E, 0x63, 0x6D, 0xED} }
|
||||
|
||||
class nsINativeMenuService : public nsISupports {
|
||||
public:
|
||||
// Given a top-level window widget and a menu bar DOM node, sets up native
|
||||
// menus. Once created, native menus are controlled via the DOM, including
|
||||
// destruction.
|
||||
NS_IMETHOD CreateNativeMenuBar(nsIWidget* aParent, nsIContent* aMenuBarNode)=0;
|
||||
};
|
||||
|
||||
#endif // nsINativeMenuService_h_
|
|
@ -55,7 +55,6 @@ class nsIDeviceContext;
|
|||
class nsIRegion;
|
||||
struct nsRect;
|
||||
struct nsFont;
|
||||
class nsIMenuBar;
|
||||
class nsIEventListener;
|
||||
class nsIRollupListener;
|
||||
class nsGUIEvent;
|
||||
|
@ -95,10 +94,10 @@ typedef nsEventStatus (*PR_CALLBACK EVENT_CALLBACK)(nsGUIEvent *event);
|
|||
#define NS_NATIVE_PLUGIN_PORT_CG 101
|
||||
#endif
|
||||
|
||||
// 517a0eef-cd1c-48b3-96f0-e341a50f120d
|
||||
// 00e25b3d-c872-4985-a15e-8e650b7b8ff6
|
||||
#define NS_IWIDGET_IID \
|
||||
{ 0x517a0eef, 0xcd1c, 0x48b3, \
|
||||
{ 0x96, 0xf0, 0xe3, 0x41, 0xa5, 0x0f, 0x12, 0x0d } }
|
||||
{ 0x00e25b3d, 0xc872, 0x4985, \
|
||||
{ 0xa1, 0x5e, 0x8e, 0x65, 0x0b, 0x7b, 0x8f, 0xf6 } }
|
||||
|
||||
// Hide the native window systems real window type so as to avoid
|
||||
// including native window system types and APIs. This is necessary
|
||||
|
@ -879,7 +878,7 @@ class nsIWidget : public nsISupports {
|
|||
* @param aMenuBar the menubar
|
||||
*/
|
||||
|
||||
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar) = 0;
|
||||
NS_IMETHOD SetMenuBar(void* aMenuBar) = 0;
|
||||
|
||||
/**
|
||||
* Set the widget's MenuBar's visibility
|
||||
|
@ -1105,6 +1104,20 @@ class nsIWidget : public nsISupports {
|
|||
const nsAString& aCharacters,
|
||||
const nsAString& aUnmodifiedCharacters) = 0;
|
||||
|
||||
/**
|
||||
* Activates a native menu item at the position specified by the index
|
||||
* string. The index string is a string of positive integers separated
|
||||
* by the "|" (pipe) character. The last integer in the string represents
|
||||
* the item index in a submenu located using the integers prior to it.
|
||||
*
|
||||
* Example: 1|0|4
|
||||
* In this string, the first integer represents the top-level submenu
|
||||
* in the native menu bar. Since the integer is 1, it is the second submeu
|
||||
* in the native menu bar. Within that, the first item (index 0) is a
|
||||
* submenu, and we want to activate the 5th item within that submenu.
|
||||
*/
|
||||
virtual nsresult ActivateNativeMenuItemAt(const nsAString& indexString) = 0;
|
||||
|
||||
protected:
|
||||
// keep the list of children. We also keep track of our siblings.
|
||||
// The ownership model is as follows: parent holds a strong ref to
|
||||
|
|
|
@ -79,20 +79,10 @@
|
|||
// Menus
|
||||
//-----------------------------------------------------------
|
||||
|
||||
// {BC658C81-4BEB-11d2-8DBB-00609703C14E}
|
||||
#define NS_MENUBAR_CID \
|
||||
{ 0xbc658c81, 0x4beb, 0x11d2, \
|
||||
{ 0x8d, 0xbb, 0x0, 0x60, 0x97, 0x3, 0xc1, 0x4e } }
|
||||
|
||||
// {35A3DEC1-4992-11d2-8DBA-00609703C14E}
|
||||
#define NS_MENU_CID \
|
||||
{ 0x35a3dec1, 0x4992, 0x11d2, \
|
||||
{ 0x8d, 0xba, 0x0, 0x60, 0x97, 0x3, 0xc1, 0x4e } }
|
||||
|
||||
// {7F045771-4BEB-11d2-8DBB-00609703C14E}
|
||||
#define NS_MENUITEM_CID \
|
||||
{ 0x7f045771, 0x4beb, 0x11d2, \
|
||||
{ 0x8d, 0xbb, 0x0, 0x60, 0x97, 0x3, 0xc1, 0x4e } }
|
||||
// {0B3FE5AA-BC72-4303-85AE-76365DF1251D}
|
||||
#define NS_NATIVEMENUSERVICE_CID \
|
||||
{ 0x0B3FE5AA, 0xBC72, 0x4303, \
|
||||
{ 0x85, 0xAE, 0x76, 0x36, 0x5D, 0xF1, 0x25, 0x1D} }
|
||||
|
||||
// {F6CD4F21-53AF-11d2-8DC4-00609703C14E}
|
||||
#define NS_POPUPMENU_CID \
|
||||
|
|
|
@ -48,8 +48,6 @@
|
|||
|
||||
#include "nsIWidget.h"
|
||||
|
||||
#include "nsIMenuBar.h"
|
||||
|
||||
#include "nsIMouseListener.h"
|
||||
#include "nsIEventListener.h"
|
||||
#include "nsString.h"
|
||||
|
@ -164,7 +162,7 @@ public:
|
|||
NS_IMETHOD SetColorMap(nsColorMap *aColorMap);
|
||||
NS_IMETHOD Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect);
|
||||
NS_IMETHOD SetTitle(const nsAString& aTitle);
|
||||
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar) { return NS_ERROR_FAILURE; }
|
||||
NS_IMETHOD SetMenuBar(void * aMenuBar) { return NS_ERROR_FAILURE; }
|
||||
NS_IMETHOD ShowMenuBar(PRBool aShow) { return NS_ERROR_FAILURE; }
|
||||
NS_IMETHOD WidgetToScreen(const nsRect& aOldRect, nsRect& aNewRect);
|
||||
NS_IMETHOD ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect);
|
||||
|
|
|
@ -66,7 +66,7 @@ REQUIRES = xpcom \
|
|||
intl \
|
||||
exthandler \
|
||||
appshell \
|
||||
lcms \
|
||||
lcms \
|
||||
thebes \
|
||||
js \
|
||||
xpconnect \
|
||||
|
@ -84,8 +84,6 @@ endif
|
|||
EXPORTS = \
|
||||
mozView.h \
|
||||
nsChangeObserver.h \
|
||||
nsIMenu.h \
|
||||
nsIMenuItem.h \
|
||||
$(NULL)
|
||||
|
||||
CMMSRCS = \
|
||||
|
@ -95,6 +93,7 @@ CMMSRCS = \
|
|||
nsMenuBarX.mm \
|
||||
nsMenuItemX.mm \
|
||||
nsMenuItemIconX.mm \
|
||||
nsMenuUtilsX.mm \
|
||||
nsFilePicker.mm \
|
||||
nsDragService.mm \
|
||||
nsToolkit.mm \
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
#include "nsIEventListener.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIDragService.h"
|
||||
#include "nsIMenuBar.h"
|
||||
|
||||
#include "nsplugindefs.h"
|
||||
|
||||
|
@ -291,7 +290,7 @@ public:
|
|||
void LocalToWindowCoordinate(nscoord& aX, nscoord& aY) { ConvertToDeviceCoordinates(aX, aY); }
|
||||
void LocalToWindowCoordinate(nsRect& aRect) { ConvertToDeviceCoordinates(aRect.x, aRect.y); }
|
||||
|
||||
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar);
|
||||
NS_IMETHOD SetMenuBar(void* aMenuBar);
|
||||
NS_IMETHOD ShowMenuBar(PRBool aShow);
|
||||
|
||||
NS_IMETHOD GetPreferredSize(PRInt32& aWidth, PRInt32& aHeight);
|
||||
|
@ -305,6 +304,8 @@ public:
|
|||
|
||||
NS_IMETHOD GetAttention(PRInt32 aCycleCount);
|
||||
|
||||
NS_IMETHOD ActivateNativeMenuItemAt(const nsAString& indexString);
|
||||
|
||||
// nsIPluginWidget
|
||||
NS_IMETHOD GetPluginClipRect(nsRect& outClipRect, nsPoint& outOrigin, PRBool& outWidgetVisible);
|
||||
NS_IMETHOD StartDrawPlugin();
|
||||
|
|
|
@ -971,7 +971,7 @@ NS_IMETHODIMP nsChildView::SetColorMap(nsColorMap *aColorMap)
|
|||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsChildView::SetMenuBar(nsIMenuBar * aMenuBar)
|
||||
NS_IMETHODIMP nsChildView::SetMenuBar(void* aMenuBar)
|
||||
{
|
||||
return NS_ERROR_FAILURE; // subviews don't have menu bars
|
||||
}
|
||||
|
@ -1373,6 +1373,51 @@ nsresult nsChildView::SynthesizeNativeKeyEvent(PRInt32 aNativeKeyboardLayout,
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
// Used for testing native menu system structure and event handling.
|
||||
NS_IMETHODIMP nsChildView::ActivateNativeMenuItemAt(const nsAString& indexString)
|
||||
{
|
||||
NSString* title = [NSString stringWithCharacters:indexString.BeginReading() length:indexString.Length()];
|
||||
NSArray* indexes = [title componentsSeparatedByString:@"|"];
|
||||
unsigned int indexCount = [indexes count];
|
||||
if (indexCount == 0)
|
||||
return NS_OK;
|
||||
|
||||
NSMenu* currentSubmenu = [NSApp mainMenu];
|
||||
for (unsigned int i = 0; i < (indexCount - 1); i++) {
|
||||
NSMenu* newSubmenu = nil;
|
||||
int targetIndex;
|
||||
// We remove the application menu from consideration for the top-level menu
|
||||
if (i == 0)
|
||||
targetIndex = [[indexes objectAtIndex:i] intValue] + 1;
|
||||
else
|
||||
targetIndex = [[indexes objectAtIndex:i] intValue];
|
||||
int itemCount = [currentSubmenu numberOfItems];
|
||||
if (targetIndex < itemCount) {
|
||||
NSMenuItem* menuItem = [currentSubmenu itemAtIndex:targetIndex];
|
||||
if ([menuItem hasSubmenu])
|
||||
newSubmenu = [menuItem submenu];
|
||||
}
|
||||
|
||||
if (newSubmenu)
|
||||
currentSubmenu = newSubmenu;
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int itemCount = [currentSubmenu numberOfItems];
|
||||
int targetIndex = [[indexes objectAtIndex:(indexCount - 1)] intValue];
|
||||
if (targetIndex < itemCount) {
|
||||
// NSLog(@"Performing action for native menu item titled: %@\n",
|
||||
// [[currentSubmenu itemAtIndex:targetIndex] title]);
|
||||
[currentSubmenu performActionForItemAtIndex:targetIndex];
|
||||
}
|
||||
else {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "nsIXULWindow.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsMenuUtilsX.h"
|
||||
|
||||
float nsCocoaUtils::MenuBarScreenHeight()
|
||||
{
|
||||
|
@ -191,7 +192,7 @@ void nsCocoaUtils::PrepareForNativeAppModalDialog()
|
|||
|
||||
// Don't do anything if this is embedding. We'll assume that if there is no hidden
|
||||
// window we shouldn't do anything, and that should cover the embedding case.
|
||||
nsIMenuBar* hiddenWindowMenuBar = MenuHelpersX::GetHiddenWindowMenuBar();
|
||||
nsMenuBarX* hiddenWindowMenuBar = nsMenuUtilsX::GetHiddenWindowMenuBar();
|
||||
if (!hiddenWindowMenuBar)
|
||||
return;
|
||||
|
||||
|
@ -212,7 +213,7 @@ void nsCocoaUtils::PrepareForNativeAppModalDialog()
|
|||
[firstMenuItem release];
|
||||
|
||||
// Add standard edit menu
|
||||
[newMenuBar addItem:MenuHelpersX::GetStandardEditMenuItem()];
|
||||
[newMenuBar addItem:nsMenuUtilsX::GetStandardEditMenuItem()];
|
||||
|
||||
// Show the new menu bar
|
||||
[NSApp setMainMenu:newMenuBar];
|
||||
|
@ -228,7 +229,7 @@ void nsCocoaUtils::CleanUpAfterNativeAppModalDialog()
|
|||
|
||||
// Don't do anything if this is embedding. We'll assume that if there is no hidden
|
||||
// window we shouldn't do anything, and that should cover the embedding case.
|
||||
nsIMenuBar* hiddenWindowMenuBar = MenuHelpersX::GetHiddenWindowMenuBar();
|
||||
nsMenuBarX* hiddenWindowMenuBar = nsMenuUtilsX::GetHiddenWindowMenuBar();
|
||||
if (!hiddenWindowMenuBar)
|
||||
return;
|
||||
|
||||
|
|
|
@ -46,9 +46,11 @@
|
|||
|
||||
#include "nsBaseWidget.h"
|
||||
#include "nsPIWidgetCocoa.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class nsCocoaWindow;
|
||||
class nsChildView;
|
||||
class nsMenuBarX;
|
||||
|
||||
typedef struct _nsCocoaWindowList {
|
||||
_nsCocoaWindowList() : prev(NULL), window(NULL) {}
|
||||
|
@ -210,8 +212,8 @@ public:
|
|||
NS_IMETHOD SetModal(PRBool aState);
|
||||
NS_IMETHOD IsVisible(PRBool & aState);
|
||||
NS_IMETHOD SetFocus(PRBool aState=PR_FALSE);
|
||||
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar);
|
||||
virtual nsIMenuBar* GetMenuBar();
|
||||
NS_IMETHOD SetMenuBar(void* aMenuBar);
|
||||
virtual nsMenuBarX* GetMenuBar();
|
||||
NS_IMETHOD ShowMenuBar(PRBool aShow);
|
||||
NS_IMETHOD WidgetToScreen(const nsRect& aOldRect, nsRect& aNewRect);
|
||||
NS_IMETHOD ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect);
|
||||
|
@ -275,7 +277,7 @@ protected:
|
|||
nsIWidget* mParent; // if we're a popup, this is our parent [WEAK]
|
||||
NSWindow* mWindow; // our cocoa window [STRONG]
|
||||
WindowDelegate* mDelegate; // our delegate for processing window msgs [STRONG]
|
||||
nsCOMPtr<nsIMenuBar> mMenuBar;
|
||||
nsRefPtr<nsMenuBarX> mMenuBar;
|
||||
NSWindow* mSheetWindowParent; // if this is a sheet, this is the NSWindow it's attached to
|
||||
nsChildView* mPopupContentView; // if this is a popup, this is its content widget
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsMenuBarX.h"
|
||||
#include "nsMenuUtilsX.h"
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
#include "lcms.h"
|
||||
|
@ -1117,13 +1118,6 @@ NS_IMETHODIMP nsCocoaWindow::GetChildSheet(PRBool aShown, nsCocoaWindow** _retva
|
|||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsCocoaWindow::GetMenuBar(nsIMenuBar** menuBar)
|
||||
{
|
||||
*menuBar = mMenuBar;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsCocoaWindow::GetRealParent(nsIWidget** parent)
|
||||
{
|
||||
*parent = mParent;
|
||||
|
@ -1200,15 +1194,15 @@ nsCocoaWindow::ReportSizeEvent(NSRect *r)
|
|||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsCocoaWindow::SetMenuBar(nsIMenuBar *aMenuBar)
|
||||
NS_IMETHODIMP nsCocoaWindow::SetMenuBar(void *aMenuBar)
|
||||
{
|
||||
if (mMenuBar)
|
||||
mMenuBar->SetParent(nsnull);
|
||||
mMenuBar = aMenuBar;
|
||||
mMenuBar = static_cast<nsMenuBarX*>(aMenuBar);
|
||||
|
||||
// We paint the hidden window menu bar if no other menu bar has been painted
|
||||
// yet so that some reasonable menu bar is displayed when the app starts up.
|
||||
if (!gSomeMenuBarPainted && mMenuBar && (MenuHelpersX::GetHiddenWindowMenuBar() == mMenuBar))
|
||||
if (!gSomeMenuBarPainted && mMenuBar && (nsMenuUtilsX::GetHiddenWindowMenuBar() == mMenuBar))
|
||||
mMenuBar->Paint();
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1264,7 +1258,7 @@ NS_IMETHODIMP nsCocoaWindow::ScreenToWidget(const nsRect& aOldRect, nsRect& aNew
|
|||
}
|
||||
|
||||
|
||||
nsIMenuBar* nsCocoaWindow::GetMenuBar()
|
||||
nsMenuBarX* nsCocoaWindow::GetMenuBar()
|
||||
{
|
||||
return mMenuBar;
|
||||
}
|
||||
|
@ -1410,7 +1404,7 @@ NS_IMETHODIMP nsCocoaWindow::EndSecureKeyboardInput()
|
|||
nsCocoaWindow* geckoWidget = [windowDelegate geckoWidget];
|
||||
NS_ASSERTION(geckoWidget, "Window delegate not returning a gecko widget!");
|
||||
|
||||
nsIMenuBar* geckoMenuBar = geckoWidget->GetMenuBar();
|
||||
nsMenuBarX* geckoMenuBar = geckoWidget->GetMenuBar();
|
||||
if (geckoMenuBar) {
|
||||
geckoMenuBar->Paint();
|
||||
}
|
||||
|
@ -1498,7 +1492,7 @@ NS_IMETHODIMP nsCocoaWindow::EndSecureKeyboardInput()
|
|||
// app modally. If one of those is up then we want it to retain its menu bar.
|
||||
if ([NSApp _isRunningAppModal])
|
||||
return;
|
||||
nsCOMPtr<nsIMenuBar> hiddenWindowMenuBar = MenuHelpersX::GetHiddenWindowMenuBar();
|
||||
nsRefPtr<nsMenuBarX> hiddenWindowMenuBar = nsMenuUtilsX::GetHiddenWindowMenuBar();
|
||||
if (hiddenWindowMenuBar) {
|
||||
// printf("painting hidden window menu bar due to window losing main status\n");
|
||||
hiddenWindowMenuBar->Paint();
|
||||
|
|
|
@ -1,240 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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 the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsIMenu_h__
|
||||
#define nsIMenu_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsStringFwd.h"
|
||||
#include "nsEvent.h"
|
||||
|
||||
class nsIMenuBar;
|
||||
class nsIMenu;
|
||||
class nsIMenuItem;
|
||||
class nsIContent;
|
||||
class nsIWidget;
|
||||
class nsMenuBarX;
|
||||
|
||||
|
||||
// 9225136B-3F56-4CA3-92E0-623D5FB8356B
|
||||
#define NS_IMENU_IID \
|
||||
{ 0x9225136B, 0x3F56, 0x4CA3, \
|
||||
{ 0x92, 0xE0, 0x62, 0x3D, 0x5F, 0xB8, 0x35, 0x6B } }
|
||||
|
||||
/**
|
||||
* Menu widget
|
||||
*/
|
||||
class nsIMenu : public nsISupports {
|
||||
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMENU_IID)
|
||||
|
||||
/**
|
||||
* Creates the Menu
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD Create(nsISupports * aParent, const nsAString &aLabel, const nsAString &aAccessKey,
|
||||
nsMenuBarX* aMenuBar, nsIContent* aNode) = 0;
|
||||
|
||||
/**
|
||||
* Get the Menu's Parent. This addrefs.
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetParent(nsISupports *&aParent) = 0;
|
||||
|
||||
/**
|
||||
* Get the Menu label
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetLabel(nsString &aText) = 0;
|
||||
|
||||
/**
|
||||
* Set the Menu label
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD SetLabel(const nsAString &aText) = 0;
|
||||
|
||||
/**
|
||||
* Get the Menu Access Key
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetAccessKey(nsString &aText) = 0;
|
||||
|
||||
/**
|
||||
* Set the Menu Access Key
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD SetAccessKey(const nsAString &aText) = 0;
|
||||
|
||||
/**
|
||||
* Set the Menu enabled state
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD SetEnabled(PRBool aIsEnabled) = 0;
|
||||
|
||||
/**
|
||||
* Get the Menu enabled state
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetEnabled(PRBool* aIsEnabled) = 0;
|
||||
|
||||
/**
|
||||
* Adds a Menu Item. Do not use outside of widget menu implementations.
|
||||
* Add and modify menu items via DOM content.
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD AddItem(nsISupports* aItem) = 0;
|
||||
|
||||
/**
|
||||
* Returns the number of visible menu items
|
||||
* This includes separators. It does not include hidden items.
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetVisibleItemCount(PRUint32 &aCount) = 0;
|
||||
|
||||
/**
|
||||
* Returns a Menu or Menu Item at a specified Index.
|
||||
* This includes separators. It does not include hidden items.
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetVisibleItemAt(const PRUint32 aPos, nsISupports *& aMenuItem) = 0;
|
||||
|
||||
/**
|
||||
* Returns the number of menu items
|
||||
* This includes separators. It -does- include hidden items.
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetItemCount(PRUint32 &aCount) = 0;
|
||||
|
||||
/**
|
||||
* Returns a Menu or Menu Item at a specified Index.
|
||||
* This includes separators. It -does- include hidden items.
|
||||
*
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* Sets Native MenuHandle
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD SetNativeData(void* aData) = 0;
|
||||
|
||||
/**
|
||||
* Get menu content
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetMenuContent(nsIContent ** aMenuContent) = 0;
|
||||
|
||||
/**
|
||||
* Enable/disable native widget for a particular nsIMenuItem
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD ChangeNativeEnabledStatusForMenuItem(nsIMenuItem* aMenuItem,
|
||||
PRBool aEnabled) = 0;
|
||||
|
||||
/**
|
||||
* Retrieve the native menu and the index of the item within that menu.
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetMenuRefAndItemIndexForMenuItem(nsISupports* aMenuItem,
|
||||
void** aMenuRef,
|
||||
PRUint16* aMenuItemIndex) = 0;
|
||||
|
||||
/**
|
||||
* Sets an appropriate icon for the menu.
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD SetupIcon() = 0;
|
||||
|
||||
/**
|
||||
* Menu has been selected
|
||||
*
|
||||
*/
|
||||
virtual nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent) = 0;
|
||||
|
||||
/**
|
||||
* Menu has been deselected
|
||||
*
|
||||
*/
|
||||
virtual void MenuDeselected(const nsMenuEvent & aMenuEvent) = 0;
|
||||
|
||||
/**
|
||||
* Construct menu
|
||||
*
|
||||
*/
|
||||
virtual void MenuConstruct(const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow, void * aMenuNode) = 0;
|
||||
|
||||
/**
|
||||
* Destruct menu
|
||||
*
|
||||
*/
|
||||
virtual void MenuDestruct(const nsMenuEvent & aMenuEvent) = 0;
|
||||
|
||||
/**
|
||||
* Set rebuild
|
||||
*
|
||||
*/
|
||||
virtual void SetRebuild(PRBool aMenuEvent) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMenu, NS_IMENU_IID)
|
||||
|
||||
#endif
|
|
@ -1,156 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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 the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsIMenuItem_h__
|
||||
#define nsIMenuItem_h__
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
// 33FA04E3-EAFE-4DD1-AFB3-B3BC8C712716
|
||||
#define NS_IMENUITEM_IID \
|
||||
{ 0x33FA04E3, 0xEAFE, 0x4DD1, \
|
||||
{ 0xAF, 0xB3, 0xB3, 0xBC, 0x8C, 0x71, 0x27, 0x16 } }
|
||||
|
||||
class nsIMenu;
|
||||
class nsIWidget;
|
||||
class nsIContent;
|
||||
class nsMenuBarX;
|
||||
|
||||
enum {
|
||||
knsMenuItemNoModifier = 0,
|
||||
knsMenuItemShiftModifier = (1 << 0),
|
||||
knsMenuItemAltModifier = (1 << 1),
|
||||
knsMenuItemControlModifier = (1 << 2),
|
||||
knsMenuItemCommandModifier = (1 << 3)
|
||||
};
|
||||
|
||||
/**
|
||||
* MenuItem widget
|
||||
*/
|
||||
class nsIMenuItem : public nsISupports {
|
||||
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMENUITEM_IID)
|
||||
|
||||
enum EMenuItemType { eRegular = 0, eCheckbox, eRadio, eSeparator} ;
|
||||
|
||||
/**
|
||||
* Creates the MenuItem
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD Create(nsIMenu* aParent, const nsString & aLabel, EMenuItemType aItemType,
|
||||
nsMenuBarX* aMenuBar, nsIContent* aNode) = 0;
|
||||
|
||||
/**
|
||||
* Get the MenuItem label
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetLabel(nsString &aText) = 0;
|
||||
|
||||
/**
|
||||
* Get the Menu shortcut char
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetShortcutChar(nsString &aText) = 0;
|
||||
|
||||
/**
|
||||
* Gets whether the item is enabled or disabled
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetEnabled(PRBool *aIsEnabled) = 0;
|
||||
|
||||
/**
|
||||
* Sets whether the item is checked or not
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD SetChecked(PRBool aIsEnabled) = 0;
|
||||
|
||||
/**
|
||||
* Gets whether the item is checked or not
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetChecked(PRBool *aIsEnabled) = 0;
|
||||
|
||||
/**
|
||||
* Gets whether the item is a checkbox or radio
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetMenuItemType(EMenuItemType *aType) = 0;
|
||||
|
||||
/**
|
||||
* Gets Native Menu Handle
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetNativeData(void*& aData) = 0;
|
||||
|
||||
/**
|
||||
* Indicates whether it is a separator
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD IsSeparator(PRBool & aIsSep) = 0;
|
||||
|
||||
/**
|
||||
* Executes the "cached" JavaScript Command
|
||||
* @return NS_OK if the command was executed properly, otherwise an error code
|
||||
*/
|
||||
NS_IMETHOD DoCommand() = 0;
|
||||
|
||||
/**
|
||||
* Sends a DOM event to the menu item's content node
|
||||
* @return NS_OK if the event was sent properly, otherwise an error code
|
||||
*/
|
||||
NS_IMETHOD DispatchDOMEvent(const nsString &eventName, PRBool *preventDefaultCalled) = 0;
|
||||
|
||||
/**
|
||||
* Sets an appropriate icon for the menu item.
|
||||
*/
|
||||
NS_IMETHOD SetupIcon() = 0;
|
||||
|
||||
/**
|
||||
* Get GetMenuItemContent
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD GetMenuItemContent(nsIContent ** aMenuItemContent) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMenuItem, NS_IMENUITEM_IID)
|
||||
|
||||
#endif
|
|
@ -39,35 +39,29 @@
|
|||
#ifndef nsMenuBarX_h_
|
||||
#define nsMenuBarX_h_
|
||||
|
||||
#include "nsIMenuBar.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "nsMenuBaseX.h"
|
||||
#include "nsIMutationObserver.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsINativeMenuService.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
class nsIWidget;
|
||||
class nsIDocument;
|
||||
class nsIDOMNode;
|
||||
class nsMenuX;
|
||||
class nsMenuItemX;
|
||||
class nsChangeObserver;
|
||||
class nsIWidget;
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
|
||||
extern "C" MenuRef _NSGetCarbonMenu(NSMenu* aMenu);
|
||||
|
||||
PRBool NodeIsHiddenOrCollapsed(nsIContent* inContent);
|
||||
|
||||
namespace MenuHelpersX
|
||||
// The native menu service for creating native menu bars.
|
||||
class nsNativeMenuServiceX : public nsINativeMenuService
|
||||
{
|
||||
nsEventStatus DispatchCommandTo(nsIContent* aTargetContent);
|
||||
NSString* CreateTruncatedCocoaLabel(const nsString& itemLabel);
|
||||
PRUint8 GeckoModifiersForNodeAttribute(const nsString& modifiersAttribute);
|
||||
unsigned int MacModifiersForGeckoModifiers(PRUint8 geckoModifiers);
|
||||
nsIMenuBar* GetHiddenWindowMenuBar();
|
||||
NSMenuItem* GetStandardEditMenuItem();
|
||||
}
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_IMETHOD CreateNativeMenuBar(nsIWidget* aParent, nsIContent* aMenuBarNode);
|
||||
};
|
||||
|
||||
|
||||
// Objective-C class used to allow us to have keyboard commands
|
||||
|
@ -76,8 +70,8 @@ namespace MenuHelpersX
|
|||
@interface GeckoNSMenu : NSMenu
|
||||
{
|
||||
}
|
||||
- (BOOL)performKeyEquivalent:(NSEvent *)theEvent;
|
||||
- (void)actOnKeyEquivalent:(NSEvent *)theEvent;
|
||||
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
|
||||
- (void)actOnKeyEquivalent:(NSEvent*)theEvent;
|
||||
- (void)performMenuUserInterfaceEffectsForEvent:(NSEvent*)theEvent;
|
||||
@end
|
||||
|
||||
|
@ -90,73 +84,59 @@ namespace MenuHelpersX
|
|||
@end
|
||||
|
||||
|
||||
//
|
||||
// Native menu bar wrapper
|
||||
//
|
||||
|
||||
class nsMenuBarX : public nsIMenuBar,
|
||||
public nsIMutationObserver,
|
||||
public nsSupportsWeakReference
|
||||
// Once instantiated, this object lives until its DOM node or its parent window is destroyed.
|
||||
// Do not hold references to this, they can become invalid any time the DOM node can be destroyed.
|
||||
class nsMenuBarX : public nsMenuObjectX,
|
||||
public nsIMutationObserver
|
||||
{
|
||||
public:
|
||||
nsMenuBarX();
|
||||
virtual ~nsMenuBarX();
|
||||
nsMenuBarX();
|
||||
virtual ~nsMenuBarX();
|
||||
|
||||
// |NSMenuItem|s target Objective-C objects
|
||||
static NativeMenuItemTarget* sNativeEventTarget;
|
||||
|
||||
static nsMenuBarX* sLastGeckoMenuBarPainted;
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
static NativeMenuItemTarget* sNativeEventTarget;
|
||||
static nsMenuBarX* sLastGeckoMenuBarPainted;
|
||||
|
||||
// nsIMutationObserver
|
||||
NS_DECL_NSIMUTATIONOBSERVER
|
||||
// The following content nodes have been removed from the menu system.
|
||||
// We save them here for use in command handling.
|
||||
nsCOMPtr<nsIContent> mAboutItemContent;
|
||||
nsCOMPtr<nsIContent> mPrefItemContent;
|
||||
nsCOMPtr<nsIContent> mQuitItemContent;
|
||||
|
||||
// nsIMenuBar Methods
|
||||
NS_IMETHOD Create(nsIWidget * aParent);
|
||||
NS_IMETHOD GetParent(nsIWidget *&aParent);
|
||||
NS_IMETHOD SetParent(nsIWidget * aParent);
|
||||
NS_IMETHOD AddMenu(nsIMenu * aMenu);
|
||||
NS_IMETHOD GetMenuCount(PRUint32 &aCount);
|
||||
NS_IMETHOD GetMenuAt(const PRUint32 aCount, nsIMenu *& aMenu);
|
||||
NS_IMETHOD InsertMenuAt(const PRUint32 aCount, nsIMenu *& aMenu);
|
||||
NS_IMETHOD RemoveMenu(const PRUint32 aCount);
|
||||
NS_IMETHOD RemoveAll();
|
||||
NS_IMETHOD GetNativeData(void*& aData);
|
||||
NS_IMETHOD Paint();
|
||||
NS_IMETHOD SetNativeData(void* aData);
|
||||
NS_IMETHOD MenuConstruct(const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow, void * aMenuNode);
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMUTATIONOBSERVER
|
||||
|
||||
PRUint32 RegisterForCommand(nsIMenuItem* aItem);
|
||||
void UnregisterCommand(PRUint32 aCommandID);
|
||||
nsIMenuItem* GetMenuItemForCommandID(PRUint32 inCommandID);
|
||||
// nsMenuObjectX
|
||||
void* NativeData() {return (void*)mRootMenu;}
|
||||
nsMenuObjectTypeX MenuObjectType() {return eMenuBarObjectType;}
|
||||
|
||||
void RegisterForContentChanges(nsIContent* aContent, nsChangeObserver* aMenuObject);
|
||||
void UnregisterForContentChanges(nsIContent* aContent);
|
||||
nsChangeObserver* LookupContentChangeObserver(nsIContent* aContent);
|
||||
// nsMenuBarX
|
||||
nsresult Create(nsIWidget* aParent, nsIContent* aContent);
|
||||
void SetParent(nsIWidget* aParent);
|
||||
void RegisterForContentChanges(nsIContent* aContent, nsChangeObserver* aMenuObject);
|
||||
void UnregisterForContentChanges(nsIContent* aContent);
|
||||
PRUint32 RegisterForCommand(nsMenuItemX* aItem);
|
||||
void UnregisterCommand(PRUint32 aCommandID);
|
||||
PRUint32 GetMenuCount();
|
||||
nsMenuX* GetMenuAt(PRUint32 aIndex);
|
||||
nsMenuItemX* GetMenuItemForCommandID(PRUint32 inCommandID);
|
||||
nsresult Paint();
|
||||
|
||||
nsCOMPtr<nsIContent> mAboutItemContent; // holds the content node for the about item that has
|
||||
// been removed from the menubar
|
||||
nsCOMPtr<nsIContent> mPrefItemContent; // as above, but for prefs
|
||||
nsCOMPtr<nsIContent> mQuitItemContent; // as above, but for quit
|
||||
protected:
|
||||
// Make our menubar conform to Aqua UI guidelines
|
||||
void AquifyMenuBar();
|
||||
void HideItem(nsIDOMDocument* inDoc, const nsAString & inID, nsIContent** outHiddenNode);
|
||||
nsresult AddMenu(nsMenuX* aMenu);
|
||||
void RemoveMenu(PRUint32 aIndex);
|
||||
nsChangeObserver* LookupContentChangeObserver(nsIContent* aContent);
|
||||
void HideItem(nsIDOMDocument* inDoc, const nsAString & inID, nsIContent** outHiddenNode);
|
||||
void AquifyMenuBar();
|
||||
NSMenuItem* CreateNativeAppMenuItem(nsMenuX* inMenu, const nsAString& nodeID, SEL action,
|
||||
int tag, NativeMenuItemTarget* target);
|
||||
nsresult CreateApplicationMenu(nsMenuX* inMenu);
|
||||
|
||||
// build the Application menu shared by all menu bars.
|
||||
NSMenuItem* CreateNativeAppMenuItem(nsIMenu* inMenu, const nsAString& nodeID, SEL action,
|
||||
int tag, NativeMenuItemTarget* target);
|
||||
nsresult CreateApplicationMenu(nsIMenu* inMenu);
|
||||
|
||||
nsCOMArray<nsIMenu> mMenusArray; // holds refs
|
||||
nsCOMPtr<nsIContent> mMenuBarContent; // menubar content node, strong ref
|
||||
nsIWidget* mParent; // weak ref
|
||||
PRBool mIsMenuBarAdded;
|
||||
PRUint32 mCurrentCommandID; // unique command id (per menu-bar) to give to next item that asks
|
||||
nsIDocument* mDocument; // pointer to document
|
||||
GeckoNSMenu* mRootMenu; // root menu, representing entire menu bar
|
||||
nsHashtable mObserverTable; // stores observers for content change notification
|
||||
nsTArray< nsAutoPtr<nsMenuX> > mMenuArray;
|
||||
nsIWidget* mParent; // [weak]
|
||||
PRUint32 mCurrentCommandID; // unique command id (per menu-bar) to give to next item that asks
|
||||
nsIDocument* mDocument; // pointer to document
|
||||
GeckoNSMenu* mRootMenu; // root menu, representing entire menu bar
|
||||
nsHashtable mObserverTable; // stores observers for content change notification
|
||||
};
|
||||
|
||||
#endif // nsMenuBarX_h_
|
||||
|
|
|
@ -36,37 +36,28 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIMenu.h"
|
||||
#include "nsIMenuItem.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
#include "nsMenuBarX.h"
|
||||
#include "nsMenuX.h"
|
||||
#include "nsChildView.h"
|
||||
#include "nsMenuItemX.h"
|
||||
#include "nsMenuUtilsX.h"
|
||||
#include "nsCocoaUtils.h"
|
||||
#include "nsCocoaWindow.h"
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIMutationObserver.h"
|
||||
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsWidgetAtoms.h"
|
||||
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
// CIDs
|
||||
#include "nsWidgetsCID.h"
|
||||
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
|
||||
#include "nsIContent.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS3(nsMenuBarX, nsIMenuBar, nsIMutationObserver, nsISupportsWeakReference)
|
||||
NS_IMPL_ISUPPORTS1(nsMenuBarX, nsIMutationObserver)
|
||||
|
||||
NativeMenuItemTarget* nsMenuBarX::sNativeEventTarget = nil;
|
||||
nsMenuBarX* nsMenuBarX::sLastGeckoMenuBarPainted = nsnull;
|
||||
|
@ -92,18 +83,22 @@ enum {
|
|||
};
|
||||
|
||||
|
||||
PRBool NodeIsHiddenOrCollapsed(nsIContent* inContent)
|
||||
NS_IMPL_ISUPPORTS1(nsNativeMenuServiceX, nsINativeMenuService)
|
||||
|
||||
NS_IMETHODIMP nsNativeMenuServiceX::CreateNativeMenuBar(nsIWidget* aParent, nsIContent* aMenuBarNode)
|
||||
{
|
||||
return (inContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::hidden,
|
||||
nsWidgetAtoms::_true, eCaseMatters) ||
|
||||
inContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::collapsed,
|
||||
nsWidgetAtoms::_true, eCaseMatters));
|
||||
NS_ASSERTION(NS_IsMainThread(), "Attempting to create native menu bar on wrong thread!");
|
||||
|
||||
nsRefPtr<nsMenuBarX> mb = new nsMenuBarX();
|
||||
if (!mb)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return mb->Create(aParent, aMenuBarNode);
|
||||
}
|
||||
|
||||
|
||||
nsMenuBarX::nsMenuBarX()
|
||||
: mParent(nsnull),
|
||||
mIsMenuBarAdded(PR_FALSE),
|
||||
mCurrentCommandID(eCommand_ID_Last),
|
||||
mDocument(nsnull)
|
||||
{
|
||||
|
@ -122,8 +117,6 @@ nsMenuBarX::~nsMenuBarX()
|
|||
if (nsMenuBarX::sLastGeckoMenuBarPainted == this)
|
||||
nsMenuBarX::sLastGeckoMenuBarPainted = nsnull;
|
||||
|
||||
mMenusArray.Clear(); // release all menus
|
||||
|
||||
// the quit/pref items of a random window might have been used if there was no
|
||||
// hidden window, thus we need to invalidate the weak references.
|
||||
if (sAboutItemContent == mAboutItemContent)
|
||||
|
@ -136,18 +129,174 @@ nsMenuBarX::~nsMenuBarX()
|
|||
// make sure we unregister ourselves as a document observer
|
||||
if (mDocument)
|
||||
mDocument->RemoveMutationObserver(this);
|
||||
|
||||
|
||||
// We have to manually clear the array here because clearing causes menu items
|
||||
// to call back into the menu bar to unregister themselves. We don't want to
|
||||
// depend on member variable ordering to ensure that the array gets cleared
|
||||
// before the registration hash table is destroyed.
|
||||
mMenuArray.Clear();
|
||||
|
||||
[mRootMenu release];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
|
||||
// Do what's necessary to conform to the Aqua guidelines for menus.
|
||||
void
|
||||
nsMenuBarX::AquifyMenuBar()
|
||||
nsresult nsMenuBarX::Create(nsIWidget* aParent, nsIContent* aContent)
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mMenuBarContent->GetDocument()));
|
||||
if (!aParent || !aContent)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
mParent = aParent;
|
||||
mContent = aContent;
|
||||
|
||||
AquifyMenuBar();
|
||||
|
||||
nsIDocument* doc = aContent->GetOwnerDoc();
|
||||
if (!doc)
|
||||
return NS_ERROR_FAILURE;
|
||||
doc->AddMutationObserver(this);
|
||||
mDocument = doc;
|
||||
|
||||
PRUint32 count = mContent->GetChildCount();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
nsIContent *menuContent = mContent->GetChildAt(i);
|
||||
if (menuContent) {
|
||||
if (menuContent->Tag() == nsWidgetAtoms::menu &&
|
||||
menuContent->IsNodeOfType(nsINode::eXUL)) {
|
||||
nsAutoString menuName;
|
||||
menuContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::label, menuName);
|
||||
nsMenuX* newMenu = new nsMenuX();
|
||||
if (newMenu) {
|
||||
nsresult rv = newMenu->Create(this, menuName, this, menuContent);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
AddMenu(newMenu);
|
||||
else
|
||||
delete newMenu;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Give this to the parent window. The parent takes ownership.
|
||||
return mParent->SetMenuBar(this);
|
||||
}
|
||||
|
||||
|
||||
PRUint32 nsMenuBarX::GetMenuCount()
|
||||
{
|
||||
return mMenuArray.Length();
|
||||
}
|
||||
|
||||
|
||||
nsresult nsMenuBarX::AddMenu(nsMenuX* aMenu)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
// If we haven't created a global Application menu yet, do it.
|
||||
if (!sApplicationMenu) {
|
||||
nsresult rv = NS_OK; // avoid warning about rv being unused
|
||||
rv = CreateApplicationMenu(aMenu);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create Application menu");
|
||||
|
||||
// Hook the new Application menu up to the menu bar.
|
||||
NSMenu* mainMenu = [NSApp mainMenu];
|
||||
NS_ASSERTION([mainMenu numberOfItems] > 0, "Main menu does not have any items, something is terribly wrong!");
|
||||
[[mainMenu itemAtIndex:0] setSubmenu:sApplicationMenu];
|
||||
}
|
||||
|
||||
// keep track of all added menus
|
||||
mMenuArray.AppendElement(aMenu); // owner
|
||||
|
||||
NSMenu* nativeMenu = (NSMenu*)aMenu->NativeData();
|
||||
nsIContent* menuContent = aMenu->Content();
|
||||
if (menuContent->GetChildCount() > 0 &&
|
||||
!nsMenuUtilsX::NodeIsHiddenOrCollapsed(menuContent)) {
|
||||
NSMenuItem* newMenuItem = [[[NSMenuItem alloc] initWithTitle:[nativeMenu title] action:NULL keyEquivalent:@""] autorelease];
|
||||
[mRootMenu addItem:newMenuItem];
|
||||
[newMenuItem setSubmenu:nativeMenu];
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
|
||||
void nsMenuBarX::RemoveMenu(PRUint32 aIndex)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NS_ASSERTION(aIndex < mMenuArray.Length(), "Attempting submenu removal with bad index!");
|
||||
|
||||
// Our native menu and our internal menu object array might be out of sync.
|
||||
// This happens, for example, when a submenu is hidden. Because of this we
|
||||
// should not assume that a native submenu is hooked up.
|
||||
[mRootMenu removeItem:(mMenuArray[aIndex]->NativeMenuItem())];
|
||||
mMenuArray.RemoveElementAt(aIndex);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
|
||||
nsMenuX* nsMenuBarX::GetMenuAt(PRUint32 aIndex)
|
||||
{
|
||||
if (mMenuArray.Length() <= aIndex) {
|
||||
NS_ERROR("Requesting menu at invalid index!");
|
||||
return NULL;
|
||||
}
|
||||
return mMenuArray[aIndex];
|
||||
}
|
||||
|
||||
|
||||
nsresult nsMenuBarX::Paint()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
NSMenu* mainMenu = [NSApp mainMenu];
|
||||
NS_ASSERTION([mainMenu numberOfItems] > 0, "Main menu does not have any items, something is terribly wrong!");
|
||||
|
||||
// Swap out first item into incoming menu bar. We have to keep the same menu item for the
|
||||
// Application menu and its submenu is global so we keep passing it along.
|
||||
NSMenuItem* firstMenuItem = [[mainMenu itemAtIndex:0] retain];
|
||||
[mainMenu removeItemAtIndex:0];
|
||||
[mRootMenu insertItem:firstMenuItem atIndex:0];
|
||||
[firstMenuItem release];
|
||||
|
||||
// Set menu bar and event target.
|
||||
[NSApp setMainMenu:mRootMenu];
|
||||
nsMenuBarX::sLastGeckoMenuBarPainted = this;
|
||||
|
||||
gSomeMenuBarPainted = YES;
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
|
||||
// Hide the item in the menu by setting the 'hidden' attribute. Returns it in |outHiddenNode| so
|
||||
// the caller can hang onto it if they so choose. It is acceptable to pass nsull
|
||||
// for |outHiddenNode| if the caller doesn't care about the hidden node.
|
||||
void nsMenuBarX::HideItem(nsIDOMDocument* inDoc, const nsAString & inID, nsIContent** outHiddenNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> menuItem;
|
||||
inDoc->GetElementById(inID, getter_AddRefs(menuItem));
|
||||
nsCOMPtr<nsIContent> menuContent(do_QueryInterface(menuItem));
|
||||
if (menuContent) {
|
||||
menuContent->SetAttr(kNameSpaceID_None, nsWidgetAtoms::hidden, NS_LITERAL_STRING("true"), PR_FALSE);
|
||||
if (outHiddenNode) {
|
||||
*outHiddenNode = menuContent.get();
|
||||
NS_IF_ADDREF(*outHiddenNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Do what is necessary to conform to the Aqua guidelines for menus.
|
||||
void nsMenuBarX::AquifyMenuBar()
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mContent->GetDocument()));
|
||||
if (domDoc) {
|
||||
// remove the "About..." item and its separator
|
||||
HideItem(domDoc, NS_LITERAL_STRING("aboutSeparator"), nsnull);
|
||||
|
@ -177,145 +326,13 @@ nsMenuBarX::AquifyMenuBar()
|
|||
}
|
||||
|
||||
|
||||
// Hide the item in the menu by setting the 'hidden' attribute. Returns it in |outHiddenNode| so
|
||||
// the caller can hang onto it if they so choose. It is acceptable to pass nsull
|
||||
// for |outHiddenNode| if the caller doesn't care about the hidden node.
|
||||
void
|
||||
nsMenuBarX::HideItem(nsIDOMDocument* inDoc, const nsAString & inID, nsIContent** outHiddenNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> menuItem;
|
||||
inDoc->GetElementById(inID, getter_AddRefs(menuItem));
|
||||
nsCOMPtr<nsIContent> menuContent(do_QueryInterface(menuItem));
|
||||
if (menuContent) {
|
||||
menuContent->SetAttr(kNameSpaceID_None, nsWidgetAtoms::hidden, NS_LITERAL_STRING("true"), PR_FALSE);
|
||||
if (outHiddenNode) {
|
||||
*outHiddenNode = menuContent.get();
|
||||
NS_IF_ADDREF(*outHiddenNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuBarX::MenuConstruct(const nsMenuEvent & aMenuEvent, nsIWidget* aParentWindow, void * aMenubarNode)
|
||||
{
|
||||
nsIDOMNode* domNode = static_cast<nsIDOMNode*>(aMenubarNode);
|
||||
mMenuBarContent = do_QueryInterface(domNode); // strong ref
|
||||
NS_ASSERTION(mMenuBarContent, "No content specified for this menubar");
|
||||
if (!mMenuBarContent)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
SetParent(aParentWindow);
|
||||
|
||||
AquifyMenuBar();
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
domNode->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
|
||||
if (!doc)
|
||||
return NS_ERROR_FAILURE;
|
||||
doc->AddMutationObserver(this);
|
||||
mDocument = doc;
|
||||
|
||||
PRUint32 count = mMenuBarContent->GetChildCount();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
nsIContent *menu = mMenuBarContent->GetChildAt(i);
|
||||
if (menu) {
|
||||
if (menu->Tag() == nsWidgetAtoms::menu &&
|
||||
menu->IsNodeOfType(nsINode::eXUL)) {
|
||||
nsAutoString menuName;
|
||||
nsAutoString menuAccessKey(NS_LITERAL_STRING(" "));
|
||||
menu->GetAttr(kNameSpaceID_None, nsWidgetAtoms::label, menuName);
|
||||
menu->GetAttr(kNameSpaceID_None, nsWidgetAtoms::accesskey, menuAccessKey);
|
||||
|
||||
// Create nsMenu, the menubar will own it
|
||||
nsCOMPtr<nsIMenu> pnsMenu(do_CreateInstance(kMenuCID));
|
||||
if (pnsMenu) {
|
||||
pnsMenu->Create(static_cast<nsIMenuBar*>(this), menuName, menuAccessKey, this, menu);
|
||||
AddMenu(pnsMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Give the aParentWindow this nsMenuBarX to hold onto.
|
||||
// The parent takes ownership.
|
||||
aParentWindow->SetMenuBar(this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuBarX::Create(nsIWidget *aParent)
|
||||
{
|
||||
SetParent(aParent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuBarX::GetParent(nsIWidget *&aParent)
|
||||
{
|
||||
NS_IF_ADDREF(aParent = mParent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuBarX::SetParent(nsIWidget *aParent)
|
||||
{
|
||||
mParent = aParent; // weak ref
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuBarX::AddMenu(nsIMenu * aMenu)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
// If we haven't created a global Application menu yet, do it.
|
||||
if (!sApplicationMenu) {
|
||||
nsresult rv = NS_OK; // avoid warning about rv being unused
|
||||
rv = CreateApplicationMenu(aMenu);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create Application menu");
|
||||
|
||||
// Hook the new Application menu up to the menu bar.
|
||||
NSMenu* mainMenu = [NSApp mainMenu];
|
||||
NS_ASSERTION([mainMenu numberOfItems] > 0, "Main menu does not have any items, something is terribly wrong!");
|
||||
[[mainMenu itemAtIndex:0] setSubmenu:sApplicationMenu];
|
||||
}
|
||||
|
||||
// keep track of all added menus
|
||||
mMenusArray.AppendObject(aMenu); // owner
|
||||
|
||||
NSMenu* nativeMenu = NULL;
|
||||
aMenu->GetNativeData((void**)&nativeMenu);
|
||||
|
||||
nsCOMPtr<nsIContent> menu;
|
||||
aMenu->GetMenuContent(getter_AddRefs(menu));
|
||||
if (menu->GetChildCount() > 0 &&
|
||||
!NodeIsHiddenOrCollapsed(menu)) {
|
||||
NSMenuItem* newMenuItem = [[[NSMenuItem alloc] initWithTitle:[nativeMenu title] action:NULL keyEquivalent:@""] autorelease];
|
||||
[mRootMenu addItem:newMenuItem];
|
||||
[newMenuItem setSubmenu:nativeMenu];
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
|
||||
// for creating menu items destined for the Application menu
|
||||
NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsIMenu* inMenu, const nsAString& nodeID, SEL action,
|
||||
NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsMenuX* inMenu, const nsAString& nodeID, SEL action,
|
||||
int tag, NativeMenuItemTarget* target)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
nsCOMPtr<nsIContent> menu;
|
||||
inMenu->GetMenuContent(getter_AddRefs(menu));
|
||||
if (!menu)
|
||||
return nil;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = menu->GetDocument();
|
||||
nsCOMPtr<nsIDocument> doc = inMenu->Content()->GetDocument();
|
||||
if (!doc)
|
||||
return nil;
|
||||
|
||||
|
@ -356,8 +373,8 @@ NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsIMenu* inMenu, const nsAString
|
|||
// now grab the key equivalent modifiers
|
||||
nsAutoString modifiersStr;
|
||||
keyContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::modifiers, modifiersStr);
|
||||
PRUint8 geckoModifiers = MenuHelpersX::GeckoModifiersForNodeAttribute(modifiersStr);
|
||||
macKeyModifiers = MenuHelpersX::MacModifiersForGeckoModifiers(geckoModifiers);
|
||||
PRUint8 geckoModifiers = nsMenuUtilsX::GeckoModifiersForNodeAttribute(modifiersStr);
|
||||
macKeyModifiers = nsMenuUtilsX::MacModifiersForGeckoModifiers(geckoModifiers);
|
||||
}
|
||||
}
|
||||
// get the label into NSString-form
|
||||
|
@ -382,8 +399,7 @@ NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsIMenu* inMenu, const nsAString
|
|||
|
||||
|
||||
// build the Application menu shared by all menu bars
|
||||
nsresult
|
||||
nsMenuBarX::CreateApplicationMenu(nsIMenu* inMenu)
|
||||
nsresult nsMenuBarX::CreateApplicationMenu(nsMenuX* inMenu)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
|
@ -536,111 +552,33 @@ nsMenuBarX::CreateApplicationMenu(nsIMenu* inMenu)
|
|||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuBarX::GetMenuCount(PRUint32 &aCount)
|
||||
void nsMenuBarX::SetParent(nsIWidget* aParent)
|
||||
{
|
||||
aCount = mMenusArray.Count();
|
||||
return NS_OK;
|
||||
mParent = aParent;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuBarX::GetMenuAt(const PRUint32 aCount, nsIMenu *& aMenu)
|
||||
{
|
||||
aMenu = NULL;
|
||||
nsCOMPtr<nsIMenu> menu = mMenusArray.ObjectAt(aCount);
|
||||
if (!menu)
|
||||
return NS_OK;
|
||||
|
||||
return CallQueryInterface(menu, &aMenu); // addref
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuBarX::InsertMenuAt(const PRUint32 aCount, nsIMenu *& aMenu)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuBarX::RemoveMenu(const PRUint32 aCount)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
mMenusArray.RemoveObjectAt(aCount);
|
||||
[mRootMenu removeItemAtIndex:aCount];
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuBarX::RemoveAll()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuBarX::GetNativeData(void *& aData)
|
||||
{
|
||||
aData = (void*)mRootMenu;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuBarX::SetNativeData(void* aData)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuBarX::Paint()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
NSMenu* mainMenu = [NSApp mainMenu];
|
||||
NS_ASSERTION([mainMenu numberOfItems] > 0, "Main menu does not have any items, something is terribly wrong!");
|
||||
|
||||
// Swap out first item into incoming menu bar. We have to keep the same menu item for the
|
||||
// Application menu and its submenu is global so we keep passing it along.
|
||||
NSMenuItem* firstMenuItem = [[mainMenu itemAtIndex:0] retain];
|
||||
[mainMenu removeItemAtIndex:0];
|
||||
[mRootMenu insertItem:firstMenuItem atIndex:0];
|
||||
[firstMenuItem release];
|
||||
|
||||
// Set menu bar and event target.
|
||||
[NSApp setMainMenu:mRootMenu];
|
||||
nsMenuBarX::sLastGeckoMenuBarPainted = this;
|
||||
|
||||
gSomeMenuBarPainted = YES;
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// nsIMutationObserver
|
||||
//
|
||||
|
||||
void
|
||||
nsMenuBarX::CharacterDataWillChange(nsIDocument * aDocument,
|
||||
nsIContent * aContent,
|
||||
CharacterDataChangeInfo * aInfo)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuBarX::CharacterDataChanged(nsIDocument * aDocument,
|
||||
nsIContent * aContent,
|
||||
CharacterDataChangeInfo * aInfo)
|
||||
void nsMenuBarX::CharacterDataWillChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
CharacterDataChangeInfo* aInfo)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsMenuBarX::ContentAppended(nsIDocument* aDocument, nsIContent* aContainer,
|
||||
PRInt32 aNewIndexInContainer)
|
||||
void nsMenuBarX::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
CharacterDataChangeInfo* aInfo)
|
||||
{
|
||||
if (aContainer != mMenuBarContent) {
|
||||
}
|
||||
|
||||
|
||||
void nsMenuBarX::ContentAppended(nsIDocument* aDocument, nsIContent* aContainer,
|
||||
PRInt32 aNewIndexInContainer)
|
||||
{
|
||||
if (aContainer != mContent) {
|
||||
nsChangeObserver* obs = LookupContentChangeObserver(aContainer);
|
||||
if (obs)
|
||||
obs->ObserveContentInserted(aDocument, aContainer, aNewIndexInContainer);
|
||||
|
@ -656,17 +594,15 @@ nsMenuBarX::ContentAppended(nsIDocument* aDocument, nsIContent* aContainer,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
nsMenuBarX::NodeWillBeDestroyed(const nsINode * aNode)
|
||||
void nsMenuBarX::NodeWillBeDestroyed(const nsINode * aNode)
|
||||
{
|
||||
mDocument = nsnull;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsMenuBarX::AttributeChanged(nsIDocument * aDocument, nsIContent * aContent,
|
||||
PRInt32 aNameSpaceID, nsIAtom * aAttribute,
|
||||
PRInt32 aModType, PRUint32 aStateMask)
|
||||
void nsMenuBarX::AttributeChanged(nsIDocument * aDocument, nsIContent * aContent,
|
||||
PRInt32 aNameSpaceID, nsIAtom * aAttribute,
|
||||
PRInt32 aModType, PRUint32 aStateMask)
|
||||
{
|
||||
// lookup and dispatch to registered thang
|
||||
nsChangeObserver* obs = LookupContentChangeObserver(aContent);
|
||||
|
@ -675,11 +611,10 @@ nsMenuBarX::AttributeChanged(nsIDocument * aDocument, nsIContent * aContent,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
nsMenuBarX::ContentRemoved(nsIDocument * aDocument, nsIContent * aContainer,
|
||||
nsIContent * aChild, PRInt32 aIndexInContainer)
|
||||
void nsMenuBarX::ContentRemoved(nsIDocument * aDocument, nsIContent * aContainer,
|
||||
nsIContent * aChild, PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (aContainer == mMenuBarContent) {
|
||||
if (aContainer == mContent) {
|
||||
UnregisterForContentChanges(aChild);
|
||||
RemoveMenu(aIndexInContainer);
|
||||
}
|
||||
|
@ -700,11 +635,10 @@ nsMenuBarX::ContentRemoved(nsIDocument * aDocument, nsIContent * aContainer,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
nsMenuBarX::ContentInserted(nsIDocument * aDocument, nsIContent * aContainer,
|
||||
nsIContent * aChild, PRInt32 aIndexInContainer)
|
||||
void nsMenuBarX::ContentInserted(nsIDocument * aDocument, nsIContent * aContainer,
|
||||
nsIContent * aChild, PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (aContainer != mMenuBarContent) {
|
||||
if (aContainer != mContent) {
|
||||
nsChangeObserver* obs = LookupContentChangeObserver(aContainer);
|
||||
if (obs)
|
||||
obs->ObserveContentInserted(aDocument, aChild, aIndexInContainer);
|
||||
|
@ -720,8 +654,7 @@ nsMenuBarX::ContentInserted(nsIDocument * aDocument, nsIContent * aContainer,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
nsMenuBarX::ParentChainChanged(nsIContent *aContent)
|
||||
void nsMenuBarX::ParentChainChanged(nsIContent *aContent)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -730,24 +663,21 @@ nsMenuBarX::ParentChainChanged(nsIContent *aContent)
|
|||
// lifetime of all these items is bounded by the lifetime of the menubar. No need to add
|
||||
// any more strong refs to the picture because the containment hierarchy already uses
|
||||
// strong refs.
|
||||
void
|
||||
nsMenuBarX::RegisterForContentChanges(nsIContent *aContent, nsChangeObserver *aMenuObject)
|
||||
void nsMenuBarX::RegisterForContentChanges(nsIContent *aContent, nsChangeObserver *aMenuObject)
|
||||
{
|
||||
nsVoidKey key(aContent);
|
||||
mObserverTable.Put(&key, aMenuObject);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsMenuBarX::UnregisterForContentChanges(nsIContent *aContent)
|
||||
void nsMenuBarX::UnregisterForContentChanges(nsIContent *aContent)
|
||||
{
|
||||
nsVoidKey key(aContent);
|
||||
mObserverTable.Remove(&key);
|
||||
}
|
||||
|
||||
|
||||
nsChangeObserver*
|
||||
nsMenuBarX::LookupContentChangeObserver(nsIContent* aContent)
|
||||
nsChangeObserver* nsMenuBarX::LookupContentChangeObserver(nsIContent* aContent)
|
||||
{
|
||||
nsVoidKey key(aContent);
|
||||
return reinterpret_cast<nsChangeObserver*>(mObserverTable.Get(&key));
|
||||
|
@ -756,8 +686,7 @@ nsMenuBarX::LookupContentChangeObserver(nsIContent* aContent)
|
|||
|
||||
// Given a menu item, creates a unique 4-character command ID and
|
||||
// maps it to the item. Returns the id for use by the client.
|
||||
PRUint32
|
||||
nsMenuBarX::RegisterForCommand(nsIMenuItem* inMenuItem)
|
||||
PRUint32 nsMenuBarX::RegisterForCommand(nsMenuItemX* inMenuItem)
|
||||
{
|
||||
// no real need to check for uniqueness. We always start afresh with each
|
||||
// window at 1. Even if we did get close to the reserved Apple command id's,
|
||||
|
@ -777,164 +706,17 @@ nsMenuBarX::RegisterForCommand(nsIMenuItem* inMenuItem)
|
|||
|
||||
// Removes the mapping between the given 4-character command ID
|
||||
// and its associated menu item.
|
||||
void
|
||||
nsMenuBarX::UnregisterCommand(PRUint32 inCommandID)
|
||||
void nsMenuBarX::UnregisterCommand(PRUint32 inCommandID)
|
||||
{
|
||||
nsPRUint32Key key(inCommandID);
|
||||
mObserverTable.Remove(&key);
|
||||
}
|
||||
|
||||
|
||||
nsIMenuItem*
|
||||
nsMenuBarX::GetMenuItemForCommandID(PRUint32 inCommandID)
|
||||
nsMenuItemX* nsMenuBarX::GetMenuItemForCommandID(PRUint32 inCommandID)
|
||||
{
|
||||
nsPRUint32Key key(inCommandID);
|
||||
return reinterpret_cast<nsIMenuItem*>(mObserverTable.Get(&key));
|
||||
}
|
||||
|
||||
|
||||
nsEventStatus
|
||||
MenuHelpersX::DispatchCommandTo(nsIContent* aTargetContent)
|
||||
{
|
||||
NS_PRECONDITION(aTargetContent, "null ptr");
|
||||
|
||||
nsEventStatus status = nsEventStatus_eConsumeNoDefault;
|
||||
nsXULCommandEvent event(PR_TRUE, NS_XUL_COMMAND, nsnull);
|
||||
|
||||
// FIXME: Should probably figure out how to init this with the actual
|
||||
// pressed keys, but this is a big old edge case anyway. -dwh
|
||||
|
||||
aTargetContent->DispatchDOMEvent(&event, nsnull, nsnull, &status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
NSString* MenuHelpersX::CreateTruncatedCocoaLabel(const nsString& itemLabel)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
// ::TruncateThemeText() doesn't take the number of characters to truncate to, it takes a pixel with
|
||||
// to fit the string in. Ugh. I talked it over with sfraser and we couldn't come up with an
|
||||
// easy way to compute what this should be given the system font, etc, so we're just going
|
||||
// to hard code it to something reasonable and bigger fonts will just have to deal.
|
||||
const short kMaxItemPixelWidth = 300;
|
||||
NSMutableString *label = [[NSMutableString stringWithCharacters:itemLabel.get() length:itemLabel.Length()] retain];
|
||||
::TruncateThemeText((CFMutableStringRef)label, kThemeMenuItemFont, kThemeStateActive, kMaxItemPixelWidth, truncMiddle, NULL);
|
||||
return label; // caller releases
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
|
||||
PRUint8 MenuHelpersX::GeckoModifiersForNodeAttribute(const nsString& modifiersAttribute)
|
||||
{
|
||||
PRUint8 modifiers = knsMenuItemNoModifier;
|
||||
char* str = ToNewCString(modifiersAttribute);
|
||||
char* newStr;
|
||||
char* token = nsCRT::strtok(str, ", \t", &newStr);
|
||||
while (token != NULL) {
|
||||
if (PL_strcmp(token, "shift") == 0)
|
||||
modifiers |= knsMenuItemShiftModifier;
|
||||
else if (PL_strcmp(token, "alt") == 0)
|
||||
modifiers |= knsMenuItemAltModifier;
|
||||
else if (PL_strcmp(token, "control") == 0)
|
||||
modifiers |= knsMenuItemControlModifier;
|
||||
else if ((PL_strcmp(token, "accel") == 0) ||
|
||||
(PL_strcmp(token, "meta") == 0)) {
|
||||
modifiers |= knsMenuItemCommandModifier;
|
||||
}
|
||||
token = nsCRT::strtok(newStr, ", \t", &newStr);
|
||||
}
|
||||
nsMemory::Free(str);
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
|
||||
unsigned int MenuHelpersX::MacModifiersForGeckoModifiers(PRUint8 geckoModifiers)
|
||||
{
|
||||
unsigned int macModifiers = 0;
|
||||
|
||||
if (geckoModifiers & knsMenuItemShiftModifier)
|
||||
macModifiers |= NSShiftKeyMask;
|
||||
if (geckoModifiers & knsMenuItemAltModifier)
|
||||
macModifiers |= NSAlternateKeyMask;
|
||||
if (geckoModifiers & knsMenuItemControlModifier)
|
||||
macModifiers |= NSControlKeyMask;
|
||||
if (geckoModifiers & knsMenuItemCommandModifier)
|
||||
macModifiers |= NSCommandKeyMask;
|
||||
|
||||
return macModifiers;
|
||||
}
|
||||
|
||||
|
||||
nsIMenuBar* MenuHelpersX::GetHiddenWindowMenuBar()
|
||||
{
|
||||
nsIWidget* hiddenWindowWidgetNoCOMPtr = nsCocoaUtils::GetHiddenWindowWidget();
|
||||
if (hiddenWindowWidgetNoCOMPtr)
|
||||
return static_cast<nsCocoaWindow*>(hiddenWindowWidgetNoCOMPtr)->GetMenuBar();
|
||||
else
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
// It would be nice if we could localize these edit menu names.
|
||||
static NSMenuItem* standardEditMenuItem = nil;
|
||||
NSMenuItem* MenuHelpersX::GetStandardEditMenuItem()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (standardEditMenuItem)
|
||||
return standardEditMenuItem;
|
||||
|
||||
NSMenuItem* standardEditMenuItem = [[NSMenuItem alloc] initWithTitle:@"Edit" action:nil keyEquivalent:@""];
|
||||
NSMenu* standardEditMenu = [[NSMenu alloc] initWithTitle:@"Edit"];
|
||||
[standardEditMenuItem setSubmenu:standardEditMenu];
|
||||
[standardEditMenu release];
|
||||
|
||||
// Add Undo
|
||||
NSMenuItem* undoItem = [[NSMenuItem alloc] initWithTitle:@"Undo" action:@selector(undo:) keyEquivalent:@"z"];
|
||||
[standardEditMenu addItem:undoItem];
|
||||
[undoItem release];
|
||||
|
||||
// Add Redo
|
||||
NSMenuItem* redoItem = [[NSMenuItem alloc] initWithTitle:@"Redo" action:@selector(redo:) keyEquivalent:@"Z"];
|
||||
[standardEditMenu addItem:redoItem];
|
||||
[redoItem release];
|
||||
|
||||
// Add separator
|
||||
[standardEditMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
// Add Cut
|
||||
NSMenuItem* cutItem = [[NSMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"];
|
||||
[standardEditMenu addItem:cutItem];
|
||||
[cutItem release];
|
||||
|
||||
// Add Copy
|
||||
NSMenuItem* copyItem = [[NSMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"];
|
||||
[standardEditMenu addItem:copyItem];
|
||||
[copyItem release];
|
||||
|
||||
// Add Paste
|
||||
NSMenuItem* pasteItem = [[NSMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:) keyEquivalent:@"v"];
|
||||
[standardEditMenu addItem:pasteItem];
|
||||
[pasteItem release];
|
||||
|
||||
// Add Delete
|
||||
NSMenuItem* deleteItem = [[NSMenuItem alloc] initWithTitle:@"Delete" action:@selector(delete:) keyEquivalent:@""];
|
||||
[standardEditMenu addItem:deleteItem];
|
||||
[deleteItem release];
|
||||
|
||||
// Add Select All
|
||||
NSMenuItem* selectAllItem = [[NSMenuItem alloc] initWithTitle:@"Select All" action:@selector(selectAll:) keyEquivalent:@"a"];
|
||||
[standardEditMenu addItem:selectAllItem];
|
||||
[selectAllItem release];
|
||||
|
||||
standardEditMenuItem = standardEditMenuItem;
|
||||
|
||||
return standardEditMenuItem;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
return reinterpret_cast<nsMenuItemX*>(mObserverTable.Get(&key));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1022,13 +804,13 @@ static BOOL gActOnSpecialCommands = YES;
|
|||
nsIContent* mostSpecificContent = sAboutItemContent;
|
||||
if (menuBar && menuBar->mAboutItemContent)
|
||||
mostSpecificContent = menuBar->mAboutItemContent;
|
||||
MenuHelpersX::DispatchCommandTo(mostSpecificContent);
|
||||
nsMenuUtilsX::DispatchCommandTo(mostSpecificContent);
|
||||
}
|
||||
else if (tag == eCommand_ID_Prefs) {
|
||||
nsIContent* mostSpecificContent = sPrefItemContent;
|
||||
if (menuBar && menuBar->mPrefItemContent)
|
||||
mostSpecificContent = menuBar->mPrefItemContent;
|
||||
MenuHelpersX::DispatchCommandTo(mostSpecificContent);
|
||||
nsMenuUtilsX::DispatchCommandTo(mostSpecificContent);
|
||||
}
|
||||
else if (tag == eCommand_ID_Quit) {
|
||||
nsIContent* mostSpecificContent = sQuitItemContent;
|
||||
|
@ -1038,7 +820,7 @@ static BOOL gActOnSpecialCommands = YES;
|
|||
// message. If you want to stop a quit from happening, provide quit content and return
|
||||
// the event as unhandled.
|
||||
if (mostSpecificContent) {
|
||||
MenuHelpersX::DispatchCommandTo(mostSpecificContent);
|
||||
nsMenuUtilsX::DispatchCommandTo(mostSpecificContent);
|
||||
}
|
||||
else {
|
||||
[NSApp terminate:nil];
|
||||
|
@ -1061,12 +843,11 @@ static BOOL gActOnSpecialCommands = YES;
|
|||
return;
|
||||
|
||||
// given the commandID, look it up in our hashtable and dispatch to
|
||||
// that content node. Recall that we store weak pointers to the content
|
||||
// nodes in the hash table.
|
||||
// that menu item.
|
||||
if (menuBar) {
|
||||
nsIMenuItem* content = menuBar->GetMenuItemForCommandID(static_cast<PRUint32>(tag));
|
||||
if (content)
|
||||
content->DoCommand();
|
||||
nsMenuItemX* menuItem = menuBar->GetMenuItemForCommandID(static_cast<PRUint32>(tag));
|
||||
if (menuItem)
|
||||
menuItem->DoCommand();
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Josh Aas <josh@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsMenuBaseX_h_
|
||||
#define nsMenuBaseX_h_
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
enum nsMenuObjectTypeX {
|
||||
eMenuBarObjectType,
|
||||
eSubmenuObjectType,
|
||||
eMenuItemObjectType
|
||||
};
|
||||
|
||||
// All menu objects subclass this.
|
||||
// Menu bars are owned by their top-level nsIWidgets.
|
||||
// All other objects are memory-managed based on the DOM.
|
||||
// Content removal deletes them immediately and nothing else should.
|
||||
// Do not attempt to hold strong references to them or delete them.
|
||||
class nsMenuObjectX
|
||||
{
|
||||
public:
|
||||
virtual ~nsMenuObjectX() { }
|
||||
virtual nsMenuObjectTypeX MenuObjectType()=0;
|
||||
virtual void* NativeData()=0;
|
||||
nsIContent* Content() { return mContent; }
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIContent> mContent;
|
||||
};
|
||||
|
||||
#endif // nsMenuBaseX_h_
|
|
@ -51,7 +51,7 @@
|
|||
class nsIURI;
|
||||
class nsIContent;
|
||||
class imgIRequest;
|
||||
class nsIMenu;
|
||||
class nsMenuObjectX;
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
@ -60,10 +60,9 @@ class nsIMenu;
|
|||
class nsMenuItemIconX : public imgIDecoderObserver
|
||||
{
|
||||
public:
|
||||
nsMenuItemIconX(nsISupports* aMenuItem,
|
||||
nsIMenu* aMenu,
|
||||
nsIContent* aContent,
|
||||
NSMenuItem* aNativeMenuItem);
|
||||
nsMenuItemIconX(nsMenuObjectX* aMenuItem,
|
||||
nsIContent* aContent,
|
||||
NSMenuItem* aNativeMenuItem);
|
||||
private:
|
||||
~nsMenuItemIconX();
|
||||
|
||||
|
@ -86,10 +85,7 @@ public:
|
|||
protected:
|
||||
nsCOMPtr<nsIContent> mContent;
|
||||
nsCOMPtr<imgIRequest> mIconRequest;
|
||||
nsISupports* mMenuItem;
|
||||
nsIMenu* mMenu;
|
||||
MenuRef mMenuRef;
|
||||
PRUint16 mMenuItemIndex;
|
||||
nsMenuObjectX* mMenuObject;
|
||||
PRPackedBool mLoadedIcon;
|
||||
PRPackedBool mSetIcon;
|
||||
NSMenuItem* mNativeMenuItem;
|
||||
|
|
|
@ -45,8 +45,6 @@
|
|||
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "prmem.h"
|
||||
#include "nsIMenu.h"
|
||||
#include "nsIMenuItem.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
|
@ -64,6 +62,7 @@
|
|||
#include "imgIRequest.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsMenuItemX.h"
|
||||
|
||||
static const PRUint32 kIconWidth = 16;
|
||||
static const PRUint32 kIconHeight = 16;
|
||||
|
@ -83,15 +82,11 @@ PRAllocCGFree(void* aInfo, const void* aData, size_t aSize) {
|
|||
|
||||
NS_IMPL_ISUPPORTS2(nsMenuItemIconX, imgIContainerObserver, imgIDecoderObserver)
|
||||
|
||||
nsMenuItemIconX::nsMenuItemIconX(nsISupports* aMenuItem,
|
||||
nsIMenu* aMenu,
|
||||
nsIContent* aContent,
|
||||
NSMenuItem* aNativeMenuItem)
|
||||
nsMenuItemIconX::nsMenuItemIconX(nsMenuObjectX* aMenuItem,
|
||||
nsIContent* aContent,
|
||||
NSMenuItem* aNativeMenuItem)
|
||||
: mContent(aContent)
|
||||
, mMenuItem(aMenuItem)
|
||||
, mMenu(aMenu)
|
||||
, mMenuRef(NULL)
|
||||
, mMenuItemIndex(0)
|
||||
, mMenuObject(aMenuItem)
|
||||
, mLoadedIcon(PR_FALSE)
|
||||
, mSetIcon(PR_FALSE)
|
||||
, mNativeMenuItem(aNativeMenuItem)
|
||||
|
@ -112,18 +107,6 @@ nsMenuItemIconX::SetupIcon()
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
nsresult rv;
|
||||
if (!mMenuRef || !mMenuItemIndex) {
|
||||
// These values are initialized here instead of in the constructor
|
||||
// because they depend on the parent menu, mMenu, having inserted
|
||||
// this object into its array of children. That can only happen after
|
||||
// the object is constructed.
|
||||
rv = mMenu->GetMenuRefAndItemIndexForMenuItem(mMenuItem,
|
||||
(void**)&mMenuRef,
|
||||
&mMenuItemIndex);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
// Still don't have one, then something is wrong, get out of here.
|
||||
if (!mNativeMenuItem) {
|
||||
NS_ERROR("No native menu item\n");
|
||||
|
@ -131,7 +114,7 @@ nsMenuItemIconX::SetupIcon()
|
|||
}
|
||||
|
||||
nsCOMPtr<nsIURI> iconURI;
|
||||
rv = GetIconURI(getter_AddRefs(iconURI));
|
||||
nsresult rv = GetIconURI(getter_AddRefs(iconURI));
|
||||
if (NS_FAILED(rv)) {
|
||||
// There is no icon for this menu item. An icon might have been set
|
||||
// earlier. Clear it.
|
||||
|
@ -155,15 +138,14 @@ nsMenuItemIconX::GetIconURI(nsIURI** aIconURI)
|
|||
// The downside is that it's possible to get a menu item marked with a
|
||||
// native checkmark and a checkmark for an icon. Head off that possibility
|
||||
// by pretending that no icon exists if this is a checkable menu item.
|
||||
nsCOMPtr<nsIMenuItem> menuItem = do_QueryInterface(mMenuItem);
|
||||
if (menuItem) {
|
||||
nsIMenuItem::EMenuItemType menuItemType;
|
||||
menuItem->GetMenuItemType(&menuItemType);
|
||||
if (menuItemType != nsIMenuItem::eRegular)
|
||||
if (mMenuObject->MenuObjectType() == eMenuItemObjectType) {
|
||||
nsMenuItemX* menuItem = static_cast<nsMenuItemX*>(mMenuObject);
|
||||
if (menuItem->GetMenuItemType() != eRegularMenuItemType)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!mContent) return NS_ERROR_FAILURE;
|
||||
if (!mContent)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// First, look at the content node's "image" attribute.
|
||||
nsAutoString imageURIString;
|
||||
|
|
|
@ -39,69 +39,68 @@
|
|||
#ifndef nsMenuItemX_h_
|
||||
#define nsMenuItemX_h_
|
||||
|
||||
#include "nsIMenuItem.h"
|
||||
#include "nsString.h"
|
||||
#include "nsMenuBaseX.h"
|
||||
#include "nsChangeObserver.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
class nsIMenu;
|
||||
class nsString;
|
||||
class nsMenuItemIconX;
|
||||
class nsMenuX;
|
||||
class nsMenuBarX;
|
||||
|
||||
/**
|
||||
* Native menu item wrapper
|
||||
*/
|
||||
enum {
|
||||
knsMenuItemNoModifier = 0,
|
||||
knsMenuItemShiftModifier = (1 << 0),
|
||||
knsMenuItemAltModifier = (1 << 1),
|
||||
knsMenuItemControlModifier = (1 << 2),
|
||||
knsMenuItemCommandModifier = (1 << 3)
|
||||
};
|
||||
|
||||
class nsMenuItemX : public nsIMenuItem,
|
||||
enum EMenuItemType {
|
||||
eRegularMenuItemType = 0,
|
||||
eCheckboxMenuItemType,
|
||||
eRadioMenuItemType,
|
||||
eSeparatorMenuItemType
|
||||
};
|
||||
|
||||
|
||||
// Once instantiated, this object lives until its DOM node or its parent window is destroyed.
|
||||
// Do not hold references to this, they can become invalid any time the DOM node can be destroyed.
|
||||
class nsMenuItemX : public nsMenuObjectX,
|
||||
public nsChangeObserver
|
||||
{
|
||||
public:
|
||||
nsMenuItemX();
|
||||
virtual ~nsMenuItemX();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CHANGEOBSERVER
|
||||
|
||||
// nsIMenuItem Methods
|
||||
NS_IMETHOD Create(nsIMenu* aParent, const nsString & aLabel, EMenuItemType aItemType,
|
||||
nsMenuBarX* aMenuBar, nsIContent* aNode);
|
||||
NS_IMETHOD GetLabel(nsString &aText);
|
||||
NS_IMETHOD GetShortcutChar(nsString &aText);
|
||||
NS_IMETHOD GetEnabled(PRBool *aIsEnabled);
|
||||
NS_IMETHOD SetChecked(PRBool aIsEnabled);
|
||||
NS_IMETHOD GetChecked(PRBool *aIsEnabled);
|
||||
NS_IMETHOD GetMenuItemType(EMenuItemType *aIsCheckbox);
|
||||
NS_IMETHOD GetNativeData(void*& aData);
|
||||
NS_IMETHOD IsSeparator(PRBool & aIsSep);
|
||||
// nsMenuObjectX
|
||||
void* NativeData() {return (void*)mNativeMenuItem;}
|
||||
nsMenuObjectTypeX MenuObjectType() {return eMenuItemObjectType;}
|
||||
|
||||
NS_IMETHOD DoCommand();
|
||||
NS_IMETHOD DispatchDOMEvent(const nsString &eventName, PRBool *preventDefaultCalled);
|
||||
NS_IMETHOD SetupIcon();
|
||||
NS_IMETHOD GetMenuItemContent(nsIContent ** aMenuItemContent);
|
||||
// nsMenuItemX
|
||||
nsresult Create(nsMenuX* aParent, const nsString& aLabel, EMenuItemType aItemType,
|
||||
nsMenuBarX* aMenuBar, nsIContent* aNode);
|
||||
nsresult SetChecked(PRBool aIsChecked);
|
||||
EMenuItemType GetMenuItemType();
|
||||
void DoCommand();
|
||||
nsresult DispatchDOMEvent(const nsString &eventName, PRBool* preventDefaultCalled);
|
||||
void SetupIcon();
|
||||
|
||||
protected:
|
||||
|
||||
void UncheckRadioSiblings(nsIContent* inCheckedElement);
|
||||
void SetKeyEquiv(PRUint8 aModifiers, const nsString &aText);
|
||||
|
||||
NSMenuItem* mNativeMenuItem; // strong ref, we own
|
||||
|
||||
nsString mLabel;
|
||||
nsString mKeyEquivalent;
|
||||
|
||||
nsIMenu* mMenuParent; // weak, parent owns us
|
||||
nsMenuBarX* mMenuBar; // weak
|
||||
|
||||
nsCOMPtr<nsIContent> mContent;
|
||||
EMenuItemType mType;
|
||||
NSMenuItem* mNativeMenuItem; // [strong]
|
||||
nsMenuX* mMenuParent; // [weak]
|
||||
nsMenuBarX* mMenuBar; // [weak]
|
||||
nsCOMPtr<nsIContent> mCommandContent;
|
||||
nsRefPtr<nsMenuItemIconX> mIcon;
|
||||
|
||||
PRUint8 mModifiers;
|
||||
PRPackedBool mEnabled;
|
||||
PRPackedBool mIsChecked;
|
||||
EMenuItemType mType; // regular, checkbox, radio, or separator
|
||||
PRBool mIsChecked;
|
||||
};
|
||||
|
||||
#endif // nsMenuItemX_h_
|
||||
|
|
|
@ -36,39 +36,37 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsMenuBarX.h" // for MenuHelpers namespace
|
||||
#include "nsMenuItemX.h"
|
||||
#include "nsIMenu.h"
|
||||
#include "nsIMenuBar.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsMenuBarX.h"
|
||||
#include "nsMenuX.h"
|
||||
#include "nsMenuItemIconX.h"
|
||||
#include "nsMenuUtilsX.h"
|
||||
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsWidgetAtoms.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsGUIEvent.h"
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOMDocumentEvent.h"
|
||||
|
||||
#include "nsMenuItemIconX.h"
|
||||
#include "nsGUIEvent.h"
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsMenuItemX, nsIMenuItem)
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
|
||||
nsMenuItemX::nsMenuItemX()
|
||||
{
|
||||
mNativeMenuItem = nil;
|
||||
mMenuParent = nsnull;
|
||||
mMenuBar = nsnull;
|
||||
mKeyEquivalent.AssignLiteral(" ");
|
||||
mEnabled = PR_TRUE;
|
||||
mIsChecked = PR_FALSE;
|
||||
mType = eRegular;
|
||||
mType = eRegularMenuItemType;
|
||||
mNativeMenuItem = nil;
|
||||
mMenuParent = nsnull;
|
||||
mMenuBar = nsnull;
|
||||
mIsChecked = PR_FALSE;
|
||||
|
||||
MOZ_COUNT_CTOR(nsMenuItemX);
|
||||
}
|
||||
|
||||
|
||||
|
@ -82,23 +80,24 @@ nsMenuItemX::~nsMenuItemX()
|
|||
if (mCommandContent)
|
||||
mMenuBar->UnregisterForContentChanges(mCommandContent);
|
||||
|
||||
MOZ_COUNT_DTOR(nsMenuItemX);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsMenuItemX::Create(nsIMenu* aParent, const nsString & aLabel, EMenuItemType aItemType,
|
||||
nsMenuBarX* aMenuBar, nsIContent* aNode)
|
||||
nsresult nsMenuItemX::Create(nsMenuX* aParent, const nsString& aLabel, EMenuItemType aItemType,
|
||||
nsMenuBarX* aMenuBar, nsIContent* aNode)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
mContent = aNode; // addref
|
||||
mMenuParent = aParent; // weak
|
||||
|
||||
mType = aItemType;
|
||||
mMenuParent = aParent;
|
||||
mContent = aNode;
|
||||
|
||||
// register for AttributeChanged messages
|
||||
mMenuBar = aMenuBar;
|
||||
NS_ASSERTION(mMenuBar, "No menu bar given, must have one");
|
||||
NS_ASSERTION(mMenuBar, "No menu bar given, must have one!");
|
||||
|
||||
mMenuBar->RegisterForContentChanges(mContent, this);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mContent->GetCurrentDoc()));
|
||||
|
@ -120,26 +119,25 @@ NS_METHOD nsMenuItemX::Create(nsIMenu* aParent, const nsString & aLabel, EMenuIt
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set up mEnabled based on command content if it exists, otherwise do it based
|
||||
|
||||
// decide enabled state based on command content if it exists, otherwise do it based
|
||||
// on our own content
|
||||
PRBool isEnabled;
|
||||
if (mCommandContent)
|
||||
mEnabled = !mCommandContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::disabled, nsWidgetAtoms::_true, eCaseMatters);
|
||||
isEnabled = !mCommandContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::disabled, nsWidgetAtoms::_true, eCaseMatters);
|
||||
else
|
||||
mEnabled = !mContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::disabled, nsWidgetAtoms::_true, eCaseMatters);
|
||||
|
||||
mLabel = aLabel;
|
||||
|
||||
isEnabled = !mContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::disabled, nsWidgetAtoms::_true, eCaseMatters);
|
||||
|
||||
// set up the native menu item
|
||||
if (mType == nsIMenuItem::eSeparator) {
|
||||
if (mType == eSeparatorMenuItemType) {
|
||||
mNativeMenuItem = [[NSMenuItem separatorItem] retain];
|
||||
}
|
||||
else {
|
||||
NSString *newCocoaLabelString = MenuHelpersX::CreateTruncatedCocoaLabel(mLabel);
|
||||
NSString *newCocoaLabelString = nsMenuUtilsX::CreateTruncatedCocoaLabel(aLabel);
|
||||
mNativeMenuItem = [[NSMenuItem alloc] initWithTitle:newCocoaLabelString action:nil keyEquivalent:@""];
|
||||
[newCocoaLabelString release];
|
||||
|
||||
[mNativeMenuItem setEnabled:(BOOL)mEnabled];
|
||||
|
||||
[mNativeMenuItem setEnabled:(BOOL)isEnabled];
|
||||
|
||||
SetChecked(mContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::checked,
|
||||
nsWidgetAtoms::_true, eCaseMatters));
|
||||
|
@ -148,11 +146,9 @@ NS_METHOD nsMenuItemX::Create(nsIMenu* aParent, const nsString & aLabel, EMenuIt
|
|||
if (domDoc) {
|
||||
nsAutoString keyValue;
|
||||
mContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::key, keyValue);
|
||||
|
||||
if (!keyValue.IsEmpty()) {
|
||||
nsCOMPtr<nsIDOMElement> keyElement;
|
||||
domDoc->GetElementById(keyValue, getter_AddRefs(keyElement));
|
||||
|
||||
if (keyElement) {
|
||||
nsCOMPtr<nsIContent> keyContent(do_QueryInterface(keyElement));
|
||||
nsAutoString keyChar(NS_LITERAL_STRING(" "));
|
||||
|
@ -160,7 +156,7 @@ NS_METHOD nsMenuItemX::Create(nsIMenu* aParent, const nsString & aLabel, EMenuIt
|
|||
|
||||
nsAutoString modifiersStr;
|
||||
keyContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::modifiers, modifiersStr);
|
||||
PRUint8 modifiers = MenuHelpersX::GeckoModifiersForNodeAttribute(modifiersStr);
|
||||
PRUint8 modifiers = nsMenuUtilsX::GeckoModifiersForNodeAttribute(modifiersStr);
|
||||
|
||||
SetKeyEquiv(modifiers, keyChar);
|
||||
}
|
||||
|
@ -168,31 +164,17 @@ NS_METHOD nsMenuItemX::Create(nsIMenu* aParent, const nsString & aLabel, EMenuIt
|
|||
}
|
||||
}
|
||||
|
||||
mIcon = new nsMenuItemIconX(static_cast<nsIMenuItem*>(this), mMenuParent, mContent, mNativeMenuItem);
|
||||
|
||||
mIcon = new nsMenuItemIconX(this, mContent, mNativeMenuItem);
|
||||
if (!mIcon)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD
|
||||
nsMenuItemX::GetLabel(nsString &aText)
|
||||
{
|
||||
aText = mLabel;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD
|
||||
nsMenuItemX::GetEnabled(PRBool *aIsEnabled)
|
||||
{
|
||||
*aIsEnabled = mEnabled;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsMenuItemX::SetChecked(PRBool aIsChecked)
|
||||
nsresult nsMenuItemX::SetChecked(PRBool aIsChecked)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
|
@ -215,41 +197,19 @@ NS_METHOD nsMenuItemX::SetChecked(PRBool aIsChecked)
|
|||
}
|
||||
|
||||
|
||||
NS_METHOD nsMenuItemX::GetChecked(PRBool *aIsEnabled)
|
||||
EMenuItemType nsMenuItemX::GetMenuItemType()
|
||||
{
|
||||
*aIsEnabled = mIsChecked;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsMenuItemX::GetMenuItemType(EMenuItemType *aType)
|
||||
{
|
||||
*aType = mType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsMenuItemX::GetNativeData(void *& aData)
|
||||
{
|
||||
aData = mNativeMenuItem;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsMenuItemX::IsSeparator(PRBool & aIsSep)
|
||||
{
|
||||
aIsSep = (mType == nsIMenuItem::eSeparator);
|
||||
return NS_OK;
|
||||
return mType;
|
||||
}
|
||||
|
||||
|
||||
// Executes the "cached" javaScript command.
|
||||
// Returns NS_OK if the command was executed properly, otherwise an error code.
|
||||
NS_IMETHODIMP nsMenuItemX::DoCommand()
|
||||
void nsMenuItemX::DoCommand()
|
||||
{
|
||||
// flip "checked" state if we're a checkbox menu, or an un-checked radio menu
|
||||
if (mType == nsIMenuItem::eCheckbox ||
|
||||
(mType == nsIMenuItem::eRadio && !mIsChecked)) {
|
||||
if (mType == eCheckboxMenuItemType ||
|
||||
(mType == eRadioMenuItemType && !mIsChecked)) {
|
||||
if (!mContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::autocheck,
|
||||
nsWidgetAtoms::_false, eCaseMatters))
|
||||
SetChecked(!mIsChecked);
|
||||
|
@ -260,29 +220,28 @@ NS_IMETHODIMP nsMenuItemX::DoCommand()
|
|||
nsXULCommandEvent event(PR_TRUE, NS_XUL_COMMAND, nsnull);
|
||||
|
||||
mContent->DispatchDOMEvent(&event, nsnull, nsnull, &status);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMenuItemX::DispatchDOMEvent(const nsString &eventName, PRBool *preventDefaultCalled)
|
||||
nsresult nsMenuItemX::DispatchDOMEvent(const nsString &eventName, PRBool *preventDefaultCalled)
|
||||
{
|
||||
if (!mContent)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
||||
// get owner document for content
|
||||
nsCOMPtr<nsIDocument> parentDoc = mContent->GetOwnerDoc();
|
||||
if (!parentDoc) {
|
||||
NS_WARNING("Failed to get owner nsIDocument for menu item content");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
// get interface for creating DOM events from content owner document
|
||||
nsCOMPtr<nsIDOMDocumentEvent> DOMEventFactory = do_QueryInterface(parentDoc);
|
||||
if (!DOMEventFactory) {
|
||||
NS_WARNING("Failed to QI parent nsIDocument to nsIDOMDocumentEvent");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
// create DOM event
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsresult rv = DOMEventFactory->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
|
||||
|
@ -291,11 +250,11 @@ NS_IMETHODIMP nsMenuItemX::DispatchDOMEvent(const nsString &eventName, PRBool *p
|
|||
return rv;
|
||||
}
|
||||
event->InitEvent(eventName, PR_TRUE, PR_TRUE);
|
||||
|
||||
|
||||
// mark DOM event as trusted
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
|
||||
privateEvent->SetTrusted(PR_TRUE);
|
||||
|
||||
|
||||
// send DOM event
|
||||
nsCOMPtr<nsIDOMEventTarget> eventTarget = do_QueryInterface(mContent);
|
||||
rv = eventTarget->DispatchEvent(event, preventDefaultCalled);
|
||||
|
@ -303,22 +262,14 @@ NS_IMETHODIMP nsMenuItemX::DispatchDOMEvent(const nsString &eventName, PRBool *p
|
|||
NS_WARNING("Failed to send DOM event via nsIDOMEventTarget");
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsMenuItemX::GetShortcutChar(nsString &aText)
|
||||
{
|
||||
aText = mKeyEquivalent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Walk the sibling list looking for nodes with the same name and
|
||||
// uncheck them all.
|
||||
void
|
||||
nsMenuItemX::UncheckRadioSiblings(nsIContent* inCheckedContent)
|
||||
void nsMenuItemX::UncheckRadioSiblings(nsIContent* inCheckedContent)
|
||||
{
|
||||
nsAutoString myGroupName;
|
||||
inCheckedContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::name, myGroupName);
|
||||
|
@ -349,13 +300,11 @@ void nsMenuItemX::SetKeyEquiv(PRUint8 aModifiers, const nsString &aText)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
mModifiers = aModifiers;
|
||||
unsigned int macModifiers = MenuHelpersX::MacModifiersForGeckoModifiers(mModifiers);
|
||||
unsigned int macModifiers = nsMenuUtilsX::MacModifiersForGeckoModifiers(aModifiers);
|
||||
[mNativeMenuItem setKeyEquivalentModifierMask:macModifiers];
|
||||
|
||||
mKeyEquivalent = aText;
|
||||
NSString *keyEquivalent = [[NSString stringWithCharacters:(unichar*)mKeyEquivalent.get()
|
||||
length:mKeyEquivalent.Length()] lowercaseString];
|
||||
NSString *keyEquivalent = [[NSString stringWithCharacters:(unichar*)aText.get()
|
||||
length:aText.Length()] lowercaseString];
|
||||
if ([keyEquivalent isEqualToString:@" "])
|
||||
[mNativeMenuItem setKeyEquivalent:@""];
|
||||
else
|
||||
|
@ -382,7 +331,7 @@ nsMenuItemX::ObserveAttributeChanged(nsIDocument *aDocument, nsIContent *aConten
|
|||
if (aAttribute == nsWidgetAtoms::checked) {
|
||||
// if we're a radio menu, uncheck our sibling radio items. No need to
|
||||
// do any of this if we're just a normal check menu.
|
||||
if (mType == nsIMenuItem::eRadio) {
|
||||
if (mType == eRadioMenuItemType) {
|
||||
if (mContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::checked,
|
||||
nsWidgetAtoms::_true, eCaseMatters))
|
||||
UncheckRadioSiblings(mContent);
|
||||
|
@ -432,8 +381,7 @@ nsMenuItemX::ObserveAttributeChanged(nsIDocument *aDocument, nsIContent *aConten
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
nsMenuItemX::ObserveContentRemoved(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
|
||||
void nsMenuItemX::ObserveContentRemoved(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (aChild == mCommandContent) {
|
||||
mMenuBar->UnregisterForContentChanges(mCommandContent);
|
||||
|
@ -444,27 +392,14 @@ nsMenuItemX::ObserveContentRemoved(nsIDocument *aDocument, nsIContent *aChild, P
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
nsMenuItemX::ObserveContentInserted(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
|
||||
void nsMenuItemX::ObserveContentInserted(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
|
||||
{
|
||||
mMenuParent->SetRebuild(PR_TRUE);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuItemX::SetupIcon()
|
||||
void nsMenuItemX::SetupIcon()
|
||||
{
|
||||
if (!mIcon)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return mIcon->SetupIcon();
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuItemX::GetMenuItemContent(nsIContent ** aMenuItemContent)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aMenuItemContent);
|
||||
NS_IF_ADDREF(*aMenuItemContent = mContent);
|
||||
return NS_OK;
|
||||
if (mIcon)
|
||||
mIcon->SetupIcon();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Josh Aas <josh@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsMenuUtilsX_h_
|
||||
#define nsMenuUtilsX_h_
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsGUIEvent.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
class nsIContent;
|
||||
class nsString;
|
||||
class nsMenuBarX;
|
||||
|
||||
// Namespace containing utility functions used in our native menu implementation.
|
||||
namespace nsMenuUtilsX
|
||||
{
|
||||
nsEventStatus DispatchCommandTo(nsIContent* aTargetContent);
|
||||
NSString* CreateTruncatedCocoaLabel(const nsString& itemLabel); // returned object is not retained
|
||||
PRUint8 GeckoModifiersForNodeAttribute(const nsString& modifiersAttribute);
|
||||
unsigned int MacModifiersForGeckoModifiers(PRUint8 geckoModifiers);
|
||||
nsMenuBarX* GetHiddenWindowMenuBar(); // returned object is not retained
|
||||
NSMenuItem* GetStandardEditMenuItem(); // returned object is not retained
|
||||
PRBool NodeIsHiddenOrCollapsed(nsIContent* inContent);
|
||||
}
|
||||
|
||||
#endif // nsMenuUtilsX_h_
|
|
@ -0,0 +1,197 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Josh Aas <josh@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsMenuUtilsX.h"
|
||||
#include "nsMenuBarX.h"
|
||||
#include "nsMenuItemX.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsCocoaUtils.h"
|
||||
#include "nsCocoaWindow.h"
|
||||
#include "nsWidgetAtoms.h"
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
nsEventStatus nsMenuUtilsX::DispatchCommandTo(nsIContent* aTargetContent)
|
||||
{
|
||||
NS_PRECONDITION(aTargetContent, "null ptr");
|
||||
|
||||
nsEventStatus status = nsEventStatus_eConsumeNoDefault;
|
||||
nsXULCommandEvent event(PR_TRUE, NS_XUL_COMMAND, nsnull);
|
||||
|
||||
// FIXME: Should probably figure out how to init this with the actual
|
||||
// pressed keys, but this is a big old edge case anyway. -dwh
|
||||
|
||||
aTargetContent->DispatchDOMEvent(&event, nsnull, nsnull, &status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
NSString* nsMenuUtilsX::CreateTruncatedCocoaLabel(const nsString& itemLabel)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
// ::TruncateThemeText() doesn't take the number of characters to truncate to, it takes a pixel with
|
||||
// to fit the string in. Ugh. I talked it over with sfraser and we couldn't come up with an
|
||||
// easy way to compute what this should be given the system font, etc, so we're just going
|
||||
// to hard code it to something reasonable and bigger fonts will just have to deal.
|
||||
const short kMaxItemPixelWidth = 300;
|
||||
NSMutableString *label = [[NSMutableString stringWithCharacters:itemLabel.get() length:itemLabel.Length()] retain];
|
||||
::TruncateThemeText((CFMutableStringRef)label, kThemeMenuItemFont, kThemeStateActive, kMaxItemPixelWidth, truncMiddle, NULL);
|
||||
return label; // caller releases
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
|
||||
PRUint8 nsMenuUtilsX::GeckoModifiersForNodeAttribute(const nsString& modifiersAttribute)
|
||||
{
|
||||
PRUint8 modifiers = knsMenuItemNoModifier;
|
||||
char* str = ToNewCString(modifiersAttribute);
|
||||
char* newStr;
|
||||
char* token = strtok_r(str, ", \t", &newStr);
|
||||
while (token != NULL) {
|
||||
if (strcmp(token, "shift") == 0)
|
||||
modifiers |= knsMenuItemShiftModifier;
|
||||
else if (strcmp(token, "alt") == 0)
|
||||
modifiers |= knsMenuItemAltModifier;
|
||||
else if (strcmp(token, "control") == 0)
|
||||
modifiers |= knsMenuItemControlModifier;
|
||||
else if ((strcmp(token, "accel") == 0) ||
|
||||
(strcmp(token, "meta") == 0)) {
|
||||
modifiers |= knsMenuItemCommandModifier;
|
||||
}
|
||||
token = strtok_r(newStr, ", \t", &newStr);
|
||||
}
|
||||
free(str);
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
|
||||
unsigned int nsMenuUtilsX::MacModifiersForGeckoModifiers(PRUint8 geckoModifiers)
|
||||
{
|
||||
unsigned int macModifiers = 0;
|
||||
|
||||
if (geckoModifiers & knsMenuItemShiftModifier)
|
||||
macModifiers |= NSShiftKeyMask;
|
||||
if (geckoModifiers & knsMenuItemAltModifier)
|
||||
macModifiers |= NSAlternateKeyMask;
|
||||
if (geckoModifiers & knsMenuItemControlModifier)
|
||||
macModifiers |= NSControlKeyMask;
|
||||
if (geckoModifiers & knsMenuItemCommandModifier)
|
||||
macModifiers |= NSCommandKeyMask;
|
||||
|
||||
return macModifiers;
|
||||
}
|
||||
|
||||
|
||||
nsMenuBarX* nsMenuUtilsX::GetHiddenWindowMenuBar()
|
||||
{
|
||||
nsIWidget* hiddenWindowWidgetNoCOMPtr = nsCocoaUtils::GetHiddenWindowWidget();
|
||||
if (hiddenWindowWidgetNoCOMPtr)
|
||||
return static_cast<nsCocoaWindow*>(hiddenWindowWidgetNoCOMPtr)->GetMenuBar();
|
||||
else
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
// It would be nice if we could localize these edit menu names.
|
||||
static NSMenuItem* standardEditMenuItem = nil;
|
||||
NSMenuItem* nsMenuUtilsX::GetStandardEditMenuItem()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (standardEditMenuItem)
|
||||
return standardEditMenuItem;
|
||||
|
||||
standardEditMenuItem = [[NSMenuItem alloc] initWithTitle:@"Edit" action:nil keyEquivalent:@""];
|
||||
NSMenu* standardEditMenu = [[NSMenu alloc] initWithTitle:@"Edit"];
|
||||
[standardEditMenuItem setSubmenu:standardEditMenu];
|
||||
[standardEditMenu release];
|
||||
|
||||
// Add Undo
|
||||
NSMenuItem* undoItem = [[NSMenuItem alloc] initWithTitle:@"Undo" action:@selector(undo:) keyEquivalent:@"z"];
|
||||
[standardEditMenu addItem:undoItem];
|
||||
[undoItem release];
|
||||
|
||||
// Add Redo
|
||||
NSMenuItem* redoItem = [[NSMenuItem alloc] initWithTitle:@"Redo" action:@selector(redo:) keyEquivalent:@"Z"];
|
||||
[standardEditMenu addItem:redoItem];
|
||||
[redoItem release];
|
||||
|
||||
// Add separator
|
||||
[standardEditMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
// Add Cut
|
||||
NSMenuItem* cutItem = [[NSMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"];
|
||||
[standardEditMenu addItem:cutItem];
|
||||
[cutItem release];
|
||||
|
||||
// Add Copy
|
||||
NSMenuItem* copyItem = [[NSMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"];
|
||||
[standardEditMenu addItem:copyItem];
|
||||
[copyItem release];
|
||||
|
||||
// Add Paste
|
||||
NSMenuItem* pasteItem = [[NSMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:) keyEquivalent:@"v"];
|
||||
[standardEditMenu addItem:pasteItem];
|
||||
[pasteItem release];
|
||||
|
||||
// Add Delete
|
||||
NSMenuItem* deleteItem = [[NSMenuItem alloc] initWithTitle:@"Delete" action:@selector(delete:) keyEquivalent:@""];
|
||||
[standardEditMenu addItem:deleteItem];
|
||||
[deleteItem release];
|
||||
|
||||
// Add Select All
|
||||
NSMenuItem* selectAllItem = [[NSMenuItem alloc] initWithTitle:@"Select All" action:@selector(selectAll:) keyEquivalent:@"a"];
|
||||
[standardEditMenu addItem:selectAllItem];
|
||||
[selectAllItem release];
|
||||
|
||||
return standardEditMenuItem;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
|
||||
PRBool nsMenuUtilsX::NodeIsHiddenOrCollapsed(nsIContent* inContent)
|
||||
{
|
||||
return (inContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::hidden,
|
||||
nsWidgetAtoms::_true, eCaseMatters) ||
|
||||
inContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::collapsed,
|
||||
nsWidgetAtoms::_true, eCaseMatters));
|
||||
}
|
|
@ -39,19 +39,19 @@
|
|||
#ifndef nsMenuX_h_
|
||||
#define nsMenuX_h_
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIMenu.h"
|
||||
#include "nsChangeObserver.h"
|
||||
#include "nsMenuBarX.h"
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
#include "nsMenuBaseX.h"
|
||||
#include "nsMenuBarX.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsChangeObserver.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class nsIMenuBar;
|
||||
class nsMenuX;
|
||||
class nsMenuItemIconX;
|
||||
class nsMenuItemX;
|
||||
class nsIWidget;
|
||||
|
||||
|
||||
// MenuDelegate is used to receive Cocoa notifications for
|
||||
|
@ -66,99 +66,71 @@ class nsMenuItemIconX;
|
|||
@end
|
||||
|
||||
|
||||
class nsMenuX : public nsIMenu,
|
||||
// Once instantiated, this object lives until its DOM node or its parent window is destroyed.
|
||||
// Do not hold references to this, they can become invalid any time the DOM node can be destroyed.
|
||||
class nsMenuX : public nsMenuObjectX,
|
||||
public nsChangeObserver
|
||||
{
|
||||
public:
|
||||
nsMenuX();
|
||||
virtual ~nsMenuX();
|
||||
nsMenuX();
|
||||
virtual ~nsMenuX();
|
||||
|
||||
// If > 0, the OS is indexing all the app's menus (triggered by opening
|
||||
// Help menu on Leopard and higher). There are some things that are
|
||||
// unsafe to do while this is happening.
|
||||
static PRInt32 sIndexingMenuLevel;
|
||||
// If > 0, the OS is indexing all the app's menus (triggered by opening
|
||||
// Help menu on Leopard and higher). There are some things that are
|
||||
// unsafe to do while this is happening.
|
||||
static PRInt32 sIndexingMenuLevel;
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CHANGEOBSERVER
|
||||
NS_DECL_CHANGEOBSERVER
|
||||
|
||||
id GetNativeMenuItem();
|
||||
// nsMenuObjectX
|
||||
void* NativeData() {return (void*)mMacMenu;}
|
||||
nsMenuObjectTypeX MenuObjectType() {return eSubmenuObjectType;}
|
||||
|
||||
// nsIMenu Methods
|
||||
NS_IMETHOD Create(nsISupports * aParent, const nsAString &aLabel, const nsAString &aAccessKey,
|
||||
nsMenuBarX* aMenuBar, nsIContent* aNode);
|
||||
NS_IMETHOD GetParent(nsISupports *&aParent);
|
||||
NS_IMETHOD GetLabel(nsString &aText);
|
||||
NS_IMETHOD SetLabel(const nsAString &aText);
|
||||
NS_IMETHOD GetAccessKey(nsString &aText);
|
||||
NS_IMETHOD SetAccessKey(const nsAString &aText);
|
||||
NS_IMETHOD AddItem(nsISupports* aText);
|
||||
NS_IMETHOD GetItemCount(PRUint32 &aCount);
|
||||
NS_IMETHOD GetItemAt(const PRUint32 aPos, nsISupports *& aMenuItem);
|
||||
NS_IMETHOD GetVisibleItemCount(PRUint32 &aCount);
|
||||
NS_IMETHOD GetVisibleItemAt(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 SetNativeData(void* aData);
|
||||
NS_IMETHOD GetMenuContent(nsIContent ** aMenuNode);
|
||||
NS_IMETHOD SetEnabled(PRBool aIsEnabled);
|
||||
NS_IMETHOD GetEnabled(PRBool* aIsEnabled);
|
||||
|
||||
NS_IMETHOD ChangeNativeEnabledStatusForMenuItem(nsIMenuItem* aMenuItem, PRBool aEnabled);
|
||||
NS_IMETHOD GetMenuRefAndItemIndexForMenuItem(nsISupports* aMenuItem,
|
||||
void** aMenuRef,
|
||||
PRUint16* aMenuItemIndex);
|
||||
NS_IMETHOD SetupIcon();
|
||||
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
|
||||
void MenuDeselected(const nsMenuEvent & aMenuEvent);
|
||||
void MenuConstruct(const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow, void * aMenuNode);
|
||||
void MenuDestruct(const nsMenuEvent & aMenuEvent);
|
||||
void SetRebuild(PRBool aMenuEvent);
|
||||
// nsMenuX
|
||||
nsresult Create(nsMenuObjectX* aParent, const nsAString &aLabel,
|
||||
nsMenuBarX* aMenuBar, nsIContent* aNode);
|
||||
PRUint32 GetItemCount();
|
||||
nsMenuObjectX* GetItemAt(PRUint32 aPos);
|
||||
nsresult GetVisibleItemCount(PRUint32 &aCount);
|
||||
nsMenuObjectX* GetVisibleItemAt(PRUint32 aPos);
|
||||
nsEventStatus MenuOpened(const nsMenuEvent& aMenuEvent);
|
||||
void MenuClosed(const nsMenuEvent& aMenuEvent);
|
||||
void SetRebuild(PRBool aMenuEvent);
|
||||
NSMenuItem* NativeMenuItem();
|
||||
|
||||
protected:
|
||||
// Determines how many menus are visible among the siblings that are before me.
|
||||
// It doesn't matter if I am visible.
|
||||
nsresult CountVisibleBefore(PRUint32* outVisibleBefore);
|
||||
void MenuConstruct(nsIWidget* aParentWindow, void* aMenuNode);
|
||||
nsresult RemoveAll();
|
||||
nsresult SetEnabled(PRBool aIsEnabled);
|
||||
nsresult GetEnabled(PRBool* aIsEnabled);
|
||||
nsresult SetupIcon();
|
||||
nsresult CountVisibleBefore(PRUint32* outVisibleBefore);
|
||||
void GetMenuPopupContent(nsIContent** aResult);
|
||||
PRBool OnOpen();
|
||||
PRBool OnOpened();
|
||||
PRBool OnClose();
|
||||
PRBool OnClosed();
|
||||
nsresult AddMenuItem(nsMenuItemX* aMenuItem);
|
||||
nsresult AddMenu(nsMenuX* aMenu);
|
||||
void LoadMenuItem(nsIContent* inMenuItemContent);
|
||||
void LoadSubMenu(nsIContent* inMenuContent);
|
||||
GeckoNSMenu* CreateMenuWithGeckoString(nsString& menuTitle);
|
||||
|
||||
// fetch the content node associated with the menupopup item
|
||||
void GetMenuPopupContent(nsIContent** aResult);
|
||||
|
||||
// fire handlers for oncreate/ondestroy
|
||||
PRBool OnDestroy();
|
||||
PRBool OnCreate();
|
||||
PRBool OnDestroyed();
|
||||
PRBool OnCreated();
|
||||
|
||||
nsresult AddMenuItem(nsIMenuItem * aMenuItem);
|
||||
nsresult AddMenu(nsIMenu * aMenu);
|
||||
|
||||
void LoadMenuItem(nsIContent* inMenuItemContent);
|
||||
void LoadSubMenu(nsIContent* inMenuContent);
|
||||
|
||||
GeckoNSMenu* CreateMenuWithGeckoString(nsString& menuTitle);
|
||||
|
||||
protected:
|
||||
nsString mLabel;
|
||||
nsCOMArray<nsISupports> mMenuItemsArray;
|
||||
PRUint32 mVisibleItemsCount; // caching number of visible items in mMenuItemsArray
|
||||
|
||||
nsISupports* mParent; // weak, my parent owns me
|
||||
nsMenuBarX* mMenuBar; // weak ref, it will outlive us
|
||||
nsCOMPtr<nsIContent> mMenuContent; // the |menu| tag, strong ref
|
||||
nsRefPtr<nsMenuItemIconX> mIcon;
|
||||
|
||||
// Mac specific
|
||||
PRInt16 mMacMenuID;
|
||||
GeckoNSMenu* mMacMenu; // strong ref, we own it
|
||||
MenuDelegate* mMenuDelegate; // strong ref, we keep this around to get events for us
|
||||
NSMenuItem* mNativeMenuItem; // strong ref, we own
|
||||
PRPackedBool mIsEnabled;
|
||||
PRPackedBool mDestroyHandlerCalled;
|
||||
PRPackedBool mNeedsRebuild;
|
||||
PRPackedBool mConstructed;
|
||||
PRPackedBool mVisible; // are we visible to the user?
|
||||
PRPackedBool mXBLAttached;
|
||||
nsTArray< nsAutoPtr<nsMenuObjectX> > mMenuObjectsArray;
|
||||
nsString mLabel;
|
||||
PRUint32 mVisibleItemsCount; // cache
|
||||
nsMenuObjectX* mParent; // [weak]
|
||||
nsMenuBarX* mMenuBar; // [weak]
|
||||
nsRefPtr<nsMenuItemIconX> mIcon;
|
||||
GeckoNSMenu* mMacMenu; // [strong]
|
||||
MenuDelegate* mMenuDelegate; // [strong]
|
||||
NSMenuItem* mNativeMenuItem; // [strong]
|
||||
PRPackedBool mIsEnabled;
|
||||
PRPackedBool mDestroyHandlerCalled;
|
||||
PRPackedBool mNeedsRebuild;
|
||||
PRPackedBool mConstructed;
|
||||
PRPackedBool mVisible;
|
||||
PRPackedBool mXBLAttached;
|
||||
};
|
||||
|
||||
#endif // nsMenuX_h_
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -39,7 +39,7 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIMenuBar;
|
||||
interface nsMenuBarX;
|
||||
interface nsCocoaWindow;
|
||||
interface nsIWidget;
|
||||
|
||||
|
@ -56,9 +56,6 @@ interface nsPIWidgetCocoa : nsISupports
|
|||
{
|
||||
void SendSetZLevelEvent();
|
||||
|
||||
// Obtain the menubar for a window
|
||||
nsIMenuBar GetMenuBar();
|
||||
|
||||
// Find the displayed child sheet (if aShown) or a child sheet that
|
||||
// wants to be displayed (if !aShown)
|
||||
nsCocoaWindow GetChildSheet(in boolean aShown);
|
||||
|
|
|
@ -49,10 +49,6 @@
|
|||
#include "nsAppShellSingleton.h"
|
||||
#include "nsFilePicker.h"
|
||||
|
||||
#include "nsMenuBarX.h"
|
||||
#include "nsMenuX.h"
|
||||
#include "nsMenuItemX.h"
|
||||
|
||||
#include "nsClipboard.h"
|
||||
#include "nsClipboardHelper.h"
|
||||
#include "nsTransferable.h"
|
||||
|
@ -74,9 +70,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildView)
|
|||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePicker)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMenuBarX)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMenuX)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMenuItemX)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
|
||||
|
@ -89,6 +82,9 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintOptionsX, Init)
|
|||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSessionX, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIdleServiceX)
|
||||
|
||||
#include "nsMenuBarX.h"
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeMenuServiceX)
|
||||
|
||||
#include "nsBidiKeyboard.h"
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
|
||||
|
||||
|
@ -125,18 +121,6 @@ static const nsModuleComponentInfo gComponents[] =
|
|||
NS_LOOKANDFEEL_CID,
|
||||
"@mozilla.org/widget/lookandfeel;1",
|
||||
nsLookAndFeelConstructor },
|
||||
{ "Menubar",
|
||||
NS_MENUBAR_CID,
|
||||
"@mozilla.org/widget/menubar/mac;1",
|
||||
nsMenuBarXConstructor },
|
||||
{ "Menu",
|
||||
NS_MENU_CID,
|
||||
"@mozilla.org/widget/menu/mac;1",
|
||||
nsMenuXConstructor },
|
||||
{ "MenuItem",
|
||||
NS_MENUITEM_CID,
|
||||
"@mozilla.org/widget/menuitem/mac;1",
|
||||
nsMenuItemXConstructor },
|
||||
{ "Sound",
|
||||
NS_SOUND_CID,
|
||||
"@mozilla.org/sound;1",
|
||||
|
@ -189,6 +173,10 @@ static const nsModuleComponentInfo gComponents[] =
|
|||
NS_IDLE_SERVICE_CID,
|
||||
"@mozilla.org/widget/idleservice;1",
|
||||
nsIdleServiceXConstructor },
|
||||
{ "Native Menu Service",
|
||||
NS_NATIVEMENUSERVICE_CID,
|
||||
"@mozilla.org/widget/nativemenuservice;1",
|
||||
nsNativeMenuServiceXConstructor },
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(nsWidgetMacModule, gComponents,
|
||||
|
|
|
@ -1373,7 +1373,7 @@ nsWindow::SetIcon(const nsAString& aIconSpec)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::SetMenuBar(nsIMenuBar * aMenuBar)
|
||||
nsWindow::SetMenuBar(void * aMenuBar)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ public:
|
|||
NS_IMETHOD SetTitle(const nsAString& aTitle);
|
||||
NS_IMETHOD SetIcon(const nsAString& aIconSpec);
|
||||
NS_IMETHOD SetWindowClass(const nsAString& xulWinType);
|
||||
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar);
|
||||
NS_IMETHOD SetMenuBar(void * aMenuBar);
|
||||
NS_IMETHOD ShowMenuBar(PRBool aShow);
|
||||
NS_IMETHOD WidgetToScreen(const nsRect& aOldRect,
|
||||
nsRect& aNewRect);
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
#include "gfxOS2Surface.h"
|
||||
#include "gfxContext.h"
|
||||
|
||||
class nsIMenuBar;
|
||||
class imgIContainer;
|
||||
|
||||
//#define DEBUG_FOCUS
|
||||
|
@ -178,7 +177,7 @@ class nsWindow : public nsBaseWidget,
|
|||
NS_IMETHOD HideWindowChrome(PRBool aShouldHide);
|
||||
NS_IMETHOD SetTitle( const nsAString& aTitle);
|
||||
NS_IMETHOD SetIcon(const nsAString& aIconSpec);
|
||||
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar) { return NS_ERROR_FAILURE; }
|
||||
NS_IMETHOD SetMenuBar(void * aMenuBar) { return NS_ERROR_FAILURE; }
|
||||
NS_IMETHOD ShowMenuBar(PRBool aShow) { return NS_ERROR_FAILURE; }
|
||||
NS_IMETHOD Invalidate( PRBool aIsSynchronous);
|
||||
NS_IMETHOD Invalidate( const nsRect & aRect, PRBool aIsSynchronous);
|
||||
|
@ -281,7 +280,6 @@ protected:
|
|||
PRInt32 mPreferredHeight;
|
||||
PRInt32 mPreferredWidth;
|
||||
nsToolkit *mOS2Toolkit;
|
||||
nsIMenuBar *mMenuBar;
|
||||
PRInt32 mWindowState;
|
||||
nsRefPtr<gfxOS2Surface> mThebesSurface;
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#include "nsRect.h"
|
||||
#include "nsTransform2D.h"
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsIMenuBar.h"
|
||||
#include "nsToolkit.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefService.h"
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
class nsNativeDragTarget;
|
||||
class nsIRollupListener;
|
||||
|
||||
class nsIMenuBar;
|
||||
class nsIFile;
|
||||
|
||||
class imgIContainer;
|
||||
|
@ -190,7 +189,7 @@ public:
|
|||
NS_IMETHOD ScrollRect(nsRect &aRect, PRInt32 aDx, PRInt32 aDy);
|
||||
NS_IMETHOD SetTitle(const nsAString& aTitle);
|
||||
NS_IMETHOD SetIcon(const nsAString& aIconSpec);
|
||||
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar) { return NS_ERROR_FAILURE; }
|
||||
NS_IMETHOD SetMenuBar(void * aMenuBar) { return NS_ERROR_FAILURE; }
|
||||
NS_IMETHOD ShowMenuBar(PRBool aShow) { return NS_ERROR_FAILURE; }
|
||||
NS_IMETHOD WidgetToScreen(const nsRect& aOldRect, nsRect& aNewRect);
|
||||
NS_IMETHOD ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect);
|
||||
|
|
|
@ -136,6 +136,7 @@ public:
|
|||
virtual void ConvertToDeviceCoordinates(nscoord &aX,nscoord &aY) {}
|
||||
virtual void FreeNativeData(void * data, PRUint32 aDataType) {}
|
||||
NS_IMETHOD BeginResizeDrag(nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical);
|
||||
virtual nsresult ActivateNativeMenuItemAt(const nsAString& indexString) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -48,5 +48,10 @@ _TEST_FILES = test_bug343416.xul \
|
|||
test_keycodes.xul \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||
_TEST_FILES += native_menus_window.xul \
|
||||
test_native_menus.xul
|
||||
endif
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla 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/MPL/
|
||||
-
|
||||
- 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 Findbar Test code
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Mozilla Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 2006
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Josh Aas <josh@mozilla.com>
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
- in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
- of those above. If you wish to allow use of your version of this file only
|
||||
- under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
- use your version of this file under the terms of the MPL, indicate your
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
|
||||
<window id="NativeMenuWindow"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
width="300"
|
||||
height="300"
|
||||
onload="onLoad();"
|
||||
title="Native Menu Test">
|
||||
|
||||
<command id="cmd_FooItem1" oncommand="executedCommandID = 'cmd_FooItem1';"/>
|
||||
<command id="cmd_FooItem2" oncommand="executedCommandID = 'cmd_FooItem2';"/>
|
||||
<command id="cmd_BarItem1" oncommand="executedCommandID = 'cmd_BarItem1';"/>
|
||||
<command id="cmd_BarItem2" oncommand="executedCommandID = 'cmd_BarItem2';"/>
|
||||
|
||||
<menubar id="nativemenubar">
|
||||
<menu id="foo" label="Foo">
|
||||
<menupopup>
|
||||
<menuitem label="FooItem1" command="cmd_FooItem1"/>
|
||||
<menuitem label="FooItem2" command="cmd_FooItem2"/>
|
||||
<menuseparator/>
|
||||
<menu label="Bar">
|
||||
<menupopup>
|
||||
<menuitem label="BarItem1" command="cmd_BarItem1"/>
|
||||
<menuitem label="BarItem2" command="cmd_BarItem2"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menubar>
|
||||
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
function ok(condition, message) {
|
||||
window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
|
||||
}
|
||||
|
||||
function onTestsFinished() {
|
||||
window.close();
|
||||
window.opener.wrappedJSObject.SimpleTest.finish();
|
||||
}
|
||||
|
||||
var executedCommandID = "";
|
||||
|
||||
function testItem(location, targetID) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
||||
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
|
||||
var correctCommandHandler = false;
|
||||
try {
|
||||
utils.activateNativeMenuItemAt(location);
|
||||
correctCommandHandler = executedCommandID == targetID;
|
||||
}
|
||||
catch (e) {
|
||||
dump(e + "\n");
|
||||
}
|
||||
finally {
|
||||
ok(correctCommandHandler, 'Command handler not run correctly');
|
||||
executedCommandID = "";
|
||||
}
|
||||
}
|
||||
|
||||
function onLoad() {
|
||||
var _delayedOnLoad = function() {
|
||||
testItem("0|0", "cmd_FooItem1");
|
||||
testItem("0|1", "cmd_FooItem2");
|
||||
testItem("0|3|0", "cmd_BarItem1");
|
||||
testItem("0|3|1", "cmd_BarItem2");
|
||||
onTestsFinished()
|
||||
}
|
||||
|
||||
setTimeout(_delayedOnLoad, 1000);
|
||||
}
|
||||
|
||||
]]></script>
|
||||
</window>
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<window title="Native menu system tests"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<title>Native menu system tests</title>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
window.open("native_menus_window.xul", "NativeMenuWindow",
|
||||
"chrome,width=600,height=600");
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
</window>
|
|
@ -109,8 +109,8 @@
|
|||
#include "nsIMarkupDocumentViewer.h"
|
||||
#include "nsIFocusEventSuppressor.h"
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#include "nsIMenuBar.h"
|
||||
#ifdef XP_MACOSX
|
||||
#include "nsINativeMenuService.h"
|
||||
#define USE_NATIVE_MENUS
|
||||
#endif
|
||||
|
||||
|
@ -122,9 +122,6 @@ static PRUint32 gWebShellWindowCount = 0;
|
|||
/* Define Class IDs */
|
||||
static NS_DEFINE_CID(kWindowCID, NS_WINDOW_CID);
|
||||
|
||||
#include "nsWidgetsCID.h"
|
||||
static NS_DEFINE_CID(kMenuBarCID, NS_MENUBAR_CID);
|
||||
|
||||
#define SIZE_PERSISTENCE_TIMEOUT 500 // msec
|
||||
|
||||
nsWebShellWindow::nsWebShellWindow() : nsXULWindow()
|
||||
|
@ -552,23 +549,17 @@ static void LoadNativeMenus(nsIDOMDocument *aDOMDoc, nsIWidget *aParentWindow)
|
|||
aDOMDoc->GetElementsByTagNameNS(NS_LITERAL_STRING("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"),
|
||||
NS_LITERAL_STRING("menubar"),
|
||||
getter_AddRefs(menubarElements));
|
||||
|
||||
|
||||
nsCOMPtr<nsIDOMNode> menubarNode;
|
||||
if (menubarElements)
|
||||
menubarElements->Item(0, getter_AddRefs(menubarNode));
|
||||
|
||||
if (!menubarNode)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIMenuBar> pnsMenuBar = do_CreateInstance(kMenuBarCID);
|
||||
if (!pnsMenuBar)
|
||||
return;
|
||||
|
||||
pnsMenuBar->Create(aParentWindow);
|
||||
|
||||
// fake event
|
||||
nsMenuEvent fake(PR_TRUE, 0, nsnull);
|
||||
pnsMenuBar->MenuConstruct(fake, aParentWindow, menubarNode);
|
||||
nsCOMPtr<nsINativeMenuService> nms = do_GetService("@mozilla.org/widget/nativemenuservice;1");
|
||||
nsCOMPtr<nsIContent> menubarContent(do_QueryInterface(menubarNode));
|
||||
if (nms && menubarContent)
|
||||
nms->CreateNativeMenuBar(aParentWindow, menubarContent);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче