Line data Source code
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 "nsString.h"
14 :
15 : #include "nsIControllers.h"
16 : #include "nsIDOMElement.h"
17 : #include "nsXULControllers.h"
18 : #include "nsIController.h"
19 :
20 : //----------------------------------------------------------------------
21 :
22 5 : nsXULControllers::nsXULControllers()
23 5 : : mCurControllerID(0)
24 : {
25 5 : }
26 :
27 0 : nsXULControllers::~nsXULControllers(void)
28 : {
29 0 : DeleteControllers();
30 0 : }
31 :
32 : void
33 0 : nsXULControllers::DeleteControllers()
34 : {
35 0 : uint32_t count = mControllers.Length();
36 0 : for (uint32_t i = 0; i < count; i++)
37 : {
38 0 : nsXULControllerData* controllerData = mControllers.ElementAt(i);
39 0 : delete controllerData; // releases the nsIController
40 : }
41 :
42 0 : mControllers.Clear();
43 0 : }
44 :
45 :
46 : nsresult
47 5 : NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult)
48 : {
49 5 : NS_PRECONDITION(aOuter == nullptr, "no aggregation");
50 5 : if (aOuter)
51 0 : return NS_ERROR_NO_AGGREGATION;
52 :
53 5 : nsXULControllers* controllers = new nsXULControllers();
54 : nsresult rv;
55 5 : NS_ADDREF(controllers);
56 5 : rv = controllers->QueryInterface(aIID, aResult);
57 5 : NS_RELEASE(controllers);
58 5 : return rv;
59 : }
60 :
61 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULControllers)
62 :
63 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULControllers)
64 0 : tmp->DeleteControllers();
65 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
66 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULControllers)
67 : {
68 0 : uint32_t i, count = tmp->mControllers.Length();
69 0 : for (i = 0; i < count; ++i) {
70 0 : nsXULControllerData* controllerData = tmp->mControllers[i];
71 0 : if (controllerData) {
72 0 : cb.NoteXPCOMChild(controllerData->mController);
73 : }
74 : }
75 : }
76 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
77 :
78 86 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULControllers)
79 81 : NS_INTERFACE_MAP_ENTRY(nsIControllers)
80 24 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIControllers)
81 20 : NS_INTERFACE_MAP_END
82 :
83 99 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULControllers)
84 88 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULControllers)
85 :
86 : NS_IMETHODIMP
87 22 : nsXULControllers::GetControllerForCommand(const char *aCommand, nsIController** _retval)
88 : {
89 22 : NS_ENSURE_ARG_POINTER(_retval);
90 22 : *_retval = nullptr;
91 :
92 22 : uint32_t count = mControllers.Length();
93 40 : for (uint32_t i=0; i < count; i++)
94 : {
95 22 : nsXULControllerData* controllerData = mControllers.ElementAt(i);
96 22 : if (controllerData)
97 : {
98 40 : nsCOMPtr<nsIController> controller;
99 22 : controllerData->GetController(getter_AddRefs(controller));
100 22 : if (controller)
101 : {
102 : bool supportsCommand;
103 22 : controller->SupportsCommand(aCommand, &supportsCommand);
104 22 : if (supportsCommand) {
105 4 : controller.forget(_retval);
106 4 : return NS_OK;
107 : }
108 : }
109 : }
110 : }
111 :
112 18 : return NS_OK;
113 : }
114 :
115 : NS_IMETHODIMP
116 5 : nsXULControllers::InsertControllerAt(uint32_t aIndex, nsIController *controller)
117 : {
118 10 : nsXULControllerData* controllerData = new nsXULControllerData(++mCurControllerID, controller);
119 : #ifdef DEBUG
120 : nsXULControllerData** inserted =
121 : #endif
122 5 : mControllers.InsertElementAt(aIndex, controllerData);
123 5 : NS_ASSERTION(inserted != nullptr, "Insertion of controller failed");
124 5 : return NS_OK;
125 : }
126 :
127 : NS_IMETHODIMP
128 0 : nsXULControllers::RemoveControllerAt(uint32_t aIndex, nsIController **_retval)
129 : {
130 0 : NS_ENSURE_ARG_POINTER(_retval);
131 0 : *_retval = nullptr;
132 :
133 0 : nsXULControllerData* controllerData = mControllers.SafeElementAt(aIndex);
134 0 : if (!controllerData) return NS_ERROR_FAILURE;
135 :
136 0 : mControllers.RemoveElementAt(aIndex);
137 :
138 0 : controllerData->GetController(_retval);
139 0 : delete controllerData;
140 :
141 0 : return NS_OK;
142 : }
143 :
144 :
145 : NS_IMETHODIMP
146 17 : nsXULControllers::GetControllerAt(uint32_t aIndex, nsIController **_retval)
147 : {
148 17 : NS_ENSURE_ARG_POINTER(_retval);
149 17 : *_retval = nullptr;
150 :
151 17 : nsXULControllerData* controllerData = mControllers.SafeElementAt(aIndex);
152 17 : if (!controllerData) return NS_ERROR_FAILURE;
153 :
154 17 : return controllerData->GetController(_retval); // does the addref
155 : }
156 :
157 : NS_IMETHODIMP
158 5 : nsXULControllers::AppendController(nsIController *controller)
159 : {
160 : // This assigns controller IDs starting at 1 so we can use 0 to test if an ID was obtained
161 10 : nsXULControllerData* controllerData = new nsXULControllerData(++mCurControllerID, controller);
162 :
163 : #ifdef DEBUG
164 : nsXULControllerData** appended =
165 : #endif
166 5 : mControllers.AppendElement(controllerData);
167 5 : NS_ASSERTION(appended != nullptr, "Appending controller failed");
168 5 : return NS_OK;
169 : }
170 :
171 : NS_IMETHODIMP
172 0 : nsXULControllers::RemoveController(nsIController *controller)
173 : {
174 : // first get the identity pointer
175 0 : nsCOMPtr<nsISupports> controllerSup(do_QueryInterface(controller));
176 : // then find it
177 0 : uint32_t count = mControllers.Length();
178 0 : for (uint32_t i = 0; i < count; i++)
179 : {
180 0 : nsXULControllerData* controllerData = mControllers.ElementAt(i);
181 0 : if (controllerData)
182 : {
183 0 : nsCOMPtr<nsIController> thisController;
184 0 : controllerData->GetController(getter_AddRefs(thisController));
185 0 : nsCOMPtr<nsISupports> thisControllerSup(do_QueryInterface(thisController)); // get identity
186 0 : if (thisControllerSup == controllerSup)
187 : {
188 0 : mControllers.RemoveElementAt(i);
189 0 : delete controllerData;
190 0 : return NS_OK;
191 : }
192 : }
193 : }
194 0 : return NS_ERROR_FAILURE; // right thing to return if no controller found?
195 : }
196 :
197 : NS_IMETHODIMP
198 0 : nsXULControllers::GetControllerId(nsIController *controller, uint32_t *_retval)
199 : {
200 0 : NS_ENSURE_ARG_POINTER(_retval);
201 :
202 0 : uint32_t count = mControllers.Length();
203 0 : for (uint32_t i = 0; i < count; i++)
204 : {
205 0 : nsXULControllerData* controllerData = mControllers.ElementAt(i);
206 0 : if (controllerData)
207 : {
208 0 : nsCOMPtr<nsIController> thisController;
209 0 : controllerData->GetController(getter_AddRefs(thisController));
210 0 : if (thisController.get() == controller)
211 : {
212 0 : *_retval = controllerData->GetControllerID();
213 0 : return NS_OK;
214 : }
215 : }
216 : }
217 0 : return NS_ERROR_FAILURE; // none found
218 : }
219 :
220 : NS_IMETHODIMP
221 0 : nsXULControllers::GetControllerById(uint32_t controllerID, nsIController **_retval)
222 : {
223 0 : NS_ENSURE_ARG_POINTER(_retval);
224 :
225 0 : uint32_t count = mControllers.Length();
226 0 : for (uint32_t i = 0; i < count; i++)
227 : {
228 0 : nsXULControllerData* controllerData = mControllers.ElementAt(i);
229 0 : if (controllerData && controllerData->GetControllerID() == controllerID)
230 : {
231 0 : return controllerData->GetController(_retval);
232 : }
233 : }
234 0 : return NS_ERROR_FAILURE; // none found
235 : }
236 :
237 : NS_IMETHODIMP
238 8 : nsXULControllers::GetControllerCount(uint32_t *_retval)
239 : {
240 8 : NS_ENSURE_ARG_POINTER(_retval);
241 8 : *_retval = mControllers.Length();
242 8 : return NS_OK;
243 : }
244 :
|