Back to index

lightning-sunbird  0.9+nobinonly
nsCommandGroup.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  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsString.h"
00039 #include "nsReadableUtils.h"
00040 #include "nsVoidArray.h"
00041 #include "nsISimpleEnumerator.h"
00042 #include "nsXPCOM.h"
00043 #include "nsSupportsPrimitives.h"
00044 #include "nsIComponentManager.h"
00045 
00046 #include "nsCommandGroup.h"
00047 #include "nsIControllerCommand.h"
00048 #include "nsCRT.h"
00049 
00050 
00051 class nsGroupsEnumerator : public nsISimpleEnumerator
00052 {
00053 public:
00054               nsGroupsEnumerator(nsHashtable& inHashTable);
00055   virtual     ~nsGroupsEnumerator();
00056 
00057   NS_DECL_ISUPPORTS
00058   NS_DECL_NSISIMPLEENUMERATOR
00059 
00060 protected:
00061 
00062   static PRBool PR_CALLBACK HashEnum(nsHashKey *aKey, void *aData, void* aClosure);
00063 
00064   nsresult      Initialize();
00065 
00066 protected:
00067 
00068   nsHashtable&  mHashTable;
00069   PRInt32       mIndex;
00070   char **       mGroupNames;        // array of pointers to PRUnichar* in the hash table
00071   PRBool        mInitted;
00072   
00073 };
00074 
00075 /* Implementation file */
00076 NS_IMPL_ISUPPORTS1(nsGroupsEnumerator, nsISimpleEnumerator)
00077 
00078 nsGroupsEnumerator::nsGroupsEnumerator(nsHashtable& inHashTable)
00079 : mHashTable(inHashTable)
00080 , mIndex(-1)
00081 , mGroupNames(nsnull)
00082 , mInitted(PR_FALSE)
00083 {
00084   /* member initializers and constructor code */
00085 }
00086 
00087 nsGroupsEnumerator::~nsGroupsEnumerator()
00088 {
00089   delete [] mGroupNames;    // ok on null pointer
00090 }
00091 
00092 /* boolean hasMoreElements (); */
00093 NS_IMETHODIMP
00094 nsGroupsEnumerator::HasMoreElements(PRBool *_retval)
00095 {
00096   nsresult  rv = NS_OK;
00097   
00098   NS_ENSURE_ARG_POINTER(_retval);
00099 
00100   if (!mInitted) {
00101     rv = Initialize();
00102     if (NS_FAILED(rv)) return rv;
00103   }
00104   
00105   *_retval = (mIndex < mHashTable.Count() - 1); 
00106   return NS_OK;
00107 }
00108 
00109 /* nsISupports getNext (); */
00110 NS_IMETHODIMP
00111 nsGroupsEnumerator::GetNext(nsISupports **_retval)
00112 {
00113   nsresult  rv = NS_OK;
00114   
00115   NS_ENSURE_ARG_POINTER(_retval);
00116 
00117   if (!mInitted) {
00118     rv = Initialize();
00119     if (NS_FAILED(rv)) return rv;
00120   }
00121   
00122   mIndex ++;
00123   if (mIndex >= mHashTable.Count())
00124     return NS_ERROR_FAILURE;
00125 
00126   char *thisGroupName = mGroupNames[mIndex];
00127   
00128   nsCOMPtr<nsISupportsCString> supportsString = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
00129   if (NS_FAILED(rv)) return rv;
00130 
00131   supportsString->SetData(nsDependentCString(thisGroupName));
00132   return CallQueryInterface(supportsString, _retval);
00133 }
00134 
00135 /* static */
00136 /* return false to stop */
00137 PRBool
00138 nsGroupsEnumerator::HashEnum(nsHashKey *aKey, void *aData, void* aClosure)
00139 {
00140   nsGroupsEnumerator*   groupsEnum = NS_REINTERPRET_CAST(nsGroupsEnumerator *, aClosure);
00141   nsCStringKey*         stringKey = NS_STATIC_CAST(nsCStringKey*, aKey);
00142   
00143   groupsEnum->mGroupNames[groupsEnum->mIndex] = (char*)stringKey->GetString();
00144   groupsEnum->mIndex ++;
00145   return PR_TRUE;
00146 }
00147 
00148 nsresult
00149 nsGroupsEnumerator::Initialize()
00150 {
00151   if (mInitted) return NS_OK;
00152   
00153   mGroupNames = new char*[mHashTable.Count()];
00154   if (!mGroupNames) return NS_ERROR_OUT_OF_MEMORY;
00155   
00156   mIndex = 0; 
00157   mHashTable.Enumerate(HashEnum, (void*)this);
00158 
00159   mIndex = -1;
00160   mInitted = PR_TRUE;
00161   return NS_OK;
00162 }
00163 
00164 #if 0
00165 #pragma mark -
00166 #endif
00167 
00168 class nsNamedGroupEnumerator : public nsISimpleEnumerator
00169 {
00170 public:
00171               nsNamedGroupEnumerator(nsVoidArray* inArray);
00172   virtual     ~nsNamedGroupEnumerator();
00173 
00174   NS_DECL_ISUPPORTS
00175   NS_DECL_NSISIMPLEENUMERATOR
00176 
00177 protected:
00178 
00179   nsVoidArray*  mGroupArray;
00180   PRInt32       mIndex;
00181   
00182 };
00183 
00184 nsNamedGroupEnumerator::nsNamedGroupEnumerator(nsVoidArray* inArray)
00185 : mGroupArray(inArray)
00186 , mIndex(-1)
00187 {
00188 }
00189 
00190 nsNamedGroupEnumerator::~nsNamedGroupEnumerator()
00191 {
00192 }
00193 
00194 NS_IMPL_ISUPPORTS1(nsNamedGroupEnumerator, nsISimpleEnumerator)
00195 
00196 /* boolean hasMoreElements (); */
00197 NS_IMETHODIMP
00198 nsNamedGroupEnumerator::HasMoreElements(PRBool *_retval)
00199 {
00200   NS_ENSURE_ARG_POINTER(_retval);
00201   
00202   PRInt32   arrayLen = mGroupArray ? mGroupArray->Count() : 0;
00203   *_retval = (mIndex < arrayLen - 1); 
00204   return NS_OK;
00205 }
00206 
00207 /* nsISupports getNext (); */
00208 NS_IMETHODIMP
00209 nsNamedGroupEnumerator::GetNext(nsISupports **_retval)
00210 {
00211   NS_ENSURE_ARG_POINTER(_retval);
00212 
00213   if (!mGroupArray)
00214     return NS_ERROR_FAILURE;
00215 
00216   mIndex ++;
00217   if (mIndex >= mGroupArray->Count())
00218     return NS_ERROR_FAILURE;
00219     
00220   PRUnichar   *thisGroupName = (PRUnichar *)mGroupArray->ElementAt(mIndex);
00221   NS_ASSERTION(thisGroupName, "Bad Element in mGroupArray");
00222   
00223   nsresult rv;
00224   nsCOMPtr<nsISupportsString> supportsString = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
00225   if (NS_FAILED(rv)) return rv;
00226 
00227   supportsString->SetData(nsDependentString(thisGroupName));
00228   return CallQueryInterface(supportsString, _retval);
00229 }
00230 
00231 #if 0
00232 #pragma mark -
00233 #endif
00234 
00235 
00236 /* Implementation file */
00237 NS_IMPL_ISUPPORTS1(nsControllerCommandGroup, nsIControllerCommandGroup)
00238 
00239 nsControllerCommandGroup::nsControllerCommandGroup()
00240 {
00241 }
00242 
00243 nsControllerCommandGroup::~nsControllerCommandGroup()
00244 {
00245   ClearGroupsHash();
00246 }
00247 
00248 void
00249 nsControllerCommandGroup::ClearGroupsHash()
00250 {
00251     mGroupsHash.Reset(ClearEnumerator, (void *)this);
00252 }
00253 
00254 #if 0
00255 #pragma mark -
00256 #endif
00257 
00258 /* void addCommandToGroup (in DOMString aCommand, in DOMString aGroup); */
00259 NS_IMETHODIMP
00260 nsControllerCommandGroup::AddCommandToGroup(const char * aCommand, const char *aGroup)
00261 {
00262   nsCStringKey   groupKey(aGroup);  
00263   nsVoidArray*  commandList;  
00264   if ((commandList = (nsVoidArray *)mGroupsHash.Get(&groupKey)) == nsnull)
00265   {
00266     // make this list
00267     commandList = new nsAutoVoidArray;    
00268     mGroupsHash.Put(&groupKey, (void *)commandList);
00269   }
00270   // add the command to the list. Note that we're not checking for duplicates here
00271   char*  commandString = nsCRT::strdup(aCommand);     // we store allocated PRUnichar* in the array
00272   if (!commandString) return NS_ERROR_OUT_OF_MEMORY;
00273   
00274   PRBool      appended = commandList->AppendElement((void *)commandString);
00275   NS_ASSERTION(appended, "Append failed");
00276 
00277   return NS_OK;
00278 }
00279 
00280 /* void removeCommandFromGroup (in DOMString aCommand, in DOMString aGroup); */
00281 NS_IMETHODIMP
00282 nsControllerCommandGroup::RemoveCommandFromGroup(const char * aCommand, const char * aGroup)
00283 {
00284   nsCStringKey   groupKey(aGroup);
00285   nsVoidArray*  commandList = (nsVoidArray *)mGroupsHash.Get(&groupKey);
00286   if (!commandList) return NS_OK;     // no group
00287 
00288   PRInt32   numEntries = commandList->Count();
00289   for (PRInt32 i = 0; i < numEntries; i ++)
00290   {
00291     char*  commandString = (char*)commandList->ElementAt(i);
00292     if (!nsCRT::strcmp(aCommand,commandString))
00293     {
00294       commandList->RemoveElementAt(i);
00295       nsMemory::Free(commandString);
00296       break;
00297     }
00298   }
00299 
00300   return NS_OK;
00301 }
00302 
00303 /* boolean isCommandInGroup (in DOMString aCommand, in DOMString aGroup); */
00304 NS_IMETHODIMP
00305 nsControllerCommandGroup::IsCommandInGroup(const char * aCommand, const char * aGroup, PRBool *_retval)
00306 {
00307   NS_ENSURE_ARG_POINTER(_retval);
00308   *_retval = PR_FALSE;
00309   
00310   nsCStringKey   groupKey(aGroup);
00311   nsVoidArray*  commandList = (nsVoidArray *)mGroupsHash.Get(&groupKey);
00312   if (!commandList) return NS_OK;     // no group
00313   
00314   PRInt32   numEntries = commandList->Count();
00315   for (PRInt32 i = 0; i < numEntries; i ++)
00316   {
00317     char*  commandString = (char*)commandList->ElementAt(i);
00318     if (!nsCRT::strcmp(aCommand,commandString))
00319     {
00320       *_retval = PR_TRUE;
00321       break;
00322     }
00323   }
00324   return NS_OK;
00325 }
00326 
00327 /* nsISimpleEnumerator getGroupsEnumerator (); */
00328 NS_IMETHODIMP
00329 nsControllerCommandGroup::GetGroupsEnumerator(nsISimpleEnumerator **_retval)
00330 {
00331   nsGroupsEnumerator*   groupsEnum = new nsGroupsEnumerator(mGroupsHash);
00332   if (!groupsEnum) return NS_ERROR_OUT_OF_MEMORY;
00333 
00334   return groupsEnum->QueryInterface(NS_GET_IID(nsISimpleEnumerator), (void **)_retval);
00335 }
00336 
00337 /* nsISimpleEnumerator getEnumeratorForGroup (in DOMString aGroup); */
00338 NS_IMETHODIMP
00339 nsControllerCommandGroup::GetEnumeratorForGroup(const char * aGroup, nsISimpleEnumerator **_retval)
00340 {
00341   nsCStringKey   groupKey(aGroup);  
00342   nsVoidArray*  commandList = (nsVoidArray *)mGroupsHash.Get(&groupKey);    // may be null
00343 
00344   nsNamedGroupEnumerator*   theGroupEnum = new nsNamedGroupEnumerator(commandList);
00345   if (!theGroupEnum) return NS_ERROR_OUT_OF_MEMORY;
00346 
00347   return theGroupEnum->QueryInterface(NS_GET_IID(nsISimpleEnumerator), (void **)_retval);
00348 }
00349 
00350 #if 0
00351 #pragma mark -
00352 #endif
00353  
00354 PRBool nsControllerCommandGroup::ClearEnumerator(nsHashKey *aKey, void *aData, void* closure)
00355 {
00356   nsVoidArray*    commandList = (nsVoidArray *)aData;
00357   if (commandList)
00358   {  
00359     PRInt32   numEntries = commandList->Count();
00360     for (PRInt32 i = 0; i < numEntries; i ++)
00361     {
00362       char*  commandString = (char*)commandList->ElementAt(i);
00363       nsMemory::Free(commandString);
00364     }
00365     
00366     delete commandList;
00367   }
00368 
00369   return PR_TRUE;
00370 }