Back to index

lightning-sunbird  0.9+nobinonly
nsXULControllers.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.org 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  *   Mark Hammond <MarkH@ActiveState.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 /*
00041 
00042   This file provides the implementation for the XUL "controllers"
00043   object.
00044 
00045 */
00046 
00047 #include "nsString.h"
00048 
00049 #include "nsIControllers.h"
00050 #include "nsIDOMElement.h"
00051 #include "nsIDOMXULCommandDispatcher.h"
00052 #include "nsXULControllers.h"
00053 #include "nsString.h"
00054 #include "nsContentUtils.h"
00055 
00056 //----------------------------------------------------------------------
00057 
00058 nsXULControllers::nsXULControllers()
00059 : mCurControllerID(0)
00060 {
00061 }
00062 
00063 nsXULControllers::~nsXULControllers(void)
00064 {
00065   DeleteControllers();
00066 }
00067 
00068 void
00069 nsXULControllers::DeleteControllers()
00070 {
00071   PRUint32 count = mControllers.Count();
00072   for (PRUint32 i = 0; i < count; i++)
00073   {
00074     nsXULControllerData*  controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(i));
00075     if (controllerData)
00076       delete controllerData;    // releases the nsIController
00077   }
00078   
00079   mControllers.Clear();
00080 }
00081 
00082 
00083 NS_IMETHODIMP
00084 NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult)
00085 {
00086   NS_PRECONDITION(aOuter == nsnull, "no aggregation");
00087   if (aOuter)
00088     return NS_ERROR_NO_AGGREGATION;
00089 
00090   nsXULControllers* controllers = new nsXULControllers();
00091   if (! controllers)
00092     return NS_ERROR_OUT_OF_MEMORY;
00093   
00094   nsresult rv;
00095   NS_ADDREF(controllers);
00096   rv = controllers->QueryInterface(aIID, aResult);
00097   NS_RELEASE(controllers);
00098   return rv;
00099 }
00100 
00101 // QueryInterface implementation for nsXULControllers
00102 NS_INTERFACE_MAP_BEGIN(nsXULControllers)
00103   NS_INTERFACE_MAP_ENTRY(nsIControllers)
00104   NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
00105   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIControllers)
00106   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(XULControllers)
00107 NS_INTERFACE_MAP_END
00108 
00109 
00110 NS_IMPL_ADDREF(nsXULControllers)
00111 NS_IMPL_RELEASE(nsXULControllers)
00112 
00113 
00114 NS_IMETHODIMP
00115 nsXULControllers::GetCommandDispatcher(nsIDOMXULCommandDispatcher** _result)
00116 {
00117   nsCOMPtr<nsIDOMXULCommandDispatcher> dispatcher = do_QueryReferent(mCommandDispatcher);
00118   *_result = dispatcher;
00119   NS_IF_ADDREF(*_result);
00120   return NS_OK;
00121 }
00122 
00123 
00124 NS_IMETHODIMP
00125 nsXULControllers::SetCommandDispatcher(nsIDOMXULCommandDispatcher* aCommandDispatcher)
00126 {
00127   mCommandDispatcher = do_GetWeakReference(aCommandDispatcher);
00128   return NS_OK;
00129 }
00130 
00131 NS_IMETHODIMP
00132 nsXULControllers::GetControllerForCommand(const char *aCommand, nsIController** _retval)
00133 {
00134   NS_ENSURE_ARG_POINTER(_retval);
00135   *_retval = nsnull;
00136 
00137   PRUint32 count = mControllers.Count();
00138   for (PRUint32 i=0; i < count; i++)
00139   {
00140     nsXULControllerData*  controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(i));
00141     if (controllerData)
00142     {
00143       nsCOMPtr<nsIController> controller;
00144       controllerData->GetController(getter_AddRefs(controller));
00145       if (controller)
00146       {
00147         PRBool supportsCommand;
00148         controller->SupportsCommand(aCommand, &supportsCommand);
00149         if (supportsCommand) {
00150           *_retval = controller;
00151           NS_ADDREF(*_retval);
00152           return NS_OK;
00153         }
00154       }
00155     }
00156   }
00157   
00158   return NS_OK;
00159 }
00160 
00161 NS_IMETHODIMP
00162 nsXULControllers::InsertControllerAt(PRUint32 aIndex, nsIController *controller)
00163 {
00164   nsXULControllerData*  controllerData = new nsXULControllerData(++mCurControllerID, controller);
00165   if (!controllerData) return NS_ERROR_OUT_OF_MEMORY;
00166 #ifdef DEBUG
00167   PRBool inserted =
00168 #endif
00169   mControllers.InsertElementAt((void *)controllerData, aIndex);
00170   NS_ASSERTION(inserted, "Insertion of controller failed");
00171   return NS_OK;
00172 }
00173 
00174 NS_IMETHODIMP
00175 nsXULControllers::RemoveControllerAt(PRUint32 aIndex, nsIController **_retval)
00176 {
00177   NS_ENSURE_ARG_POINTER(_retval);
00178   *_retval = nsnull;
00179 
00180   nsXULControllerData*  controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.SafeElementAt(aIndex));
00181   if (!controllerData) return NS_ERROR_FAILURE;
00182 
00183 #ifdef DEBUG
00184   PRBool removed =
00185 #endif
00186   mControllers.RemoveElementAt(aIndex);
00187   NS_ASSERTION(removed, "Removal of controller failed");
00188 
00189   controllerData->GetController(_retval);
00190   delete controllerData;
00191   
00192   return NS_OK;
00193 }
00194 
00195 
00196 NS_IMETHODIMP
00197 nsXULControllers::GetControllerAt(PRUint32 aIndex, nsIController **_retval)
00198 {
00199   NS_ENSURE_ARG_POINTER(_retval);
00200   *_retval = nsnull;
00201 
00202   nsXULControllerData*  controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.SafeElementAt(aIndex));
00203   if (!controllerData) return NS_ERROR_FAILURE;
00204 
00205   return controllerData->GetController(_retval);   // does the addref  
00206 }
00207 
00208 NS_IMETHODIMP
00209 nsXULControllers::AppendController(nsIController *controller)
00210 {
00211   // This assigns controller IDs starting at 1 so we can use 0 to test if an ID was obtained
00212   nsXULControllerData*  controllerData = new nsXULControllerData(++mCurControllerID, controller);
00213   if (!controllerData) return NS_ERROR_OUT_OF_MEMORY;
00214 
00215 #ifdef DEBUG
00216   PRBool appended =
00217 #endif
00218   mControllers.AppendElement((void *)controllerData);
00219   NS_ASSERTION(appended, "Appending controller failed");
00220   return NS_OK;
00221 }
00222 
00223 NS_IMETHODIMP
00224 nsXULControllers::RemoveController(nsIController *controller)
00225 {
00226   // first get the identity pointer
00227   nsCOMPtr<nsISupports> controllerSup(do_QueryInterface(controller));
00228   // then find it
00229   PRUint32 count = mControllers.Count();
00230   for (PRUint32 i = 0; i < count; i++)
00231   {
00232     nsXULControllerData*  controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(i));
00233     if (controllerData)
00234     {
00235       nsCOMPtr<nsIController> thisController;
00236       controllerData->GetController(getter_AddRefs(thisController));
00237       nsCOMPtr<nsISupports> thisControllerSup(do_QueryInterface(thisController)); // get identity
00238       if (thisControllerSup == controllerSup)
00239       {
00240         mControllers.RemoveElementAt(i);
00241         delete controllerData;
00242         return NS_OK;
00243       }
00244     }
00245   }
00246   return NS_ERROR_FAILURE;      // right thing to return if no controller found?
00247 }
00248     
00249 /* unsigned long getControllerId (in nsIController controller); */
00250 NS_IMETHODIMP
00251 nsXULControllers::GetControllerId(nsIController *controller, PRUint32 *_retval)
00252 {
00253   NS_ENSURE_ARG_POINTER(_retval);
00254 
00255   PRUint32 count = mControllers.Count();
00256   for (PRUint32 i = 0; i < count; i++)
00257   {
00258     nsXULControllerData*  controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(i));
00259     if (controllerData)
00260     {
00261       nsCOMPtr<nsIController> thisController;
00262       controllerData->GetController(getter_AddRefs(thisController));
00263       if (thisController.get() == controller)
00264       {
00265         *_retval = controllerData->GetControllerID();
00266         return NS_OK;
00267       }
00268     }
00269   }
00270   return NS_ERROR_FAILURE;  // none found
00271 }
00272 
00273 /* nsIController getControllerById (in unsigned long controllerID); */
00274 NS_IMETHODIMP
00275 nsXULControllers::GetControllerById(PRUint32 controllerID, nsIController **_retval)
00276 {
00277   NS_ENSURE_ARG_POINTER(_retval);
00278     
00279   PRUint32 count = mControllers.Count();
00280   for (PRUint32 i = 0; i < count; i++)
00281   {
00282     nsXULControllerData*  controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(i));
00283     if (controllerData && controllerData->GetControllerID() == controllerID)
00284     {
00285       return controllerData->GetController(_retval);
00286     }
00287   }
00288   return NS_ERROR_FAILURE;  // none found
00289 }
00290 
00291 NS_IMETHODIMP
00292 nsXULControllers::GetControllerCount(PRUint32 *_retval)
00293 {
00294   NS_ENSURE_ARG_POINTER(_retval);
00295   *_retval = mControllers.Count();
00296   return NS_OK;
00297 }
00298 
00299 // nsISecurityCheckedComponent implementation
00300 
00301 static char* cloneAllAccess()
00302 {
00303   static const char allAccess[] = "AllAccess";
00304   return (char*)nsMemory::Clone(allAccess, sizeof(allAccess));
00305 }
00306 
00307 static char* cloneUniversalXPConnect()
00308 {
00309   static const char universalXPConnect[] = "UniversalXPConnect";
00310   return (char*)nsMemory::Clone(universalXPConnect, sizeof(universalXPConnect));
00311 }
00312 
00313 NS_IMETHODIMP
00314 nsXULControllers::CanCreateWrapper(const nsIID * iid, char **_retval)
00315 {
00316   *_retval = cloneAllAccess();
00317   return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
00318 }
00319 
00320 NS_IMETHODIMP
00321 nsXULControllers::CanCallMethod(const nsIID * iid, const PRUnichar *methodName,
00322                                 char **_retval)
00323 {
00324   // OK if you're cool enough
00325   *_retval = cloneUniversalXPConnect();
00326   return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
00327 }
00328 
00329 NS_IMETHODIMP
00330 nsXULControllers::CanGetProperty(const nsIID * iid,
00331                                  const PRUnichar *propertyName,
00332                                  char **_retval)
00333 {
00334   // OK if you're cool enough
00335   *_retval = cloneUniversalXPConnect();
00336   return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
00337 }
00338 
00339 
00340 NS_IMETHODIMP
00341 nsXULControllers::CanSetProperty(const nsIID * iid,
00342                                  const PRUnichar *propertyName,
00343                                  char **_retval)
00344 {
00345   // OK if you're cool enough
00346   *_retval = cloneUniversalXPConnect();
00347   return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
00348 }