Back to index

lightning-sunbird  0.9+nobinonly
nsSpatialNavigationService.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Spatial Navigation
00015  *
00016  * The Initial Developer of the Original Code is 
00017  * Douglas F. Turner II  <dougt@meer.net>
00018  * Portions created by the Initial Developer are Copyright (C) 2004-2005
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #include "nsSpatialNavigationPrivate.h"
00038 
00039 nsSpatialNavigationService::nsSpatialNavigationService()  
00040 {
00041   mEnabled             = PR_TRUE;
00042   mIgnoreTextFields    = PR_FALSE;
00043   mDisableJSWhenFocusing = PR_TRUE;
00044 
00045   mKeyCodeLeft         = nsIDOMKeyEvent::DOM_VK_LEFT;
00046   mKeyCodeRight        = nsIDOMKeyEvent::DOM_VK_RIGHT;
00047   mKeyCodeUp           = nsIDOMKeyEvent::DOM_VK_UP;
00048   mKeyCodeDown         = nsIDOMKeyEvent::DOM_VK_DOWN;
00049 
00050   mKeyCodeModifier     = 0x00000012 | 0x00100000; // By default ALT and SHIFT
00051 }  
00052 
00053 nsSpatialNavigationService::~nsSpatialNavigationService()  
00054 {
00055 }  
00056 
00057 NS_IMPL_ISUPPORTS1(nsSpatialNavigationService, nsIObserver)
00058 
00059 NS_IMETHODIMP
00060 nsSpatialNavigationService::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
00061 {
00062   nsresult rv;
00063 
00064   if (!strcmp(aTopic,"domwindowopened")) 
00065   {
00066     nsCOMPtr<nsIDOMWindow> chromeWindow = do_QueryInterface(aSubject);
00067     
00068     nsSpatialNavigation* sn = new nsSpatialNavigation(this);
00069 
00070     if (!sn)
00071       return NS_ERROR_OUT_OF_MEMORY;
00072 
00073     sn->Init(chromeWindow);
00074     
00075     mObjects.AppendObject(sn);  // the array owns the only reference to sn.
00076 
00077     return NS_OK;
00078   }
00079   
00080   if (!strcmp(aTopic,"domwindowclosed")) 
00081   {
00082     nsCOMPtr<nsIDOMWindow> chromeWindow = do_QueryInterface(aSubject);
00083     // need to find it in our array
00084   
00085     PRInt32 count = mObjects.Count();
00086     for (PRInt32 i = 0; i < count; i++)
00087     {
00088       nsISpatialNavigation* sn = mObjects[i];
00089       nsCOMPtr<nsIDOMWindow> attachedWindow;
00090       sn->GetAttachedWindow(getter_AddRefs(attachedWindow));
00091 
00092       if (attachedWindow == chromeWindow) 
00093       {
00094         sn->Shutdown();
00095         mObjects.RemoveObjectAt(i);
00096         return NS_OK;
00097       }
00098     }
00099     return NS_OK;
00100   }
00101 
00102   
00103   if (!strcmp(aTopic,"app-startup")) 
00104   {
00105     nsCOMPtr<nsIWindowWatcher> windowWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
00106     NS_ENSURE_SUCCESS(rv, rv);
00107     windowWatcher->RegisterNotification(this);
00108     
00109     nsCOMPtr<nsIPrefBranch2> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
00110     NS_ENSURE_SUCCESS(rv, rv);
00111 
00112        prefBranch->AddObserver("snav.", this, PR_FALSE);
00113     return NS_OK;
00114   }
00115   
00116   if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) 
00117   {
00118     nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(aSubject);
00119     nsXPIDLCString cstr;
00120     
00121     const char* pref = NS_ConvertUCS2toUTF8(aData).get();
00122 
00123     if (!strcmp(pref, "snav.enabled"))
00124     {
00125       prefBranch->GetBoolPref(pref, &mEnabled);
00126     }
00127     else if (!strcmp(pref, "snav.ignoreTextFields"))
00128     {
00129       prefBranch->GetBoolPref(pref, &mIgnoreTextFields);
00130     }
00131     else if (!strcmp(pref, "snav.directionalBias"))
00132     {
00133       prefBranch->GetIntPref(pref, &gDirectionalBias);
00134       if (gDirectionalBias == 0)
00135         gDirectionalBias = 1;
00136     }
00137     else if (!strcmp(pref, "snav.disableJS"))
00138     {
00139       prefBranch->GetBoolPref(pref, &mDisableJSWhenFocusing);
00140     }
00141     else if (!strcmp(pref, "snav.rectFudge"))
00142     {
00143       prefBranch->GetIntPref(pref, &gRectFudge);
00144     }
00145     else if (!strcmp(pref, "snav.keyCode.left"))
00146     {
00147       prefBranch->GetIntPref(pref, &mKeyCodeLeft);
00148     }
00149     else if (!strcmp(pref, "snav.keyCode.right"))
00150     {
00151       prefBranch->GetIntPref(pref, &mKeyCodeRight);
00152     }
00153     else if (!strcmp(pref, "snav.keyCode.up"))
00154     {
00155       prefBranch->GetIntPref(pref, &mKeyCodeUp);
00156     }    
00157     else if (!strcmp(pref, "snav.keyCode.down"))
00158     {
00159       prefBranch->GetIntPref(pref, &mKeyCodeDown);
00160     }    
00161     else if (!strcmp(pref, "snav.keyCode.modifier"))
00162     {
00163       prefBranch->GetIntPref(pref, &mKeyCodeModifier);
00164     }
00165     
00166     return NS_OK;
00167   }
00168   
00169   return NS_OK;
00170 }
00171 
00172 
00173 //------------------------------------------------------------------------------
00174 //  XPCOM REGISTRATION BELOW
00175 //------------------------------------------------------------------------------
00176 
00177 #define SpatialNavigation_CID \
00178 { 0xd1b91385, 0xe1c1, 0x46ec, \
00179 {0x8d, 0x15, 0x88, 0x0c, 0x45, 0xbe, 0x8e, 0x0e} }
00180 
00181 #define SpatialNavigation_ContractID "@mozilla.org/spatialNavigation/service;1"
00182 
00183 #define SpatialNavigationService_CID \
00184 { 0x4125624b, 0xaf22, 0x4d50, \
00185 { 0x87, 0xf6, 0x40, 0x19, 0xc9, 0x85, 0x7b, 0x58} }
00186 
00187 #define SpatialNavigationService_ContractID "@mozilla.org/spatialnavigation/service"
00188 
00189 static NS_METHOD SpatialNavigationServiceRegistration(nsIComponentManager *aCompMgr,
00190                                                       nsIFile *aPath,
00191                                                       const char *registryLocation,
00192                                                       const char *componentType,
00193                                                       const nsModuleComponentInfo *info)
00194 {
00195   nsresult rv;
00196   
00197   nsCOMPtr<nsIServiceManager> servman = do_QueryInterface((nsISupports*)aCompMgr, &rv);
00198   if (NS_FAILED(rv))
00199     return rv;
00200   
00201   
00202   nsCOMPtr<nsICategoryManager> catman;
00203   servman->GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID, 
00204                                   NS_GET_IID(nsICategoryManager), 
00205                                   getter_AddRefs(catman));
00206   
00207   if (NS_FAILED(rv))
00208     return rv;
00209   
00210   char* previous = nsnull;
00211   rv = catman->AddCategoryEntry("app-startup",
00212                                 "SpatialNavigationService", 
00213                                 SpatialNavigationService_ContractID,
00214                                 PR_TRUE, 
00215                                 PR_TRUE, 
00216                                 &previous);
00217   if (previous)
00218     nsMemory::Free(previous);
00219   
00220   return rv;
00221 }
00222 
00223 static NS_METHOD SpatialNavigationServiceUnregistration(nsIComponentManager *aCompMgr,
00224                                                         nsIFile *aPath,
00225                                                         const char *registryLocation,
00226                                                         const nsModuleComponentInfo *info)
00227 {
00228   nsresult rv;
00229   
00230   nsCOMPtr<nsIServiceManager> servman = do_QueryInterface((nsISupports*)aCompMgr, &rv);
00231   if (NS_FAILED(rv))
00232     return rv;
00233   
00234   nsCOMPtr<nsICategoryManager> catman;
00235   servman->GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID, 
00236                                   NS_GET_IID(nsICategoryManager), 
00237                                   getter_AddRefs(catman));
00238   
00239   if (NS_FAILED(rv))
00240     return rv;
00241   
00242   rv = catman->DeleteCategoryEntry("app-startup",
00243                                    "SpatialNavigationService", 
00244                                    PR_TRUE);
00245   
00246   return rv;
00247 }
00248 
00249 
00250 
00251 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSpatialNavigationService)
00252   
00253   
00254 static const nsModuleComponentInfo components[] =
00255 {
00256   { "SpatialNavigationService", 
00257     SpatialNavigationService_CID, 
00258     SpatialNavigationService_ContractID,
00259     nsSpatialNavigationServiceConstructor,
00260     SpatialNavigationServiceRegistration,
00261     SpatialNavigationServiceUnregistration
00262   }
00263   
00264 };
00265 
00266 NS_IMPL_NSGETMODULE(SpatialNavigationModule, components)