messagingappbase/smartmessaging/vcalbc/src/VCalendarBioControl.cpp
branchRCL_3
changeset 27 7fdbb852d323
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingappbase/smartmessaging/vcalbc/src/VCalendarBioControl.cpp	Wed Sep 01 12:31:54 2010 +0100
@@ -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 <eikon.hrh>
+#include <eikmenup.h>
+#include <msvapi.h>
+#include <s32file.h>                // RFileReadStream
+#include <StringLoader.h>           // StringLoader
+#include <msgbiocontrolObserver.h>  // MMsgBioControlObserver
+#include <vcalbc.rsg>               // resouce identifiers
+#include <CRichBio.h>               // CRichBio
+#include <CalenImporter.h>          // CCalenImporter
+#include <calentryview.h>           // CCalEntryView
+#include <MsgBioUtils.h>
+#include <bldvariant.hrh>			// __SERIES60_HELP
+#include <csxhelp/smart.hlp.hrh>
+#include <featmgr.h>
+#include <calsession.h>
+#include <mmsvattachmentmanager.h>
+#include <sysutil.h>
+#include <ecom/ecom.h>
+#include <AknDef.h>
+#include <AiwServiceHandler.h>          // CAiwServiceHandler
+#include <SmsViewer.rsg>
+#include <bva.rsg>
+#include <AiwCommon.hrh>
+#include <data_caging_path_literals.hrh>
+
+// 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<KReadDataAmount> 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<MMsgBioControlScrollExtension*> (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