|
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: implementation of collection path |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <s32strm.h> |
|
19 #include <e32panic.h> |
|
20 #include <mpxuser.h> |
|
21 #include <mpxcmn.h> |
|
22 #include <mpxattribute.h> |
|
23 #include <mpxdata.h> |
|
24 #include "mpxcollectionpath.h" |
|
25 |
|
26 /** |
|
27 * Encapsulates single node in collection hierarchy level. A node represents a |
|
28 * level of the collection path |
|
29 */ |
|
30 NONSHARABLE_CLASS(CMPXCollectionPathNode) : public CBase |
|
31 { |
|
32 public: |
|
33 static CMPXCollectionPathNode* NewL(); |
|
34 static CMPXCollectionPathNode* NewLC(); |
|
35 static CMPXCollectionPathNode* NewLC(const CMPXCollectionPathNode& aNode); |
|
36 virtual ~CMPXCollectionPathNode(); |
|
37 public: |
|
38 /** |
|
39 * Sets current item at this level |
|
40 */ |
|
41 void Set(const TMPXItemId& aId, TInt aIndex); |
|
42 |
|
43 /** |
|
44 * Sets the next level open mode |
|
45 */ |
|
46 void Set(TMPXOpenMode aRequest); |
|
47 |
|
48 /** |
|
49 * Sets the next level open attributes |
|
50 */ |
|
51 void SetL(const TArray<TMPXAttribute>& aAttrs); |
|
52 |
|
53 /** |
|
54 * Current index |
|
55 */ |
|
56 TInt Index() const; |
|
57 |
|
58 /** |
|
59 * Current Id |
|
60 */ |
|
61 const TMPXItemId& Id() const; |
|
62 |
|
63 /** |
|
64 * Open mode for next level |
|
65 */ |
|
66 TMPXOpenMode OpenMode() const; |
|
67 |
|
68 /** |
|
69 * Open attributes for next level |
|
70 */ |
|
71 const TArray<TMPXAttribute> OpenAttributes() const; |
|
72 |
|
73 public: |
|
74 void ExternalizeL(RWriteStream& aStream) const; |
|
75 void InternalizeL(RReadStream& aStream); |
|
76 |
|
77 private: |
|
78 CMPXCollectionPathNode(); |
|
79 void ConstructL(const CMPXCollectionPathNode& aNode); |
|
80 void ConstructL(); |
|
81 |
|
82 private: |
|
83 TMPXItemId iId; |
|
84 TInt iIndex; |
|
85 TMPXOpenMode iOpenMode; |
|
86 RArray<TMPXAttribute> iAttrs; // Open attributes for next level |
|
87 }; |
|
88 |
|
89 |
|
90 // ----------------------------------------------------------------------------- |
|
91 // CMPXCollectionPathNode::NewL |
|
92 // ----------------------------------------------------------------------------- |
|
93 // |
|
94 CMPXCollectionPathNode* CMPXCollectionPathNode::NewL() |
|
95 { |
|
96 CMPXCollectionPathNode* self = NewLC(); |
|
97 CleanupStack::Pop(self); |
|
98 return self; |
|
99 } |
|
100 |
|
101 // ----------------------------------------------------------------------------- |
|
102 // CMPXCollectionPathNode::NewLC |
|
103 // ----------------------------------------------------------------------------- |
|
104 // |
|
105 CMPXCollectionPathNode* CMPXCollectionPathNode::NewLC() |
|
106 { |
|
107 CMPXCollectionPathNode* self = new(ELeave) CMPXCollectionPathNode(); |
|
108 CleanupStack::PushL(self); |
|
109 self->ConstructL(); |
|
110 return self; |
|
111 } |
|
112 |
|
113 // ----------------------------------------------------------------------------- |
|
114 // CMPXCollectionPathNode::NewLC |
|
115 // ----------------------------------------------------------------------------- |
|
116 // |
|
117 CMPXCollectionPathNode* CMPXCollectionPathNode::NewLC( |
|
118 const CMPXCollectionPathNode& aNode) |
|
119 { |
|
120 CMPXCollectionPathNode* self = new(ELeave) CMPXCollectionPathNode(); |
|
121 CleanupStack::PushL(self); |
|
122 self->ConstructL(aNode); |
|
123 return self; |
|
124 } |
|
125 |
|
126 // ----------------------------------------------------------------------------- |
|
127 // CMPXCollectionPathNode::ConstructL |
|
128 // ----------------------------------------------------------------------------- |
|
129 // |
|
130 void CMPXCollectionPathNode::ConstructL() |
|
131 { |
|
132 } |
|
133 |
|
134 // ----------------------------------------------------------------------------- |
|
135 // CMPXCollectionPathNode::ConstructL |
|
136 // ----------------------------------------------------------------------------- |
|
137 // |
|
138 void CMPXCollectionPathNode::ConstructL( |
|
139 const CMPXCollectionPathNode& aNode) |
|
140 { |
|
141 iId=aNode.iId; |
|
142 iIndex=aNode.iIndex; |
|
143 iOpenMode=aNode.iOpenMode; |
|
144 ::CopyArrayL<TMPXAttribute>(aNode.iAttrs.Array(), iAttrs); |
|
145 } |
|
146 |
|
147 // ----------------------------------------------------------------------------- |
|
148 // CMPXCollectionPathNode::CMPXCollectionPathNode |
|
149 // ----------------------------------------------------------------------------- |
|
150 // |
|
151 CMPXCollectionPathNode::CMPXCollectionPathNode() |
|
152 : iId(KMPXInvalidItemId), |
|
153 iIndex(KErrNotFound), |
|
154 iOpenMode(EMPXOpenGroupOrPlaylist) |
|
155 { |
|
156 } |
|
157 |
|
158 // ----------------------------------------------------------------------------- |
|
159 // CMPXCollectionPathNode::~CMPXCollectionPathNode |
|
160 // ----------------------------------------------------------------------------- |
|
161 // |
|
162 CMPXCollectionPathNode::~CMPXCollectionPathNode() |
|
163 { |
|
164 iAttrs.Close(); |
|
165 } |
|
166 |
|
167 // ----------------------------------------------------------------------------- |
|
168 // CMPXCollectionPathNode::Set |
|
169 // ----------------------------------------------------------------------------- |
|
170 // |
|
171 void CMPXCollectionPathNode::Set(const TMPXItemId& aId, TInt aIndex) |
|
172 { |
|
173 iId=aId; |
|
174 iIndex=aIndex; |
|
175 } |
|
176 |
|
177 // ----------------------------------------------------------------------------- |
|
178 // CMPXCollectionPathNode::Set |
|
179 // ----------------------------------------------------------------------------- |
|
180 // |
|
181 void CMPXCollectionPathNode::Set(TMPXOpenMode aMode) |
|
182 { |
|
183 iOpenMode=aMode; |
|
184 } |
|
185 |
|
186 // ----------------------------------------------------------------------------- |
|
187 // CMPXCollectionPathNode::Set |
|
188 // ----------------------------------------------------------------------------- |
|
189 // |
|
190 void CMPXCollectionPathNode::SetL(const TArray<TMPXAttribute>& aAttrs) |
|
191 { |
|
192 ::CopyArrayL(aAttrs, iAttrs); |
|
193 } |
|
194 |
|
195 // ----------------------------------------------------------------------------- |
|
196 // CMPXCollectionPathNode::Index |
|
197 // ----------------------------------------------------------------------------- |
|
198 // |
|
199 TInt CMPXCollectionPathNode::Index() const |
|
200 { |
|
201 return iIndex; |
|
202 } |
|
203 |
|
204 // ----------------------------------------------------------------------------- |
|
205 // CMPXCollectionPathNode::Id |
|
206 // ----------------------------------------------------------------------------- |
|
207 // |
|
208 const TMPXItemId& CMPXCollectionPathNode::Id() const |
|
209 { |
|
210 return iId; |
|
211 } |
|
212 |
|
213 // ----------------------------------------------------------------------------- |
|
214 // CMPXCollectionPathNode::OpenMode |
|
215 // ----------------------------------------------------------------------------- |
|
216 // |
|
217 TMPXOpenMode CMPXCollectionPathNode::OpenMode() const |
|
218 { |
|
219 return iOpenMode; |
|
220 } |
|
221 |
|
222 // ----------------------------------------------------------------------------- |
|
223 // CMPXCollectionPathNode::OpenAttributes |
|
224 // ----------------------------------------------------------------------------- |
|
225 // |
|
226 const TArray<TMPXAttribute> CMPXCollectionPathNode::OpenAttributes() const |
|
227 { |
|
228 return iAttrs.Array(); |
|
229 } |
|
230 |
|
231 // ----------------------------------------------------------------------------- |
|
232 // Externalize object |
|
233 // ----------------------------------------------------------------------------- |
|
234 // |
|
235 void CMPXCollectionPathNode::ExternalizeL(RWriteStream& aStream) const |
|
236 { |
|
237 aStream.WriteUint32L(iId.iId1); |
|
238 aStream.WriteUint32L(iId.iId2); |
|
239 aStream.WriteInt32L(iIndex); |
|
240 aStream.WriteInt32L(iOpenMode); |
|
241 ::ExternalizeL(iAttrs.Array(), aStream); |
|
242 } |
|
243 |
|
244 // ----------------------------------------------------------------------------- |
|
245 // Internalize object |
|
246 // ----------------------------------------------------------------------------- |
|
247 // |
|
248 void CMPXCollectionPathNode::InternalizeL(RReadStream& aStream) |
|
249 { |
|
250 TUint32 id1 = aStream.ReadUint32L(); |
|
251 TUint32 id2 = aStream.ReadUint32L(); |
|
252 iId=TMPXItemId( id1, id2 ); |
|
253 iIndex=aStream.ReadInt32L(); |
|
254 iOpenMode=static_cast<TMPXOpenMode>(aStream.ReadInt32L()); |
|
255 iAttrs.Reset(); |
|
256 ::InternalizeL(iAttrs, aStream); |
|
257 } |
|
258 |
|
259 // ============================== MEMBER FUNCTIONS ============================= |
|
260 |
|
261 // ----------------------------------------------------------------------------- |
|
262 // Two-phased constructor. |
|
263 // ----------------------------------------------------------------------------- |
|
264 // |
|
265 EXPORT_C CMPXCollectionPath* CMPXCollectionPath::NewL() |
|
266 { |
|
267 CMPXCollectionPath* p = new(ELeave) CMPXCollectionPath(); |
|
268 CleanupStack::PushL(p); |
|
269 p->ConstructL(); |
|
270 CleanupStack::Pop(p); |
|
271 return p; |
|
272 } |
|
273 |
|
274 // ----------------------------------------------------------------------------- |
|
275 // Two-phased constructor. |
|
276 // ----------------------------------------------------------------------------- |
|
277 // |
|
278 EXPORT_C CMPXCollectionPath* CMPXCollectionPath::NewL( |
|
279 const CMPXCollectionPath& aPath) |
|
280 { |
|
281 CMPXCollectionPath* p = new(ELeave) CMPXCollectionPath(); |
|
282 CleanupStack::PushL(p); |
|
283 p->ConstructL(aPath); |
|
284 CleanupStack::Pop(p); |
|
285 return p; |
|
286 } |
|
287 |
|
288 // ----------------------------------------------------------------------------- |
|
289 // Two-phased constructor. |
|
290 // ----------------------------------------------------------------------------- |
|
291 // |
|
292 EXPORT_C CMPXCollectionPath* CMPXCollectionPath::NewL( |
|
293 RReadStream& aStream) |
|
294 { |
|
295 CMPXCollectionPath* p = new(ELeave) CMPXCollectionPath(); |
|
296 CleanupStack::PushL(p); |
|
297 p->ConstructL(aStream); |
|
298 CleanupStack::Pop(p); |
|
299 return p; |
|
300 } |
|
301 |
|
302 // ----------------------------------------------------------------------------- |
|
303 // Destructor |
|
304 // ----------------------------------------------------------------------------- |
|
305 // |
|
306 EXPORT_C CMPXCollectionPath::~CMPXCollectionPath() |
|
307 { |
|
308 iNodeArray.ResetAndDestroy(); |
|
309 iNodeArray.Close(); |
|
310 iIds.Close(); |
|
311 iSelection.Close(); |
|
312 } |
|
313 |
|
314 // ----------------------------------------------------------------------------- |
|
315 // Default constructor |
|
316 // ----------------------------------------------------------------------------- |
|
317 // |
|
318 CMPXCollectionPath::CMPXCollectionPath() : iInvalidId(KMPXInvalidItemId) |
|
319 { |
|
320 } |
|
321 |
|
322 // ---------------------------------------------------------------------------- |
|
323 // 2nd phase constructor. |
|
324 // ---------------------------------------------------------------------------- |
|
325 // |
|
326 void CMPXCollectionPath::ConstructL(const CMPXCollectionPath& aPath) |
|
327 { |
|
328 iNodeArray.ResetAndDestroy(); |
|
329 TInt count = aPath.iNodeArray.Count(); |
|
330 for (TInt i=0; i<count; ++i) |
|
331 { |
|
332 CMPXCollectionPathNode* node = |
|
333 CMPXCollectionPathNode::NewLC(*(aPath.iNodeArray[i])); |
|
334 iNodeArray.AppendL(node); |
|
335 CleanupStack::Pop(node); |
|
336 } |
|
337 ::CopyArrayL(aPath.iIds.Array(),iIds); |
|
338 ::CopyArrayL(aPath.iSelection.Array(),iSelection); |
|
339 } |
|
340 |
|
341 // ---------------------------------------------------------------------------- |
|
342 // 2nd phase constructor. |
|
343 // ---------------------------------------------------------------------------- |
|
344 // |
|
345 void CMPXCollectionPath::ConstructL() |
|
346 { |
|
347 } |
|
348 |
|
349 // ---------------------------------------------------------------------------- |
|
350 // 2nd phase constructor. |
|
351 // ---------------------------------------------------------------------------- |
|
352 // |
|
353 void CMPXCollectionPath::ConstructL(RReadStream& aStream) |
|
354 { |
|
355 InternalizeL(aStream); |
|
356 } |
|
357 |
|
358 // ----------------------------------------------------------------------------- |
|
359 // Advances path to next item |
|
360 // ----------------------------------------------------------------------------- |
|
361 // |
|
362 EXPORT_C TBool CMPXCollectionPath::operator++() |
|
363 { |
|
364 TBool ret(EFalse); |
|
365 TInt index=Index(); |
|
366 if (index < Count()-1) |
|
367 { |
|
368 Set(++index); |
|
369 ret=ETrue; |
|
370 } // else the last one, no more to go and return false |
|
371 return ret; |
|
372 } |
|
373 |
|
374 // ----------------------------------------------------------------------------- |
|
375 // Advances path to previous item |
|
376 // ----------------------------------------------------------------------------- |
|
377 // |
|
378 EXPORT_C TBool CMPXCollectionPath::operator--() |
|
379 { |
|
380 TBool ret=EFalse; |
|
381 TInt index=Index(); |
|
382 if (index>0) |
|
383 { |
|
384 Set(--index); |
|
385 ret=ETrue; |
|
386 } // else the first one, no more to go and return false |
|
387 return ret; |
|
388 } |
|
389 |
|
390 // ----------------------------------------------------------------------------- |
|
391 // Sets path to first item |
|
392 // ----------------------------------------------------------------------------- |
|
393 // |
|
394 EXPORT_C void CMPXCollectionPath::SetToFirst() |
|
395 { |
|
396 Set(0); |
|
397 } |
|
398 |
|
399 // ----------------------------------------------------------------------------- |
|
400 // Sets path to last item |
|
401 // ----------------------------------------------------------------------------- |
|
402 // |
|
403 EXPORT_C void CMPXCollectionPath::SetToLast() |
|
404 { |
|
405 Set(Count()-1); |
|
406 } |
|
407 |
|
408 // ----------------------------------------------------------------------------- |
|
409 // Change current item by index at top level |
|
410 // ----------------------------------------------------------------------------- |
|
411 // |
|
412 EXPORT_C void CMPXCollectionPath::Set(TInt aIndex) |
|
413 { |
|
414 MPX_ASSERT(Levels()); |
|
415 CMPXCollectionPathNode& topLevel = TopLevel(); |
|
416 // RArray will panic if aIndex out of bound |
|
417 topLevel.Set(iIds[aIndex], aIndex); |
|
418 } |
|
419 |
|
420 // ----------------------------------------------------------------------------- |
|
421 // Change current item by id at top level |
|
422 // ----------------------------------------------------------------------------- |
|
423 // |
|
424 EXPORT_C void CMPXCollectionPath::Set(const TMPXItemId& aId) |
|
425 { |
|
426 TInt index=IndexOfId(aId); |
|
427 MPX_ASSERT(KErrNotFound!=index && Levels()); |
|
428 CMPXCollectionPathNode& topLevel = TopLevel(); |
|
429 topLevel.Set(aId, index); |
|
430 } |
|
431 |
|
432 // ----------------------------------------------------------------------------- |
|
433 // Set open mode for next level |
|
434 // ----------------------------------------------------------------------------- |
|
435 // |
|
436 EXPORT_C void CMPXCollectionPath::Set(TMPXOpenMode aMode) |
|
437 { |
|
438 MPX_ASSERT(Levels()); |
|
439 TopLevel().Set(aMode); |
|
440 } |
|
441 |
|
442 // ----------------------------------------------------------------------------- |
|
443 // Set open attrobutes for next level |
|
444 // ----------------------------------------------------------------------------- |
|
445 // |
|
446 EXPORT_C void CMPXCollectionPath::Set(const TArray<TMPXAttribute>& aAttrs) |
|
447 { // DEPRECATED |
|
448 TRAP_IGNORE(SetL(aAttrs)); |
|
449 } |
|
450 |
|
451 // ----------------------------------------------------------------------------- |
|
452 // Set open attrobutes for next level |
|
453 // ----------------------------------------------------------------------------- |
|
454 // |
|
455 EXPORT_C void CMPXCollectionPath::SetL(const TArray<TMPXAttribute>& aAttrs) |
|
456 { |
|
457 MPX_ASSERT(Levels()); |
|
458 TopLevel().SetL(aAttrs); |
|
459 } |
|
460 |
|
461 // ----------------------------------------------------------------------------- |
|
462 // Select an item by id in the path |
|
463 // ----------------------------------------------------------------------------- |
|
464 // |
|
465 EXPORT_C void CMPXCollectionPath::SelectL(const TMPXItemId& aId) |
|
466 { |
|
467 TInt index=IndexOfId(aId); |
|
468 MPX_ASSERT(KErrNotFound != index); |
|
469 SelectL(index); |
|
470 } |
|
471 |
|
472 // ----------------------------------------------------------------------------- |
|
473 // Select an item by index in the path |
|
474 // ----------------------------------------------------------------------------- |
|
475 // |
|
476 EXPORT_C void CMPXCollectionPath::SelectL(TInt aIndex) |
|
477 { |
|
478 MPX_ASSERT_EX(aIndex>=0 && aIndex<iIds.Count(), EBadArrayIndex); |
|
479 TInt err = iSelection.InsertInOrder(aIndex); |
|
480 if (KErrNone!=err && KErrAlreadyExists!=err) |
|
481 { // ignore duplicated items |
|
482 User::Leave(err); |
|
483 } |
|
484 } |
|
485 |
|
486 // ----------------------------------------------------------------------------- |
|
487 // Select an item by index in the path |
|
488 // ----------------------------------------------------------------------------- |
|
489 // |
|
490 EXPORT_C void CMPXCollectionPath::SelectAllL() |
|
491 { |
|
492 iSelection.Reset(); |
|
493 for (TInt i=0; i < iIds.Count(); ++i) |
|
494 { |
|
495 iSelection.AppendL(i); |
|
496 } |
|
497 } |
|
498 |
|
499 // ----------------------------------------------------------------------------- |
|
500 // Deselects an item by id in the path |
|
501 // ----------------------------------------------------------------------------- |
|
502 // |
|
503 EXPORT_C void CMPXCollectionPath::Deselect(const TMPXItemId& aId) |
|
504 { |
|
505 TInt index=IndexOfId(aId); |
|
506 MPX_ASSERT(KErrNotFound != index); |
|
507 Deselect(index); |
|
508 } |
|
509 |
|
510 // ----------------------------------------------------------------------------- |
|
511 // Deselects an item by index in the path |
|
512 // ----------------------------------------------------------------------------- |
|
513 // |
|
514 EXPORT_C void CMPXCollectionPath::Deselect(TInt aIndex) |
|
515 { |
|
516 MPX_ASSERT_EX(aIndex>=0 && aIndex<iIds.Count(), EBadArrayIndex); |
|
517 TInt index(iSelection.FindInOrder(aIndex)); |
|
518 MPX_ASSERT(KErrNotFound !=index); |
|
519 iSelection.Remove(index); |
|
520 } |
|
521 |
|
522 // ----------------------------------------------------------------------------- |
|
523 // Select an item by index in the path |
|
524 // ----------------------------------------------------------------------------- |
|
525 // |
|
526 EXPORT_C void CMPXCollectionPath::DeselectAll() |
|
527 { |
|
528 iSelection.Reset(); |
|
529 } |
|
530 |
|
531 // ----------------------------------------------------------------------------- |
|
532 // Removes an item in the path |
|
533 // ----------------------------------------------------------------------------- |
|
534 // |
|
535 EXPORT_C void CMPXCollectionPath::Remove(const TMPXItemId& aId) |
|
536 { |
|
537 TInt index=IndexOfId(aId); |
|
538 MPX_ASSERT(KErrNotFound != index); |
|
539 Remove(index); |
|
540 } |
|
541 |
|
542 // ----------------------------------------------------------------------------- |
|
543 // Removes an item in the path |
|
544 // ----------------------------------------------------------------------------- |
|
545 // |
|
546 EXPORT_C void CMPXCollectionPath::Remove(TInt aIndex) |
|
547 { |
|
548 iIds.Remove(aIndex); |
|
549 TInt ret = iSelection.FindInOrder(aIndex); |
|
550 if (KErrNotFound != ret) |
|
551 { |
|
552 iSelection.Remove(ret); |
|
553 TInt count = iSelection.Count(); |
|
554 for (TInt i=ret; i<count; i++) |
|
555 { |
|
556 --iSelection[i]; |
|
557 } |
|
558 } |
|
559 } |
|
560 |
|
561 // ----------------------------------------------------------------------------- |
|
562 // Query selection |
|
563 // ----------------------------------------------------------------------------- |
|
564 // |
|
565 EXPORT_C TBool CMPXCollectionPath::IsSelected(const TMPXItemId& aId) const |
|
566 { |
|
567 TBool ret(EFalse); |
|
568 TInt index=IndexOfId(aId); |
|
569 if (KErrNotFound != index) |
|
570 { |
|
571 ret = IsSelected(index); |
|
572 } |
|
573 return ret; |
|
574 } |
|
575 |
|
576 // ----------------------------------------------------------------------------- |
|
577 // Query selection |
|
578 // ----------------------------------------------------------------------------- |
|
579 // |
|
580 EXPORT_C TBool CMPXCollectionPath::IsSelected(TInt aIndex) const |
|
581 { |
|
582 return iSelection.FindInOrder(aIndex) != KErrNotFound; |
|
583 } |
|
584 |
|
585 // ----------------------------------------------------------------------------- |
|
586 // Clears selection |
|
587 // ----------------------------------------------------------------------------- |
|
588 // |
|
589 EXPORT_C void CMPXCollectionPath::ClearSelection() |
|
590 { |
|
591 iSelection.Reset(); |
|
592 } |
|
593 |
|
594 // ----------------------------------------------------------------------------- |
|
595 // Array of currently selected indices |
|
596 // ----------------------------------------------------------------------------- |
|
597 // |
|
598 EXPORT_C TArray<TInt> CMPXCollectionPath::Selection() const |
|
599 { |
|
600 return iSelection.Array(); |
|
601 } |
|
602 |
|
603 // ----------------------------------------------------------------------------- |
|
604 // Current selected IDs |
|
605 // ----------------------------------------------------------------------------- |
|
606 // |
|
607 EXPORT_C void CMPXCollectionPath::SelectionL(RArray<TMPXItemId>& aIds) const |
|
608 { |
|
609 aIds.Reset(); |
|
610 TInt idCount(iIds.Count()); |
|
611 TInt selCount(iSelection.Count()); |
|
612 for (TInt i=0; i<selCount; ++i) |
|
613 { |
|
614 TInt idIndex(iSelection[i]); |
|
615 if (idIndex < idCount) |
|
616 { |
|
617 aIds.AppendL(iIds[idIndex]); |
|
618 } |
|
619 } |
|
620 } |
|
621 |
|
622 // ----------------------------------------------------------------------------- |
|
623 // Update the item id at a particular index |
|
624 // ----------------------------------------------------------------------------- |
|
625 // |
|
626 EXPORT_C void CMPXCollectionPath::Update( TInt aIndex, TMPXItemId& aNewId ) |
|
627 { |
|
628 MPX_ASSERT( aIndex >= 0 && aIndex < iIds.Count() ); |
|
629 iIds[aIndex] = aNewId; |
|
630 } |
|
631 |
|
632 // ----------------------------------------------------------------------------- |
|
633 // Index of current item at top level |
|
634 // ----------------------------------------------------------------------------- |
|
635 // |
|
636 EXPORT_C TInt CMPXCollectionPath::Index() const |
|
637 { |
|
638 TInt ret(KErrNotFound); |
|
639 if (Levels()) |
|
640 { |
|
641 ret = TopLevel().Index(); |
|
642 } |
|
643 return ret; |
|
644 } |
|
645 |
|
646 // ----------------------------------------------------------------------------- |
|
647 // Return current item id at top level |
|
648 // ----------------------------------------------------------------------------- |
|
649 // |
|
650 EXPORT_C const TMPXItemId& CMPXCollectionPath::Id() const |
|
651 { |
|
652 if (Levels()) |
|
653 { |
|
654 return TopLevel().Id(); |
|
655 } |
|
656 else |
|
657 { |
|
658 return iInvalidId; |
|
659 } |
|
660 } |
|
661 |
|
662 // ----------------------------------------------------------------------------- |
|
663 // Returns the number of items at top level |
|
664 // ----------------------------------------------------------------------------- |
|
665 // |
|
666 EXPORT_C TInt CMPXCollectionPath::Count() const |
|
667 { |
|
668 return iIds.Count(); |
|
669 } |
|
670 |
|
671 // ----------------------------------------------------------------------------- |
|
672 // Returns the open mode for the next level |
|
673 // ----------------------------------------------------------------------------- |
|
674 // |
|
675 EXPORT_C TMPXOpenMode CMPXCollectionPath::OpenNextMode() const |
|
676 { |
|
677 return Levels() ? TopLevel().OpenMode():EMPXOpenGroupOrPlaylist; |
|
678 } |
|
679 |
|
680 // ----------------------------------------------------------------------------- |
|
681 // Returns the open mode for the previous level |
|
682 // ----------------------------------------------------------------------------- |
|
683 // |
|
684 EXPORT_C TMPXOpenMode CMPXCollectionPath::OpenPreviousMode() const |
|
685 { |
|
686 TInt n=Levels(); |
|
687 return n>1?iNodeArray[n-2]->OpenMode():EMPXOpenGroupOrPlaylist; |
|
688 } |
|
689 |
|
690 // ----------------------------------------------------------------------------- |
|
691 // Index from id |
|
692 // ----------------------------------------------------------------------------- |
|
693 // |
|
694 EXPORT_C TInt CMPXCollectionPath::IndexOfId(const TMPXItemId& aId) const |
|
695 { |
|
696 TInt ret(KErrNotFound); |
|
697 for (TInt i=iIds.Count(); --i>=0; ) |
|
698 { |
|
699 if (aId == iIds[i]) |
|
700 { |
|
701 ret = i; |
|
702 break; |
|
703 } |
|
704 } |
|
705 return ret; |
|
706 } |
|
707 |
|
708 // ----------------------------------------------------------------------------- |
|
709 // Return item id at top specific level for a specific item |
|
710 // ----------------------------------------------------------------------------- |
|
711 // |
|
712 EXPORT_C const TMPXItemId& CMPXCollectionPath::IdOfIndex( TInt aIndex ) const |
|
713 { |
|
714 if( aIndex >=0 && aIndex < iIds.Count() ) |
|
715 { |
|
716 return iIds[aIndex]; |
|
717 } |
|
718 else |
|
719 { |
|
720 return iInvalidId; |
|
721 } |
|
722 } |
|
723 |
|
724 // ----------------------------------------------------------------------------- |
|
725 // Return item index at a specific level |
|
726 // ----------------------------------------------------------------------------- |
|
727 // |
|
728 EXPORT_C TInt CMPXCollectionPath::Index(TInt aLevel) const |
|
729 { |
|
730 MPX_ASSERT(aLevel>=0 && aLevel < Levels()); |
|
731 return iNodeArray[aLevel]->Index(); |
|
732 } |
|
733 |
|
734 // ----------------------------------------------------------------------------- |
|
735 // Return item id at a specific level |
|
736 // ----------------------------------------------------------------------------- |
|
737 // |
|
738 EXPORT_C const TMPXItemId& CMPXCollectionPath::Id(TInt aLevel) const |
|
739 { |
|
740 if( aLevel < iNodeArray.Count() && aLevel >= 0 ) |
|
741 { |
|
742 return iNodeArray[aLevel]->Id(); |
|
743 } |
|
744 else |
|
745 { |
|
746 return iInvalidId; |
|
747 } |
|
748 } |
|
749 |
|
750 // ----------------------------------------------------------------------------- |
|
751 // Returns the depth into the collection |
|
752 // ----------------------------------------------------------------------------- |
|
753 // |
|
754 EXPORT_C TInt CMPXCollectionPath::Levels() const |
|
755 { |
|
756 return iNodeArray.Count(); |
|
757 } |
|
758 |
|
759 // ----------------------------------------------------------------------------- |
|
760 // Remove a level from path |
|
761 // ----------------------------------------------------------------------------- |
|
762 // |
|
763 EXPORT_C void CMPXCollectionPath::Back() |
|
764 { |
|
765 TInt levels = Levels(); |
|
766 MPX_ASSERT(levels > 0); |
|
767 CMPXCollectionPathNode* node = iNodeArray[levels-1]; |
|
768 iNodeArray.Remove(levels-1); |
|
769 delete node; |
|
770 iIds.Reset(); |
|
771 iSelection.Reset(); |
|
772 } |
|
773 |
|
774 // ----------------------------------------------------------------------------- |
|
775 // Append a new level |
|
776 // ----------------------------------------------------------------------------- |
|
777 // |
|
778 EXPORT_C void CMPXCollectionPath::AppendL(const TArray<TMPXItemId>& aIds) |
|
779 { |
|
780 iIds.Reset(); |
|
781 iSelection.Reset(); |
|
782 CMPXCollectionPathNode* node(NULL); |
|
783 if (aIds.Count()) |
|
784 { |
|
785 ::CopyArrayL(aIds, iIds); |
|
786 node = CMPXCollectionPathNode::NewLC(); |
|
787 node->Set(iIds[0], 0); |
|
788 iNodeArray.AppendL(node); |
|
789 CleanupStack::Pop(node); |
|
790 } |
|
791 else |
|
792 {// add a level in order to support back |
|
793 node = CMPXCollectionPathNode::NewLC(); |
|
794 node->Set(iInvalidId, KErrNotFound); |
|
795 iNodeArray.AppendL(node); |
|
796 CleanupStack::Pop(node); |
|
797 } |
|
798 } |
|
799 |
|
800 // ----------------------------------------------------------------------------- |
|
801 // Append a new level |
|
802 // ----------------------------------------------------------------------------- |
|
803 // |
|
804 EXPORT_C void CMPXCollectionPath::AppendL(const TMPXItemId& aId) |
|
805 { |
|
806 RArray<TMPXItemId> ids; |
|
807 CleanupClosePushL(ids); |
|
808 ids.AppendL(aId); |
|
809 AppendL(ids.Array()); |
|
810 CleanupStack::PopAndDestroy(&ids); |
|
811 } |
|
812 |
|
813 // ----------------------------------------------------------------------------- |
|
814 // Append an id |
|
815 // ----------------------------------------------------------------------------- |
|
816 // |
|
817 EXPORT_C void CMPXCollectionPath::InsertL(const TMPXItemId& aId, TInt aPos) |
|
818 { |
|
819 MPX_ASSERT(iIds.Count()); |
|
820 iIds.InsertL(aId, aPos); |
|
821 // update the selection |
|
822 for (TInt i=0; i<iSelection.Count(); ++i) |
|
823 { |
|
824 TInt& sel = iSelection[i]; |
|
825 if (sel >=aPos) |
|
826 { |
|
827 ++sel; |
|
828 } |
|
829 } |
|
830 } |
|
831 |
|
832 // ----------------------------------------------------------------------------- |
|
833 // Resets the collection path object |
|
834 // ----------------------------------------------------------------------------- |
|
835 // |
|
836 EXPORT_C void CMPXCollectionPath::Reset() |
|
837 { |
|
838 iNodeArray.ResetAndDestroy(); |
|
839 iIds.Reset(); |
|
840 iSelection.Reset(); |
|
841 } |
|
842 |
|
843 // ----------------------------------------------------------------------------- |
|
844 // Creates a collection path pointing to the container |
|
845 // ----------------------------------------------------------------------------- |
|
846 // |
|
847 EXPORT_C CMPXCollectionPath* CMPXCollectionPath::ContainerPathL() const |
|
848 { |
|
849 CMPXCollectionPath* p = CMPXCollectionPath::NewL(); |
|
850 CleanupStack::PushL( p ); |
|
851 |
|
852 TInt count = iNodeArray.Count() - 1; // Copy up to container level |
|
853 for (TInt i=0; i<count; ++i) |
|
854 { |
|
855 CMPXCollectionPathNode* node = |
|
856 CMPXCollectionPathNode::NewLC(*iNodeArray[i]); |
|
857 p->iNodeArray.AppendL(node); |
|
858 CleanupStack::Pop(node); |
|
859 } |
|
860 |
|
861 CleanupStack::Pop( p ); |
|
862 return p; |
|
863 } |
|
864 |
|
865 // ----------------------------------------------------------------------------- |
|
866 // Update collection path. When a item changed in the collection plugin, |
|
867 // collection plugin calls back collection context, which in turn updates |
|
868 // its collection paths by calling this function |
|
869 // ----------------------------------------------------------------------------- |
|
870 // |
|
871 EXPORT_C TInt CMPXCollectionPath::HandleChange( |
|
872 const TUid& aCollectionId, |
|
873 const TMPXItemId& aId, |
|
874 const TMPXItemId& aDeprecatedId, |
|
875 CMPXCollectionPath::TMPXCollectionPathChange aChange, |
|
876 TInt& aSelection ) |
|
877 { |
|
878 TBool updated(EPathUnchanged); |
|
879 aSelection = KErrNotFound; |
|
880 |
|
881 if (aChange == CMPXCollectionPath::EAdded) |
|
882 { |
|
883 updated = EPathModified; |
|
884 } |
|
885 else if (aChange == CMPXCollectionPath::EGroupModified ) |
|
886 { |
|
887 TInt levels( Levels() ); |
|
888 if( levels > 0 ) |
|
889 { |
|
890 // Check if the collection id is correct |
|
891 if (iNodeArray[ECollectionUid]->Id() == |
|
892 TMPXItemId(aCollectionId.iUid) && levels > 1) |
|
893 { |
|
894 // Check if the container level is the one modified |
|
895 if( aId == Id( levels-2 ) ) |
|
896 { |
|
897 updated = EPathModified; |
|
898 } |
|
899 } |
|
900 } |
|
901 } |
|
902 else if (aChange == CMPXCollectionPath::EDeleted || |
|
903 aChange == CMPXCollectionPath::EModified) |
|
904 { |
|
905 TInt levels = Levels(); |
|
906 if (levels > 0) |
|
907 { |
|
908 // check collection id level, aka root level |
|
909 if (iNodeArray[ECollectionUid]->Id() == |
|
910 TMPXItemId(aCollectionId.iUid) && levels > 1) |
|
911 { |
|
912 // check node array except top level and root level. |
|
913 for (TInt i=ECollectionRoot+1; i<levels-1; ++i) |
|
914 { |
|
915 if (iNodeArray[i]->Id() == aId || |
|
916 (aDeprecatedId != 0 && iNodeArray[i]->Id() == aDeprecatedId)) |
|
917 { |
|
918 if( aChange == CMPXCollectionPath::EModified && |
|
919 aDeprecatedId != 0 ) |
|
920 { |
|
921 // If the item is modified and the item id is updated |
|
922 // we simply replace the node level item id with the new |
|
923 // item id |
|
924 // |
|
925 // Continue and check other levels if any other |
|
926 // levels are using this ID. ie: all songs of an artist |
|
927 // The item IDs need to be unique across all levels, but |
|
928 // can have duplicates. This is in the case of a playlist with |
|
929 // more than 1 instance of a song |
|
930 // |
|
931 CMPXCollectionPathNode* node = iNodeArray[i]; |
|
932 node->Set( aId, Index(i) ); |
|
933 updated = EPathModified; |
|
934 } |
|
935 else |
|
936 { |
|
937 // Trim the path and break out of the loop |
|
938 aSelection = Index(i); |
|
939 for (TInt j=Levels()-1; j>i; --j) |
|
940 { |
|
941 CMPXCollectionPathNode* node = iNodeArray[j]; |
|
942 iNodeArray.Remove(j); |
|
943 delete node; |
|
944 } |
|
945 updated = EPathClipped; |
|
946 break; |
|
947 } |
|
948 } |
|
949 } |
|
950 // Check the top level |
|
951 if (!updated) |
|
952 { |
|
953 TMPXItemId search = aDeprecatedId != 0? aDeprecatedId : aId; |
|
954 TInt temp(KErrNotFound); |
|
955 |
|
956 // Unmatched ids in the item ID, |
|
957 // try to look for an exact match first |
|
958 // |
|
959 if( search.iId1 != search.iId2 ) |
|
960 { |
|
961 for (TInt i=iIds.Count(); --i>=0; ) |
|
962 { |
|
963 if (search == iIds[i] ) |
|
964 { |
|
965 temp = i; |
|
966 break; |
|
967 } |
|
968 } |
|
969 } |
|
970 // Still not found, check for approximate equal |
|
971 // |
|
972 if( KErrNotFound == temp ) |
|
973 { |
|
974 for (TInt i=iIds.Count(); --i>=0; ) |
|
975 { |
|
976 if (search.ApproxEqual(iIds[i])) |
|
977 { |
|
978 temp = i; |
|
979 break; |
|
980 } |
|
981 } |
|
982 } |
|
983 if (KErrNotFound != temp) |
|
984 { // Improvement: only remove item deleted |
|
985 updated = EPathModified; |
|
986 aSelection = temp; |
|
987 } |
|
988 } |
|
989 |
|
990 // Only clean up level if the path has been clipped |
|
991 if (updated == EPathClipped ) |
|
992 { |
|
993 // Reset top level |
|
994 iIds.Reset(); |
|
995 iSelection.Reset(); |
|
996 } |
|
997 } |
|
998 } |
|
999 } |
|
1000 return updated; |
|
1001 } |
|
1002 |
|
1003 // ----------------------------------------------------------------------------- |
|
1004 // CMPXCollectionPath::OpenAttributes |
|
1005 // ----------------------------------------------------------------------------- |
|
1006 // |
|
1007 EXPORT_C const TArray<TMPXAttribute> CMPXCollectionPath::OpenAttributes() const |
|
1008 { |
|
1009 MPX_ASSERT(Levels()>0); |
|
1010 return TopLevel().OpenAttributes(); |
|
1011 } |
|
1012 |
|
1013 // ----------------------------------------------------------------------------- |
|
1014 // Get top level items |
|
1015 // ----------------------------------------------------------------------------- |
|
1016 // |
|
1017 EXPORT_C const TArray<TMPXItemId> CMPXCollectionPath::Items() const |
|
1018 { |
|
1019 MPX_ASSERT(Levels()>0); |
|
1020 return iIds.Array(); |
|
1021 } |
|
1022 |
|
1023 // ----------------------------------------------------------------------------- |
|
1024 // Internalize object |
|
1025 // ----------------------------------------------------------------------------- |
|
1026 // |
|
1027 EXPORT_C void CMPXCollectionPath::InternalizeL(RReadStream& aStream) |
|
1028 { |
|
1029 (void)aStream.ReadInt32L(); // Discard object type |
|
1030 iNodeArray.ResetAndDestroy(); |
|
1031 ::InternalizeCObjectArrayL(iNodeArray, aStream); |
|
1032 iIds.Reset(); |
|
1033 MPXUser::InternalizeL(iIds, aStream); |
|
1034 iSelection.Reset(); |
|
1035 ::InternalizeL(iSelection, aStream); |
|
1036 } |
|
1037 |
|
1038 // ----------------------------------------------------------------------------- |
|
1039 // Externalize object |
|
1040 // ----------------------------------------------------------------------------- |
|
1041 // |
|
1042 EXPORT_C void CMPXCollectionPath::ExternalizeL(RWriteStream& aStream) const |
|
1043 { |
|
1044 aStream.WriteInt32L(MMPXData::EPath); |
|
1045 ::ExternalizeL(iNodeArray.Array(), aStream); |
|
1046 MPXUser::ExternalizeL(iIds.Array(), aStream); |
|
1047 ::ExternalizeL(iSelection.Array(), aStream); |
|
1048 } |
|
1049 |
|
1050 // ----------------------------------------------------------------------------- |
|
1051 // Top level |
|
1052 // ----------------------------------------------------------------------------- |
|
1053 // |
|
1054 CMPXCollectionPathNode& CMPXCollectionPath::TopLevel() |
|
1055 { |
|
1056 MPX_ASSERT(Levels() > 0); |
|
1057 return *iNodeArray[Levels()-1]; |
|
1058 } |
|
1059 |
|
1060 // ----------------------------------------------------------------------------- |
|
1061 // Top level |
|
1062 // ----------------------------------------------------------------------------- |
|
1063 // |
|
1064 const CMPXCollectionPathNode& CMPXCollectionPath::TopLevel() const |
|
1065 { |
|
1066 MPX_ASSERT(Levels() > 0); |
|
1067 return *iNodeArray[Levels()-1]; |
|
1068 } |