diff -r 000000000000 -r 72b543305e3a email/mail/PluginSrc/icalviewer/uisrc/CICalViewer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/mail/PluginSrc/icalviewer/uisrc/CICalViewer.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,649 @@ +/* +* Copyright (c) 2002-2006 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: ICalendar viewer ECOM plugin +* +*/ + + +// INCLUDE FILES + +#include "CICalViewer.h" +#include "CICalViewerView.h" +#include "MailLog.h" +#include "ICalViewer.hrh" +#include "icalvieweruid.h" +#include +#include "cicalattaloader.h" +#include + +// SYSTEM INCLUDES +#include +#include // CMsgEditorView +#include +#include +#include +#include +#include +#include +#include +#include +#include //calendar api V2 +#include //entry ui params +#include //mail viewer application uid +#include //mail +#include //HBufC +#include //CCalAttendee +#include //CCalAlarm +#include //TCalRRule +#include +#include +#include // import/export for ical files +#include //MTM uid constants for resolver params + + +// CONSTANTS +/// Unnamed namespace for local definitions +namespace { + +_LIT(KICalUiResourceFile, "icalvieweruires.rsc"); +_LIT8(KDataTypeVCalendar2, "text/x-vCalendar"); // vCalendar v1.0 MIME type +_LIT8(KDataTypeVCalendar3, "text/calendar"); // vCalendar v2.0 MIME type + +enum TStatusFlags + { + EFlagRecognized = KBit0, + EFlagIsUnread = KBit1, // MsgEditor sets unread flag to EFalse too early! + EFlagIsNavigableForward = KBit2, + EFlagIsNavigableBackward = KBit3, + }; + +} // namespace + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CICalViewer::CICalViewer +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CICalViewer::CICalViewer(): iFlags(0) + { + } + +// ----------------------------------------------------------------------------- +// CICalViewer::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CICalViewer::ConstructL() + { + LOG("CICalViewer::ConstructL"); + FeatureManager::InitializeLibL(); + + TFileName driveName; + DoGetCorrectDllDriveL( driveName ); + TInt nameLength = driveName.Length() + KICalUiResourceFile().Length(); + LOG1("CICalViewer::ConstructL: namelength: %d", nameLength); + iResourceFile = HBufC::NewL( KMaxFileName ); + *iResourceFile = driveName; + iResourceFile->Des().Append( KICalUiResourceFile ); + + LOG("CICalViewer::ConstructL -> End"); + } +// ----------------------------------------------------------------------------- +// CICalViewer::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CICalViewer* CICalViewer::NewL() + { + CICalViewer* self = new(ELeave) CICalViewer(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// CICalViewer::~CICalViewer() +// Destructor +// ----------------------------------------------------------------------------- +// +CICalViewer::~CICalViewer() + { + LOG("CICalViewer::~CICalViewer"); + delete iResourceFile; + delete iAttaLoad; + delete iICalView; + FeatureManager::UnInitializeLib(); + iEntries.ResetAndDestroy(); + delete iIdleLauncher; + delete iImporter; + delete iEntryUiInParams; + delete iEntryUiOutParams; + delete iSession; + LOG("CICalViewer::~CICalViewer -> End"); + } + +// ----------------------------------------------------------------------------- +// CICalViewer::ViewMessageL +// ----------------------------------------------------------------------------- +// +void CICalViewer::ViewMessageL( RFileReadStream& aReadStream, + MMailAppUiInterface& aUICallBack) + { + LOG("CICalViewer::ViewMessageL (BVA)"); + + if (!iAppUi) + { + iAppUi = &aUICallBack; + } + + if ( !iSession ) + { + iSession = CCalSession::NewL(); + } + + TRAPD( err, iSession->OpenL( iSession->DefaultFileNameL() ) ); + if ( err == KErrNotFound ) + { + iSession->CreateCalFileL( iSession->DefaultFileNameL() ); + iSession->OpenL( iSession->DefaultFileNameL() ); + } + else + { + User::LeaveIfError( err ); + } + + if ( !iImporter ) + { + iImporter = CCalenImporter::NewL( *iSession ); + } + + LOG("CICalViewer::ViewMessageL, starting iCal importing"); + iImporter->ImportICalendarL( aReadStream, iEntries ); + + if( iEntries.Count() == 0 ) + { + User::Leave( KErrNotFound ); + } + + LOG("CICalViewer:: ...importing finished"); + + LOG("CICalViewer::ViewMessageL, creating AgnEntryUi"); + iEntryUiInParams = new(ELeave) MAgnEntryUi::TAgnEntryUiInParams( + TUid::Uid( KUidBVAApplication ), + *iSession, + MAgnEntryUi::EViewEntry ); + + LOG("CICalViewer::ViewMessageL, launching viewer"); + // In case of BVA we can always launch the default AgnEntryUi + // -> this can be achieved by giving SMTP mtm uid + DoViewMessageL( KSenduiMtmSmtpUid ); + LOG("CICalViewer::ViewMessageL -> End"); + } + +// ----------------------------------------------------------------------------- +// CICalViewer::ParseMessageToCalEntryL +// ----------------------------------------------------------------------------- +// +void CICalViewer::ParseMessageToCalEntryL( CMailMessage& aMessage ) + { + LOG("CICalViewer::ParseMessageToCalEntryL"); + if ( !iSession ) + { + iSession = CCalSession::NewL(); + } + + TRAPD( err, iSession->OpenL( iSession->DefaultFileNameL() ) ); + if ( err == KErrNotFound ) + { + iSession->CreateCalFileL( iSession->DefaultFileNameL() ); + iSession->OpenL( iSession->DefaultFileNameL() ); + } + else + { + User::LeaveIfError( err ); + } + + LOG("CICalViewer::ParseMessageToCalEntryL, checking attachment info"); + + MMsvAttachmentManager& attachmentManager = + aMessage.AttachmentManager(); + + TInt attaCount = attachmentManager.AttachmentCount(); + + if ( attaCount > 0 ) + { + CMsvAttachment* info = attachmentManager.GetAttachmentInfoL(0); + CleanupStack::PushL(info); + + const TDesC& filePath = info->FilePath(); + + RFile attachment = attachmentManager.GetAttachmentFileL( 0 ); + CleanupClosePushL( attachment ); // RFile must be closed + + RFileReadStream stream( attachment, 0 ); + CleanupClosePushL( stream ); + + if ( !iImporter ) + { + iImporter = CCalenImporter::NewL( *iSession ); + } + + LOG("CICalViewer:: starting iCal importing"); + iImporter->ImportICalendarL( stream, iEntries ); + + if( iEntries.Count() == 0 ) + { + User::Leave( KErrNotFound ); + } + + LOG("CICalViewer:: ...importing finished"); + + //checking of ical entry on rudimentary level + //so that we can make a leave here... + //even so... the ical cant be launched from plain text viewer + //only the alternative description text is shown to user + + CCalEntry& entry = *( iEntries[0] ); + switch ( entry.MethodL() ) + { + case CCalEntry::EMethodNone: + case CCalEntry::EMethodPublish: + case CCalEntry::EMethodAdd: + case CCalEntry::EMethodRefresh: + case CCalEntry::EMethodCounter: + case CCalEntry::EMethodDeclineCounter: + { + User::Leave( KErrNotSupported ); + } + } + + CleanupStack::PopAndDestroy( 3 ); // CSI: 47 # stream, attachment, info + } + LOG("CICalViewer::ParseMessageToCalEntryL -> End"); + } + +// ----------------------------------------------------------------------------- +// CICalViewer::ViewMessageL +// ----------------------------------------------------------------------------- +// +void CICalViewer::ViewMessageL( + CMailMessage& aMessage, + MMailAppUiInterface& aUICallBack, + TUint& aParam ) + { + LOG("CICalViewer::ViewMessageL (mail)"); + + aParam |= EMailUseDefaultNaviPane; + + iMsg = aMessage.MessageEntry(); + + if (!iAppUi) + { + iAppUi = &aUICallBack; + } + + LOG("CICalViewer::ViewMessageL, creating AgnEntryUi"); + iEntryUiInParams = new(ELeave) MAgnEntryUi::TAgnEntryUiInParams( + TUid::Uid( KUidMsgMailViewer ), + *iSession, + MAgnEntryUi::EViewEntry ); + + iEntryUiInParams->iMailBoxId = iMsg.iServiceId; + iEntryUiInParams->iMsgSession = aMessage.Session(); + iEntryUiInParams->iMessageId = iMsg.Id(); + + // Load attachments, otherwise they won't be visible in the + // attachement manager. CICalViewer::MessageLoadL() received + // also attachments ready signal, but attachment manager was + // resetted after that. + if ( !iAttaLoad ) + { + iAttaLoad = CICalAttaLoader::NewL( *iAppUi ); + } + iAttaLoad->StartLoadingL( aMessage ); + + LOG("CICalViewer::ViewMessageL, launching viewer"); + DoViewMessageL( iMsg.iMtm ); + LOG("CICalViewer::ViewMessageL -> End"); + } + +// ----------------------------------------------------------------------------- +// CICalViewer::IdleTimerCallbackL +// This method must be leaving so that exiting from viewer +// is possible (done using basched.h KLeaveExit) +// ----------------------------------------------------------------------------- +// +TInt CICalViewer::IdleTimerCallbackL(TAny* aViewer) // CSI: 40 # We must return + // the integer value although this + // is a leaving method. + { + CICalViewer* thisViewer = static_cast( aViewer ); + TRAPD( err, thisViewer->DoOMRViewerLaunchL() ); + if ( err != KErrNone ) + { + LOG("CIcalViewer::IdleTimerCallback, leave occurred, exiting"); + thisViewer->iAppUi->AppUiHandleCommandL( EAknSoftkeyBack ); + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CICalViewer::DoOMRViewerLaunchL +// ----------------------------------------------------------------------------- +// +void CICalViewer::DoOMRViewerLaunchL() + { + LOG("CICalViewer::DoOMRViewerLaunchL"); + iEntryUiOutParams = new(ELeave) MAgnEntryUi::TAgnEntryUiOutParams(); + ASSERT( iSession ); + + LOG("CICalViewer::DoOMRViewerLaunchL, executing viewer"); + iRetVal = iICalView->ExecuteViewL( iEntries, + *iEntryUiInParams, + *iEntryUiOutParams, + *this ); + LOG("CICalViewer::DoOMRViewerLaunchL, viewer finished"); + //we need to call back to ui for exiting the mail application + iAppUi->AppUiHandleCommandL( EAknSoftkeyBack ); + + LOG("CICalViewer::DoOMRViewerLaunchL -> End"); + } + +// ----------------------------------------------------------------------------- +// CICalViewer::DoGetCorrectDllDriveL +// ----------------------------------------------------------------------------- +// +void CICalViewer::DoGetCorrectDllDriveL( TFileName& aDriveName ) + { + TParse parse; + Dll::FileName( aDriveName ); + User::LeaveIfError( parse.Set( aDriveName, NULL, NULL ) ); + aDriveName = parse.Drive(); // contains drive, e.g. "c:" + } + +// ----------------------------------------------------------------------------- +// CICalViewer::DoViewMessageL +// ----------------------------------------------------------------------------- +// +void CICalViewer::DoViewMessageL( TUid aMtmUid ) + { + + if ( iAppUi->IsNextMessageAvailableL( ETrue ) ) + { + iFlags |= EFlagIsNavigableForward; + } + + if ( iAppUi->IsNextMessageAvailableL( EFalse ) ) + { + iFlags |= EFlagIsNavigableBackward; + } + + + LOG("CICalViewer::DoViewMessageL"); + iAppUi->SetTitleTextL(R_QTN_MAIL_TITLE_MTG_REQUEST); + + iICalView = CICalViewerView::NewL( aMtmUid ); + + LOG("CICalViewer:: adding ical viewer control"); + iAppUi->AddControlL(*iICalView); + + //idle timer + iIdleLauncher = CIdle::NewL(CActive::EPriorityIdle); + LOG("CICalViewer:: starting idle launcher"); + iIdleLauncher->Start(TCallBack(IdleTimerCallbackL,this)); + LOG("CICalViewer::DoViewMessageL -> End"); + } + +// ----------------------------------------------------------------------------- +// CICalViewer::DynInitMenuPaneL +// ----------------------------------------------------------------------------- +// +void CICalViewer::DynInitMenuPaneL(TInt /*aResourceId*/, + CEikMenuPane* /*aMenuPane*/) + { + } + +// ----------------------------------------------------------------------------- +// CICalViewer::HandleCommandL +// ----------------------------------------------------------------------------- +// +TBool CICalViewer::HandleCommandL(TInt /*aCommand*/) + { + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CICalViewer::HandleKeyEventL +// ----------------------------------------------------------------------------- +// +TKeyResponse CICalViewer::HandleKeyEventL(const TKeyEvent& /*aKeyEvent*/, + TEventCode /*aType*/) + { + return EKeyWasConsumed; + } + +// ----------------------------------------------------------------------------- +// CICalViewer::ResourceFile +// ----------------------------------------------------------------------------- +// +const TDesC& CICalViewer::ResourceFile() + { + return *iResourceFile; + } + +// ----------------------------------------------------------------------------- +// CICalViewer::MessageLoadL +// ----------------------------------------------------------------------------- +// +void CICalViewer::MessageLoadL( TInt aState, CMailMessage& aMessage ) + { + LOG("CICalViewer::MessageLoadL"); + switch (aState) + { + case CMailMessage::EHeaderReady: + { + LOG("CICalViewer::aState == EHeaderReady"); + // This switch case doesn't seem to ever get called + break; + } + case CMailMessage::EAttachmentsReady: + { + LOG("CICalViewer::aState == EAttachmentsReady"); + + if ( !aMessage.MessageEntry().ICalendar() ) + { // check that the entry is ical message + LOG("TMsvEmailEntry::ICalendar() returned EFalse"); + User::Leave( KErrUnknown ); + } + + RFile attachment; + TInt count = aMessage.AttachmentManager().AttachmentCount(); + + if ( count > 0 ) + { + attachment = + aMessage.AttachmentManager().GetAttachmentFileL( 0 ); + CleanupClosePushL( attachment ); + + RApaLsSession apaSession; + User::LeaveIfError( apaSession.Connect() ); + CleanupClosePushL( apaSession ); + TUid appUID( KNullUid ); + TDataType dataType; + // Check only first attachment + User::LeaveIfError( apaSession.AppForDocument( attachment, + appUID, + dataType ) ); + CleanupStack::PopAndDestroy( 2 ); // CSI: 47 # apaSession, attachment + + if ( dataType.Des8().FindF( + KDataTypeVCalendar2 ) != KErrNotFound || + dataType.Des8().FindF( + KDataTypeVCalendar3 ) != KErrNotFound ) + { + LOG("CICalViewer::starting msg parsing"); + //we can do attachment parsing only here as + //attachment manager is resetted after this + + ParseMessageToCalEntryL( aMessage ); + + iFlags |= EFlagRecognized; + LOG("CICalViewer::recognized!"); + } + else + { + LOG("CICalViewer::datatype unknown"); + // unknown + User::Leave( KErrUnknown ); + } + } + else + { + User::Leave( KErrUnknown ); + } + break; + } + case CMailMessage::ELoadEnd: + { + LOG("CICalViewer::aState == ELoadEnd"); + if ( !(iFlags & EFlagRecognized) ) + { + // Not valid message + User::Leave( KErrUnknown ); + } + if ( aMessage.IsNew() ) + { + iFlags |= EFlagIsUnread; + } + break; + } + default: + { + // do nothing + break; + } + } + LOG("CICalViewer::MessageLoadL -> End"); + } + +// ----------------------------------------------------------------------------- +// CICalViewer::IsCommandAvailable +// ----------------------------------------------------------------------------- +// +TBool CICalViewer::IsCommandAvailable( TInt aCommandId ) + { + TBool retVal( EFalse ); + switch ( aCommandId ) + { + case EMRCommandRetrieve: + { + retVal = iMsg.PartialDownloaded(); + break; + } + case EMRCommandAttachments: + { + retVal = ( iAttaLoad && iAttaLoad->FinishedWithAttachments() ); + break; + } + case EMRCommandUnreadOpeningNote: + { + retVal = ( ( iFlags & EFlagIsUnread ) != 0 ); + break; + } + case EMRCommandNavigateBackward: + { + retVal = ( ( iFlags & EFlagIsNavigableBackward ) != 0 ); + } + case EMRCommandNavigateForward: + { + retVal = ( ( iFlags & EFlagIsNavigableForward ) != 0 ); + break; + } + default: + { + break; + } + } + return retVal; + } + +// ----------------------------------------------------------------------------- +// CICalViewer::ProcessCommandWithResultL +// ----------------------------------------------------------------------------- +// +TInt CICalViewer::ProcessCommandWithResultL( TInt aCommandId ) // CSI: 40 # We must return + // the integer value although this + // is a leaving method. + { + LOG("CICalViewer::ProcessCommandWithResultL -> End"); + TInt retVal( KErrNone ); + switch ( aCommandId ) + { + case EMRCommandForward: + { + LOG("Calling AppUiHandleCommandL with forward cmd..."); + iAppUi->AppUiHandleCommandL( EMsgMailViewerCmdForward ); + break; + } + case EMRCommandRetrieve: + { + iAppUi->AppUiHandleCommandL( EMsgMailViewerCmdRetrieve ); + break; + } + case EMRCommandAttachments: + { + iAppUi->AppUiHandleCommandL( EMsgMailViewerCmdAttachments ); + break; + } + case EMRCommandMessageDetails: + { + iAppUi->AppUiHandleCommandL( EMsgMailViewerCmdMessageInfo ); + break; + } + case EMRCommandNavigateBackward: + { + iAppUi->NextMessageL( EFalse ); + break; + } + case EMRCommandNavigateForward: + { + iAppUi->NextMessageL( ETrue ); + break; + } + default: + { + User::Leave( KErrNotSupported ); + return KErrNotSupported; + } + } + LOG("CICalViewer::ProcessCommandWithResultL -> End"); + return retVal; + } + +// ----------------------------------------------------------------------------- +// CICalViewer::ProcessCommandL +// ----------------------------------------------------------------------------- +// +void CICalViewer::ProcessCommandL( TInt aCommandId ) + { + ProcessCommandWithResultL( aCommandId ); + } + +// End of File +