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