clfwrapper/ClientSrc/CCLFDefaultOperation.cpp
changeset 0 c53acadfccc6
child 6 646a02f170b9
equal deleted inserted replaced
-1:000000000000 0:c53acadfccc6
       
     1 /*
       
     2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include    "CCLFDefaultOperation.h"
       
    22 #include    <MCLFSortingStyle.h>
       
    23 #include    <MCLFModifiableItem.h>
       
    24 #include    <ContentListingFactory.h>
       
    25 #include    <collate.h>
       
    26 #include    <badesca.h>
       
    27 #include    "MGDebugPrint.h"
       
    28 
       
    29 // CONSTANTS
       
    30 const TInt KCLFGroupedItemArrayGranularity( 4 );
       
    31 const TInt KCLFSortingStyleArrayGranularity( 3 );
       
    32 
       
    33 // CLASS DECLARATION
       
    34 
       
    35 /**
       
    36 *  Internal helper class for sorting
       
    37 */
       
    38 class TCLFSortingItem
       
    39     {
       
    40     public:
       
    41         TCLFSortingItem()
       
    42             : iData( KNullDesC ),
       
    43               iIntData( 0 ),
       
    44               iTimeData( 0 ),
       
    45               iItem( NULL )
       
    46             {
       
    47             }
       
    48 
       
    49         TPtrC iData;
       
    50         TInt32 iIntData;
       
    51         TTime iTimeData;
       
    52         MCLFItem* iItem;
       
    53     };
       
    54 
       
    55 // ============================= LOCAL FUNCTIONS ===============================
       
    56 
       
    57 // -----------------------------------------------------------------------------
       
    58 // CompareAlphaAscending
       
    59 // -----------------------------------------------------------------------------
       
    60 //
       
    61 TInt CompareAlphaAscending( const TCLFSortingItem& aFirst,
       
    62                             const TCLFSortingItem& aSecond )
       
    63     {
       
    64     // get the standard method
       
    65     TCollationMethod m = *Mem::CollationMethodByIndex( 0 );
       
    66     m.iFlags |= TCollationMethod::EIgnoreNone | TCollationMethod::EFoldCase;
       
    67     return aFirst.iData.CompareC( aSecond.iData, 3, &m  );
       
    68     }
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CompareIntAscending
       
    72 // -----------------------------------------------------------------------------
       
    73 //
       
    74 TInt CompareIntAscending( const TCLFSortingItem& aFirst,
       
    75                           const TCLFSortingItem& aSecond )
       
    76     {
       
    77     return aFirst.iIntData - aSecond.iIntData;
       
    78     }
       
    79 
       
    80 // -----------------------------------------------------------------------------
       
    81 // CompareTimeAscending
       
    82 // -----------------------------------------------------------------------------
       
    83 //
       
    84 TInt CompareTimeAscending( const TCLFSortingItem& aFirst,
       
    85                            const TCLFSortingItem& aSecond )
       
    86     {
       
    87     if ( aFirst.iTimeData > aSecond.iTimeData )
       
    88         {
       
    89         return 1;
       
    90         }
       
    91     else if ( aFirst.iTimeData < aSecond.iTimeData )
       
    92         {
       
    93         return -1;
       
    94         }
       
    95     return 0;
       
    96     }
       
    97 
       
    98 // -----------------------------------------------------------------------------
       
    99 // AppendItemsArrayL
       
   100 // -----------------------------------------------------------------------------
       
   101 //
       
   102 void AppendItemsToArrayL( const TArray<MCLFItem*>& aSourceArray,
       
   103                           RPointerArray<MCLFItem>& aDestArray )
       
   104     {
       
   105     const TInt count( aSourceArray.Count() );
       
   106     for( TInt i = 0 ; i < count ; ++i )
       
   107         {
       
   108         aDestArray.AppendL( aSourceArray[ i ] );
       
   109         }
       
   110     }
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // AppendItemsToArrayL
       
   114 // append aSourceArray items to aDestArray
       
   115 // -----------------------------------------------------------------------------
       
   116 //
       
   117 void AppendItemsToArrayL( const TArray<MCLFItem*>& aSourceArray,
       
   118                           RPointerArray<MCLFItem>& aDestArray,
       
   119                           TCLFUndefinedItemPosition aPosition,
       
   120                           TInt& aItemIndex,
       
   121                           TInt& aLastAddedItemCount )
       
   122     {
       
   123     if( aPosition == ECLFSortingStyleUndefinedFirst )
       
   124         {
       
   125         aItemIndex = aItemIndex - aLastAddedItemCount;
       
   126         }
       
   127 
       
   128     aLastAddedItemCount = aSourceArray.Count();
       
   129     for( TInt i = 0 ; i < aLastAddedItemCount ; ++i )
       
   130         {
       
   131         aDestArray.InsertL( aSourceArray[i], aItemIndex );
       
   132         ++aItemIndex;
       
   133         }
       
   134     }
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // AppendSortingItemsArrayL
       
   138 // -----------------------------------------------------------------------------
       
   139 //
       
   140 void AppendSortingItemsToArrayL( const TArray<TCLFSortingItem>& aSourceArray,
       
   141                                  RPointerArray<MCLFItem>& aDestArray )
       
   142     {
       
   143     const TInt count( aSourceArray.Count() );
       
   144     for( TInt i = 0 ; i < count ; ++i )
       
   145         {
       
   146         aDestArray.AppendL( aSourceArray[i].iItem );
       
   147         }
       
   148     }
       
   149 
       
   150 // -----------------------------------------------------------------------------
       
   151 // AppendSortingItemsArrayReverseL
       
   152 // -----------------------------------------------------------------------------
       
   153 //
       
   154 void AppendSortingItemsToArrayReverseL(
       
   155                         const TArray<TCLFSortingItem>& aSourceArray,
       
   156                         RPointerArray<MCLFItem>& aDestArray )
       
   157     {
       
   158     for( TInt i = aSourceArray.Count() - 1 ; i > -1 ; --i )
       
   159         {
       
   160         aDestArray.AppendL( aSourceArray[i].iItem );
       
   161         }
       
   162     }
       
   163 
       
   164 // -----------------------------------------------------------------------------
       
   165 // MakeSortingItemsL
       
   166 // Add/Make items to sorting item array and undefined items to
       
   167 // undefined item array
       
   168 // -----------------------------------------------------------------------------
       
   169 //
       
   170 void MakeSortingItemsL( RArray<TCLFSortingItem>& aSortingItemArray,
       
   171                         RPointerArray<MCLFItem>& aUndefinedItemArray,
       
   172                         const TArray<MCLFItem*>& aItemArray,
       
   173                         const TArray<TCLFFieldId> aSortFields,
       
   174                         TCLFItemDataType aSortingDataType )
       
   175     {
       
   176     MG_DEBUG1( MSI1, "MakeSortingItemsL start" );
       
   177 
       
   178     const TInt sortingFieldsCount( aSortFields.Count() );
       
   179     const TInt count( aItemArray.Count() );
       
   180     for( TInt i = 0 ; i < count ; ++i )
       
   181         {
       
   182         MCLFItem* seItem = aItemArray[i];
       
   183         TCLFSortingItem sortingItem;
       
   184         TInt fieldIdIndex( -1 );
       
   185         TInt error( KErrNone );
       
   186         do
       
   187             {
       
   188             ++fieldIdIndex;
       
   189             TCLFFieldId fieldId( aSortFields[fieldIdIndex] );
       
   190             switch( aSortingDataType )
       
   191                 {
       
   192                 case ECLFItemDataTypeDesC:
       
   193                     {
       
   194                     error = seItem->GetField( fieldId, sortingItem.iData );
       
   195                     break;
       
   196                     }
       
   197                 case ECLFItemDataTypeTInt32:
       
   198                     {
       
   199                     error = seItem->GetField( fieldId, sortingItem.iIntData );
       
   200                     break;
       
   201                     }
       
   202                 case ECLFItemDataTypeTTime:
       
   203                 default:
       
   204                     {
       
   205                     error = seItem->GetField( fieldId, sortingItem.iTimeData );
       
   206                     break;
       
   207                     }
       
   208                 }
       
   209             } while( ( error != KErrNone ) &&
       
   210                      ( fieldIdIndex < ( sortingFieldsCount - 1 ) ) );
       
   211         if( error == KErrNone )
       
   212             {
       
   213             sortingItem.iItem = seItem;
       
   214             aSortingItemArray.AppendL( sortingItem );
       
   215             }
       
   216         else
       
   217             { // field not found -> undefined item
       
   218             aUndefinedItemArray.AppendL( seItem );
       
   219             }
       
   220         }
       
   221 
       
   222     MG_DEBUG1( MSI2, "MakeSortingItemsL end" );
       
   223     }
       
   224 
       
   225 // -----------------------------------------------------------------------------
       
   226 // SortSortingItemsL
       
   227 // Select correct sortign operation
       
   228 // -----------------------------------------------------------------------------
       
   229 //
       
   230 void SortSortingItemsL( RArray<TCLFSortingItem>& aItemArray,
       
   231                         TCLFItemDataType aSortingDataType )
       
   232     {
       
   233     TLinearOrder<TCLFSortingItem>* sorter = NULL;
       
   234 
       
   235     switch ( aSortingDataType )
       
   236         {
       
   237         case ECLFItemDataTypeDesC:
       
   238             {
       
   239             sorter = new ( ELeave ) TLinearOrder<TCLFSortingItem>
       
   240                         ( CompareAlphaAscending );
       
   241             break;
       
   242             }
       
   243         case ECLFItemDataTypeTInt32:
       
   244             {
       
   245             sorter = new ( ELeave ) TLinearOrder<TCLFSortingItem>
       
   246                         ( CompareIntAscending );
       
   247             break;
       
   248             }
       
   249         case ECLFItemDataTypeTTime:
       
   250         default:
       
   251             {
       
   252             sorter = new ( ELeave ) TLinearOrder<TCLFSortingItem>
       
   253                         ( CompareTimeAscending );
       
   254             break;
       
   255             }
       
   256         }
       
   257 
       
   258     aItemArray.Sort( *sorter );
       
   259     delete sorter;
       
   260     sorter = NULL;
       
   261     }
       
   262 
       
   263 // -----------------------------------------------------------------------------
       
   264 // SortItemsBySortingStyleL
       
   265 // sort aItemArray with aSortingStyle
       
   266 // add undefined items to aUndefinedItemArray
       
   267 // -----------------------------------------------------------------------------
       
   268 //
       
   269 void SortItemsBySortingStyleL( RPointerArray<MCLFItem>& aItemArray,
       
   270                                MCLFSortingStyle& aSortingStyle,
       
   271                                RPointerArray<MCLFItem>& aUndefinedItemArray )
       
   272     {
       
   273     RArray<TCLFFieldId> sortingFields;
       
   274     CleanupClosePushL( sortingFields );
       
   275     aSortingStyle.GetFieldsL( sortingFields );
       
   276     const TInt sortingFieldsCount( sortingFields.Count() );
       
   277     if( sortingFieldsCount )  // sort only if there are sorting fields
       
   278         {
       
   279         TCLFItemDataType sortingDataType( aSortingStyle.SortingDataType() );
       
   280 
       
   281         RArray<TCLFSortingItem> sortingArray;
       
   282         CleanupClosePushL( sortingArray );
       
   283         MakeSortingItemsL( sortingArray,
       
   284                            aUndefinedItemArray,
       
   285                            aItemArray.Array(),
       
   286                            sortingFields.Array(),
       
   287                            sortingDataType );
       
   288 
       
   289         SortSortingItemsL( sortingArray, sortingDataType );
       
   290 
       
   291         aItemArray.Reset();
       
   292         if( aSortingStyle.Ordering() == ECLFOrderingAscending )
       
   293             {
       
   294             AppendSortingItemsToArrayL( sortingArray.Array(),
       
   295                                         aItemArray );
       
   296             }
       
   297         else
       
   298             {
       
   299             AppendSortingItemsToArrayReverseL( sortingArray.Array(),
       
   300                                                aItemArray );
       
   301             }
       
   302 
       
   303         CleanupStack::PopAndDestroy( &sortingArray ); // sortingArray.Close
       
   304         }
       
   305     CleanupStack::PopAndDestroy( &sortingFields ); // sortingFields.Close
       
   306     }
       
   307 
       
   308 
       
   309 // ============================ MEMBER FUNCTIONS ===============================
       
   310 
       
   311 // -----------------------------------------------------------------------------
       
   312 // CCLFDefaultOperation::CCLFDefaultOperation
       
   313 // C++ default constructor can NOT contain any code, that
       
   314 // might leave.
       
   315 // -----------------------------------------------------------------------------
       
   316 //
       
   317 CCLFDefaultOperation::CCLFDefaultOperation()
       
   318     : iSortingStyle( NULL ),
       
   319       iSortingStyleArray( KCLFSortingStyleArrayGranularity ),
       
   320       iGrouping( ECLFNoGrouping ),
       
   321       iGroupedItemList( KCLFGroupedItemArrayGranularity )
       
   322     {
       
   323     }
       
   324 
       
   325 // -----------------------------------------------------------------------------
       
   326 // CCLFDefaultOperation::NewL
       
   327 // Two-phased constructor.
       
   328 // -----------------------------------------------------------------------------
       
   329 //
       
   330 CCLFDefaultOperation* CCLFDefaultOperation::NewL()
       
   331     {
       
   332     return new( ELeave ) CCLFDefaultOperation;
       
   333     }
       
   334 
       
   335 // -----------------------------------------------------------------------------
       
   336 // CCLFDefaultOperation::NewL
       
   337 // Destructor
       
   338 // -----------------------------------------------------------------------------
       
   339 //
       
   340 CCLFDefaultOperation::~CCLFDefaultOperation()
       
   341     {
       
   342     iGroupedItemList.ResetAndDestroy();
       
   343     iSortingStyleArray.Close();
       
   344     }
       
   345 
       
   346 
       
   347 // -----------------------------------------------------------------------------
       
   348 // CCLFDefaultOperation::SetSortingStyle
       
   349 // -----------------------------------------------------------------------------
       
   350 //
       
   351 void CCLFDefaultOperation::SetSortingStyle( MCLFSortingStyle* aSortingStyle )
       
   352     {
       
   353     iSortingStyle = aSortingStyle;
       
   354     iSortingStyleArray.Reset();
       
   355     }
       
   356 
       
   357 // -----------------------------------------------------------------------------
       
   358 // CCLFDefaultOperation::AppendSortingStyleL
       
   359 // -----------------------------------------------------------------------------
       
   360 //
       
   361 void CCLFDefaultOperation::AppendSortingStyleL(
       
   362                                             MCLFSortingStyle& aSortingStyle )
       
   363     {
       
   364     iSortingStyleArray.AppendL( &aSortingStyle );
       
   365     }
       
   366 
       
   367 // -----------------------------------------------------------------------------
       
   368 // CCLFDefaultOperation::SetGrouping
       
   369 // -----------------------------------------------------------------------------
       
   370 //
       
   371 void CCLFDefaultOperation::SetGrouping( TCLFGrouping aGrouping )
       
   372     {
       
   373     iGrouping = aGrouping;
       
   374     }
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CCLFDefaultOperation::FilterItemsL
       
   378 // -----------------------------------------------------------------------------
       
   379 //
       
   380 void CCLFDefaultOperation::FilterItemsL( const TArray<MCLFItem*>& aItemList,
       
   381                                    RPointerArray<MCLFItem>& aFilteredItemList )
       
   382     {
       
   383     AppendItemsToArrayL( aItemList, aFilteredItemList );
       
   384     }
       
   385 
       
   386 // -----------------------------------------------------------------------------
       
   387 // CCLFDefaultOperation::GroupItemsL
       
   388 // -----------------------------------------------------------------------------
       
   389 //
       
   390 void CCLFDefaultOperation::GroupItemsL( const TArray<MCLFItem*>& aSourceList,
       
   391                                         RPointerArray<MCLFItem>& aGroupedList )
       
   392     {
       
   393     MG_DEBUG1( GI1, "CCLFDefaultOperation::GroupItemsL start" );
       
   394 
       
   395     iGroupedItemList.ResetAndDestroy();
       
   396     switch ( iGrouping )
       
   397         {
       
   398         case ECLFMusicAlbumGrouping:
       
   399             {
       
   400             DoMusicAlbumGroupingL( aSourceList, aGroupedList );
       
   401             break;
       
   402             }
       
   403         case ECLFNoGrouping:
       
   404         default:
       
   405             {
       
   406             AppendItemsToArrayL( aSourceList, aGroupedList );
       
   407             break;
       
   408             }
       
   409         }
       
   410 
       
   411     MG_DEBUG1( GI2, "CCLFDefaultOperation::GroupItemsL end" );
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CCLFDefaultOperation::SortItemsL
       
   416 // -----------------------------------------------------------------------------
       
   417 //
       
   418 void CCLFDefaultOperation::SortItemsL( RPointerArray<MCLFItem>& aItemArray )
       
   419     {
       
   420     if( iSortingStyle )
       
   421         {
       
   422         RPointerArray<MCLFItem> array;
       
   423         CleanupClosePushL( array );
       
   424         RPointerArray<MCLFItem> array1;
       
   425         CleanupClosePushL( array1 );
       
   426         RPointerArray<MCLFItem>* undefinedItemArray = &array;
       
   427         RPointerArray<MCLFItem>* newUndefinedItemArray = &array1;
       
   428 
       
   429         SortItemsBySortingStyleL( aItemArray,
       
   430                                   *iSortingStyle,
       
   431                                   *undefinedItemArray );
       
   432         TInt lastAddedItemCount( aItemArray.Count() );
       
   433         TInt nextItemIndex( lastAddedItemCount );
       
   434         TCLFUndefinedItemPosition position(
       
   435                                     iSortingStyle->UndefinedItemPosition() );
       
   436 
       
   437         const TInt secondarySorterCount( iSortingStyleArray.Count() );
       
   438         for( TInt i = 0 ; i < secondarySorterCount ; ++i )
       
   439             {
       
   440             MCLFSortingStyle& sortingStyle = *iSortingStyleArray[i];
       
   441 
       
   442             newUndefinedItemArray->Reset();
       
   443             // sort undefined items
       
   444             SortItemsBySortingStyleL( *undefinedItemArray,
       
   445                                       sortingStyle,
       
   446                                       *newUndefinedItemArray );
       
   447 
       
   448             // append sorted items to aItemArray
       
   449             AppendItemsToArrayL( undefinedItemArray->Array(),
       
   450                                  aItemArray,
       
   451                                  position,
       
   452                                  nextItemIndex,
       
   453                                  lastAddedItemCount );
       
   454 
       
   455 
       
   456             position = sortingStyle.UndefinedItemPosition();
       
   457 
       
   458             // change pointers
       
   459             RPointerArray<MCLFItem>* tmp = undefinedItemArray;
       
   460             undefinedItemArray = newUndefinedItemArray;
       
   461             newUndefinedItemArray = tmp;
       
   462             }
       
   463 
       
   464 
       
   465         // copy rest undefined items to correct position
       
   466         AppendItemsToArrayL( undefinedItemArray->Array(),
       
   467                              aItemArray,
       
   468                              position,
       
   469                              nextItemIndex,
       
   470                              lastAddedItemCount );
       
   471 
       
   472                                     // close undefined arrays
       
   473         CleanupStack::PopAndDestroy( 2, &array );
       
   474         }
       
   475         // else no sorting
       
   476     }
       
   477 
       
   478 
       
   479 // -----------------------------------------------------------------------------
       
   480 // CCLFDefaultOperation::DoMusicAlbumGroupingL
       
   481 // -----------------------------------------------------------------------------
       
   482 //
       
   483 void CCLFDefaultOperation::DoMusicAlbumGroupingL(
       
   484                                     const TArray<MCLFItem*>& aSourceList,
       
   485                                     RPointerArray<MCLFItem>& aGroupedList )
       
   486     {
       
   487     MG_DEBUG1( DMAG1, "CCLFDefaultOperation::DoMusicAlbumGroupingL start" );
       
   488 
       
   489     CDesCArray* tempAlbumNameArray =
       
   490                 new (ELeave) CDesCArraySeg( KCLFGroupedItemArrayGranularity );
       
   491     CleanupStack::PushL( tempAlbumNameArray );
       
   492 
       
   493     const TInt count( aSourceList.Count() );
       
   494     for( TInt i = 0 ; i < count ; ++i )
       
   495         {
       
   496         const MCLFItem* item = aSourceList[i];
       
   497         TPtrC albumName;
       
   498         if( item->GetField( ECLFFieldIdAlbum, albumName ) == KErrNone )
       
   499             {
       
   500             TInt pos( 0 );
       
   501             if( tempAlbumNameArray->Find( albumName, pos ) )
       
   502                 {
       
   503                 // not found
       
   504                 tempAlbumNameArray->AppendL( albumName );
       
   505 
       
   506                 // make new item
       
   507                 MCLFModifiableItem* newItem =
       
   508                                 ContentListingFactory::NewModifiableItemLC();
       
   509                 newItem->AddFieldL( ECLFFieldIdAlbum, albumName );
       
   510                 iGroupedItemList.AppendL( newItem );    // takes ownership
       
   511                 CleanupStack::Pop(); // newItem
       
   512 
       
   513                 TPtrC artistName;
       
   514                 if( item->GetField( ECLFFieldIdArtist, artistName ) == KErrNone )
       
   515                     {
       
   516                     newItem->AddFieldL( ECLFFieldIdArtist, artistName );
       
   517                     }
       
   518 
       
   519                 // add new item to grouper list
       
   520                 aGroupedList.AppendL( newItem );
       
   521                 }
       
   522             }
       
   523         }
       
   524     CleanupStack::PopAndDestroy( tempAlbumNameArray );
       
   525 
       
   526     MG_DEBUG1( DMAG2, "CCLFDefaultOperation::DoMusicAlbumGroupingL end" );
       
   527     }
       
   528 
       
   529 //  End of File