decomtaminate nsIChangeObserver, nsIChangeManager, nsIMenuCommandDispatcher. b=413407 r=bent sr=roc a=beltzner

This commit is contained in:
joshmoz%gmail.com 2008-01-23 04:04:16 +00:00
Родитель 2200f581c7
Коммит 69e630f5d8
16 изменённых файлов: 611 добавлений и 168 удалений

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

@ -64,10 +64,7 @@ EXPORTS = \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
EXPORTS += \
nsIMenuBar.h \
nsIMenu.h \
nsIMenuItem.h
EXPORTS += nsIMenuBar.h
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)

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

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

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

@ -84,6 +84,9 @@ endif
EXPORTS = \
mozView.h \
nsChangeObserver.h \
nsIMenu.h \
nsIMenuItem.h \
$(NULL)
CMMSRCS = \
@ -117,8 +120,6 @@ CMMSRCS = \
$(NULL)
XPIDLSRCS += \
nsIChangeManager.idl \
nsIMenuCommandDispatcher.idl \
nsPIWidgetCocoa.idl \
$(NULL)

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

@ -466,10 +466,10 @@ nsAppShell::ProcessNextNativeEvent(PRBool aMayWait)
// Minefield) the modal window (or non-main event loop) won't receive key
// events or most mouse events.
if ([NSApp _isRunningModal] || !InGeckoMainEventLoop()) {
if (nextEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:waitUntil
inMode:currentMode
dequeue:YES]) {
if ((nextEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:waitUntil
inMode:currentMode
dequeue:YES])) {
[NSApp sendEvent:nextEvent];
eventProcessed = PR_TRUE;
}

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

@ -0,0 +1,77 @@
/* -*- Mode: IDL; 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 Communicator.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corp.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mike Pinkerton
* Josh Aas <josh@mozilla.com> (decomtaminate)
*
* 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 nsChangeObserver_h_
#define nsChangeObserver_h_
class nsIContent;
class nsIDocument;
class nsIAtom;
#define NS_DECL_CHANGEOBSERVER \
void ObserveAttributeChanged(nsIDocument *aDocument, nsIContent *aContent, nsIAtom *aAttribute); \
void ObserveContentRemoved(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer); \
void ObserveContentInserted(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer);
// Something that wants to be alerted to changes in attributes or changes in
// its corresponding content object.
//
// This interface is used by our menu code so we only have to have one
// nsIDocumentObserver.
//
// Any class that implements this interface must take care to unregister itself
// on deletion.
class nsChangeObserver
{
public:
virtual void ObserveAttributeChanged(nsIDocument* aDocument,
nsIContent* aContent,
nsIAtom* aAttribute)=0;
virtual void ObserveContentRemoved(nsIDocument* aDocument,
nsIContent* aChild,
PRInt32 aIndexInContainer)=0;
virtual void ObserveContentInserted(nsIDocument* aDocument,
nsIContent* aChild,
PRInt32 aIndexInContainer)=0;
};
#endif // nsChangeObserver_h_

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

240
widget/src/cocoa/nsIMenu.h Normal file
Просмотреть файл

@ -0,0 +1,240 @@
/* -*- 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

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

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

@ -0,0 +1,168 @@
/* -*- 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"
// CC986E81-9F46-4AA2-B809-C544789E6F06
#define NS_IMENUITEM_IID \
{ 0xCC986E81, 0x9F46, 0x4AA2, \
{ 0xB8, 0x09, 0xC5, 0x44, 0x78, 0x9E, 0x6F, 0x06 } }
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;
/**
* Set the Menu shortcut char
*
*/
NS_IMETHOD SetShortcutChar(const 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;
/**
*
*/
NS_IMETHOD SetModifiers(PRUint8 aModifiers) = 0;
NS_IMETHOD GetModifiers(PRUint8 * aModifiers) = 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

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

@ -41,8 +41,6 @@
#include "nsIMenuBar.h"
#include "nsIMutationObserver.h"
#include "nsIChangeManager.h"
#include "nsIMenuCommandDispatcher.h"
#include "nsCOMArray.h"
#include "nsHashtable.h"
#include "nsWeakReference.h"
@ -54,6 +52,7 @@
class nsIWidget;
class nsIDocument;
class nsIDOMNode;
class nsChangeObserver;
extern "C" MenuRef _NSGetCarbonMenu(NSMenu* aMenu);
@ -82,8 +81,6 @@ namespace MenuHelpersX
class nsMenuBarX : public nsIMenuBar,
public nsIMutationObserver,
public nsIChangeManager,
public nsIMenuCommandDispatcher,
public nsSupportsWeakReference
{
public:
@ -96,8 +93,6 @@ public:
static NSWindow* sEventTargetWindow;
NS_DECL_ISUPPORTS
NS_DECL_NSICHANGEMANAGER
NS_DECL_NSIMENUCOMMANDDISPATCHER
// nsIMutationObserver
NS_DECL_NSIMUTATIONOBSERVER
@ -117,8 +112,14 @@ public:
NS_IMETHOD SetNativeData(void* aData);
NS_IMETHOD MenuConstruct(const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow, void * aMenuNode);
PRUint32 RegisterForCommand(nsIMenuItem* aItem);
void UnregisterCommand(PRUint32 aCommandID);
void RegisterForContentChanges(nsIContent* aContent, nsChangeObserver* aMenuObject);
void UnregisterForContentChanges(nsIContent* aContent);
nsChangeObserver* LookupContentChangeObserver(nsIContent* aContent);
protected:
// Make our menubar conform to Aqua UI guidelines
void AquifyMenuBar();
void HideItem(nsIDOMDocument* inDoc, const nsAString & inID, nsIContent** outHiddenNode);

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

@ -64,8 +64,7 @@
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
NS_IMPL_ISUPPORTS5(nsMenuBarX, nsIMenuBar, nsIMutationObserver,
nsIChangeManager, nsIMenuCommandDispatcher, nsISupportsWeakReference)
NS_IMPL_ISUPPORTS3(nsMenuBarX, nsIMenuBar, nsIMutationObserver, nsISupportsWeakReference)
EventHandlerUPP nsMenuBarX::sCommandEventHandler = nsnull;
NativeMenuItemTarget* nsMenuBarX::sNativeEventTarget = nil;
@ -102,7 +101,10 @@ PRBool NodeIsHiddenOrCollapsed(nsIContent* inContent)
nsMenuBarX::nsMenuBarX()
: mParent(nsnull), mIsMenuBarAdded(PR_FALSE), mCurrentCommandID(eCommand_ID_Last), mDocument(nsnull)
: mParent(nsnull),
mIsMenuBarAdded(PR_FALSE),
mCurrentCommandID(eCommand_ID_Last),
mDocument(nsnull)
{
mRootMenu = [[NSMenu alloc] initWithTitle:@"MainMenuBar"];
@ -335,8 +337,7 @@ nsMenuBarX::MenuConstruct(const nsMenuEvent & aMenuEvent, nsIWidget* aParentWind
// Create nsMenu, the menubar will own it
nsCOMPtr<nsIMenu> pnsMenu(do_CreateInstance(kMenuCID));
if (pnsMenu) {
pnsMenu->Create(static_cast<nsIMenuBar*>(this), menuName, menuAccessKey,
static_cast<nsIChangeManager *>(this), menu);
pnsMenu->Create(static_cast<nsIMenuBar*>(this), menuName, menuAccessKey, this, menu);
AddMenu(pnsMenu);
}
}
@ -722,20 +723,19 @@ nsMenuBarX::CharacterDataChanged(nsIDocument * aDocument,
void
nsMenuBarX::ContentAppended(nsIDocument * aDocument, nsIContent * aContainer,
nsMenuBarX::ContentAppended(nsIDocument* aDocument, nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
if (aContainer != mMenuBarContent) {
nsCOMPtr<nsIChangeObserver> obs;
Lookup(aContainer, getter_AddRefs(obs));
nsChangeObserver* obs = LookupContentChangeObserver(aContainer);
if (obs)
obs->ContentInserted(aDocument, aContainer, aNewIndexInContainer);
obs->ObserveContentInserted(aDocument, aContainer, aNewIndexInContainer);
else {
nsCOMPtr<nsIContent> parent = aContainer->GetParent();
if (parent) {
Lookup(parent, getter_AddRefs(obs));
obs = LookupContentChangeObserver(parent);
if (obs)
obs->ContentInserted(aDocument, aContainer, aNewIndexInContainer);
obs->ObserveContentInserted(aDocument, aContainer, aNewIndexInContainer);
}
}
}
@ -755,32 +755,31 @@ nsMenuBarX::AttributeChanged(nsIDocument * aDocument, nsIContent * aContent,
PRInt32 aModType, PRUint32 aStateMask)
{
// lookup and dispatch to registered thang
nsCOMPtr<nsIChangeObserver> obs;
Lookup(aContent, getter_AddRefs(obs));
nsChangeObserver* obs = LookupContentChangeObserver(aContent);
if (obs)
obs->AttributeChanged(aDocument, aNameSpaceID, aContent, aAttribute);
obs->ObserveAttributeChanged(aDocument, aContent, aAttribute);
}
void
nsMenuBarX::ContentRemoved(nsIDocument * aDocument, nsIContent * aContainer,
nsIContent * aChild, PRInt32 aIndexInContainer)
{
nsIContent * aChild, PRInt32 aIndexInContainer)
{
if (aContainer == mMenuBarContent) {
Unregister(aChild);
UnregisterForContentChanges(aChild);
RemoveMenu(aIndexInContainer);
}
else {
nsCOMPtr<nsIChangeObserver> obs;
Lookup (aContainer, getter_AddRefs(obs));
if (obs)
obs->ContentRemoved(aDocument, aChild, aIndexInContainer);
nsChangeObserver* obs = LookupContentChangeObserver(aContainer);
if (obs) {
obs->ObserveContentRemoved(aDocument, aChild, aIndexInContainer);
}
else {
nsCOMPtr<nsIContent> parent = aContainer->GetParent();
if (parent) {
Lookup (parent, getter_AddRefs(obs));
obs = LookupContentChangeObserver(parent);
if (obs)
obs->ContentRemoved(aDocument, aChild, aIndexInContainer);
obs->ObserveContentRemoved(aDocument, aChild, aIndexInContainer);
}
}
}
@ -790,18 +789,17 @@ nsMenuBarX::ContentRemoved(nsIDocument * aDocument, nsIContent * aContainer,
void
nsMenuBarX::ContentInserted(nsIDocument * aDocument, nsIContent * aContainer,
nsIContent * aChild, PRInt32 aIndexInContainer)
{
{
if (aContainer != mMenuBarContent) {
nsCOMPtr<nsIChangeObserver> obs;
Lookup (aContainer, getter_AddRefs(obs));
nsChangeObserver* obs = LookupContentChangeObserver(aContainer);
if (obs)
obs->ContentInserted (aDocument, aChild, aIndexInContainer);
obs->ObserveContentInserted(aDocument, aChild, aIndexInContainer);
else {
nsCOMPtr<nsIContent> parent = aContainer->GetParent();
if (parent) {
Lookup (parent, getter_AddRefs(obs));
obs = LookupContentChangeObserver(parent);
if (obs)
obs->ContentInserted(aDocument, aChild, aIndexInContainer);
obs->ObserveContentInserted(aDocument, aChild, aIndexInContainer);
}
}
}
@ -814,81 +812,62 @@ nsMenuBarX::ParentChainChanged(nsIContent *aContent)
}
//
// nsIChangeManager
//
// We don't use a |nsSupportsHashtable| because we know that the 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.
//
NS_IMETHODIMP
nsMenuBarX::Register(nsIContent *aContent, nsIChangeObserver *aMenuObject)
// For change management, we don't use a |nsSupportsHashtable| because we know that the
// 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)
{
nsVoidKey key(aContent);
mObserverTable.Put(&key, aMenuObject);
return NS_OK;
}
NS_IMETHODIMP
nsMenuBarX::Unregister(nsIContent *aContent)
void
nsMenuBarX::UnregisterForContentChanges(nsIContent *aContent)
{
nsVoidKey key(aContent);
mObserverTable.Remove(&key);
return NS_OK;
}
NS_IMETHODIMP
nsMenuBarX::Lookup(nsIContent *aContent, nsIChangeObserver **_retval)
nsChangeObserver*
nsMenuBarX::LookupContentChangeObserver(nsIContent* aContent)
{
*_retval = nsnull;
nsVoidKey key (aContent);
*_retval = reinterpret_cast<nsIChangeObserver*>(mObserverTable.Get(&key));
NS_IF_ADDREF (*_retval);
return NS_OK;
nsVoidKey key(aContent);
return reinterpret_cast<nsChangeObserver*>(mObserverTable.Get(&key));
}
//
// Implementation methods for nsIMenuCommandDispatcher
//
// 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.
NS_IMETHODIMP
nsMenuBarX::Register(nsIMenuItem* inMenuItem, PRUint32* outCommandID)
PRUint32
nsMenuBarX::RegisterForCommand(nsIMenuItem* 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,
// those don't start until at least ' ', which is integer 538976288. If
// we have that many menu items in one window, I think we have other problems.
// make id unique
++mCurrentCommandID;
// put it in the table, set out param for client
nsPRUint32Key key(mCurrentCommandID);
mObserverTable.Put(&key, inMenuItem);
*outCommandID = mCurrentCommandID;
// make id unique for next time
++mCurrentCommandID;
return NS_OK;
return mCurrentCommandID;
}
// Removes the mapping between the given 4-character command ID
// and its associated menu item.
NS_IMETHODIMP
nsMenuBarX::Unregister(PRUint32 inCommandID)
void
nsMenuBarX::UnregisterCommand(PRUint32 inCommandID)
{
nsPRUint32Key key(inCommandID);
mObserverTable.Remove(&key);
return NS_OK;
}

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

@ -41,8 +41,7 @@
#include "nsIMenuItem.h"
#include "nsString.h"
#include "nsIChangeManager.h"
#include "nsIWidget.h"
#include "nsChangeObserver.h"
#include "nsAutoPtr.h"
#import <Cocoa/Cocoa.h>
@ -51,11 +50,11 @@ class nsIMenu;
class nsMenuItemIconX;
/**
* Native Motif MenuItem wrapper
* Native menu item wrapper
*/
class nsMenuItemX : public nsIMenuItem,
public nsIChangeObserver
public nsChangeObserver
{
public:
nsMenuItemX();
@ -63,11 +62,11 @@ public:
// nsISupports
NS_DECL_ISUPPORTS
NS_DECL_NSICHANGEOBSERVER
NS_DECL_CHANGEOBSERVER
// nsIMenuItem Methods
NS_IMETHOD Create(nsIMenu* aParent, const nsString & aLabel, EMenuItemType aItemType,
nsIChangeManager* aManager, nsIContent* aNode);
nsMenuBarX* aMenuBar, nsIContent* aNode);
NS_IMETHOD GetLabel(nsString &aText);
NS_IMETHOD SetShortcutChar(const nsString &aText);
NS_IMETHOD GetShortcutChar(nsString &aText);
@ -95,7 +94,7 @@ protected:
nsString mKeyEquivalent;
nsIMenu* mMenuParent; // weak, parent owns us
nsIChangeManager* mManager; // weak
nsMenuBarX* mMenuBar; // weak
nsCOMPtr<nsIContent> mContent;
nsCOMPtr<nsIContent> mCommandContent;

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

@ -57,14 +57,14 @@
#include "nsGUIEvent.h"
NS_IMPL_ISUPPORTS2(nsMenuItemX, nsIMenuItem, nsIChangeObserver)
NS_IMPL_ISUPPORTS1(nsMenuItemX, nsIMenuItem)
nsMenuItemX::nsMenuItemX()
{
mNativeMenuItem = nil;
mMenuParent = nsnull;
mManager = nsnull;
mMenuBar = nsnull;
mKeyEquivalent.AssignLiteral(" ");
mEnabled = PR_TRUE;
mIsChecked = PR_FALSE;
@ -76,14 +76,14 @@ nsMenuItemX::~nsMenuItemX()
{
[mNativeMenuItem autorelease];
if (mContent)
mManager->Unregister(mContent);
mMenuBar->UnregisterForContentChanges(mContent);
if (mCommandContent)
mManager->Unregister(mCommandContent);
mMenuBar->UnregisterForContentChanges(mCommandContent);
}
NS_METHOD nsMenuItemX::Create(nsIMenu* aParent, const nsString & aLabel, EMenuItemType aItemType,
nsIChangeManager* aManager, nsIContent* aNode)
nsMenuBarX* aMenuBar, nsIContent* aNode)
{
mContent = aNode; // addref
mMenuParent = aParent; // weak
@ -91,10 +91,10 @@ NS_METHOD nsMenuItemX::Create(nsIMenu* aParent, const nsString & aLabel, EMenuIt
mType = aItemType;
// register for AttributeChanged messages
mManager = aManager;
nsCOMPtr<nsIChangeObserver> obs = do_QueryInterface(static_cast<nsIChangeObserver*>(this));
mManager->Register(mContent, obs); // does not addref this
mMenuBar = aMenuBar;
NS_ASSERTION(mMenuBar, "No menu bar given, must have one");
mMenuBar->RegisterForContentChanges(mContent, this);
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mContent->GetCurrentDoc()));
// if we have a command associated with this menu item, register for changes
@ -110,7 +110,7 @@ NS_METHOD nsMenuItemX::Create(nsIMenu* aParent, const nsString & aLabel, EMenuIt
if (commandElement) {
mCommandContent = do_QueryInterface(commandElement);
// register to observe the command DOM element
mManager->Register(mCommandContent, obs); // does not addref this
mMenuBar->RegisterForContentChanges(mCommandContent, this);
}
}
}
@ -368,15 +368,15 @@ nsMenuItemX::UncheckRadioSiblings(nsIContent* inCheckedContent)
//
// nsIChangeObserver
// nsChangeObserver
//
NS_IMETHODIMP
nsMenuItemX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIContent *aContent, nsIAtom *aAttribute)
void
nsMenuItemX::ObserveAttributeChanged(nsIDocument *aDocument, nsIContent *aContent, nsIAtom *aAttribute)
{
if (!aContent)
return NS_OK;
return;
if (aContent == mContent) { // our own content node changed
if (aAttribute == nsWidgetAtoms::checked) {
@ -427,29 +427,25 @@ nsMenuItemX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIC
[mNativeMenuItem setEnabled:YES];
}
}
return NS_OK;
}
NS_IMETHODIMP
nsMenuItemX::ContentRemoved(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
void
nsMenuItemX::ObserveContentRemoved(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
{
if (aChild == mCommandContent) {
mManager->Unregister(mCommandContent);
mMenuBar->UnregisterForContentChanges(mCommandContent);
mCommandContent = nsnull;
}
mMenuParent->SetRebuild(PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsMenuItemX::ContentInserted(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
void
nsMenuItemX::ObserveContentInserted(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
{
mMenuParent->SetRebuild(PR_TRUE);
return NS_OK;
}

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

@ -42,7 +42,7 @@
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsIMenu.h"
#include "nsIChangeManager.h"
#include "nsChangeObserver.h"
#include "nsMenuBarX.h"
#import <Carbon/Carbon.h>
@ -67,21 +67,20 @@ class nsMenuItemIconX;
class nsMenuX : public nsIMenu,
public nsIChangeObserver
public nsChangeObserver
{
public:
nsMenuX();
virtual ~nsMenuX();
NS_DECL_ISUPPORTS
NS_DECL_NSICHANGEOBSERVER
NS_DECL_CHANGEOBSERVER
id GetNativeMenuItem();
// nsIMenu Methods
NS_IMETHOD Create(nsISupports * aParent, const nsAString &aLabel, const nsAString &aAccessKey,
nsIChangeManager* aManager, nsIContent* aNode);
nsMenuBarX* aMenuBar, nsIContent* aNode);
NS_IMETHOD GetParent(nsISupports *&aParent);
NS_IMETHOD GetLabel(nsString &aText);
NS_IMETHOD SetLabel(const nsAString &aText);
@ -140,7 +139,7 @@ protected:
PRUint32 mVisibleItemsCount; // caching number of visible items in mMenuItemsArray
nsISupports* mParent; // weak, my parent owns me
nsIChangeManager* mManager; // weak ref, it will outlive us [menubar]
nsMenuBarX* mMenuBar; // weak ref, it will outlive us
nsCOMPtr<nsIContent> mMenuContent; // the |menu| tag, strong ref
nsRefPtr<nsMenuItemIconX> mIcon;

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

@ -50,7 +50,6 @@
#include "nsIMenu.h"
#include "nsIMenuBar.h"
#include "nsIMenuItem.h"
#include "nsIMenuCommandDispatcher.h"
#include "nsToolkit.h"
#include "nsString.h"
@ -83,11 +82,11 @@ static PRBool gConstructingMenu = PR_FALSE;
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
static NS_DEFINE_CID(kMenuItemCID, NS_MENUITEM_CID);
NS_IMPL_ISUPPORTS2(nsMenuX, nsIMenu, nsIChangeObserver)
NS_IMPL_ISUPPORTS1(nsMenuX, nsIMenu)
nsMenuX::nsMenuX()
: mVisibleItemsCount(0), mParent(nsnull), mManager(nsnull), mMacMenuID(0),
: mVisibleItemsCount(0), mParent(nsnull), mMenuBar(nsnull), mMacMenuID(0),
mMacMenu(nil), mNativeMenuItem(nil), mIsEnabled(PR_TRUE),
mDestroyHandlerCalled(PR_FALSE), mNeedsRebuild(PR_TRUE),
mConstructed(PR_FALSE), mVisible(PR_TRUE), mXBLAttached(PR_FALSE)
@ -106,25 +105,24 @@ nsMenuX::~nsMenuX()
[mMacMenu release];
[mMenuDelegate release];
[mNativeMenuItem release];
// alert the change notifier we don't care no more
mManager->Unregister(mMenuContent);
if (mMenuContent)
mMenuBar->UnregisterForContentChanges(mMenuContent);
}
NS_IMETHODIMP
nsMenuX::Create(nsISupports * aParent, const nsAString &aLabel, const nsAString &aAccessKey,
nsIChangeManager* aManager, nsIContent* aNode)
nsMenuBarX* aMenuBar, nsIContent* aNode)
{
mMenuContent = aNode;
NS_ASSERTION(mMenuContent, "Menu not given a dom node at creation time");
// register this menu to be notified when changes are made to our content object
mManager = aManager; // weak ref
nsCOMPtr<nsIChangeObserver> changeObs(do_QueryInterface(static_cast<nsIChangeObserver*>(this)));
mManager->Register(mMenuContent, changeObs);
NS_ASSERTION(mMenuContent, "Menu not given a dom node at creation time");
NS_ASSERTION(mManager, "No change manager given, can't tell content model updates");
mMenuBar = aMenuBar; // weak ref
NS_ASSERTION(mMenuBar, "No menu bar given, must have one");
mMenuBar->RegisterForContentChanges(mMenuContent, this);
mParent = aParent;
// our parent could be either a menu bar (if we're toplevel) or a menu (if we're a submenu)
@ -249,13 +247,7 @@ nsresult nsMenuX::AddMenuItem(nsIMenuItem * aMenuItem)
[newNativeMenuItem setAction:@selector(menuItemHit:)];
// set its command. we get the unique command id from the menubar
nsCOMPtr<nsIMenuCommandDispatcher> dispatcher(do_QueryInterface(mManager));
if (dispatcher) {
PRUint32 commandID = 0L;
dispatcher->Register(aMenuItem, &commandID);
if (commandID)
[newNativeMenuItem setTag:commandID];
}
[newNativeMenuItem setTag:mMenuBar->RegisterForCommand(aMenuItem)];
return NS_OK;
}
@ -387,13 +379,11 @@ NS_IMETHODIMP nsMenuX::RemoveItem(const PRUint32 aPos)
NS_IMETHODIMP nsMenuX::RemoveAll()
{
if (mMacMenu != nil) {
if (mMacMenu) {
// clear command id's
nsCOMPtr<nsIMenuCommandDispatcher> dispatcher(do_QueryInterface(mManager));
if (dispatcher) {
for (int i = 0; i < [mMacMenu numberOfItems]; i++)
dispatcher->Unregister((PRUint32)[[mMacMenu itemAtIndex:i] tag]);
}
int itemCount = [mMacMenu numberOfItems];
for (int i = 0; i < itemCount; i++)
mMenuBar->UnregisterCommand((PRUint32)[[mMacMenu itemAtIndex:i] tag]);
// get rid of Cocoa menu items
for (int i = [mMacMenu numberOfItems] - 1; i >= 0; i--)
[mMacMenu removeItemAtIndex:i];
@ -644,7 +634,7 @@ void nsMenuX::LoadMenuItem(nsIContent* inMenuItemContent)
}
// Create the item.
pnsMenuItem->Create(this, menuitemName, itemType, mManager, inMenuItemContent);
pnsMenuItem->Create(this, menuitemName, itemType, mMenuBar, inMenuItemContent);
AddMenuItem(pnsMenuItem);
@ -665,7 +655,7 @@ void nsMenuX::LoadSubMenu(nsIContent* inMenuContent)
if (!pnsMenu)
return;
pnsMenu->Create(reinterpret_cast<nsISupports*>(this), menuName, EmptyString(), mManager, inMenuContent);
pnsMenu->Create(reinterpret_cast<nsISupports*>(this), menuName, EmptyString(), mMenuBar, inMenuContent);
AddMenu(pnsMenu);
@ -959,16 +949,16 @@ nsMenuX::GetNativeMenuItem()
//
// nsIChangeObserver
// nsChangeObserver
//
NS_IMETHODIMP nsMenuX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpaceID,
nsIContent *aContent, nsIAtom *aAttribute)
void
nsMenuX::ObserveAttributeChanged(nsIDocument *aDocument, nsIContent *aContent, nsIAtom *aAttribute)
{
// ignore the |open| attribute, which is by far the most common
if (gConstructingMenu || (aAttribute == nsWidgetAtoms::open))
return NS_OK;
return;
nsCOMPtr<nsIMenuBar> menubarParent = do_QueryInterface(mParent);
@ -1004,7 +994,7 @@ NS_IMETHODIMP nsMenuX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpa
// don't do anything if the state is correct already
if (contentIsHiddenOrCollapsed != mVisible)
return NS_OK;
return;
nsCOMPtr<nsIMenu> menuParent = do_QueryInterface(mParent);
if (contentIsHiddenOrCollapsed) {
@ -1038,36 +1028,32 @@ NS_IMETHODIMP nsMenuX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpa
}
else if (aAttribute == nsWidgetAtoms::image) {
SetupIcon();
}
return NS_OK;
}
}
NS_IMETHODIMP nsMenuX::ContentRemoved(nsIDocument *aDocument, nsIContent *aChild,
PRInt32 aIndexInContainer)
void
nsMenuX::ObserveContentRemoved(nsIDocument *aDocument, nsIContent *aChild,
PRInt32 aIndexInContainer)
{
if (gConstructingMenu)
return NS_OK;
return;
SetRebuild(PR_TRUE);
RemoveItem(aIndexInContainer);
mManager->Unregister(aChild);
return NS_OK;
mMenuBar->UnregisterForContentChanges(aChild);
}
NS_IMETHODIMP nsMenuX::ContentInserted(nsIDocument *aDocument, nsIContent *aChild,
PRInt32 aIndexInContainer)
void
nsMenuX::ObserveContentInserted(nsIDocument *aDocument, nsIContent *aChild,
PRInt32 aIndexInContainer)
{
if (gConstructingMenu)
return NS_OK;
return;
SetRebuild(PR_TRUE);
return NS_OK;
}