diff -r 000000000000 -r 84ad3b177aa3 browserui/browser/FeedsSrc/FeedsFileSearchAgent.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/browserui/browser/FeedsSrc/FeedsFileSearchAgent.cpp Mon Mar 30 12:49:49 2009 +0300 @@ -0,0 +1,426 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +// INCLUDE FILES + +#include "FeedsFileSearchAgent.h" +#include + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CFeedsFileSearchAgent::CFileSearchAgent +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CFeedsFileSearchAgent::CFeedsFileSearchAgent(MFeedsFileSearchAgentCallback& aCallback) + : iCallback(&aCallback), iCancelSearch(EFalse) + { + } + +// ----------------------------------------------------------------------------- +// CFeedsFileSearchAgent::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CFeedsFileSearchAgent::ConstructL() + { + TDriveList driveList; + TChar driveLetter; + + // we'll keep two lists. one for the drives in the system, the + // other for the list of found files + iDriveEntryList = new(ELeave) CDriveEntryList(KMaxDrives); + iFileEntryList = new(ELeave) CFileEntryList(FEEDS_FILE_SEARCH_AGENT_MAX_RESULTS); + // Create a directory scan object. + iScan = CDirScan::NewL(iFs); + iLazyCaller = CIdle::NewL(CActive::EPriorityIdle ); + + // Connect to fs for FS ops, etc + User::LeaveIfError(iFs.Connect()); + + // populate list of drives + GetDriveListL(); + } + +// ----------------------------------------------------------------------------- +// CFeedsFileSearchAgent::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CFeedsFileSearchAgent* CFeedsFileSearchAgent::NewL(MFeedsFileSearchAgentCallback& aCallback) + { + CFeedsFileSearchAgent* self = new( ELeave ) CFeedsFileSearchAgent(aCallback); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + + return self; + } + +// ----------------------------------------------------------------------------- +// CFeedsFileSearchAgent::~CFeedsFileSearchAgent() +// Destructor +// ----------------------------------------------------------------------------- +// +CFeedsFileSearchAgent::~CFeedsFileSearchAgent() + { + CancelSearch(); + iFs.Close(); + delete iScan; + delete iLazyCaller; + delete iDriveEntryList; + delete iFileEntryList; + } + + +// ----------------------------------------------------------------------------- +// CFeedsFileSearchAgent::StartSearchingL +// +// +// ----------------------------------------------------------------------------- +// +void CFeedsFileSearchAgent::StartSearchingL() + { + iSearchDriveIndex = -1; + + // Return control to the CIdle + // The searching work will be done in LazyCallBack. + iLazyCaller->Start(TCallBack(CFeedsFileSearchAgent::LazyCallBack,this)); + + } + +// ----------------------------------------------------------------------------- +// CFeedsFileSearchAgent::GetFileEntry +// +// +// ----------------------------------------------------------------------------- +// +TFileEntry* CFeedsFileSearchAgent::GetFileEntry(const TInt aIndex) + { + // for a client, return a pointer to a file that was found given + // it's index within the list of found files + if(aIndex >= iFileEntryList->Count()) + { + return NULL; + } + else + { + return &(iFileEntryList->At(aIndex)); + } + } + +// ----------------------------------------------------------------------------- +// CFeedsFileSearchAgent::GetDriveListL +// +// +// ----------------------------------------------------------------------------- +// +void CFeedsFileSearchAgent::GetDriveListL() + { + TDriveList driveList; + + // Setup List of drives + // DriveList will return an array of 26 bytes. + // nonzero entries means there is media present in + // that drive letter. + User::LeaveIfError(iFs.DriveList(driveList)); + for (TInt i=0; iAppendL(driveEntry); + } + } + } + +// ----------------------------------------------------------------------------- +// CFeedsFileSearchAgent::DoSearchFilesL +// +// Searches a given path or paths for a filename and add it to this class' list +// of found files. The filename can contain wildcards. +// ----------------------------------------------------------------------------- +// +TInt CFeedsFileSearchAgent::DoSearchFiles(const TDesC& aFileName, const TDesC& aPath) + { + TFindFile fileFinder(iFs); + CDir* dir = NULL; + + // given a semicolon-separated lists of paths to search in, + // look for the filename (that can include wildcards) found in that path or paths + // This first search will allocate memory for dir and will contain the list of + // files found within the first path given + TInt err = fileFinder.FindWildByPath(aFileName, &aPath, dir); + + while(err == KErrNone) + { + // For the current path given, + // loop through list of found items within that path + for (TInt i=0; iCount(); i++) + { + TEntry entry = (*dir)[i]; + + // create and setup TParse object, useful for later extracting parts + // of the found files used by clients of this class + TParse parsedName; + parsedName.Set(entry.iName, &fileFinder.File(), NULL); + + // as a sanity check, + // make sure the drive, path are valid and + // that the drive found matches the path given + if(parsedName.Drive().Length() && aPath.Length() && parsedName.Drive()[0] == aPath[0]) + { + // the wildcard search may have found directories that match + // exlude these from our list because we use this function to + // record files only + if(!entry.IsDir()) + { + // Create a fileEntry based upon the found file + // FullName will be the complete path specifier for the file + // while entry will be just the name within the directory + TFileEntry fileEntry; + fileEntry.iPath = parsedName.FullName(); + fileEntry.iEntry = entry; + + // copy this entry into to our list of found files + TRAP(err, iFileEntryList->AppendL(fileEntry)); + + // If we have exceeded our maximum number of possible entries, + // or we're cancelling an ongoing search + // then stop adding to the list + if(iFileEntryList->Count() >= FEEDS_FILE_SEARCH_AGENT_MAX_RESULTS || + iCancelSearch) + { + // cleanup dir + if(dir != NULL) + { + delete(dir); + dir = NULL; + } + return err; + } + } + } + } + + // + // We have completed looking at the results for this dir. Look + // At the results where we left off, for the next path given. + // If there is no next path, KErrNotFound will be returned, we'll + // complete the search cycle. + // + if(dir != NULL) + { + delete(dir); + dir = NULL; + } + err = fileFinder.FindWild(dir); + } + + // Cleanup the final instance of dir that has been allocated + if(dir != NULL) + { + delete(dir); + dir = NULL; + } + return err; + } + +// ----------------------------------------------------------------------------- +// CFeedsFileSearchAgent::DoSearchFilesRecursive +// +// Starting from a given path, search the filesystem recursively for a given +// filename. The filename may contain wildcards. +// ----------------------------------------------------------------------------- +// + +TInt CFeedsFileSearchAgent::DoSearchFilesRecursive(const TDesC& aFileName) + { + TInt err(KErrNone); + CDir* dir = NULL; + + // Find the entries from the next directory in the hierarchy + // or NULL/error if there are none + TRAP(err, iScan->NextL(dir)); + + // done, break out of loop + if(!dir || (err != KErrNone) ) + { + return KErrGeneral; + } + + // loop through the number of found directories + for(TInt i=0; i < dir->Count(); i++) + { + TEntry entry = (*dir)[i]; + + // The search will find directories as well as files. We're + // only interested here in directories. + if(entry.IsDir()) + { + // From the scan, get the full path including the drive letter + // being scanned. + TFileName path(iScan->FullPath()); + + if(path.Length()) + { + // If valid, append a slash to the end of the directory, + // and then search for the desired filename given this path + path.Append(entry.iName); + path.Append(_L("\\")); + DoSearchFiles(aFileName,path); + } + } + } + + // Delete the dir that was allocated in this iteration + if(dir != NULL) + { + delete(dir); + dir = NULL; + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CFeedsFileSearchAgent::LazyCallBack +// +// This function calls StartSearchFile instead of calling it from StartSearchingL function +// To ensure it doesn't called if user has cancelled the request +// ----------------------------------------------------------------------------- +// +TBool CFeedsFileSearchAgent::LazyCallBack(TAny* aPtr) + { + CFeedsFileSearchAgent* ptr = (CFeedsFileSearchAgent*)aPtr; + // if we've cancelled the search + // then stop adding to the list + if(!ptr->iCancelSearch) + { + return ptr->StartSearchFile(); + } + else + { + return EFalse; + } + } + +// ----------------------------------------------------------------------------- +// CFeedsFileSearchAgent::StartSearchFile +// +// starts the search of *.OPML Files. +// ----------------------------------------------------------------------------- +// +TBool CFeedsFileSearchAgent::StartSearchFile() + { + // Quit looping and don't try to scan if we've already exceeded the number of + // possible file entries + // or if we've cancelled the search + if(iFileEntryList->Count() >= FEEDS_FILE_SEARCH_AGENT_MAX_RESULTS || + iCancelSearch) + { + TRAP_IGNORE(iCallback->FeedsFileSearchCompleteL( iFileEntryList->Count() )); + return EFalse; + } + TInt retVal = KErrGeneral; + if(iSearchDriveIndex != -1) + { + retVal = DoSearchFilesRecursive( _L("*.opml")); + } + if(retVal != KErrNone) + { + iSearchDriveIndex++; + if(iSearchDriveIndex < iDriveEntryList->Count()) + { + TDriveEntry driveEntry = iDriveEntryList->At(iSearchDriveIndex); + TBuf<5> driveRoot; + + driveRoot.Append(driveEntry.iLetter); + driveRoot.Append(_L(":\\")); + + // Search the base of the drive and also search recursively + // through it's folder hierarchy. + DoSearchFiles(_L("*.opml"),driveRoot); + TRAP_IGNORE(iScan->SetScanDataL(driveRoot, KEntryAttDir|KEntryAttMatchMask, ESortByName | EAscending | EDirsFirst)); + return ETrue; + } + else + { + TRAP_IGNORE(iCallback->FeedsFileSearchCompleteL( iFileEntryList->Count() )); + return EFalse; + } + } + else + { + return ETrue; + } + } + +// ----------------------------------------------------------------------------- +// CFeedsFileSearchAgent::CancelSearch. +// +// Cancel the ongoing search. +// ----------------------------------------------------------------------------- +// +void CFeedsFileSearchAgent::CancelSearch() + { + if(iLazyCaller->IsActive()) + { + iLazyCaller->Cancel(); + } + iCancelSearch = ETrue; + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + + +// End of File