|
1 /* |
|
2 * Copyright (c) 2006 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: Collection Ui Helper implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <e32base.h> |
|
20 #include <s32file.h> |
|
21 #include <mpxmedia.h> |
|
22 #include <mpxcollectionplaylist.h> |
|
23 #include <mpxmediaarray.h> |
|
24 #include <mpxmediageneraldefs.h> |
|
25 #include <mpxmediacontainerdefs.h> |
|
26 #include <mpxuser.h> |
|
27 #include <mpxcmn.h> |
|
28 #include <mpxcollectionutility.h> |
|
29 #include <mpxcollectiontype.h> |
|
30 #include <mpxcollectionmediator.h> |
|
31 #include <mpxplaylistenginedefs.h> |
|
32 #include <mpxlog.h> |
|
33 #include <mpxcollectionmessage.h> |
|
34 #include <mpxtaskqueue.h> |
|
35 #include <mpxcollectionplugin.hrh> |
|
36 #include <mpxharvesterutility.h> |
|
37 #include <mpxcommandgeneraldefs.h> |
|
38 #include <mpxcollectioncommanddefs.h> |
|
39 #include <UsbWatcherInternalPSKeys.h> |
|
40 #include <usbpersonalityids.h> |
|
41 |
|
42 #include "mpxcollectionuihelperobserver.h" |
|
43 #include "mpxcollectionuihelperimp.h" |
|
44 #include "mpxcollectionhelpercommon.h" |
|
45 #include "mpxdeletehelper.h" |
|
46 |
|
47 // CONSTANTS |
|
48 const TInt KMPXAllSongsViewIndex = 0; |
|
49 const TInt KMPXPlaylistViewIndex = 1; |
|
50 const TInt KMPXRecentlyPlayedIndex = 0x20000000; |
|
51 const TInt KMPXMostPlayedIndex = 0x20000001; |
|
52 const TInt KMPXRecentlyAddedIndex = 0x20000002; |
|
53 |
|
54 _LIT( KPathVirtualPlaylistHandling, "openpath.dat"); |
|
55 |
|
56 // ======== MEMBER FUNCTIONS ======== |
|
57 |
|
58 // --------------------------------------------------------------------------- |
|
59 // Private Constructor |
|
60 // --------------------------------------------------------------------------- |
|
61 // |
|
62 CMPXCollectionUiHelperImp::CMPXCollectionUiHelperImp() |
|
63 { |
|
64 } |
|
65 |
|
66 |
|
67 // --------------------------------------------------------------------------- |
|
68 // 2nd Phase Constructor |
|
69 // --------------------------------------------------------------------------- |
|
70 // |
|
71 void CMPXCollectionUiHelperImp::ConstructL(const TUid& aModeId) |
|
72 { |
|
73 iCollection = MMPXCollectionUtility::NewL(this,aModeId); |
|
74 iMediator = CMPXCollectionMediator::NewL( iCollection->Collection(), |
|
75 this ); |
|
76 iHarvester = CMPXHarvesterFactory::NewL(); |
|
77 iTaskQueue = CMPXActiveTaskQueue::NewL(); |
|
78 iDeleteHelper = CMPXDeleteHelper::NewL(*iCollection, *iHarvester, *this); |
|
79 |
|
80 iRemainder = 0; |
|
81 iTotalChunkNumber = 0; |
|
82 iChunkNumber = 0; |
|
83 iChunkSize = 0; |
|
84 iArrayIndex = 0; |
|
85 } |
|
86 |
|
87 |
|
88 // --------------------------------------------------------------------------- |
|
89 // Two-Phased Constructor |
|
90 // --------------------------------------------------------------------------- |
|
91 // |
|
92 CMPXCollectionUiHelperImp* CMPXCollectionUiHelperImp::NewL(const TUid& aModeId) |
|
93 { |
|
94 CMPXCollectionUiHelperImp* self = CMPXCollectionUiHelperImp::NewLC(aModeId); |
|
95 CleanupStack::Pop( self ); |
|
96 return self; |
|
97 } |
|
98 |
|
99 |
|
100 // --------------------------------------------------------------------------- |
|
101 // Two-Phased Constructor |
|
102 // --------------------------------------------------------------------------- |
|
103 // |
|
104 CMPXCollectionUiHelperImp* CMPXCollectionUiHelperImp::NewLC(const TUid& aModeId) |
|
105 { |
|
106 CMPXCollectionUiHelperImp* self = new( ELeave ) CMPXCollectionUiHelperImp(); |
|
107 CleanupStack::PushL( self ); |
|
108 self->ConstructL(aModeId); |
|
109 return self; |
|
110 } |
|
111 |
|
112 // --------------------------------------------------------------------------- |
|
113 // Virtual Destructor |
|
114 // --------------------------------------------------------------------------- |
|
115 // |
|
116 CMPXCollectionUiHelperImp::~CMPXCollectionUiHelperImp() |
|
117 { |
|
118 delete iMediator; |
|
119 if( iCollection ) |
|
120 { |
|
121 iCollection->Close(); |
|
122 } |
|
123 if( iHarvester ) |
|
124 { |
|
125 iHarvester->Close(); |
|
126 } |
|
127 delete iTaskQueue; |
|
128 delete iMedia; |
|
129 delete iDeleteHelper; |
|
130 |
|
131 delete iInputMedia; |
|
132 } |
|
133 |
|
134 |
|
135 // --------------------------------------------------------------------------- |
|
136 // Issue collection initialization command to collection framework. |
|
137 // This is necessary when collection helper serves as an intermediator |
|
138 // between collection framework and Podcast App or MTP, etc. |
|
139 // There is, currently, no way to check the merge status of the collections |
|
140 // through the collection utility API. Therefore, collectionhelper issue |
|
141 // an EMcCmdCollectionInit(or merge) command before any collectionhelper |
|
142 // functionality, which expects collection is in valid state, is excuted. |
|
143 // --------------------------------------------------------------------------- |
|
144 // |
|
145 |
|
146 // --------------------------------------------------------------------------- |
|
147 // Add a Media to the collection |
|
148 // --------------------------------------------------------------------------- |
|
149 // |
|
150 void CMPXCollectionUiHelperImp::AddL( const CMPXMedia& aMedia, |
|
151 MMPXCHelperObserver* aObserver ) |
|
152 { |
|
153 if (!aObserver) |
|
154 { |
|
155 User::Leave( KErrArgument ); |
|
156 } |
|
157 |
|
158 // |
|
159 // leave if the given media doesn't contain the following attributes |
|
160 // |
|
161 if (!aMedia.IsSupported(KMPXMediaGeneralType) || |
|
162 !aMedia.IsSupported(KMPXMediaGeneralCategory)) |
|
163 { |
|
164 User::Leave( KErrArgument ); |
|
165 } |
|
166 |
|
167 // |
|
168 // leave if the given media isn't a playlist (i.e. type must be EMPXItem and category |
|
169 // must be EMPXPlaylist |
|
170 // |
|
171 TMPXGeneralType mediaType = |
|
172 aMedia.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType); |
|
173 |
|
174 TMPXGeneralCategory mediaCategory = |
|
175 aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory); |
|
176 |
|
177 // |
|
178 // currently only supporting playlists |
|
179 // |
|
180 if ( mediaType != EMPXItem || |
|
181 mediaCategory != EMPXPlaylist ) |
|
182 { |
|
183 User::Leave( KErrNotSupported ); |
|
184 } |
|
185 |
|
186 // |
|
187 // leave if the media doesn't contain mandatory attributes for adding a playlist |
|
188 // or adding (appending) tracks to an existing playlist. |
|
189 // Required attributes for adding a new playlist are: |
|
190 // type, category, array contents, array counts, title, and path for playlist |
|
191 // Required attributes for adding tracks to an existing playlist are: |
|
192 // type, category, array contents, array counts, and playlist Id |
|
193 // |
|
194 if (!aMedia.IsSupported(KMPXMediaArrayContents) || |
|
195 !aMedia.IsSupported(KMPXMediaArrayCount)) |
|
196 { |
|
197 User::Leave( KErrArgument ); |
|
198 } |
|
199 |
|
200 TInt task(ETaskNone); |
|
201 if (!aMedia.IsSupported(KMPXMediaGeneralId)) |
|
202 { |
|
203 if (!aMedia.IsSupported(KMPXMediaGeneralTitle) || |
|
204 !aMedia.IsSupported(KMPXMediaGeneralUri)) |
|
205 { |
|
206 User::Leave( KErrArgument ); |
|
207 } |
|
208 else |
|
209 { |
|
210 task = ETaskAddMedia; |
|
211 } |
|
212 } |
|
213 else |
|
214 { |
|
215 task = ETaskAppendMedia; |
|
216 } |
|
217 |
|
218 // |
|
219 // externalize parameters |
|
220 // |
|
221 CBufBase* taskParam(NULL); |
|
222 ::CreateBufferL<CMPXMedia>( aMedia, taskParam ); |
|
223 CleanupStack::PushL(taskParam); |
|
224 |
|
225 // Increase reference count for task queue |
|
226 CMPXMedia* ref = CMPXMedia::NewL( aMedia ); |
|
227 CleanupStack::PushL(ref); |
|
228 |
|
229 // |
|
230 // add request to the task queue |
|
231 // |
|
232 iTaskQueue->AddTaskL( task, |
|
233 aObserver, // callback when task completed |
|
234 this, // task queue observer |
|
235 0, // Integer paramter, not used |
|
236 taskParam, // task queue assumes ownership of taskParam |
|
237 NULL, // Ptr data |
|
238 ref ); // ownership transferred |
|
239 |
|
240 CleanupStack::Pop(2, taskParam); // ref & task Param |
|
241 } |
|
242 |
|
243 // --------------------------------------------------------------------------- |
|
244 // Increment Addition |
|
245 // --------------------------------------------------------------------------- |
|
246 // |
|
247 void CMPXCollectionUiHelperImp::IncAddL( const CMPXMedia& aMedia, |
|
248 MMPXCHelperObserver* aObserver, |
|
249 const TInt aSize ) |
|
250 { |
|
251 if (!aObserver) |
|
252 { |
|
253 User::Leave( KErrArgument ); |
|
254 } |
|
255 |
|
256 // |
|
257 // leave if the given media doesn't contain the following attributes |
|
258 // |
|
259 if (!aMedia.IsSupported(KMPXMediaGeneralType) || |
|
260 !aMedia.IsSupported(KMPXMediaGeneralCategory)) |
|
261 { |
|
262 User::Leave( KErrArgument ); |
|
263 } |
|
264 |
|
265 // |
|
266 // leave if the given media isn't a playlist (i.e. type must be EMPXItem and category |
|
267 // must be EMPXPlaylist |
|
268 // |
|
269 TMPXGeneralType mediaType = |
|
270 aMedia.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType); |
|
271 |
|
272 TMPXGeneralCategory mediaCategory = |
|
273 aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory); |
|
274 |
|
275 // |
|
276 // currently only supporting playlists |
|
277 // |
|
278 if ( mediaType != EMPXItem || |
|
279 mediaCategory != EMPXPlaylist ) |
|
280 { |
|
281 User::Leave( KErrNotSupported ); |
|
282 } |
|
283 |
|
284 // |
|
285 // leave if the media doesn't contain mandatory attributes for adding a playlist |
|
286 // or adding (appending) tracks to an existing playlist. |
|
287 // Required attributes for adding a new playlist are: |
|
288 // type, category, array contents, array counts, title, and path for playlist |
|
289 // Required attributes for adding tracks to an existing playlist are: |
|
290 // type, category, array contents, array counts, and playlist Id |
|
291 // |
|
292 if (!aMedia.IsSupported(KMPXMediaArrayContents) || |
|
293 !aMedia.IsSupported(KMPXMediaArrayCount)) |
|
294 { |
|
295 User::Leave( KErrArgument ); |
|
296 } |
|
297 |
|
298 TInt task(ETaskNone); |
|
299 if (!aMedia.IsSupported(KMPXMediaGeneralId)) |
|
300 { |
|
301 if (!aMedia.IsSupported(KMPXMediaGeneralTitle) || |
|
302 !aMedia.IsSupported(KMPXMediaGeneralUri)) |
|
303 { |
|
304 User::Leave( KErrArgument ); |
|
305 } |
|
306 else |
|
307 { |
|
308 task = ETaskAddMedia; |
|
309 } |
|
310 } |
|
311 else |
|
312 { |
|
313 task = ETaskAppendMedia; |
|
314 } |
|
315 |
|
316 // get tracks from input media |
|
317 // since using Value instead of ValueCObject, no Push/Pop |
|
318 CMPXMediaArray* tracksArray = |
|
319 aMedia.Value<CMPXMediaArray>( KMPXMediaArrayContents ); |
|
320 |
|
321 // use incremental add only if number of songs > aSize |
|
322 // this is needed as IncAdd does not deal w/ the case when tracksArray->Count() == aSize |
|
323 if( tracksArray->Count() <= aSize || aSize <= 0 ) |
|
324 { |
|
325 // |
|
326 // externalize parameters |
|
327 // |
|
328 CBufBase* taskParam(NULL); |
|
329 ::CreateBufferL<CMPXMedia>( aMedia, taskParam ); |
|
330 CleanupStack::PushL(taskParam); |
|
331 |
|
332 // Increase reference count for task queue |
|
333 CMPXMedia* ref = CMPXMedia::NewL( aMedia ); |
|
334 CleanupStack::PushL(ref); |
|
335 |
|
336 // |
|
337 // add request to the task queue |
|
338 // |
|
339 iTaskQueue->AddTaskL( task, |
|
340 aObserver, // callback when task completed |
|
341 this, // task queue observer |
|
342 0, // Integer paramter, not used |
|
343 taskParam, // task queue assumes ownership of taskParam |
|
344 NULL, // Ptr data |
|
345 ref ); // ownership transferred |
|
346 |
|
347 CleanupStack::Pop(2, taskParam); // ref & task Param |
|
348 } |
|
349 else // Inc Add |
|
350 { |
|
351 // calculate number of songs in the last chunk |
|
352 iRemainder = tracksArray->Count() % aSize; |
|
353 |
|
354 // calculate the number of iterations/chunks needed to divide the songs |
|
355 // each chunk contians aSize number of songs |
|
356 if( iRemainder == 0 ) |
|
357 { |
|
358 iTotalChunkNumber = tracksArray->Count() / aSize; |
|
359 } |
|
360 else |
|
361 { |
|
362 iTotalChunkNumber = tracksArray->Count() / aSize + 1; |
|
363 } |
|
364 |
|
365 iChunkNumber = 0; // initialize chunk number |
|
366 iChunkSize = aSize; |
|
367 |
|
368 // need this in the case multiple Inc Add is called (if something leaves and |
|
369 // iInputMedia was not cleaned up properly) |
|
370 if( iInputMedia ) |
|
371 { |
|
372 delete iInputMedia; |
|
373 iInputMedia = NULL; |
|
374 } |
|
375 |
|
376 // save needed info for subsequent processing |
|
377 iInputMedia = CMPXMedia::CopyL(aMedia); |
|
378 iArrayIndex = 0; // index on tracksArray of the input media |
|
379 |
|
380 for( int i = 0; i < iTotalChunkNumber; i++ ) |
|
381 { |
|
382 if( task == ETaskAddMedia ) |
|
383 { |
|
384 // schedule the adding requests to the task queue |
|
385 iTaskQueue->AddTaskL( ETaskIncAddMedia, |
|
386 aObserver, // callback when task completed |
|
387 this ); // task queue observer |
|
388 } |
|
389 else // ETaskAppendMedia |
|
390 { |
|
391 // schedule the appending requests to the task queue |
|
392 iTaskQueue->AddTaskL( ETaskIncAppendMedia, |
|
393 aObserver, // callback when task completed |
|
394 this ); // task queue observer |
|
395 } |
|
396 } |
|
397 } |
|
398 |
|
399 } |
|
400 |
|
401 |
|
402 |
|
403 |
|
404 // --------------------------------------------------------------------------- |
|
405 // Update a single media property |
|
406 // Checks for podcast changes in gendre |
|
407 // Checks for "PodCast" gendre |
|
408 // --------------------------------------------------------------------------- |
|
409 // |
|
410 void CMPXCollectionUiHelperImp::SetL( CMPXMedia*& aMedia, |
|
411 MMPXCHelperObserver* aObserver ) |
|
412 { |
|
413 MPX_FUNC("CMPXCollectionUiHelperImp::SetL"); |
|
414 |
|
415 if (!aObserver) |
|
416 { |
|
417 User::Leave( KErrArgument ); |
|
418 } |
|
419 |
|
420 // |
|
421 // leave if the given media doesn't contain the following attributes |
|
422 // |
|
423 if (!aMedia->IsSupported(KMPXMediaGeneralType) || |
|
424 !aMedia->IsSupported(KMPXMediaGeneralCategory)) |
|
425 { |
|
426 User::Leave( KErrArgument ); |
|
427 } |
|
428 |
|
429 // |
|
430 // externalize parameters |
|
431 // |
|
432 CBufBase* taskParam(NULL); |
|
433 ::CreateBufferL<CMPXMedia>( *aMedia, taskParam ); |
|
434 CleanupStack::PushL(taskParam); |
|
435 |
|
436 // |
|
437 // add request to the task queue |
|
438 // |
|
439 CMPXMedia* ref = CMPXMedia::NewL( *aMedia ); // ownership transferred |
|
440 CleanupStack::PushL(ref); |
|
441 |
|
442 iTaskQueue->AddTaskL( ETaskSetMedia, |
|
443 aObserver, // callback when task completed |
|
444 this, // task queue observer |
|
445 0, // Integer paramter, not used |
|
446 taskParam, // task queue assumes ownership of taskParam |
|
447 NULL, // ptr data |
|
448 ref ); // keep reference count alive |
|
449 |
|
450 CleanupStack::Pop(2, taskParam); // ref & taskParam |
|
451 } |
|
452 |
|
453 // --------------------------------------------------------------------------- |
|
454 // Update a list of medias, checks for podcast changes in genre |
|
455 // --------------------------------------------------------------------------- |
|
456 // |
|
457 void CMPXCollectionUiHelperImp::SetL( TArray<CMPXMedia*>& aMediaArray, |
|
458 CMPXCollectionPath& aPath, |
|
459 RArray<TInt>& aIndices ) |
|
460 { |
|
461 iMediator->SetItemL( aMediaArray, aPath, aIndices ); |
|
462 } |
|
463 |
|
464 // --------------------------------------------------------------------------- |
|
465 // rename a media |
|
466 // --------------------------------------------------------------------------- |
|
467 // |
|
468 void CMPXCollectionUiHelperImp::RenameL( const CMPXMedia& aMedia, |
|
469 MMPXCHelperObserver* aObserver ) |
|
470 { |
|
471 if (!aObserver) |
|
472 { |
|
473 User::Leave( KErrArgument ); |
|
474 } |
|
475 |
|
476 // |
|
477 // leave if the given media doesn't contain the following attributes |
|
478 // |
|
479 if (!aMedia.IsSupported(KMPXMediaGeneralType) || |
|
480 !aMedia.IsSupported(KMPXMediaGeneralCategory)) |
|
481 { |
|
482 User::Leave( KErrArgument ); |
|
483 } |
|
484 |
|
485 // |
|
486 // leave if the given media isn't a playlist |
|
487 // |
|
488 TMPXGeneralType mediaType = |
|
489 aMedia.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType); |
|
490 |
|
491 TMPXGeneralCategory mediaCategory = |
|
492 aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory); |
|
493 |
|
494 // |
|
495 // currently only supporting playlists |
|
496 // |
|
497 if ( mediaType != EMPXItem || |
|
498 mediaCategory != EMPXPlaylist ) |
|
499 { |
|
500 User::Leave( KErrNotSupported ); |
|
501 } |
|
502 |
|
503 // |
|
504 // leave if the media doesn't contain mandatory attributes for renaming a playlist |
|
505 // |
|
506 if (!aMedia.IsSupported(KMPXMediaGeneralTitle) || |
|
507 !aMedia.IsSupported(KMPXMediaGeneralId)) |
|
508 { |
|
509 User::Leave( KErrArgument ); |
|
510 } |
|
511 |
|
512 // |
|
513 // externalize parameters |
|
514 // |
|
515 CBufBase* taskParam(NULL); |
|
516 ::CreateBufferL<CMPXMedia>( aMedia, taskParam ); |
|
517 CleanupStack::PushL(taskParam); |
|
518 |
|
519 // Keep media alive |
|
520 CMPXMedia* ref = CMPXMedia::NewL( aMedia ); |
|
521 CleanupStack::PushL(ref); |
|
522 |
|
523 // |
|
524 // add request to the task queue |
|
525 // |
|
526 iTaskQueue->AddTaskL( ETaskRenameMedia, |
|
527 aObserver, // callback when task completed |
|
528 this, // task queue observer |
|
529 0, // Integer paramter, not used |
|
530 taskParam, // task queue assumes ownership of taskParam |
|
531 NULL, // ptr data |
|
532 ref ); // ownership transferred |
|
533 |
|
534 CleanupStack::Pop(2, taskParam); // ref & taskParam |
|
535 } |
|
536 |
|
537 // --------------------------------------------------------------------------- |
|
538 // Delete a collection path and the files |
|
539 // associated with each leaf node in the path |
|
540 // 1: Removes the file from Collection db |
|
541 // 2: Deletes the file from FS |
|
542 // 3: Removes the file from Harvester db |
|
543 // --------------------------------------------------------------------------- |
|
544 // |
|
545 void CMPXCollectionUiHelperImp::DeleteL( CMPXCollectionPath& aPath, |
|
546 MMPXCHelperObserver* aObs ) |
|
547 { |
|
548 if (!aObs) |
|
549 { |
|
550 User::Leave(KErrArgument); |
|
551 } |
|
552 |
|
553 MPX_DEBUG_PATH(aPath); |
|
554 |
|
555 // |
|
556 // externalize parameters |
|
557 // |
|
558 CBufBase* taskParam(NULL); |
|
559 ::CreateBufferL<CMPXCollectionPath>( aPath, taskParam ); |
|
560 CleanupStack::PushL(taskParam); |
|
561 |
|
562 // |
|
563 // add request to the task queue |
|
564 // |
|
565 iTaskQueue->AddTaskL( ETaskRemoveMedia, |
|
566 aObs, // callback when task completed |
|
567 this, // task queue observer |
|
568 0, // Integer paramter, not used |
|
569 taskParam); // task queue assumes ownership of taskParam |
|
570 |
|
571 CleanupStack::Pop(taskParam); |
|
572 } |
|
573 |
|
574 // --------------------------------------------------------------------------- |
|
575 // Move an item from one collection to another |
|
576 // 0: Convert enum to collection lookup UID |
|
577 // 1: Removes the item from the old collection |
|
578 // 2: Adds the item to the new collection using mediator |
|
579 // (Mediator sets genre "Podcast" to "Unknown" if we move from Music -> Podcast |
|
580 // --------------------------------------------------------------------------- |
|
581 // |
|
582 void CMPXCollectionUiHelperImp::MoveL( CMPXMedia*& aMedia, |
|
583 TUid aNewCollection, |
|
584 MMPXCHelperObserver* aObs ) |
|
585 { |
|
586 if (!aMedia->IsSupported(KMPXMediaGeneralCollectionId)) |
|
587 { |
|
588 User::Leave(KErrArgument); |
|
589 } |
|
590 |
|
591 // Lookup the collection |
|
592 // |
|
593 RArray<TUid> ary; |
|
594 CleanupClosePushL( ary ); |
|
595 ary.AppendL( aNewCollection ); |
|
596 TUid newuid = iCollection->CollectionIDL( ary.Array() ); |
|
597 CleanupStack::PopAndDestroy( &ary ); |
|
598 |
|
599 // Move with mediator |
|
600 // |
|
601 const TUid& olduid = aMedia->ValueTObjectL<TUid>( KMPXMediaGeneralCollectionId ); |
|
602 |
|
603 iHelperObserver = aObs; |
|
604 if( !aObs ) |
|
605 { |
|
606 iMediator->MoveItemL( aMedia, olduid, newuid ); |
|
607 } |
|
608 else |
|
609 { |
|
610 // Should i add this to the task queue? need to think about it |
|
611 iMediator->MoveItemL( aMedia, olduid, newuid, this ); |
|
612 } |
|
613 |
|
614 // Notify harvester of the explicit move in collection |
|
615 // |
|
616 aMedia->SetTObjectValueL<TUid>(KMPXMediaGeneralCollectionId, newuid); |
|
617 iHarvester->UpdateFileL( aMedia ); |
|
618 } |
|
619 |
|
620 // --------------------------------------------------------------------------- |
|
621 // Open the collection in embedded mode for a media |
|
622 // Cannot cleanup aObs because UPnP is using this. |
|
623 // --------------------------------------------------------------------------- |
|
624 // |
|
625 void CMPXCollectionUiHelperImp::OpenL( const TUid& aHostId, CMPXMedia& aMedia, |
|
626 MMPXCHelperEmbeddedOpenObserver* /*aObs*/, |
|
627 TInt aPluginInfo ) |
|
628 { |
|
629 // Grab the in memory collection plugin UID |
|
630 // aPluginInfo provides additional resolution to find the plugin |
|
631 // |
|
632 RArray<TUid> ary; |
|
633 CleanupClosePushL( ary ); |
|
634 ary.AppendL( TUid::Uid(EMPXCollectionPluginHidden) ); |
|
635 ary.AppendL( TUid::Uid(EMPXCollectionPluginTemporary) ); |
|
636 if( aPluginInfo ) |
|
637 { |
|
638 ary.AppendL( TUid::Uid(aPluginInfo) ); |
|
639 } |
|
640 |
|
641 TUid inMemCollection = iCollection->CollectionIDL( ary.Array() ); |
|
642 CleanupStack::PopAndDestroy( &ary ); |
|
643 |
|
644 // First step is to add this media to the in memory plugin |
|
645 // Set the item id to be the host ID |
|
646 // |
|
647 aMedia.SetTObjectValueL( KMPXMediaGeneralCollectionId, inMemCollection ); |
|
648 aMedia.SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId, aHostId.iUid ); |
|
649 |
|
650 // Add the media via CMPXCommand |
|
651 CMPXCommand* cmd = CMPXCommand::NewL(); |
|
652 CleanupStack::PushL( cmd ); |
|
653 cmd->SetTObjectValueL( KMPXCommandGeneralId, |
|
654 KMPXCommandIdCollectionAdd ); |
|
655 cmd->SetTObjectValueL( KMPXCommandGeneralDoSync, |
|
656 ETrue ); |
|
657 cmd->SetTObjectValueL( KMPXCommandGeneralCollectionId, |
|
658 inMemCollection.iUid ); |
|
659 cmd->SetCObjectValueL( KMPXCommandColAddMedia, |
|
660 &aMedia ); |
|
661 iCollection->Collection().CommandL( *cmd ); |
|
662 CleanupStack::PopAndDestroy( cmd ); |
|
663 |
|
664 // Second Step is to construct collection path |
|
665 // | collection id | host id | |
|
666 // |
|
667 CMPXCollectionPath* path = CMPXCollectionPath::NewL(); |
|
668 CleanupStack::PushL( path ); |
|
669 path->AppendL( inMemCollection.iUid ); |
|
670 path->AppendL( aHostId.iUid ); |
|
671 |
|
672 // Last step is to open this path |
|
673 // |
|
674 iCollection->Collection().OpenL( *path ); |
|
675 CleanupStack::PopAndDestroy( path ); |
|
676 } |
|
677 |
|
678 // --------------------------------------------------------------------------- |
|
679 // Open the collection in embedded mode for a file handle |
|
680 // --------------------------------------------------------------------------- |
|
681 // |
|
682 void CMPXCollectionUiHelperImp::OpenL( const TUid& aHostId, const TDesC& aFile, |
|
683 MMPXCHelperEmbeddedOpenObserver* aObs, |
|
684 TInt aPluginInfo ) |
|
685 { |
|
686 |
|
687 // Open in embedded mode, no database merge necessary |
|
688 if( !aObs ) |
|
689 { |
|
690 User::LeaveIfError( KErrArgument ); |
|
691 } |
|
692 |
|
693 iEmbeddedModeID = aHostId; |
|
694 iEmbeddedPluginInfo = aPluginInfo; |
|
695 iOpenObserver = aObs; |
|
696 |
|
697 iHarvester->ImportFileL( aFile, this ); |
|
698 } |
|
699 |
|
700 // --------------------------------------------------------------------------- |
|
701 // Open the collection in embedded mode for a file handle |
|
702 // --------------------------------------------------------------------------- |
|
703 // |
|
704 void CMPXCollectionUiHelperImp::OpenL( RFile& aFile, |
|
705 MMPXCHelperEmbeddedOpenObserver* aObs ) |
|
706 { |
|
707 MPX_FUNC( "CMPXCollectionUiHelperImp::OpenL (file handle, observer)" ); |
|
708 // Open in embedded mode, no database merge necessary |
|
709 if( !aObs ) |
|
710 { |
|
711 User::Leave( KErrArgument ); |
|
712 } |
|
713 |
|
714 iOpenObserver = aObs; |
|
715 TMPXGeneralCategory category( EMPXNoCategory ); |
|
716 |
|
717 CFileStore* store( NULL ); |
|
718 MPX_TRAPD( error, store = CDirectFileStore::FromL( aFile ); ); |
|
719 |
|
720 if ( error == KErrNone ) |
|
721 { |
|
722 CleanupStack::PushL( store ); |
|
723 |
|
724 RStoreReadStream stream; |
|
725 stream.OpenLC( *store, store->Root() ); |
|
726 |
|
727 // Recreate the collection path that we were browsing |
|
728 CMPXCollectionPath* collectionPath = CMPXCollectionPath::NewL( stream ); |
|
729 CleanupStack::PopAndDestroy( 2, store ); // stream, store |
|
730 CleanupStack::PushL( collectionPath ); |
|
731 |
|
732 MPX_DEBUG_PATH( *collectionPath ); |
|
733 |
|
734 if ( collectionPath->Levels() != 3 || |
|
735 ( collectionPath->Id(1) != KMPXAllSongsViewIndex && |
|
736 collectionPath->Id(1) != KMPXPlaylistViewIndex ) ) |
|
737 { |
|
738 error = KErrNotSupported; |
|
739 } |
|
740 else |
|
741 { |
|
742 category = collectionPath->Id( 1 ) == |
|
743 KMPXAllSongsViewIndex ? EMPXSong : EMPXPlaylist; |
|
744 TRAP( error, iCollection->Collection().OpenL( *collectionPath ) ); |
|
745 } |
|
746 CleanupStack::PopAndDestroy( collectionPath ); |
|
747 } |
|
748 |
|
749 // Callback to observer for err handling |
|
750 ( ( MMPXCHelperEmbeddedOpenObserver* )iOpenObserver )->HandleEmbeddedOpenL( error, category ); |
|
751 } |
|
752 |
|
753 // --------------------------------------------------------------------------- |
|
754 // Queries about the playlist file extension of the currently selected playlist |
|
755 // plugin |
|
756 // --------------------------------------------------------------------------- |
|
757 HBufC* CMPXCollectionUiHelperImp::PlaylistFileExtensionLC() |
|
758 { |
|
759 // default to M3U playlist type for now |
|
760 return iHarvester->PlaylistFileExtensionLC(EMPXPlaylistTypeM3U); |
|
761 } |
|
762 |
|
763 // --------------------------------------------------------------------------- |
|
764 // Export a playlist |
|
765 // --------------------------------------------------------------------------- |
|
766 // |
|
767 void CMPXCollectionUiHelperImp::ExportPlaylistL(TMPXItemId aPlaylistId, |
|
768 const TDesC& aDestinationDriveAndPath, |
|
769 MMPXCHelperObserver* aObs) |
|
770 { |
|
771 if (!aObs) |
|
772 { |
|
773 User::Leave(KErrArgument); |
|
774 } |
|
775 |
|
776 CMPXMedia* media = CMPXMedia::NewL(); |
|
777 CleanupStack::PushL(media); |
|
778 |
|
779 media->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, aPlaylistId); |
|
780 media->SetTextValueL(KMPXMediaGeneralUri, aDestinationDriveAndPath); |
|
781 |
|
782 // |
|
783 // externalize parameters |
|
784 // |
|
785 CBufBase* taskParam(NULL); |
|
786 ::CreateBufferL<CMPXMedia>( *media, taskParam ); |
|
787 CleanupStack::PushL(taskParam); |
|
788 |
|
789 // |
|
790 // add request to the task queue |
|
791 // |
|
792 iTaskQueue->AddTaskL( ETaskExportPlaylist, |
|
793 aObs, // callback when task completed |
|
794 this, // task queue observer |
|
795 0, // Integer paramter, not used |
|
796 taskParam, // task queue assumes ownership of taskParam |
|
797 NULL, |
|
798 media ); // keep media alive, ownership transferred |
|
799 |
|
800 CleanupStack::Pop(2, media); // taskParam & media |
|
801 } |
|
802 |
|
803 // --------------------------------------------------------------------------- |
|
804 // Reorder a song in a playlist |
|
805 // --------------------------------------------------------------------------- |
|
806 // |
|
807 void CMPXCollectionUiHelperImp::ReorderPlaylistL(const TMPXItemId& aPlaylistId, |
|
808 const TMPXItemId& aSongId, |
|
809 TUint aOriginalOrdinal, |
|
810 TUint aNewOrdinal, |
|
811 MMPXCHelperObserver* aObs) |
|
812 { |
|
813 if (!aObs) |
|
814 { |
|
815 User::Leave(KErrArgument); |
|
816 } |
|
817 |
|
818 CMPXMedia* command = CMPXMedia::NewL(); |
|
819 CleanupStack::PushL(command); |
|
820 |
|
821 command->SetTObjectValueL<TMPXItemId>(KMPXCommandReorderPlaylistId, aPlaylistId); |
|
822 command->SetTObjectValueL<TMPXItemId>(KMPXCommandReorderSongId, aSongId); |
|
823 command->SetTObjectValueL<TUint>(KMPXCommandReorderOriginalOrdinal, aOriginalOrdinal); |
|
824 command->SetTObjectValueL<TUint>(KMPXCommandReorderNewOrdinal, aNewOrdinal); |
|
825 |
|
826 // |
|
827 // externalize parameters |
|
828 // |
|
829 CBufBase* taskParam(NULL); |
|
830 ::CreateBufferL<CMPXMedia>( *command, taskParam ); |
|
831 CleanupStack::PushL(taskParam); |
|
832 |
|
833 // |
|
834 // add request to the task queue |
|
835 // |
|
836 iTaskQueue->AddTaskL( ETaskReorderPlaylist, |
|
837 aObs, // callback when task completed |
|
838 this, // task queue observer |
|
839 0, // Integer paramter, not used |
|
840 taskParam, // task queue assumes ownership of taskParam |
|
841 NULL, |
|
842 command ); // keep media alive, ownership transferred |
|
843 |
|
844 CleanupStack::Pop(2, command); // taskParam & media |
|
845 } |
|
846 |
|
847 // --------------------------------------------------------------------------- |
|
848 // Creates a default collection path to the music menu |
|
849 // --------------------------------------------------------------------------- |
|
850 // |
|
851 CMPXCollectionPath* CMPXCollectionUiHelperImp::MusicMenuPathL() |
|
852 { |
|
853 // Get top level path only, no database merge necessary |
|
854 |
|
855 // Convert the Virtual UID to the real UID |
|
856 RArray<TUid> ary; |
|
857 CleanupClosePushL( ary ); |
|
858 ary.AppendL( TUid::Uid(EMPXCollectionPluginMusic) ); |
|
859 TUid musicCollection = iCollection->CollectionIDL( ary.Array() ); |
|
860 CleanupStack::PopAndDestroy( &ary ); |
|
861 |
|
862 // Second Step is to construct collection path |
|
863 // | collection id | |
|
864 // |
|
865 CMPXCollectionPath* path = CMPXCollectionPath::NewL(); |
|
866 CleanupStack::PushL( path ); |
|
867 path->AppendL( musicCollection.iUid ); |
|
868 CleanupStack::Pop( path ); |
|
869 |
|
870 return path; |
|
871 } |
|
872 |
|
873 // --------------------------------------------------------------------------- |
|
874 // Creates a default collection path to the podcast menu |
|
875 // --------------------------------------------------------------------------- |
|
876 // |
|
877 CMPXCollectionPath* CMPXCollectionUiHelperImp::PodCastMenuPathL() |
|
878 { |
|
879 // Get top level path only, no database merge necessary |
|
880 |
|
881 // Convert the Virtual UID to the real UID |
|
882 RArray<TUid> ary; |
|
883 CleanupClosePushL( ary ); |
|
884 ary.AppendL( TUid::Uid(EMPXCollectionPluginPodCast) ); |
|
885 TUid pcCollection = iCollection->CollectionIDL( ary.Array() ); |
|
886 CleanupStack::PopAndDestroy( &ary ); |
|
887 |
|
888 // Second Step is to construct collection path |
|
889 // | collection id | |
|
890 // |
|
891 CMPXCollectionPath* path = CMPXCollectionPath::NewL(); |
|
892 CleanupStack::PushL( path ); |
|
893 path->AppendL( pcCollection.iUid ); |
|
894 CleanupStack::Pop( path ); |
|
895 |
|
896 return path; |
|
897 } |
|
898 |
|
899 // --------------------------------------------------------------------------- |
|
900 // Creates a default collection path to the music all songs |
|
901 // --------------------------------------------------------------------------- |
|
902 // |
|
903 CMPXCollectionPath* CMPXCollectionUiHelperImp::MusicAllSongsPathL() |
|
904 { |
|
905 CMPXCollectionPath* path = MusicMenuPathL(); |
|
906 CleanupStack::PushL( path ); |
|
907 path->AppendL( KMPXAllSongsViewIndex ); |
|
908 CleanupStack::Pop( path ); |
|
909 |
|
910 return path; |
|
911 } |
|
912 |
|
913 // --------------------------------------------------------------------------- |
|
914 // Creates a default collection path to the music playlist |
|
915 // --------------------------------------------------------------------------- |
|
916 // |
|
917 CMPXCollectionPath* CMPXCollectionUiHelperImp::MusicPlaylistPathL() |
|
918 { |
|
919 CMPXCollectionPath* path = MusicMenuPathL(); |
|
920 CleanupStack::PushL( path ); |
|
921 path->AppendL( KMPXPlaylistViewIndex ); |
|
922 CleanupStack::Pop( path ); |
|
923 |
|
924 return path; |
|
925 } |
|
926 |
|
927 // --------------------------------------------------------------------------- |
|
928 // Creates a default collection path to the music auto playlist |
|
929 // --------------------------------------------------------------------------- |
|
930 // |
|
931 CMPXCollectionPath* CMPXCollectionUiHelperImp::MusicPlaylistPathL(TMPXAutoPlaylistType aPlaylistType) |
|
932 { |
|
933 CMPXCollectionPath* path = MusicPlaylistPathL(); |
|
934 CleanupStack::PushL( path ); |
|
935 if ( aPlaylistType == EMPXRecentlyPlayedPlaylist ) |
|
936 { |
|
937 path->AppendL( KMPXRecentlyPlayedIndex ); |
|
938 } |
|
939 else if ( aPlaylistType == EMPXMostPlayedPlaylist ) |
|
940 { |
|
941 path->AppendL( KMPXMostPlayedIndex ); |
|
942 } |
|
943 else if ( aPlaylistType == EMPXRecentlyAddedPlaylist) |
|
944 { |
|
945 path->AppendL( KMPXRecentlyAddedIndex ); |
|
946 } |
|
947 CleanupStack::Pop( path ); |
|
948 |
|
949 return path; |
|
950 } |
|
951 |
|
952 // --------------------------------------------------------------------------- |
|
953 // Creates a default collection playlist hard coded to all songs of |
|
954 // music database |
|
955 // --------------------------------------------------------------------------- |
|
956 // |
|
957 CMPXCollectionPath* CMPXCollectionUiHelperImp::CreateDefaultPlaylistPathLC() |
|
958 { |
|
959 // Get top level path only, no database merge necessary |
|
960 |
|
961 // Convert the Virtual UID to the real UID |
|
962 RArray<TUid> ary; |
|
963 CleanupClosePushL( ary ); |
|
964 ary.AppendL( TUid::Uid(EMPXCollectionPluginMusic) ); |
|
965 TUid musicCollection = iCollection->CollectionIDL( ary.Array() ); |
|
966 CleanupStack::PopAndDestroy( &ary ); |
|
967 |
|
968 // Second Step is to construct collection path |
|
969 // | collection id | all songs id | |
|
970 // |
|
971 CMPXCollectionPath* path = CMPXCollectionPath::NewL(); |
|
972 CleanupStack::PushL( path ); |
|
973 path->AppendL( musicCollection.iUid ); |
|
974 path->AppendL( 0 ); // MAGIC, all songs, cannot have dependency to plugin in MPXMusicPlayer |
|
975 |
|
976 return path; |
|
977 } |
|
978 |
|
979 // --------------------------------------------------------------------------- |
|
980 // Returns the file name used for virtual playlist handling |
|
981 // --------------------------------------------------------------------------- |
|
982 // |
|
983 HBufC* CMPXCollectionUiHelperImp::ExternalCollectionPathHandlingFileNameLC() |
|
984 { |
|
985 MPX_FUNC( "CMPXCollectionUiHelperImp::ExternalCollectionPathHandlingFileNameLC" ); |
|
986 return KPathVirtualPlaylistHandling().AllocLC(); |
|
987 } |
|
988 |
|
989 // --------------------------------------------------------------------------- |
|
990 // Cancel current op |
|
991 // --------------------------------------------------------------------------- |
|
992 // |
|
993 void CMPXCollectionUiHelperImp::Cancel() |
|
994 { |
|
995 if( iTask == ETaskRemoveMedia ) |
|
996 { |
|
997 iDeleteHelper->Cancel(); |
|
998 } |
|
999 else |
|
1000 { |
|
1001 // currently only used by incremental add |
|
1002 iTaskQueue->CancelRequests(); |
|
1003 |
|
1004 // clean up iInputMedia |
|
1005 if( iInputMedia ) |
|
1006 { |
|
1007 delete iInputMedia; |
|
1008 iInputMedia = NULL; |
|
1009 } |
|
1010 } |
|
1011 } |
|
1012 |
|
1013 // --------------------------------------------------------------------------- |
|
1014 // Frees this object |
|
1015 // --------------------------------------------------------------------------- |
|
1016 // |
|
1017 void CMPXCollectionUiHelperImp::Close() |
|
1018 { |
|
1019 delete this; |
|
1020 } |
|
1021 |
|
1022 // --------------------------------------------------------------------------- |
|
1023 // Test if the specified title already exists for the category |
|
1024 // --------------------------------------------------------------------------- |
|
1025 // |
|
1026 TBool CMPXCollectionUiHelperImp::TitleExistsL(TMPXGeneralCategory aCategory, |
|
1027 const TDesC& aTitle, |
|
1028 TMPXGeneralType aType) |
|
1029 { |
|
1030 CMPXMedia* query = CMPXMedia::NewL(); |
|
1031 CleanupStack::PushL(query); |
|
1032 query->SetTObjectValueL(KMPXMediaGeneralType, aType); |
|
1033 query->SetTObjectValueL(KMPXMediaGeneralCategory, aCategory); |
|
1034 query->SetTextValueL(KMPXMediaGeneralTitle, aTitle); |
|
1035 |
|
1036 // Look up collection UID and set to criteria |
|
1037 // |
|
1038 RArray<TUid> ary; |
|
1039 CleanupClosePushL( ary ); |
|
1040 ary.AppendL( TUid::Uid(EMPXCollectionPluginMusic) ); |
|
1041 TUid musicCollection = iCollection->CollectionIDL( ary.Array() ); |
|
1042 CleanupStack::PopAndDestroy( &ary ); |
|
1043 |
|
1044 query->SetTObjectValueL<TUid>( KMPXMediaGeneralCollectionId, musicCollection ); |
|
1045 |
|
1046 RArray<TMPXAttribute> attributes; |
|
1047 CleanupClosePushL(attributes); |
|
1048 attributes.AppendL(KMPXMediaGeneralId); |
|
1049 |
|
1050 CMPXMedia* result = |
|
1051 iCollection->Collection().FindAllL(*query, attributes.Array()); |
|
1052 CleanupStack::PopAndDestroy(&attributes); |
|
1053 CleanupStack::PopAndDestroy(query); |
|
1054 CleanupStack::PushL(result); |
|
1055 |
|
1056 TInt count = result->ValueTObjectL<TInt>(KMPXMediaArrayCount); |
|
1057 CleanupStack::PopAndDestroy(result); |
|
1058 |
|
1059 return count; |
|
1060 } |
|
1061 |
|
1062 // --------------------------------------------------------------------------- |
|
1063 // Updates the harvester with the up to date collection <-> file mapping |
|
1064 // --------------------------------------------------------------------------- |
|
1065 // |
|
1066 void CMPXCollectionUiHelperImp::HandleMediatorPathUpdatedL( CMPXMedia*& aProperty, |
|
1067 TUid /*aOldPath*/ ) |
|
1068 { |
|
1069 iHarvester->UpdateFileL( aProperty ); |
|
1070 } |
|
1071 |
|
1072 // --------------------------------------------------------------------------- |
|
1073 // Handles completion of playlist export |
|
1074 // to-do: this should be changed to HandlePlaylistExportCompleted |
|
1075 // --------------------------------------------------------------------------- |
|
1076 // |
|
1077 void CMPXCollectionUiHelperImp::HandlePlaylistExportCompletedL( CMPXMedia* aMedia, TInt aErr ) |
|
1078 { |
|
1079 TRAPD(error, DoHandlePlaylistExportCompletedL(aMedia, aErr)); |
|
1080 |
|
1081 CompleteTask(iTask, aErr==KErrNone?error:aErr); |
|
1082 } |
|
1083 |
|
1084 // --------------------------------------------------------------------------- |
|
1085 // Handles completion of playlist export |
|
1086 // --------------------------------------------------------------------------- |
|
1087 // |
|
1088 void CMPXCollectionUiHelperImp::DoHandlePlaylistExportCompletedL( CMPXMedia* aMedia, TInt aErr ) |
|
1089 { |
|
1090 if (aErr == KErrNone) |
|
1091 { |
|
1092 CleanupStack::PushL(aMedia); |
|
1093 iMedia->SetTextValueL( |
|
1094 KMPXMediaGeneralUri, aMedia->ValueText(KMPXMediaGeneralUri)); |
|
1095 CleanupStack::PopAndDestroy(aMedia); |
|
1096 } |
|
1097 } |
|
1098 |
|
1099 // --------------------------------------------------------------------------- |
|
1100 // Handles completion of playlist import |
|
1101 // --------------------------------------------------------------------------- |
|
1102 // |
|
1103 void CMPXCollectionUiHelperImp::HandlePlaylistImportCompletedL( CMPXMedia* aMedia, TInt aErr ) |
|
1104 { |
|
1105 if (aErr == KErrNone) |
|
1106 { |
|
1107 delete aMedia; |
|
1108 } |
|
1109 // Should never come here |
|
1110 ASSERT(0); |
|
1111 } |
|
1112 |
|
1113 // --------------------------------------------------------------------------- |
|
1114 // Handle asynchronous file addition by file name |
|
1115 // --------------------------------------------------------------------------- |
|
1116 // |
|
1117 void CMPXCollectionUiHelperImp::HandleFileAddCompletedL( CMPXMedia* aMedia, TInt aErr ) |
|
1118 { |
|
1119 // to-do |
|
1120 if (aErr == KErrNone) |
|
1121 { |
|
1122 delete aMedia; |
|
1123 } |
|
1124 // Should never come here |
|
1125 ASSERT(0); |
|
1126 } |
|
1127 |
|
1128 // --------------------------------------------------------------------------- |
|
1129 // Handle file delete completion |
|
1130 // --------------------------------------------------------------------------- |
|
1131 // |
|
1132 void CMPXCollectionUiHelperImp::HandleDeleteCompletedL( TInt /*aErr*/ ) |
|
1133 { |
|
1134 } |
|
1135 |
|
1136 // --------------------------------------------------------------------------- |
|
1137 // From MMPXHarvesterUtilityObserver |
|
1138 // --------------------------------------------------------------------------- |
|
1139 // |
|
1140 void CMPXCollectionUiHelperImp::HandleFileImportCompletedL( CMPXMedia* aMedia, |
|
1141 TInt aErr ) |
|
1142 { |
|
1143 // Only do this if we are embedded mode |
|
1144 // |
|
1145 CleanupStack::PushL( aMedia ); |
|
1146 if( iEmbeddedModeID.iUid ) |
|
1147 { |
|
1148 TInt err( aErr ); |
|
1149 TMPXGeneralCategory cat( EMPXNoCategory ); |
|
1150 if( aErr == KErrNone ) |
|
1151 { |
|
1152 TRAP( err, OpenL( iEmbeddedModeID, |
|
1153 *aMedia, |
|
1154 (MMPXCHelperEmbeddedOpenObserver*)iOpenObserver , |
|
1155 iEmbeddedPluginInfo ) ); |
|
1156 cat = aMedia->ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory); |
|
1157 } |
|
1158 |
|
1159 // Callback to observer for err handling |
|
1160 ((MMPXCHelperEmbeddedOpenObserver*)iOpenObserver)->HandleEmbeddedOpenL( err, cat ); |
|
1161 } |
|
1162 CleanupStack::PopAndDestroy( aMedia ); |
|
1163 } |
|
1164 |
|
1165 // --------------------------------------------------------------------------- |
|
1166 // From MMPXHarvesterUtilityObserver |
|
1167 // --------------------------------------------------------------------------- |
|
1168 // |
|
1169 void CMPXCollectionUiHelperImp::HandleFileGetMediaCompletedL( CMPXMedia* /*aMedia*/, |
|
1170 TInt /*aErr*/ ) |
|
1171 { |
|
1172 // Not used |
|
1173 ASSERT(0); |
|
1174 } |
|
1175 |
|
1176 // --------------------------------------------------------------------------- |
|
1177 // From MMPXCollectionMediaObserver |
|
1178 // --------------------------------------------------------------------------- |
|
1179 // |
|
1180 void CMPXCollectionUiHelperImp::HandleCollectionMediaL(const CMPXMedia& /*aMedia*/, |
|
1181 TInt /*aError*/) |
|
1182 { |
|
1183 // Not used |
|
1184 ASSERT(0); |
|
1185 } |
|
1186 |
|
1187 // --------------------------------------------------------------------------- |
|
1188 // From MMPXCollectionObserver |
|
1189 // --------------------------------------------------------------------------- |
|
1190 // |
|
1191 void CMPXCollectionUiHelperImp::HandleCollectionMessage(CMPXMessage* aMsg, TInt aErr) |
|
1192 { |
|
1193 iDeleteHelper->HandleCollectionMessage( aMsg, aErr ); |
|
1194 } |
|
1195 |
|
1196 // --------------------------------------------------------------------------- |
|
1197 // From MMPXCollectionObserver |
|
1198 // --------------------------------------------------------------------------- |
|
1199 // |
|
1200 void CMPXCollectionUiHelperImp::HandleOpenL(const CMPXMedia& /*aEntries*/, TInt /*aIndex*/, TBool /*aComplete*/, TInt /*aError*/) |
|
1201 { |
|
1202 // Not used |
|
1203 ASSERT(0); |
|
1204 } |
|
1205 |
|
1206 // --------------------------------------------------------------------------- |
|
1207 // From MMPXCollectionObserver |
|
1208 // --------------------------------------------------------------------------- |
|
1209 // |
|
1210 void CMPXCollectionUiHelperImp::HandleOpenL(const CMPXCollectionPlaylist& /*aPlaylist*/, TInt /*aError*/) |
|
1211 { |
|
1212 // Not used |
|
1213 ASSERT(0); |
|
1214 } |
|
1215 |
|
1216 // ---------------------------------------------------------------------------- |
|
1217 // Handles completion of moving an object, just a proxy |
|
1218 // ---------------------------------------------------------------------------- |
|
1219 // |
|
1220 void CMPXCollectionUiHelperImp::HandleMoveCompleteL( TInt aErr ) |
|
1221 { |
|
1222 if( iHelperObserver ) |
|
1223 { |
|
1224 iHelperObserver->HandleOperationCompleteL( EMoveOp, aErr, NULL ); |
|
1225 } |
|
1226 } |
|
1227 |
|
1228 // ---------------------------------------------------------------------------- |
|
1229 // Handles completion of removing a collection path |
|
1230 // ---------------------------------------------------------------------------- |
|
1231 // |
|
1232 void CMPXCollectionUiHelperImp::HandleOperationCompleteL( TCHelperOperation aOperation, |
|
1233 TInt aErr, |
|
1234 void* aArgument ) |
|
1235 { |
|
1236 if (aOperation == EDeleteOp && iTask == ETaskRemoveMedia) |
|
1237 { |
|
1238 CompleteTask(iTask, aErr); |
|
1239 } |
|
1240 else if ( aOperation == EDeleteStatusOp ) |
|
1241 { |
|
1242 iHelperObserver->HandleOperationCompleteL( aOperation, aErr, aArgument ); |
|
1243 } |
|
1244 } |
|
1245 |
|
1246 // ---------------------------------------------------------------------------- |
|
1247 // Execute an async task |
|
1248 // ---------------------------------------------------------------------------- |
|
1249 // |
|
1250 void CMPXCollectionUiHelperImp::ExecuteTask( |
|
1251 TInt aTask, |
|
1252 TInt /*aParamData*/, |
|
1253 TAny* /*aPtrData*/, |
|
1254 const CBufBase& aBuf, |
|
1255 TAny* aCallback, |
|
1256 CBase* /*aCObject1*/, |
|
1257 CBase* /*aCObject2*/) |
|
1258 { |
|
1259 TRAPD(err, ExecuteTaskL(aTask, aBuf, aCallback)); |
|
1260 if (err != KErrNone) |
|
1261 { |
|
1262 CompleteTask(aTask, err); |
|
1263 } |
|
1264 } |
|
1265 |
|
1266 // ---------------------------------------------------------------------------- |
|
1267 // Indicates that a task was terminated with an error |
|
1268 // ---------------------------------------------------------------------------- |
|
1269 // |
|
1270 void CMPXCollectionUiHelperImp::HandleTaskError( |
|
1271 TInt /* aTask */, |
|
1272 TAny* /*aPtrData*/, |
|
1273 TAny* /*aCallback*/, |
|
1274 TInt /* aError */) |
|
1275 { |
|
1276 // Do nothing |
|
1277 } |
|
1278 |
|
1279 // ---------------------------------------------------------------------------- |
|
1280 // Execute an async task. Leaves when an error is encountered. |
|
1281 // ---------------------------------------------------------------------------- |
|
1282 // |
|
1283 void CMPXCollectionUiHelperImp::ExecuteTaskL(TInt aTask, const CBufBase& aBuf, TAny* aCallback) |
|
1284 { |
|
1285 iTask = aTask; |
|
1286 MPX_DEBUG2("CMPXCollectionUiHelperImp::ExecuteTaskL, aTask = %d", aTask); |
|
1287 |
|
1288 // cenrep key need to be checked whether USB cable is connected in MTP/Combined Mode |
|
1289 // prevent any general add, general delete, and any moficiation of playlist |
|
1290 if ((iTask == ETaskAddMedia) |
|
1291 || (iTask == ETaskAppendMedia) |
|
1292 || (iTask == ETaskIncAddMedia) |
|
1293 || (iTask == ETaskIncAppendMedia) |
|
1294 || (iTask == ETaskRemoveMedia) |
|
1295 || (iTask == ETaskReorderPlaylist) |
|
1296 || (iTask == ETaskRenameMedia)) |
|
1297 { |
|
1298 TInt usbStatus; |
|
1299 RProperty::Get(KPSUidUsbWatcher, KUsbWatcherSelectedPersonality, usbStatus); |
|
1300 |
|
1301 if ((usbStatus == KUsbPersonalityIdMTP) || (usbStatus == KUsbPersonalityIdPCSuiteMTP) |
|
1302 || (usbStatus == KUsbPersonalityIdMS) ) |
|
1303 { |
|
1304 MPX_DEBUG1("USB is active, Leave with KErrLocked"); |
|
1305 // need to call back even if it leaves here |
|
1306 iHelperObserver = (MMPXCHelperObserver*)aCallback; |
|
1307 CompleteTask( aTask, KErrLocked ); |
|
1308 //User::Leave(KErrLocked); |
|
1309 if ((iTaskQueue->Task() != ETaskIncAddMedia)&&(iTaskQueue->Task() != ETaskIncAppendMedia)) |
|
1310 { |
|
1311 iIncAdding = EFalse; |
|
1312 } |
|
1313 return; |
|
1314 } |
|
1315 } |
|
1316 |
|
1317 switch( aTask ) |
|
1318 { |
|
1319 case ETaskAddMedia: // fall through |
|
1320 case ETaskAppendMedia: |
|
1321 { |
|
1322 delete iMedia; |
|
1323 iMedia = NULL; |
|
1324 ::NewFromBufferL<CMPXMedia>( aBuf, iMedia ); |
|
1325 iHelperObserver = (MMPXCHelperObserver*)aCallback; |
|
1326 DoAddL(); |
|
1327 } |
|
1328 break; |
|
1329 |
|
1330 case ETaskIncAddMedia: |
|
1331 { |
|
1332 iHelperObserver = (MMPXCHelperObserver*)aCallback; |
|
1333 DoIncAddMediaL(); |
|
1334 } |
|
1335 break; |
|
1336 |
|
1337 case ETaskIncAppendMedia: |
|
1338 { |
|
1339 iHelperObserver = (MMPXCHelperObserver*)aCallback; |
|
1340 DoIncAppendMediaL(); |
|
1341 } |
|
1342 break; |
|
1343 |
|
1344 case ETaskSetMedia: |
|
1345 { |
|
1346 delete iMedia; |
|
1347 iMedia = NULL; |
|
1348 ::NewFromBufferL<CMPXMedia>( aBuf, iMedia ); |
|
1349 iHelperObserver = (MMPXCHelperObserver*)aCallback; |
|
1350 DoSetL(); |
|
1351 } |
|
1352 break; |
|
1353 |
|
1354 case ETaskRenameMedia: |
|
1355 { |
|
1356 delete iMedia; |
|
1357 iMedia = NULL; |
|
1358 ::NewFromBufferL<CMPXMedia>( aBuf, iMedia ); |
|
1359 iHelperObserver = (MMPXCHelperObserver*)aCallback; |
|
1360 DoRenameL(); |
|
1361 } |
|
1362 break; |
|
1363 |
|
1364 case ETaskRemoveMedia: |
|
1365 { |
|
1366 CMPXCollectionPath* path(NULL); |
|
1367 ::NewFromBufferL<CMPXCollectionPath>( aBuf, path ); |
|
1368 CleanupStack::PushL(path); |
|
1369 MPX_DEBUG_PATH(*path); |
|
1370 |
|
1371 iHelperObserver = (MMPXCHelperObserver*) aCallback; |
|
1372 iDeleteHelper->DeleteL(*path); |
|
1373 CleanupStack::PopAndDestroy(path); |
|
1374 } |
|
1375 break; |
|
1376 |
|
1377 case ETaskExportPlaylist: |
|
1378 { |
|
1379 delete iMedia; |
|
1380 iMedia = NULL; |
|
1381 |
|
1382 CMPXMedia* params(NULL); |
|
1383 ::NewFromBufferL<CMPXMedia>( aBuf, params ); |
|
1384 CleanupStack::PushL(params); |
|
1385 |
|
1386 iHelperObserver = (MMPXCHelperObserver*)aCallback; |
|
1387 |
|
1388 DoExportPlaylistL( |
|
1389 params->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId), |
|
1390 params->ValueText(KMPXMediaGeneralUri)); |
|
1391 |
|
1392 CleanupStack::PopAndDestroy(params); |
|
1393 } |
|
1394 break; |
|
1395 |
|
1396 case ETaskReorderPlaylist: |
|
1397 { |
|
1398 delete iMedia; |
|
1399 iMedia = NULL; |
|
1400 |
|
1401 CMPXCommand* params(NULL); |
|
1402 ::NewFromBufferL<CMPXCommand>( aBuf, params ); |
|
1403 CleanupStack::PushL(params); |
|
1404 |
|
1405 iHelperObserver = (MMPXCHelperObserver*)aCallback; |
|
1406 |
|
1407 DoReorderPlaylistL(*params); |
|
1408 |
|
1409 CleanupStack::PopAndDestroy(params); |
|
1410 } |
|
1411 break; |
|
1412 |
|
1413 // |
|
1414 // command not supported |
|
1415 // |
|
1416 default: |
|
1417 { |
|
1418 User::Leave( KErrNotSupported ); |
|
1419 } |
|
1420 } |
|
1421 } |
|
1422 |
|
1423 // ---------------------------------------------------------------------------- |
|
1424 // Completes the currently executing task |
|
1425 // ---------------------------------------------------------------------------- |
|
1426 // |
|
1427 void CMPXCollectionUiHelperImp::CompleteTask(TInt aTask, TInt aError) |
|
1428 { |
|
1429 MPX_FUNC("CMPXCollectionUiHelperImp::CompleteTask"); |
|
1430 |
|
1431 MPX_DEBUG3("task %d, error %d", aTask, aError); |
|
1432 |
|
1433 TRAP_IGNORE(NotifyClientL(aTask, aError)); |
|
1434 |
|
1435 if ( iTask != ETaskNone ) |
|
1436 { |
|
1437 // clean up data set during processing of the current task |
|
1438 Cleanup(); |
|
1439 |
|
1440 // Complete current task and move on to the next |
|
1441 iTaskQueue->CompleteTask(); |
|
1442 } |
|
1443 } |
|
1444 |
|
1445 // ---------------------------------------------------------------------------- |
|
1446 // Notifies the client of the completion of a collection helper request |
|
1447 // ---------------------------------------------------------------------------- |
|
1448 // |
|
1449 void CMPXCollectionUiHelperImp::NotifyClientL(TInt aTask, TInt aError) |
|
1450 { |
|
1451 MPX_DEBUG3("CMPXCollectionUiHelperImp::NotifyClientL(task %d, error %d)", aTask, aError); |
|
1452 |
|
1453 switch (aTask) |
|
1454 { |
|
1455 case ETaskAddMedia: // fall through |
|
1456 case ETaskAppendMedia: |
|
1457 { |
|
1458 if ( aError >= KErrNone ) |
|
1459 { |
|
1460 // make a copy of iMedia to hand over to the client which takes ownership |
|
1461 // of the copied media. if we failed to make a copy, client is not notified. |
|
1462 iHelperObserver->HandleOperationCompleteL(EAddOp, |
|
1463 KErrNone, |
|
1464 CMPXMedia::NewL(*iMedia) ); |
|
1465 } |
|
1466 else |
|
1467 { |
|
1468 iHelperObserver->HandleOperationCompleteL( EAddOp, |
|
1469 aError, |
|
1470 NULL ); |
|
1471 } |
|
1472 } |
|
1473 break; |
|
1474 case ETaskIncAddMedia: |
|
1475 case ETaskIncAppendMedia: |
|
1476 { |
|
1477 if ( KErrLocked == aError ) |
|
1478 { |
|
1479 if( EFalse == iIncAdding ) |
|
1480 { |
|
1481 iIncAdding = ETrue; |
|
1482 iHelperObserver->HandleOperationCompleteL( EAddOp, aError, NULL ); |
|
1483 } |
|
1484 } |
|
1485 } |
|
1486 break; |
|
1487 case ETaskIncFinish: |
|
1488 { |
|
1489 if ( aError >= KErrNone ) |
|
1490 { |
|
1491 // input media is handed over to observer |
|
1492 iHelperObserver->HandleOperationCompleteL(EAddOp, |
|
1493 KErrNone, |
|
1494 CMPXMedia::NewL(*iInputMedia) ); |
|
1495 } |
|
1496 else |
|
1497 { |
|
1498 iHelperObserver->HandleOperationCompleteL( EAddOp, |
|
1499 aError, |
|
1500 NULL ); |
|
1501 } |
|
1502 // clean up input media |
|
1503 delete iInputMedia; |
|
1504 iInputMedia = NULL; |
|
1505 } |
|
1506 break; |
|
1507 |
|
1508 case ETaskSetMedia: |
|
1509 { |
|
1510 if ( aError >= KErrNone ) |
|
1511 { |
|
1512 // make a copy of iMedia to hand over to the client which takes ownership |
|
1513 // of the copied media. if we failed to make a copy, client is not notified. |
|
1514 iHelperObserver->HandleOperationCompleteL( ESetOp, |
|
1515 KErrNone, |
|
1516 CMPXMedia::NewL(*iMedia) ); |
|
1517 } |
|
1518 else |
|
1519 { |
|
1520 iHelperObserver->HandleOperationCompleteL( ESetOp, |
|
1521 aError, |
|
1522 NULL ); |
|
1523 } |
|
1524 } |
|
1525 break; |
|
1526 |
|
1527 case ETaskRenameMedia: |
|
1528 { |
|
1529 if ( aError >= KErrNone ) |
|
1530 { |
|
1531 // make a copy of iMedia to hand over to the client which takes ownership |
|
1532 // of the copied media. if we failed to make a copy, client is not notified. |
|
1533 iHelperObserver->HandleOperationCompleteL( ERenameOp, |
|
1534 KErrNone, |
|
1535 CMPXMedia::NewL(*iMedia) ); |
|
1536 } |
|
1537 else |
|
1538 { |
|
1539 iHelperObserver->HandleOperationCompleteL( ERenameOp, |
|
1540 aError, |
|
1541 NULL ); |
|
1542 } |
|
1543 } |
|
1544 break; |
|
1545 |
|
1546 case ETaskRemoveMedia: |
|
1547 { |
|
1548 iHelperObserver->HandleOperationCompleteL( EDeleteOp, |
|
1549 aError >= KErrNone? KErrNone : aError, |
|
1550 NULL ); |
|
1551 } |
|
1552 break; |
|
1553 |
|
1554 case ETaskExportPlaylist: |
|
1555 { |
|
1556 HBufC* buf( NULL ); |
|
1557 if( aError == KErrNone ) |
|
1558 { |
|
1559 const TDesC& uri = |
|
1560 iMedia->ValueText(KMPXMediaGeneralUri); |
|
1561 buf = uri.AllocL(); |
|
1562 } |
|
1563 |
|
1564 // client assumes ownership of HBufC copied from title |
|
1565 iHelperObserver->HandleOperationCompleteL(EExportPlaylistOp, aError, buf); |
|
1566 } |
|
1567 break; |
|
1568 |
|
1569 case ETaskReorderPlaylist: |
|
1570 { |
|
1571 iHelperObserver->HandleOperationCompleteL( EReorderPlaylistOp, |
|
1572 aError >= KErrNone? KErrNone : aError, |
|
1573 NULL ); |
|
1574 } |
|
1575 break; |
|
1576 |
|
1577 default: |
|
1578 break; |
|
1579 } |
|
1580 } |
|
1581 |
|
1582 // ---------------------------------------------------------------------------- |
|
1583 // Cleanup async task variables |
|
1584 // ---------------------------------------------------------------------------- |
|
1585 // |
|
1586 void CMPXCollectionUiHelperImp::Cleanup() |
|
1587 { |
|
1588 MPX_DEBUG1("-->CMPXCollectionUiHelperImp::Cleanup"); |
|
1589 iTask = ETaskNone; |
|
1590 iHelperObserver = NULL; |
|
1591 delete iMedia; |
|
1592 iMedia = NULL; |
|
1593 MPX_DEBUG1("<--CMPXCollectionUiHelperImp::Cleanup"); |
|
1594 } |
|
1595 |
|
1596 // --------------------------------------------------------------------------- |
|
1597 // Add a Media to the collection |
|
1598 // |
|
1599 // For playlists: |
|
1600 // 1) add to collection |
|
1601 // 2) when successfully added to collection, AddItemL returns; otherwise, |
|
1602 // AddItemL leaves. |
|
1603 // 3) complete task upon successfully addition to the collection. If a leave |
|
1604 // occurs, it's trapped by ExecuteTask and task is completed by ExecuteTask |
|
1605 // --------------------------------------------------------------------------- |
|
1606 // |
|
1607 void CMPXCollectionUiHelperImp::DoAddL() |
|
1608 { |
|
1609 // creating a new playlist |
|
1610 if (iTask == ETaskAddMedia) |
|
1611 { |
|
1612 // find the collection Id |
|
1613 HBufC* playlistExtension = PlaylistFileExtensionLC(); |
|
1614 |
|
1615 TInt collectionId = FindCollectionIdL(*playlistExtension); |
|
1616 |
|
1617 // Add to collection, make sure we set the collection ID. |
|
1618 iMedia->SetTObjectValueL<TUid>( |
|
1619 KMPXMediaGeneralCollectionId, TUid::Uid( collectionId )); |
|
1620 |
|
1621 CleanupStack::PopAndDestroy(playlistExtension); |
|
1622 } |
|
1623 |
|
1624 // adding/appending tracks to a saved playlist |
|
1625 else |
|
1626 { |
|
1627 FillInPlaylistDetailsL(*iMedia); |
|
1628 } |
|
1629 |
|
1630 // when playlist is successfully added to the collection, its |
|
1631 // KMPXMediaGeneralId is automatically updated by mediator |
|
1632 iMediator->AddItemL( iMedia ); |
|
1633 |
|
1634 CompleteTask(iTask, KErrNone); |
|
1635 } |
|
1636 |
|
1637 // --------------------------------------------------------------------------- |
|
1638 // Add media to the collection incrementally |
|
1639 // --------------------------------------------------------------------------- |
|
1640 // |
|
1641 void CMPXCollectionUiHelperImp::DoIncAddMediaL() |
|
1642 { |
|
1643 /***** include only aSize/iChunkSize number of songs *****/ |
|
1644 |
|
1645 // copy media |
|
1646 CMPXMedia* media = CMPXMedia::CopyL(*iInputMedia); |
|
1647 CleanupStack::PushL(media); |
|
1648 |
|
1649 CMPXMediaArray* tracksArray = iInputMedia->Value<CMPXMediaArray>( KMPXMediaArrayContents ); |
|
1650 |
|
1651 CMPXMediaArray* cArray = CMPXMediaArray::NewL(); |
|
1652 CleanupStack::PushL(cArray); |
|
1653 |
|
1654 // last interation/chunk |
|
1655 // for the case when aSize/iChunkSize evenly devides number of songs, the else clause takes care of it |
|
1656 if( (iChunkNumber == iTotalChunkNumber-1) && iRemainder != 0 ) |
|
1657 { |
|
1658 // add remaining songs to the array |
|
1659 for(int j = 0; j < iRemainder; j++ ) |
|
1660 { |
|
1661 cArray->AppendL(*tracksArray->AtL(iArrayIndex)); |
|
1662 iArrayIndex++; |
|
1663 } |
|
1664 } |
|
1665 else |
|
1666 { |
|
1667 // adding next aSize/iChunkSize elements |
|
1668 for(int j = 0; j < iChunkSize; j++) |
|
1669 { |
|
1670 cArray->AppendL(*tracksArray->AtL(iArrayIndex)); |
|
1671 iArrayIndex++; |
|
1672 } |
|
1673 } |
|
1674 |
|
1675 // update media w/ new array |
|
1676 media->SetCObjectValueL(KMPXMediaArrayContents, cArray); |
|
1677 media->SetTObjectValueL(KMPXMediaArrayCount, cArray->Count() ); |
|
1678 |
|
1679 |
|
1680 /***** logic to see which chunk this code is in *****/ |
|
1681 |
|
1682 // first chunk |
|
1683 // for the case that there is only one chunk (first & last chunk at the same |
|
1684 // time), Inc Add is not used |
|
1685 if ( iChunkNumber == 0 ) |
|
1686 { |
|
1687 // find the collection Id |
|
1688 HBufC* playlistExtension = PlaylistFileExtensionLC(); |
|
1689 |
|
1690 TInt collectionId = FindCollectionIdL(*playlistExtension); |
|
1691 |
|
1692 // Add to collection, make sure we set the collection ID. |
|
1693 media->SetTObjectValueL<TUid>( |
|
1694 KMPXMediaGeneralCollectionId, TUid::Uid( collectionId )); |
|
1695 |
|
1696 // save collectionId for adding subsequent chunks |
|
1697 iInputMedia->SetTObjectValueL<TUid>( |
|
1698 KMPXMediaGeneralCollectionId, TUid::Uid( collectionId )); |
|
1699 |
|
1700 CleanupStack::PopAndDestroy(playlistExtension); |
|
1701 |
|
1702 iMediator->AddItemL( media ); // this creates the new playlist |
|
1703 |
|
1704 // save playlistId in input media & use it for subsequent appending operations |
|
1705 TMPXItemId playlistId = media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId); |
|
1706 iInputMedia->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, playlistId); |
|
1707 |
|
1708 iChunkNumber++; // move on to next chunk |
|
1709 |
|
1710 CompleteTask(iTask, KErrNone); |
|
1711 } |
|
1712 else if ( iChunkNumber == iTotalChunkNumber-1 ) // last chunk |
|
1713 { |
|
1714 // get saved collection id from input media & set it in current media |
|
1715 TUid id = iInputMedia->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId); |
|
1716 media->SetTObjectValueL<TUid>(KMPXMediaGeneralCollectionId, id); |
|
1717 |
|
1718 // get playlistId from input media & set it in current media |
|
1719 TMPXItemId playlistId = iInputMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId); |
|
1720 media->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, playlistId); |
|
1721 |
|
1722 iMediator->AddItemL( media ); |
|
1723 |
|
1724 CompleteTask(ETaskIncFinish, KErrNone); // finish inc task |
|
1725 } |
|
1726 else // intermedia chunks |
|
1727 { |
|
1728 // get saved collection id from input media & set it in current media |
|
1729 TUid id = iInputMedia->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId); |
|
1730 media->SetTObjectValueL<TUid>(KMPXMediaGeneralCollectionId, id); |
|
1731 |
|
1732 // get playlistId from original media & set it in current media |
|
1733 TMPXItemId playlistId = iInputMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId); |
|
1734 media->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, playlistId); |
|
1735 |
|
1736 iMediator->AddItemL( media ); |
|
1737 |
|
1738 iChunkNumber++; // move on to next chunk |
|
1739 |
|
1740 CompleteTask(iTask, KErrNone); |
|
1741 } |
|
1742 |
|
1743 CleanupStack::PopAndDestroy(cArray); |
|
1744 CleanupStack::PopAndDestroy(media); |
|
1745 } |
|
1746 |
|
1747 // --------------------------------------------------------------------------- |
|
1748 // Append media to the collection incrementally |
|
1749 // --------------------------------------------------------------------------- |
|
1750 // |
|
1751 void CMPXCollectionUiHelperImp::DoIncAppendMediaL() |
|
1752 { |
|
1753 /***** include only aSize/iChunkSize number of songs *****/ |
|
1754 |
|
1755 // copy media |
|
1756 CMPXMedia* media = CMPXMedia::CopyL(*iInputMedia); |
|
1757 CleanupStack::PushL(media); |
|
1758 |
|
1759 CMPXMediaArray* tracksArray = iInputMedia->Value<CMPXMediaArray>( KMPXMediaArrayContents ); |
|
1760 |
|
1761 CMPXMediaArray* cArray = CMPXMediaArray::NewL(); |
|
1762 CleanupStack::PushL(cArray); |
|
1763 |
|
1764 // last interation/chunk |
|
1765 // for the case when aSize/iChunkSize evenly devides number of tracks, the else clause takes care of it |
|
1766 if( (iChunkNumber == iTotalChunkNumber-1) && iRemainder != 0 ) |
|
1767 { |
|
1768 for(int j = 0; j < iRemainder; j++ ) |
|
1769 { |
|
1770 cArray->AppendL(*tracksArray->AtL(iArrayIndex)); |
|
1771 iArrayIndex++; |
|
1772 } |
|
1773 } |
|
1774 else |
|
1775 { |
|
1776 // adding next aSize/iChunkSize elements |
|
1777 for(int j = 0; j < iChunkSize; j++) |
|
1778 { |
|
1779 cArray->AppendL(*tracksArray->AtL(iArrayIndex)); |
|
1780 iArrayIndex++; |
|
1781 } |
|
1782 } |
|
1783 |
|
1784 // update media w/ new array |
|
1785 media->SetCObjectValueL(KMPXMediaArrayContents, cArray); |
|
1786 media->SetTObjectValueL(KMPXMediaArrayCount, cArray->Count() ); |
|
1787 |
|
1788 |
|
1789 /***** logic to see which chunk this code is in *****/ |
|
1790 |
|
1791 // update media then append to playlist |
|
1792 FillInPlaylistDetailsL(*media); |
|
1793 iMediator->AddItemL( media ); |
|
1794 |
|
1795 // last chunk |
|
1796 // for the case that there is only one chunk (first & last chunk at the same |
|
1797 // time), Inc Add is not used |
|
1798 if( iChunkNumber == iTotalChunkNumber-1 ) |
|
1799 { |
|
1800 // update input media as well |
|
1801 FillInPlaylistDetailsL(*iInputMedia); |
|
1802 CompleteTask(ETaskIncFinish, KErrNone); |
|
1803 } |
|
1804 else // intermediate chunks, including first chunk |
|
1805 { |
|
1806 iChunkNumber++; |
|
1807 CompleteTask(iTask, KErrNone); |
|
1808 } |
|
1809 |
|
1810 CleanupStack::PopAndDestroy(cArray); |
|
1811 CleanupStack::PopAndDestroy(media); |
|
1812 } |
|
1813 |
|
1814 // --------------------------------------------------------------------------- |
|
1815 // Update a media in the collection |
|
1816 // |
|
1817 // For updating (overwriting) a playlist, or updating a song/artist/album/genre/ |
|
1818 // composer: |
|
1819 // 1) update collection |
|
1820 // 2) when successfully updated the collection, SetItemL is returned; otherwise |
|
1821 // a leave occurs. |
|
1822 // 3) complete task upon successfully updating the collection. If a leave |
|
1823 // occurs, it's trapped by ExecuteTask and task is completed by ExecuteTask |
|
1824 // --------------------------------------------------------------------------- |
|
1825 // |
|
1826 void CMPXCollectionUiHelperImp::DoSetL() |
|
1827 { |
|
1828 MPX_FUNC("CMPXCollectionUiHelperImp::DoSetL"); |
|
1829 |
|
1830 // fill in playlist details |
|
1831 TMPXGeneralCategory category = |
|
1832 iMedia->ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory); |
|
1833 if ( category == EMPXPlaylist ) |
|
1834 { |
|
1835 FillInPlaylistDetailsL(*iMedia); |
|
1836 } |
|
1837 |
|
1838 // find the collection Id |
|
1839 if (!iMedia->IsSupported(KMPXMediaGeneralCollectionId) && |
|
1840 iMedia->IsSupported(KMPXMediaGeneralUri)) |
|
1841 { |
|
1842 TInt collectionId = |
|
1843 FindCollectionIdL(iMedia->ValueText(KMPXMediaGeneralUri)); |
|
1844 |
|
1845 if (collectionId) |
|
1846 { |
|
1847 iMedia->SetTObjectValueL<TUid>( |
|
1848 KMPXMediaGeneralCollectionId , TUid::Uid(collectionId)); |
|
1849 } |
|
1850 } |
|
1851 |
|
1852 // update collection. |
|
1853 iMediator->SetItemL( iMedia ); |
|
1854 |
|
1855 CompleteTask(iTask, KErrNone); |
|
1856 } |
|
1857 |
|
1858 // --------------------------------------------------------------------------- |
|
1859 // Rename a media in the collection |
|
1860 // --------------------------------------------------------------------------- |
|
1861 // |
|
1862 void CMPXCollectionUiHelperImp::DoRenameL() |
|
1863 { |
|
1864 // find the collection Id of the playlist from playlist Id |
|
1865 // iMedia isn't used as the search criteria because it |
|
1866 // contains the new title of the playlist; calling |
|
1867 // FillInPlaylistDetailsL(*iMedia) will result in playlist |
|
1868 // not found. |
|
1869 if (!iMedia->IsSupported(KMPXMediaGeneralCollectionId)) |
|
1870 { |
|
1871 CMPXMedia* media = CMPXMedia::NewL(); |
|
1872 CleanupStack::PushL(media); |
|
1873 |
|
1874 media->SetTObjectValueL(KMPXMediaGeneralType, EMPXItem); |
|
1875 media->SetTObjectValueL(KMPXMediaGeneralCategory,EMPXPlaylist); |
|
1876 media->SetTObjectValueL(KMPXMediaGeneralId, iMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)); |
|
1877 |
|
1878 FillInPlaylistDetailsL(*media); |
|
1879 |
|
1880 if (media->IsSupported(KMPXMediaGeneralCollectionId)) |
|
1881 { |
|
1882 iMedia->SetTObjectValueL<TUid>( |
|
1883 KMPXMediaGeneralCollectionId, media->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId)); |
|
1884 } |
|
1885 else |
|
1886 { |
|
1887 User::Leave(KErrNotFound); |
|
1888 } |
|
1889 CleanupStack::PopAndDestroy(media); |
|
1890 } |
|
1891 |
|
1892 // Update collection via command |
|
1893 // |
|
1894 CMPXCommand* cmd = CMPXCommand::NewL(); |
|
1895 CleanupStack::PushL( cmd ); |
|
1896 cmd->SetTObjectValueL( KMPXCommandGeneralId, KMPXCommandIdCollectionSet ); |
|
1897 cmd->SetTObjectValueL( KMPXCommandGeneralDoSync, ETrue ); |
|
1898 TUid colId = iMedia->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId); |
|
1899 cmd->SetTObjectValueL( KMPXCommandGeneralCollectionId, colId.iUid ); |
|
1900 cmd->SetCObjectValueL<CMPXMedia>( KMPXCommandColSetMedia, iMedia ); |
|
1901 |
|
1902 iCollection->Collection().CommandL( *cmd ); |
|
1903 CleanupStack::PopAndDestroy( cmd ); |
|
1904 |
|
1905 CompleteTask(iTask, KErrNone); |
|
1906 } |
|
1907 |
|
1908 // --------------------------------------------------------------------------- |
|
1909 // Export a playlist |
|
1910 // --------------------------------------------------------------------------- |
|
1911 // |
|
1912 void CMPXCollectionUiHelperImp::DoExportPlaylistL(TMPXItemId aPlaylistId, |
|
1913 const TDesC& aDestinationDriveAndPath) |
|
1914 { |
|
1915 // |
|
1916 // fill in playlist info |
|
1917 // |
|
1918 iMedia = CMPXMedia::NewL(); |
|
1919 |
|
1920 iMedia->SetTObjectValueL(KMPXMediaGeneralType, EMPXItem); |
|
1921 iMedia->SetTObjectValueL(KMPXMediaGeneralCategory, EMPXPlaylist); |
|
1922 iMedia->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, aPlaylistId); |
|
1923 |
|
1924 FillInPlaylistDetailsL(*iMedia); |
|
1925 |
|
1926 // |
|
1927 // find songs that are in the specified playlist |
|
1928 // |
|
1929 CMPXMedia* songQuery = CMPXMedia::NewL(); |
|
1930 CleanupStack::PushL(songQuery); |
|
1931 songQuery->SetTObjectValueL(KMPXMediaGeneralType, EMPXGroup); |
|
1932 songQuery->SetTObjectValueL(KMPXMediaGeneralCategory, EMPXSong); |
|
1933 songQuery->SetTObjectValueL(KMPXMediaGeneralId, aPlaylistId); |
|
1934 |
|
1935 RArray<TMPXAttribute> songAttributes; |
|
1936 CleanupClosePushL(songAttributes); |
|
1937 iHarvester->RequiredAttributesL( EMPXPlaylistTypeM3U, songAttributes ); |
|
1938 songAttributes.AppendL(KMPXMediaGeneralTitle); |
|
1939 |
|
1940 CMPXMedia* songQueryResult = |
|
1941 iCollection->Collection().FindAllL(*songQuery, songAttributes.Array()); |
|
1942 CleanupStack::PopAndDestroy(&songAttributes); |
|
1943 CleanupStack::PopAndDestroy(songQuery); |
|
1944 CleanupStack::PushL(songQueryResult); |
|
1945 |
|
1946 // medias contains tracks currently in the playlist |
|
1947 const CMPXMediaArray* medias = |
|
1948 songQueryResult->Value<CMPXMediaArray>(KMPXMediaArrayContents); |
|
1949 if( !medias ) |
|
1950 { |
|
1951 User::Leave( KErrNoMemory ); |
|
1952 } |
|
1953 |
|
1954 // add media array to iMedia |
|
1955 iMedia->SetCObjectValueL( |
|
1956 KMPXMediaArrayContents, const_cast<CMPXMediaArray*>(medias)); |
|
1957 iMedia->SetTObjectValueL( |
|
1958 KMPXMediaArrayCount, medias->Count()); |
|
1959 |
|
1960 CleanupStack::PopAndDestroy(songQueryResult); |
|
1961 |
|
1962 // export playlist, default to M3U file type. When ExportPlaylistL completes, |
|
1963 // HandlePlaylistExportCompletedL will be called |
|
1964 iHarvester->ExportPlaylistL( *iMedia, aDestinationDriveAndPath, EMPXPlaylistTypeM3U, this ); |
|
1965 } |
|
1966 |
|
1967 // --------------------------------------------------------------------------- |
|
1968 // Reorder a song in a playlist |
|
1969 // --------------------------------------------------------------------------- |
|
1970 // |
|
1971 void CMPXCollectionUiHelperImp::DoReorderPlaylistL(CMPXCommand& aCommand) |
|
1972 { |
|
1973 // Update collection via command |
|
1974 // |
|
1975 aCommand.SetTObjectValueL( KMPXCommandGeneralId, KMPXCommandIdReorderPlaylist ); |
|
1976 aCommand.SetTObjectValueL( KMPXCommandGeneralDoSync, ETrue ); |
|
1977 |
|
1978 iCollection->Collection().CommandL( aCommand ); |
|
1979 |
|
1980 CompleteTask(iTask, KErrNone); |
|
1981 } |
|
1982 |
|
1983 // --------------------------------------------------------------------------- |
|
1984 // retrieve information for the required attributes |
|
1985 // --------------------------------------------------------------------------- |
|
1986 // |
|
1987 void CMPXCollectionUiHelperImp::FillInPlaylistDetailsL(CMPXMedia& aMedia) |
|
1988 { |
|
1989 MPX_FUNC("CMPXCollectionUiHelperImp::FillInPlaylistDetailsL"); |
|
1990 |
|
1991 // |
|
1992 // retrieve info about the playlist itself |
|
1993 // |
|
1994 RArray<TMPXAttribute> playlistAttributes; |
|
1995 CleanupClosePushL(playlistAttributes); |
|
1996 playlistAttributes.AppendL(KMPXMediaGeneralId); |
|
1997 playlistAttributes.AppendL(KMPXMediaGeneralTitle); |
|
1998 playlistAttributes.AppendL(KMPXMediaGeneralUri); |
|
1999 playlistAttributes.AppendL(KMPXMediaGeneralCollectionId); |
|
2000 |
|
2001 CMPXMedia* playlistSearchResult = |
|
2002 iCollection->Collection().FindAllL(aMedia, playlistAttributes.Array()); |
|
2003 CleanupStack::PopAndDestroy(&playlistAttributes); |
|
2004 CleanupStack::PushL(playlistSearchResult); |
|
2005 |
|
2006 const CMPXMediaArray* results = |
|
2007 playlistSearchResult->Value<CMPXMediaArray>(KMPXMediaArrayContents); |
|
2008 if( !results ) |
|
2009 { |
|
2010 User::Leave( KErrNoMemory ); |
|
2011 } |
|
2012 |
|
2013 if ( results->Count() != 1 ) |
|
2014 { |
|
2015 User::Leave(KErrArgument); |
|
2016 } |
|
2017 |
|
2018 MPX_DEBUG1("playlist found"); |
|
2019 |
|
2020 aMedia.SetTObjectValueL( |
|
2021 KMPXMediaGeneralId, results->AtL(0)->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)); |
|
2022 aMedia.SetTextValueL( |
|
2023 KMPXMediaGeneralTitle, results->AtL(0)->ValueText(KMPXMediaGeneralTitle)); |
|
2024 aMedia.SetTextValueL( |
|
2025 KMPXMediaGeneralUri, results->AtL(0)->ValueText(KMPXMediaGeneralUri)); |
|
2026 aMedia.SetTObjectValueL( |
|
2027 KMPXMediaGeneralCollectionId, results->AtL(0)->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId)); |
|
2028 |
|
2029 CleanupStack::PopAndDestroy(playlistSearchResult); |
|
2030 } |
|
2031 |
|
2032 // --------------------------------------------------------------------------- |
|
2033 // retrieve collection from URI |
|
2034 // ResolvePlugin should be able to resolve the plugin without |
|
2035 // the client looking for the collection Id |
|
2036 // --------------------------------------------------------------------------- |
|
2037 // |
|
2038 TInt CMPXCollectionUiHelperImp::FindCollectionIdL(const TDesC& aUri) |
|
2039 { |
|
2040 MPX_FUNC("CMPXCollectionUiHelperImp::FindCollectionIdL"); |
|
2041 |
|
2042 TInt collectionId(KErrNotFound); |
|
2043 |
|
2044 TParsePtrC parser( aUri ); |
|
2045 |
|
2046 RPointerArray<CMPXCollectionType> collectionType; |
|
2047 iCollection->Collection().GetSupportedTypesL(collectionType); |
|
2048 |
|
2049 TInt index(KErrNotFound); |
|
2050 TInt count( collectionType.Count() ); |
|
2051 |
|
2052 for (TInt i = 0; i < count; i++) |
|
2053 { |
|
2054 const CDesCArray& extensions = collectionType[i]->Extensions(); |
|
2055 |
|
2056 if (extensions.FindIsq(parser.Ext(), index) == 0) |
|
2057 { |
|
2058 collectionId = collectionType[i]->Uid().iUid; |
|
2059 break; |
|
2060 } |
|
2061 } |
|
2062 |
|
2063 collectionType.ResetAndDestroy(); |
|
2064 |
|
2065 MPX_DEBUG3("Uid 0x%x for %S", collectionId, &aUri); |
|
2066 |
|
2067 return collectionId; |
|
2068 } |
|
2069 |
|
2070 // End of file |