Back to index

lightning-sunbird  0.9+nobinonly
nsMenuListener.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Original Author: David W. Hyatt (hyatt@netscape.com)
00024  *   Dean Tessman <dean_tessman@hotmail.com>
00025  *   Mark Hammond <markh@ActiveState.com>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 #include "nsMenuListener.h"
00042 #include "nsMenuBarFrame.h"
00043 #include "nsIDOMKeyListener.h"
00044 #include "nsIDOMEventReceiver.h"
00045 #include "nsIDOMEventListener.h"
00046 #include "nsIDOMNSUIEvent.h"
00047 #include "nsGUIEvent.h"
00048 
00049 // Drag & Drop, Clipboard
00050 #include "nsIServiceManager.h"
00051 #include "nsWidgetsCID.h"
00052 #include "nsCOMPtr.h"
00053 #include "nsIDOMKeyEvent.h"
00054 #include "nsIDOMNSEvent.h"
00055 #include "nsPresContext.h"
00056 #include "nsIContent.h"
00057 #include "nsIDOMNode.h"
00058 #include "nsIDOMElement.h"
00059 #include "nsXULAtoms.h"
00060 
00061 #include "nsIEventStateManager.h"
00062 
00063 #include "nsIViewManager.h"
00064 #include "nsIView.h"
00065 #include "nsISupportsArray.h"
00066 
00067 /*
00068  * nsMenuListener implementation
00069  */
00070 
00071 NS_IMPL_ADDREF(nsMenuListener)
00072 NS_IMPL_RELEASE(nsMenuListener)
00073 NS_IMPL_QUERY_INTERFACE3(nsMenuListener, nsIDOMKeyListener, nsIDOMFocusListener, nsIDOMMouseListener)
00074 
00075 
00077 
00078 nsMenuListener::nsMenuListener(nsIMenuParent* aMenuParent) 
00079 {
00080   mMenuParent = aMenuParent;
00081 }
00082 
00084 nsMenuListener::~nsMenuListener() 
00085 {
00086 }
00087 
00088 
00089 
00091 nsresult
00092 nsMenuListener::KeyUp(nsIDOMEvent* aKeyEvent)
00093 {
00094   aKeyEvent->StopPropagation();
00095   aKeyEvent->PreventDefault();
00096 
00097   return NS_ERROR_BASE; // I am consuming event
00098 }
00099 
00101 nsresult
00102 nsMenuListener::KeyDown(nsIDOMEvent* aKeyEvent)
00103 {
00104   PRInt32 menuAccessKey = -1;
00105   
00106   // If the key just pressed is the access key (usually Alt),
00107   // dismiss and unfocus the menu.
00108 
00109   nsMenuBarListener::GetMenuAccessKey(&menuAccessKey);
00110   if (menuAccessKey) {
00111     PRUint32 theChar;
00112     nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
00113     keyEvent->GetKeyCode(&theChar);
00114 
00115     if (theChar == (PRUint32)menuAccessKey) {
00116       // No other modifiers can be down.
00117       // Especially CTRL.  CTRL+ALT == AltGR, and
00118       // we'll fuck up on non-US enhanced 102-key
00119       // keyboards if we don't check this.
00120       PRBool ctrl = PR_FALSE;
00121       if (menuAccessKey != nsIDOMKeyEvent::DOM_VK_CONTROL)
00122         keyEvent->GetCtrlKey(&ctrl);
00123       PRBool alt=PR_FALSE;
00124       if (menuAccessKey != nsIDOMKeyEvent::DOM_VK_ALT)
00125         keyEvent->GetAltKey(&alt);
00126       PRBool shift=PR_FALSE;
00127       if (menuAccessKey != nsIDOMKeyEvent::DOM_VK_SHIFT)
00128         keyEvent->GetShiftKey(&shift);
00129       PRBool meta=PR_FALSE;
00130       if (menuAccessKey != nsIDOMKeyEvent::DOM_VK_META)
00131         keyEvent->GetMetaKey(&meta);
00132       if (!(ctrl || alt || shift || meta)) {
00133         // The access key just went down and no other
00134         // modifiers are already down.
00135         mMenuParent->DismissChain();
00136       }
00137     }
00138   }
00139 
00140   // Since a menu was open, eat the event to keep other event
00141   // listeners from becoming confused.
00142   aKeyEvent->StopPropagation();
00143   aKeyEvent->PreventDefault();
00144   return NS_ERROR_BASE; // I am consuming event
00145 }
00146 
00148 nsresult
00149 nsMenuListener::KeyPress(nsIDOMEvent* aKeyEvent)
00150 {
00151   // Don't check prevent default flag -- menus always get first shot at key events.
00152   // When a menu is open, the prevent default flag on a keypress is always set, so
00153   // that no one else uses the key event.
00154 
00155   //handlers shouldn't be triggered by non-trusted events.
00156   nsCOMPtr<nsIDOMNSEvent> domNSEvent = do_QueryInterface(aKeyEvent);
00157   PRBool trustedEvent = PR_FALSE;
00158 
00159   if (domNSEvent) {
00160     domNSEvent->GetIsTrusted(&trustedEvent);
00161   }
00162 
00163   if (!trustedEvent)
00164     return NS_OK;
00165 
00166   nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
00167   PRUint32 theChar;
00168        keyEvent->GetKeyCode(&theChar);
00169   PRBool handled = PR_FALSE;
00170 
00171   if (theChar == NS_VK_LEFT ||
00172       theChar == NS_VK_RIGHT ||
00173       theChar == NS_VK_UP ||
00174       theChar == NS_VK_DOWN ||
00175       theChar == NS_VK_HOME ||
00176       theChar == NS_VK_END) {
00177     // The navigation keys were pressed. User is moving around within
00178     // the menus.
00179          mMenuParent->KeyboardNavigation(theChar, handled);
00180   }
00181   else if (theChar == NS_VK_ESCAPE) {
00182     // Close one level.
00183     // Prevents us from getting destroyed by Escape(), we need to return to ourselves
00184     NS_ADDREF_THIS();
00185          mMenuParent->Escape(handled);
00186     NS_RELEASE_THIS();
00187     if (!handled)
00188       mMenuParent->DismissChain();
00189   }
00190   else if (theChar == NS_VK_TAB)
00191     mMenuParent->DismissChain();
00192   else if (theChar == NS_VK_ENTER ||
00193            theChar == NS_VK_RETURN) {
00194     // Open one level.
00195     mMenuParent->Enter();
00196   }
00197 #if !defined(XP_MAC) && !defined(XP_MACOSX)
00198   else if (theChar == NS_VK_F10) {
00199     // doesn't matter what modifier keys are down in Non-Mac platform
00200     // if the menu bar is active and F10 is pressed - deactivate it
00201     mMenuParent->DismissChain();
00202   }
00203 #endif // !XP_MAC && !XP_MACOSX
00204   else {
00205     PRInt32 menuAccessKey = -1;
00206     nsMenuBarListener::GetMenuAccessKey(&menuAccessKey);
00207     if (menuAccessKey) {
00208       // Do shortcut navigation.
00209       // A letter was pressed. We want to see if a shortcut gets matched. If
00210       // so, we'll know the menu got activated.
00211       keyEvent->GetCharCode(&theChar);
00212       mMenuParent->ShortcutNavigation(keyEvent, handled);
00213     }
00214   }
00215 
00216   aKeyEvent->StopPropagation();
00217   aKeyEvent->PreventDefault();
00218   return NS_ERROR_BASE; // I am consuming event
00219 }
00220 
00222 
00223 nsresult
00224 nsMenuListener::Focus(nsIDOMEvent* aEvent)
00225 {
00226   return NS_OK; // means I am NOT consuming event
00227 }
00228 
00230 nsresult
00231 nsMenuListener::Blur(nsIDOMEvent* aEvent)
00232 {
00233   
00234   return NS_OK; // means I am NOT consuming event
00235 }
00236   
00238 nsresult 
00239 nsMenuListener::MouseDown(nsIDOMEvent* aMouseEvent)
00240 {
00241   return NS_OK; // means I am NOT consuming event
00242 }
00243 
00245 nsresult 
00246 nsMenuListener::MouseUp(nsIDOMEvent* aMouseEvent)
00247 {
00248   return NS_OK; // means I am NOT consuming event
00249 }
00250 
00251 nsresult 
00252 nsMenuListener::MouseClick(nsIDOMEvent* aMouseEvent)
00253 {
00254   return NS_OK; // means I am NOT consuming event
00255 }
00256 
00258 nsresult 
00259 nsMenuListener::MouseDblClick(nsIDOMEvent* aMouseEvent)
00260 {
00261   return NS_OK; // means I am NOT consuming event
00262 }
00263 
00265 nsresult 
00266 nsMenuListener::MouseOver(nsIDOMEvent* aMouseEvent)
00267 {
00268   return NS_OK; // means I am NOT consuming event
00269 }
00270 
00272 nsresult 
00273 nsMenuListener::MouseOut(nsIDOMEvent* aMouseEvent)
00274 {
00275   return NS_OK; // means I am NOT consuming event
00276 }
00277 
00279 nsresult
00280 nsMenuListener::HandleEvent(nsIDOMEvent* aEvent)
00281 {
00282   return NS_OK;
00283 }
00284 
00285