--- /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 <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