remove these files since they are getting build when they are not even in the makefile and thus screwing up Cam

ino builds. We should figure out why this is happening, but for now lets just fix it. b=111230 sr=samsidler
This commit is contained in:
joshmoz%gmail.com 2005-10-19 23:09:26 +00:00
parent 5e764dbeba
commit 6c15f9b840
3 changed files with 0 additions and 2746 deletions

View File

@ -1,959 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsIComponentManager.h"
#include "nsINameSpaceManager.h"
#include "nsIMenu.h"
#include "nsIMenuItem.h"
#include "nsIContent.h"
#include "nsMenuBarX.h"
#include "nsMenuX.h"
#include "nsISupports.h"
#include "nsIWidget.h"
#include "nsString.h"
#include "nsIStringBundle.h"
#include "nsIDocument.h"
#include "nsIDocShell.h"
#include "nsIDocumentViewer.h"
#include "nsIDocumentObserver.h"
#include "nsIDOMDocument.h"
#include "nsWidgetAtoms.h"
#include <Menus.h>
#include <TextUtils.h>
#include <Balloons.h>
#include <Resources.h>
#include <Appearance.h>
#include <Gestalt.h>
#include "nsMacResources.h"
#include "nsGUIEvent.h"
// CIDs
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
NS_IMPL_ISUPPORTS6(nsMenuBarX, nsIMenuBar, nsIMenuListener, nsIDocumentObserver,
nsIChangeManager, nsIMenuCommandDispatcher, nsISupportsWeakReference)
MenuRef nsMenuBarX::sAppleMenu = nsnull;
EventHandlerUPP nsMenuBarX::sCommandEventHandler = nsnull;
//
// nsMenuBarX constructor
//
nsMenuBarX::nsMenuBarX()
: mCurrentCommandID(1),
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.");
// create our global carbon event command handler shared by all windows
if ( !sCommandEventHandler )
sCommandEventHandler = ::NewEventHandlerUPP(CommandEventHandler);
}
//
// nsMenuBarX destructor
//
nsMenuBarX::~nsMenuBarX()
{
mMenusArray.Clear(); // release all menus
// make sure we unregister ourselves as a document observer
if ( mDocument ) {
nsCOMPtr<nsIDocumentObserver> observer ( do_QueryInterface(NS_STATIC_CAST(nsIMenuBar*,this)) );
mDocument->RemoveObserver(observer);
}
if ( mRootMenu )
::ReleaseMenu(mRootMenu);
}
nsEventStatus
nsMenuBarX::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
// Dispatch menu event
nsEventStatus eventStatus = nsEventStatus_eIgnore;
PRUint32 numItems;
mMenusArray.Count(&numItems);
for (PRUint32 i = numItems; i > 0; --i)
{
nsCOMPtr<nsISupports> menuSupports = getter_AddRefs(mMenusArray.ElementAt(i - 1));
nsCOMPtr<nsIMenuListener> menuListener = do_QueryInterface(menuSupports);
if(menuListener)
{
eventStatus = menuListener->MenuItemSelected(aMenuEvent);
if (nsEventStatus_eIgnore != eventStatus)
return eventStatus;
}
}
return eventStatus;
}
nsEventStatus
nsMenuBarX::MenuSelected(const nsMenuEvent & aMenuEvent)
{
// Dispatch event
nsEventStatus eventStatus = nsEventStatus_eIgnore;
nsCOMPtr<nsIMenuListener> menuListener;
//((nsISupports*)mMenuVoidArray[i-1])->QueryInterface(NS_GET_IID(nsIMenuListener), (void**)&menuListener);
//printf("gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count());
#if !TARGET_CARBON
nsCOMPtr<nsIMenu> theMenu;
gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, getter_AddRefs(theMenu));
menuListener = do_QueryInterface(theMenu);
#endif
if (menuListener) {
//TODO: MenuSelected is the right thing to call...
//eventStatus = menuListener->MenuSelected(aMenuEvent);
eventStatus = menuListener->MenuItemSelected(aMenuEvent);
if (nsEventStatus_eIgnore != eventStatus)
return eventStatus;
} else {
// If it's the help menu, gPreviousMenuStack won't be accurate so we need to get the listener a different way
// We'll do it the old fashioned way of looping through and finding it
PRUint32 numItems;
mMenusArray.Count(&numItems);
for (PRUint32 i = numItems; i > 0; --i)
{
nsCOMPtr<nsISupports> menuSupports = getter_AddRefs(mMenusArray.ElementAt(i - 1));
nsCOMPtr<nsIMenuListener> thisListener = do_QueryInterface(menuSupports);
if (thisListener)
{
//TODO: MenuSelected is the right thing to call...
//eventStatus = menuListener->MenuSelected(aMenuEvent);
eventStatus = thisListener->MenuItemSelected(aMenuEvent);
if(nsEventStatus_eIgnore != eventStatus)
return eventStatus;
}
}
}
return eventStatus;
}
nsEventStatus
nsMenuBarX::MenuDeselected(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
nsEventStatus
nsMenuBarX::CheckRebuild(PRBool & aNeedsRebuild)
{
aNeedsRebuild = PR_TRUE;
return nsEventStatus_eIgnore;
}
nsEventStatus
nsMenuBarX::SetRebuild(PRBool aNeedsRebuild)
{
return nsEventStatus_eIgnore;
}
void
nsMenuBarX :: GetDocument ( nsIDocShell* inDocShell, nsIDocument** outDocument )
{
*outDocument = nsnull;
if ( inDocShell ) {
nsCOMPtr<nsIContentViewer> cv;
inDocShell->GetContentViewer(getter_AddRefs(cv));
if (cv) {
// get the document
nsCOMPtr<nsIDocumentViewer> docv(do_QueryInterface(cv));
if (!docv)
return;
docv->GetDocument(outDocument); // addrefs
}
}
}
//
// RegisterAsDocumentObserver
//
// Name says it all.
//
void
nsMenuBarX :: RegisterAsDocumentObserver ( nsIDocShell* inDocShell )
{
nsCOMPtr<nsIDocument> doc;
GetDocument(inDocShell, 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 docshell goes away
// we can still remove ourself as doc observer directly from doc
mDocument = doc;
} // RegisterAsDocumentObesrver
//
// AquifyMenuBar
//
// Do what's necessary to conform to the Aqua guidelines for menus. Initially, this
// means removing 'Quit' from the file menu and 'Preferences' from the edit menu, along
// with their various separators (if present).
//
void
nsMenuBarX :: AquifyMenuBar ( )
{
nsCOMPtr<nsIDOMDocument> domDoc ( do_QueryInterface(mMenuBarContent->GetDocument()) );
if ( domDoc ) {
// remove quit item and its separator
HideItem ( domDoc, NS_LITERAL_STRING("menu_FileQuitSeparator"), nsnull );
HideItem ( domDoc, NS_LITERAL_STRING("menu_FileQuitItem"), getter_AddRefs(mQuitItemContent) );
// remove prefs item and its separator, but save off the pref content node
// so we can invoke its command later.
HideItem ( domDoc, NS_LITERAL_STRING("menu_PrefsSeparator"), nsnull );
HideItem ( domDoc, NS_LITERAL_STRING("menu_preferences"), getter_AddRefs(mPrefItemContent) );
}
} // AquifyMenuBar
//
// InstallCommandEventHandler
//
// Grab our window and install an event handler to handle command events which are
// used to drive the action when the user chooses an item from a menu. We have to install
// it on the window because the menubar isn't in the event chain for a menu command event.
//
OSStatus
nsMenuBarX :: InstallCommandEventHandler ( )
{
OSStatus err = noErr;
WindowRef myWindow = NS_REINTERPRET_CAST(WindowRef, mParent->GetNativeData(NS_NATIVE_DISPLAY));
NS_ASSERTION ( myWindow, "Can't get WindowRef to install command handler!" );
if ( myWindow && sCommandEventHandler ) {
const EventTypeSpec commandEventList[] = { {kEventClassCommand, kEventCommandProcess},
{kEventClassCommand, kEventCommandUpdateStatus} };
err = ::InstallWindowEventHandler ( myWindow, sCommandEventHandler, 2, commandEventList, this, NULL );
NS_ASSERTION ( err == noErr, "Uh oh, command handler not installed" );
}
return err;
} // InstallCommandEventHandler
//
// CommandEventHandler
//
// Processes Command carbon events from enabling/selecting of items in the menu.
//
pascal OSStatus
nsMenuBarX :: CommandEventHandler ( EventHandlerCallRef inHandlerChain, EventRef inEvent, void* userData )
{
OSStatus handled = eventNotHandledErr;
HICommand command;
OSErr err1 = ::GetEventParameter ( inEvent, kEventParamDirectObject, typeHICommand,
NULL, sizeof(HICommand), NULL, &command );
if ( err1 )
return handled;
nsMenuBarX* self = NS_REINTERPRET_CAST(nsMenuBarX*, userData);
switch ( ::GetEventKind(inEvent) ) {
// user selected a menu item. See if it's one we handle.
case kEventCommandProcess:
{
switch ( command.commandID ) {
case kHICommandPreferences:
{
nsEventStatus status = self->ExecuteCommand(self->mPrefItemContent);
if ( status == nsEventStatus_eConsumeNoDefault ) // event handled, no other processing
handled = noErr;
break;
}
case kHICommandQuit:
{
nsEventStatus status = self->ExecuteCommand(self->mQuitItemContent);
if ( status == nsEventStatus_eConsumeNoDefault ) // event handled, no other processing
handled = noErr;
break;
}
case kHICommandAbout:
{
// the 'about' command is special because we don't have a nsIMenu or nsIMenuItem
// for the apple menu. Grovel for the content node with an id of "aboutName"
// and call it directly.
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(self->mDocument);
if ( domDoc ) {
nsCOMPtr<nsIDOMElement> domElement;
domDoc->GetElementById(NS_LITERAL_STRING("aboutName"), getter_AddRefs(domElement));
nsCOMPtr<nsIContent> aboutContent ( do_QueryInterface(domElement) );
self->ExecuteCommand(aboutContent);
}
handled = noErr;
break;
}
default:
{
// given the commandID, look it up in our hashtable and dispatch to
// that content node. Recall that we store weak pointers to the content
// nodes in the hash table.
nsPRUint32Key key ( command.commandID );
nsIMenuItem* content = NS_REINTERPRET_CAST(nsIMenuItem*, self->mObserverTable.Get(&key));
if ( content )
content->DoCommand();
handled = noErr;
break;
}
} // switch on commandID
break;
}
// enable/disable menu id's
case kEventCommandUpdateStatus:
{
// only enable the preferences item in the app menu if we found a pref
// item DOM node in this menubar.
if ( command.commandID == kHICommandPreferences ) {
if ( self->mPrefItemContent )
::EnableMenuCommand ( nsnull, kHICommandPreferences );
else
::DisableMenuCommand ( nsnull, kHICommandPreferences );
handled = noErr;
}
break;
}
} // switch on event type
return handled;
} // CommandEventHandler
//
// ExecuteCommand
//
// Execute the menu item by sending a command message to the
// DOM node specified in |inDispatchTo|.
//
nsEventStatus
nsMenuBarX :: ExecuteCommand ( nsIContent* inDispatchTo )
{
nsEventStatus status = nsEventStatus_eIgnore;
if ( inDispatchTo ) {
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocShellWeakRef);
if (!docShell)
return nsEventStatus_eConsumeNoDefault;
nsCOMPtr<nsPresContext> presContext;
MenuHelpersX::DocShellToPresContext(docShell, getter_AddRefs(presContext));
nsMouseEvent event(PR_TRUE, NS_XUL_COMMAND, nsnull, nsMouseEvent::eReal);
inDispatchTo->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
return status;
} // ExecuteCommand
//
// HideItem
//
// Hide the item in the menu by setting the 'hidden' attribute. Returns it in |outHiddenNode| so
// the caller can hang onto it if they so choose. It is acceptable to pass nsull
// for |outHiddenNode| if the caller doesn't care about the hidden node.
//
void
nsMenuBarX :: HideItem ( nsIDOMDocument* inDoc, const nsAString & inID, nsIContent** outHiddenNode )
{
nsCOMPtr<nsIDOMElement> menuItem;
inDoc->GetElementById(inID, getter_AddRefs(menuItem));
nsCOMPtr<nsIContent> menuContent ( do_QueryInterface(menuItem) );
if ( menuContent ) {
menuContent->SetAttr ( kNameSpaceID_None, nsWidgetAtoms::hidden, NS_LITERAL_STRING("true"), PR_FALSE );
if ( outHiddenNode ) {
*outHiddenNode = menuContent.get();
NS_IF_ADDREF(*outHiddenNode);
}
}
} // HideItem
nsEventStatus
nsMenuBarX::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWindow,
void * menubarNode, void * aDocShell )
{
mDocShellWeakRef = do_GetWeakReference(NS_STATIC_CAST(nsIDocShell*, aDocShell));
nsIDOMNode* aDOMNode = NS_STATIC_CAST(nsIDOMNode*, menubarNode);
mMenuBarContent = do_QueryInterface(aDOMNode); // strong ref
NS_ASSERTION ( mMenuBarContent, "No content specified for this menubar" );
if ( !mMenuBarContent )
return nsEventStatus_eIgnore;
Create(aParentWindow);
// if we're on X (using aqua UI guidelines for menus), remove quit and prefs
// from our menubar.
SInt32 result = 0L;
OSStatus err = ::Gestalt ( gestaltMenuMgrAttr, &result );
if ( !err && (result & gestaltMenuMgrAquaLayoutMask) )
AquifyMenuBar();
err = InstallCommandEventHandler();
if ( err )
return nsEventStatus_eIgnore;
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocShellWeakRef);
if (docShell) RegisterAsDocumentObserver(docShell);
// set this as a nsMenuListener on aParentWindow
aParentWindow->AddMenuListener((nsIMenuListener *)this);
PRUint32 count = mMenuBarContent->GetChildCount();
for ( PRUint32 i = 0; i < count; ++i ) {
nsIContent *menu = mMenuBarContent->GetChildAt(i);
if ( menu ) {
if (menu->Tag() == nsWidgetAtoms::menu &&
menu->IsContentOfType(nsIContent::eXUL)) {
nsAutoString menuName;
nsAutoString menuAccessKey(NS_LITERAL_STRING(" "));
menu->GetAttr(kNameSpaceID_None, nsWidgetAtoms::label, menuName);
menu->GetAttr(kNameSpaceID_None, nsWidgetAtoms::accesskey, menuAccessKey);
// Don't create the whole menu yet, just add in the top level names
// Create nsMenu, the menubar will own it
nsCOMPtr<nsIMenu> pnsMenu ( do_CreateInstance(kMenuCID) );
if ( pnsMenu ) {
pnsMenu->Create(NS_STATIC_CAST(nsIMenuBar*, this), menuName, menuAccessKey,
NS_STATIC_CAST(nsIChangeManager *, this),
NS_REINTERPRET_CAST(nsIDocShell*, aDocShell), menu);
// Make nsMenu a child of nsMenuBar. nsMenuBar takes ownership
AddMenu(pnsMenu);
nsAutoString menuIDstring;
menu->GetAttr(kNameSpaceID_None, nsWidgetAtoms::id, menuIDstring);
if ( menuIDstring.EqualsLiteral("menu_Help") ) {
nsMenuEvent event(PR_TRUE, 0, nsnull);
MenuHandle handle = nsnull;
#if !TARGET_CARBON
::HMGetHelpMenuHandle(&handle);
#endif
event.mCommand = (unsigned int) handle;
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(pnsMenu));
listener->MenuSelected(event);
}
}
}
}
} // for each menu
// Give the aParentWindow this nsMenuBarX to hold onto.
// The parent takes ownership
aParentWindow->SetMenuBar(this);
return nsEventStatus_eIgnore;
}
nsEventStatus
nsMenuBarX::MenuDestruct(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
//
// Create the proper widget
//
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::Create(nsIWidget *aParent)
{
SetParent(aParent);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::GetParent(nsIWidget *&aParent)
{
NS_IF_ADDREF(aParent = mParent);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::SetParent(nsIWidget *aParent)
{
mParent = aParent; // weak ref
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::AddMenu(nsIMenu * aMenu)
{
// keep track of all added menus.
mMenusArray.AppendElement(aMenu); // owner
if (mNumMenus == 0) {
// if apple menu hasn't been created, create it.
if ( !sAppleMenu ) {
nsresult rv = CreateAppleMenu(aMenu);
NS_ASSERTION ( NS_SUCCEEDED(rv), "Can't create Apple menu" );
}
// add shared Apple menu to our menubar
if ( sAppleMenu ) {
// 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;
::InsertMenuItem(mRootMenu, "\pA", mNumMenus);
::SetMenuItemHierarchicalMenu(mRootMenu, 1, sAppleMenu);
}
}
MenuRef menuRef = nsnull;
aMenu->GetNativeData((void**)&menuRef);
PRBool helpMenu;
aMenu->IsHelpMenu(&helpMenu);
if(!helpMenu) {
nsCOMPtr<nsIContent> menu;
aMenu->GetMenuContent(getter_AddRefs(menu));
nsAutoString menuHidden;
menu->GetAttr(kNameSpaceID_None, nsWidgetAtoms::hidden, menuHidden);
if( !menuHidden.EqualsLiteral("true")) {
// make sure we only increment |mNumMenus| if the menu is visible, since
// we use it as an index of where to insert the next menu.
mNumMenus++;
::InsertMenuItem(mRootMenu, "\pPlaceholder", mNumMenus);
OSStatus status = ::SetMenuItemHierarchicalMenu(mRootMenu, mNumMenus, menuRef);
NS_ASSERTION(status == noErr, "nsMenuBarX::AddMenu: SetMenuItemHierarchicalMenu failed.");
}
}
return NS_OK;
}
//
// CreateAppleMenu
//
// build the Apple menu shared by all menu bars.
//
nsresult
nsMenuBarX :: CreateAppleMenu ( nsIMenu* inMenu )
{
Str32 menuStr = { 1, kMenuAppleLogoFilledGlyph };
OSStatus s = ::CreateNewMenu(kAppleMenuID, 0, &sAppleMenu);
if ( s == noErr && sAppleMenu ) {
::SetMenuTitle(sAppleMenu, menuStr);
// 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;
inMenu->GetMenuContent(getter_AddRefs(menu));
if (menu) {
nsCOMPtr<nsIDocument> doc = menu->GetDocument();
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.get(), label.Length());
if ( labelRef ) {
::InsertMenuItemTextWithCFString(sAppleMenu, labelRef, 1, 0, 0);
::CFRelease(labelRef);
}
::SetMenuItemCommandID(sAppleMenu, 1, kHICommandAbout);
::AppendMenu(sAppleMenu, "\p-");
}
return (s == noErr && sAppleMenu) ? NS_OK : NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::GetMenuCount(PRUint32 &aCount)
{
aCount = mNumMenus;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::GetMenuAt(const PRUint32 aCount, nsIMenu *& aMenu)
{
aMenu = NULL;
nsCOMPtr<nsISupports> supports = getter_AddRefs(mMenusArray.ElementAt(aCount));
if (!supports) return NS_OK;
return CallQueryInterface(supports, &aMenu); // addref
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::InsertMenuAt(const PRUint32 aCount, nsIMenu *& aMenu)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::RemoveMenu(const PRUint32 aCount)
{
mMenusArray.RemoveElementAt(aCount);
::DeleteMenuItem(mRootMenu, aCount + 1); // MenuManager is 1-based
::DrawMenuBar();
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::RemoveAll()
{
NS_ASSERTION(0, "Not implemented!");
// mMenusArray.Clear(); // maybe?
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::GetNativeData(void *& aData)
{
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;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBarX::Paint()
{
// hack to correctly swap menu bars.
// hopefully this is fast enough.
::SetRootMenu(mRootMenu);
::DrawMenuBar();
return NS_OK;
}
#pragma mark -
//
// nsIDocumentObserver
// this is needed for menubar changes
//
NS_IMPL_NSIDOCUMENTOBSERVER_LOAD_STUB(nsMenuBarX)
NS_IMPL_NSIDOCUMENTOBSERVER_REFLOW_STUB(nsMenuBarX)
NS_IMPL_NSIDOCUMENTOBSERVER_STATE_STUB(nsMenuBarX)
NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(nsMenuBarX)
void
nsMenuBarX::BeginUpdate( nsIDocument * aDocument, nsUpdateType aUpdateType )
{
}
void
nsMenuBarX::EndUpdate( nsIDocument * aDocument, nsUpdateType aUpdateType )
{
}
void
nsMenuBarX::CharacterDataChanged( nsIDocument * aDocument, nsIContent * aContent, PRBool aAppend)
{
}
void
nsMenuBarX::ContentAppended( nsIDocument * aDocument, nsIContent * aContainer,
PRInt32 aNewIndexInContainer)
{
if ( aContainer == mMenuBarContent ) {
//Register(aContainer, );
//InsertMenu ( aNewIndexInContainer );
}
else {
nsCOMPtr<nsIChangeObserver> obs;
Lookup ( aContainer, getter_AddRefs(obs) );
if ( obs )
obs->ContentInserted ( aDocument, aContainer, aNewIndexInContainer );
else {
nsCOMPtr<nsIContent> parent = aContainer->GetParent();
if(parent) {
Lookup ( parent, getter_AddRefs(obs) );
if ( obs )
obs->ContentInserted ( aDocument, aContainer, aNewIndexInContainer );
}
}
}
}
void
nsMenuBarX::DocumentWillBeDestroyed( nsIDocument * aDocument )
{
mDocument = nsnull;
}
void
nsMenuBarX::AttributeChanged( nsIDocument * aDocument, nsIContent * aContent, PRInt32 aNameSpaceID,
nsIAtom * aAttribute, PRInt32 aModType)
{
// lookup and dispatch to registered thang.
nsCOMPtr<nsIChangeObserver> obs;
Lookup ( aContent, getter_AddRefs(obs) );
if ( obs )
obs->AttributeChanged ( aDocument, aNameSpaceID, aAttribute );
}
void
nsMenuBarX::ContentRemoved( nsIDocument * aDocument, nsIContent * aContainer,
nsIContent * aChild, PRInt32 aIndexInContainer )
{
if ( aContainer == mMenuBarContent ) {
Unregister(aChild);
RemoveMenu ( aIndexInContainer );
}
else {
nsCOMPtr<nsIChangeObserver> obs;
Lookup ( aContainer, getter_AddRefs(obs) );
if ( obs )
obs->ContentRemoved ( aDocument, aChild, aIndexInContainer );
else {
nsCOMPtr<nsIContent> parent = aContainer->GetParent();
if(parent) {
Lookup ( parent, getter_AddRefs(obs) );
if ( obs )
obs->ContentRemoved ( aDocument, aChild, aIndexInContainer );
}
}
}
}
void
nsMenuBarX::ContentInserted( nsIDocument * aDocument, nsIContent * aContainer,
nsIContent * aChild, PRInt32 aIndexInContainer )
{
if ( aContainer == mMenuBarContent ) {
//Register(aChild, );
//InsertMenu ( aIndexInContainer );
}
else {
nsCOMPtr<nsIChangeObserver> obs;
Lookup ( aContainer, getter_AddRefs(obs) );
if ( obs )
obs->ContentInserted ( aDocument, aChild, aIndexInContainer );
else {
nsCOMPtr<nsIContent> parent = aContainer->GetParent();
if(parent) {
Lookup ( parent, getter_AddRefs(obs) );
if ( obs )
obs->ContentInserted ( aDocument, aChild, aIndexInContainer );
}
}
}
}
#pragma mark -
//
// nsIChangeManager
//
// We don't use a |nsSupportsHashtable| because we know that the lifetime of all these items
// is bouded 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 )
{
nsVoidKey key ( aContent );
mObserverTable.Put ( &key, aMenuObject );
return NS_OK;
}
NS_IMETHODIMP
nsMenuBarX :: Unregister ( nsIContent *aContent )
{
nsVoidKey key ( aContent );
mObserverTable.Remove ( &key );
return NS_OK;
}
NS_IMETHODIMP
nsMenuBarX :: Lookup ( nsIContent *aContent, nsIChangeObserver **_retval )
{
*_retval = nsnull;
nsVoidKey key ( aContent );
*_retval = NS_REINTERPRET_CAST(nsIChangeObserver*, mObserverTable.Get(&key));
NS_IF_ADDREF ( *_retval );
return NS_OK;
}
#pragma mark -
//
// Implementation methods for nsIMenuCommandDispatcher
//
//
// Register
//
// 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 )
{
// 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.
// 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;
}
//
// Unregister
//
// Removes the mapping between the given 4-character command ID
// and its associated menu item.
//
NS_IMETHODIMP
nsMenuBarX :: Unregister ( PRUint32 inCommandID )
{
nsPRUint32Key key ( inCommandID );
mObserverTable.Remove ( &key );
return NS_OK;
}
#pragma mark -
//
// DocShellToPresContext
//
// Helper to dig out a pres context from a docshell. A common thing to do before
// sending an event into the dom.
//
// XXXbz this should be using DOM event apis!
nsresult
MenuHelpersX::DocShellToPresContext (nsIDocShell* inDocShell, nsPresContext** outContext )
{
NS_ENSURE_ARG_POINTER(outContext);
*outContext = nsnull;
if (!inDocShell)
return NS_ERROR_INVALID_ARG;
nsresult retval = NS_OK;
nsCOMPtr<nsIContentViewer> contentViewer;
inDocShell->GetContentViewer(getter_AddRefs(contentViewer));
if ( contentViewer ) {
nsCOMPtr<nsIDocumentViewer> docViewer ( do_QueryInterface(contentViewer) );
if ( docViewer )
docViewer->GetPresContext(outContext); // AddRefs for us
else
retval = NS_ERROR_FAILURE;
}
else
retval = NS_ERROR_FAILURE;
return retval;
} // DocShellToPresContext

View File

@ -1,406 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCOMPtr.h"
#include "nsIDocumentViewer.h"
#include "nsIContent.h"
#include "nsPresContext.h"
#include "nsMenuBarX.h" // for MenuHelpers namespace
#include "nsMenuItemX.h"
#include "nsIMenu.h"
#include "nsIMenuBar.h"
#include "nsIWidget.h"
#include "nsIMenuListener.h"
#include "nsINameSpaceManager.h"
#include "nsWidgetAtoms.h"
#include "nsIServiceManager.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsGUIEvent.h"
#if 0
nsInstanceCounter gMenuItemCounterX("nsMenuItemX");
#endif
NS_IMPL_ISUPPORTS4(nsMenuItemX, nsIMenuItem, nsIMenuListener, nsIChangeObserver, nsISupportsWeakReference)
//
// nsMenuItemX constructor
//
nsMenuItemX::nsMenuItemX()
{
mMenuParent = nsnull;
mIsSeparator = PR_FALSE;
mKeyEquivalent.AssignLiteral(" ");
mEnabled = PR_TRUE;
mIsChecked = PR_FALSE;
mMenuType = eRegular;
#if 0
++gMenuItemCounterX;
#endif
}
//
// nsMenuItemX destructor
//
nsMenuItemX::~nsMenuItemX()
{
mManager->Unregister(mContent);
#if 0
--gMenuItemCounterX;
#endif
}
NS_METHOD nsMenuItemX::Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator,
EMenuItemType aItemType, PRBool aEnabled,
nsIChangeManager* aManager, nsIDocShell* aShell, nsIContent* aNode )
{
mContent = aNode; // addref
mMenuParent = aParent; // weak
mDocShellWeakRef = do_GetWeakReference(aShell);
mEnabled = aEnabled;
mMenuType = aItemType;
// register for AttributeChanged messages
mManager = aManager;
nsCOMPtr<nsIChangeObserver> obs = do_QueryInterface(NS_STATIC_CAST(nsIChangeObserver*,this));
mManager->Register(mContent, obs); // does not addref this
mIsSeparator = aIsSeparator;
mLabel = aLabel;
return NS_OK;
}
NS_METHOD
nsMenuItemX::GetLabel(nsString &aText)
{
aText = mLabel;
return NS_OK;
}
NS_METHOD
nsMenuItemX::GetEnabled(PRBool *aIsEnabled)
{
*aIsEnabled = mEnabled;
return NS_OK;
}
NS_METHOD nsMenuItemX::SetChecked(PRBool aIsEnabled)
{
mIsChecked = aIsEnabled;
// update the content model. This will also handle unchecking our siblings
// if we are a radiomenu
mContent->SetAttr(kNameSpaceID_None, nsWidgetAtoms::checked,
mIsChecked ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false"), PR_TRUE);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItemX::GetChecked(PRBool *aIsEnabled)
{
*aIsEnabled = mIsChecked;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItemX::GetMenuItemType(EMenuItemType *aType)
{
*aType = mMenuType;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItemX::GetTarget(nsIWidget *& aTarget)
{
NS_IF_ADDREF(aTarget = mTarget);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItemX::GetNativeData(void *& aData)
{
//aData = (void *)mMenu;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItemX::AddMenuListener(nsIMenuListener * aMenuListener)
{
mXULCommandListener = aMenuListener; // addref
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItemX::RemoveMenuListener(nsIMenuListener * aMenuListener)
{
if (mXULCommandListener.get() == aMenuListener)
mXULCommandListener = nsnull;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItemX::IsSeparator(PRBool & aIsSep)
{
aIsSep = mIsSeparator;
return NS_OK;
}
//-------------------------------------------------------------------------
// nsIMenuListener interface
//-------------------------------------------------------------------------
nsEventStatus nsMenuItemX::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
// this is all handled by Carbon Events
return nsEventStatus_eConsumeNoDefault;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItemX::MenuSelected(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
// nsIMenuListener interface
//-------------------------------------------------------------------------
nsEventStatus nsMenuItemX::MenuDeselected(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItemX::MenuConstruct(
const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menuNode,
void * aDocShell)
{
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItemX::MenuDestruct(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItemX::CheckRebuild(PRBool & aNeedsRebuild)
{
aNeedsRebuild = PR_TRUE;
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItemX::SetRebuild(PRBool aNeedsRebuild)
{
//mNeedsRebuild = aNeedsRebuild;
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
/**
* Executes the "cached" JavaScript Command
* @return NS_OK if the command was executed properly, otherwise an error code
*/
NS_METHOD nsMenuItemX::DoCommand()
{
nsCOMPtr<nsPresContext> presContext;
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocShellWeakRef);
if (!docShell)
return nsEventStatus_eConsumeNoDefault;
MenuHelpersX::DocShellToPresContext(docShell, getter_AddRefs(presContext));
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event(PR_TRUE, NS_XUL_COMMAND, nsnull, nsMouseEvent::eReal);
// See if we have a command element. If so, we execute on the command instead
// of on our content element.
nsAutoString command;
mContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::command, command);
if (!command.IsEmpty()) {
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mContent->GetDocument()));
nsCOMPtr<nsIDOMElement> commandElt;
domDoc->GetElementById(command, getter_AddRefs(commandElt));
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
if (commandContent)
commandContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
else
mContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
return nsEventStatus_eConsumeNoDefault;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItemX::GetModifiers(PRUint8 * aModifiers)
{
nsresult res = NS_OK;
*aModifiers = mModifiers;
return res;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItemX::SetModifiers(PRUint8 aModifiers)
{
nsresult res = NS_OK;
mModifiers = aModifiers;
return res;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItemX::SetShortcutChar(const nsString &aText)
{
nsresult res = NS_OK;
mKeyEquivalent = aText;
return res;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItemX::GetShortcutChar(nsString &aText)
{
nsresult res = NS_OK;
aText = mKeyEquivalent;
return res;
}
//
// UncheckRadioSiblings
//
// walk the sibling list looking for nodes with the same name and
// uncheck them all.
//
void
nsMenuItemX :: UncheckRadioSiblings(nsIContent* inCheckedContent)
{
nsAutoString myGroupName;
inCheckedContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::name, myGroupName);
if ( ! myGroupName.Length() ) // no groupname, nothing to do
return;
nsCOMPtr<nsIContent> parent = inCheckedContent->GetParent();
if ( !parent )
return;
// loop over siblings
PRUint32 count = parent->GetChildCount();
for ( PRUint32 i = 0; i < count; ++i ) {
nsIContent *sibling = parent->GetChildAt(i);
if ( sibling ) {
if ( sibling != inCheckedContent ) { // skip this node
// if the current sibling is in the same group, clear it
nsAutoString currGroupName;
sibling->GetAttr(kNameSpaceID_None, nsWidgetAtoms::name, currGroupName);
if ( currGroupName == myGroupName )
sibling->SetAttr(kNameSpaceID_None, nsWidgetAtoms::checked, NS_LITERAL_STRING("false"), PR_TRUE);
}
}
} // for each sibling
} // UncheckRadioSiblings
#pragma mark -
//
// nsIChangeObserver
//
NS_IMETHODIMP
nsMenuItemX :: AttributeChanged ( nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom *aAttribute )
{
if (aAttribute == nsWidgetAtoms::checked) {
// if we're a radio menu, uncheck our sibling radio items. No need to
// do any of this if we're just a normal check menu.
if ( mMenuType == eRadio ) {
nsAutoString checked;
mContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::checked, checked);
if (checked.EqualsLiteral("true") )
UncheckRadioSiblings(mContent);
}
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE);
}
else if (aAttribute == nsWidgetAtoms::disabled || aAttribute == nsWidgetAtoms::hidden ||
aAttribute == nsWidgetAtoms::collapsed ) {
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE);
}
return NS_OK;
} // AttributeChanged
NS_IMETHODIMP
nsMenuItemX :: ContentRemoved(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
{
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE);
return NS_OK;
} // ContentRemoved
NS_IMETHODIMP
nsMenuItemX :: ContentInserted(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
{
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE);
return NS_OK;
} // ContentInserted

File diff suppressed because it is too large Load Diff