[Not part of build] Updated to use SetRootMenu() and SetMenuItemHierarchicalMenu() rather than juggling menu bars.

This commit is contained in:
beard%netscape.com 2000-12-15 21:43:22 +00:00
Родитель b2951a4ef6
Коммит 725b574834
4 изменённых файлов: 334 добавлений и 488 удалений

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

@ -51,27 +51,16 @@
#include <Appearance.h>
#include "nsMacResources.h"
static NS_DEFINE_IID(kIStringBundleServiceIID, NS_ISTRINGBUNDLESERVICE_IID);
static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
nsWeakPtr gMacMenubarX;
#if !TARGET_CARBON
extern nsMenuStack gPreviousMenuStack;
#endif
// CIDs
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kMenuBarCID, NS_MENUBAR_CID);
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
static NS_DEFINE_CID(kMenuItemCID, NS_MENUITEM_CID);
PRInt32 gMenuBarCounterX = 0;
NS_IMPL_ISUPPORTS5(nsMenuBarX, nsIMenuBar, nsIMenuListener, nsIDocumentObserver, nsIChangeManager, nsISupportsWeakReference)
static MenuRef gDefaultRootMenu = nsnull;
//
// nsMenuBarX constructor
//
@ -81,16 +70,14 @@ nsMenuBarX::nsMenuBarX()
mNumMenus = 0;
mParent = nsnull;
mIsMenuBarAdded = PR_FALSE;
mMacMBarHandle = nsnull;
++gMenuBarCounterX;
// if there's already a menu bar, save off its contents, so we have a clean slate.
if (gMacMenubarX) {
nsCOMPtr<nsIMenuBar> menuBar = do_QueryReferent(gMacMenubarX);
if (menuBar) menuBar->SetNativeData(::GetMenuBar());
gMacMenubarX = nsnull;
OSStatus status = ::CreateNewMenu(0, 0, &mRootMenu);
NS_ASSERTION(status == noErr, "nsMenuBarX::nsMenuBarX: creation of root menu failed.");
if (gDefaultRootMenu == nsnull) {
gDefaultRootMenu = ::AcquireRootMenu();
NS_ASSERTION(gDefaultRootMenu != nsnull, "nsMenuBarX::nsMenuBarX: no default root menu!.");
}
::ClearMenuBar();
}
//
@ -109,12 +96,11 @@ nsMenuBarX::~nsMenuBarX()
doc->RemoveObserver(observer);
}
--gMenuBarCounterX;
if (gMenuBarCounterX == 0)
::ClearMenuBar();
if (mMacMBarHandle)
::DisposeHandle(mMacMBarHandle);
if (mRootMenu != NULL) {
NS_ASSERTION(gDefaultRootMenu != nsnull, "nsMenuBarX::~nsMenuBarX: no default root menu!.");
::SetRootMenu(gDefaultRootMenu);
::ReleaseMenu(mRootMenu);
}
}
nsEventStatus
@ -246,8 +232,6 @@ nsEventStatus
nsMenuBarX::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWindow,
void * menubarNode, void * aWebShell )
{
gMacMenubarX = getter_AddRefs(NS_GetWeakReference((nsIMenuBar*)this));
mWebShellWeakRef = getter_AddRefs(NS_GetWeakReference(NS_STATIC_CAST(nsIWebShell*, aWebShell)));
mDOMNode = NS_STATIC_CAST(nsIDOMNode*, menubarNode); // strong ref
@ -308,9 +292,6 @@ nsMenuBarX::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWin
// The parent takes ownership
aParentWindow->SetMenuBar(this);
// Get a copy of the menu list
SetNativeData(::GetMenuBar());
return nsEventStatus_eIgnore;
}
@ -351,13 +332,11 @@ NS_METHOD nsMenuBarX::SetParent(nsIWidget *aParent)
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::AddMenu(nsIMenu * aMenu)
{
// XXX add to internal data structure
nsCOMPtr<nsISupports> supports = do_QueryInterface(aMenu);
if(supports)
mMenusArray.AppendElement(supports); // owner
// keep track of all added menus.
mMenusArray.AppendElement(aMenu); // owner
MenuHandle menuHandle = nsnull;
aMenu->GetNativeData((void**)&menuHandle);
MenuRef menuRef = nsnull;
aMenu->GetNativeData((void**)&menuRef);
mNumMenus++;
PRBool helpMenu;
@ -368,8 +347,12 @@ NS_METHOD nsMenuBarX::AddMenu(nsIMenu * aMenu)
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(domNode);
nsAutoString menuHidden;
domElement->GetAttribute(NS_LITERAL_STRING("hidden"), menuHidden);
if( menuHidden != NS_LITERAL_STRING("true"))
::InsertMenu(menuHandle, 0);
if (menuHidden != NS_LITERAL_STRING("true")) {
Str255 title;
::InsertMenuItem(mRootMenu, ::GetMenuTitle(menuRef, title), mNumMenus);
OSStatus status = ::SetMenuItemHierarchicalMenu(mRootMenu, mNumMenus, menuRef);
NS_ASSERTION(status == noErr, "nsMenuBarX::AddMenu: SetMenuItemHierarchicalMenu failed.");
}
}
return NS_OK;
@ -418,19 +401,19 @@ NS_METHOD nsMenuBarX::RemoveAll()
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::GetNativeData(void *& aData)
{
aData = (void *) mMacMBarHandle;
aData = (void *) mRootMenu;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::SetNativeData(void* aData)
{
#if 0
Handle menubarHandle = (Handle)aData;
if (mMacMBarHandle && mMacMBarHandle != menubarHandle)
::DisposeHandle(mMacMBarHandle);
mMacMBarHandle = menubarHandle;
#endif
return NS_OK;
}
@ -438,14 +421,8 @@ NS_METHOD nsMenuBarX::SetNativeData(void* aData)
NS_METHOD nsMenuBarX::Paint()
{
// hack to correctly swap menu bars.
nsCOMPtr<nsIMenuBar> menuBar = do_QueryReferent(gMacMenubarX);
if (menuBar.get() != (nsIMenuBar*)this) {
if (menuBar)
menuBar->SetNativeData(::GetMenuBar());
gMacMenubarX = getter_AddRefs(NS_GetWeakReference((nsIMenuBar*)this));
if (mMacMBarHandle)
::SetMenuBar(mMacMBarHandle);
}
// hopefully this is fast enough.
::SetRootMenu(mRootMenu);
#if !TARGET_CARBON
// Now we have blown away the merged Help menu, so we have to rebuild it

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

@ -157,8 +157,6 @@ protected:
void GetDocument ( nsIWebShell* inWebShell, nsIDocument** outDocument ) ;
void RegisterAsDocumentObserver ( nsIWebShell* inWebShell ) ;
static void SwapMenuBar();
nsHashtable mObserverTable; // stores observers for content change notification
PRUint32 mNumMenus;
@ -170,8 +168,7 @@ protected:
nsWeakPtr mWebShellWeakRef; // weak ref to webshell
// Mac Specific
Handle mMacMBarHandle;
MenuRef mRootMenu; // root menu, representing entire menu bar.
};
#endif // nsMenuBarX_h__

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

@ -52,15 +52,8 @@
#include "nsDynamicMDEF.h"
// Beginning ID for top level menus. IDs 2-5 are the 4 Golden Hierarchical Menus
const PRInt16 kMacMenuIDX = 6;
// Submenu depth tracking
PRInt16 gMenuDepthX = 0;
PRInt16 gCurrentMenuDepthX = 1;
PRInt16 mMacMenuIDCountX = kMacMenuIDX;
const PRInt16 kMacMenuIDX = 1;
static PRInt16 gMacMenuIDCountX = kMacMenuIDX;
static PRBool gConstructingMenu = PR_FALSE;
#if DEBUG
@ -95,48 +88,12 @@ NS_IMPL_ISUPPORTS4(nsMenuX, nsIMenu, nsIMenuListener, nsIChangeObserver, nsISupp
// nsMenuX constructor
//
nsMenuX::nsMenuX()
: mNumMenuItems(0), mParent(nsnull), mManager(nsnull),
mMacMenuID(0), mMacMenuHandle(nsnull), mHelpMenuOSItemsCount(0),
mIsHelpMenu(PR_FALSE), mIsEnabled(PR_TRUE), mDestroyHandlerCalled(PR_FALSE),
mNeedsRebuild(PR_TRUE), mConstructed(PR_FALSE)
{
NS_INIT_REFCNT();
mNumMenuItems = 0;
mMenuParent = nsnull;
mMenuBarParent = nsnull;
mManager = nsnull;
mMacMenuID = 0;
mMacMenuHandle = nsnull;
mIsHelpMenu = PR_FALSE;
mHelpMenuOSItemsCount = 0;
mIsEnabled = PR_TRUE;
mConstructed = nsnull;
mDestroyHandlerCalled = PR_FALSE;
mNeedsRebuild = PR_TRUE;
//
// create a multi-destination Unicode converter which can handle all of the installed
// script systems
//
// To fix the menu bar problem, we add the primary script by using 0x80000000 with one
// script. This will make sure the converter first try to convert to the system script
// before it try other script.
//
// Mac OS 8 and 9 Developer Document > Text and Other Interionational Service >
// Text Encoding Converter Manager
// Inside Macintosh: Programming With the Text Encoding Conversion Manager
// CreateUnicodeToTextRunInfoByScriptCode
// iNumberOfScriptCodes
// The number of desired scripts. .... If you set the high-order bit for this parameter, the
// Unicode converter assumes that the iScripts parameter contains a singel element specifying
// the preferred script. This feature i ssupported beginning with the Text
// Encoding Conversion Manager 1.2
// Also .. from About Eariler Release:
// .. TEC Manager 1.2 was included with Mac OS 8 in July 1997...
ScriptCode ps[1];
ps[0] = ::GetScriptManagerVariable(smSysScript);
OSErr err = ::CreateUnicodeToTextRunInfoByScriptCode(0x80000000,ps,&mUnicodeTextRunConverter);
NS_ASSERTION(err==noErr,"nsMenuX::nsMenuX: CreateUnicodeToTextRunInfoByScriptCode failed.");
#if DEBUG
++gMenuCounterX;
@ -151,14 +108,8 @@ nsMenuX::~nsMenuX()
{
RemoveAll();
OSErr err = ::DisposeUnicodeToTextRunInfo(&mUnicodeTextRunConverter);
NS_ASSERTION(err==noErr,"nsMenuX::~nsMenuX: DisposeUnicodeToTextRunInfo failed.");
// Don't destroy the 4 Golden Hierarchical Menu
if((mMacMenuID > 5) || (mMacMenuID < 2) && !mIsHelpMenu) {
//printf("WARNING: DeleteMenu called!!! \n");
::DeleteMenu(mMacMenuID);
}
if (mMacMenuHandle != NULL)
::ReleaseMenu(mMacMenuHandle);
// alert the change notifier we don't care no more
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
@ -189,19 +140,15 @@ nsMenuX::Create(nsISupports * aParent, const nsAReadableString &aLabel, const ns
NS_ASSERTION ( mDOMNode, "Menu not given a dom node at creation time" );
NS_ASSERTION ( mManager, "No change manager given, can't tell content model updates" );
mParent = aParent;
// our parent could be either a menu bar (if we're toplevel) or a menu (if we're a submenu)
PRBool isValidParent = PR_FALSE;
if (aParent) {
nsCOMPtr<nsIMenuBar> menubar = do_QueryInterface(aParent);
if (menubar)
mMenuBarParent = menubar; // weak ref
else
{
nsCOMPtr<nsIMenu> menu = do_QueryInterface(aParent);
if (menu)
mMenuParent = menu; // weak ref
isValidParent = (menubar || menu);
}
}
NS_ASSERTION( mMenuParent || mMenuBarParent, "Menu parent not a menu bar or menu!" );
NS_ASSERTION(isValidParent, "Menu parent not a menu bar or menu!" );
SetLabel(aLabel);
SetAccessKey(aAccessKey);
@ -212,13 +159,9 @@ nsMenuX::Create(nsISupports * aParent, const nsAReadableString &aLabel, const ns
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::GetParent(nsISupports*& aParent)
{
aParent = nsnull;
if (mMenuParent)
return mMenuParent->QueryInterface(NS_GET_IID(nsISupports),(void**)&aParent);
else if (mMenuBarParent)
return mMenuBarParent->QueryInterface(NS_GET_IID(nsISupports),(void**)&aParent);
return NS_ERROR_FAILURE;
aParent = mParent;
NS_IF_ADDREF(aParent);
return NS_OK;
}
//-------------------------------------------------------------------------
@ -262,7 +205,7 @@ NS_METHOD nsMenuX::SetLabel(const nsAReadableString &aText)
// first time? create the menu handle, attach event handler to it.
if (mMacMenuHandle == nsnull) {
mMacMenuID = mMacMenuIDCountX++;
mMacMenuID = gMacMenuIDCountX++;
mMacMenuHandle = NSStringNewMenu(mMacMenuID, mLabel);
}
@ -286,18 +229,19 @@ NS_METHOD nsMenuX::SetAccessKey(const nsAReadableString &aText)
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::AddItem(nsISupports* aItem)
{
nsresult rv = NS_ERROR_FAILURE;
if (aItem) {
// Figure out what we're adding
nsCOMPtr<nsIMenuItem> menuitem(do_QueryInterface(aItem));
if (menuitem) {
AddMenuItem(menuitem);
nsCOMPtr<nsIMenuItem> menuItem(do_QueryInterface(aItem));
if (menuItem) {
rv = AddMenuItem(menuItem);
} else {
nsCOMPtr<nsIMenu> menu(do_QueryInterface(aItem));
if (menu)
AddMenu(menu);
rv = AddMenu(menu);
}
}
return NS_OK;
return rv;
}
//-------------------------------------------------------------------------
@ -305,10 +249,7 @@ NS_METHOD nsMenuX::AddMenuItem(nsIMenuItem * aMenuItem)
{
if(!aMenuItem) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsISupports> supports = do_QueryInterface(aMenuItem);
if (!supports) return NS_ERROR_NO_INTERFACE;
mMenuItemsArray.AppendElement(supports); // owning ref
mMenuItemsArray.AppendElement(aMenuItem); // owning ref
PRUint32 currItemIndex;
mMenuItemsArray.Count(&currItemIndex);
@ -316,13 +257,14 @@ NS_METHOD nsMenuX::AddMenuItem(nsIMenuItem * aMenuItem)
nsAutoString label;
aMenuItem->GetLabel(label);
//printf("%s \n", label.ToNewCString());
//printf("%d = mMacMenuID\n", mMacMenuID);
::InsertMenuItem(mMacMenuHandle, "\p(Blank menu item", currItemIndex);
MenuHelpersX::SetMenuItemText(mMacMenuHandle, currItemIndex, label, mUnicodeTextRunConverter);
// ::InsertMenuItem(mMacMenuHandle, "\p(Blank menu item", currItemIndex);
// MenuHelpersX::SetMenuItemText(mMacMenuHandle, currItemIndex, label, mUnicodeTextRunConverter);
CFStringRef labelRef = ::CFStringCreateWithCharacters(kCFAllocatorDefault, (UniChar*)label.GetUnicode(), label.Length());
::InsertMenuItemTextWithCFString(mMacMenuHandle, labelRef, currItemIndex, 0, 0);
::CFRelease(labelRef);
// I want to be internationalized too!
nsAutoString keyEquivalent; keyEquivalent.AssignWithConversion(" ");
nsAutoString keyEquivalent(NS_LITERAL_STRING(" "));
aMenuItem->GetShortcutChar(keyEquivalent);
if (keyEquivalent != NS_LITERAL_STRING(" ")) {
keyEquivalent.ToUpperCase();
@ -387,8 +329,11 @@ NS_METHOD nsMenuX::AddMenu(nsIMenu * aMenu)
aMenu->GetLabel(label);
//printf("AddMenu %s \n", label.ToNewCString());
::InsertMenuItem(mMacMenuHandle, "\p(Blank Menu", currItemIndex);
MenuHelpersX::SetMenuItemText(mMacMenuHandle, currItemIndex, label, mUnicodeTextRunConverter);
// ::InsertMenuItem(mMacMenuHandle, "\p(Blank Menu", currItemIndex);
// MenuHelpersX::SetMenuItemText(mMacMenuHandle, currItemIndex, label, mUnicodeTextRunConverter);
CFStringRef labelRef = ::CFStringCreateWithCharacters(kCFAllocatorDefault, (UniChar*)label.GetUnicode(), label.Length());
::InsertMenuItemTextWithCFString(mMacMenuHandle, labelRef, currItemIndex, 0, 0);
::CFRelease(labelRef);
PRBool isEnabled;
aMenu->GetEnabled(&isEnabled);
@ -398,10 +343,8 @@ NS_METHOD nsMenuX::AddMenu(nsIMenu * aMenu)
::DisableMenuItem(mMacMenuHandle, currItemIndex);
MenuHandle childMenu;
if (aMenu->GetNativeData(&childMenu) == NS_OK) {
::InsertMenu(childMenu, hierMenu);
::SetMenuItemHierarchicalID((MenuHandle) mMacMenuHandle, currItemIndex, ::GetMenuID(childMenu));
}
if (aMenu->GetNativeData(&childMenu) == NS_OK)
::SetMenuItemHierarchicalMenu((MenuHandle) mMacMenuHandle, currItemIndex, childMenu);
return NS_OK;
}
@ -449,26 +392,8 @@ NS_METHOD nsMenuX::RemoveItem(const PRUint32 aPos)
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::RemoveAll()
{
#ifdef notdef
#if !TARGET_CARBON
MenuHandle helpmh;
::HMGetHelpMenuHandle(&helpmh);
if ( helpmh != mMacMenuHandle)
helpmh = nsnull;
#endif
#endif
PRUint32 curItem;
mMenuItemsArray.Count(&curItem);
while (curItem > 0)
{
/* don't delete the actual Mac menu item if it's a MacOS item */
if (curItem > mHelpMenuOSItemsCount)
::DeleteMenuItem(mMacMenuHandle, curItem);
curItem --;
}
if (mMacMenuHandle != NULL)
::DeleteMenuItems(mMacMenuHandle, 1, ::CountMenuItems(mMacMenuHandle));
mMenuItemsArray.Clear(); // remove all items
return NS_OK;
}
@ -516,6 +441,7 @@ nsEventStatus nsMenuX::MenuItemSelected(const nsMenuEvent & aMenuEvent)
// Determine if this is the correct menu to handle the event
PRInt16 menuID = HiWord(((nsMenuEvent)aMenuEvent).mCommand);
#if !TARGET_CARBON
if ((kHMHelpMenuID == menuID) && (menuID != mMacMenuID))
{
/* 'this' is not correct; we need to find the help nsMenuX */
@ -532,10 +458,8 @@ nsEventStatus nsMenuX::MenuItemSelected(const nsMenuEvent & aMenuEvent)
/* set up a default event to query with */
nsMenuEvent event;
MenuHandle handle;
#if !TARGET_CARBON
// XXX fix me for carbon!
::HMGetHelpMenuHandle(&handle);
#endif
event.mCommand = (unsigned int) handle;
/* loop through the top-level menus in the menubar */
@ -567,7 +491,9 @@ nsEventStatus nsMenuX::MenuItemSelected(const nsMenuEvent & aMenuEvent)
}
}
}
else if (mMacMenuID == menuID)
else
#endif
if (mMacMenuID == menuID)
{
// Call MenuItemSelected on the correct nsMenuItem
PRInt16 menuItemID = LoWord(((nsMenuEvent)aMenuEvent).mCommand);
@ -620,8 +546,7 @@ nsEventStatus nsMenuX::MenuSelected(const nsMenuEvent & aMenuEvent)
// Determine if this is the correct menu to handle the event
MenuHandle selectedMenuHandle = (MenuHandle) aMenuEvent.mCommand;
if(mMacMenuHandle == selectedMenuHandle)
{
if (mMacMenuHandle == selectedMenuHandle) {
if (mIsHelpMenu && mConstructed){
RemoveAll();
mConstructed = false;
@ -640,8 +565,7 @@ nsEventStatus nsMenuX::MenuSelected(const nsMenuEvent & aMenuEvent)
return nsEventStatus_eConsumeNoDefault;
}
if(!mConstructed || mNeedsRebuild)
{
if(!mConstructed || mNeedsRebuild) {
if (mNeedsRebuild)
RemoveAll();
@ -661,14 +585,11 @@ nsEventStatus nsMenuX::MenuSelected(const nsMenuEvent & aMenuEvent)
//printf("Menu already constructed \n");
}
eventStatus = nsEventStatus_eConsumeNoDefault;
}
else
{
} else {
// Make sure none of our submenus are the ones that should be handling this
PRUint32 numItems;
mMenuItemsArray.Count(&numItems);
for (PRUint32 i = numItems; i > 0; i--)
{
for (PRUint32 i = numItems; i > 0; i--) {
nsCOMPtr<nsISupports> menuSupports = getter_AddRefs(mMenuItemsArray.ElementAt(i - 1));
nsCOMPtr<nsIMenu> submenu = do_QueryInterface(menuSupports);
nsCOMPtr<nsIMenuListener> menuListener = do_QueryInterface(submenu);
@ -678,7 +599,6 @@ nsEventStatus nsMenuX::MenuSelected(const nsMenuEvent & aMenuEvent)
return eventStatus;
}
}
}
return eventStatus;
@ -687,13 +607,11 @@ nsEventStatus nsMenuX::MenuSelected(const nsMenuEvent & aMenuEvent)
//-------------------------------------------------------------------------
nsEventStatus nsMenuX::MenuDeselected(const nsMenuEvent & aMenuEvent)
{
//printf("MenuDeselect called for %s\n", mLabel.ToNewCString());
// Destroy the menu
if (mConstructed) {
MenuDestruct(aMenuEvent);
mConstructed = false;
}
return nsEventStatus_eIgnore;
}
@ -713,8 +631,6 @@ nsEventStatus nsMenuX::MenuConstruct(
//printf("nsMenuX::MenuConstruct called for %s = %d \n", mLabel.ToNewCString(), mMacMenuHandle);
// Begin menuitem inner loop
gCurrentMenuDepthX++;
// Now get the kids. Retrieve our menupopup child.
nsCOMPtr<nsIDOMNode> menuPopupNode;
GetMenuPopupElement(getter_AddRefs(menuPopupNode));
@ -728,8 +644,7 @@ nsEventStatus nsMenuX::MenuConstruct(
while (menuitemNode)
{
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
if (menuitemElement)
{
if (menuitemElement) {
nsAutoString label;
menuitemElement->GetAttribute(NS_LITERAL_STRING("value"), label);
//printf("label = %s \n", label.ToNewCString());
@ -753,8 +668,6 @@ nsEventStatus nsMenuX::MenuConstruct(
mNeedsRebuild = PR_FALSE;
//printf(" Done building, mMenuItemVoidArray.Count() = %d \n", mMenuItemVoidArray.Count());
gCurrentMenuDepthX--;
return nsEventStatus_eIgnore;
}
@ -774,8 +687,6 @@ nsEventStatus nsMenuX::HelpMenuConstruct(
mMenuItemsArray.AppendElement(&gDummyMenuItemX);
}
gCurrentMenuDepthX++;
// Now get the kids. Retrieve our menupopup child.
nsCOMPtr<nsIDOMNode> menuPopupNode;
GetMenuPopupElement ( getter_AddRefs(menuPopupNode) );
@ -815,8 +726,6 @@ nsEventStatus nsMenuX::HelpMenuConstruct(
//printf(" Done building, mMenuItemVoidArray.Count() = %d \n", mMenuItemVoidArray.Count());
gCurrentMenuDepthX--;
//PreviousMenuStackUnwind(this, mMacMenuHandle);
//PushMenu(this);
@ -830,22 +739,7 @@ nsEventStatus nsMenuX::MenuDestruct(const nsMenuEvent & aMenuEvent)
// Fire our ondestroy handler. If we're told to stop, don't destroy the menu
PRBool keepProcessing = OnDestroy();
if ( keepProcessing )
{
#if !TARGET_CARBON
if( mMacMenuHandle == gLevel2HierMenuX ||
mMacMenuHandle == gLevel3HierMenuX ||
mMacMenuHandle == gLevel4HierMenuX ||
mMacMenuHandle == gLevel5HierMenuX)
{
mNeedsRebuild = PR_TRUE;
}
#else
// perhaps this needs to be true if we are hierarchical?
if (mMenuBarParent == NULL)
mNeedsRebuild = PR_TRUE;
#endif
if ( keepProcessing ) {
if(mNeedsRebuild) {
RemoveAll();
mConstructed = false;
@ -902,17 +796,10 @@ NS_METHOD nsMenuX::SetEnabled(PRBool aIsEnabled)
{
mIsEnabled = aIsEnabled;
// If we're at the depth of a top-level menu, enable/disable the menu explicity.
// Otherwise we're working with a single "golden child" menu shared by all hierarchicals
// so if we touch it, it will affect the display of every other hierarchical spawnded from
// this menu (which would be bad).
if ( gCurrentMenuDepthX < 2 &&
(mMacMenuID > 5 || mMacMenuID < 2)) {
if ( aIsEnabled )
::EnableMenuItem(mMacMenuHandle, 0);
else
::DisableMenuItem(mMacMenuHandle, 0);
}
return NS_OK;
}
@ -924,8 +811,8 @@ NS_METHOD nsMenuX::SetEnabled(PRBool aIsEnabled)
*/
NS_METHOD nsMenuX::GetEnabled(PRBool* aIsEnabled)
{
NS_ENSURE_ARG_POINTER(aIsEnabled);
*aIsEnabled = mIsEnabled;
return NS_OK;
}
@ -936,6 +823,7 @@ NS_METHOD nsMenuX::GetEnabled(PRBool* aIsEnabled)
*/
NS_METHOD nsMenuX::IsHelpMenu(PRBool* aIsHelpMenu)
{
NS_ENSURE_ARG_POINTER(aIsHelpMenu);
*aIsHelpMenu = mIsHelpMenu;
return NS_OK;
}
@ -962,7 +850,7 @@ static pascal OSStatus MyMenuEventHandler(EventHandlerCallRef myHandler, EventRe
OSStatus result = eventNotHandledErr;
UInt32 kind = ::GetEventKind(event);
if (kind == kEventMenuOpening) {
if (kind == kEventMenuOpening || kind == kEventMenuClosed) {
nsISupports* supports = reinterpret_cast<nsISupports*>(userData);
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(supports));
if (listener) {
@ -976,7 +864,10 @@ static pascal OSStatus MyMenuEventHandler(EventHandlerCallRef myHandler, EventRe
menuEvent.widget = nsnull;
menuEvent.time = PR_IntervalNow();
menuEvent.mCommand = (PRUint32) menuRef;
if (kind == kEventMenuOpening)
listener->MenuSelected(menuEvent);
else
listener->MenuDeselected(menuEvent);
}
}
@ -1336,10 +1227,12 @@ nsresult
nsMenuX::GetNextVisibleMenu(nsIMenu** outNextVisibleMenu)
{
*outNextVisibleMenu = nsnull;
if (!mMenuBarParent) return NS_ERROR_FAILURE;
nsCOMPtr<nsIMenuBar> menubarParent = do_QueryInterface(mParent);
if (!menubarParent) return NS_ERROR_FAILURE;
PRUint32 numMenus;
mMenuBarParent->GetMenuCount(numMenus);
menubarParent->GetMenuCount(numMenus);
PRBool gotThisMenu = PR_FALSE;
PRUint32 thisMenuIndex;
@ -1347,7 +1240,7 @@ nsMenuX::GetNextVisibleMenu(nsIMenu** outNextVisibleMenu)
for (PRUint32 i = 0; i < numMenus; i ++)
{
nsCOMPtr<nsIMenu> thisMenu;
mMenuBarParent->GetMenuAt(i, *getter_AddRefs(thisMenu));
menubarParent->GetMenuAt(i, *getter_AddRefs(thisMenu));
if (!thisMenu) continue;
if (gotThisMenu) // we're looking for the next visible
@ -1410,6 +1303,8 @@ nsMenuX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom
return NS_OK;
}
nsCOMPtr<nsIMenuBar> menubarParent = do_QueryInterface(mParent);
if (aAttribute == disabledAtom.get()) // disabled
{
mNeedsRebuild = PR_TRUE;
@ -1429,39 +1324,17 @@ nsMenuX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom
domElement->GetAttribute(NS_LITERAL_STRING("value"), mLabel);
if((mMacMenuID <= 5) && (mMacMenuID >= 2))
return NS_OK;
// reuse the existing menu, to avoid invalidating root menu bar.
NS_ASSERTION(mMacMenuHandle != NULL, "nsMenuX::AttributeChanged: invalid menu handle.");
RemoveAll();
CFStringRef titleRef = ::CFStringCreateWithCharacters(kCFAllocatorDefault, (UniChar*)mLabel.GetUnicode(), mLabel.Length());
NS_ASSERTION(titleRef, "nsMenuX::AttributeChanged: CFStringCreateWithCharacters failed.");
::SetMenuTitleWithCFString(mMacMenuHandle, titleRef);
::CFRelease(titleRef);
::DeleteMenu(mMacMenuID);
mMacMenuHandle = NSStringNewMenu(mMacMenuID, mLabel);
// Need to get the menuID of the next visible menu
SInt16 nextMenuID = -1; // default to the submenu case
if (mMenuBarParent) // this is a top-level menu
{
nsCOMPtr<nsIMenu> nextVisibleMenu;
GetNextVisibleMenu(getter_AddRefs(nextVisibleMenu));
if (nextVisibleMenu)
{
MenuHandle nextHandle;
nextVisibleMenu->GetNativeData((void **)&nextHandle);
nextMenuID = (nextHandle) ? ::GetMenuID(nextHandle) : mMacMenuID + 1;
}
else
{
nextMenuID = mMacMenuID + 1;
}
}
::InsertMenu(mMacMenuHandle, nextMenuID);
if(mMenuBarParent)
{
mMenuBarParent->SetNativeData(::GetMenuBar());
if (menubarParent)
::DrawMenuBar();
}
}
else if(aAttribute == hiddenAtom.get() || aAttribute == collapsedAtom.get()) // hidden of collapsed
{
@ -1472,14 +1345,14 @@ nsMenuX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom
domElement->GetAttribute(NS_LITERAL_STRING("collapsed"), collapsedValue);
if (hiddenValue == NS_LITERAL_STRING("true") || collapsedValue == NS_LITERAL_STRING("true")) {
// hide this menu
::DeleteMenu(mMacMenuID);
NS_ASSERTION(PR_FALSE, "nsMenuX::AttributeChanged: WRITE HIDE CODE.");
}
else
{
// Need to get the menuID of the next visible menu
SInt16 nextMenuID = -1; // default to the submenu case
if (mMenuBarParent) // this is a top-level menu
if (menubarParent) // this is a top-level menu
{
nsCOMPtr<nsIMenu> nextVisibleMenu;
GetNextVisibleMenu(getter_AddRefs(nextVisibleMenu));
@ -1497,10 +1370,9 @@ nsMenuX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom
}
// show this menu
::InsertMenu(mMacMenuHandle, nextMenuID);
NS_ASSERTION(PR_FALSE, "nsMenuX::AttributeChanged: WRITE SHOW CODE.");
}
if(mMenuBarParent) {
mMenuBarParent->SetNativeData(::GetMenuBar());
if (menubarParent) {
::DrawMenuBar();
}
}

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

@ -116,17 +116,17 @@ protected:
PRUint32 mNumMenuItems;
nsSupportsArray mMenuItemsArray; // array holds refs
nsIMenu* mMenuParent; // weak, my parent owns me
nsIMenuBar* mMenuBarParent;
nsISupports* mParent; // weak, my parent owns me
// nsIMenu* mMenuParent;
// nsIMenuBar* mMenuBarParent;
nsIChangeManager* mManager; // weak ref, it will outlive us
nsWeakPtr mWebShellWeakRef; // weak ref to webshell
nsCOMPtr<nsIDOMNode> mDOMNode; // strong ref
nsCOMPtr<nsIMenuListener> mListener;
nsCOMPtr<nsIMenuListener> mListener; // strong ref
// MacSpecific
PRInt16 mMacMenuID;
MenuHandle mMacMenuHandle;
UnicodeToTextRunInfo mUnicodeTextRunConverter;
PRInt16 mHelpMenuOSItemsCount;
PRPackedBool mIsHelpMenu;
PRPackedBool mIsEnabled;