--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/calendarui/organizerplugin/aiagendaplugin2/src/aicalendarplugin2.cpp Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,1594 @@
+/*
+* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+ *
+*/
+
+#include "aicalendarplugin2.h"
+#include "aicalendarplugin2contentmodel.h"
+#include "AIAgendaPluginEngineIf.h"
+#include "aicalendarplugin2constantdata.h"
+#include "aicalendarplugin2data.h"
+#include "aicalendarplugin2constants.hrh"
+#include "aicalendarplugin2uids.hrh"
+
+#include <aicalendarplugin2.mbg>
+#include <calendar.mbg>
+#include <gulicon.h>
+#include <bautils.h>
+#include <ecom/implementationproxy.h>
+
+#include <aistrparser.h>
+#include <aiutility.h>
+#include <aipluginsettings.h>
+
+// CONSTANTS
+
+const TInt KAI2CurrentIconLoadSizeX = 40;
+const TInt KAI2CurrentIconLoadSizeY = 40;
+
+const TInt KAI2InternalIdForNoEvents = -357;
+const TInt KAI2InternalIdForNoMoreEvents = -38;
+const TInt KAI2InternalIdForNextEvent = -44;
+const TInt KAI2InternalIdForNextEvents = -45;
+const TInt KAI2InternalIdForNextEventTomorrow = -762;
+
+enum TAi2CalIcons
+ {
+ // Lets be explicit to maintain readability
+ KAi2IconCalendar = 0,
+ KAi2MeetingIcon, // 1
+ KAi2Memo, // 2
+ KAi2Anniversary, // 3
+ KAi2UncompeledTodo // 4
+ };
+
+_LIT( KResourceDrive, "z:" );
+_LIT( KCalendarBitmapFile, "calendar.mif" );
+_LIT( KAIPluginIconBitmapFile, "aicalendarplugin2.mif" );
+_LIT( KCalendarResourceFile, "calendar.rsc" );
+_LIT( KAIPluginTextsResourceFileName, "aicalendarplugin2res.rsc");
+
+_LIT16( KHexPrefix16, "0x" );
+
+
+TInt ParseInt
+ ( TInt32& aValue, const TDesC16& aStringValue )
+ {
+ const TInt pos = aStringValue.FindF( KHexPrefix16 );
+ if (pos != KErrNotFound)
+ {
+ TLex16 lex( aStringValue.Mid( pos + KHexPrefix16().Length() ) );
+ // Hex parsing needs unsigned int
+ TUint32 value = 0;
+ const TInt parseResult = lex.Val( value, EHex );
+ if ( parseResult == KErrNone )
+ {
+ aValue = value;
+ }
+ return parseResult;
+ }
+ else
+ {
+ TLex16 lex( aStringValue );
+ return lex.Val(aValue);
+ }
+ }
+
+TInt GetTimedItemLineNeed(
+ RPointerArray<CAiCalendarPlugin2EventItem>& /*aArray*/,
+ TInt /*aArrayOffset*/ )
+ {
+ // Multiline cale
+ return 1;
+ }
+
+TInt GetTimedArrayLineNeed(
+ RPointerArray<CAiCalendarPlugin2EventItem>& aArray, TInt aSpaceTaken )
+ {
+ // Multiline cale
+ return aArray.Count() * aSpaceTaken;
+ }
+
+TInt CalculateStartIndexBackwards(
+ RPointerArray<CAiCalendarPlugin2EventItem>& aArray,
+ TInt aLinesAvailable,
+ TInt spaceUse,
+ TBool aHasPriority )
+ {
+ TInt i = aArray.Count() - 1;
+ TInt totalSpace = 0;
+ for( ; i >= 0; --i )
+ {
+ if( totalSpace + spaceUse >= aLinesAvailable )
+ {
+ if( totalSpace + spaceUse > aLinesAvailable )
+ {
+ ++i;
+ }
+ break;
+ }
+ totalSpace += spaceUse;
+ }
+ if( i >= aArray.Count() )
+ {
+ i = aArray.Count() - 1;
+ }
+ else if( ( ( i < 0 ) && aHasPriority ) ||// <- if there is little space left only priority item are
+ // fitted to the screen
+ ( aLinesAvailable > aArray.Count() ) )// <- if theres lot of space, make sure to fit us too
+ {
+ i = 0;
+ }
+ return i;
+ }
+
+// Provide a key pair value table for ECOM.
+// Used to identify the correct construction function for the requested interface.
+const TImplementationProxy ImplementationTable[] =
+ {
+ IMPLEMENTATION_PROXY_ENTRY( AI_UID_ECOM_IMPLEMENTATION_CONTENTPUBLISHER_CALENDARPLUGIN,
+ CAICalendarPlugin2::NewL )
+ };
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+CAICalendarPlugin2* CAICalendarPlugin2::NewL()
+ {
+ CAICalendarPlugin2* self = new( ELeave )CAICalendarPlugin2;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CAICalendarPlugin2::CAICalendarPlugin2()
+ : iActualLinesInUse( KAICal2DefaultActualLines ),
+ iNonTimedItemReservation( KAICal2DefaultItemReservation )
+ {
+ }
+
+void CAICalendarPlugin2::ConstructL()
+ {
+ if( !iCalendarResourceFileOffset )
+ {
+ TFileName resFile;
+ resFile.Append( KResourceDrive );
+ resFile.Append( KDC_APP_RESOURCE_DIR );
+ resFile.Append( KCalendarResourceFile );
+ BaflUtils::NearestLanguageFile( CCoeEnv::Static()->FsSession(), resFile );
+ iCalendarResourceFileOffset = CCoeEnv::Static()->AddResourceFileL( resFile );
+ }
+
+ if( !iTextResourceFileOffset )
+ {
+ TFileName resFile;
+ resFile.Append( KResourceDrive );
+ resFile.Append( KDC_RESOURCE_FILES_DIR );
+ resFile.Append( KAIPluginTextsResourceFileName );
+ BaflUtils::NearestLanguageFile( CCoeEnv::Static()->FsSession(), resFile );
+ iTextResourceFileOffset = CCoeEnv::Static()->AddResourceFileL( resFile );
+ }
+
+ iCalendarIconFileName = HBufC::NewL( KResourceDrive().Length() +
+ KDC_APP_BITMAP_DIR().Length() +
+ KCalendarBitmapFile().Length() );
+ iCalendarIconFileName->Des().Append( KResourceDrive );
+ iCalendarIconFileName->Des().Append( KDC_APP_BITMAP_DIR );
+ iCalendarIconFileName->Des().Append( KCalendarBitmapFile );
+
+ iPluginIconFileName = HBufC::NewL( KResourceDrive().Length() +
+ KDC_APP_BITMAP_DIR().Length() +
+ KAIPluginIconBitmapFile().Length() );
+ iPluginIconFileName->Des().Append( KResourceDrive );
+ iPluginIconFileName->Des().Append( KDC_APP_BITMAP_DIR );
+ iPluginIconFileName->Des().Append( KAIPluginIconBitmapFile );
+
+ iConstantData = CAICalendarPlugin2ConstantData::NewL();
+ iEventData = CAICalendarPlugin2Data::NewL();
+ iStrParser = AiUtility::CreateStrParserL();
+ }
+
+CAICalendarPlugin2::~CAICalendarPlugin2()
+ {
+ if( iCalendarResourceFileOffset )
+ {
+ CCoeEnv::Static()->DeleteResourceFile( iCalendarResourceFileOffset );
+ }
+ if( iTextResourceFileOffset )
+ {
+ CCoeEnv::Static()->DeleteResourceFile( iTextResourceFileOffset );
+ }
+ delete iEngine;
+ delete iEventData;
+ delete iConstantData;
+ Release( iStrParser );
+
+ iBitmaps.ResetAndDestroy();
+ iMasks.ResetAndDestroy();
+
+ delete iPluginIconFileName;
+ delete iCalendarIconFileName;
+ iPublishedDataStore.Reset();
+ iNewCollectedDataStore.Reset();
+ delete iPrevUid;
+ }
+
+void CAICalendarPlugin2::CreateBitmapSkinnedIconL( const TAknsItemID& aSkinIconId,
+ const TDesC& aFilename,
+ TInt aNormalIconId,
+ TInt aNormalMaskId,
+ CFbsBitmap*& aBitmap,
+ CFbsBitmap*& aMask )
+ {
+ AknsUtils::CreateIconLC( AknsUtils::SkinInstance(),
+ aSkinIconId,
+ aBitmap,
+ aMask,
+ aFilename,
+ aNormalIconId,
+ aNormalMaskId );
+
+ CleanupStack::Pop( 2 ); // bitmap, mask, cant use pop param here, we dont know
+ // the push order of the CreateIconLC
+ }
+
+void CAICalendarPlugin2::CreateIconsL(void)
+ {
+ CFbsBitmap* bitmap;
+ CFbsBitmap* mask;
+ iBitmaps.ResetAndDestroy();
+ iMasks.ResetAndDestroy();
+
+ TSize iconSize( TSize( KAI2CurrentIconLoadSizeX,
+ KAI2CurrentIconLoadSizeY ) );
+ /**
+ * Creation order!:
+ * Calendar icon
+ * Meeting icon
+ * Note icon
+ * Anniversary icon
+ * Uncompleted to-do icon
+ *
+ **/
+ CreateBitmapSkinnedIconL( KAknsIIDQgnIndiAiCale,
+ *iPluginIconFileName,
+ EMbmAicalendarplugin2Qgn_indi_ai_cale,
+ EMbmAicalendarplugin2Qgn_indi_ai_cale_mask,
+ bitmap, mask );
+
+ // These bitmaps are permanently owned by arrays here.
+ // Only duplicates are provided to system, are they can
+ // do whatever they want to them.
+ User::LeaveIfError( iBitmaps.Append( bitmap ) );
+ User::LeaveIfError( iMasks.Append( mask ) );
+ User::LeaveIfError(
+ AknIconUtils::SetSize( bitmap, iconSize ) );
+
+ CreateBitmapSkinnedIconL( KAknsIIDQgnIndiCdrMeeting,
+ *iCalendarIconFileName,
+ EMbmCalendarQgn_indi_cdr_meeting,
+ EMbmCalendarQgn_indi_cdr_meeting_mask,
+ bitmap, mask );
+ User::LeaveIfError( iBitmaps.Append( bitmap ) );
+ User::LeaveIfError( iMasks.Append( mask ) );
+ User::LeaveIfError(
+ AknIconUtils::SetSize( bitmap, iconSize ) );
+
+ CreateBitmapSkinnedIconL( KAknsIIDQgnIndiCdrReminder,
+ *iCalendarIconFileName,
+ EMbmCalendarQgn_indi_cdr_reminder,
+ EMbmCalendarQgn_indi_cdr_reminder_mask,
+ bitmap, mask );
+ User::LeaveIfError( iBitmaps.Append( bitmap ) );
+ User::LeaveIfError( iMasks.Append( mask ) );
+ User::LeaveIfError(
+ AknIconUtils::SetSize( bitmap, iconSize ) );
+
+ CreateBitmapSkinnedIconL( KAknsIIDQgnIndiCdrBirthday,
+ *iCalendarIconFileName,
+ EMbmCalendarQgn_indi_cdr_birthday,
+ EMbmCalendarQgn_indi_cdr_birthday_mask,
+ bitmap, mask );
+ User::LeaveIfError( iBitmaps.Append( bitmap ) );
+ User::LeaveIfError( iMasks.Append( mask ) );
+ User::LeaveIfError(
+ AknIconUtils::SetSize( bitmap, iconSize ) );
+
+ CreateBitmapSkinnedIconL( KAknsIIDQgnPropTodoUndone,
+ *iCalendarIconFileName,
+ EMbmCalendarQgn_indi_cdr_todo,
+ EMbmCalendarQgn_indi_cdr_todo_mask,
+ bitmap, mask );
+ User::LeaveIfError( iBitmaps.Append( bitmap ) );
+ User::LeaveIfError( iMasks.Append( mask ) );
+ User::LeaveIfError(
+ AknIconUtils::SetSize( bitmap, iconSize ) );
+
+ iBitmaps.Compress();
+ iMasks.Compress();
+ }
+
+void CAICalendarPlugin2::Resume( TAiTransitionReason aReason )
+ {
+ TRAP_IGNORE( DoResumeL( aReason ) );
+ }
+
+void CAICalendarPlugin2::DoResumeL( TAiTransitionReason aReason )
+ {
+ if( aReason == EAiIdleForeground ||
+ aReason == EAiBacklightOn ||
+ aReason == EAiSystemStartup ||
+ aReason == EAiGeneralThemeChanged )
+ {
+ if( aReason == EAiGeneralThemeChanged )
+ {
+ // Reset for republishing. Especially icons!
+ iPublishedDataStore.Reset();
+ }
+ if( !iEngine )
+ {
+ iEngine = CAIAgendaPluginEngineIf::NewL( *this, ECalendarAndTodoObserver );
+ }
+ else
+ {
+ iEngine->Refresh();
+ }
+ }
+ }
+
+void CAICalendarPlugin2::Suspend( TAiTransitionReason /*aReason*/ )
+ {
+ delete iEngine;
+ iEngine = NULL;
+ }
+
+void CAICalendarPlugin2::Stop( TAiTransitionReason /*aReason*/ )
+ {
+ delete iEngine;
+ iEngine = NULL;
+ iPublishedDataStore.Reset();
+ }
+
+void CAICalendarPlugin2::SubscribeL( MAiContentObserver& aObserver )
+ {
+ iEventData->AppendObserverL( aObserver );
+ }
+
+void CAICalendarPlugin2::ConfigureL( RAiSettingsItemArray& aSettings )
+ {
+ // Receive the settings for this plugin from the user(theme or similar).
+ // There are four settings we need for the current implementation to work
+ // properly:
+ //
+ // 1) total item count of the UI = EPluginEventItemCount
+ //
+ // 2) the vertical space taken by timed item (relative to the size of non timed item)
+ // = EPluginTimedEventLineCount
+ //
+ // 3) the vertical space taken by non timed item (relative to the size of timed item)
+ // = EPluginNonTimedEventLineCount
+ //
+ // 4) the amount of lines we reserve for non timed events if many timed and non timed
+ // events are present = EPluginNonTimedReservedItems
+ //
+ // In the current 2.6.2006 specification for example (Navibar theme), we have non timed items
+ // half the vertical size of timed items. Timed items take 2 lines visible space and
+ // non timed take 1 line of visible space. We need to able to show at maximum 6
+ // non timed items, so we need total 6 items (1 line items). As timed items take
+ // 2 lines we can fit three of them in to the view (no setting need/can be calculated)
+ // as stated in the specification. If many timed and non timed calendar events are
+ // present we always reserve 2 times for non timed events.
+ // So the setting to satisfy the UI spec of the "Navibar UI" are 6, 2, 1, 2
+ //
+ //
+ for( TInt i = 0; i < aSettings.Count(); ++i )
+ {
+ MAiPluginSettingsItem& item = (aSettings[i])->AiPluginSettingsItem();
+ TInt32 value = 0;
+ if( ParseInt( value, item.Value() ) != KErrNone )
+ {
+ continue;
+ }
+ if( value < 0 )
+ {
+ continue;
+ }
+
+ if( item.Key() == EPluginEventItemCount )
+ {
+ iActualLinesInUse = value;
+ continue;
+ }
+ else if( item.Key() == EPluginTimedEventLineCount )
+ {
+ iEventData->SetSpaceTakenByTimedEvent( value );
+ continue;
+ }
+ else if( item.Key() == EPluginNonTimedEventLineCount )
+ {
+ iEventData->SetSpaceTakenByNonTimedEvent( value );
+ continue;
+ }
+ else if( item.Key() == EPluginNonTimedReservedItems )
+ {
+ iNonTimedItemReservation = value;
+ continue;
+ }
+ else if( item.Key() == EPluginAppendEndTimeToOngoingItems )
+ {
+ iConstantData->iAppendEndTimeToOngoingItems = value;
+ continue;
+ }
+ else if( item.Key() == EPluginUseAlternatePublishForUpcomingAndOngoingItems )
+ {
+ iConstantData->iUseAlternatePublish = value;
+ continue;
+ }
+ else if( item.Key() == EPluginOpenInViewerOrEditor )
+ {
+ iConstantData->iOpenInViewer = !value;
+ continue;
+ }
+ else if( item.Key() == EPluginDaysToHandleAsNotToday )
+ {
+ iConstantData->iDaysToHandleAsNotToday = value;
+ continue;
+ }
+ else if( item.Key() == EPluginOpenFirstValidOnIndexZero )
+ {
+ iConstantData->iOpenFirstValid = value;
+ continue;
+ }
+ else if ( item.Key() == EPluginPublishInfoWithAlternateId )
+ {
+ iConstantData->iUseAlternateInfoPublish = value;
+ continue;
+ }
+
+ }
+ // Last op, free array and items
+ aSettings.ResetAndDestroy();
+ }
+
+TAny* CAICalendarPlugin2::Extension( TUid aUid )
+ {
+ if (aUid == KExtensionUidProperty)
+ {
+ return static_cast<MAiPropertyExtension*>(this);
+ }
+ else if (aUid == KExtensionUidEventHandler)
+ {
+ return static_cast<MAiEventHandlerExtension*>(this);
+ }
+ return NULL;
+ }
+
+TAny* CAICalendarPlugin2::GetPropertyL( TInt aProperty )
+ {
+ return iConstantData->GetPropertyL( aProperty );
+ }
+
+void CAICalendarPlugin2::SetPropertyL( TInt aProperty, TAny* aValue )
+ {
+ if( aValue )
+ {
+ iConstantData->SetPropertyL( aProperty, aValue );
+ }
+ }
+
+void CAICalendarPlugin2::HandleEvent( TInt aEvent, const TDesC& aParam )
+ {
+ if( aEvent == EAICalendarPlugin2EventItemSelected )
+ {
+ TInt32 index = 0;
+ if( ParseInt( index, aParam ) != KErrNone )
+ {
+ return;
+ }
+
+ // Other "out of bounds" checked inside launch method.
+ if( index > iActualLinesInUse )
+ {
+ // invalid index
+ return;
+ }
+ iEventData->LaunchCalendarApplication( index, iConstantData->iOpenFirstValid );
+ }
+ }
+
+void CAICalendarPlugin2::PluginDataChanged(
+ const RPointerArray<CCalInstance>& aEntryArray,
+ TBool aHadEvents )
+ {
+ iEventData->SetHadExpiredEvents( aHadEvents );
+
+ iEventData->ClearDataArrays();
+
+ TRAP_IGNORE(
+ FillDataArraysL( aEntryArray );
+ PublishDataArraysL();
+ );
+ }
+
+void CAICalendarPlugin2::FillDataArraysL(
+ const RPointerArray<CCalInstance>& aEntryArray )
+ {
+ /**
+ * [uses icon y/n] time formatting | subject and location formatting
+ *
+ * [Y] 13:05-14:00 subject, location... // normal day event
+ * [Y] 00:00-08:00 subject, location... // event starting yesterday
+ * [Y] 19:00-23:59 subject, location... // event ends tomorrow
+ * [Y] 16:50-16:50 subject, location... // event with no duration
+ * [Y] 25/8/04 16:00- subject... // normal not today event
+ * [Y] subject... // normal non timed event
+ * [Y] 25/8/04 subject... // not today non timed event
+ * 26.10.2006 Tuomas Karjagin: - all item now will use icons
+ * - end time removed from normal not today.
+ **/
+
+ // extract new data from CAgnEntry objects
+ TInt daynoteIndex = 0; // to insert day notes in correct order...
+ delete iPrevUid;
+ iPrevUid = NULL;
+
+ for( TInt eventArrayIndex = 0, count = aEntryArray.Count();
+ eventArrayIndex < count;
+ eventArrayIndex++ )
+ {
+ CAiCalendarPlugin2EventItem* eventItem = CAiCalendarPlugin2EventItem::NewL(
+ *aEntryArray[eventArrayIndex],
+ *iConstantData );
+ CleanupStack::PushL( eventItem );
+
+ // Multiple-day Todos contain multiple eventItems
+ // Showing only one and deleting the rest
+ if ( ( iPrevUid ) && ( eventItem->Type() == EPluginItemToDo )
+ && ( iPrevUid->Compare( *( eventItem->iUid ) ) == 0 ) )
+ {
+ CleanupStack::PopAndDestroy( eventItem );
+ }
+ else
+ {
+ delete iPrevUid;
+ iPrevUid = NULL;
+ iPrevUid = eventItem->iUid->AllocL();
+
+ // Append item ot correct array, method increments daynoteIndex if required
+ if( iEventData->AppendItemToCorrectArray( *eventItem,
+ daynoteIndex ) != KErrNone )
+ {
+ // Append not allowed, destroy item and proceed
+ CleanupStack::PopAndDestroy( eventItem );
+ }
+ else
+ {
+ // Item accepted and ownership transferred
+ CleanupStack::Pop( eventItem );
+ }
+ }
+ }
+ delete iPrevUid;
+ iPrevUid = NULL;
+ iEventData->SortArrayByTime( iEventData->FutureItemArray() );
+ iEventData->SortArrayByTime( iEventData->TomorrowEventArray() );
+ }
+
+
+void CAICalendarPlugin2::PublishDataArraysL()
+ {
+
+ // We publish only to the first registered observer.
+ // If needed edit the publishing helper function to
+ // publish to all.
+ if( iEventData->ObserverArray().Count() <= 0 )
+ {
+ // If no observers registered, return immediate
+ iEventData->ClearDataArrays();
+ return;
+ }
+ iCurrentObserver = (iEventData->ObserverArray())[0];
+ iCurrentObserver->StartTransaction( reinterpret_cast<TInt32>(this) );
+ iNewCollectedDataStore.Reset();
+ iNewCollectedDataStore.Append( 0 ); // always append the not used zero
+ // this because publishes start from 1
+ // so we dont need to -1 everywhere
+
+ /**************************************************************************
+ * Current publish order description, based on the Active Idle UI spec
+ *
+ * Last update date: 19/09/2006, UI Spec date 08/09/2006
+ *
+ * --- Last change item was to swap 3 and 4. Pre calculation part is
+ * --- no longer required but left in the code so that they can be restored
+ * --- just by moving the for loop again, no other changes required.
+ *
+ * Sections are accordingly numbered in the code below:
+ *
+ * 0) Publish "No (more calendar) events for today" if no (more)
+ * events today.
+ *
+ * 1) If there are on going meetings/appointments and extra room for these
+ * after all non timer and upcoming meetings have been published,
+ * publish as many on going events as fits in to the view. These
+ * are only published if there is left over space = low priority.
+ *
+ * 2) Publish as many timed events for today as fits in to view, but
+ * reserve space for todays non timed event if any. Reserve as many
+ * lines as is in the spec, currently up to 2 lines are reserved.
+ * These are top priority items.
+ *
+ * 3) Publish non timed event for today. Use all space left from 1), 2)
+ * and 3) if necessary. These are top priority items.
+ *
+ * 4) These are only published if there is left over space = low priority.
+ *
+ * 5) Publish empty content to the rest of the items.
+ *
+ * NOTES: Care must be taken when changes are made to this system.
+ * Extensive testing recommended when making even the smallest
+ * change.
+ *
+ **************************************************************************/
+
+ TInt lineUsage = 0;
+ TInt publishIndex = 1; // publishes start from 1, because 0 is "reserved"
+ // according to spec! maybe to.do: add a setting for this.
+ const TInt cstSpaceTakenByTimed = iEventData->SpaceTakenByTimedEvent();
+ const TInt cstSpaceTakenByNonTimed = iEventData->SpaceTakenByNonTimedEvent();
+
+ // SPACE VALUES INCLUDES CONSIDERATION TO 1 line - 2 lines space reservation
+ const TInt cstTotalNonTimedTodaySpace = iEventData->NonTimedEventArray().Count() *
+ cstSpaceTakenByNonTimed;
+
+ const TInt cstMinLinesForTodayNonTimed = Min( cstTotalNonTimedTodaySpace,
+ iNonTimedItemReservation *
+ cstSpaceTakenByNonTimed );
+
+
+ // Simplify total today item count, calculate it ready here
+ const TInt cstTotalTimedTodayItemCount = iEventData->TotalTimedTodayItemCount();
+
+ RArray<TAiCalendarFocusData>& focusDataArray = iEventData->FocusDataArray();
+ focusDataArray.Reset();
+
+ // First item always occupied by title line.
+ TAiCalendarFocusData titleFocusItem;
+ titleFocusItem.iType = EAI2CalOpenToday;
+ focusDataArray.Append( titleFocusItem );
+
+ TBool cleanInfo = ETrue;
+ // The "+ 1" in "lineUsage + 1"
+ // and "upcoming2HrsIndex + nonTimedIndex + futureTimedIndex + futureNonTimedIndex + ongoingIndex + ongoing30Index + upcomingIndex + nonCalendarEventItemIndex + 1"
+ // derives from the fact that we do not publish to index 0
+ // it is specified as reserved.
+
+ /**
+ * 0)
+ */
+ if( iEventData->TotalTodayItemCount() == 0 &&
+ iEventData->LongOngoingArray().Count() == 0 )
+ {
+ // hadExpiredEvents tells us if we had any events today, when
+ // there are no upcoming event for today. Then we can choose
+ // proper text to display.
+
+ Clean( EAICalendarPlugin2EventSubject, lineUsage + 1 );
+ Clean( EAICalendarPlugin2EventLocation, lineUsage + 1 );
+ Clean( EAICalendarPlugin2EventTimeStart, lineUsage + 1 );
+ Clean( EAICalendarPlugin2EventTimeEnd, lineUsage + 1 );
+ Clean( EAICalendarPlugin2EventTextSecondLine, lineUsage + 1 );
+
+ if( ( iEventData->TomorrowEventArray().Count() > 0 ) &&
+ ( iConstantData->iDaysToHandleAsNotToday == KAIRangeTomorrowOnly ) )
+ {
+ if ( !iConstantData->iUseAlternateInfoPublish )
+ {
+ CleanInfo();
+ }
+ TTime eventTime = (iEventData->TomorrowEventArray())[0]->Time();
+ // display "Next event tomorrow:"
+ if( !( CompareChecksums( publishIndex,
+ KAI2InternalIdForNextEventTomorrow ) ) )
+ {
+ PublishIconL( EAICalendarPlugin2NoEventsForToday, publishIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTextFirstLine,
+ EAICalendarPlugin2NextEventTomorrow,
+ lineUsage + 1 ); // Text line 1
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventSubject,
+ EAICalendarPlugin2NextEventTomorrow,
+ lineUsage + 1 ); // Text line 1
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2TimeStartAndSubject,
+ EAICalendarPlugin2NextEventTomorrow,
+ lineUsage + 1 ); // Text line 1
+ }
+ ++lineUsage;
+ ++publishIndex;
+
+ TAiCalendarFocusData focusItem;
+ focusItem.iType = EAI2CalOpenOnEventDay;
+ focusItem.iEntryTime = eventTime;
+ focusDataArray.Append( focusItem );
+ }
+ else if( ( ( iEventData->NotTodayItemArray().Count() > 0 ) &&
+ ( iConstantData->iDaysToHandleAsNotToday > 0 ) ) ||
+ ( ( iEventData->TomorrowEventArray().Count() > 0 ) &&
+ ( iConstantData->iDaysToHandleAsNotToday > KAIRangeTomorrowOnly ) ) )
+ {
+ if ( !iConstantData->iUseAlternateInfoPublish )
+ {
+ CleanInfo();
+ }
+ TTime eventTime;
+ if( iEventData->TomorrowEventArray().Count() > 0 )
+ {
+ eventTime = (iEventData->TomorrowEventArray())[0]->Time();
+ }
+ else
+ {
+ eventTime = (iEventData->NotTodayItemArray())[0]->Time();
+ }
+
+ // display "Next event(s):"
+ if( iEventData->NotTodayItemArray().Count() == 1 )
+ {
+ if( !( CompareChecksums( publishIndex,
+ KAI2InternalIdForNextEvent ) ) )
+ {
+ PublishIconL( EAICalendarPlugin2NoEventsForToday, publishIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTextFirstLine,
+ EAICalendarPlugin2NextEvent,
+ lineUsage + 1 ); // Text line 1
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventSubject,
+ EAICalendarPlugin2NextEvent,
+ lineUsage + 1 ); // Text line 1
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2TimeStartAndSubject,
+ EAICalendarPlugin2NextEvent,
+ lineUsage + 1 ); // Text line 1
+ }
+ }
+ else
+ {
+ if( !( CompareChecksums( publishIndex,
+ KAI2InternalIdForNextEvents ) ) )
+ {
+ PublishIconL( EAICalendarPlugin2NoEventsForToday, publishIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTextFirstLine,
+ EAICalendarPlugin2NextEvents,
+ lineUsage + 1 ); // Text line 1
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventSubject,
+ EAICalendarPlugin2NextEvents,
+ lineUsage + 1 ); // Text line 1
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2TimeStartAndSubject,
+ EAICalendarPlugin2NextEvents,
+ lineUsage + 1 ); // Text line 1
+ }
+ }
+ ++lineUsage;
+ ++publishIndex;
+
+ TAiCalendarFocusData focusItem;
+ focusItem.iType = EAI2CalOpenOnEventDay;
+ focusItem.iEntryTime = eventTime;
+ focusDataArray.Append( focusItem );
+ }
+ else if( ( iEventData->FutureItemArray().Count() > 0 ) ||
+ ( ( iEventData->TomorrowEventArray().Count() > 0 ) &&
+ ( iConstantData->iDaysToHandleAsNotToday == 0 ) ) )
+ {
+ if ( !iConstantData->iUseAlternateInfoPublish )
+ {
+ CleanInfo();
+ }
+ CAiCalendarPlugin2EventItem* item = NULL;
+ if( ( iEventData->TomorrowEventArray().Count() > 0 ) &&
+ ( iConstantData->iDaysToHandleAsNotToday == 0 ) )
+ {
+ item = (iEventData->TomorrowEventArray())[0];
+ }
+ else
+ {
+ item = (iEventData->FutureItemArray())[0];
+ }
+
+ TTime eventTime = item->Time();
+ const TDesC& nextOn = iConstantData->MakeEventOnL(eventTime);
+
+ if( !( CompareChecksums( 0, item->CreateChecksumFromString( nextOn ) ) ) )
+ {
+ // this change publish next event information to calendar info text instead of calendar entry text
+ // some languages needs two rows for publishing
+ cleanInfo = EFalse;
+ // display "Next event on: [day of the week] [date]"
+ PublishIconL( EAICalendarPlugin2NoMoreEventsForToday, 0, EAICalendarPlugin2InfoIcon );
+ iCurrentObserver->Publish( *this, EAICalendarPlugin2InfoText, nextOn, 0 );
+ }
+ ++lineUsage;
+ ++publishIndex;
+
+ TAiCalendarFocusData focusItem;
+ focusItem.iType = EAI2CalOpenOnEventDay;
+ focusItem.iEntryTime = eventTime;
+ focusDataArray.Append( focusItem );
+ /**
+ * 5) Clean the rest
+ */
+ for( ; publishIndex <= iActualLinesInUse; ++publishIndex )
+ {
+ CleanAll( publishIndex );
+
+ TAiCalendarFocusData focusItem2;
+ focusItem2.iType = EAI2CalOpenToday;
+ focusDataArray.Append( focusItem2 );
+ }
+
+ if( ( iPublishedDataStore.Count() == 0 ) ||
+ ( iPublishedDataStore.Count() != iNewCollectedDataStore.Count() ) )
+ {
+ iPublishedDataStore.Reset();
+ for( TInt i = 0; i < iNewCollectedDataStore.Count(); ++i )
+ {
+ iPublishedDataStore.Append( iNewCollectedDataStore[i] );
+ }
+ iCurrentObserver->Commit( reinterpret_cast<TInt32>(this) );
+ }
+ else
+ {
+ iCurrentObserver->CancelTransaction( reinterpret_cast<TInt32>(this) );
+ }
+
+ iEventData->ClearDataArrays();
+ return;
+ }
+ else if( !iConstantData->iUseAlternatePublish )
+ {
+ if ( iConstantData->iUseAlternateInfoPublish )
+ {
+ Clean( EAICalendarPlugin2EventTextFirstLine, lineUsage + 1 );
+ Clean( EAICalendarPlugin2TimeStartAndSubject, lineUsage + 1 );
+ }
+ else
+ {
+ CleanInfo();
+ }
+ // display ""No Calendar events for today or next 7 days"
+ // or "No more Calendar events for today or next 7 days"
+ if( !iEventData->HadExpiredEvents() )
+ {
+ if( !( CompareChecksums( publishIndex,
+ KAI2InternalIdForNoMoreEvents ) ) )
+ {
+ if( !iConstantData->iUseAlternateInfoPublish )
+ {
+ PublishIconL( EAICalendarPlugin2NoEventsForToday,
+ publishIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTextFirstLine,
+ EAICalendarPlugin2NoEventsForToday,
+ lineUsage + 1 ); // Text line 1
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventSubject,
+ EAICalendarPlugin2NoEventsForToday,
+ lineUsage + 1 ); // Text line 1
+ }
+ // In case theme instructs us we need to publish the status
+ // texts and icons to a different location
+ else
+ {
+ cleanInfo = EFalse;
+ PublishIconL( EAICalendarPlugin2NoEventsForToday,
+ 0,
+ EAICalendarPlugin2InfoIcon);
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2InfoText,
+ EAICalendarPlugin2NoEventsForToday,
+ 0); // Text line 1
+ }
+ }
+ }
+ else
+ {
+ if( !( CompareChecksums( publishIndex,
+ KAI2InternalIdForNoEvents ) ) )
+ {
+ if( !iConstantData->iUseAlternateInfoPublish )
+ {
+ PublishIconL( EAICalendarPlugin2NoEventsForToday, publishIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTextFirstLine,
+ EAICalendarPlugin2NoMoreEventsForToday,
+ lineUsage + 1 ); // Text line 1
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventSubject,
+ EAICalendarPlugin2NoMoreEventsForToday,
+ lineUsage + 1 ); // Text line 1
+ }
+ // In case theme instructs us we need to publish the status
+ // texts and icons to a different location
+ else
+ {
+ cleanInfo = EFalse;
+ PublishIconL( EAICalendarPlugin2NoEventsForToday,
+ 0,
+ EAICalendarPlugin2InfoIcon);
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2InfoText,
+ EAICalendarPlugin2NoMoreEventsForToday,
+ 0 ); // Text line 1
+ }
+ }
+ }
+ ++lineUsage;
+ ++publishIndex;
+
+ TAiCalendarFocusData focusItem;
+ focusItem.iType = EAI2CalOpenToday;
+ focusDataArray.Append( focusItem );
+ }
+ }
+
+ const TInt cstMaxLinesForTimedEvents =
+ ( iActualLinesInUse - cstMinLinesForTodayNonTimed );
+
+ /**
+ * -1) Really old ongoing timed events need full set of info.
+ */
+ const TInt cstLinesReserved3 =
+ GetTimedArrayLineNeed( iEventData->Upcoming2HrsArray(), iEventData->SpaceTakenByTimedEvent() ) +
+ GetTimedArrayLineNeed( iEventData->Ongoing30MinArray(), iEventData->SpaceTakenByTimedEvent() ) +
+ GetTimedArrayLineNeed( iEventData->UpcomingArray(), iEventData->SpaceTakenByTimedEvent() ) +
+ GetTimedArrayLineNeed( iEventData->OngoingArray(), iEventData->SpaceTakenByTimedEvent() ) +
+ cstTotalNonTimedTodaySpace;
+ const TInt startIndex3 = CalculateStartIndexBackwards(
+ iEventData->LongOngoingArray(),
+ iActualLinesInUse - cstLinesReserved3,
+ ( iConstantData->iUseAlternatePublish ?
+ 1 :iEventData->SpaceTakenByTimedEvent() ),
+ EFalse );
+ if( startIndex3 >= 0 )
+ {
+ PublishTodayTimedItemsForArrayL(
+ iEventData->LongOngoingArray(),
+ publishIndex, // reference passed and updated inside
+ lineUsage, // reference passed and updated inside
+ cstMaxLinesForTimedEvents,
+ startIndex3,
+ cstLinesReserved3 );
+ }
+
+ /**
+ * 1) Ongoing today timed events need full set of info.
+ */
+ const TInt cstLinesReserved =
+ GetTimedArrayLineNeed( iEventData->Upcoming2HrsArray(), iEventData->SpaceTakenByTimedEvent() ) +
+ GetTimedArrayLineNeed( iEventData->Ongoing30MinArray(), iEventData->SpaceTakenByTimedEvent() ) +
+ GetTimedArrayLineNeed( iEventData->UpcomingArray(), iEventData->SpaceTakenByTimedEvent() ) +
+ cstTotalNonTimedTodaySpace;
+ const TInt startIndex = CalculateStartIndexBackwards(
+ iEventData->OngoingArray(),
+ iActualLinesInUse - cstLinesReserved,
+ ( iConstantData->iUseAlternatePublish ?
+ 1 :iEventData->SpaceTakenByTimedEvent() ),
+ ETrue );
+
+ if( startIndex >= 0 )
+ {
+ PublishTodayTimedItemsForArrayL(
+ iEventData->OngoingArray(),
+ publishIndex, // reference passed and updated inside
+ lineUsage, // reference passed and updated inside
+ cstMaxLinesForTimedEvents,
+ startIndex,
+ cstLinesReserved );
+ }
+
+ /**
+ * Ongoing not older than 30min today timed events.
+ */
+ const TInt cstLinesReserved2 =
+ GetTimedArrayLineNeed( iEventData->Upcoming2HrsArray(), iEventData->SpaceTakenByTimedEvent() ) +
+ cstMinLinesForTodayNonTimed;
+ const TInt startIndex2 = CalculateStartIndexBackwards(
+ iEventData->Ongoing30MinArray(),
+ iActualLinesInUse - cstLinesReserved2,
+ iEventData->SpaceTakenByTimedEvent() ,
+ ETrue );
+
+ if( startIndex2 >= 0 )
+ {
+ PublishTodayTimedItemsForArrayL(
+ iEventData->Ongoing30MinArray(),
+ publishIndex, // reference passed and updated inside
+ lineUsage, // reference passed and updated inside
+ cstMaxLinesForTimedEvents,
+ startIndex2,
+ cstLinesReserved2 );
+ }
+
+ /**
+ * Upcoming today timed events.
+ */
+ PublishTodayTimedItemsForArrayL(
+ iEventData->Upcoming2HrsArray(),
+ publishIndex, // reference passed and updated inside
+ lineUsage, // reference passed and updated inside
+ cstMaxLinesForTimedEvents );
+
+ PublishTodayTimedItemsForArrayL(
+ iEventData->UpcomingArray(),
+ publishIndex, // reference passed and updated inside
+ lineUsage, // reference passed and updated inside
+ cstMaxLinesForTimedEvents );
+
+ /**
+ * 3) Non timed events only need combined icon and subject/location string.
+ * Other fields are cleaned.
+ */
+ for( TInt nonTimedIndex = 0; ( nonTimedIndex < iEventData->NonTimedEventArray().Count() ) &&
+ ( lineUsage + cstSpaceTakenByNonTimed <= iActualLinesInUse )
+ ; ++nonTimedIndex )
+ {
+ if( !( CompareChecksums( publishIndex,
+ iEventData->NonTimedEventArray()[nonTimedIndex]->Checksum() ) ) )
+ {
+ PublishIconL( iEventData->NonTimedEventArray()[nonTimedIndex]->IconId(), publishIndex );
+
+ Clean( EAICalendarPlugin2EventTextSecondLine, publishIndex );
+
+ PublishNonTimedEventTexts( *iEventData->NonTimedEventArray()[nonTimedIndex],
+ publishIndex );
+ }
+ lineUsage += cstSpaceTakenByNonTimed;
+ ++publishIndex;
+ focusDataArray.Append( iEventData->NonTimedEventArray()[nonTimedIndex]->FocusData() );
+ }
+
+ if( iConstantData->iDaysToHandleAsNotToday > 0 )
+ {
+ /**
+ * 4) Future items
+ */
+ PublishFutureItemsForArrayL(
+ iEventData->TomorrowEventArray(),
+ publishIndex, // reference passed and updated inside
+ lineUsage, // reference passed and updated inside
+ iActualLinesInUse);
+
+ PublishFutureItemsForArrayL(
+ iEventData->NotTodayItemArray(),
+ publishIndex, // reference passed and updated inside
+ lineUsage, // reference passed and updated inside
+ iActualLinesInUse);
+ }
+
+ /**
+ * 5) Clean the rest
+ */
+ for( ; publishIndex <= iActualLinesInUse; ++publishIndex )
+ {
+ CleanAll( publishIndex );
+
+ TAiCalendarFocusData focusItem;
+ focusItem.iType = EAI2CalOpenToday;
+ focusDataArray.Append( focusItem );
+ }
+
+ if ( cleanInfo )
+ {
+ CleanInfo();
+ }
+
+ if( ( iPublishedDataStore.Count() == 0 ) ||
+ ( iPublishedDataStore.Count() != iNewCollectedDataStore.Count() ) )
+ {
+ iPublishedDataStore.Reset();
+ for( TInt i = 0; i < iNewCollectedDataStore.Count(); ++i )
+ {
+ iPublishedDataStore.Append( iNewCollectedDataStore[i] );
+ }
+ iCurrentObserver->Commit( reinterpret_cast<TInt32>(this) );
+ }
+ else
+ {
+ iCurrentObserver->CancelTransaction( reinterpret_cast<TInt32>(this) );
+ }
+
+ iEventData->ClearDataArrays();
+
+ }
+
+void CAICalendarPlugin2::PublishTodayTimedItemsForArrayL(
+ RPointerArray<CAiCalendarPlugin2EventItem>& aArray,
+ TInt& aPublishIndex,
+ TInt& aLineUsage,
+ TInt aMaxLinesAvailable,
+ TInt aArrayOffset,
+ TInt aExtraLineReservation )
+ {
+ TInt spaceTakenByNext = GetTimedItemLineNeed( aArray, aArrayOffset );
+ if( ( ( &aArray == &iEventData->OngoingArray() ) && !iConstantData->iUseAlternatePublish ) ||
+ &aArray == &iEventData->Ongoing30MinArray() )
+ {
+ spaceTakenByNext =iEventData->SpaceTakenByTimedEvent();
+ }
+ TInt spaceTaken = aLineUsage;
+ TInt index = 0;
+ for( ; ( ( index + aArrayOffset ) < aArray.Count() ) &&
+ ( ( iActualLinesInUse - ( aExtraLineReservation + spaceTakenByNext + spaceTaken ) ) >= 0 ) &&
+ ( ( aLineUsage + spaceTakenByNext ) <= aMaxLinesAvailable )
+ ; ++index )
+ {
+ const TInt pbIndex = index + aArrayOffset;
+
+ if( !( CompareChecksums( aPublishIndex, aArray[index]->Checksum(), ETrue ) ) )
+ {
+ PublishIconL( aArray[pbIndex]->IconId(), aPublishIndex );
+ }
+
+ if( aArray[pbIndex]->Type() == EPluginItemOlderOnGoingEvent &&
+ iConstantData->iUseAlternatePublish )
+ {
+ if( !( CompareChecksums( aPublishIndex, aArray[index]->Checksum() ) ) )
+ {
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2EventTextSecondLine,
+ aPublishIndex );
+
+ PublishTimedEventTexts( *aArray[pbIndex], aPublishIndex, aLineUsage );
+ }
+ else
+ {
+ // increase line usage only
+ aLineUsage += spaceTakenByNext;
+ }
+ }
+ else
+ {
+ if( !( CompareChecksums( aPublishIndex, aArray[index]->Checksum() ) ) )
+ {
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2EventTextFirstLine,
+ aPublishIndex );
+
+ PublishTimeRelatedTexts( *aArray[pbIndex], aPublishIndex, aLineUsage );
+ }
+ else
+ {
+ // increase line usage only
+ aLineUsage += spaceTakenByNext;
+ }
+ }
+
+ ++aPublishIndex;
+ iEventData->FocusDataArray().Append( aArray[pbIndex]->FocusData() );
+ spaceTaken += spaceTakenByNext;
+ if( ( ( &aArray == &iEventData->OngoingArray() ) && !iConstantData->iUseAlternatePublish ) ||
+ &aArray == &iEventData->Ongoing30MinArray() )
+ {
+ spaceTakenByNext =iEventData->SpaceTakenByTimedEvent();
+ }
+ else
+ {
+ spaceTakenByNext = GetTimedItemLineNeed( aArray, pbIndex + 1 );
+ }
+ }
+ }
+
+void CAICalendarPlugin2::PublishFutureItemsForArrayL(
+ RPointerArray<CAiCalendarPlugin2EventItem>& aArray,
+ TInt& aPublishIndex,
+ TInt& aLineUsage,
+ TInt aMaxLinesAvailable )
+ {
+ TInt index = 0;
+
+ TInt spaceTakenByNext = GetTimedItemLineNeed( aArray, index );
+
+ for( ; ( index < aArray.Count() )
+ ; ++index )
+ {
+ if( !( ( aLineUsage + spaceTakenByNext ) <= aMaxLinesAvailable ) )
+ {
+ spaceTakenByNext = GetTimedItemLineNeed( aArray, index + 1 );
+ continue;
+ }
+ if( !( CompareChecksums( aPublishIndex, aArray[index]->Checksum(), ETrue ) ) )
+ {
+ PublishIconL( aArray[index]->IconId(), aPublishIndex );
+ }
+
+ if( aArray[index]->Type() == EPluginItemMeeting && iConstantData->iUseAlternatePublish )
+ {
+ if( !( CompareChecksums( aPublishIndex, aArray[index]->Checksum() ) ) )
+ {
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2EventTextSecondLine,
+ aPublishIndex );
+
+ PublishTimedEventTexts( *aArray[index], aPublishIndex, aLineUsage );
+ }
+ else
+ {
+ // increase line usage only
+ aLineUsage += spaceTakenByNext;
+ }
+ }
+ else if( aArray[index]->Type() == EPluginItemMeeting )
+ {
+ if( !( CompareChecksums( aPublishIndex, aArray[index]->Checksum() ) ) )
+ {
+ PublishTimeRelatedTexts( *aArray[index], aPublishIndex, aLineUsage );
+ }
+ else
+ {
+ // increase line usage only
+ aLineUsage += spaceTakenByNext;
+ }
+ }
+ else
+ {
+ if( !( CompareChecksums( aPublishIndex, aArray[index]->Checksum() ) ) )
+ {
+ Clean( EAICalendarPlugin2EventTextSecondLine, aPublishIndex );
+
+ PublishNonTimedEventTexts( *aArray[index],
+ aPublishIndex );
+ }
+ // increase line usage
+ aLineUsage += iEventData->SpaceTakenByNonTimedEvent();
+ }
+
+ ++aPublishIndex;
+
+ iEventData->FocusDataArray().Append( aArray[index]->FocusData() );
+ spaceTakenByNext = GetTimedItemLineNeed( aArray, index + 1 );
+ }
+
+ }
+
+
+void CAICalendarPlugin2::CleanAll( TInt aIndex )
+ {
+ CleanTimeRelated( aIndex );
+ CleanTexts( aIndex );
+ CleanIcon( aIndex );
+ }
+
+void CAICalendarPlugin2::CleanTimeRelated( TInt aIndex )
+ {
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2EventTextFirstLine,
+ aIndex );
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2EventTimeStart,
+ aIndex );
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2EventTimeEnd,
+ aIndex );
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2TimeStartAndSubject,
+ aIndex);
+ }
+
+void CAICalendarPlugin2::CleanTexts( TInt aIndex )
+ {
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2EventTextSecondLine,
+ aIndex );
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2EventSubject,
+ aIndex );
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2EventLocation,
+ aIndex );
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2TimeStartAndSubject,
+ aIndex);
+ }
+
+void CAICalendarPlugin2::CleanIcon( TInt aIndex )
+ {
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2EventIcon,
+ aIndex );
+ }
+
+void CAICalendarPlugin2::Clean( TInt aItem, TInt aIndex )
+ {
+ iCurrentObserver->Clean( *this,
+ aItem,
+ aIndex );
+ }
+
+void CAICalendarPlugin2::CleanInfo()
+ {
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2InfoText,
+ 0);
+
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2InfoIcon,
+ 0);
+ }
+
+void CAICalendarPlugin2::PublishTimedEventTexts( CAiCalendarPlugin2EventItem& aData,
+ TInt aIndex,
+ TInt& aLineUsage )
+ {
+ // here the first line - second line mix is intentional. see below comment
+ if( aData.FirstLineText() != KNullDesC )
+ {
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTextFirstLine,
+ aData.FirstLineText(),
+ aIndex );
+ ++aLineUsage;
+ }
+ else
+ {
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2EventTextFirstLine,
+ aIndex );
+ }
+
+ // Separate field publishes
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTimeStart,
+ aData.StartTimeText(),
+ aIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTimeEnd,
+ aData.EndTimeText(),
+ aIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventSubject,
+ aData.SubjectText(),
+ aIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventLocation,
+ aData.LocationText(),
+ aIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2TimeStartAndSubject,
+ aData.SubjectTimeString( ETrue ),
+ aIndex);
+ }
+
+void CAICalendarPlugin2::PublishNonTimedEventTexts( CAiCalendarPlugin2EventItem& aData,
+ TInt aIndex )
+ {
+ // here the first line - second line mix is intentional. see above comment
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTextFirstLine,
+ aData.SecondLineText(),
+ aIndex );
+
+ // Separate field publishes
+ if( aData.StartTimeText().Length() > 0 )
+ {
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTimeStart,
+ aData.StartTimeText(),
+ aIndex );
+ }
+ else
+ {
+ Clean( EAICalendarPlugin2EventTimeStart, aIndex );
+ }
+ if( aData.EndTimeText().Length() > 0 )
+ {
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTimeEnd,
+ aData.EndTimeText(),
+ aIndex );
+ }
+ else
+ {
+ Clean( EAICalendarPlugin2EventTimeEnd, aIndex );
+ }
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventSubject,
+ aData.SubjectText(),
+ aIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventLocation,
+ aData.LocationText(),
+ aIndex );
+
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2TimeStartAndSubject,
+ aData.SubjectTimeString( ETrue ),
+ aIndex );
+ }
+
+void CAICalendarPlugin2::PublishTimeRelatedTexts( CAiCalendarPlugin2EventItem& aData,
+ TInt aIndex,
+ TInt& aLineUsage )
+ {
+ // here the first line - second line mix is intentional. see above comments
+ if( aData.SecondLineText() != KNullDesC )
+ {
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTextSecondLine,
+ aData.SecondLineText(),
+ aIndex );
+ ++aLineUsage;
+ }
+ else if( aData.FirstLineText() != KNullDesC )
+ {
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTextSecondLine,
+ aData.FirstLineText(),
+ aIndex );
+ ++aLineUsage;
+ }
+ else
+ {
+ iCurrentObserver->Clean( *this,
+ EAICalendarPlugin2EventTextSecondLine,
+ aIndex );
+ }
+
+ // Separate field publishes
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTimeStart,
+ aData.StartTimeText(),
+ aIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventTimeEnd,
+ aData.EndTimeText(),
+ aIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventSubject,
+ aData.SubjectText(),
+ aIndex );
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2EventLocation,
+ aData.LocationText(),
+ aIndex );
+
+ iCurrentObserver->Publish( *this,
+ EAICalendarPlugin2TimeStartAndSubject,
+ aData.SubjectTimeString( ETrue ),
+ aIndex );
+ }
+
+void CAICalendarPlugin2::PublishIconL( const TInt aIconId, TInt aIndex, TInt aContent )
+ {
+ CGulIcon* icon = NULL;
+ CFbsBitmap* bitmap3 = NULL;
+ CFbsBitmap* mask3 = NULL;
+ TAknsItemID skinIconId;
+
+ HBufC* bitmapFile = iCalendarIconFileName;
+
+ TInt bitmapId = 0;
+ TInt maskId = 0;
+
+ // Map events to MBM id's and load from correct file
+ switch( aIconId )
+ {
+ case EAICalendarPlugin2IconAppt:
+ case EAICalendarPlugin2IconMeetingAccepted:
+ case EAICalendarPlugin2IconMeetingNotAnswered:
+ case EAICalendarPlugin2IconMeetingTentative:
+ {
+ skinIconId.Set( KAknsIIDQgnIndiCdrMeeting );
+ bitmapId = EMbmCalendarQgn_indi_cdr_meeting;
+ maskId = EMbmCalendarQgn_indi_cdr_meeting_mask;
+ break;
+ }
+ case EAICalendarPlugin2IconTodo: // Uncompleted To-Do icon
+ {
+ skinIconId.Set( KAknsIIDQgnIndiCdrTodo );
+ bitmapId = EMbmCalendarQgn_indi_cdr_todo;
+ maskId = EMbmCalendarQgn_indi_cdr_todo_mask;
+ break;
+ }
+ case EAICalendarPlugin2IconMemo: // Memo icon
+ {
+ skinIconId.Set( KAknsIIDQgnIndiCdrReminder );
+ bitmapId = EMbmCalendarQgn_indi_cdr_reminder;
+ maskId = EMbmCalendarQgn_indi_cdr_reminder_mask;
+ break;
+ }
+ case EAICalendarPlugin2IconAnniv: // Anniversary icon
+ {
+ skinIconId.Set( KAknsIIDQgnIndiCdrBirthday );
+ bitmapId = EMbmCalendarQgn_indi_cdr_birthday;
+ maskId = EMbmCalendarQgn_indi_cdr_birthday_mask;
+ break;
+ }
+ case EAICalendarPlugin2NoMoreEventsForToday:
+ case EAICalendarPlugin2NoEventsForToday:
+ {
+ skinIconId.Set( KAknsIIDQgnIndiAiCale );
+ bitmapId = EMbmAicalendarplugin2Qgn_indi_ai_cale;
+ maskId = EMbmAicalendarplugin2Qgn_indi_ai_cale_mask;
+ bitmapFile = iPluginIconFileName;
+ break;
+ }
+ default:
+ {
+ return;
+ }
+ }
+
+ CreateBitmapSkinnedIconL( skinIconId,
+ *bitmapFile,
+ bitmapId,
+ maskId,
+ bitmap3, mask3 );
+
+ // icon will own the bitmaps
+ CleanupStack::PushL( bitmap3 );
+ CleanupStack::PushL( mask3 );
+ icon = CGulIcon::NewL( bitmap3, mask3 );
+ CleanupStack::Pop( 2, bitmap3 );
+
+ TInt err = iCurrentObserver->PublishPtr( *this,
+ aContent,
+ icon,
+ aIndex );
+ if( err != KErrNone )
+ {
+ delete icon;
+ }
+ }
+
+void CAICalendarPlugin2::PublishIconL( const TInt aIconId, TInt aIndex )
+ {
+ PublishIconL( aIconId, aIndex, EAICalendarPlugin2EventIcon );
+ }
+
+TBool CAICalendarPlugin2::CompareChecksums(
+ TInt aChecksumIndex,
+ TInt aItemChecksum,
+ TBool aIsIcon )
+ {
+ if( !aIsIcon )
+ {
+ iNewCollectedDataStore.Append( aItemChecksum );
+ }
+ if( ( iPublishedDataStore.Count() > aChecksumIndex ) &&
+ ( iPublishedDataStore[aChecksumIndex] == aItemChecksum ) )
+ {
+ // checksum match
+ return ETrue;
+ }
+ iPublishedDataStore.Reset();
+ return EFalse;
+ }
+
+// ======== GLOBAL FUNCTIONS ========
+
+// Return an instance of the proxy table.
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
+ {
+ aTableCount = sizeof( ImplementationTable ) / sizeof( TImplementationProxy );
+ return ImplementationTable;
+ }
+
+// End of File