|         |      1 /* | 
|         |      2 * Copyright (c) 2007 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:  Searches items matching with given string in given file system | 
|         |     15 * | 
|         |     16 */ | 
|         |     17  | 
|         |     18  | 
|         |     19  | 
|         |     20 // INCLUDE FILES | 
|         |     21 #include <e32std.h> | 
|         |     22 #include <f32file.h> | 
|         |     23 #include <bautils.h> | 
|         |     24 #include "CGflmFileFinder.h" | 
|         |     25 #include "CGflmFileFinderItem.h" | 
|         |     26 #include "CGflmDriveItem.h" | 
|         |     27 #include "CGflmDriveResolver.h" | 
|         |     28 #include "CGflmItemLocalizer.h" | 
|         |     29 #include "MGflmItemFilter.h" | 
|         |     30 #include "GflmUtils.h" | 
|         |     31  | 
|         |     32 // CONSTANTS | 
|         |     33 const TInt KWildCardSpace = 2; | 
|         |     34 _LIT( KWildCard, "*" ); | 
|         |     35 const TInt KSearchResultsGranularity = 32; | 
|         |     36  | 
|         |     37 // ============================= LOCAL FUNCTIONS =============================== | 
|         |     38  | 
|         |     39 // ----------------------------------------------------------------------------- | 
|         |     40 // MakeWildStringL | 
|         |     41 // ----------------------------------------------------------------------------- | 
|         |     42 // | 
|         |     43 static HBufC* MakeWildStringL( const TDesC& aString ) | 
|         |     44     { | 
|         |     45     if ( GflmUtils::HasWildCard( aString ) ) | 
|         |     46         { | 
|         |     47         return aString.AllocL(); | 
|         |     48         } | 
|         |     49     HBufC* ret = HBufC::NewL( aString.Length() + KWildCardSpace ); | 
|         |     50     TPtr ptr( ret->Des() ); | 
|         |     51     ptr.Copy( KWildCard ); | 
|         |     52     ptr.Append( aString ); | 
|         |     53     ptr.Append( KWildCard ); | 
|         |     54     return ret; | 
|         |     55     } | 
|         |     56  | 
|         |     57 // ----------------------------------------------------------------------------- | 
|         |     58 // MakeWildPathL | 
|         |     59 // ----------------------------------------------------------------------------- | 
|         |     60 // | 
|         |     61 #if 0 | 
|         |     62 static HBufC* MakeWildPathL( const TDesC& aFolder, const TDesC& aString ) | 
|         |     63     { | 
|         |     64     const TInt KBackslashSpace = 1; | 
|         |     65     if ( !GflmUtils::HasWildCard( aString ) ) | 
|         |     66         { | 
|         |     67         return aFolder.AllocL(); | 
|         |     68         } | 
|         |     69     HBufC* ret = HBufC::NewL( | 
|         |     70         aFolder.Length() + aString.Length() + KBackslashSpace ); | 
|         |     71     TPtr ptr( ret->Des() ); | 
|         |     72     ptr.Copy( aFolder ); | 
|         |     73     GflmUtils::EnsureFinalBackslash( ptr ); | 
|         |     74     ptr.Append( aString ); | 
|         |     75     return ret; | 
|         |     76     } | 
|         |     77 #endif // 0 | 
|         |     78  | 
|         |     79 // ============================ MEMBER FUNCTIONS =============================== | 
|         |     80  | 
|         |     81 // ----------------------------------------------------------------------------- | 
|         |     82 // CGflmFileFinder::CGflmFileFinder | 
|         |     83 // ----------------------------------------------------------------------------- | 
|         |     84 // | 
|         |     85 CGflmFileFinder::CGflmFileFinder( | 
|         |     86             RFs& aFss, | 
|         |     87             CGflmItemLocalizer& aLocalizer, | 
|         |     88             CGflmDriveResolver& aResolver, | 
|         |     89             const TBool& aCancelIndicator ) : | 
|         |     90         iFss( aFss ), | 
|         |     91         iItemLocalizer( aLocalizer ), | 
|         |     92         iDriveResolver( aResolver ), | 
|         |     93         iCancelIndicator( aCancelIndicator ), | 
|         |     94         iSearchResults( KSearchResultsGranularity ) | 
|         |     95     { | 
|         |     96     } | 
|         |     97  | 
|         |     98 // ----------------------------------------------------------------------------- | 
|         |     99 // CGflmFileFinder::NewL | 
|         |    100 // ----------------------------------------------------------------------------- | 
|         |    101 // | 
|         |    102 CGflmFileFinder* CGflmFileFinder::NewL( | 
|         |    103         RFs& aFss, | 
|         |    104         CGflmItemLocalizer& aLocalizer, | 
|         |    105         CGflmDriveResolver& aResolver, | 
|         |    106         const TBool& aCancelIndicator ) | 
|         |    107     { | 
|         |    108     CGflmFileFinder* self = new( ELeave ) CGflmFileFinder(  | 
|         |    109         aFss, aLocalizer, aResolver, aCancelIndicator ); | 
|         |    110     CleanupStack::PushL( self ); | 
|         |    111     self->ConstructL(); | 
|         |    112     CleanupStack::Pop( self ); | 
|         |    113     return self; | 
|         |    114     } | 
|         |    115  | 
|         |    116 // ----------------------------------------------------------------------------- | 
|         |    117 // CGflmFileFinder::ConstructL | 
|         |    118 // ----------------------------------------------------------------------------- | 
|         |    119 // | 
|         |    120 void CGflmFileFinder::ConstructL() | 
|         |    121     { | 
|         |    122     iSortCollationMethod = *Mem::CollationMethodByIndex( 0 ); | 
|         |    123     iSortCollationMethod.iFlags |= | 
|         |    124         TCollationMethod::EIgnoreNone | TCollationMethod::EFoldCase; | 
|         |    125     } | 
|         |    126  | 
|         |    127 // ----------------------------------------------------------------------------- | 
|         |    128 // CGflmFileFinder::~CGflmFileFinder | 
|         |    129 // ----------------------------------------------------------------------------- | 
|         |    130 //  | 
|         |    131 CGflmFileFinder::~CGflmFileFinder() | 
|         |    132     { | 
|         |    133     delete iSearchFolder; | 
|         |    134     delete iSearchFolderWild; | 
|         |    135     delete iSearchString; | 
|         |    136     delete iSearchStringWild; | 
|         |    137     iSearchResults.ResetAndDestroy(); | 
|         |    138     iSearchResults.Close(); | 
|         |    139     } | 
|         |    140  | 
|         |    141 // ----------------------------------------------------------------------------- | 
|         |    142 // CGflmFileFinder::SetSearchFolderL | 
|         |    143 // ----------------------------------------------------------------------------- | 
|         |    144 //  | 
|         |    145 void CGflmFileFinder::SetSearchFolderL( const TDesC& aSearchFolder ) | 
|         |    146     { | 
|         |    147     delete iSearchFolderWild; | 
|         |    148     iSearchFolderWild = NULL; | 
|         |    149  | 
|         |    150     delete iSearchFolder; | 
|         |    151     iSearchFolder = NULL; | 
|         |    152     iSearchFolder = aSearchFolder.AllocL(); | 
|         |    153     } | 
|         |    154  | 
|         |    155 // ----------------------------------------------------------------------------- | 
|         |    156 // CGflmFileFinder::SetSearchStringL | 
|         |    157 // ----------------------------------------------------------------------------- | 
|         |    158 //  | 
|         |    159 void CGflmFileFinder::SetSearchStringL( const TDesC& aSearchString ) | 
|         |    160     { | 
|         |    161     delete iSearchFolderWild; | 
|         |    162     iSearchFolderWild = NULL; | 
|         |    163  | 
|         |    164     delete iSearchString; | 
|         |    165     iSearchString = NULL; | 
|         |    166     iSearchString = aSearchString.AllocL(); | 
|         |    167  | 
|         |    168     delete iSearchStringWild; | 
|         |    169     iSearchStringWild = NULL; | 
|         |    170     iSearchStringWild = MakeWildStringL( aSearchString ); | 
|         |    171     } | 
|         |    172  | 
|         |    173 // ----------------------------------------------------------------------------- | 
|         |    174 // CGflmFileFinder::RefreshL | 
|         |    175 // ----------------------------------------------------------------------------- | 
|         |    176 //  | 
|         |    177 void CGflmFileFinder::RefreshL( | 
|         |    178         MGflmItemFilter* aFilter, | 
|         |    179         TGflmSortMethod aSortMethod, | 
|         |    180         TGflmRefreshMode aRefreshMode ) | 
|         |    181     { | 
|         |    182     FUNC_LOG | 
|         |    183  | 
|         |    184     INFO_LOG2( | 
|         |    185         "CGflmItemGroupImpl::RefreshL-aRefreshMode=%d, aSortMethod=%d", | 
|         |    186         aRefreshMode, aSortMethod ) | 
|         |    187  | 
|         |    188     if ( aRefreshMode == ERefreshItems ) | 
|         |    189         { | 
|         |    190         TRAPD( err, DoSearchL( aFilter ) ); | 
|         |    191  | 
|         |    192         // If error just log it and show already found items | 
|         |    193         if ( err != KErrNone ) | 
|         |    194             { | 
|         |    195             ERROR_LOG1( "CGflmFileFinder::RefreshL-err=%d", err ) | 
|         |    196             } | 
|         |    197         } | 
|         |    198  | 
|         |    199     if ( aSortMethod == EByMatch ) | 
|         |    200         { | 
|         |    201         iSearchResults.Sort( CGflmFileFinderItem::CompareByMatch ); | 
|         |    202         } | 
|         |    203     else | 
|         |    204         { | 
|         |    205         iSearchResults.Sort( CGflmGroupItem::GetSortL( aSortMethod ) ); | 
|         |    206         } | 
|         |    207     } | 
|         |    208  | 
|         |    209 // ----------------------------------------------------------------------------- | 
|         |    210 // CGflmFileFinder::DoSearchL | 
|         |    211 // ----------------------------------------------------------------------------- | 
|         |    212 //  | 
|         |    213 void CGflmFileFinder::DoSearchL( MGflmItemFilter* aFilter ) | 
|         |    214     { | 
|         |    215     FUNC_LOG | 
|         |    216  | 
|         |    217     iSearchResults.ResetAndDestroy(); | 
|         |    218  | 
|         |    219     // Ensure that search data is defined | 
|         |    220     if ( !iSearchFolder || !iSearchString || !iSearchStringWild ) | 
|         |    221         { | 
|         |    222         return; | 
|         |    223         } | 
|         |    224     // Ensure that search drive exists | 
|         |    225     CGflmDriveItem* drvItem = iDriveResolver.DriveFromPath( *iSearchFolder ); | 
|         |    226     if ( !drvItem ) | 
|         |    227         { | 
|         |    228         return; | 
|         |    229         } | 
|         |    230     if ( !iSearchFolderWild ) | 
|         |    231         { | 
|         |    232 #if 0 | 
|         |    233         if ( iDriveResolver.IsRemoteDrive( *iSearchFolder ) ) | 
|         |    234             { | 
|         |    235             // Some remote drives are case sensitive with wild cards.  | 
|         |    236             // Therefore, wild cards cannot be used for remote drives,  | 
|         |    237             // because then it is not possible to do case  | 
|         |    238             // insensitive comparison like it is done for local drives.  | 
|         |    239             iSearchFolderWild = iSearchFolder->AllocL(); | 
|         |    240             } | 
|         |    241         else | 
|         |    242             { | 
|         |    243             // Do search using the folder with wild string for better performance. | 
|         |    244             // It is faster to let file server do the wild matching instead of  | 
|         |    245             // reading all subitems under search folder to be matched here. | 
|         |    246  | 
|         |    247             // Prepare search folder with wild search string | 
|         |    248             iSearchFolderWild = MakeWildPathL( | 
|         |    249                 *iSearchFolder, *iSearchStringWild ); | 
|         |    250             } | 
|         |    251 #else | 
|         |    252         // Because of problems with localized folder names,  | 
|         |    253         // wild card folder string cannot be given to file server since  | 
|         |    254         // file server is not aware of localized names.  | 
|         |    255         // This search operation is slower because all items are transferred  | 
|         |    256         // here for comparison.  | 
|         |    257         iSearchFolderWild = iSearchFolder->AllocL(); | 
|         |    258 #endif | 
|         |    259         } | 
|         |    260  | 
|         |    261     INFO_LOG1( "CGflmFileFinder::DoSearchL-CDirScan::NewLC-%S", | 
|         |    262         iSearchFolderWild ) | 
|         |    263     CDirScan* dirScan = CDirScan::NewLC( iFss ); | 
|         |    264  | 
|         |    265     INFO_LOG( "CGflmFileFinder::DoSearchL-CDirScan::SetScanDataL" ) | 
|         |    266     dirScan->SetScanDataL( *iSearchFolderWild, KEntryAttDir, ESortNone ); | 
|         |    267  | 
|         |    268     INFO_LOG( "CGflmFileFinder::DoSearchL-CDirScan::NextL" ) | 
|         |    269     CDir* dir = NULL; | 
|         |    270     dirScan->NextL( dir ); | 
|         |    271  | 
|         |    272     while( dir ) | 
|         |    273         { | 
|         |    274         CleanupStack::PushL( dir ); | 
|         |    275         if ( iCancelIndicator ) | 
|         |    276             { | 
|         |    277             User::Leave( KErrCancel ); | 
|         |    278             } | 
|         |    279         TPtrC basePath( dirScan->FullPath() ); | 
|         |    280         INFO_LOG1( "CGflmFileFinder::DoSearchL-Search-%S", &basePath ) | 
|         |    281  | 
|         |    282         TInt count( dir->Count() ); | 
|         |    283         for ( TInt i( 0 ); i < count; ++i ) | 
|         |    284             { | 
|         |    285             if ( iCancelIndicator ) | 
|         |    286                 { | 
|         |    287                 User::Leave( KErrCancel ); | 
|         |    288                 } | 
|         |    289             const TEntry& entry( ( *dir )[ i ] ); | 
|         |    290             TPtrC name( entry.iName ); | 
|         |    291             TBool isLocalized( EFalse ); | 
|         |    292             TBool isDir( entry.IsDir() ); | 
|         |    293             if( isDir ) | 
|         |    294                 { | 
|         |    295                 // Handle localized name | 
|         |    296                 GflmUtils::GetFullPath( basePath, entry, iFullPath ); | 
|         |    297                 TPtrC localizedName( | 
|         |    298                     iItemLocalizer.LocalizeFromWorkThread( iFullPath ) ); | 
|         |    299                 if ( localizedName.Length() ) | 
|         |    300                     { | 
|         |    301                     name.Set( localizedName ); | 
|         |    302                     isLocalized = ETrue; | 
|         |    303                     } | 
|         |    304                 } | 
|         |    305             // Append matching items | 
|         |    306             if( name.MatchC( *iSearchStringWild ) != KErrNotFound ) | 
|         |    307                 { | 
|         |    308                 CGflmFileFinderItem* finderItem = CGflmFileFinderItem::NewLC( | 
|         |    309                     entry, basePath ); | 
|         |    310                 if ( isLocalized ) | 
|         |    311                     { | 
|         |    312                     finderItem->SetLocalizedNameL( name ); | 
|         |    313                     } | 
|         |    314                 // Filter out unwanted items | 
|         |    315                 if ( !aFilter || | 
|         |    316                      ( aFilter && aFilter->FilterItemL( | 
|         |    317                         finderItem, | 
|         |    318                         isDir ? CGflmGroupItem::EDirectory : CGflmGroupItem::EFile, | 
|         |    319                         drvItem ) ) ) | 
|         |    320                     { | 
|         |    321                     finderItem->PrepareSort( *iSearchString ); | 
|         |    322                     finderItem->SetGroup( this ); | 
|         |    323                     iSearchResults.AppendL( finderItem ); | 
|         |    324                     CleanupStack::Pop( finderItem ); | 
|         |    325                     } | 
|         |    326                 else | 
|         |    327                     { | 
|         |    328                     CleanupStack::PopAndDestroy( finderItem ); | 
|         |    329                     } | 
|         |    330                 } | 
|         |    331             } | 
|         |    332         CleanupStack::PopAndDestroy( dir ); | 
|         |    333  | 
|         |    334         INFO_LOG( "CGflmFileFinder::DoSearchL-CDirScan::NextL" ) | 
|         |    335         dirScan->NextL( dir ); | 
|         |    336         } | 
|         |    337     CleanupStack::PopAndDestroy( dirScan ); | 
|         |    338     } | 
|         |    339  | 
|         |    340 // ----------------------------------------------------------------------------- | 
|         |    341 // CGflmFileFinder::ItemCount | 
|         |    342 // ----------------------------------------------------------------------------- | 
|         |    343 //  | 
|         |    344 TInt CGflmFileFinder::ItemCount() const | 
|         |    345     { | 
|         |    346     return iSearchResults.Count(); | 
|         |    347     } | 
|         |    348  | 
|         |    349 // ----------------------------------------------------------------------------- | 
|         |    350 // CGflmFileFinder::Item | 
|         |    351 // ----------------------------------------------------------------------------- | 
|         |    352 //  | 
|         |    353 CGflmGroupItem* CGflmFileFinder::Item( TInt aIndex ) | 
|         |    354     { | 
|         |    355     return iSearchResults[ aIndex ]; | 
|         |    356     } | 
|         |    357  | 
|         |    358 // ----------------------------------------------------------------------------- | 
|         |    359 // CGflmFileFinder::Id | 
|         |    360 // ----------------------------------------------------------------------------- | 
|         |    361 //  | 
|         |    362 TInt CGflmFileFinder::Id() const | 
|         |    363     { | 
|         |    364     return KErrNotFound; | 
|         |    365     } | 
|         |    366  | 
|         |    367 // ----------------------------------------------------------------------------- | 
|         |    368 // CGflmFileFinder::AddSourceL | 
|         |    369 // ----------------------------------------------------------------------------- | 
|         |    370 //  | 
|         |    371 void CGflmFileFinder::AddSourceL( const TDesC& /*aDirectory*/ ) | 
|         |    372     { | 
|         |    373     } | 
|         |    374  | 
|         |    375 // ----------------------------------------------------------------------------- | 
|         |    376 // CGflmFileFinder::ResetSources | 
|         |    377 // ----------------------------------------------------------------------------- | 
|         |    378 //  | 
|         |    379 void CGflmFileFinder::ResetSources() | 
|         |    380     { | 
|         |    381     } | 
|         |    382  | 
|         |    383 // ----------------------------------------------------------------------------- | 
|         |    384 // CGflmFileFinder::AddActionItemL | 
|         |    385 // ----------------------------------------------------------------------------- | 
|         |    386 //  | 
|         |    387 void CGflmFileFinder::AddActionItemL( TInt /*aId*/, const TDesC& /*aCaption*/ ) | 
|         |    388     { | 
|         |    389     } | 
|         |    390  | 
|         |    391 // ----------------------------------------------------------------------------- | 
|         |    392 // CGflmFileFinder::SetInclusion | 
|         |    393 // ----------------------------------------------------------------------------- | 
|         |    394 //  | 
|         |    395 void CGflmFileFinder::SetInclusion( TUint /*aInclusion*/ ) | 
|         |    396     { | 
|         |    397     } | 
|         |    398  | 
|         |    399 // ----------------------------------------------------------------------------- | 
|         |    400 // CGflmFileFinder::CollationMethod | 
|         |    401 // ----------------------------------------------------------------------------- | 
|         |    402 //  | 
|         |    403 const TCollationMethod* CGflmFileFinder::CollationMethod() | 
|         |    404     { | 
|         |    405     return &iSortCollationMethod; | 
|         |    406     } | 
|         |    407  | 
|         |    408 // End of File |