diff -r 000000000000 -r f979ecb2b13e calendarui/views/src/caleneventviewcontainer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/calendarui/views/src/caleneventviewcontainer.cpp Tue Feb 02 10:12:19 2010 +0200 @@ -0,0 +1,2989 @@ +/* +* Copyright (c) 2009 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: event view's container implementation +* +*/ + +// system includes +#include +#include // CAknNavigationDecorator +#include // CAknNaviLabel +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // CEikMenuPane +#include +#include // FeatureManager +#include // CEikRichTextEditor +#include +#include +#include // CRichText +#include +#include //Autofinder +#include +#include +#include +#include +#include +#include +#include +#include +#include // EAknCmdHelp +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // Calendar commands +#include +#include // TCalenInstanceId +#include +#include +#include +#include + +// user includes +#include "caleneventviewcontainer.h" +#include "caleneventview.h" +#include "calennativeview.h" +#include "calendarui_debug.h" +#include "calenicondrawer.h" +#include "calennotedatautil.h" +#include "calendar.hrh" +#include "calenentryutil.h" +#include "CalenUid.h" // KUidCalendar +#include "calenlocationutil.h" +#include "CalendarPrivateCRKeys.h" +#include "calenattachmentutils.h" +#include "calenglobaldata.h" +#include "CleanupResetAndDestroy.h" + +// LOCAL CONSTANTS AND MACROS +_LIT( KWesternSummaryMarker, "\x200E" ); +_LIT( KArabicSummaryMarker , "\x200F" ); +_LIT(KSpace, " "); +_LIT(KYearFormatString,"%F%Y"); +_LIT(KAttachmentSeparator,"; "); +_LIT8( KNotePadTextDataType, "text/plain" ); + +const TInt KDefaultRightMargin=0; +const TInt KScrollViewerUp = 1; +const TInt KScrollViewerDown = -1; +const TInt KMaxDateLength = 32; + +//PANIC CODE +enum TPanicCode + { + EPanicArrayOfSizeZero=2, + }; + +// ================= MEMBER FUNCTIONS ========================================= + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::CCalenEventViewContainer +// C++ constructor. +// ---------------------------------------------------------------------------- +// +CCalenEventViewContainer::CCalenEventViewContainer(CCalenNativeView* aView, + MCalenServices& aServices ) + : CCalenContainer( aView, aServices ), + iEntry(NULL), + iAutomaticHlValue(ETrue), + iAutomaticHlInitialized(EFalse) + { + TRACE_ENTRY_POINT; + iNumOfLinesBeforeLocField = 0; + iLocaleChanged = EFalse; + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::~CCalenEventViewContainer +// Destructor +// ---------------------------------------------------------------------------- +// +CCalenEventViewContainer::~CCalenEventViewContainer() + { + TRACE_ENTRY_POINT; + + if(iEntry) + { + delete iEntry; + } + + iFetchedEntries.ResetAndDestroy(); + + delete iParaFormat; + delete iSearchBuf; + delete iEventViewData; + delete iTextEditor; + delete iBgContext; + delete iTimeFormat; + delete iDateFormat; + delete iDocHandler; + delete iAutoFinder; + delete iFindMenu; + + if( iNotifier ) + { + iNotifier->StopListening(); + delete iNotifier; + }; + + delete iCenRepSession; + if(iLabel) + delete iLabel; + + //Reset the attachment posiitons array + iAttachmentPosInfoArray.Reset(); + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::ConstructImplL +// Third phase constructor. +// This function was called CCalenNativeView::ConstructL(). +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::ConstructImplL() + { + TRACE_ENTRY_POINT; + + iTimeFormat = StringLoader::LoadL( R_QTN_TIME_USUAL_WITH_ZERO, CEikonEnv::Static() ); + iDateFormat = StringLoader::LoadL( R_QTN_DATE_USUAL_WITH_ZERO, CEikonEnv::Static() ); + + iBgContext = CAknsBasicBackgroundControlContext::NewL( KAknsIIDQsnBgAreaMain, + Rect(), + ETrue ); + + iDocHandler = CDocumentHandler::NewL( iEikonEnv->Process() ); + iAutoFinder = CItemFinder::NewL(); + iFindMenu = CFindItemMenu::NewL( EFindItemMenuPlaceHolder ); + iFindMenu->AttachItemFinderMenuL(0); + + iParaFormat = CParaFormat::NewL(); + + + iTextEditor = new (ELeave) CEikRichTextEditor; + iTextEditor->ConstructL(this, 0, 0, CEikEdwin::EReadOnly | CEikEdwin::EAvkonDisableCursor | + CEikEdwin::ENoAutoSelection|CEikEdwin::EAvkonEditor); + iTextEditor->SetMopParent(this); + iTextEditor->SetRect( Rect() ); + + iLabel = new (ELeave) CEikLabel; + iLabel->SetContainerWindowL(*this); + iLabel->SetTextL(_L("")); + iLabel->SetRect(Rect()); + + ReadAutoHlCenRepValueAndSetNotifyL(); + + CCalenEventView* eventView = static_cast( iView ); + if( !( eventView->IsAlarmActiveInViewer() ) ) + { + SetAutomaticHighlightL(iAutomaticHlValue); + } + + iDocHandler->SetExitObserver( this ); + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::UpdateSize +// Do layout changes after calendar settings are +// changed. No necessary actions for this view. +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::UpdateSize() + { + TRACE_ENTRY_POINT; + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::CreateIconIndicesL +// Second and final stage of population. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::CreateIconIndicesL( RArray& /*aIndexArray*/ ) + { + TRACE_ENTRY_POINT; + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::CompletePopulationL +// Complete population +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::CompletePopulationL() + { + TRACE_ENTRY_POINT; + if(iTextEditor && iTextEditor->Text()->DocumentLength() > 0 && iAutoFinder && + iSelectedText.iCursorPos == 0 && iSelectedText.iAnchorPos == 0) + { + iAutoFinder->SetEditor((CEikRichTextEditor**)&iTextEditor); + } + + iTextEditor->SetFocus(ETrue); + ActivateL(); + AddToStackAndMakeVisibleL(); + DrawDeferred(); + if(iSelectedText.iCursorPos > 0 || iSelectedText.iAnchorPos > 0) + { + //Set the text selection existed before layout change + iTextEditor->SetCursorPosL(iSelectedText.iCursorPos, EFalse); + iTextEditor->SetSelectionL(iSelectedText.iCursorPos,iSelectedText.iAnchorPos); + } + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::HandleNaviDecoratorEventL +// ?implementation_description +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::HandleNaviDecoratorEventL( TInt /*aEventID*/ ) + { + TRACE_ENTRY_POINT; + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::HandleLongTapEventL +// processing of a long tap event +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::HandleLongTapEventL( const TPoint& /*aPenEventLocation*/, + const TPoint& /*aPenEventScreenLocation*/ ) + { + TRACE_ENTRY_POINT; + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::Draw +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::Draw(const TRect& /*aRect*/) const + { + TRACE_ENTRY_POINT; + + CWindowGc& gc = SystemGc(); + + TRect mainPane; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPane ); + TRect bgContextRect( TPoint(0, 0), mainPane.Size() ); + iBgContext->SetRect( bgContextRect); + iBgContext->SetParentPos(mainPane.iTl); + AknsDrawUtils::Background( AknsUtils::SkinInstance(), iBgContext, this, gc, Rect()); + + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::Sizechanged +// Child control was resized. +// (other items were commented in a header) +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::SizeChanged() + { + TRACE_ENTRY_POINT; + + SetLayoutFromLookAndFeelL(); + + if (iTextEditor) + { + TRAPD(error,iTextEditor->HandleTextChangedL() ); + if(error!=KErrNone) + { + // Do nothing to avoid warning + } + } + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::CountComponentControls +// Return child control count. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt CCalenEventViewContainer::CountComponentControls() const + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + return 2; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::ComponentControl +// Return child control pointer. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +CCoeControl* CCalenEventViewContainer::ComponentControl(TInt aIndex) const // Child control index + { + TRACE_ENTRY_POINT; + CCoeControl* control ( NULL ); + switch(aIndex) + { + case 0: + control = iTextEditor; + break; + + case 1: + control = iLabel; + break; + + default: + __ASSERT_DEBUG( 0, User::Invariant() ); + break; + } + TRACE_EXIT_POINT; + + return control; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::OfferKeyEventL +// Process key event. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TKeyResponse CCalenEventViewContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType) + { + TRACE_ENTRY_POINT; + + TKeyResponse keyResponse(EKeyWasNotConsumed); + + if (aType == EEventKey) + { + switch (aKeyEvent.iCode) + { + case EKeyUpArrow: + { + iAutoFinder->NextItemOrScrollL( CItemFinder::ENextUp ); + // Scroll the text view up by one line + iTextEditor->MakeVisible(EFalse); + TInt scrollLines = KScrollViewerUp; + iTextEditor->TextView()->ScrollDisplayLinesL(scrollLines); + iTextEditor->UpdateScrollBarsL(); + iTextEditor->MakeVisible(ETrue); + //Set focus immediately for highlight of auto find text + iTextEditor->SetFocus(ETrue); + keyResponse = EKeyWasConsumed; + } + break; + + case EKeyDownArrow: + { + iAutoFinder->NextItemOrScrollL( CItemFinder::ENextDown ); + // Scroll the text view down by one line + iTextEditor->MakeVisible(EFalse); + TInt scrollLines = KScrollViewerDown; + iTextEditor->TextView()->ScrollDisplayLinesL(scrollLines); + iTextEditor->UpdateScrollBarsL(); + iTextEditor->MakeVisible(ETrue); + //Set focus immediately for highlight of auto find text + iTextEditor->SetFocus(ETrue); + keyResponse = EKeyWasConsumed; + } + break; + + case EKeyOK: + { + iView->HandleCommandL(ECalenCmdPromptThenEdit); + keyResponse = EKeyWasConsumed; + } + break; + case EKeyEscape: + { + // Calendar relaunched from cmd line - close viewer + iView->HandleCommandL(EAknSoftkeyBack); + keyResponse = EKeyWasConsumed; + } + break; + case EKeyPhoneSend: + { + HandleNumberCallL(); + break; + } + case EKeyBackspace: /* fall through... */ + case EKeyDelete: + { + CCalenEventView* eventView = static_cast( iView ); + if( !( eventView->IsAlarmActiveInViewer() ) ) + { + iView->HandleCommandL( ECalenDeleteCurrentEntry ); + } + } + break; + default: + break; + } + } + // For handling geokeys on corolla hardware + // For Add location hard key + if( aKeyEvent.iScanCode == EStdKeyApplication1C && aType == EEventKeyUp ) + { + if(CCalenLocationUtil::IsMapProviderAvailableL()) + { + CCalEntry::TType entryType = iEntry->EntryTypeL(); + if(entryType == CCalEntry::EAppt) + { + iServices.IssueCommandL(ECalenGetLocationAndSave); + } + keyResponse = EKeyWasConsumed; + } + } + // For Show location hard key + else if( aKeyEvent.iScanCode == EStdKeyApplication1B && aType == EEventKeyUp ) + { + if(CCalenLocationUtil::IsMapProviderAvailableL()) + { + CCalEntry::TType entryType = iEntry->EntryTypeL(); + if(entryType == CCalEntry::EAppt) + { + TPtrC location = iEntry->LocationL(); + if(iEntry->GeoValueL()) + { + iServices.IssueCommandL(ECalenShowLocation); + keyResponse = EKeyWasConsumed; + } + else if(location.Length()) + { + iServices.IssueCommandL(ECalenGetLocationAndReplace); + } + else + { + iServices.IssueCommandL(ECalenShowLocationQuery); + } + keyResponse = EKeyWasConsumed; + } + } + } + // Swallow all other keyevents to prevent the active container processing them. + keyResponse = EKeyWasConsumed; + + TRACE_EXIT_POINT; + return keyResponse; + + + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::HandleNumberCallL +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::HandleNumberCallL() + { + TRACE_ENTRY_POINT; + + const CItemFinder::CFindItemExt& findItem = iAutoFinder->CurrentItemExt(); + + if(findItem.iItemType != CItemFinder::EPhoneNumber) + { + return; + } + + iFindMenu->HandleCallL( findItem.iItemDescriptor->Des() ); + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::HandlePointerEventL +// Process pointer event. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::HandlePointerEventL(const TPointerEvent& aPointerEvent) + { + TRACE_ENTRY_POINT; + + if(!AknLayoutUtils::PenEnabled()) + { + return; + } + + CCalenEventView* eventView = static_cast( iView ); + if( !( eventView->IsAlarmActiveInViewer() ) ) + { + if(iTextEditor->Rect().Contains(aPointerEvent.iPosition)) + { + switch(aPointerEvent.iType) + { + case TPointerEvent::EButton1Down: + { + iTextEditor->SetFocus(ETrue); + + // TODO: Uncomment this when enabling attachment support + + if(iEventViewData->AttachmentCount()) + { + CTextView *textView = iTextEditor->TextView(); + + TTmPosInfo2 *posInfo = new(ELeave) TTmPosInfo2; + textView->FindXyPosL(aPointerEvent.iPosition,*posInfo); + + // Check if it is tapped on any attachment name, if yes then open that attachment + CheckAndOpenTappedAttachment(posInfo); + delete posInfo; + } + break; + } + case TPointerEvent::EDrag: + { + iTextEditor->SetFocus(ETrue); + break; + } + case TPointerEvent::EButton1Up: + { + iTextEditor->SetFocus(ETrue); + TInt curPos = iTextEditor->CursorPos(); + TRect rect = iTextEditor->Rect(); + if ( !iAutoFinder->ItemWasTappedL( aPointerEvent.iPosition - rect.iTl ) ) + { + // return; + } + break; + } + default: + { + break; + } + } + iTextEditor->HandlePointerEventL(aPointerEvent); + } + } + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::GetHelpContext +// Get help context. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::GetHelpContext(TCoeHelpContext& aContext) const + { + TRACE_ENTRY_POINT; + + aContext.iMajor = KUidCalendar; + aContext.iContext = KCALE_HLP_NOTE_VIEWER; // need to change + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::HandleResourceChange +// Handles a resource relative event. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::HandleResourceChange(TInt aType) + { + TRACE_ENTRY_POINT; + + CCalenContainer::HandleResourceChange( aType ); + + if( ( aType == KUidValueCoeColorSchemeChangeEvent ) || + ( aType == KUidValueCoeZoomChangeEvent ) || + ( aType == KUidValueCoeFontChangeEvent ) ) + { + CEikAppUi* appUi = static_cast( ControlEnv()->AppUi() ); + SetRect( appUi->ClientRect() ); + } + + if( KAknsMessageSkinChange == aType || + KEikDynamicLayoutVariantSwitch == aType ) + { + SizeChanged(); + + if(iTextEditor->ScrollBarFrame()) + { + // make the scrollbars invisible + iTextEditor->ScrollBarFrame()->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EOff); + } + + // refresh + TRAPD( error, iView->BeginRepopulationL() ); + if( KErrNone != error ) + { + // To avoid warning. + } + } + + // Allow the coecontrol to handle the changes if any. + CCoeControl::HandleResourceChange( aType ); + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::BuildTextEditorL +// Build text editor +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::BuildTextEditorL() + { + TRACE_ENTRY_POINT; + + iTextEditor->SetFocus(EFalse); + iTextEditor->SetRect( Rect() ); + iTextEditor->RichText()->Reset(); + + // Create the scroll bars. + iTextEditor->CreateScrollBarFrameL(); + iTextEditor->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto); + iTextEditor->SetAknEditorFlags(EAknEditorFlagEnableScrollBars); + iTextEditor->ScrollBarFrame()->VerticalScrollBar()->SetMopParent(this); + + iTextEditor->ScrollBarFrame()->SetScrollBarFrameObserver(this); + + TEikScrollBarModel h,v; + TEikScrollBarFrameLayout lay; + CEikAppUi* appUi = static_cast( ControlEnv()->AppUi() ); + TRect rec = appUi->ClientRect(); + // ASSERT( iTextEditor->ScrollBarFrame()->TileL( &h, &v, rec, rec, lay) ); + + SetLayoutFromLookAndFeelL(); + + SetupFontL(); + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::SetIconsL +// Set the icons +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::SetIconsL(CCalenIconDrawer* aIconDrawer) + { + // Create a TPictureHeader to insert our icons into the viewer + TPictureHeader header; + header.iPicture = TSwizzle(aIconDrawer); + + // Insert the icon drawer into the Rich Text Editor. This takes + // ownership of the icon drawer. + // Insert at index 0 in the document to cause the icons to be drawn when + // the first line is visible. The icons will not be drawn at position 0, + // but this position must be on the screen for the icons to be drawn. + iTextEditor->RichText()->InsertL( iTextEditor->RichText()->DocumentLength(), header ); + + // Tell the text editor that it has been updated. This will cause + // a redraw. + iTextEditor->HandleTextChangedL(); + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::CreateAndInitializeIconsDrawerL +// Cretaes the CCalenIconDrawer object for the container and returns it +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +CCalenIconDrawer* CCalenEventViewContainer::CreateAndInitializeIconsDrawerL() + { + // Create and populate the icon drawer. We need to do this first to prevent a long + // summary text being drawn over the icons + // Ownership of icon drawer transferred to rich text editor + CCalenIconDrawer* iconDrawer = CCalenIconDrawer::NewL( iServices ); + PopulateIconDrawerL(*iconDrawer); + return iconDrawer; + } +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::RequestInstanceViewL +// Request for instance view +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TInt CCalenEventViewContainer::RequestInstanceViewL() + { + TRACE_ENTRY_POINT; + + MCalenContext& context = iServices.Context(); + TCalenInstanceId instanceId = context.InstanceId(); + TCalLocalUid entryLocalUid = instanceId.iEntryLocalUid; + TTime instanceStartTime = context.InstanceId().iInstanceTime; + + if(iEntry) + { + delete iEntry; + iEntry = NULL; + } + //If the timezone is changed after opening the viewer + //We need to use the new instance time and need to update the context later + // Get the active collection ids. + RArray colIdArray; + CCalenNativeView::GetActiveCollectionidsL( iServices, colIdArray ); + + CCalInstanceView* instanceView = NULL; + if(iLocaleChanged) + { + instanceView = iServices.InstanceViewL(colIdArray); + CCalInstance* instance = FindPossibleInstanceL( instanceId,*instanceView ); + if(instance) + { + instanceStartTime = instance->StartTimeL().TimeLocalL(); + } + } + colIdArray.Reset(); + + iEntry = iServices.EntryViewL(context.InstanceId().iColId)->FetchL(entryLocalUid); + + TCalTime instanceDateTime; + instanceDateTime.SetTimeLocalL( context.InstanceId().iInstanceTime ); + + if(!iEntry) + { + // If the entry is not let's not further proceed. + // The entry has been removed by some other app eg. Synch. + return KErrNotFound; + } + + if(iEventViewData) + { + delete iEventViewData; + iEventViewData = NULL; + } + iEventViewData = CCalenEntryUtil::NewL( *iEntry, instanceDateTime ); + + //If timezone is changed after opening the entry in the viewer + //we need to update the instance id to the context + if(iLocaleChanged) + { + iLocaleChanged = EFalse; + instanceId.iInstanceTime = instanceStartTime; + context.SetFocusDateAndTimeAndInstanceL( instanceDateTime,instanceId,TVwsViewId( KUidCalendar, KUidCalenEventView ) ); + } + TRACE_EXIT_POINT; + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::AddFieldsL +// Add the data fields +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddFieldsL() + { + TRACE_ENTRY_POINT; + // Initialize icon drawer + CCalenIconDrawer* iconDrawer = CreateAndInitializeIconsDrawerL(); + + SetLabelContentL(*iLabel); + // add subject field + AddSubjectFieldL(); + + switch ( iEntry->EntryTypeL() ) + { + case CCalEntry::EReminder: + case CCalEntry::EAppt: + { + // start time + AddTimeFieldL(); + + // location + AddLocationFieldL(); + + // Adds empty line + AddEmptyLineL(); + + // alarm + AddAlarmDateTimeFieldL(); + + // We want to show the repeat fields for repeating parent entries or + // child entries. If the entry is a child then the repeat information from the + // parent will be shown + //if ((iEventViewData->IsRepeating()) || (Handler().Edited()->Entry().RecurrenceIdL().TimeUtcL() != Time::NullTTime())) + if ((iEventViewData->IsRepeating()) || (iEntry->RecurrenceIdL().TimeUtcL() != Time::NullTTime())) + { + AddRepeatFieldL(); + } + + iTitleTextId = R_CALEN_EVENT_VIEW_MEETING_TITLE; + } + break; + + case CCalEntry::EAnniv: + { + // date field + AddDateFieldL(iEventViewData->StartDateTime()); + + // Adds empty line + AddEmptyLineL(); + + // alarm + AddAlarmDateTimeFieldL(); + + // Add the 'since' field. + AddSinceFieldL(); + + iTitleTextId = R_CALEN_EVENT_VIEW_ANNIV_TITLE; + } + break; + + case CCalEntry::EEvent: + { + // If the start time is on the same day as the end time, just show the date. + // Otherwise, show "start date - end date". + TTime startTime = iEventViewData->StartDateTime(); + TTime endTime = iEventViewData->EndDateTime(); + + // For allday (1 day) event Eg. "Start:- 12:00am, 15-08-2010 & End:-12:00am, 16-08-2010" + // In viewer it should be displayed as "StartDate: 15-08-2010 & EndDate:15-08-2010" + // No time filed is displayed. + endTime -= TTimeIntervalDays( 1 ); + + // Set title to 'ALL DAY' + iTitleTextId = R_CALEN_EVENT_VIEW_ALLDAY_TITLE; + + if( CalenDateUtils::OnSameDay(startTime, endTime) ) + { + AddDateFieldL( startTime ); + } + else + { + AddDateDateFieldL( startTime, endTime ); + } + + // extra empty line between primary and secondary information + AddEmptyLineL(); + + // alarm + AddAlarmDateTimeFieldL(); + + // Currently it's not possible to create a repeating day note in the UI. + // However, it is possible to import one from an iCalendar file or create + // one in code. Therefore the repeat properties of day notes are shown + // if they exist. If the entry is modified (in the editor), the repeat + // properties will be lost. + if(iEventViewData->IsRepeating()) + { + AddRepeatFieldL(); + } + + } + break; + + case CCalEntry::ETodo: + { + // extra empty line between primary and secondary information + AddEmptyLineL(); + + // Due date + TTime dueDate = iEventViewData->EventDateTime(); + AddDateFieldL(R_QTN_CALE_EVENT_VIEW_DUE_DATE, dueDate); + // Adds empty line + AddEmptyLineL(); + + //Adds calendar info field to the viewer + //AddCalendarInfoFieldL(); + + // Adds empty line + //AddEmptyLineL(); + + // Alarm is only shown if the todo is not complete. + //if (Handler().Entry().StatusL() != CCalEntry::ETodoCompleted) + if (iEntry->StatusL() != CCalEntry::ETodoCompleted) + { + AddAlarmDateTimeFieldL(); + } + + // Show completion date if complete + else + { + AddDateFieldL(R_QTN_CALE_EVENT_VIEW_COMPLETED, iEntry->CompletedTimeL().TimeLocalL()); + } + + // Priority + AddPriorityFieldL(); + + // Repeat rules. Supporting repeating todos sounds like asking for trouble to me. + if (iEventViewData->IsRepeating()) + { + AddRepeatFieldL(); + } + + iTitleTextId = R_CALEN_EVENT_VIEW_TODO_TITLE; + } + break; + + default: + __ASSERT_DEBUG(EFalse, User::Invariant()); + break; + } + if(IsEventHasMapLocationL()) + { + // Update iNumOfLinesBeforeLocField + CalcNumOfLinesBeforeLocation(); + + // Add map icon to the icon drawer + iconDrawer->AddIconL( MCalenServices::ECalenMapIcon ); + + // Set the icon sizes + iconDrawer->SetIconSizesFromLayout(iNumOfLinesBeforeLocField); + } + SetIconsL(iconDrawer); + + // Add Description + AddDescriptionFieldL(); + + // Add attachment field + // TODO: Uncomment this when enabling attachment support + + if(iEventViewData->AttachmentCount()) + { + AddAttachmentFieldL(); + } + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::SetLayoutFromLookAndFeelL +// Set the layout data +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::SetLayoutFromLookAndFeelL() + { + TRACE_ENTRY_POINT; + + iParaFormat->Reset(); + iParaFormatMask.ClearAll(); + iCharFormatMask.ClearAll(); + + iParaFormatMask.SetAttrib(EAttLeftMargin); + iParaFormatMask.SetAttrib(EAttRightMargin); + + // Get the main pane + TSize main_pane_size; + AknLayoutUtils::LayoutMetricsSize (AknLayoutUtils::EMainPane, main_pane_size); + TRect main_pane(main_pane_size); + + // Get main_cale_event_viewer_pane with main_pane as parent + TAknLayoutRect main_cale_event_viewer_pane; + main_cale_event_viewer_pane.LayoutRect(main_pane, AknLayoutScalable_Apps::main_cale_event_viewer_pane().LayoutLine() ); + + // Get listscroll_cale_event_viewer_pane with main_cale_event_viewer_pane as parent + TAknLayoutRect listscroll_cale_event_viewer_pane; + listscroll_cale_event_viewer_pane.LayoutRect(main_cale_event_viewer_pane.Rect(), AknLayoutScalable_Apps::listscroll_cale_event_viewer_pane().LayoutLine() ); + + // Get list_cale_ev2_pane with listscroll_cale_event_viewer_pane as parent + TAknLayoutRect list_cale_ev2_pane; + list_cale_ev2_pane.LayoutRect(listscroll_cale_event_viewer_pane.Rect(), AknLayoutScalable_Apps::list_cale_ev2_pane().LayoutLine() ); + + // Get the main pane + TAknLayoutRect main_cale_day_pane; + main_cale_day_pane.LayoutRect( Rect(), + AknLayoutScalable_Apps::main_cale_day_pane().LayoutLine() ); + + TAknLayoutRect listscroll_cale_day_pane; + listscroll_cale_day_pane.LayoutRect( main_cale_day_pane.Rect(), + AknLayoutScalable_Apps::listscroll_cale_day_pane( 0 ).LayoutLine() ); + + iLabel->SetRect(GetLabelRectL()); + + // Listbox layout + TAknLayoutRect list_cale_pane; + list_cale_pane.LayoutRect( main_cale_day_pane.Rect(), AknLayoutScalable_Apps::list_cale_pane( 3 ).LayoutLine() ); + + // Adjust the rect to show the map icon if necessary + TRect temp_list_cale_ev2_pane = list_cale_pane.Rect(); + + + iTextEditor->SetRect(temp_list_cale_ev2_pane); + + // Scrollbar layout + AknLayoutUtils::LayoutVerticalScrollBar( iTextEditor->ScrollBarFrame(), + listscroll_cale_day_pane.Rect(), + AknLayoutScalable_Apps::scroll_pane_cp09( 3 ).LayoutLine() ); + + // Get field_cale_ev2_pane with list_cale_ev2_pane as parent + TAknLayoutRect field_cale_ev2_pane; + field_cale_ev2_pane.LayoutRect(list_cale_ev2_pane.Rect(), AknLayoutScalable_Apps::field_cale_ev2_pane(0).LayoutLine() ); + + // Get field_cale_ev2_pane_t1 + TAknTextLineLayout field_cale_ev2_pane_t1 = AknLayoutScalable_Apps::field_cale_ev2_pane_t1(0).LayoutLine(); + + // Get heading layout properties from field_cale_ev2_pane_t1 with list_cale_ev2_pane as parent + TAknLayoutText headingTextLayout; + headingTextLayout.LayoutText(list_cale_ev2_pane.Rect(), field_cale_ev2_pane_t1); + + // Set heading indenting and font + if (!AknLayoutUtils::LayoutMirrored()) + { + // Normal L-R layout. + // Heading indent is heading text layout rect left x pos - + // text editor rect left xpos. The heading text layout rect gives us an absolute + // screen position, but the value that we need should be relative to + // the text editor itself + TInt headingIndentPixels = headingTextLayout.TextRect().iTl.iX - + list_cale_ev2_pane.Rect().iTl.iX; + iHeadingIndent = PixelsToTwips(headingIndentPixels); + } + else + { + // Mirrored, R-L layout. + // Heading indent is the text editor rect right x pos - + // the heading text layout rect right x pos + TInt headingIndentPixels = list_cale_ev2_pane.Rect().iBr.iX - + headingTextLayout.TextRect().iBr.iX; + iHeadingIndent = PixelsToTwips(headingIndentPixels); + } + + iHeadingFontSpec = headingTextLayout.Font()->FontSpecInTwips(); + iHeadingFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); + iEmptyLineHeight = PixelsToTwips(headingTextLayout.TextRect().Height() / 2); + iHeadingFont = headingTextLayout.Font(); + + // Get field_cale_ev2_pane_t2 + TAknTextLineLayout field_cale_ev2_pane_t2 = AknLayoutScalable_Apps::field_cale_ev2_pane_t2(1).LayoutLine(); + + // Get body layout properties from field_cale_ev2_pane_t2 // with field_ev_content_pane as parent + TAknLayoutText bodyTextLayout; + bodyTextLayout.LayoutText(list_cale_ev2_pane.Rect(), field_cale_ev2_pane_t2); + iMaxWidth = bodyTextLayout.TextRect().Width(); + + // Set body indenting and font + if (!AknLayoutUtils::LayoutMirrored()) + { + // Normal L-R layout. + // Body text indent is body text layout rect left x pos - + // text editor rect left xpos. The heading text layout rect gives us an absolute + // screen position, but the value that we need should be relative to + // the text editor itself + TInt bodyIndentPixels = bodyTextLayout.TextRect().iTl.iX - + list_cale_ev2_pane.Rect().iTl.iX; + iBodyIndent = PixelsToTwips(bodyIndentPixels); + } + else + { + // Mirrored, R-L layout. + // Body indent is the text editor rect right x pos - + // the body text layout rect right x pos + TInt bodyIndentPixels = list_cale_ev2_pane.Rect().iBr.iX - + bodyTextLayout.TextRect().iBr.iX; + iBodyIndent = PixelsToTwips(bodyIndentPixels); + } + + iBodyFontSpec = bodyTextLayout.Font()->FontSpecInTwips(); + iBodyFont = bodyTextLayout.Font(); // Used for TryToFitL + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::SetupFontL +// Set the font colour, and set default para/char format layers to the +// rich text editor. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::SetupFontL() + { + TRACE_ENTRY_POINT; + + // Set desired character formatting attributes. Gets sensible text colour based on theme. + TRgb textColourFromSkin(255,0,0); // If you see bright red text, the skins api is broken! + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); // Does not transfer ownership. + AknsUtils::GetCachedColor(skin, textColourFromSkin, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6); + + TCharFormat charFormat; + TCharFormatMask charFormatMask; + // Set the text colour we found. + charFormat.iFontPresentation.iTextColor = TLogicalRgb(textColourFromSkin); + charFormatMask.SetAttrib(EAttColor); + + // Set up our paragraph formatting attributes. + CParaFormat* paraFormat = CParaFormat::NewLC(); + TParaFormatMask paraFormatMask; + + // Set up the default font so it's the same as the body text used. + // This means we can do without setting the para/char format layers + // when adding body text. + paraFormat->iLeftMarginInTwips = iBodyIndent; + paraFormatMask.SetAttrib(EAttLeftMargin); + paraFormatMask.SetAttrib(EAttRightMargin); + + charFormat.iFontSpec = iBodyFontSpec; + charFormatMask.SetAttrib(EAttFontHeight); + charFormatMask.SetAttrib(EAttFontTypeface); + charFormatMask.SetAttrib(EAttFontStrokeWeight); + + // Create some format layers based on the attributes we specified above. + // The underlying Edwin will take ownership of the format objects created below, so don't need to delete. + CParaFormatLayer* paraFormatLayer = CParaFormatLayer::NewL(paraFormat, paraFormatMask); + CleanupStack::PushL(paraFormatLayer); + CCharFormatLayer* charFormatLayer = CCharFormatLayer::NewL(charFormat, charFormatMask); + CleanupStack::Pop(paraFormatLayer); + + // Set the format layers. + iTextEditor->SetParaFormatLayer(paraFormatLayer); + iTextEditor->SetCharFormatLayer(charFormatLayer); + + // And get rid of paraFormat. All other allocations are owned by the CEikRichTextEditor. + CleanupStack::PopAndDestroy(paraFormat); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenViewerBase::PopulateIconDrawerL +// Ask IconDrawer to prepare icons that are going to be drawn +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::PopulateIconDrawerL(CCalenIconDrawer& aIconDrawer) + { + TRACE_ENTRY_POINT; + + // Alarm icon? + if( iEventViewData->IsAlarmActivated() ) + { + // For todos, only add the alarm icon if it's not completed. + if ( iEventViewData->EntryType() == CCalEntry::ETodo ) + { + // if(iEditedCalEntry.StatusL() != CCalEntry::ETodoCompleted) + if(iEntry->StatusL() != CCalEntry::ETodoCompleted) + { + aIconDrawer.AddIconL( MCalenServices::ECalenAlarmIcon ); + } + } + else + { + aIconDrawer.AddIconL( MCalenServices::ECalenAlarmIcon ); + } + } + + // Repeat / exception icon? + if (iEventViewData->IsRepeating()) + { + aIconDrawer.AddIconL( MCalenServices::ECalenRepeatIcon ); + } + else + { + if (iEntry->RecurrenceIdL().TimeUtcL() != Time::NullTTime()) + { + aIconDrawer.AddIconL( MCalenServices::ECalenRepeatExceptionIcon ); + } + } + + // Todo priority icon? + if (iEventViewData->EntryType() == CCalEntry::ETodo) + { + CCalenEntryUtil::TTodoPriority priority = iEventViewData->Priority(); + if (priority == CCalenEntryUtil::ETodoPriorityHigh) + { + aIconDrawer.AddIconL( MCalenServices::ECalenNotePriorityHigh ); + } + else if (priority == CCalenEntryUtil::ETodoPriorityLow) + { + aIconDrawer.AddIconL( MCalenServices::ECalenNotePriorityLow ); + } + else + { + // nothing + } + } + // Set the icon sizes + aIconDrawer.SetIconSizesFromLayout(iNumOfLinesBeforeLocField); + + // Get the icon drawer width + iIconDrawerWidthInPixels = aIconDrawer.WidthInPixels(); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::SetFormatAndAddHeadingL +// +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::SetFormatAndAddHeadingL(const TDesC& aHeading) + { + TRACE_ENTRY_POINT; + + iCharFormatMask.ClearAll(); + iParaFormat->iLeftMarginInTwips = iHeadingIndent; + iCharFormat.iFontSpec = iHeadingFontSpec; + iCharFormatMask.SetAttrib( EAttFontHeight ); + iCharFormatMask.SetAttrib( EAttFontTypeface ); + iCharFormatMask.SetAttrib( EAttFontStrokeWeight ); + AddFormattedTextL( aHeading ); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::SetFormatAndAddBodyL +// +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::SetFormatAndAddBodyL(const TDesC& aBody) + { + TRACE_ENTRY_POINT; + + iCharFormatMask.ClearAll(); + iParaFormat->iLeftMarginInTwips = iBodyIndent; + iCharFormat.iFontSpec = iBodyFontSpec; + iCharFormatMask.SetAttrib( EAttFontHeight ); + iCharFormatMask.SetAttrib( EAttFontTypeface ); + iCharFormatMask.SetAttrib( EAttFontStrokeWeight ); + AddFormattedTextL( aBody ); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddEmptyLineL +// +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddEmptyLineL() + { + TRACE_ENTRY_POINT; + + CParaFormat* paraFormat = CParaFormat::NewLC(); + TParaFormatMask paraFormatMask; + paraFormat->iLineSpacingControl = CParaFormat::ELineSpacingExactlyInTwips; + paraFormatMask.SetAttrib(EAttLineSpacingControl); + paraFormat->iLineSpacingInTwips = iEmptyLineHeight; + paraFormatMask.SetAttrib(EAttLineSpacing); + paraFormatMask.SetAttrib(EAttFontHighlightColor); + + CRichText* richText = iTextEditor->RichText(); + TInt startPos = richText->DocumentLength(); + richText->InsertL(richText->DocumentLength(), CEditableText::EParagraphDelimiter); + TInt endPos = richText->DocumentLength(); + + richText->ApplyParaFormatL(paraFormat, paraFormatMask, startPos, endPos - startPos); + + CleanupStack::PopAndDestroy(paraFormat); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddFormattedTextL +// Add a string to the view. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddFormattedTextL(const TDesC& aText) + { + TRACE_ENTRY_POINT; + + CRichText* richText = iTextEditor->RichText(); + TInt startPos = richText->DocumentLength(); + HBufC* text = HBufC::NewLC( aText.Length() + 10); + TPtr target = text->Des(); + if(AknLayoutUtils::LayoutMirrored()) + { + target.Append(KArabicSummaryMarker); + } + else + { + target.Append(KWesternSummaryMarker); + } + target.Append(aText); + + richText->InsertL(startPos, target); + richText->InsertL(richText->DocumentLength(), CEditableText::EParagraphDelimiter); + TInt endPos = richText->DocumentLength(); + + richText->ApplyCharFormatL(iCharFormat, iCharFormatMask, startPos, endPos - startPos); + ++startPos; // Without this the previous paragraph is formatted as well, ie no indent + richText->ApplyParaFormatL(iParaFormat, iParaFormatMask, startPos, endPos - startPos); + CleanupStack::PopAndDestroy(text); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddDescriptionFieldL +// Add a description field to the view. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddDescriptionFieldL() + { + TRACE_ENTRY_POINT; + //Add description + if (iEventViewData->Description() != KNullDesC) + { + AddTextFieldL(R_QTN_CALE_EVENT_VIEW_DESC, iEventViewData->Description()); + // Add in a paragraph delimeter character + // Without this, long descriptions get cut off half way down the last line. + CRichText* richText = iTextEditor->RichText(); + richText->InsertL(richText->DocumentLength(), CEditableText::EParagraphDelimiter); + } + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddSinceFieldL +// Add a since field to the view. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddSinceFieldL() + { + TRACE_ENTRY_POINT; + + // Add since field, if the since year is different from the year of the instance opened. + // TInt instanceYear = Handler().Original().StartDateTime().DateTime().Year(); + TInt instanceYear = iEventViewData->StartDateTime().DateTime().Year(); + TTime seriesTime = ParentEntryL().StartTimeL().TimeLocalL(); + TInt seriesYear = seriesTime.DateTime().Year(); + + if( seriesYear != instanceYear ) + { + TBuf<32> formattedYear; + seriesTime.FormatL(formattedYear, KYearFormatString); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedYear); + AddTextFieldL(R_QTN_CALE_EVENT_VIEW_SINCE, formattedYear); + } + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddTextFieldL +// Add a text field to the view. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddTextFieldL(TInt aHeadingResource, TInt aBodyResource) + { + TRACE_ENTRY_POINT; + HBufC* textHeading = StringLoader::LoadLC(aHeadingResource); + SetFormatAndAddHeadingL(*textHeading); + CleanupStack::PopAndDestroy(textHeading); + + HBufC* textBody = StringLoader::LoadLC(aBodyResource); + SetFormatAndAddBodyL(*textBody); + CleanupStack::PopAndDestroy(textBody); + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddTextFieldL +// Add a text field to the view. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddTextFieldL(TInt aHeadingResource, const TDesC& aBody) + { + TRACE_ENTRY_POINT; + + HBufC* textHeading = StringLoader::LoadLC(aHeadingResource); + SetFormatAndAddHeadingL(*textHeading); + CleanupStack::PopAndDestroy(textHeading); + + // If the value is empty, put a space in the output so we don't compress the empty line. + if( CalenAgendaUtils::IsEmptyText(aBody) ) + { + SetFormatAndAddBodyL(KSpace); + } + else + { + SetFormatAndAddBodyL(aBody); + } + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddSubjectFieldL +// Adds the entry's subject to the view. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddSubjectFieldL() + { + TRACE_ENTRY_POINT; + + iParaFormat->iRightMarginInTwips = PixelsToTwips(iIconDrawerWidthInPixels); + if (iEventViewData->Summary() != KNullDesC) + { + SetFormatAndAddHeadingL(iEventViewData->Summary()); + } + else + { + HBufC* untitled = StringLoader::LoadLC(R_QTN_CALE_EVENT_VIEW_EMPTY_SUBJECT); + SetFormatAndAddHeadingL(*untitled); + CleanupStack::PopAndDestroy(untitled); + } + iParaFormat->iRightMarginInTwips = KDefaultRightMargin; + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddLocationFieldL +// Adds the entry's location to the view. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddLocationFieldL() + { + TRACE_ENTRY_POINT; + + + + iParaFormat->iRightMarginInTwips = PixelsToTwips(20); + if (iEventViewData->Location() != KNullDesC ) + { + SetFormatAndAddBodyL(iEventViewData->Location()); + } + iParaFormat->iRightMarginInTwips = KDefaultRightMargin; + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddPriorityFieldL +// Reads the priority from the entry and adds a field to the form accordingly. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddPriorityFieldL() + { + TRACE_ENTRY_POINT; + + CCalenEntryUtil::TTodoPriority priority = iEventViewData->Priority(); + + // Don't add the priority field if it's normal priority. + if( priority != CCalenEntryUtil::ETodoPriorityNormal ) + { + CDesCArrayFlat* priorities = ControlEnv()->ReadDesCArrayResourceL(R_CALE_EVENT_VIEW_TODO_PRIORITY); + CleanupStack::PushL(priorities); + const TDesC& priorityText = (*priorities)[CalendarPriorityToFormPriority(priority)]; + AddTextFieldL(R_QTN_CALE_EVENT_VIEW_PRIO, priorityText); + CleanupStack::PopAndDestroy(); // priorities + } + TRACE_EXIT_POINT; + } + + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddTimeFieldL +// Add a time field to the form. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddTimeFieldL(TInt aLabelResource, const TTime& aTime) + { + TRACE_ENTRY_POINT; + + TBuf<32> formattedTime; + aTime.FormatL(formattedTime, *iTimeFormat); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedTime); + AddTextFieldL(aLabelResource, formattedTime); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddDateFieldL +// Add a date field to the form. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddDateFieldL(const TTime& aDate) + { + TRACE_ENTRY_POINT; + + TBuf<32> formattedDate; + aDate.FormatL(formattedDate, *iDateFormat); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedDate); + SetFormatAndAddBodyL(formattedDate); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddDateFieldL +// Add a date field to the form. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddDateFieldL(TInt aHeadingResource, const TTime& aDate) + { + TRACE_ENTRY_POINT; + + HBufC* textHeading = StringLoader::LoadLC(aHeadingResource); + SetFormatAndAddHeadingL(*textHeading); + CleanupStack::PopAndDestroy(textHeading); + AddDateFieldL(aDate); + + TRACE_EXIT_POINT; + } +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddDateFieldL +// Add a field to the form in the format "DATE - DATE". +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddDateDateFieldL(const TTime& aStartDate, const TTime& aEndDate) + { + TRACE_ENTRY_POINT; + + CDesCArrayFlat* strings = new CDesCArrayFlat( 2 ); + CleanupStack::PushL( strings ); + + TBuf firstDate; + aStartDate.FormatL( firstDate, *iDateFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(firstDate); + strings->AppendL( firstDate ); + + TBuf secondDate; + aEndDate.FormatL( secondDate, *iDateFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(secondDate); + strings->AppendL( secondDate ); + + HBufC* stringholder = StringLoader::LoadL( R_QTN_CALE_EVENT_VIEW_VALID_LIMITED, *strings ); + CleanupStack::PopAndDestroy( strings ); + CleanupStack::PushL( stringholder ); + + SetFormatAndAddBodyL(*stringholder); + CleanupStack::PopAndDestroy(stringholder); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddAlarmDateAndTimeFieldL +// Add a date and time field to the form, in the ordering according to +// localisation (date followed by the time). +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddAlarmDateAndTimeFieldL( const TTime& aTime ) + { + TRACE_ENTRY_POINT; + + CDesCArrayFlat* strings = new CDesCArrayFlat( 2 ); + CleanupStack::PushL( strings ); + + TBuf formattedTime; + aTime.FormatL( formattedTime, *iTimeFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedTime); + strings->AppendL( formattedTime ); + + TBuf formattedDate; + aTime.FormatL( formattedDate, *iDateFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedDate); + strings->AppendL( formattedDate ); + + HBufC* stringholder = StringLoader::LoadL( R_QTN_CALE_EVENT_VIEW_ALARM_TIME, *strings ); + CleanupStack::PopAndDestroy( strings ); + CleanupStack::PushL( stringholder ); + + AddTextFieldL( R_QTN_CALE_EVENT_VIEW_ALARM, *stringholder ); + CleanupStack::PopAndDestroy( stringholder ); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddAlarmDateTimeFieldL +// Reads the alarm from the entry and add a field containing its date-time. +// If the alarm is on the same day as the entry, only the time is shown. +// If no alarm is present, the field is not shown +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddAlarmDateTimeFieldL() + { + TRACE_ENTRY_POINT; + if( iEventViewData->IsAlarmActivated() ) + { + TTime alarmTime = iEventViewData->AlarmDateTime(); + alarmTime = CalenDateUtils::LimitToValidTime( alarmTime ); + + // If alarm is on the same day as the entry, AND the meeting only lasts one day, + // just show the alarm time and not the date. + if( CalenDateUtils::OnSameDay( alarmTime, iEventViewData->StartDateTime() ) && + CalenDateUtils::OnSameDay( iEventViewData->StartDateTime(), iEventViewData->EndDateTime() ) ) + { + // On same day, only show time. + AddTimeFieldL( R_QTN_CALE_EVENT_VIEW_ALARM, alarmTime ); + } + else + { + // Different days, show both date and time. + AddAlarmDateAndTimeFieldL( alarmTime ); + } + } + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::GetMinAndMaxTimesL +// Find the maximum and minimum times from the given array. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::GetMinAndMaxTimesL( RArray& aTimes, + TCalTime& aMinTime, + TCalTime& aMaxTime ) + { + TRACE_ENTRY_POINT; + + TInt minIndex=0; + TInt maxIndex=0; + + for( TInt i=1; i aTimes[maxIndex].TimeUtcL() ) + { + maxIndex = i; + } + else + { + if( aTimes[i].TimeUtcL() < aTimes[minIndex].TimeUtcL() ) + { + minIndex = i; + } + } + } + + aMinTime = aTimes[minIndex]; + aMaxTime = aTimes[maxIndex]; + + TRACE_EXIT_POINT; + } +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::RemoveDuplicateTimesL +// If there is more than one time at the same time, leave only one in the array. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::RemoveDuplicateTimesL( RArray& aTimes ) + { + TRACE_ENTRY_POINT; + + for( TInt i=0; ii; --j ) + { + if( aTimes[i].TimeUtcL() == aTimes[j].TimeUtcL() ) + { + aTimes.Remove( j ); + } + } + } + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::RemoveExcludedTimesL +// From the given array of start dates, remove any which match up with an +// exception date and also have no child associated with them. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::RemoveExcludedTimesL( RArray& aStartDates, + RArray& aExDates, + RPointerArray& aChildEntries ) + { + TRACE_ENTRY_POINT; + + for( TInt i=0; i=0; --j ) + { + if( aStartDates[j].TimeUtcL() == aExDates[i].TimeUtcL() ) + { + TBool hasChild = EFalse; + for( TInt k=0; kRecurrenceIdL().TimeUtcL() == aStartDates[j].TimeUtcL() ) + { + hasChild = ETrue; + break; + } + } + + if( !hasChild ) + { + aStartDates.Remove( j ); + break; + } + } + } + } + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------- +// CCalenEventViewContainer::CalendaryPriorityToFormPriority +// Convert replication to confidentiality +// (other items were commented in a header). +// ---------------------------------------------------- +// +TInt CCalenEventViewContainer::CalendarPriorityToFormPriority(CCalenEntryUtil::TTodoPriority aCalPriority) + { + TRACE_ENTRY_POINT; + // Calendar priority is in same order as resource, starting from one number lower. + TRACE_EXIT_POINT; + return aCalPriority-1; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::TryToFitL +// Returns ETrue if the given string fits into aMaxWidth, +// using the font aFont - EFalse otherwise +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCalenEventViewContainer::TryToFitL( const TDesC& aStr, TInt aMaxWidth, const CFont& aFont ) + { + TRACE_ENTRY_POINT; + + TInt width = aFont.TextWidthInPixels(aStr); + // We add one because it seems the edwin wrapping doesn't quite agree with CFont's width. + ++width; + + TRACE_EXIT_POINT; + return width < aMaxWidth; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::PixelsToTwips +// Convert pixels to twips +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CCalenEventViewContainer::PixelsToTwips(TInt aPixels) + { + TRACE_ENTRY_POINT; + + CWindowGc& windowGc = ControlEnv()->SystemGc(); + TInt twips = windowGc.Device()->HorizontalPixelsToTwips(aPixels); + + TRACE_EXIT_POINT; + return twips; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::GetSeriesRepeatInformationL +// Attempts to calculate the start and end dates of the series by looking at the +// given entry's RDates and RRule. If these dates have successfully been +// calculated, the function returns ETrue, or EFalse otherwise. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCalenEventViewContainer::GetSeriesRepeatInformationL( CCalEntry& aEntry, + TCalenRepeatIndex& aRepeatIndex, + TTime& aSeriesStart, + TTime& aSeriesEnd ) + { + TRACE_ENTRY_POINT; + + TBool success; + + RArray rdates; + CleanupClosePushL( rdates ); + + aEntry.GetRDatesL(rdates); + + if( rdates.Count() ) + { + // Calculate the start and end dates from the RDates. + + // We need to expand the RDates. This involves getting all the instance start dates, + // then removing any start date with an exdate but no modifying child for that instance. + // Include the entry start date in this, as that counts as part of the series. + rdates.AppendL( aEntry.StartTimeL() ); + + RemoveDuplicateTimesL( rdates ); + + RArray exdates; + CleanupClosePushL( exdates ); + aEntry.GetExceptionDatesL( exdates ); + if( exdates.Count() ) + { + RemoveExcludedTimesL( rdates, exdates, AllInstancesL() ); + } + CleanupStack::PopAndDestroy( &exdates ); + + TCalRRule rrule; + if( iEntry->GetRRuleL(rrule) ) + { + // Hopefully no UI would create an entry with an RRule as well as RDates. + // Although the spec says it's possible, Calendar certainly can't. + // We have a vague go at including the RRule in the min/max date but + // don't bother removing exdates from it as we would then need to expand + // every instance of the RRule. + rdates.AppendL( rrule.DtStart() ); + rdates.AppendL( rrule.Until() ); + RemoveDuplicateTimesL( rdates ); + } + + // The true instance dates should be in the 'rdates' array. Now we just need + // the minimum and maximum times from here. + TCalTime min, max; + GetMinAndMaxTimesL( rdates, min, max ); + aSeriesStart = min.TimeLocalL(); + aSeriesEnd = max.TimeLocalL(); + + // Set the repeat type to "Other" for rdates. + aRepeatIndex = ERepeatOther; + success = ETrue; + } + else + { + TCalRRule rrule; + if( aEntry.GetRRuleL( rrule ) ) + { + // This 'switch' differs slightly from CalenNoteDataUtil::RepeatIndex in + // that we are a bit more generous in awarding repeat types instead of + // falling back to 'other' repeat type. + aRepeatIndex = ERepeatOther; + switch( rrule.Type() ) + { + case TCalRRule::EDaily: + { + if( rrule.Interval() == 1 ) + { + aRepeatIndex = ERepeatDaily; + } + else if( rrule.Interval() == 7 ) + { + aRepeatIndex = ERepeatWeekly; + } + else if( rrule.Interval() == 14 ) + { + aRepeatIndex = ERepeatBiWeekly; + } + else + { + // nothing + } + } + break; + + case TCalRRule::EWeekly: + { + TInt repeatInterval( rrule.Interval() ); + TBool status; + status = CalenNoteDataUtil::IsWorkdaysRepeatingL( rrule ); + if(status) + { + aRepeatIndex = ERepeatWorkdays ; + } + else + { + switch( repeatInterval ) + { + case 1: aRepeatIndex = ERepeatWeekly; + break; + case 2: aRepeatIndex = ERepeatBiWeekly; + break; + default:break; + } + } + } + break; + + case TCalRRule::EMonthly: + { + if( rrule.Interval() == 1 ) + { + aRepeatIndex = ERepeatMonthly; + } + } + break; + + case TCalRRule::EYearly: + { + if( rrule.Interval() == 1 ) + { + aRepeatIndex = ERepeatYearly; + } + } + break; + default: + break; + } + + aSeriesStart = rrule.DtStart().TimeLocalL(); + aSeriesEnd = rrule.Until().TimeLocalL(); + success = ETrue; + } + else + { + // No repeat information. + success = EFalse; + } + } + + CleanupStack::PopAndDestroy( &rdates ); + + return success; + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddRepeatFieldL +// Add repeat text field to the +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddRepeatFieldL() + { + TRACE_ENTRY_POINT; + // Get the repeat rule from the entry. If this is a child entry, + // find the parent and get the repeat rule from that. + TCalRRule rrule; + TCalenRepeatIndex repeatIndex; + // 'start' is the start time of the series, not the start time of the instance we are viewing + TTime start; + TTime until; + + if( !GetSeriesRepeatInformationL( *iEntry, repeatIndex, start, until ) ) + { + // An entry with no RDates or RRule but a non-null recurrence id. + // This entry is a child. We have to get the parent to see the repeat information. + // We assert here - a parent really should have some form of repeat information. + __ASSERT_ALWAYS( GetSeriesRepeatInformationL( ParentEntryL(), repeatIndex, start, until ), + User::Invariant() ); + } + + // Set repIndex to be the resource used for the heading. + // This will be "Repeats daily", "Repeats weekly" etc. + TInt repIndex = -1; + + switch(repeatIndex) + { + case ERepeatDaily: + repIndex = R_QTN_CALE_EVENT_VIEW_REPEAT_DAILY; + break; + case ERepeatWeekly: + repIndex = R_QTN_CALE_EVENT_VIEW_REPEAT_WEEKLY; + break; + case ERepeatBiWeekly: + repIndex = R_QTN_CALE_EVENT_VIEW_REPEAT_FORTNIGHTLY; + break; + case ERepeatMonthly: + repIndex = R_QTN_CALE_EVENT_VIEW_REPEAT_MONTHLY; + break; + case ERepeatYearly: + repIndex = R_QTN_CALE_EVENT_VIEW_REPEAT_YEARLY; + break; + case ERepeatWorkdays: + repIndex = R_QTN_CALE_EVENT_VIEW_REPEAT_WORKDAYS; + break; + case ERepeatOther: + repIndex = R_QTN_CALE_EVENT_VIEW_REPEAT_OTHER; + break; + default: + ASSERT(EFalse); + break; + } + + TBuf<64> dateString; + + // Infinite repeat if repeat until is on or after the max time, or if repeat until is null. + TBool finiteRepeat = until < CalenDateUtils::BeginningOfDay( CalenDateUtils::MaxTime() ) + && until != Time::NullTTime(); + + if( finiteRepeat ) + { + // Finite repeat, string (e.g.) "17/01/2006 - 27/01/2006" + CDesCArrayFlat* strings = new CDesCArrayFlat( 2 ); + CleanupStack::PushL( strings ); + + TBuf formattedTime; + start.FormatL( formattedTime, *iDateFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedTime); + strings->AppendL( formattedTime ); + + TBuf formattedDate; + until.FormatL( formattedDate, *iDateFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedDate); + strings->AppendL( formattedDate ); + + HBufC* stringholder = StringLoader::LoadL( R_QTN_CALE_EVENT_VIEW_VALID_LIMITED, *strings ); + CleanupStack::PopAndDestroy( strings ); + CleanupStack::PushL( stringholder ); + + AddTextFieldL( repIndex, *stringholder ); + CleanupStack::PopAndDestroy( stringholder ); + } + else + { + // Repeats forever, string (e.g.) "From 17/01/2006" + CDesCArrayFlat* strings = new CDesCArrayFlat( 1 ); + CleanupStack::PushL( strings ); + + TBuf formattedTime; + start.FormatL( formattedTime, *iDateFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedTime); + strings->AppendL( formattedTime ); + + HBufC* stringholder = StringLoader::LoadL( R_QTN_CALE_EVENT_VIEW_VALID_FOREVER, *strings ); + CleanupStack::PopAndDestroy( strings ); + CleanupStack::PushL( stringholder ); + + AddTextFieldL( repIndex, *stringholder ); + CleanupStack::PopAndDestroy( stringholder ); + } + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddTimeFieldL +// Add entry time field text to the +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddTimeFieldL() + { + TRACE_ENTRY_POINT; + + // If the start time is on the same day as the end time, just show the date. + // Otherwise, show "start date - end date". + TTime startTime = iEventViewData->StartDateTime(); + TTime endTime = iEventViewData->EndDateTime(); + iTimeFieldLines = 1; // Increment the value to be considered while drawing the map icon + TBuf<64> concatString; + + if( CalenDateUtils::OnSameDay(startTime, endTime) ) + { + // String looks like (e.g.) "14:00 - 16:00 17/01/2006" + CDesCArrayFlat* strings = new CDesCArrayFlat( 3 ); + CleanupStack::PushL( strings ); + + TBuf formattedStartTime; + startTime.FormatL( formattedStartTime, *iTimeFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedStartTime); + strings->AppendL( formattedStartTime ); + + TBuf formattedEndTime; + endTime.FormatL( formattedEndTime, *iTimeFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedEndTime); + strings->AppendL( formattedEndTime ); + + TBuf formattedStartDate; + startTime.FormatL( formattedStartDate, *iDateFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedStartDate); + strings->AppendL( formattedStartDate ); + + HBufC* stringholder = StringLoader::LoadLC( R_QTN_CALE_EVENT_VIEW_TIME_DAY, *strings ); + + TBool fits = TryToFitL(*stringholder, iMaxWidth, *iBodyFont); + if (fits) + { + SetFormatAndAddBodyL(*stringholder); + } + else + { + iTimeFieldLines++; // Increment the value to be considered while drawing the map icon + HBufC* wrappedStringholder = StringLoader::LoadLC( R_QTN_CALE_EVENT_VIEW_TIME_DAY_WRAPPED, *strings ); + SetFormatAndAddBodyL(*wrappedStringholder); + CleanupStack::PopAndDestroy(wrappedStringholder); + } + + CleanupStack::PopAndDestroy( stringholder ); + CleanupStack::PopAndDestroy( strings ); + } + else + { + // String looks like (e.g.) "14:00 16/01/2006 - 16:00 19/01/2006" + CDesCArrayFlat* strings = new CDesCArrayFlat( 3 ); + CleanupStack::PushL( strings ); + + TBuf formattedStartTime; + startTime.FormatL( formattedStartTime, *iTimeFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedStartTime); + strings->AppendL( formattedStartTime ); + + TBuf formattedStartDate; + startTime.FormatL( formattedStartDate, *iDateFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedStartDate); + strings->AppendL( formattedStartDate ); + + TBuf formattedEndTime; + endTime.FormatL( formattedEndTime, *iTimeFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedEndTime); + strings->AppendL( formattedEndTime ); + + TBuf formattedEndDate; + endTime.FormatL( formattedEndDate, *iDateFormat ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion(formattedEndDate); + strings->AppendL( formattedEndDate ); + + HBufC* stringholder = StringLoader::LoadLC( R_QTN_CALE_EVENT_VIEW_TIME_DAYS, *strings ); + + TBool fits = TryToFitL(*stringholder, iMaxWidth, *iBodyFont); + if (fits) + { + SetFormatAndAddBodyL(*stringholder); + } + else + { + iTimeFieldLines++; + HBufC* wrappedStringholder = StringLoader::LoadLC( R_QTN_CALE_EVENT_VIEW_TIME_DAYS_WRAPPED, *strings ); + SetFormatAndAddBodyL(*wrappedStringholder); + CleanupStack::PopAndDestroy(wrappedStringholder); + } + + CleanupStack::PopAndDestroy( stringholder ); + CleanupStack::PopAndDestroy( strings ); + } + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::MopSupplyObject +// Pass the skin information +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TTypeUid::Ptr CCalenEventViewContainer::MopSupplyObject( TTypeUid aId ) + { + return MAknsControlContext::SupplyMopObject( aId, iBgContext ); + } + + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::BuildSearchBufferL +// Generate the text string to use for text searches +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::BuildSearchBufferL() + { + TRACE_ENTRY_POINT; + + // Get the full text from the form to use for search API. + TInt textLength = iTextEditor->RichText()->DocumentLength(); + + // Delete any existing search buffer + if (iSearchBuf) + { + delete iSearchBuf; + iSearchBuf = NULL; + } + + // Text searched is currently summary , location and description + iSearchBuf = HBufC::NewL(textLength); + TPtr searchPtr = iSearchBuf->Des(); + GetTextFieldsFromFormL(searchPtr); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::GetTextFieldsFromFormL +// Gets the text fields from the form into a descriptor for +// the find api to use. +// Currently uses subject, location and description only +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::GetTextFieldsFromFormL(TDes& aDesc) + { + TRACE_ENTRY_POINT; + + aDesc.Append(iEventViewData->Summary()); + aDesc.Append(_L(" \r\n")); + aDesc.Append(iEventViewData->Location()); + aDesc.Append(_L(" \r\n")); + aDesc.Append(iEventViewData->Description()); + aDesc.Append(_L(" \r\n")); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::GetTitleTextId +// Gets the title text resource +// ----------------------------------------------------------------------------- +// +TInt CCalenEventViewContainer::GetTitleTextId() + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + return iTitleTextId; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::ParentEntryL +// Returns the parent entry of the entry being edited. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CCalEntry& CCalenEventViewContainer::ParentEntryL() + { + TRACE_ENTRY_POINT; + MCalenContext& context = iServices.Context(); + + if(iFetchedEntries.Count() == 0) + { + iServices.EntryViewL(context.InstanceId().iColId)->FetchL( iEntry->UidL(), iFetchedEntries ); + } + __ASSERT_ALWAYS( iFetchedEntries.Count() > 0, User::Panic(_L("CCalenEventViewContainer::ParentEntryL"),EPanicArrayOfSizeZero)); + + TRACE_EXIT_POINT; + return *iFetchedEntries[0]; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AllInstancesL +// Returns all the instances associated with the entry being edited. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +RPointerArray& CCalenEventViewContainer::AllInstancesL() + { + TRACE_ENTRY_POINT; + MCalenContext& context = iServices.Context(); + + if(iFetchedEntries.Count() == 0) + { + iServices.EntryViewL(context.InstanceId().iColId)->FetchL( iEntry->UidL(), iFetchedEntries ); + } + + TRACE_EXIT_POINT; + return iFetchedEntries; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::GetEventViewData +// Gets the Event View Data +// ----------------------------------------------------------------------------- +// +CCalenEntryUtil* CCalenEventViewContainer::GetEventViewData() + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + return iEventViewData; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::ReadAutoHlCenRepValueAndSetNotifyL +// +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::ReadAutoHlCenRepValueAndSetNotifyL() + { + TRACE_ENTRY_POINT; + + if ( iAutomaticHlInitialized ) + return; + + // Create the session + iCenRepSession = CRepository::NewL( KCRUidCommonUi ); + + if( iCenRepSession ) + { + // Get the value of AutomaticHighlight key + iCenRepSession->Get( KCuiAutomaticHighlight, iAutomaticHlValue ); + // Create the notifer + iNotifier = + CCenRepNotifyHandler::NewL( + *this, *iCenRepSession, CCenRepNotifyHandler::EIntKey, + KCuiAutomaticHighlight ); + // Start listening + iNotifier->StartListeningL(); + } + + iAutomaticHlInitialized = ETrue; // Done once per viewer + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::HandleNotifyInt +// Handles the incoming notifications of key changes +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::HandleNotifyInt( TUint32 /*aId*/, TInt aNewValue ) + { + TRACE_ENTRY_POINT; + + // Notifies changes on KCuiAutomaticHighlight + TRAPD(error,SetAutomaticHighlightL( aNewValue )); + if ( error != KErrNone ) + { + User::Panic(_L("CCalenEventViewContainer"),error); + } + TRACE_EXIT_POINT; + } + + +void CCalenEventViewContainer::HandleNotifyError( TUint32 /*aId*/,TInt /*aError*/, + CCenRepNotifyHandler* /*aHandler*/ ) + { + TRACE_ENTRY_POINT; + + if( iNotifier ) + { + iNotifier->StopListening(); + delete iNotifier; + iNotifier = NULL; + } + + delete iCenRepSession; + iCenRepSession = NULL; + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::SetAutomaticHighlightL +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::SetAutomaticHighlightL( const TBool aSwitchON ) + { + TRACE_ENTRY_POINT; + + if ( iAutoFinder ) + { + // content highlight + if ( aSwitchON ) + { // switch ON + iAutoFinder->SetFindModeL( + CItemFinder::EPhoneNumber | + CItemFinder::EUrlAddress | + CItemFinder::EEmailAddress ); + + } + else + { // switch OFF + iAutoFinder->SetFindModeL( + CItemFinder::ENoneSelected ); + + } + } + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::GetItemFinder +// ----------------------------------------------------------------------------- +// +CItemFinder* CCalenEventViewContainer::GetItemFinder() + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + + return iAutoFinder; + } +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::GetFindItemMenu +// ----------------------------------------------------------------------------- +// +CFindItemMenu* CCalenEventViewContainer::GetFindItemMenu() + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + + return iFindMenu; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::HandleScrollEventL +// Handles scroll events +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::HandleScrollEventL(CEikScrollBar* aScrollBar, + TEikScrollEvent aEventType) + { + TRACE_ENTRY_POINT; + + iTextEditor->HandleScrollEventL(aScrollBar,aEventType); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::HandleStopCommandL +// Handles scroll events +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::HandleStopCommandL() + { + TRACE_ENTRY_POINT; + + CCalenEventView* eventView = static_cast( iView ); + + eventView->HandleCommandL( ECalenStopAlarm ); + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::IsEventHasMapLocationOrNoLocationTextL +// Stores the necessary information in the context +// and returns ETrue if event has geo coordinates else EFalse +// ---------------------------------------------------------------------------- +TBool CCalenEventViewContainer::IsEventHasMapLocationL() + { + CCalGeoValue* geoValue = iEntry->GeoValueL(); + if(geoValue) + { + delete geoValue; + return ETrue; + } + else + { + return EFalse; + } + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::IsEventHasNoLocationTextL +// Returns ETrue if event has location text else EFalse +// ---------------------------------------------------------------------------- +TBool CCalenEventViewContainer::IsEventHasNoLocationTextL() + { + TPtrC location = iEntry->LocationL(); + if(!location.Length()) + { + return ETrue; + } + else + { + return EFalse; + } + } + +// ---------------------------------------------------------------------------- +// CCalenEventView::OnLocaleChangedL +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::HandleLocaleChangedL(/* TInt aReason */) + { + TRACE_ENTRY_POINT; + + iLocaleChanged = ETrue; + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddCalendarInfoFieldL +// Adds calendar info field to the viewer +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddCalendarInfoFieldL() + { + TRACE_ENTRY_POINT; + TCalCollectionId colId = iServices.Context().InstanceId().iColId; + + RPointerArray calendarInfoList; + iServices.GetAllCalendarInfoL(calendarInfoList); + CleanupClosePushL(calendarInfoList); + + HBufC* calendarFileName = iServices.GetCalFileNameForCollectionId(colId).AllocLC(); + TInt index = calendarInfoList.Find( *calendarFileName, + CCalenEventViewContainer::CalendarInfoIdentifierL); + CleanupStack::PopAndDestroy(calendarFileName); + if(index != KErrNotFound) + { + // add the calendar info's text field + AddTextFieldL( + R_CALE_VIEWER_CALENDAR_INFO, calendarInfoList[index]->NameL()); + } + CleanupStack::PopAndDestroy(&calendarInfoList); + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::CalendarInfoIdentifierL +// Searches for the index in calendar info list based on calendar file name +// ----------------------------------------------------------------------------- +// +TBool CCalenEventViewContainer::CalendarInfoIdentifierL( const HBufC* aName, + const CCalCalendarInfo& aCalendarInfo) + { + TRACE_ENTRY_POINT; + TBool retVal = EFalse; + HBufC* calendarFileName = aCalendarInfo.FileNameL().AllocLC(); + retVal = calendarFileName->CompareF(*aName); + CleanupStack::PopAndDestroy(calendarFileName); + TRACE_EXIT_POINT; + return (!retVal); + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::LabelRectL +// Returns the available label rect for this container +// ---------------------------------------------------------------------------- +TRect CCalenEventViewContainer::GetLabelRectL() + { + TRACE_ENTRY_POINT; + + // Get the main pane + TAknLayoutRect main_cale_day_pane; + main_cale_day_pane.LayoutRect( Rect(), + AknLayoutScalable_Apps::main_cale_day_pane().LayoutLine() ); + + TAknLayoutRect listscroll_cale_day_pane; + listscroll_cale_day_pane.LayoutRect( main_cale_day_pane.Rect(), + AknLayoutScalable_Apps::listscroll_cale_day_pane(1).LayoutLine() ); + + // Create a dummy label to find the layout rect + CEikLabel* dummyLabel = new( ELeave ) CEikLabel; + CleanupStack::PushL( dummyLabel ); + + + AknLayoutUtils::LayoutLabel( dummyLabel, listscroll_cale_day_pane.Rect(), + AknLayoutScalable_Apps::listscroll_cale_day_pane_t1( 0 ).LayoutLine() ); + + TRect labelRect = dummyLabel->Rect(); + + // Discard the label + CleanupStack::PopAndDestroy( dummyLabel ); + + TRACE_EXIT_POINT; + return labelRect; + } +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::SetLabelContentL +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::SetLabelContentL( CEikLabel& aLabel ) + { + TRACE_ENTRY_POINT; + const CFont* labelFont = NULL; + labelFont = AknLayoutUtils::FontFromId(EAknLogicalFontPrimarySmallFont,NULL); + aLabel.SetFont( labelFont ); + aLabel.SetLabelAlignment(ELayoutAlignLeft); + aLabel.OverrideColorL( EColorLabelTextEmphasis, KRgbBlack ); + + // get the multiple db data from services + RPointerArray calendarInfoList; + iServices.GetAllCalendarInfoL(calendarInfoList); + CleanupClosePushL(calendarInfoList); + + TCalCollectionId colId; + colId = iServices.Context().InstanceId().iColId; + + HBufC* calendarFileName = iServices.GetCalFileNameForCollectionId(colId).AllocLC(); + TInt calIndex = calendarInfoList.Find( *calendarFileName, + CCalenEventViewContainer::CalendarInfoIdentifierL); + CleanupStack::PopAndDestroy(calendarFileName); + + if(calIndex != KErrNotFound) + { + // add the calendar info's text field + aLabel.SetTextL(calendarInfoList[calIndex]->NameL()); + + TInt calendarColor = calendarInfoList[calIndex]->Color().Value(); + aLabel.OverrideColorL( EColorLabelHighlightFullEmphasis, calendarColor ); + + // Increment the iNumOfLinesBeforeLocField so that map icon is drwan at proper place + iNumOfLinesBeforeLocField = 1; + } + CleanupStack::PopAndDestroy(&calendarInfoList); + + aLabel.CropText(); + aLabel.SetEmphasis( CEikLabel::EFullEmphasis ); + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::AddAttachmentFieldL +// Adds attachment field +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddAttachmentFieldL() + { + TRACE_ENTRY_POINT; + + // format and add heading "Attachment:" + HBufC* textHeading = StringLoader::LoadLC(R_CALE_EVENT_VIEW_ATTACHMENT_INFO); + SetFormatAndAddHeadingL(*textHeading); + CleanupStack::PopAndDestroy(textHeading); + + + + RPointerArray attachmentNames; + + iEventViewData->AttachmentNamesL(attachmentNames); + TInt attachmentsCount = attachmentNames.Count(); + + //Reset the attachment posiitons array before addign them + iAttachmentPosInfoArray.Reset(); + + for(TInt i = 0; i < attachmentsCount; i++) + { + AddAttachmentNameL(*attachmentNames[i]); + } + // Add in a paragraph delimeter character + // Without this, long descriptions get cut off half way down the last line. + CRichText* richText = iTextEditor->RichText(); + richText->InsertL(richText->DocumentLength(), CEditableText::EParagraphDelimiter); + attachmentNames.ResetAndDestroy(); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::AddFormattedTextL +// Add a string to the view. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::AddAttachmentNameL(const TDesC& aText) + { + TRACE_ENTRY_POINT; + + // Set the charatcer formats and paragraph formats + iCharFormatMask.ClearAll(); + iParaFormat->iLeftMarginInTwips = iBodyIndent; + iCharFormat.iFontSpec = iBodyFontSpec; + iCharFormat.iFontPresentation.iUnderline = EUnderlineOn; + iCharFormatMask.SetAttrib(EAttFontUnderline); + iCharFormatMask.SetAttrib(EAttFontHeight); + iCharFormatMask.SetAttrib(EAttFontTypeface) ; + iCharFormatMask.SetAttrib(EAttFontStrokeWeight); + + // Add the text into the richtext document + CRichText* richText = iTextEditor->RichText(); + TInt startPos = richText->DocumentLength(); + HBufC* text = HBufC::NewLC( aText.Length() + 10); + TPtr target = text->Des(); + if(AknLayoutUtils::LayoutMirrored()) + { + target.Append(KArabicSummaryMarker); + } + else + { + target.Append(KWesternSummaryMarker); + } + target.Append(aText); + target.Append(KAttachmentSeparator); // Append the attachment seperator + TTextPos posInfo; + posInfo.iDocStart = richText->DocumentLength(); + richText->InsertL(startPos, target); + posInfo.iDocEnd = richText->DocumentLength(); + iAttachmentPosInfoArray.Append(posInfo); + TInt endPos = richText->DocumentLength(); + richText->ApplyCharFormatL(iCharFormat, iCharFormatMask, startPos, (endPos - startPos - 1)); + ++startPos; // Without this the previous paragraph is formatted as well, ie no indent + richText->ApplyParaFormatL(iParaFormat, iParaFormatMask, startPos, (endPos - startPos - 1)); + CleanupStack::PopAndDestroy(text); + + TRACE_EXIT_POINT; + } + + // ---------------------------------------------------------------------------- +// CCalenEventViewContainer::OpenViewerL() +// Opens the attachment in the Viewer +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::OpenViewerL(TInt attachmentToBeOpened) + { + // Update the Attahcment model with the attahcments of the current entry + iServices.GetAttachmentData()->CheckForExistingAttachmentsL(iEntry); + + // Get the file handler + RFile file = iServices.GetAttachmentData()->GetAttachmentFileL( attachmentToBeOpened ); + + // Hide the toolbar before opening the attachment + MCalenToolbar* toolbar = iServices.ToolbarOrNull(); + if(toolbar && toolbar->IsVisible()) + { + toolbar->SetToolbarVisibilityL(EFalse); + } + + //open the attachment + OpenAttachmentViewerL(file, *this); + + // Unhide the toolbar after coming back + if(toolbar) + { + toolbar->SetToolbarVisibilityL(ETrue); + } + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::HandleServerAppExit +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::HandleServerAppExit( TInt aReason) + { + TRACE_ENTRY_POINT; + + if (aReason == EAknCmdExit) + { + //issue this notification, which will be handled by attachmentui. + } + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::CheckAndOpenTappedAttachment +// Checks if it is tapped on any attachment, if yes, then opens that attachment +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::CheckAndOpenTappedAttachment(TTmPosInfo2* posInfo) + { + // iterate through iAttachmentPosInfoArray to see if posInfo falls in any of the range + TInt attachmentToBeOpened = -1; + for(TInt i = 0; i < iAttachmentPosInfoArray.Count(); i++) + { + if( (posInfo->iDocPos.iPos >= iAttachmentPosInfoArray[i].iDocStart) && ( posInfo->iDocPos.iPos < iAttachmentPosInfoArray[i].iDocEnd )) + { + attachmentToBeOpened = i; + break; + } + } + if(attachmentToBeOpened != -1) + { + OpenViewerL(attachmentToBeOpened); + } + } + +// ---------------------------------------------------------------------------- +// CCalenEventViewContainer::CalcNumOfLinesBeforeLocation +// Calculates the number of line before locaiton field in the document of the rich text editor +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenEventViewContainer::CalcNumOfLinesBeforeLocation() + { + TRACE_ENTRY_POINT; + + CCalGeoValue* geoValue = iEntry->GeoValueL(); + if(geoValue) + { + // Get the count of lines before location field + // so that map icon is drwan exactly at the firlst line of location text on the event viewer + HBufC* visualText = NULL; + CArrayFixFlat* lineWidths = new( ELeave )CArrayFixFlat( 5 ); + CleanupStack::PushL( lineWidths ); + lineWidths->AppendL(iMaxWidth - iIconDrawerWidthInPixels); + // trim of enter keys entered at the end of the summary text, + TBuf<160> summary; + summary.Append(iEventViewData->Summary()); + TChar ch = 0x2029; // For Enter key + TInt length = iEventViewData->Summary().Length(); + TInt count = 0; + + while( length > 0 ) + { + if(summary[--length] == ch) + { + count++; + summary.Copy(summary.Left(length)); // trim off the enter key + } + } + + // Count the number of lines summary will occupy after squeezing enter keys at the end of the text + CArrayFixFlat* textLines = new(ELeave)CArrayFixFlat(5); + CleanupStack::PushL( textLines ); + visualText = AknBidiTextUtils::ConvertToVisualAndWrapToArrayWholeTextL(summary , + *lineWidths, + *iHeadingFont, + *textLines); + iNumOfLinesBeforeLocField += textLines->Count() + iTimeFieldLines; // Added for time and date field + if (iEventViewData->Summary() == KNullDesC) // If summary is NULL, then will be added as first line, hence, increment it + { + iNumOfLinesBeforeLocField++; + } + iNumOfLinesBeforeLocField += count; // Add the number of enter keys added at the end of the summary + iTimeFieldLines = 0; // Reset the value + CleanupStack::PopAndDestroy(textLines); + CleanupStack::PopAndDestroy(lineWidths); + delete visualText; + delete geoValue; + } + } + +// ----------------------------------------------------------------------------- +// CCalenCommonUI::FindPossibleInstanceL +// Finds an instance with the given instance id and instance view. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CCalInstance* CCalenEventViewContainer::FindPossibleInstanceL( + const TCalenInstanceId& aId, + CCalInstanceView& aInstanceView ) + { + TRACE_ENTRY_POINT; + + RPointerArray instances; + CleanupResetAndDestroyPushL( instances ); + + //If timezone is changed we need to read the latest instance time + //SO we are reading all the instances in the timerange of past 24 hrs ans next 24 hrs minus + //a minute so that instanceid shouldnt match with daily repeat meeting + TCalTime momentStart, momentEnd; + momentStart.SetTimeLocalL( (aId.iInstanceTime - TTimeIntervalDays(1)) + TTimeIntervalMinutes(1)); + momentEnd.SetTimeLocalL( (aId.iInstanceTime + TTimeIntervalDays(1)) - TTimeIntervalMinutes(1)); + CalCommon::TCalTimeRange range( momentStart, momentEnd ); + aInstanceView.FindInstanceL( instances, CalCommon::EIncludeAll, range ); + + CCalInstance* result = NULL; + + // For instances finishing the next day (now possible with unified DateTime editor), + // we have to do our best to match the instance time exactly - otherwise we could + // match the LocalUid to the incorrect instance in a series. + for ( TInt i=0; i < instances.Count() && !result; ++i ) + { + if( instances[i]->Entry().LocalUidL() == aId.iEntryLocalUid ) + { + // Check the instance time matches. + if( instances[i]->StartTimeL().TimeLocalL() == aId.iInstanceTime ) + { + result = instances[i]; + instances.Remove(i); + } + } + } + + if( !result ) + { + // Couldn't match the instance time exactly - just use the instance + // with the same LocalUid as the one we're looking for. + for ( TInt i=0; i < instances.Count() && !result; ++i ) + { + if( instances[i]->Entry().LocalUidL() == aId.iEntryLocalUid ) + { + result = instances[i]; + instances.Remove(i); + } + } + } + + CleanupStack::PopAndDestroy( &instances ); + + TRACE_EXIT_POINT; + return result; + } + +// ----------------------------------------------------------------------------- +// CCalenEventViewContainer::OpenAttachmentL +// Opens a particular attachment +// ----------------------------------------------------------------------------- +// +void CCalenEventViewContainer::OpenAttachmentViewerL(RFile& file, MAknServerAppExitObserver& /*aExitObserver*/) + { + TRACE_ENTRY_POINT; + + TBuf<250> fileName; + file.FullName(fileName); + TDataType datatype( CCalenAttachmentUtils::GetMimeTypeL(fileName) ); + + TInt ret = KErrNone; + + file.Close(); + RFs& fs = CEikonEnv::Static()->FsSession(); + + //open the file, before giving it to Notepad. + TInt err1 = file.Open( fs, fileName, EFileRead | EFileShareReadersOnly ); + CleanupClosePushL( file ); + + if(datatype == KNotePadTextDataType()) + { + const TDesC& notepadTitle = _L("NotePad"); + // file handle ownership transferred. + + // 1.File handle from arg has problem for notes since junk chars are reported in file. + // so we use another file handle exclusively open with filename an pass to note viewer. + // + // 2.Pass ETrue to 4th param ExecFileViewerL , to guess encoding. + RFile fileForNotes; + TInt err = fileForNotes.Open( fs, fileName, EFileRead | EFileShareReadersOnly ); + CleanupClosePushL( fileForNotes ); + ret = CNotepadApi::ExecFileViewerL( fileForNotes, + ¬epadTitle, + ETrue, + ETrue, + KCharacterSetIdentifierIso88591 ); + + CleanupStack::PopAndDestroy(&fileForNotes); + } + else + { + //doc handler will open the other files (other than text file). + TRAP( ret, iDocHandler->OpenFileEmbeddedL( file, datatype ) ); + } + CleanupStack::PopAndDestroy(&file); + + switch(ret) + { + case KErrNone: + break; + default: + { + CAknInformationNote* note = new ( ELeave ) CAknInformationNote; + HBufC* cannotOpen = StringLoader::LoadLC( + R_QTN_CALEN_INFO_CANNOT_OPEN, CEikonEnv::Static() ); + note->ExecuteLD( *cannotOpen ); + CleanupStack::PopAndDestroy(); + } + break; + } + TRACE_EXIT_POINT + } + + +// end of file +