diff -r 000000000000 -r f979ecb2b13e searchfw/plugins/calendarplugin/src/calendarsearcher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/searchfw/plugins/calendarplugin/src/calendarsearcher.cpp Tue Feb 02 10:12:19 2010 +0200 @@ -0,0 +1,807 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: Plugin for calendarplugin information search. +* +*/ + + + +//System Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "calendarsearcher.h" +#include "calentrydetails.h" +#include "calendarsearchpluginpanic.h" +#include "defines.h" + +const int KBufferLength = 60; +const int KBigBufferLength = 120; +_LIT( KAvkonResoureFilePath, "avkon.Rsc" ); +_LIT( KEmptySpace, " " ); +const int KHour = 23; +const int KMinute = 59; + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::NewL +// Symbian OS 2 phased constructor. +// ----------------------------------------------------------------------------- +// +CCalendarSearcher* CCalendarSearcher::NewL( const RArray& aContentIdArray, + const CSearchCondition& aCondition, + const TUid& aPluginId, + MSearchPluginObserver& aObserver ) + { + CCalendarSearcher* self = new( ELeave )CCalendarSearcher( aPluginId ); + CleanupStack::PushL ( self ); + self->ConstructL( aContentIdArray, aCondition,aObserver); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::CCalendarSearcher +// Destructor. +// ----------------------------------------------------------------------------- +// +CCalendarSearcher::~CCalendarSearcher() + { + iFsSession.Close(); + + + delete iTextSearcher; + iTextSearcher = NULL; + + delete iReadDateBuffer; + iReadDateBuffer = NULL; + + + delete iReadTimeBuffer; + iReadTimeBuffer = NULL; + + if(0 < iHeavyResultsArray.Count()) + { + iHeavyResultsArray.Reset(); + } + + iCalDesCArray.ResetAndDestroy(); + iCalLocalUidArray.Close(); + + delete iEntry; + + delete iEntryView; + delete iInstanceView; + delete iSession; + iSession = NULL; + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::GetIfEntryExists +// Check if the entry exists in calander +// ----------------------------------------------------------------------------- + +TBool CCalendarSearcher::GetIfEntryExistsL (TCalLocalUid aId) + { + + CCalEntry * temp = iEntryView->FetchL(aId); + if(temp) + { + delete temp; + temp = NULL; + return ETrue; + } + return EFalse; + + + } +// CCalendarSearcher::StartSearchL +// Start search, set active +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::StartSearchL() + { + if( iNeedToCallReportFinishedL ) + { + ReportFinishedL( iErrorCode ); + return; + } + + // set the active object in pending state until the CCalEntryView is created + iStatus = KRequestPending; // change Kiran + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::Destroy +// Performs the Cleanup operations. +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::Destroy() + { + iSearchNotCancelled = EFalse; + if(IsActive()) + { + CActive::Cancel(); + } + else + { + Cleanup(); + } + + + if(0 < iHeavyResultsArray.Count()) + { + iHeavyResultsArray.ResetAndDestroy(); + } + + iCalDesCArray.ResetAndDestroy(); + delete this; + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::SearchL +// Performs a Search Operation +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::SearchL() +{ + + iSearchNotCancelled = ETrue; + iCalDesCArray.ResetAndDestroy(); + + if(0 < iHeavyResultsArray.Count()) + { + iHeavyResultsArray.ResetAndDestroy(); + } + + // Check if plug-in was constructed for searching and if not panic + __ASSERT_ALWAYS( this, User::Panic( KCalendarSearchPlugIn, + ECalendarSearchPlugInWrongConstructionParameters ) ); + + if( !iFilter ) + { + ReportFinishedL( KErrNone ); + return; + } + + // ASSERT_ here when already searching + __ASSERT_ALWAYS( !IsSearching(), User::Panic( KCalendarSearchPlugIn, + ECalendarSearchPlugInActiveSearchingExist) ); + + if( iSetParamsDone ) + { + InitializationL(); + } + else + { + ReportFinishedL( iErrorCode ); + } +} + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::IsSearching +// Checks wheather a Search Operation is going or not. +// ----------------------------------------------------------------------------- +// +TBool CCalendarSearcher::IsSearching() + { + return IsActive(); + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::CancelSearch +// Canels the Search operation. +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::CancelSearch() +{ + iSearchNotCancelled = EFalse; + CActive::Cancel(); + Cleanup(); +} + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::GetResultsL +// Results are passed in aDocumentIdArray. +// ---------------------------------------------------------f-------------------- +// +void CCalendarSearcher::GetResultsL( const RPointerArray& aDocumentIdArray ) + { + RPointerArray aSearchResultArray; + _LIT8(KText,"MIME/TEXT"); + TBufC8 tempBuf(KText); + + for( TInt i = 0 ; i < aDocumentIdArray.Count() ; i++ ) + { + for( TInt j = 0 ; j < iHeavyResultsArray.Count() ; j++ ) + { + + if( (aDocumentIdArray[i]->DocumentId() == + (iHeavyResultsArray[j]->Result()).DocumentId().DocumentId() ) && + (aDocumentIdArray[i]->PluginId().iUid == iPluginId.iUid ) && + (aDocumentIdArray[i]->RepositoryId() == KSearchCClassCalendarUid.iUid) + ) + + { + CSearchResult* tempHeavy = iHeavyResultsArray[j]; + if((&tempHeavy->Title() != NULL) && (&tempHeavy->Snippet() != NULL)) + { + aSearchResultArray.Append( iHeavyResultsArray[j]); + continue; + } + + TBufC8 tempString; + TPtr8 tempPtr8( tempString.Des() ); + CnvUtfConverter::ConvertFromUnicodeToUtf8( tempPtr8, + *( iCalDesCArray[j]->GetSnippet()) ); + + HBufC* tmpTitlte = (iCalDesCArray[j]->GetSummary())->AllocL(); + if( tmpTitlte->Length() == 0 ) + { + _LIT(KUnNamed, ""); + TBufC<20> tmpBufTitle(KUnNamed); + tmpTitlte = tmpBufTitle.AllocL(); + } + + iHeavyResultsArray[j]->SetTitleL( *tmpTitlte ); + delete tmpTitlte; + tmpTitlte = NULL; + iHeavyResultsArray[j]->SetSnippetL( tempPtr8 ); + iHeavyResultsArray[j]->SetSnippetFormatL( tempBuf.Des() ); + aSearchResultArray.AppendL( iHeavyResultsArray[j] ); + } + + } + } + + iObserver->ResultsRetrieveCompleteL( aSearchResultArray ); + aSearchResultArray.Reset(); + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::CancelResultsRetrieve +// Cancels the operation of result retrieval. +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::CancelResultsRetrieve() +{ + +} + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::GetSearchProgressL +// +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::GetSearchProgressL( TUid& aContentClassId, + TInt& aCurrentDocument, + TInt& aTotalDocuments ) + { + if( aContentClassId == KSearchCClassCalendarUid ) + { + aCurrentDocument = iCurrentDocumentSearching; + aTotalDocuments = iTotalNumOfDocumentsSearched; + } + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::HitL +// Called by TextObserver when Keyword is found. +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::HitL( TInt aKeyWordPos ) +{ + if( isFirstKeyWordHit && aKeyWordPos!= KErrNotFound ) + { + + _LIT8( KNumber, "%d" ); + HBufC8* buf8 = HBufC8::NewLC( KUidLength ); + buf8->Des().Format( KNumber, iEntry->LocalUidL() ); + CSearchDocumentId* documentId = CSearchDocumentId::NewL( iEntry->LocalUidL(), iPluginId ); + documentId->SetRepositoryIdL( KSearchCClassCalendarUid.iUid); + + CSearchLightResult* searchLightResult = CSearchLightResult::NewL( documentId ); + searchLightResult->SetContentClassId( KSearchCClassCalendarUid ); + + iTotalNumOfDocumentsSearched++; + + if( iEntry->EntryTypeL() == CCalEntry::EAnniv ) + { + searchLightResult->SetContentFolderId( KSearchCFolderAnniversaryUid ); + } + + if( ( iEntry->EntryTypeL() == CCalEntry::EAppt ) || + ( iEntry->EntryTypeL() == CCalEntry::EReminder ) ) + { + searchLightResult->SetContentFolderId( KSearchCFolderMeetingsUid ); + } + + if( iEntry->EntryTypeL() == CCalEntry::EEvent ) + { + searchLightResult->SetContentFolderId( KSearchCFolderMemoUid ); + } + + if( iEntry->EntryTypeL() == CCalEntry::ETodo ) + { + searchLightResult->SetContentFolderId( KSearchCFolderToDoUid ); + } + + searchLightResult->SetServiceId( KNullUid ); + isFirstKeyWordHit = 0; + + CCalDesC* caldetail = new(ELeave) CCalDesC(); + CleanupStack::PushL ( caldetail ); + + TTime startDateTime = iEntry->StartTimeL().TimeLocalL(); + + const TPtrC16 ptrReadDateBuffer(( TText16*) iReadDateBuffer->Ptr(), + ( iReadDateBuffer->Length()+1 )>>1 ); + HBufC16* dateBuffer=HBufC16::NewLC(ptrReadDateBuffer.Length()); + *dateBuffer=ptrReadDateBuffer; + + TBufC dateString; + TPtr tempDateStringPtr( dateString.Des() ); + startDateTime.FormatL( tempDateStringPtr, *dateBuffer ); + CCalAlarm* pAlarm = iEntry->AlarmL(); + + if( ( iEntry->EntryTypeL() == CCalEntry::EAppt ) || + ( iEntry->EntryTypeL() == CCalEntry::EReminder ) || + ( iEntry->EntryTypeL() == CCalEntry::EEvent && pAlarm )|| + ( iEntry->EntryTypeL() == CCalEntry::ETodo && pAlarm ) ) + { + if( iEntry->EntryTypeL() == CCalEntry::EEvent || + iEntry->EntryTypeL() == CCalEntry::ETodo ) + { + TTimeIntervalMinutes timeInterval = pAlarm->TimeOffset(); + startDateTime = startDateTime - timeInterval; + } + + const TPtrC16 ptrReadTimeBuffer(( TText16*) iReadTimeBuffer->Ptr(), + ( iReadTimeBuffer->Length()+1 )>>1 ); + HBufC16* timeBuffer=HBufC16::NewLC( ptrReadTimeBuffer.Length() ); + *timeBuffer=ptrReadTimeBuffer; + + TBufC timeString; + TPtr tempTimeStringPtr( timeString.Des() ); + startDateTime.FormatL( tempTimeStringPtr, *timeBuffer ); + tempDateStringPtr.Append( KEmptySpace ); + tempDateStringPtr.Append( tempTimeStringPtr ); + + CleanupStack::PopAndDestroy( timeBuffer ); + } + + caldetail->SetSnippetL( tempDateStringPtr ); + caldetail->SetSummaryL( iEntry->SummaryL() ); + caldetail->SetUidL( *buf8 ); + iCalDesCArray.AppendL( caldetail ); + + CleanupStack::PopAndDestroy( dateBuffer ); + CleanupStack::Pop( caldetail ); + CleanupStack::PopAndDestroy( buf8 ); + + + + CSearchResult* searchResult = CSearchResult::NewL( searchLightResult); + + searchResult->SetSnippetL(KNullDesC8); + searchResult->SetTitleL(KNullDesC); + iHeavyResultsArray.Append( searchResult ); + + iObserver->ResultFoundL( searchLightResult, iCurrentDocumentSearching, + iTotalNumOfDocumentsSearched ); + } +} + + + HBufC8* CCalendarSearcher::LaunchInfoL( const CSearchDocumentId& aDocumentID ) + { + + if((aDocumentID.PluginId() == iPluginId) && + (aDocumentID.RepositoryId() == KSearchCClassCalendarUid.iUid)) + { + HBufC8 * launchInfo = HBufC8::NewL(256); + TPtr8 docIdPtr = launchInfo->Des(); + docIdPtr.AppendNum(aDocumentID.DocumentId()); + return launchInfo; + } + + return NULL; + + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::InitializationL +// Initializes Search. Causes Search to start when contact to calendar server finished. +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::InitializationL() + { + delete iEntryView; + iEntryView = NULL; + + delete iInstanceView; + iInstanceView = NULL; + + delete iSession; + iSession = NULL; + + iSession = CCalSession::NewL(); + + TRAPD( error, iSession->OpenL( iSession->DefaultFileNameL() )); + if ( error != KErrNone ) + { + ReportFinishedL( error ); + return; + } + + iCalendarState = ECreatingCalendarEntryView; + iEntryView = CCalEntryView::NewL( *iSession, *this ); + + TRAPD( err, StartSearchL() ); + if ( err != KErrNone ) + { + iNeedToCallReportFinishedL = ETrue; + } + + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::Completed +// Is called when classes related to Calendar connection are finished initializing. +// This is called after CCalInstanceView::NewL and CCalEntryView::NewL. +// When initialization is complete starts the search automatically. +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::Completed(TInt aError) + { + switch ( iCalendarState ) + { + case ECreatingCalendarEntryView: + { + // CCalEntryView is constructed -> Active object must complete + TRequestStatus* status = &iStatus; + User::RequestComplete( status, aError ); + break; + } + + case ECreatingCalendarInstanceView: + { + // CCalInstanceView is constructed -> Active object must complete + TRequestStatus* status = &iStatus; + User::RequestComplete( status, aError ); + break; + } + + default: // If we get here, it's a program error + { + User::Panic( KCalendarSearchPlugIn, ECalendarSearchPlugWrongState ); + } + } + + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::ReportFinishedL +// Tell observer search finished +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::ReportFinishedL( TInt aSearchResult, TInt aTotalNumOfItems) + { + iObserver->SearchCompletedL( aSearchResult, aTotalNumOfItems ); + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::ConstructL +// Performs the second phase construction. +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::ConstructL( const RArray& aContentIdArray, + const CSearchCondition& aCondition, + MSearchPluginObserver& aObserver ) + { + iObserver = &aObserver; + for( TInt ctr= 0 ; ctr < aContentIdArray.Count() ; ctr++ ) + { + if( aContentIdArray[ctr] == KSearchCClassCalendarUid ) + { + iFilter = CalCommon::EIncludeAll; + break; + } + else + { + if ( aContentIdArray[ctr] == KSearchCFolderAnniversaryUid ) + iFilter = iFilter || ( CalCommon::EIncludeAnnivs + | CalCommon::EIncludeReminder ); + + if ( aContentIdArray[ctr] == KSearchCFolderMeetingsUid ) + iFilter = iFilter || CalCommon::EIncludeAppts ; + + if ( aContentIdArray[ctr] == KSearchCFolderMemoUid ) + iFilter = iFilter || CalCommon::EIncludeEvents; + + if ( aContentIdArray[ctr] == KSearchCFolderToDoUid ) + iFilter = iFilter || ( CalCommon::EIncludeCompletedTodos + | CalCommon::EIncludeIncompletedTodos ); + } + } + + SetPriority( EPriorityStandard ); + iTextSearcher = CSearchTextSearcher::NewL( *this ); + TRAPD(ParameterError, iTextSearcher->SetParametersL( aCondition )); + User::LeaveIfError( iFsSession.Connect() ); + + + TFileName resourceFileName; + RResourceFile resourceFile; + + resourceFileName.Copy( TParsePtrC( RProcess().FileName() ).Drive() ); + resourceFileName.Append( KDC_RESOURCE_FILES_DIR ); + resourceFileName.Append( KAvkonResoureFilePath ); + + // Get language local file name of resource file. + BaflUtils::NearestLanguageFile( iFsSession, resourceFileName ); + resourceFile.OpenL(iFsSession, resourceFileName ); + resourceFile.ConfirmSignatureL(); + + + iReadDateBuffer = resourceFile.AllocReadL( R_QTN_DATE_SHORT ); + iReadTimeBuffer = resourceFile.AllocReadL( R_QTN_TIME_USUAL ); + + + if( ParameterError == KErrNone) + { + iSetParamsDone = ETrue; + } + else + { + iErrorCode = ParameterError; + } + resourceFile.Close(); + + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::CCalendarSearcher +// Performs the first phase of two phase construction. +// ----------------------------------------------------------------------------- +// +CCalendarSearcher::CCalendarSearcher( const TUid& aPluginId ) : + CActive( CActive::EPriorityStandard ), iCurrentDocumentSearching( 0 ),iFilter( 0 ), + iPluginId( aPluginId ), isFirstKeyWordHit( 0 ), + iSetParamsDone( EFalse ), iNeedToCallReportFinishedL( EFalse ),iSearchNotCancelled( EFalse ) + { + CActiveScheduler::Add( this ); + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::IsSearching +// Does Cleanup for this class. +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::Cleanup() + { + + switch ( iCalendarState ) + { + case ECreatingCalendarEntryView: + { + // CCalEntryView does not have a Cancel function, thus delete is the only option + // CCalendarSearcher::Completed will get called with KErrCancel + delete iEntryView; + iEntryView = NULL; + break; + } + + case ECreatingCalendarInstanceView: + { + // CCalInstanceView does not have a Cancel function, thus delete is the only option + // CCalendarSearcher::Completed will get called with KErrCancel + delete iInstanceView; + iInstanceView = NULL; + break; + } + + case ESearching: + { + // Outstanding request is cancelled and search will not continue. + break; + } + + default: // If we get here, it's a program error + { + User::Panic( KCalendarSearchPlugIn, ECalendarSearchPlugWrongState ); + } + } + + //iInstanceArray.ResetAndDestroy(); + + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::DoActualSearchL +// Search calendar database +// ----------------------------------------------------------------------------- +// +TBool CCalendarSearcher::DoActualSearchL() + { + TBool calendarItems( ETrue ); + TInt calEntriesInOneGoCounter(0); + while ( calendarItems && iSearchNotCancelled && (calEntriesInOneGoCounter < KSearchThisManyCalEntriesInOneGo)) + { + delete iEntry; + iEntry = NULL; + iEntry = iEntryView->FetchL( iCalLocalUidArray[0] ); + calEntriesInOneGoCounter++; + isFirstKeyWordHit = 1; + HBufC16* textToBeSearched = NULL; + iTextSearcher->Cleanup(); + iCurrentDocumentSearching++; + TPtrC summaryLine = iEntry->SummaryL(); + + if( ( iEntry->EntryTypeL() == CCalEntry::EAppt ) || + ( iEntry->EntryTypeL() == CCalEntry::EReminder ) ) + { + TPtrC locationLine = iEntry->LocationL(); + TPtrC descriptionLine = iEntry->DescriptionL(); + textToBeSearched = HBufC16::NewLC( summaryLine.Length() + + descriptionLine.Length() + + locationLine.Length() + 2 ); + textToBeSearched->Des().Append(summaryLine); + textToBeSearched->Des().Append( KEmptySpace ); + textToBeSearched->Des().Append(descriptionLine); + textToBeSearched->Des().Append( KEmptySpace ); + textToBeSearched->Des().Append(locationLine); + + iTextSearcher->SearchL( *textToBeSearched ); + CleanupStack::PopAndDestroy( textToBeSearched ); + } + else + { + iTextSearcher->SearchL( summaryLine ); + } + // Remove the element that was just searched + iCalLocalUidArray.Remove ( 0 ); + + // Check hometime and check if more items need searching + //now.HomeTime(); + calendarItems = iCalLocalUidArray.Count() > 0; + + } + + if( !calendarItems ) + { + ReportFinishedL( KErrNone, iTotalNumOfDocumentsSearched ); + return EFalse; + } + return ETrue; + } + +TBool CCalendarSearcher::FetchAllCalendarIdsL() + { + // Minimum time allowed in the API + TCalTime minTime; + minTime.SetTimeLocalL( TCalTime::MinTime() ); + + // Check if there are items available for the search + TCalTime nextInstanceTime = iInstanceView->NextInstanceL( iFilter, minTime ); + if ( nextInstanceTime.TimeUtcL() == Time::NullTTime() ) + { + ReportFinishedL( KErrNone, iTotalNumOfDocumentsSearched ); + return EFalse; // Indicate that no search is needed + } + + // Because the minimum time allowed is used in the query, we get all items available in the db + iCalLocalUidArray.Reset(); + iCalLocalUidArray.Compress(); + iEntryView->GetIdsModifiedSinceDateL( minTime, iCalLocalUidArray ); + + return ETrue; // Indicated that search must start + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::RunL +// Continue search +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::RunL() + { + switch ( iCalendarState ) + { + case ECreatingCalendarEntryView: + { + delete iInstanceView; + iInstanceView = NULL; + // Next create the CCalInstanceView + iInstanceView = CCalInstanceView::NewL( *iSession, *this ); + iCalendarState = ECreatingCalendarInstanceView; + + iStatus = KRequestPending; + SetActive(); + break; + } + + case ECreatingCalendarInstanceView: + { + // Fetch all calendar UIDs + if ( FetchAllCalendarIdsL() ) + { + // Next we start the actual search + iCalendarState = ESearching; + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + SetActive(); + } + break; + } + + case ESearching: + { + if ( DoActualSearchL() ) + { + // We keep searching until nothing to search anymore + iCalendarState = ESearching; + + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + SetActive(); + } + break; + } + + default: // If we get here, it's a program error + { + User::Panic( KCalendarSearchPlugIn, ECalendarSearchPlugWrongState ); + } + } + + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::DoCancel +// Implements cancellation of an outstanding request. +// This function is called as part of the active object's Cancel(). +// ----------------------------------------------------------------------------- +// +void CCalendarSearcher::DoCancel() + { + Cleanup(); + } + +// ----------------------------------------------------------------------------- +// CCalendarSearcher::RunError +// Called by system when RunL leave +// ----------------------------------------------------------------------------- +// +TInt CCalendarSearcher::RunError( TInt aError ) + { + return aError; + } + +