add 'about mozilla' item and impl to carbon menu code. fix indentation. bug#83187, r=saari/sr=sfraser.

git-svn-id: svn://10.0.0.236/trunk@96027 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
pinkerton%netscape.com 2001-05-29 23:18:26 +00:00
parent 4193d27532
commit 5c32fb0a1d
3 changed files with 376 additions and 489 deletions

View File

@ -68,19 +68,19 @@ static MenuRef gDefaultRootMenu = nsnull;
//
nsMenuBarX::nsMenuBarX()
{
NS_INIT_REFCNT();
mNumMenus = 0;
mParent = nsnull;
mIsMenuBarAdded = PR_FALSE;
mDocument = nsnull;
NS_INIT_REFCNT();
mNumMenus = 0;
mParent = nsnull;
mIsMenuBarAdded = PR_FALSE;
mDocument = nsnull;
OSStatus status = ::CreateNewMenu(0, 0, &mRootMenu);
NS_ASSERTION(status == noErr, "nsMenuBarX::nsMenuBarX: creation of root menu failed.");
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!.");
}
if (gDefaultRootMenu == nsnull) {
gDefaultRootMenu = ::AcquireRootMenu();
NS_ASSERTION(gDefaultRootMenu != nsnull, "nsMenuBarX::nsMenuBarX: no default root menu!.");
}
}
//
@ -217,17 +217,17 @@ nsMenuBarX :: GetDocument ( nsIWebShell* inWebShell, nsIDocument** outDocument )
void
nsMenuBarX :: RegisterAsDocumentObserver ( nsIWebShell* inWebShell )
{
nsCOMPtr<nsIDocument> doc;
GetDocument(inWebShell, getter_AddRefs(doc));
if (!doc)
nsCOMPtr<nsIDocument> doc;
GetDocument(inWebShell, getter_AddRefs(doc));
if (!doc)
return;
// register ourselves
nsCOMPtr<nsIDocumentObserver> observer ( do_QueryInterface(NS_STATIC_CAST(nsIMenuBar*,this)) );
doc->AddObserver(observer);
// also get pointer to doc, just in case webshell goes away
// we can still remove ourself as doc observer directly from doc
mDocument = doc;
// register ourselves
nsCOMPtr<nsIDocumentObserver> observer ( do_QueryInterface(NS_STATIC_CAST(nsIMenuBar*,this)) );
doc->AddObserver(observer);
// also get pointer to doc, just in case webshell goes away
// we can still remove ourself as doc observer directly from doc
mDocument = doc;
} // RegisterAsDocumentObesrver
@ -337,6 +337,48 @@ NS_METHOD nsMenuBarX::AddMenu(nsIMenu * aMenu)
// keep track of all added menus.
mMenusArray.AppendElement(aMenu); // owner
if (mNumMenus == 0)
{
Str32 menuStr = { 1, kMenuAppleLogoFilledGlyph };
MenuHandle appleMenu;
OSStatus s = ::CreateNewMenu(kAppleMenuID, 0, &appleMenu);
::SetMenuTitle(appleMenu, menuStr);
if (appleMenu)
{
// this code reads the "label" attribute from the <menuitem/> with
// id="aboutName" and puts its label in the Apple Menu
nsAutoString label;
nsCOMPtr<nsIContent> menu;
aMenu->GetMenuContent(getter_AddRefs(menu));
if (menu) {
nsCOMPtr<nsIDocument> doc;
menu->GetDocument(*getter_AddRefs(doc));
if (doc) {
nsCOMPtr<nsIDOMDocument> domdoc ( do_QueryInterface(doc) );
if ( domdoc ) {
nsCOMPtr<nsIDOMElement> aboutMenuItem;
domdoc->GetElementById(NS_LITERAL_STRING("aboutName"), getter_AddRefs(aboutMenuItem));
if (aboutMenuItem)
aboutMenuItem->GetAttribute(NS_LITERAL_STRING("label"), label);
}
}
}
CFStringRef labelRef = ::CFStringCreateWithCharacters(kCFAllocatorDefault, (UniChar*)label.GetUnicode(), label.Length());
::InsertMenuItemTextWithCFString(appleMenu, labelRef, 1, 0, 0);
::CFRelease(labelRef);
// InsertMenuItem() is 1-based, so the apple/application menu needs to
// be at index 1. |mNumMenus| will be incremented below, so the following menu (File)
// won't overwrite the apple menu by reusing the ID.
mNumMenus = 1;
::AppendMenu(appleMenu, "\p-");
::InsertMenuItem(mRootMenu, menuStr, mNumMenus);
OSStatus status = ::SetMenuItemHierarchicalMenu(mRootMenu, mNumMenus, appleMenu);
}
}
MenuRef menuRef = nsnull;
aMenu->GetNativeData((void**)&menuRef);
@ -424,31 +466,6 @@ NS_METHOD nsMenuBarX::Paint()
// hack to correctly swap menu bars.
// 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
PRUint32 numItems;
mMenusArray.Count(&numItems);
for (PRInt32 i = numItems - 1; i >= 0; --i)
{
nsCOMPtr<nsISupports> thisItem = getter_AddRefs(mMenusArray.ElementAt(i));
nsCOMPtr<nsIMenu> menu = do_QueryInterface(thisItem);
PRBool isHelpMenu = PR_FALSE;
if (menu)
menu->IsHelpMenu(&isHelpMenu);
if (isHelpMenu)
{
MenuHandle helpMenuHandle;
::HMGetHelpMenuHandle(&helpMenuHandle);
menu->SetNativeData((void*)helpMenuHandle);
nsMenuEvent event;
event.mCommand = (unsigned int) helpMenuHandle;
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(menu);
listener->MenuSelected(event);
}
}
#endif
::DrawMenuBar();
return NS_OK;
}
@ -701,95 +718,6 @@ nsMenuBarX :: Lookup ( nsIContent *aContent, nsIChangeObserver **_retval )
#pragma mark -
//
// SetMenuItemText
//
// A utility routine for handling unicode->OS text conversions for setting the item
// text in a menu.
//
void
MenuHelpersX::SetMenuItemText ( MenuHandle inMacMenuHandle, short inMenuItem, const nsString& inMenuString,
const UnicodeToTextRunInfo inConverter )
{
// ::TruncString() doesn't take the number of characters to truncate to, it takes a pixel with
// to fit the string in. Ugh. I talked it over with sfraser and we couldn't come up with an
// easy way to compute what this should be given the system font, etc, so we're just going
// to hard code it to something reasonable and bigger fonts will just have to deal.
const short kMaxItemPixelWidth = 300;
short themeFontID;
SInt16 themeFontSize;
Style themeFontStyle;
char* scriptRunText = ConvertToScriptRun ( inMenuString, inConverter, &themeFontID,
&themeFontSize, &themeFontStyle );
if ( scriptRunText ) {
// convert it to a pascal string
Str255 menuTitle;
short scriptRunTextLength = strlen(scriptRunText);
if (scriptRunTextLength > 255)
scriptRunTextLength = 255;
BlockMoveData(scriptRunText, &menuTitle[1], scriptRunTextLength);
menuTitle[0] = scriptRunTextLength;
// if the item text is too long, truncate it.
::TruncString ( kMaxItemPixelWidth, menuTitle, truncMiddle );
::SetMenuItemText(inMacMenuHandle, inMenuItem, menuTitle);
OSErr err = ::SetMenuItemFontID(inMacMenuHandle, inMenuItem, themeFontID);
nsMemory::Free(scriptRunText);
}
} // SetMenuItemText
//
// ConvertToScriptRun
//
// Converts unicode to a single script run and extract the relevant font information. The
// caller is responsible for deleting the memory allocated by this call with |nsMemory::Free()|.
// Returns |nsnull| if an error occurred.
//
char*
MenuHelpersX::ConvertToScriptRun ( const nsString & inStr, const UnicodeToTextRunInfo inConverter,
short* outFontID, SInt16* outFontSize, Style* outFontStyle )
{
//
// extract the Unicode text from the nsString and convert it into a single script run
//
const PRUnichar* unicodeText = inStr.GetUnicode();
size_t unicodeTextLengthInBytes = inStr.Length() * sizeof(PRUnichar);
size_t scriptRunTextSizeInBytes = unicodeTextLengthInBytes * 2;
char* scriptRunText = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(scriptRunTextSizeInBytes + sizeof(char)));
if ( !scriptRunText )
return nsnull;
ScriptCodeRun convertedTextScript;
size_t unicdeTextReadInBytes, scriptRunTextLengthInBytes, scriptCodeRunListLength;
OSErr err = ::ConvertFromUnicodeToScriptCodeRun(inConverter, unicodeTextLengthInBytes,
NS_REINTERPRET_CAST(const PRUint16*, unicodeText),
0, /* no flags*/
0,NULL,NULL,NULL, /* no offset arrays */
scriptRunTextSizeInBytes,&unicdeTextReadInBytes,&scriptRunTextLengthInBytes,
scriptRunText,
1 /* count of script runs*/,&scriptCodeRunListLength,&convertedTextScript);
NS_ASSERTION(err==noErr,"nsMenu::NSStringSetMenuItemText: ConvertFromUnicodeToScriptCodeRun failed.");
if ( err ) { nsMemory::Free(scriptRunText); return nsnull; }
scriptRunText[scriptRunTextLengthInBytes] = '\0'; // null terminate
//
// get a font from the script code
//
Str255 themeFontName;
err = ::GetThemeFont(kThemeSystemFont, convertedTextScript.script, themeFontName, outFontSize, outFontStyle);
NS_ASSERTION(err==noErr,"nsMenu::NSStringSetMenuItemText: GetThemeFont failed.");
if ( err ) { nsMemory::Free(scriptRunText); return nsnull; }
::GetFNum(themeFontName, outFontID);
return scriptRunText;
} // ConvertToScriptRun
//
// WebShellToPresContext
//

View File

@ -48,16 +48,6 @@ namespace MenuHelpersX
// utility routine for getting a PresContext out of a webShell
nsresult WebShellToPresContext ( nsIWebShell* inWebShell, nsIPresContext** outContext ) ;
// utility routine for handling unicode->OS text conversions for setting the item
// text in a menu.
void SetMenuItemText ( MenuHandle macMenuHandle, short menuItem, const nsString& text,
const UnicodeToTextRunInfo converter ) ;
// Converts unicode to a single script run and extract the relevant font information. The
// caller is responsible for deleting the memory allocated by this call with |nsMemory::Free()|.
// Returns |nsnull| if an error occurred.
char* ConvertToScriptRun ( const nsString & inStr, const UnicodeToTextRunInfo inConverter,
short* outFontID, SInt16* outFontSize, Style* outFontStyle ) ;
}
@ -75,6 +65,8 @@ public:
nsMenuBarX();
virtual ~nsMenuBarX();
enum { kAppleMenuID = 1 } ;
NS_DECL_ISUPPORTS
NS_DECL_NSICHANGEMANAGER

View File

@ -98,10 +98,10 @@ nsMenuX::nsMenuX()
mIsHelpMenu(PR_FALSE), mIsEnabled(PR_TRUE), mDestroyHandlerCalled(PR_FALSE),
mNeedsRebuild(PR_TRUE), mConstructed(PR_FALSE)
{
NS_INIT_REFCNT();
NS_INIT_REFCNT();
#if DEBUG
++gMenuCounterX;
++gMenuCounterX;
#endif
}
@ -111,16 +111,16 @@ nsMenuX::nsMenuX()
//
nsMenuX::~nsMenuX()
{
RemoveAll();
RemoveAll();
if (mMacMenuHandle != NULL)
::ReleaseMenu(mMacMenuHandle);
if (mMacMenuHandle != NULL)
::ReleaseMenu(mMacMenuHandle);
// alert the change notifier we don't care no more
mManager->Unregister(mMenuContent);
// alert the change notifier we don't care no more
mManager->Unregister(mMenuContent);
#if DEBUG
--gMenuCounterX;
--gMenuCounterX;
#endif
}
@ -132,39 +132,39 @@ NS_METHOD
nsMenuX::Create(nsISupports * aParent, const nsAReadableString &aLabel, const nsAReadableString &aAccessKey,
nsIChangeManager* aManager, nsIWebShell* aShell, nsIContent* aNode )
{
mWebShellWeakRef = getter_AddRefs(NS_GetWeakReference(aShell));
mMenuContent = aNode;
mWebShellWeakRef = getter_AddRefs(NS_GetWeakReference(aShell));
mMenuContent = aNode;
// register this menu to be notified when changes are made to our content object
mManager = aManager; // weak ref
nsCOMPtr<nsIChangeObserver> changeObs ( do_QueryInterface(NS_STATIC_CAST(nsIChangeObserver*, this)) );
mManager->Register(mMenuContent, changeObs);
// register this menu to be notified when changes are made to our content object
mManager = aManager; // weak ref
nsCOMPtr<nsIChangeObserver> changeObs ( do_QueryInterface(NS_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" );
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" );
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);
nsCOMPtr<nsIMenu> menu = do_QueryInterface(aParent);
isValidParent = (menubar || menu);
}
NS_ASSERTION(isValidParent, "Menu parent not a menu bar or menu!" );
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);
nsCOMPtr<nsIMenu> menu = do_QueryInterface(aParent);
isValidParent = (menubar || menu);
}
NS_ASSERTION(isValidParent, "Menu parent not a menu bar or menu!" );
SetLabel(aLabel);
SetAccessKey(aAccessKey);
SetLabel(aLabel);
SetAccessKey(aAccessKey);
return NS_OK;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::GetParent(nsISupports*& aParent)
{
aParent = mParent;
NS_IF_ADDREF(aParent);
return NS_OK;
aParent = mParent;
NS_IF_ADDREF(aParent);
return NS_OK;
}
//-------------------------------------------------------------------------
@ -179,51 +179,29 @@ static OSStatus InstallMyMenuEventHandler(MenuRef menuRef, void* userData);
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::SetLabel(const nsAReadableString &aText)
{
mLabel = aText;
#if !TARGET_CARBON
nsAutoString menuIDstring;
mMenuContent->GetAttribute(kNameSpaceID_None, nsWidgetAtoms::id, menuIDstring);
if(menuIDstring == NS_LITERAL_STRING("menu_Help"))
{
mIsHelpMenu = PR_TRUE;
::HMGetHelpMenuHandle(&mMacMenuHandle);
mMacMenuID = kHMHelpMenuID;
int numHelpItems = ::CountMenuItems(mMacMenuHandle);
if (mHelpMenuOSItemsCount == 0)
mHelpMenuOSItemsCount = numHelpItems;
for (int i=0; i < numHelpItems; ++i)
{
nsDummyMenuItem* dummyItem = new nsDummyMenuItem;
mMenuItemsArray.AppendElement(dummyItem); // owned
}
return NS_OK;
}
#endif
mLabel = aText;
// first time? create the menu handle, attach event handler to it.
if (mMacMenuHandle == nsnull) {
mMacMenuID = gMacMenuIDCountX++;
mMacMenuHandle = NSStringNewMenu(mMacMenuID, mLabel);
}
//printf("MacMenuID = %d", mMacMenuID);
// first time? create the menu handle, attach event handler to it.
if (mMacMenuHandle == nsnull) {
mMacMenuID = gMacMenuIDCountX++;
mMacMenuHandle = NSStringNewMenu(mMacMenuID, mLabel);
}
return NS_OK;
//printf("MacMenuID = %d", mMacMenuID);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::GetAccessKey(nsString &aText)
{
return NS_OK;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::SetAccessKey(const nsAReadableString &aText)
{
return NS_OK;
return NS_OK;
}
//-------------------------------------------------------------------------
@ -247,106 +225,102 @@ NS_METHOD nsMenuX::AddItem(nsISupports* aItem)
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::AddMenuItem(nsIMenuItem * aMenuItem)
{
if(!aMenuItem) return NS_ERROR_NULL_POINTER;
if(!aMenuItem) return NS_ERROR_NULL_POINTER;
mMenuItemsArray.AppendElement(aMenuItem); // owning ref
PRUint32 currItemIndex;
mMenuItemsArray.Count(&currItemIndex);
mMenuItemsArray.AppendElement(aMenuItem); // owning ref
PRUint32 currItemIndex;
mMenuItemsArray.Count(&currItemIndex);
mNumMenuItems++;
mNumMenuItems++;
nsAutoString label;
aMenuItem->GetLabel(label);
// ::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(NS_LITERAL_STRING(" "));
aMenuItem->GetShortcutChar(keyEquivalent);
if (keyEquivalent != NS_LITERAL_STRING(" ")) {
keyEquivalent.ToUpperCase();
char keyStr[2];
keyEquivalent.ToCString(keyStr, sizeof(keyStr));
short inKey = keyStr[0];
::SetItemCmd(mMacMenuHandle, currItemIndex, inKey);
//::SetMenuItemKeyGlyph(mMacMenuHandle, mNumMenuItems, 0x61);
}
nsAutoString label;
aMenuItem->GetLabel(label);
CFStringRef labelRef = ::CFStringCreateWithCharacters(kCFAllocatorDefault, (UniChar*)label.GetUnicode(), label.Length());
::InsertMenuItemTextWithCFString(mMacMenuHandle, labelRef, currItemIndex, 0, 0);
::CFRelease(labelRef);
PRUint8 modifiers;
aMenuItem->GetModifiers(&modifiers);
PRUint8 macModifiers = kMenuNoModifiers;
if (knsMenuItemShiftModifier & modifiers)
macModifiers |= kMenuShiftModifier;
// I want to be internationalized too!
nsAutoString keyEquivalent(NS_LITERAL_STRING(" "));
aMenuItem->GetShortcutChar(keyEquivalent);
if (keyEquivalent != NS_LITERAL_STRING(" ")) {
keyEquivalent.ToUpperCase();
char keyStr[2];
keyEquivalent.ToCString(keyStr, sizeof(keyStr));
short inKey = keyStr[0];
::SetItemCmd(mMacMenuHandle, currItemIndex, inKey);
//::SetMenuItemKeyGlyph(mMacMenuHandle, mNumMenuItems, 0x61);
}
if (knsMenuItemAltModifier & modifiers)
macModifiers |= kMenuOptionModifier;
PRUint8 modifiers;
aMenuItem->GetModifiers(&modifiers);
PRUint8 macModifiers = kMenuNoModifiers;
if (knsMenuItemShiftModifier & modifiers)
macModifiers |= kMenuShiftModifier;
if (knsMenuItemControlModifier & modifiers)
macModifiers |= kMenuControlModifier;
if (knsMenuItemAltModifier & modifiers)
macModifiers |= kMenuOptionModifier;
if (!(knsMenuItemCommandModifier & modifiers))
macModifiers |= kMenuNoCommandModifier;
if (knsMenuItemControlModifier & modifiers)
macModifiers |= kMenuControlModifier;
::SetMenuItemModifiers(mMacMenuHandle, currItemIndex, macModifiers);
if (!(knsMenuItemCommandModifier & modifiers))
macModifiers |= kMenuNoCommandModifier;
PRBool isEnabled;
aMenuItem->GetEnabled(&isEnabled);
if(isEnabled)
::EnableMenuItem(mMacMenuHandle, currItemIndex);
else
::DisableMenuItem(mMacMenuHandle, currItemIndex);
::SetMenuItemModifiers(mMacMenuHandle, currItemIndex, macModifiers);
PRBool isChecked;
aMenuItem->GetChecked(&isChecked);
if(isChecked)
::CheckMenuItem(mMacMenuHandle, currItemIndex, true);
else
::CheckMenuItem(mMacMenuHandle, currItemIndex, false);
PRBool isEnabled;
aMenuItem->GetEnabled(&isEnabled);
if(isEnabled)
::EnableMenuItem(mMacMenuHandle, currItemIndex);
else
::DisableMenuItem(mMacMenuHandle, currItemIndex);
return NS_OK;
PRBool isChecked;
aMenuItem->GetChecked(&isChecked);
if(isChecked)
::CheckMenuItem(mMacMenuHandle, currItemIndex, true);
else
::CheckMenuItem(mMacMenuHandle, currItemIndex, false);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::AddMenu(nsIMenu * aMenu)
{
// Add a submenu
if (!aMenu) return NS_ERROR_NULL_POINTER;
// Add a submenu
if (!aMenu) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsISupports> supports = do_QueryInterface(aMenu);
if (!supports) return NS_ERROR_NO_INTERFACE;
nsCOMPtr<nsISupports> supports = do_QueryInterface(aMenu);
if (!supports) return NS_ERROR_NO_INTERFACE;
mMenuItemsArray.AppendElement(supports); // owning ref
PRUint32 currItemIndex;
mMenuItemsArray.Count(&currItemIndex);
mMenuItemsArray.AppendElement(supports); // owning ref
PRUint32 currItemIndex;
mMenuItemsArray.Count(&currItemIndex);
mNumMenuItems++;
mNumMenuItems++;
// We have to add it as a menu item and then associate it with the item
nsAutoString label;
aMenu->GetLabel(label);
//printf("AddMenu %s \n", label.ToNewCString());
// We have to add it as a menu item and then associate it with the item
nsAutoString label;
aMenu->GetLabel(label);
//printf("AddMenu %s \n", label.ToNewCString());
// ::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);
CFStringRef labelRef = ::CFStringCreateWithCharacters(kCFAllocatorDefault, (UniChar*)label.GetUnicode(), label.Length());
::InsertMenuItemTextWithCFString(mMacMenuHandle, labelRef, currItemIndex, 0, 0);
::CFRelease(labelRef);
PRBool isEnabled;
aMenu->GetEnabled(&isEnabled);
if (isEnabled)
::EnableMenuItem(mMacMenuHandle, currItemIndex);
else
::DisableMenuItem(mMacMenuHandle, currItemIndex);
PRBool isEnabled;
aMenu->GetEnabled(&isEnabled);
if (isEnabled)
::EnableMenuItem(mMacMenuHandle, currItemIndex);
else
::DisableMenuItem(mMacMenuHandle, currItemIndex);
MenuHandle childMenu;
if (aMenu->GetNativeData(&(void*)childMenu) == NS_OK)
::SetMenuItemHierarchicalMenu((MenuHandle) mMacMenuHandle, currItemIndex, childMenu);
return NS_OK;
MenuHandle childMenu;
if (aMenu->GetNativeData(&(void*)childMenu) == NS_OK)
::SetMenuItemHierarchicalMenu((MenuHandle) mMacMenuHandle, currItemIndex, childMenu);
return NS_OK;
}
//-------------------------------------------------------------------------
@ -385,47 +359,46 @@ NS_METHOD nsMenuX::InsertItemAt(const PRUint32 aPos, nsISupports * aMenuItem)
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::RemoveItem(const PRUint32 aPos)
{
NS_WARNING("Not implemented");
return NS_OK;
NS_WARNING("Not implemented");
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::RemoveAll()
{
if (mMacMenuHandle != NULL)
::DeleteMenuItems(mMacMenuHandle, 1, ::CountMenuItems(mMacMenuHandle));
mMenuItemsArray.Clear(); // remove all items
return NS_OK;
if (mMacMenuHandle != NULL)
::DeleteMenuItems(mMacMenuHandle, 1, ::CountMenuItems(mMacMenuHandle));
mMenuItemsArray.Clear(); // remove all items
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::GetNativeData(void ** aData)
{
*aData = mMacMenuHandle;
return NS_OK;
*aData = mMacMenuHandle;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::SetNativeData(void * aData)
{
mMacMenuHandle = (MenuHandle) aData;
return NS_OK;
mMacMenuHandle = (MenuHandle) aData;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::AddMenuListener(nsIMenuListener * aMenuListener)
{
mListener = aMenuListener; // strong ref
return NS_OK;
mListener = aMenuListener; // strong ref
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::RemoveMenuListener(nsIMenuListener * aMenuListener)
{
if (aMenuListener == mListener) {
mListener = nsnull;
}
return NS_OK;
if (aMenuListener == mListener)
mListener = nsnull;
return NS_OK;
}
@ -436,64 +409,60 @@ NS_METHOD nsMenuX::RemoveMenuListener(nsIMenuListener * aMenuListener)
//-------------------------------------------------------------------------
nsEventStatus nsMenuX::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
//printf("MenuItemSelected called \n");
nsEventStatus eventStatus = nsEventStatus_eIgnore;
//printf("MenuItemSelected called \n");
nsEventStatus eventStatus = nsEventStatus_eIgnore;
// 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 */
nsIMenuBar *mb = mMenuBarParent;
if ( mb == nsnull )
{
nsCOMPtr<nsIMenuBar> menuBar = do_QueryReferent(gMacMenubarX);
if (!menuBar)
return nsEventStatus_eIgnore;
// Determine if this is the correct menu to handle the event
PRInt16 menuID = HiWord(((nsMenuEvent)aMenuEvent).mCommand);
mb = menuBar;
}
if( menuID == nsMenuBarX::kAppleMenuID ) {
PRInt16 menuItemID = LoWord(((nsMenuEvent)aMenuEvent).mCommand);
if (menuItemID == 1) {
/* handle about app here */
nsresult rv = NS_ERROR_FAILURE;
// Go find the about menu item
if (!mMenuContent)
return nsEventStatus_eConsumeNoDefault;
nsCOMPtr<nsIDocument> doc;
mMenuContent->GetDocument(*getter_AddRefs(doc));
if (!doc)
return nsEventStatus_eConsumeNoDefault;
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(doc);
if (!xulDoc) {
NS_ERROR("nsIDOMDocument to nsIDOMXULDocument QI failed.");
return nsEventStatus_eConsumeNoDefault;
}
// "aboutName" is the element id for the "About &shortBrandName;"
// <menuitem/>. This is the glue code which causes any script code
// in the <menuitem/> to be executed.
nsCOMPtr<nsIDOMElement> domElement;
xulDoc->GetElementById(NS_LITERAL_STRING("aboutName"), getter_AddRefs(domElement));
if (!domElement)
return nsEventStatus_eConsumeNoDefault;
// Now get the pres context so we can execute the command
nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef);
if (!webShell)
return nsEventStatus_eConsumeNoDefault;
nsCOMPtr<nsIPresContext> presContext;
MenuHelpersX::WebShellToPresContext(webShell, getter_AddRefs(presContext));
/* set up a default event to query with */
nsMenuEvent event;
MenuHandle handle;
// XXX fix me for carbon!
::HMGetHelpMenuHandle(&handle);
event.mCommand = (unsigned int) handle;
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event;
event.eventStructType = NS_MOUSE_EVENT;
event.message = NS_MENU_ACTION;
/* loop through the top-level menus in the menubar */
PRUint32 numMenus = 0;
mb->GetMenuCount(numMenus);
numMenus--;
for (PRInt32 i = numMenus; i >= 0; i--)
{
nsCOMPtr<nsIMenu> menu;
mb->GetMenuAt(i, *getter_AddRefs(menu));
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(menu));
if (listener)
{
nsAutoString label;
menu->GetLabel(label);
/* ask if this is the right menu */
eventStatus = listener->MenuSelected(event);
if(eventStatus != nsEventStatus_eIgnore)
{
// call our ondestroy handler now because the menu is going away.
// do it now before sending the event into the dom in case our window
// goes away.
OnDestroy();
/* call back into this method with the proper "this" */
eventStatus = listener->MenuItemSelected(aMenuEvent);
return eventStatus;
}
}
}
}
else
#endif
if (mMacMenuID == menuID)
nsCOMPtr<nsIContent> contentNode = do_QueryInterface(domElement);
if (!contentNode)
return nsEventStatus_eConsumeNoDefault;
rv = contentNode->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
return nsEventStatus_eConsumeNoDefault;
}
}
else if (mMacMenuID == menuID)
{
// Call MenuItemSelected on the correct nsMenuItem
PRInt16 menuItemID = LoWord(((nsMenuEvent)aMenuEvent).mCommand);
@ -540,78 +509,76 @@ nsEventStatus nsMenuX::MenuItemSelected(const nsMenuEvent & aMenuEvent)
//-------------------------------------------------------------------------
nsEventStatus nsMenuX::MenuSelected(const nsMenuEvent & aMenuEvent)
{
//printf("MenuSelected called for %s \n", mLabel.ToNewCString());
nsEventStatus eventStatus = nsEventStatus_eIgnore;
//printf("MenuSelected called for %s \n", mLabel.ToNewCString());
nsEventStatus eventStatus = nsEventStatus_eIgnore;
// Determine if this is the correct menu to handle the event
MenuHandle selectedMenuHandle = (MenuHandle) aMenuEvent.mCommand;
// Determine if this is the correct menu to handle the event
MenuHandle selectedMenuHandle = (MenuHandle) aMenuEvent.mCommand;
if (mMacMenuHandle == selectedMenuHandle) {
if (mIsHelpMenu && mConstructed){
RemoveAll();
mConstructed = false;
mNeedsRebuild = PR_TRUE;
}
// Open the node.
mMenuContent->SetAttribute(kNameSpaceID_None, nsWidgetAtoms::open, NS_LITERAL_STRING("true"), PR_TRUE);
// Fire our oncreate handler. If we're told to stop, don't build the menu at all
PRBool keepProcessing = OnCreate();
if (!mIsHelpMenu && !mNeedsRebuild || !keepProcessing) {
return nsEventStatus_eConsumeNoDefault;
}
if(!mConstructed || mNeedsRebuild) {
if (mNeedsRebuild)
RemoveAll();
nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef);
if (!webShell) {
NS_ERROR("No web shell");
return nsEventStatus_eConsumeNoDefault;
}
if (mIsHelpMenu) {
HelpMenuConstruct(aMenuEvent, nsnull /* mParentWindow */, nsnull, webShell);
mConstructed = true;
} else {
MenuConstruct(aMenuEvent, nsnull /* mParentWindow */, nsnull, webShell);
mConstructed = true;
}
} else {
//printf("Menu already constructed \n");
}
eventStatus = nsEventStatus_eConsumeNoDefault;
} 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--) {
nsCOMPtr<nsISupports> menuSupports = getter_AddRefs(mMenuItemsArray.ElementAt(i - 1));
nsCOMPtr<nsIMenu> submenu = do_QueryInterface(menuSupports);
nsCOMPtr<nsIMenuListener> menuListener = do_QueryInterface(submenu);
if (menuListener) {
eventStatus = menuListener->MenuSelected(aMenuEvent);
if (nsEventStatus_eIgnore != eventStatus)
return eventStatus;
}
}
if (mMacMenuHandle == selectedMenuHandle) {
if (mIsHelpMenu && mConstructed){
RemoveAll();
mConstructed = false;
mNeedsRebuild = PR_TRUE;
}
return eventStatus;
// Open the node.
mMenuContent->SetAttribute(kNameSpaceID_None, nsWidgetAtoms::open, NS_LITERAL_STRING("true"), PR_TRUE);
// Fire our oncreate handler. If we're told to stop, don't build the menu at all
PRBool keepProcessing = OnCreate();
if (!mIsHelpMenu && !mNeedsRebuild || !keepProcessing)
return nsEventStatus_eConsumeNoDefault;
if(!mConstructed || mNeedsRebuild) {
if (mNeedsRebuild)
RemoveAll();
nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef);
if (!webShell) {
NS_ERROR("No web shell");
return nsEventStatus_eConsumeNoDefault;
}
if (mIsHelpMenu) {
HelpMenuConstruct(aMenuEvent, nsnull /* mParentWindow */, nsnull, webShell);
mConstructed = true;
} else {
MenuConstruct(aMenuEvent, nsnull /* mParentWindow */, nsnull, webShell);
mConstructed = true;
}
}
eventStatus = nsEventStatus_eConsumeNoDefault;
}
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--) {
nsCOMPtr<nsISupports> menuSupports = getter_AddRefs(mMenuItemsArray.ElementAt(i - 1));
nsCOMPtr<nsIMenu> submenu = do_QueryInterface(menuSupports);
nsCOMPtr<nsIMenuListener> menuListener = do_QueryInterface(submenu);
if (menuListener) {
eventStatus = menuListener->MenuSelected(aMenuEvent);
if (nsEventStatus_eIgnore != eventStatus)
return eventStatus;
}
}
}
return eventStatus;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuX::MenuDeselected(const nsMenuEvent & aMenuEvent)
{
// Destroy the menu
if (mConstructed) {
MenuDestruct(aMenuEvent);
mConstructed = false;
}
return nsEventStatus_eIgnore;
// Destroy the menu
if (mConstructed) {
MenuDestruct(aMenuEvent);
mConstructed = false;
}
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
@ -752,14 +719,14 @@ nsEventStatus nsMenuX::SetRebuild(PRBool aNeedsRebuild)
*/
NS_METHOD nsMenuX::SetEnabled(PRBool aIsEnabled)
{
mIsEnabled = aIsEnabled;
mIsEnabled = aIsEnabled;
if ( aIsEnabled )
::EnableMenuItem(mMacMenuHandle, 0);
else
::DisableMenuItem(mMacMenuHandle, 0);
if ( aIsEnabled )
::EnableMenuItem(mMacMenuHandle, 0);
else
::DisableMenuItem(mMacMenuHandle, 0);
return NS_OK;
return NS_OK;
}
//-------------------------------------------------------------------------
@ -769,9 +736,9 @@ NS_METHOD nsMenuX::SetEnabled(PRBool aIsEnabled)
*/
NS_METHOD nsMenuX::GetEnabled(PRBool* aIsEnabled)
{
NS_ENSURE_ARG_POINTER(aIsEnabled);
*aIsEnabled = mIsEnabled;
return NS_OK;
NS_ENSURE_ARG_POINTER(aIsEnabled);
*aIsEnabled = mIsEnabled;
return NS_OK;
}
//-------------------------------------------------------------------------
@ -781,9 +748,9 @@ NS_METHOD nsMenuX::GetEnabled(PRBool* aIsEnabled)
*/
NS_METHOD nsMenuX::IsHelpMenu(PRBool* aIsHelpMenu)
{
NS_ENSURE_ARG_POINTER(aIsHelpMenu);
*aIsHelpMenu = mIsHelpMenu;
return NS_OK;
NS_ENSURE_ARG_POINTER(aIsHelpMenu);
*aIsHelpMenu = mIsHelpMenu;
return NS_OK;
}
@ -806,69 +773,69 @@ NS_METHOD nsMenuX::GetMenuContent(nsIContent ** aMenuContent)
static pascal OSStatus MyMenuEventHandler(EventHandlerCallRef myHandler, EventRef event, void* userData)
{
OSStatus result = eventNotHandledErr;
OSStatus result = eventNotHandledErr;
UInt32 kind = ::GetEventKind(event);
if (kind == kEventMenuOpening || kind == kEventMenuClosed) {
nsISupports* supports = reinterpret_cast<nsISupports*>(userData);
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(supports));
if (listener) {
MenuRef menuRef;
::GetEventParameter(event, kEventParamDirectObject, typeMenuRef, NULL, sizeof(menuRef), NULL, &menuRef);
nsMenuEvent menuEvent;
menuEvent.message = NS_MENU_SELECTED;
menuEvent.eventStructType = NS_MENU_EVENT;
menuEvent.point.x = 0;
menuEvent.point.y = 0;
menuEvent.widget = nsnull;
menuEvent.time = PR_IntervalNow();
menuEvent.mCommand = (PRUint32) menuRef;
if (kind == kEventMenuOpening)
listener->MenuSelected(menuEvent);
else
listener->MenuDeselected(menuEvent);
}
UInt32 kind = ::GetEventKind(event);
if (kind == kEventMenuOpening || kind == kEventMenuClosed) {
nsISupports* supports = reinterpret_cast<nsISupports*>(userData);
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(supports));
if (listener) {
MenuRef menuRef;
::GetEventParameter(event, kEventParamDirectObject, typeMenuRef, NULL, sizeof(menuRef), NULL, &menuRef);
nsMenuEvent menuEvent;
menuEvent.message = NS_MENU_SELECTED;
menuEvent.eventStructType = NS_MENU_EVENT;
menuEvent.point.x = 0;
menuEvent.point.y = 0;
menuEvent.widget = nsnull;
menuEvent.time = PR_IntervalNow();
menuEvent.mCommand = (PRUint32) menuRef;
if (kind == kEventMenuOpening)
listener->MenuSelected(menuEvent);
else
listener->MenuDeselected(menuEvent);
}
return result;
}
return result;
}
static OSStatus InstallMyMenuEventHandler(MenuRef menuRef, void* userData)
{
// install the event handler for the various carbon menu events.
static EventTypeSpec eventList[] = {
{ kEventClassMenu, kEventMenuBeginTracking },
{ kEventClassMenu, kEventMenuEndTracking },
{ kEventClassMenu, kEventMenuChangeTrackingMode },
{ kEventClassMenu, kEventMenuOpening },
{ kEventClassMenu, kEventMenuClosed },
{ kEventClassMenu, kEventMenuTargetItem },
{ kEventClassMenu, kEventMenuMatchKey },
{ kEventClassMenu, kEventMenuEnableItems }
};
static EventHandlerUPP gMyMenuEventHandlerUPP = NewEventHandlerUPP(&MyMenuEventHandler);
return ::InstallMenuEventHandler(menuRef, gMyMenuEventHandlerUPP,
sizeof(eventList) / sizeof(EventTypeSpec), eventList,
userData, NULL);
// install the event handler for the various carbon menu events.
static EventTypeSpec eventList[] = {
{ kEventClassMenu, kEventMenuBeginTracking },
{ kEventClassMenu, kEventMenuEndTracking },
{ kEventClassMenu, kEventMenuChangeTrackingMode },
{ kEventClassMenu, kEventMenuOpening },
{ kEventClassMenu, kEventMenuClosed },
{ kEventClassMenu, kEventMenuTargetItem },
{ kEventClassMenu, kEventMenuMatchKey },
{ kEventClassMenu, kEventMenuEnableItems }
};
static EventHandlerUPP gMyMenuEventHandlerUPP = NewEventHandlerUPP(&MyMenuEventHandler);
return ::InstallMenuEventHandler(menuRef, gMyMenuEventHandlerUPP,
sizeof(eventList) / sizeof(EventTypeSpec), eventList,
userData, NULL);
}
//-------------------------------------------------------------------------
MenuHandle nsMenuX::NSStringNewMenu(short menuID, nsString& menuTitle)
{
MenuRef menuRef;
OSStatus status = ::CreateNewMenu(menuID, 0, &menuRef);
NS_ASSERTION(status == noErr,"nsMenuX::NSStringNewMenu: NewMenu failed.");
CFStringRef titleRef = ::CFStringCreateWithCharacters(kCFAllocatorDefault, (UniChar*)menuTitle.GetUnicode(), menuTitle.Length());
NS_ASSERTION(titleRef,"nsMenuX::NSStringNewMenu: CFStringCreateWithCharacters failed.");
if (titleRef) {
::SetMenuTitleWithCFString(menuRef, titleRef);
::CFRelease(titleRef);
}
status = ::InstallMyMenuEventHandler(menuRef, this);
NS_ASSERTION(status == noErr,"nsMenuX::NSStringNewMenu: InstallMyMenuEventHandler failed.");
MenuRef menuRef;
OSStatus status = ::CreateNewMenu(menuID, 0, &menuRef);
NS_ASSERTION(status == noErr,"nsMenuX::NSStringNewMenu: NewMenu failed.");
CFStringRef titleRef = ::CFStringCreateWithCharacters(kCFAllocatorDefault, (UniChar*)menuTitle.GetUnicode(), menuTitle.Length());
NS_ASSERTION(titleRef,"nsMenuX::NSStringNewMenu: CFStringCreateWithCharacters failed.");
if (titleRef) {
::SetMenuTitleWithCFString(menuRef, titleRef);
::CFRelease(titleRef);
}
status = ::InstallMyMenuEventHandler(menuRef, this);
NS_ASSERTION(status == noErr,"nsMenuX::NSStringNewMenu: InstallMyMenuEventHandler failed.");
return menuRef;
return menuRef;
}
@ -1349,15 +1316,15 @@ nsMenuX::AttributeChanged(nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom
NS_IMETHODIMP
nsMenuX :: ContentRemoved(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
{
if (gConstructingMenu)
return NS_OK;
mNeedsRebuild = PR_TRUE;
RemoveItem(aIndexInContainer);
mManager->Unregister(aChild);
if (gConstructingMenu)
return NS_OK;
mNeedsRebuild = PR_TRUE;
RemoveItem(aIndexInContainer);
mManager->Unregister(aChild);
return NS_OK;
} // ContentRemoved