diff --git a/widget/public/Makefile.in b/widget/public/Makefile.in index 141f4e081b1..89be38f0219 100644 --- a/widget/public/Makefile.in +++ b/widget/public/Makefile.in @@ -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) diff --git a/widget/public/nsIMenu.h b/widget/public/nsIMenu.h deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/widget/public/nsIMenuItem.h b/widget/public/nsIMenuItem.h deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/widget/src/cocoa/Makefile.in b/widget/src/cocoa/Makefile.in index c3b5d66fcfe..d9fedfa3dfc 100644 --- a/widget/src/cocoa/Makefile.in +++ b/widget/src/cocoa/Makefile.in @@ -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) diff --git a/widget/src/cocoa/nsAppShell.mm b/widget/src/cocoa/nsAppShell.mm index 8456f021b09..7b08d4e1dfb 100644 --- a/widget/src/cocoa/nsAppShell.mm +++ b/widget/src/cocoa/nsAppShell.mm @@ -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; } diff --git a/widget/src/cocoa/nsChangeObserver.h b/widget/src/cocoa/nsChangeObserver.h new file mode 100644 index 00000000000..b51cfd5e6b9 --- /dev/null +++ b/widget/src/cocoa/nsChangeObserver.h @@ -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 (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_ diff --git a/widget/src/cocoa/nsIChangeManager.idl b/widget/src/cocoa/nsIChangeManager.idl deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/widget/src/cocoa/nsIMenu.h b/widget/src/cocoa/nsIMenu.h new file mode 100644 index 00000000000..55fb8528004 --- /dev/null +++ b/widget/src/cocoa/nsIMenu.h @@ -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 diff --git a/widget/src/cocoa/nsIMenuCommandDispatcher.idl b/widget/src/cocoa/nsIMenuCommandDispatcher.idl deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/widget/src/cocoa/nsIMenuItem.h b/widget/src/cocoa/nsIMenuItem.h new file mode 100644 index 00000000000..4e5be47c2c3 --- /dev/null +++ b/widget/src/cocoa/nsIMenuItem.h @@ -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 diff --git a/widget/src/cocoa/nsMenuBarX.h b/widget/src/cocoa/nsMenuBarX.h index fc2f5e1e210..2f9abd7ccb6 100644 --- a/widget/src/cocoa/nsMenuBarX.h +++ b/widget/src/cocoa/nsMenuBarX.h @@ -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); diff --git a/widget/src/cocoa/nsMenuBarX.mm b/widget/src/cocoa/nsMenuBarX.mm index 12cbd2178e9..b306338261b 100644 --- a/widget/src/cocoa/nsMenuBarX.mm +++ b/widget/src/cocoa/nsMenuBarX.mm @@ -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 pnsMenu(do_CreateInstance(kMenuCID)); if (pnsMenu) { - pnsMenu->Create(static_cast(this), menuName, menuAccessKey, - static_cast(this), menu); + pnsMenu->Create(static_cast(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 obs; - Lookup(aContainer, getter_AddRefs(obs)); + nsChangeObserver* obs = LookupContentChangeObserver(aContainer); if (obs) - obs->ContentInserted(aDocument, aContainer, aNewIndexInContainer); + obs->ObserveContentInserted(aDocument, aContainer, aNewIndexInContainer); else { nsCOMPtr 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 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 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 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 obs; - Lookup (aContainer, getter_AddRefs(obs)); + nsChangeObserver* obs = LookupContentChangeObserver(aContainer); if (obs) - obs->ContentInserted (aDocument, aChild, aIndexInContainer); + obs->ObserveContentInserted(aDocument, aChild, aIndexInContainer); else { nsCOMPtr 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(mObserverTable.Get(&key)); - NS_IF_ADDREF (*_retval); - - return NS_OK; + nsVoidKey key(aContent); + return reinterpret_cast(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; } diff --git a/widget/src/cocoa/nsMenuItemX.h b/widget/src/cocoa/nsMenuItemX.h index eee886bc974..6307bfe80e6 100644 --- a/widget/src/cocoa/nsMenuItemX.h +++ b/widget/src/cocoa/nsMenuItemX.h @@ -41,8 +41,7 @@ #include "nsIMenuItem.h" #include "nsString.h" -#include "nsIChangeManager.h" -#include "nsIWidget.h" +#include "nsChangeObserver.h" #include "nsAutoPtr.h" #import @@ -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 mContent; nsCOMPtr mCommandContent; diff --git a/widget/src/cocoa/nsMenuItemX.mm b/widget/src/cocoa/nsMenuItemX.mm index 508217a9a5c..4ed37841449 100644 --- a/widget/src/cocoa/nsMenuItemX.mm +++ b/widget/src/cocoa/nsMenuItemX.mm @@ -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 obs = do_QueryInterface(static_cast(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 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; } diff --git a/widget/src/cocoa/nsMenuX.h b/widget/src/cocoa/nsMenuX.h index 501f9709cc8..d8b7bc83e9b 100644 --- a/widget/src/cocoa/nsMenuX.h +++ b/widget/src/cocoa/nsMenuX.h @@ -42,7 +42,7 @@ #include "nsCOMPtr.h" #include "nsAutoPtr.h" #include "nsIMenu.h" -#include "nsIChangeManager.h" +#include "nsChangeObserver.h" #include "nsMenuBarX.h" #import @@ -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 mMenuContent; // the |menu| tag, strong ref nsRefPtr mIcon; diff --git a/widget/src/cocoa/nsMenuX.mm b/widget/src/cocoa/nsMenuX.mm index 45448cca99c..8c53fccd93d 100644 --- a/widget/src/cocoa/nsMenuX.mm +++ b/widget/src/cocoa/nsMenuX.mm @@ -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 changeObs(do_QueryInterface(static_cast(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 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 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(this), menuName, EmptyString(), mManager, inMenuContent); + pnsMenu->Create(reinterpret_cast(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 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 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; }