diff -r 000000000000 -r 72b543305e3a messagingappbase/smartmessaging/vcalbc/src/VCalendarBioControl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingappbase/smartmessaging/vcalbc/src/VCalendarBioControl.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,579 @@ +/* +* Copyright (c) 2002-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: Bio control for vCalendar messages +* +*/ + + + + +// INCLUDE FILES +#include "VCalendarBioControl.h" // CVCalendarBioControl +#include "VCalBcDataFiller.h" // CVCalBcDataFiller +#include "VCalLog.h" // Logging functionality +#include "VCalBcPanics.h" + +#include +#include +#include +#include // RFileReadStream +#include // StringLoader +#include // MMsgBioControlObserver +#include // resouce identifiers +#include // CRichBio +#include // CCalenImporter +#include // CCalEntryView +#include +#include // __SERIES60_HELP +#include +#include +#include +#include +#include +#include +#include +#include // CAiwServiceHandler +#include +#include +#include +#include + +// LOCAL CONSTANTS AND MACROS + +const TInt KVCalBcLeaveCodeCorrupt = KErrMsgBioMessageNotValid; +const TInt KIndexFirst = 0; +const TInt KLengthBeginVCalendar = 15; // "BEGIN:VCALENDAR" -string length +const TInt KVCalBcHeightReductionBva = 9; +//recognition string for ical +_LIT8(KVersionICal, "VERSION:2.0"); +//recognition string for vcal +_LIT8(KVersionVCal, "VERSION:1.0"); +const TInt KReadDataAmount = 256; + + +_LIT(KVCalBCResourceFile, "vcalbc.rsc"); +_LIT(KAvkonResourceFile, "avkon.rsc"); +_LIT(KSmsViewerResourceFile, "smsviewer.rsc"); +_LIT(KBvaResourceFile, "bva.rsc"); + +// MEMBER FUNCTIONS + +CVCalendarBioControl::~CVCalendarBioControl() + { + FeatureManager::UnInitializeLib(); + iFileHandle.Close(); + delete iViewer; + iCalEntryArray.ResetAndDestroy(); + delete iCalEntryView; + delete iSession; + if( iCalAiwServiceHandler ) + { + delete iCalAiwServiceHandler; + iCalAiwServiceHandler = NULL; + } + } + +EXPORT_C CMsgBioControl* CVCalendarBioControl::NewL( + MMsgBioControlObserver& aObserver, + CMsvSession* aSession, + TMsvId aId, + TMsgBioMode aEditorOrViewerMode, + const RFile* aFile) + { + LOG("CVCalendarBioControl::NewL begin"); + CVCalendarBioControl* self = new(ELeave) CVCalendarBioControl( + aObserver, + aSession, + aId, + aEditorOrViewerMode, + aFile); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); //self + return self; + } + +void CVCalendarBioControl::SetAndGetSizeL(TSize& aSize) + { + if(iIsFileBased) + { + SetPosition(TPoint(0,KVCalBcHeightReductionBva)); + aSize.iHeight -= KVCalBcHeightReductionBva; + iViewer->SetAndGetSizeL(aSize); + SetSizeWithoutNotification(aSize); + } + else + { + iViewer->SetAndGetSizeL(aSize); + + //the following compares the window size against the + //"virtual" height of the viewer. This way there is no + //scrolling if virtualHeight is less than window size + if(iViewer->VirtualHeight() <= Window().Size().iHeight) + { + aSize.iHeight = iViewer->VirtualHeight(); + SetSizeWithoutNotification(aSize); + } + else + { + SetSizeWithoutNotification(aSize); + } + } + } + +void CVCalendarBioControl::SetMenuCommandSetL(CEikMenuPane& aMenuPane) + { + if (!IsEditor()) + { + aMenuPane.SetItemDimmed( KAiwCmdSaveToCalendar, EFalse ); + + if( !iCalAiwServiceHandler ) + { + iCalAiwServiceHandler = CAiwServiceHandler :: NewL(); + } + + // Adding to Calendar is only supported for received calendar messages + // At this stage, aFile which is given to constructor is corrupted. + // Base class method IsFileBased() cannot be used because file handle + // in invalid. Guilty: \s60\avkon\src\AknOpenFileService.cpp + // void CAknOpenFileServiceSession::OpenHandleWithParamsL(const RMessage2& aMessage). + // File handle which is given to vCal BIO control is ***local variable*** + // in that method. When vCal is successfully viewed, OpenHandleWithParamsL + // completes and causes file handle to be invalid. 30.6.2005 / Sauli Painilainen + if( iIsFileBased ) + { + // Attaching the interest to the menu. + // This internally load the aiwprovider plug-in. + iCalAiwServiceHandler->AttachMenuL( R_BVA_MENU, R_BVA_AIW_CALENDAR_INTEREST ); + + // This menu should contain AIW menu placeholder,a sanity check. + __ASSERT_DEBUG( iCalAiwServiceHandler->IsAiwMenu( R_BVA_MENU ), Panic( EPanic2 ) ); + + if (iCalAiwServiceHandler->IsAiwMenu( R_BVA_MENU ) ) + { + iCalAiwServiceHandler->InitializeMenuPaneL( aMenuPane, R_BVA_MENU, + KAiwCmdSaveToCalendar, + iCalAiwServiceHandler->InParamListL() ); + } + } + else + { + // Attaching the interest to the menu. + // This internally load the aiwprovider plug-in. + iCalAiwServiceHandler->AttachMenuL( R_SMSV_OPTIONSMENUPANE, R_SMSV_AIW_CALENDAR_INTEREST ); + + // This menu should contain AIW menu placeholder,a sanity check. + __ASSERT_DEBUG( iCalAiwServiceHandler->IsAiwMenu( R_SMSV_OPTIONSMENUPANE ), Panic( EPanic2 ) ); + + if (iCalAiwServiceHandler->IsAiwMenu( R_SMSV_OPTIONSMENUPANE ) ) + { + iCalAiwServiceHandler->InitializeMenuPaneL( aMenuPane, R_SMSV_OPTIONSMENUPANE, + KAiwCmdSaveToCalendar, + iCalAiwServiceHandler->InParamListL() ); + } + } + } + } + +TBool CVCalendarBioControl::HandleBioCommandL(TInt aCommand) + { + if( aCommand == KAiwCmdSaveToCalendar ) + { + // Sending the filehandle to provider as input parameter. + CAiwGenericParamList& inCalParamList = iCalAiwServiceHandler->InParamListL(); + + RFile fileHandle; + ResolveFileL( fileHandle ); + TAiwGenericParam calenParam( EGenericParamFile ); + calenParam.Value().Set( fileHandle ); + inCalParamList.AppendL( calenParam ); + iCalAiwServiceHandler->ExecuteMenuCmdL( aCommand, + inCalParamList, + iCalAiwServiceHandler->OutParamListL(), + 0, NULL); + return ETrue; + } + return EFalse; + } + +TRect CVCalendarBioControl::CurrentLineRect() const + { + return iViewer->CurrentLineRect(); + } + +TBool CVCalendarBioControl::IsFocusChangePossible( + TMsgFocusDirection aDirection) const + { + if (aDirection == EMsgFocusUp) + { + return iViewer->IsCursorLocation(EMsgTop); + } + return EFalse; + } + +HBufC* CVCalendarBioControl::HeaderTextL() const + { + return StringLoader::LoadL(R_QTN_SM_TITLE_INVITATION, iCoeEnv); + } + +TInt CVCalendarBioControl::VirtualHeight() + { + return iViewer->VirtualHeight(); + } + +TInt CVCalendarBioControl::VirtualVisibleTop() + { + return iViewer->VirtualVisibleTop(); + } + +TBool CVCalendarBioControl::IsCursorLocation(TMsgCursorLocation aLocation) const + { + return iViewer->IsCursorLocation(aLocation); + } +void CVCalendarBioControl::GetHelpContext( + TCoeHelpContext& aHelpContext) const + { + if ( FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + const TUid KUidSmart = {0x101F4CDA}; + if ( ! iIsFileBased ) + { + aHelpContext.iContext=IsEditor()? + KSMART_HLP_CALENDAREDITOR():KSMART_HLP_CALENDARVIEWER() ; + aHelpContext.iMajor=KUidSmart; + } + else + { + if ( !IsEditor() ) + { + aHelpContext.iContext=KSMART_HLP_CALPULLMESVIEWER; + aHelpContext.iMajor=KUidSmart; + } + } + } + } + + + + +TInt CVCalendarBioControl::CountComponentControls() const + { + return 1; // the viewer component + } + +CCoeControl* CVCalendarBioControl::ComponentControl(TInt aIndex) const + { + if (aIndex == 0) + { + return iViewer; + } + return NULL; + } + +void CVCalendarBioControl::SizeChanged() + { + iViewer->SetExtent(Position(), iViewer->Size()); + } + +void CVCalendarBioControl::FocusChanged(TDrawNow /*aDrawNow*/) + { + iViewer->SetFocus(IsFocused()); + } + +void CVCalendarBioControl::SetContainerWindowL(const CCoeControl& aContainer) + { + + CCoeControl::SetContainerWindowL(aContainer); + + // The reason for creating the viewer control here is that the + // construction of the viewer requires a parent with a window. So it + // cannot be done in ConstructL(). + // + iViewer->ConstructL(this); + } + +TKeyResponse CVCalendarBioControl::OfferKeyEventL( + const TKeyEvent& aKeyEvent, + TEventCode aType) + { + return iViewer->OfferKeyEventL(aKeyEvent, aType); + } + +void CVCalendarBioControl::HandleResourceChange( TInt aType ) + { + LOG("CVCalendarBioControl::HandleResourceChange begin"); + CMsgBioControl::HandleResourceChange( aType ); + + if ( aType == KEikDynamicLayoutVariantSwitch ) + { + iViewer->Reset(); + } + LOG("CVCalendarBioControl::HandleResourceChange end"); + } + +#if defined (__I_CAL_SUPPORT) && defined (RD_MESSAGING_ICAL_IMPORT) +void CVCalendarBioControl::ImportVCalendarL() + { + LOG("CVCalendarBioControl::ImportVCalendarL begin"); + + CCalenImporter* calImporter = CCalenImporter::NewL( *iSession ); + CleanupStack::PushL( calImporter ); + calImporter->SetImportMode( ECalenImportModeExtended ); + + RFile fileHandle; + ResolveFileL( fileHandle ); + RFileReadStream stream( fileHandle,0 ); + CleanupClosePushL( stream ); + + TBuf8 vcalData; + + TInt errRead( KErrNone ); + TRAP( errRead,stream.ReadL( vcalData,KReadDataAmount ) ); + + if( errRead != KErrEof && errRead != KErrNone ) + { + User::Leave( KVCalBcLeaveCodeCorrupt ); + } + + //return the read stream back to the beginning for import + stream.Source()->SeekL( MStreamBuf::ERead, EStreamBeginning, 0 ); + + TInt errImport( KErrNone ); + //Reset the array if its already imported. + if(iCalEntryArray.Count()) + iCalEntryArray.ResetAndDestroy(); + + if ( vcalData.FindF( KVersionVCal ) == KErrNotFound ) + { + //using the ICAl import API + TRAP( errImport, calImporter->ImportICalendarL( stream, iCalEntryArray ) ); + } + else if ( vcalData.FindF( KVersionICal ) == KErrNotFound ) + { + //using the VCAL import API + TRAP( errImport, calImporter->ImportVCalendarL( stream, iCalEntryArray ) ); + } + CleanupStack::PopAndDestroy( 2, calImporter ); //stream, calImporter + if( errImport != KErrNone || iCalEntryArray.Count() == 0 ) + { + LOG1("CVCalendarBioControl::ImportVCalendarL ERROR %d", err); + LOG1("CVCalendarBioControl::ImportVCalendarL ERROR imported cal entry count %d", iCalEntryArray.Count() ); + // the data was corrupt + User::Leave( KVCalBcLeaveCodeCorrupt ); + } + + //BIO viewer always sets the local UID to 0 in imported entry + iCalEntryArray[0]->SetLocalUidL( TCalLocalUid(0) ); + + LOG("CVCalendarBioControl::ImportVCalendarL end"); + } +#else +void CVCalendarBioControl::ImportVCalendarL() + { + LOG("CVCalendarBioControl::ImportVCalendarL begin"); + + CCalenImporter* calImporter = CCalenImporter::NewL( *iSession ); + CleanupStack::PushL( calImporter ); + calImporter->SetImportMode( ECalenImportModeExtended ); + + RFile fileHandle; + ResolveFileL( fileHandle ); + RFileReadStream stream( fileHandle,0 ); + CleanupClosePushL( stream ); + + iCalEntryArray.ResetAndDestroy(); + TRAPD( err, calImporter->ImportVCalendarL( stream, iCalEntryArray ) ); + CleanupStack::PopAndDestroy( 2,calImporter );//stream, calImporter + if( err != KErrNone || iCalEntryArray.Count() == 0 ) + { + LOG1("CVCalendarBioControl::ImportVCalendarL ERROR %d", err); + LOG1("CVCalendarBioControl::ImportVCalendarL ERROR imported cal entry count %d", iCalEntryArray.Count() ); + // the data was corrupt + User::Leave( KVCalBcLeaveCodeCorrupt ); + } + + //BIO viewer always sets the local UID to 0 in imported entry + iCalEntryArray[0]->SetLocalUidL( TCalLocalUid(0) ); + + LOG("CVCalendarBioControl::ImportVCalendarL end"); + } +#endif + +void CVCalendarBioControl::ResolveFileL( RFile& aFile ) + { + if ( iIsFileBased ) + { + //if filebased vcalendar message (opened via BVA) + //we make a copy to a new handle from class variable iFileHandle + aFile.Duplicate( iFileHandle ); + } + else + { + //if vcal is opened from message then we fetch new handle from attachment + CMsvEntry* entry = MsvSession().GetEntryL( iId ); + CleanupStack::PushL( entry ); + CMsvStore* store = entry->ReadStoreL(); + CleanupStack::PushL(store); + MMsvAttachmentManager& attachMan = store->AttachmentManagerL(); + aFile = attachMan.GetAttachmentFileL( 0 ); //entry is the first attachment + CleanupStack::PopAndDestroy( 2 ); // store, entry + } + } + +void CVCalendarBioControl::FileBasedAddMenuItemL(CEikMenuPane& aMenuPane, + TInt aStringRes, TInt aCommandOffset) + { + CEikMenuPaneItem::SData menuItem; + menuItem.iCascadeId = NULL; + menuItem.iFlags = NULL; + menuItem.iText.Format(*StringLoader::LoadLC(aStringRes, iCoeEnv)); + CleanupStack::PopAndDestroy(); // (string) + menuItem.iCommandId = iBioControlObserver.FirstFreeCommand() + + aCommandOffset; + aMenuPane.InsertMenuItemL(menuItem, 0); + } + +void CVCalendarBioControl::OpenStreamLC(RFileReadStream& aStream, + TFileName& aFileName) + { + User::LeaveIfError( aStream.Open( + CCoeEnv::Static()->FsSession(), + aFileName, + EFileStream )); + aStream.PushL(); + } + +CVCalendarBioControl::CVCalendarBioControl( + MMsgBioControlObserver& aObserver, + CMsvSession* aSession, + TMsvId aId, + TMsgBioMode aEditorOrViewerMode, + const RFile* aFile): + CMsgBioControl(aObserver, + aSession, + aId, + aEditorOrViewerMode, + aFile), + iCalEntryInitErrno( KErrNone ) + { + } + +void CVCalendarBioControl::ConstructL() + { + LOG("CVCalendarBioControl::ConstructL begin"); + + SetExtension( this ); + + iIsFileBased = IsFileBased(); + + LoadResourceL(KVCalBCResourceFile); + LoadResourceL(KAvkonResourceFile); + + LoadResourceL(KBvaResourceFile, KDC_APP_RESOURCE_DIR); + LoadResourceL(KSmsViewerResourceFile, KDC_APP_RESOURCE_DIR); + LoadStandardBioResourceL(); + iSession = CCalSession::NewL(); + // Which calendar file should be used. + TRAPD( err, iSession->OpenL( iSession->DefaultFileNameL() ) ); + if ( err == KErrNotFound ) + { + // If calendar file was not found, should we create it or not? + // I think is not BIO control's responsibility to create it. + // + iSession->CreateCalFileL( iSession->DefaultFileNameL() ); + iSession->OpenL( iSession->DefaultFileNameL() ); + } + else + { + User::LeaveIfError( err ); + } + + //make a copy of the filehandle if the vcal is opened from a file + //this is because it cannot be acquired later since it goes out of scope + if ( iIsFileBased ) + { + iFileHandle.Duplicate(FileHandle()); + } + + RFile fileHandle; + ResolveFileL(fileHandle); + RFileReadStream stream( fileHandle,0 ); + CleanupClosePushL( stream ); + + MStreamBuf* buf = stream.Source(); + buf->PushL(); + User::LeaveIfNull(buf); + TInt bufferSize = buf->SizeL(); + if (bufferSize == 0 || (bufferSize < KLengthBeginVCalendar)) + { + User::Leave(KErrMsgBioMessageNotValid); + } + FeatureManager::InitializeLibL(); + + ImportVCalendarL(); + iViewer = new (ELeave) CRichBio(ERichBioModeEditorBase); + CVCalBcDataFiller::FillViewerWithDataL( + *iViewer, *iCalEntryArray[KIndexFirst], *iCoeEnv); + + CleanupStack::PopAndDestroy(2); + + LOG("CVCalendarBioControl::ConstructL end"); + } + +void CVCalendarBioControl::Progress(TInt /* aPercentageCompleted */) + { + // Empty + } + +void CVCalendarBioControl::Completed(TInt aError) + { + iCalEntryInitErrno = aError; + CActiveScheduler::Stop(); + } + +TBool CVCalendarBioControl::NotifyProgress() + { + // Return ETrue if you want progress information. + return EFalse; + } + +TAny* CVCalendarBioControl::BioControlExtension(TInt aExtensionId) + { + if ( aExtensionId == KMsgBioControlScrollExtension ) + { + return static_cast (this); + } + else + { + return NULL; + } + } + +TInt CVCalendarBioControl::ExtScrollL( TInt aPixelsToScroll, + TMsgScrollDirection aDirection ) + { + return iViewer->ScrollL(aPixelsToScroll, aDirection); + } + +void CVCalendarBioControl::ExtNotifyViewEvent( TMsgViewEvent aEvent, TInt aParam ) + { + iViewer->NotifyViewEvent( aEvent, aParam ); + } + +GLDEF_C void Panic(TVCalBcPanic aPanic) + { + _LIT(KPanicText, "VCalBC.dll"); + User::Panic(KPanicText, aPanic); + } +// End of File