|
1 /* |
|
2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Generic fetch context to retrieve attributes |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <AknUtils.h> |
|
19 |
|
20 #include "glxattributecontext.h" |
|
21 #include "mglxmedialist.h" |
|
22 #include "glxerrormanager.h" |
|
23 #include "glxtracer.h" |
|
24 #include "glxlog.h" |
|
25 #include "glxlistutils.h" |
|
26 |
|
27 // Default granularity of items to request for |
|
28 const TUint KGlxAttributeContextDefaultGranularity = 200; |
|
29 |
|
30 const TInt KVisibleItemsCorrectionValue = 1; |
|
31 const TInt KVisibleItemsModFactor = 2; |
|
32 |
|
33 // ----------------------------------------------------------------------------- |
|
34 // Constructor |
|
35 // ----------------------------------------------------------------------------- |
|
36 // |
|
37 EXPORT_C CGlxAttributeContext::CGlxAttributeContext(MGlxMediaListIterator* aIterator) : |
|
38 iIterator(aIterator), |
|
39 iGranularity(KGlxAttributeContextDefaultGranularity) |
|
40 { |
|
41 TRACER("CGlxAttributeContext::Default Constructor"); |
|
42 |
|
43 __ASSERT_DEBUG(aIterator, Panic(EGlxPanicNullPointer)); |
|
44 } |
|
45 |
|
46 // ----------------------------------------------------------------------------- |
|
47 // Destructor |
|
48 // ----------------------------------------------------------------------------- |
|
49 // |
|
50 EXPORT_C CGlxAttributeContext::~CGlxAttributeContext() |
|
51 { |
|
52 TRACER("CGlxAttributeContext:: Destructor"); |
|
53 |
|
54 iAttributes.Close(); |
|
55 } |
|
56 |
|
57 // ----------------------------------------------------------------------------- |
|
58 // Adds an attribute to be retrieved for all items |
|
59 // ----------------------------------------------------------------------------- |
|
60 // |
|
61 EXPORT_C void CGlxAttributeContext::AddAttributeL(const TMPXAttribute& aAttribute) |
|
62 { |
|
63 TRACER("CGlxAttributeContext::AddAttributeL"); |
|
64 |
|
65 // Check that the attribute is not added twice |
|
66 TIdentityRelation<TMPXAttribute> match (&TMPXAttribute::Match); |
|
67 TInt index = iAttributes.Find(aAttribute, match); |
|
68 |
|
69 // Add the attribute |
|
70 if (KErrNotFound == index) |
|
71 { |
|
72 iAttributes.AppendL(aAttribute); |
|
73 } |
|
74 } |
|
75 |
|
76 // ----------------------------------------------------------------------------- |
|
77 // Removes an attribute from the "retrieval instructions" |
|
78 // ----------------------------------------------------------------------------- |
|
79 // |
|
80 EXPORT_C void CGlxAttributeContext::RemoveAttribute(const TMPXAttribute& aAttribute) |
|
81 { |
|
82 TRACER("CGlxAttributeContext::RemoveAttribute"); |
|
83 |
|
84 // Check that the attribute to be removed exists |
|
85 TIdentityRelation<TMPXAttribute> match (&TMPXAttribute::Match); |
|
86 TInt index = iAttributes.Find(aAttribute, match); |
|
87 |
|
88 // Remove the attribute |
|
89 if (KErrNotFound != index) |
|
90 { |
|
91 iAttributes.Remove(index); |
|
92 } |
|
93 } |
|
94 |
|
95 // ----------------------------------------------------------------------------- |
|
96 // CGlxDefaultAttributeContext::AttributeCount |
|
97 // ----------------------------------------------------------------------------- |
|
98 // |
|
99 EXPORT_C TInt CGlxAttributeContext::AttributeCount() |
|
100 { |
|
101 TRACER("CGlxAttributeContext::AttributeCount"); |
|
102 |
|
103 return iAttributes.Count(); |
|
104 } |
|
105 |
|
106 // ----------------------------------------------------------------------------- |
|
107 // Sets granularity of the item index array returned from AttributeRequestL |
|
108 // ----------------------------------------------------------------------------- |
|
109 EXPORT_C void CGlxAttributeContext::SetGranularity(TUint aGranularity) |
|
110 { |
|
111 TRACER("CGlxAttributeContext::SetGranularity"); |
|
112 |
|
113 iGranularity = aGranularity; |
|
114 } |
|
115 |
|
116 // ----------------------------------------------------------------------------- |
|
117 // Get attributes request for an item |
|
118 // From MGlxFetchContext |
|
119 // ----------------------------------------------------------------------------- |
|
120 // |
|
121 TInt CGlxAttributeContext::AttributeRequestL(const MGlxMediaList* aList, |
|
122 RArray<TInt>& aItemIndices, RArray<TMPXAttribute>& aAttributes, |
|
123 CMPXAttributeSpecs*& /*aDetailedSpecs*/) const |
|
124 { |
|
125 TRACER("CGlxAttributeContext::AttributeRequestL"); |
|
126 |
|
127 TInt itemCount = aList->Count(); |
|
128 if (0 == itemCount || !iIterator) |
|
129 { |
|
130 return 0; |
|
131 } |
|
132 |
|
133 // Check through the items in the order defined by the iterator |
|
134 iIterator->SetToFirst(aList); |
|
135 |
|
136 // Loop until iterator does not give any more indexes or granularity reached |
|
137 TInt index = KErrNotFound; |
|
138 TInt error = KErrNone; |
|
139 TBool firstItem = ETrue; |
|
140 TInt defaultVisItems = GlxListUtils::VisibleItemsGranularityL(); |
|
141 if (defaultVisItems%KVisibleItemsModFactor == 0) |
|
142 { |
|
143 defaultVisItems += KVisibleItemsCorrectionValue; |
|
144 } |
|
145 |
|
146 while ((KErrNotFound != (index = (*iIterator)++)) && (aItemIndices.Count() < iGranularity) && (KErrNone == error)) |
|
147 { |
|
148 // Check if this item is lacking attributes |
|
149 TBool attributesAdded = AddItemAttributesL(index, aList, aAttributes, error, firstItem); |
|
150 if (attributesAdded) |
|
151 { |
|
152 aItemIndices.AppendL(index); |
|
153 GLX_DEBUG3("CGlxAttributeContext::AttributeRequestL() index=%d, Media Id=%d", |
|
154 index, aList->Item(index).Id().Value()); |
|
155 firstItem = EFalse; |
|
156 |
|
157 // Fetch the visible items attrib first |
|
158 if (aItemIndices[0] == (aList->VisibleWindowIndex()+ (defaultVisItems/2)) |
|
159 && aItemIndices.Count() == defaultVisItems) |
|
160 { |
|
161 GLX_DEBUG1("Break to fetch the visible items attrib first"); |
|
162 break; |
|
163 } |
|
164 } |
|
165 else if ( firstItem && ( error != KErrNone ) ) |
|
166 { |
|
167 // Continue iterating through the list |
|
168 // if the first item had errors |
|
169 // See EMYP-79VDHP |
|
170 error = KErrNone; |
|
171 } |
|
172 } |
|
173 |
|
174 // If an error was found, return KErrGeneral |
|
175 if (error != KErrNone) |
|
176 { |
|
177 return KErrGeneral; |
|
178 } |
|
179 |
|
180 GLX_DEBUG2("CGlxAttributeContext::AttributeRequestL() aItemIndices.Count()=%d", |
|
181 aItemIndices.Count()); |
|
182 return aItemIndices.Count(); |
|
183 } |
|
184 |
|
185 // ----------------------------------------------------------------------------- |
|
186 // Get all attributes required for the item (whether the are fetched or not) |
|
187 // From MGlxFetchContext |
|
188 // ----------------------------------------------------------------------------- |
|
189 // |
|
190 void CGlxAttributeContext::AllAttributesL(const MGlxMediaList* aList, TInt aListIndex, |
|
191 RArray<TMPXAttribute>& aAttributes) const |
|
192 { |
|
193 TRACER("CGlxAttributeContext::AllAttributesL"); |
|
194 |
|
195 // An empty request makes no sense, but won't do any harm. |
|
196 |
|
197 // If no iterator, no request |
|
198 if (!iIterator || !iAttributes.Count()) |
|
199 { |
|
200 return; |
|
201 } |
|
202 |
|
203 // No requests outside range |
|
204 iIterator->SetToFirst(aList); |
|
205 if (!iIterator->InRange(aListIndex)) |
|
206 { |
|
207 return; |
|
208 } |
|
209 |
|
210 // Just list all attributes specified for this context |
|
211 TInt count = iAttributes.Count(); |
|
212 for (TInt i = 0; i < count; i++) |
|
213 { |
|
214 aAttributes.AppendL(iAttributes[i]); |
|
215 } |
|
216 } |
|
217 |
|
218 // ----------------------------------------------------------------------------- |
|
219 // Number of current requests |
|
220 // From MGlxFetchContext |
|
221 // ----------------------------------------------------------------------------- |
|
222 TInt CGlxAttributeContext::RequestCountL(const MGlxMediaList* aList) const |
|
223 { |
|
224 TRACER("CGlxAttributeContext::RequestCountL"); |
|
225 |
|
226 RArray<TInt> itemIndices; |
|
227 CleanupClosePushL(itemIndices); |
|
228 |
|
229 RArray<TMPXAttribute> attributes; |
|
230 CleanupClosePushL(attributes); |
|
231 |
|
232 CMPXAttributeSpecs* attrSpecs = NULL; |
|
233 |
|
234 TInt requestCount = AttributeRequestL(aList, itemIndices, attributes, attrSpecs); |
|
235 |
|
236 delete attrSpecs; |
|
237 |
|
238 CleanupStack::PopAndDestroy(&attributes); |
|
239 CleanupStack::PopAndDestroy(&itemIndices); |
|
240 |
|
241 return requestCount; |
|
242 } |
|
243 |
|
244 // ----------------------------------------------------------------------------- |
|
245 // Check if the item at the index requires any attributes to be added to request |
|
246 // ----------------------------------------------------------------------------- |
|
247 TBool CGlxAttributeContext::AddItemAttributesL(TInt aIndexInList, |
|
248 const MGlxMediaList* aList, RArray<TMPXAttribute>& aAttributes, |
|
249 TInt& aError, TBool aFirstItem) const |
|
250 { |
|
251 TRACER("CGlxAttributeContext::AddItemAttributesL"); |
|
252 |
|
253 TInt attributesAdded = EFalse; |
|
254 |
|
255 const TGlxMedia& m = aList->Item(aIndexInList); |
|
256 if (!m.IsStatic()) |
|
257 { |
|
258 const CGlxMedia* media = m.Properties(); |
|
259 TInt attributeCount = iAttributes.Count(); |
|
260 if (!media) |
|
261 { |
|
262 // There are no attributes for this item |
|
263 // Add all attributes |
|
264 for (TInt count = 0; count < attributeCount; ++count) |
|
265 { |
|
266 AddItemAttributeL(aAttributes, iAttributes[count]); |
|
267 } |
|
268 |
|
269 if ( attributeCount > 0 ) |
|
270 { |
|
271 attributesAdded = ETrue; |
|
272 } |
|
273 } |
|
274 else |
|
275 { |
|
276 if ( GlxErrorManager::HasError(media) ) |
|
277 { |
|
278 // Item has one or more errors on its attributes |
|
279 // Check if we are going to try to add an attribute that may have an error on it |
|
280 for (TInt count = 0; (count < attributeCount) && (KErrNone == aError); ++count) |
|
281 { |
|
282 aError = GlxErrorManager::HasAttributeErrorL(media, iAttributes[count]); |
|
283 } |
|
284 } |
|
285 |
|
286 // Always allow attribute adding if it's the first item |
|
287 if ( KErrNone == aError || aFirstItem ) |
|
288 { |
|
289 // There may be some attributes for this item |
|
290 // Add attributes that don't exist yet |
|
291 for (TInt count = 0; count < attributeCount; ++count) |
|
292 { |
|
293 const TMPXAttribute& attribute = iAttributes[count]; |
|
294 if (!media->IsSupported(attribute)) |
|
295 { |
|
296 if ( KErrNone == GlxErrorManager::HasAttributeErrorL(media, iAttributes[count]) ) |
|
297 { |
|
298 AddItemAttributeL(aAttributes, attribute); |
|
299 attributesAdded = ETrue; |
|
300 } |
|
301 } |
|
302 } |
|
303 } |
|
304 } |
|
305 } |
|
306 |
|
307 return attributesAdded; |
|
308 } |
|
309 |
|
310 // ----------------------------------------------------------------------------- |
|
311 // Add attribute to array, no duplicates |
|
312 // ----------------------------------------------------------------------------- |
|
313 void CGlxAttributeContext::AddItemAttributeL(RArray<TMPXAttribute>& aAttributes, |
|
314 const TMPXAttribute& aAttribute) const |
|
315 { |
|
316 TRACER("CGlxAttributeContext::AddItemAttributeL"); |
|
317 |
|
318 TIdentityRelation<TMPXAttribute> match(&TMPXAttribute::Match); |
|
319 TInt index = aAttributes.Find(aAttribute, match); |
|
320 |
|
321 if (index == KErrNotFound) |
|
322 { |
|
323 aAttributes.AppendL(aAttribute); |
|
324 } |
|
325 } |
|
326 |
|
327 // ----------------------------------------------------------------------------- |
|
328 // ----------------------------------------------------------------------------- |
|
329 // CGlxDefaultAttributeContext |
|
330 // ----------------------------------------------------------------------------- |
|
331 // ----------------------------------------------------------------------------- |
|
332 // |
|
333 |
|
334 // NewL |
|
335 // ----------------------------------------------------------------------------- |
|
336 // |
|
337 EXPORT_C CGlxDefaultAttributeContext* CGlxDefaultAttributeContext::NewL() |
|
338 { |
|
339 TRACER("CGlxDefaultAttributeContext::NewL"); |
|
340 |
|
341 CGlxDefaultAttributeContext* obj = new (ELeave) CGlxDefaultAttributeContext(); |
|
342 return obj; |
|
343 } |
|
344 |
|
345 // ----------------------------------------------------------------------------- |
|
346 // Constructor |
|
347 // Sets the iterator of base class to be TGlxFromFocusOutwardIterator |
|
348 // ----------------------------------------------------------------------------- |
|
349 // |
|
350 CGlxDefaultAttributeContext::CGlxDefaultAttributeContext() : |
|
351 CGlxAttributeContext(&iFromFocusIterator) |
|
352 { |
|
353 } |
|
354 |
|
355 // ----------------------------------------------------------------------------- |
|
356 // Destructor |
|
357 // ----------------------------------------------------------------------------- |
|
358 // |
|
359 EXPORT_C CGlxDefaultAttributeContext::~CGlxDefaultAttributeContext() |
|
360 { |
|
361 TRACER("CGlxDefaultAttributeContext::Destructor"); |
|
362 |
|
363 } |
|
364 |
|
365 // ---------------------------------------------------------------------------- |
|
366 // Set range offsets |
|
367 // ---------------------------------------------------------------------------- |
|
368 // |
|
369 EXPORT_C void CGlxDefaultAttributeContext::SetRangeOffsets(TInt aFrontOffset, TInt aRearOffset) |
|
370 { |
|
371 TRACER("CGlxDefaultAttributeContext::SetRangeOffsets"); |
|
372 |
|
373 iFromFocusIterator.SetRangeOffsets(aRearOffset, aFrontOffset); |
|
374 } |