nsXULControllers.cpp (6731B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /* 7 8 This file provides the implementation for the XUL "controllers" 9 object. 10 11 */ 12 13 #include "nsXULControllers.h" 14 15 #include "mozilla/RefPtr.h" 16 #include "nsIController.h" 17 #include "nsIControllers.h" 18 #include "nsString.h" 19 20 //---------------------------------------------------------------------- 21 22 nsXULControllerData::nsXULControllerData(uint32_t inControllerID, 23 nsIController* inController) 24 : mControllerID(inControllerID), mController(inController) {} 25 26 nsresult nsXULControllerData::GetController(nsIController** outController) { 27 NS_IF_ADDREF(*outController = mController); 28 return NS_OK; 29 } 30 31 nsXULControllers::nsXULControllers() : mCurControllerID(0) {} 32 33 nsXULControllers::~nsXULControllers(void) { DeleteControllers(); } 34 35 void nsXULControllers::DeleteControllers() { 36 uint32_t count = mControllers.Length(); 37 for (uint32_t i = 0; i < count; i++) { 38 nsXULControllerData* controllerData = mControllers.ElementAt(i); 39 delete controllerData; // releases the nsIController 40 } 41 42 mControllers.Clear(); 43 } 44 45 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULControllers) 46 47 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULControllers) 48 tmp->DeleteControllers(); 49 NS_IMPL_CYCLE_COLLECTION_UNLINK_END 50 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULControllers) 51 { 52 uint32_t i, count = tmp->mControllers.Length(); 53 for (i = 0; i < count; ++i) { 54 nsXULControllerData* controllerData = tmp->mControllers[i]; 55 if (controllerData) { 56 cb.NoteXPCOMChild(controllerData->mController); 57 } 58 } 59 } 60 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 61 62 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULControllers) 63 NS_INTERFACE_MAP_ENTRY(nsIControllers) 64 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIControllers) 65 NS_INTERFACE_MAP_END 66 67 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULControllers) 68 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULControllers) 69 70 NS_IMETHODIMP 71 nsXULControllers::GetControllerForCommand(const char* aCommand, 72 nsIController** _retval) { 73 NS_ENSURE_ARG_POINTER(_retval); 74 *_retval = nullptr; 75 76 uint32_t count = mControllers.Length(); 77 for (uint32_t i = 0; i < count; i++) { 78 nsXULControllerData* controllerData = mControllers.ElementAt(i); 79 if (controllerData) { 80 nsCOMPtr<nsIController> controller; 81 controllerData->GetController(getter_AddRefs(controller)); 82 if (controller) { 83 bool supportsCommand; 84 controller->SupportsCommand(aCommand, &supportsCommand); 85 if (supportsCommand) { 86 controller.forget(_retval); 87 return NS_OK; 88 } 89 } 90 } 91 } 92 93 return NS_OK; 94 } 95 96 NS_IMETHODIMP 97 nsXULControllers::InsertControllerAt(uint32_t aIndex, 98 nsIController* controller) { 99 nsXULControllerData* controllerData = 100 new nsXULControllerData(++mCurControllerID, controller); 101 #ifdef DEBUG 102 nsXULControllerData** inserted = 103 #endif 104 mControllers.InsertElementAt(aIndex, controllerData); 105 NS_ASSERTION(inserted != nullptr, "Insertion of controller failed"); 106 return NS_OK; 107 } 108 109 NS_IMETHODIMP 110 nsXULControllers::RemoveControllerAt(uint32_t aIndex, nsIController** _retval) { 111 NS_ENSURE_ARG_POINTER(_retval); 112 *_retval = nullptr; 113 114 nsXULControllerData* controllerData = mControllers.SafeElementAt(aIndex); 115 if (!controllerData) return NS_ERROR_FAILURE; 116 117 mControllers.RemoveElementAt(aIndex); 118 119 controllerData->GetController(_retval); 120 delete controllerData; 121 122 return NS_OK; 123 } 124 125 NS_IMETHODIMP 126 nsXULControllers::GetControllerAt(uint32_t aIndex, nsIController** _retval) { 127 NS_ENSURE_ARG_POINTER(_retval); 128 *_retval = nullptr; 129 130 nsXULControllerData* controllerData = mControllers.SafeElementAt(aIndex); 131 if (!controllerData) return NS_ERROR_FAILURE; 132 133 return controllerData->GetController(_retval); // does the addref 134 } 135 136 NS_IMETHODIMP 137 nsXULControllers::AppendController(nsIController* controller) { 138 // This assigns controller IDs starting at 1 so we can use 0 to test if an ID 139 // was obtained 140 nsXULControllerData* controllerData = 141 new nsXULControllerData(++mCurControllerID, controller); 142 143 #ifdef DEBUG 144 nsXULControllerData** appended = 145 #endif 146 mControllers.AppendElement(controllerData); 147 NS_ASSERTION(appended != nullptr, "Appending controller failed"); 148 return NS_OK; 149 } 150 151 NS_IMETHODIMP 152 nsXULControllers::RemoveController(nsIController* controller) { 153 // first get the identity pointer 154 nsCOMPtr<nsISupports> controllerSup(do_QueryInterface(controller)); 155 // then find it 156 uint32_t count = mControllers.Length(); 157 for (uint32_t i = 0; i < count; i++) { 158 nsXULControllerData* controllerData = mControllers.ElementAt(i); 159 if (controllerData) { 160 nsCOMPtr<nsIController> thisController; 161 controllerData->GetController(getter_AddRefs(thisController)); 162 nsCOMPtr<nsISupports> thisControllerSup( 163 do_QueryInterface(thisController)); // get identity 164 if (thisControllerSup == controllerSup) { 165 mControllers.RemoveElementAt(i); 166 delete controllerData; 167 return NS_OK; 168 } 169 } 170 } 171 return NS_ERROR_FAILURE; // right thing to return if no controller found? 172 } 173 174 NS_IMETHODIMP 175 nsXULControllers::GetControllerId(nsIController* controller, 176 uint32_t* _retval) { 177 NS_ENSURE_ARG_POINTER(_retval); 178 179 uint32_t count = mControllers.Length(); 180 for (uint32_t i = 0; i < count; i++) { 181 nsXULControllerData* controllerData = mControllers.ElementAt(i); 182 if (controllerData) { 183 nsCOMPtr<nsIController> thisController; 184 controllerData->GetController(getter_AddRefs(thisController)); 185 if (thisController.get() == controller) { 186 *_retval = controllerData->GetControllerID(); 187 return NS_OK; 188 } 189 } 190 } 191 return NS_ERROR_FAILURE; // none found 192 } 193 194 NS_IMETHODIMP 195 nsXULControllers::GetControllerById(uint32_t controllerID, 196 nsIController** _retval) { 197 NS_ENSURE_ARG_POINTER(_retval); 198 199 uint32_t count = mControllers.Length(); 200 for (uint32_t i = 0; i < count; i++) { 201 nsXULControllerData* controllerData = mControllers.ElementAt(i); 202 if (controllerData && controllerData->GetControllerID() == controllerID) { 203 return controllerData->GetController(_retval); 204 } 205 } 206 return NS_ERROR_FAILURE; // none found 207 } 208 209 NS_IMETHODIMP 210 nsXULControllers::GetControllerCount(uint32_t* _retval) { 211 NS_ENSURE_ARG_POINTER(_retval); 212 *_retval = mControllers.Length(); 213 return NS_OK; 214 }