From 3293dd7eac3b1b76054700c1027ea8458ea1a766 Mon Sep 17 00:00:00 2001 From: "sfraser%netscape.com" Date: Fri, 30 Mar 2001 03:20:56 +0000 Subject: [PATCH] Fix for bug 72578 -- add ability to retrieve controllers by ID from an nsIControllers. r=kin, sr=hyatt --- .../xul/document/public/nsIControllers.idl | 14 +- content/xul/document/src/nsXULControllers.cpp | 155 +++++++++++++----- content/xul/document/src/nsXULControllers.h | 34 +++- 3 files changed, 161 insertions(+), 42 deletions(-) diff --git a/content/xul/document/public/nsIControllers.idl b/content/xul/document/public/nsIControllers.idl index 0d748dd8b535..fa7e2cd2320b 100644 --- a/content/xul/document/public/nsIControllers.idl +++ b/content/xul/document/public/nsIControllers.idl @@ -22,10 +22,12 @@ #include "nsISecurityCheckedComponent.idl" #include "nsIController.idl" + interface nsIDOMXULCommandDispatcher; [scriptable, uuid(A5ED3A01-7CC7-11d3-BF87-00105A1B0627)] -interface nsIControllers : nsISecurityCheckedComponent { +interface nsIControllers : nsISecurityCheckedComponent +{ attribute nsIDOMXULCommandDispatcher commandDispatcher; nsIController getControllerForCommand(in wstring command); @@ -37,5 +39,15 @@ interface nsIControllers : nsISecurityCheckedComponent { void appendController(in nsIController controller); void removeController(in nsIController controller); + /* + Return an ID for this controller which is unique to this + nsIControllers. + */ + unsigned long getControllerId(in nsIController controller); + /* + Get the controller specified by the given ID. + */ + nsIController getControlleryById(in unsigned long controllerID); + unsigned long getControllerCount(); }; diff --git a/content/xul/document/src/nsXULControllers.cpp b/content/xul/document/src/nsXULControllers.cpp index a2aedeca330a..e9b8df339b6d 100644 --- a/content/xul/document/src/nsXULControllers.cpp +++ b/content/xul/document/src/nsXULControllers.cpp @@ -31,6 +31,8 @@ */ +#include "nsString.h" + #include "nsIControllers.h" #include "nsIDOMElement.h" #include "nsIDOMXULCommandDispatcher.h" @@ -39,12 +41,28 @@ //---------------------------------------------------------------------- nsXULControllers::nsXULControllers() +: mCurControllerID(0) { NS_INIT_REFCNT(); } nsXULControllers::~nsXULControllers(void) { + DeleteControllers(); +} + +void +nsXULControllers::DeleteControllers() +{ + PRUint32 count = mControllers.Count(); + for (PRUint32 i = 0; i < count; i++) + { + nsXULControllerData* controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(i)); + if (controllerData) + delete controllerData; // releases the nsIController + } + + mControllers.Clear(); } @@ -87,53 +105,59 @@ nsXULControllers::SetCommandDispatcher(nsIDOMXULCommandDispatcher* aCommandDispa } NS_IMETHODIMP -nsXULControllers::GetControllerForCommand(const PRUnichar *command, nsIController** _retval) +nsXULControllers::GetControllerForCommand(const PRUnichar *aCommand, nsIController** _retval) { + NS_ENSURE_ARG_POINTER(_retval); *_retval = nsnull; - if(!mControllers) - return NS_OK; - PRUint32 count; - mControllers->Count(&count); - for(PRUint32 i=0; i < count; i++) { + PRUint32 count = mControllers.Count(); + for (PRUint32 i=0; i < count; i++) + { + nsXULControllerData* controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(i)); + if (controllerData) + { nsCOMPtr controller; - mControllers->QueryElementAt(i, NS_GET_IID(nsIController), getter_AddRefs(controller)); - if( controller ) { + controllerData->GetController(getter_AddRefs(controller)); + if (controller) + { PRBool supportsCommand; - controller->SupportsCommand(command, &supportsCommand); - if(supportsCommand) { + controller->SupportsCommand(aCommand, &supportsCommand); + if (supportsCommand) { *_retval = controller; NS_ADDREF(*_retval); return NS_OK; } } } + } + return NS_OK; } NS_IMETHODIMP nsXULControllers::InsertControllerAt(PRUint32 index, nsIController *controller) { - if(! mControllers ) { - nsresult rv; - rv = NS_NewISupportsArray(getter_AddRefs(mControllers)); - if (NS_FAILED(rv)) return rv; - } - - mControllers->InsertElementAt(controller, index); + nsXULControllerData* controllerData = new nsXULControllerData(mCurControllerID++, controller); + if (!controllerData) return NS_ERROR_OUT_OF_MEMORY; + PRBool inserted = mControllers.InsertElementAt((void *)controllerData, index); + NS_ASSERTION(inserted, "Insertion of controller failed"); return NS_OK; } NS_IMETHODIMP nsXULControllers::RemoveControllerAt(PRUint32 index, nsIController **_retval) { - if(mControllers) { - nsresult rv = mControllers->QueryElementAt(index, NS_GET_IID(nsIController), (void**)_retval); - if (NS_SUCCEEDED(rv) && *_retval) - mControllers->RemoveElementAt(index); - } else + NS_ENSURE_ARG_POINTER(_retval); *_retval = nsnull; + nsXULControllerData* controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(index)); + if (!controllerData) return NS_ERROR_FAILURE; + + PRBool removed = mControllers.RemoveElementAt(index); + NS_ASSERTION(removed, "Removal of controller failed"); + controllerData->GetController(getter_AddRefs(_retval)); + delete controllerData; + return NS_OK; } @@ -141,44 +165,95 @@ nsXULControllers::RemoveControllerAt(PRUint32 index, nsIController **_retval) NS_IMETHODIMP nsXULControllers::GetControllerAt(PRUint32 index, nsIController **_retval) { - if(mControllers) - mControllers->QueryElementAt(index, NS_GET_IID(nsIController), (void**)_retval); - else + NS_ENSURE_ARG_POINTER(_retval); *_retval = nsnull; - return NS_OK; + + nsXULControllerData* controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(index)); + if (!controllerData) return NS_ERROR_FAILURE; + + return controllerData->GetController(_retval); // does the addref } NS_IMETHODIMP nsXULControllers::AppendController(nsIController *controller) { - if(! mControllers ) { - nsresult rv; - rv = NS_NewISupportsArray(getter_AddRefs(mControllers)); - if (NS_FAILED(rv)) return rv; - } - - mControllers->AppendElement(controller); + nsXULControllerData* controllerData = new nsXULControllerData(mCurControllerID++, controller); + if (!controllerData) return NS_ERROR_OUT_OF_MEMORY; + PRBool appended = mControllers.AppendElement((void *)controllerData); + NS_ASSERTION(appended, "Appending controller failed"); return NS_OK; } NS_IMETHODIMP nsXULControllers::RemoveController(nsIController *controller) { - if(mControllers) { - nsCOMPtr supports = do_QueryInterface(controller); - mControllers->RemoveElement(supports); + // first find it + PRUint32 count = mControllers.Count(); + for (PRUint32 i = 0; i < count; i++) + { + nsXULControllerData* controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(i)); + if (controllerData) + { + nsCOMPtr thisController; + controllerData->GetController(getter_AddRefs(thisController)); + if (thisController.get() == controller) + { + mControllers.RemoveElementAt(i); + delete controllerData; + return NS_OK; + } } + } + return NS_ERROR_FAILURE; // right thing to return if no controller found? +} +/* unsigned long getControllerId (in nsIController controller); */ +NS_IMETHODIMP +nsXULControllers::GetControllerId(nsIController *controller, PRUint32 *_retval) +{ + NS_ENSURE_ARG_POINTER(_retval); + + PRUint32 count = mControllers.Count(); + for (PRUint32 i = 0; i < count; i++) + { + nsXULControllerData* controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(i)); + if (controllerData) + { + nsCOMPtr thisController; + controllerData->GetController(getter_AddRefs(thisController)); + if (thisController.get() == controller) + { + *_retval = controllerData->GetControllerID(); return NS_OK; + } + } + } + return NS_ERROR_FAILURE; // none found +} + +/* nsIController getControlleryById (in unsigned long controllerID); */ +NS_IMETHODIMP +nsXULControllers::GetControlleryById(PRUint32 controllerID, nsIController **_retval) +{ + NS_ENSURE_ARG_POINTER(_retval); + + PRUint32 count = mControllers.Count(); + for (PRUint32 i = 0; i < count; i++) + { + nsXULControllerData* controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(i)); + if (controllerData && controllerData->GetControllerID() == controllerID) + { + return controllerData->GetController(_retval); + } + } + return NS_ERROR_FAILURE; // none found } NS_IMETHODIMP nsXULControllers::GetControllerCount(PRUint32 *_retval) { - *_retval = 0; - if(mControllers) - mControllers->Count(_retval); - + NS_ENSURE_ARG_POINTER(_retval); + *_retval = mControllers.Count(); return NS_OK; } diff --git a/content/xul/document/src/nsXULControllers.h b/content/xul/document/src/nsXULControllers.h index 3e57a699f932..736881637cf9 100644 --- a/content/xul/document/src/nsXULControllers.h +++ b/content/xul/document/src/nsXULControllers.h @@ -33,12 +33,41 @@ #define nsXULControllers_h__ #include "nsCOMPtr.h" +#include "nsVoidArray.h" #include "nsWeakPtr.h" #include "nsIControllers.h" #include "nsISupportsArray.h" class nsIDOMXULCommandDispatcher; + +/* non-XPCOM class for holding controllers and their IDs */ +class nsXULControllerData +{ +public: + nsXULControllerData(PRUint32 inControllerID, nsIController* inController) + : mControllerID(inControllerID) + , mController(inController) + { + } + + ~nsXULControllerData() {} + + PRUint32 GetControllerID() { return mControllerID; } + + nsresult GetController(nsIController **outController) + { + NS_IF_ADDREF(*outController = mController); + return NS_OK; + } + +protected: + + PRUint32 mControllerID; + nsCOMPtr mController; +}; + + class nsXULControllers : public nsIControllers { public: @@ -53,8 +82,11 @@ protected: nsXULControllers(); virtual ~nsXULControllers(void); - nsCOMPtr mControllers; + void DeleteControllers(); + + nsVoidArray mControllers; nsWeakPtr mCommandDispatcher; + PRUint32 mCurControllerID; };