--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrgui/mrfieldbuilderpluginextension/src/cesmrresponsefield.cpp Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,695 @@
+/*
+* 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: Meeting Request viewer response field implementation
+*
+*/
+#include "cesmrresponsefield.h"
+#include "cesmrresponseitem.h"
+#include "mesmrresponseobserver.h"
+#include "mesmrmeetingrequestentry.h"
+#include "cesmrconflictpopup.h"
+#include "nmrlayoutmanager.h"
+#include "esmrhelper.h"
+#include "cfsmailcommon.h"
+
+#include "cesmrlistquery.h"
+#include <esmrgui.rsg>
+#include <StringLoader.h>
+#include <caluser.h>
+
+// DEBUG
+#include "emailtrace.h"
+
+/// Unnamed namespace for local definitions
+namespace
+ {
+ const TInt KConflictItemIndex( 0 );
+ const TInt KExtraInfoItemIndex( 1 ); //"Request is out of date" "Please respond", ect
+ } // namespace
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// CESMRResponseField
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+// ======== MEMBER FUNCTIONS ========
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::NewL
+// -----------------------------------------------------------------------------
+//
+CESMRResponseField* CESMRResponseField::NewL(
+ MESMRResponseObserver* aResponseObserver )
+ {
+ FUNC_LOG;
+ CESMRResponseField* self = new (ELeave) CESMRResponseField(aResponseObserver);
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::~CESMRResponseField
+// -----------------------------------------------------------------------------
+//
+CESMRResponseField::~CESMRResponseField()
+ {
+ FUNC_LOG;
+ iResponseItemArray.ResetAndDestroy();
+ delete iConfPopup;
+
+ if( iESMRStaticAccessed )
+ {
+ iESMRStatic.Close();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::CESMRResponseField
+// -----------------------------------------------------------------------------
+//
+CESMRResponseField::CESMRResponseField(MESMRResponseObserver* aResponseObserver)
+: iResponseObserver(aResponseObserver), iSelectionIndex( 0 ),
+ iESMRStaticAccessed(EFalse), iConflicted(EFalse)
+ {
+ FUNC_LOG;
+ SetFieldId( EESMRFieldResponseArea );
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CESMRResponseField::ConstructL()
+ {
+ FUNC_LOG;
+
+ CESMRField::ConstructL( NULL );
+
+ // Add pls resopond item to this field.
+ CESMRResponseItem* responseItem =
+ CESMRResponseItem::NewLC( EESMRCmdUndefined, KNullDesC, EFalse );
+ responseItem->SetContainerWindowL( *this );
+ iResponseItemArray.AppendL( responseItem );
+ CleanupStack::Pop( responseItem );
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::InitializeL
+// -----------------------------------------------------------------------------
+//
+void CESMRResponseField::InitializeL()
+ {
+ FUNC_LOG;
+ TAknLayoutText layout =
+ NMRLayoutManager::GetLayoutText(
+ Rect(), NMRLayoutManager::EMRTextLayoutCheckboxEditor );
+ SetFont( layout.Font() );
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::CountComponentControls
+// -----------------------------------------------------------------------------
+//
+TInt CESMRResponseField::CountComponentControls() const
+ {
+ FUNC_LOG;
+ return iResponseItemArray.Count();
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::ComponentControl
+// -----------------------------------------------------------------------------
+//
+CCoeControl* CESMRResponseField::ComponentControl( TInt aInd ) const
+ {
+ FUNC_LOG;
+ return iResponseItemArray[aInd];
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::SizeChanged
+// -----------------------------------------------------------------------------
+//
+void CESMRResponseField::SizeChanged()
+ {
+ FUNC_LOG;
+ TInt count( iResponseItemArray.Count() );
+ TRect parentRect( Rect() );
+ TRect rect;
+ for( TInt i = 0; i < count; ++i )
+ {
+ TAknLayoutRect choiceLayoutRect =
+ NMRLayoutManager::GetFieldRowLayoutRect( parentRect, i + 1 );
+ rect = parentRect;
+ // Move the row down then it will be drawn to correct position.
+ // controlIndex+1 tells the fields index.
+ TInt movement = choiceLayoutRect.Rect().Height();
+ rect.Move( 0, movement * i );
+
+ TInt leftMargin = choiceLayoutRect.Rect().iTl.iX;
+ TInt rightMargin = choiceLayoutRect.Rect().iBr.iX;
+ leftMargin -= parentRect.iTl.iX;
+ rightMargin -= parentRect.iTl.iX;
+
+ AknLayoutUtils::LayoutControl(
+ ComponentControl( i ),
+ rect,
+ choiceLayoutRect.Color().Value(),
+ leftMargin,
+ 0,
+ rightMargin,
+ choiceLayoutRect.Rect().iBr.iY,
+ choiceLayoutRect.Rect().Width(),
+ choiceLayoutRect.Rect().Height() );
+ }
+ RecordField();
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::MinimumSize
+// -----------------------------------------------------------------------------
+//
+TSize CESMRResponseField::MinimumSize()
+ {
+ TRect rect( Rect() );
+
+ // Topic field
+ TAknLayoutRect row1LayoutRect(
+ NMRLayoutManager::GetFieldRowLayoutRect( rect, 1 ) );
+ rect = row1LayoutRect.Rect();
+
+ TInt rowCount( iResponseItemArray.Count() );
+ TInt height( rect.Height() * rowCount );
+ return TSize( Parent()->Size().iWidth, height );
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::OfferKeyEventL
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CESMRResponseField::OfferKeyEventL( const TKeyEvent& aKeyEvent,
+ TEventCode aType )
+ {
+ FUNC_LOG;
+ TKeyResponse consumed( EKeyWasNotConsumed );
+
+ if ( aType == EEventKey )
+ {
+ if ( iConflicted )
+ {
+ if ( aKeyEvent.iScanCode == EStdKeyUpArrow && iSelectionIndex > 0 )
+ {
+ iResponseItemArray[KExtraInfoItemIndex]->RemoveHighlight();
+ iResponseItemArray[KConflictItemIndex]->SetHighlight();
+ iSelectionIndex = KConflictItemIndex;
+ consumed = EKeyWasConsumed;
+ }
+
+ if ( aKeyEvent.iScanCode == EStdKeyDownArrow && iSelectionIndex < iResponseItemArray.Count()-1 )
+ {
+ iResponseItemArray[KConflictItemIndex]->RemoveHighlight();
+ iResponseItemArray[KExtraInfoItemIndex]->SetHighlight();
+ iSelectionIndex = KExtraInfoItemIndex;
+ consumed = EKeyWasConsumed;
+ }
+ }
+ }
+
+ if ( consumed == EKeyWasConsumed )
+ {
+ DrawDeferred();
+ }
+
+ return consumed;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::FocusChanged
+// -----------------------------------------------------------------------------
+//
+void CESMRResponseField::FocusChanged( TDrawNow /*aDrawNow*/ )
+ {
+ FUNC_LOG;
+ if ( iConflicted && !iPointEvent )
+ {
+ // set the default value for iSelectionIndex, depend on iPreItemIndex
+ if ( PreItemIndex() <= CurrentItemIndex() )
+ {
+ iSelectionIndex = 0;
+ }
+ else
+ {
+ iSelectionIndex = 1;
+ }
+ }
+ // Focus received
+ if ( IsFocused() && iSelectionIndex < iResponseItemArray.Count() )
+ {
+ if( !iPointEvent )
+ {
+ // By default, highlight the first item
+ iResponseItemArray[iSelectionIndex]->SetHighlight();
+ DrawDeferred();
+ }
+ }
+ else // Focus lost remove highlight
+ {
+ for( TInt i = 0; i < iResponseItemArray.Count() ; i++ )
+ {
+ iResponseItemArray[i]->RemoveHighlight();
+ }
+ }
+ iPointEvent = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::InternalizeL
+// -----------------------------------------------------------------------------
+//
+void CESMRResponseField::InternalizeL( MESMRCalEntry& aEntry )
+ {
+ FUNC_LOG;
+ iNormalResponse = EFalse;
+ iRemoveResponse = EFalse;
+ MESMRMeetingRequestEntry* entry = NULL;
+ if ( MESMRCalEntry::EESMRCalEntryMeetingRequest == aEntry.Type() )
+ {
+ entry = static_cast<MESMRMeetingRequestEntry*>(&aEntry);
+ }
+ else
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ // Judge if there is any conflicts with other existed event.
+ iConflicted = entry->Conflicts();
+ if ( iConflicted )
+ {
+ // Construct the item to show conflicts info, and insert it to the beginning of array
+ CESMRResponseItem* conflictItem =
+ CESMRResponseItem::NewLC( EESMRCmdUndefined, KNullDesC, EFalse );
+ conflictItem->SetContainerWindowL( *this );
+ iResponseItemArray.Insert( conflictItem, 0 );
+ CleanupStack::Pop( conflictItem );
+
+ HBufC* conflictString;
+ conflictString = StringLoader::LoadLC(
+ R_QTN_MEET_REQ_RESPONSE_CONFLICT , iEikonEnv );
+ // Show prompt conflict dialog
+ iConfPopup = CESMRConflictPopup::NewL(aEntry);
+
+ if ( iResponseItemArray.Count() > 0 )
+ {
+ iResponseItemArray[KConflictItemIndex]->SetUnderlineL( ETrue );
+ iResponseItemArray[KConflictItemIndex]->SetTextL( conflictString->Des() );
+ }
+ CleanupStack::PopAndDestroy( conflictString );
+ }
+
+
+ // Set other info, for example, "please respond", "Request is out of date",
+ // "Meeting has been canceled" ......
+ MESMRMeetingRequestEntry::TESMREntryInfo attendeeInfo = entry->EntryAttendeeInfoL();
+ HBufC* stringholder;
+ switch( attendeeInfo )
+ {
+ case MESMRMeetingRequestEntry::EESMREntryInfoOutOfDate:
+ {
+ stringholder = StringLoader::LoadLC(
+ R_QTN_MEET_REQ_RESPONSE_OUT_OF_DATE , iEikonEnv );
+ if( entry->IsOpenedFromMail() )
+ {
+ iRemoveResponse = ETrue;
+ }
+ break;
+ }
+
+ case MESMRMeetingRequestEntry::EESMREntryInfoCancelled:
+ {
+ stringholder = StringLoader::LoadLC(
+ R_QTN_MEET_REQ_RESPONSE_CANCELLED , iEikonEnv );
+ HandleCancelledEventItemsL( aEntry );
+ if( entry->IsOpenedFromMail() )
+ {
+ iRemoveResponse = ETrue;
+ }
+ break;
+ }
+
+ case MESMRMeetingRequestEntry::EESMREntryInfoAccepted:
+ {
+ stringholder = StringLoader::LoadLC(
+ R_QTN_MEET_REQ_RESPOND_ACCEPTED , iEikonEnv );
+ iNormalResponse = ETrue;
+ break;
+ }
+
+ case MESMRMeetingRequestEntry::EESMREntryInfoTentativelyAccepted:
+ {
+ stringholder = StringLoader::LoadLC(
+ R_QTN_MEET_REQ_RESPOND_TENTATIVE , iEikonEnv );
+ iNormalResponse = ETrue;
+ break;
+ }
+
+ case MESMRMeetingRequestEntry::EESMREntryInfoDeclined:
+ {
+ stringholder = StringLoader::LoadLC(
+ R_QTN_MEET_REQ_RESPOND_DECLINED , iEikonEnv );
+ iNormalResponse = ETrue;
+ break;
+ }
+
+ case MESMRMeetingRequestEntry::EESMREntryInfoOccursInPast:
+ {
+ stringholder = StringLoader::LoadLC(
+ R_QTN_MEET_REQ_RESPONSE_OCCURS_PAST , iEikonEnv );
+ if( entry->IsOpenedFromMail() )
+ {
+ iRemoveResponse = ETrue;
+ }
+ break;
+ }
+
+ case MESMRMeetingRequestEntry::EESMREntryInfoNormal:
+ {
+ stringholder = StringLoader::LoadLC(
+ R_QTN_MEET_REQ_RESPONSE_PLEASE_RESPOND , iEikonEnv );
+ iNormalResponse = ETrue;
+ break;
+ }
+
+ default:
+ stringholder = StringLoader::LoadLC(
+ R_QTN_MEET_REQ_RESPONSE_PLEASE_RESPOND , iEikonEnv );
+ iNormalResponse = ETrue;
+ break;
+ }
+
+ TInt repondItemIndex( 0 );
+ if ( iConflicted && iResponseItemArray.Count() == 2 )
+ {
+ repondItemIndex = 1;
+ }
+
+ iResponseItemArray[repondItemIndex]->SetUnderlineL( ETrue );
+ iResponseItemArray[repondItemIndex]->SetTextL( stringholder->Des() );
+
+ SizeChanged();
+ CleanupStack::PopAndDestroy( stringholder );
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::AddObserver
+// -----------------------------------------------------------------------------
+//
+void CESMRResponseField::AddObserver( MESMRResponseObserver* aResponseObserver )
+ {
+ FUNC_LOG;
+ iResponseObserver = aResponseObserver;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::SetFont
+// -----------------------------------------------------------------------------
+//
+void CESMRResponseField::SetFont( const CFont* aFont )
+ {
+ FUNC_LOG;
+ iFont = aFont;
+ // Set font for the response items (conflict and extrainfo item )
+ TInt itemCount = iResponseItemArray.Count();
+ for( TInt i = 0; i < itemCount; i++ )
+ {
+ iResponseItemArray[i]->SetFont( aFont );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::ItemSelectedL
+// -----------------------------------------------------------------------------
+//
+TBool CESMRResponseField::ItemSelectedL()
+ {
+ FUNC_LOG;
+ TBool selected( EFalse );
+ TInt ret( KErrCancel );
+
+ if ( iConflicted )
+ {
+ if ( iSelectionIndex == 0 )
+ {
+ if ( iConfPopup )
+ {
+ iConfPopup->ShowPopup();
+ }
+ }
+
+ if ( KExtraInfoItemIndex == iSelectionIndex )
+ {
+ if ( iNormalResponse )
+ {
+ // Try to send response
+ CESMRListQuery* query =
+ CESMRListQuery::NewL( CESMRListQuery::EESMRNormalResponseQuery );
+ CleanupStack::PushL( query );
+ ret = query->ExecuteLD();
+ CleanupStack::Pop( query );
+ }
+ if ( iRemoveResponse )
+ {
+ CESMRListQuery* query =
+ CESMRListQuery::NewL( CESMRListQuery::EESMRRemoveResponseQuery );
+ CleanupStack::PushL( query );
+ ret = query->ExecuteLD();
+ CleanupStack::Pop( query );
+ }
+ }
+ }
+ else
+ {
+ if ( KConflictItemIndex == iSelectionIndex )
+ {
+ if ( iNormalResponse )
+ {
+ // Try to send response
+ CESMRListQuery* query =
+ CESMRListQuery::NewL( CESMRListQuery::EESMRNormalResponseQuery );
+ CleanupStack::PushL( query );
+ ret = query->ExecuteLD();
+ CleanupStack::Pop( query );
+ }
+ if ( iRemoveResponse )
+ {
+ CESMRListQuery* query =
+ CESMRListQuery::NewL( CESMRListQuery::EESMRRemoveResponseQuery );
+ CleanupStack::PushL( query );
+ ret = query->ExecuteLD();
+ CleanupStack::Pop( query );
+ }
+ }
+ }
+
+ if ( KErrCancel != ret )
+ {
+ NotifyEventAsyncL( ret );
+ }
+
+ return selected;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::HandleCancelledEventItemsL
+// -----------------------------------------------------------------------------
+//
+void CESMRResponseField::HandleCancelledEventItemsL( MESMRCalEntry& aEntry )
+ {
+ FUNC_LOG;
+ CCalEntry& entry = aEntry.Entry();
+ CCalUser* calUser = entry.PhoneOwnerL();
+ TPtrC addr = ESMRHelper::AddressWithoutMailtoPrefix( calUser->Address() );
+
+ iESMRStatic.ConnectL();
+ iESMRStaticAccessed = ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::ExecuteGenericCommandL
+// -----------------------------------------------------------------------------
+//
+TBool CESMRResponseField::ExecuteGenericCommandL( TInt aCommand )
+ {
+ FUNC_LOG;
+ TBool isUsed( EFalse );
+
+ switch ( aCommand )
+ {
+ case EAknSoftkeySelect:
+ case EAknCmdOpen:
+ {
+ ItemSelectedL();
+ isUsed = ETrue;
+ break;
+ }
+ default:
+ {
+ isUsed = CESMRField::ExecuteGenericCommandL( aCommand );
+ break;
+ }
+ }
+
+ return isUsed;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::SetOutlineFocusL
+// -----------------------------------------------------------------------------
+//
+void CESMRResponseField::SetOutlineFocusL( TBool aFocus )
+ {
+ FUNC_LOG;
+ CESMRField::SetOutlineFocusL( aFocus );
+
+ if ( aFocus )
+ {
+ SetMiddleSoftKeyVisible( ETrue );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRResponseField::HandleSingletapEventL
+// -----------------------------------------------------------------------------
+//
+TBool CESMRResponseField::HandleSingletapEventL( const TPoint& aPosition )
+ {
+ FUNC_LOG;
+
+ TBool handled( EFalse );
+ if( !iLongTapEventConsumed )
+ {
+ handled = HandleTapEventL( aPosition );
+ }
+ iLongTapEventConsumed = EFalse;
+
+ return handled;
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRResponseField::HandleLongtapEventL
+// ---------------------------------------------------------------------------
+//
+void CESMRResponseField::HandleLongtapEventL( const TPoint& aPosition )
+ {
+ FUNC_LOG;
+ HandleTapEventL( aPosition );
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRResponseField::HandletapEventL
+// ---------------------------------------------------------------------------
+//
+TBool CESMRResponseField::HandleTapEventL( const TPoint& aPosition )
+ {
+ TBool handled = EFalse;
+ TInt ret = KErrCancel;
+
+ if ( Rect().Contains( aPosition ) )
+ {
+ HandleTactileFeedbackL();
+ if ( iConflicted )
+ {
+ TRect conflictItemRect = iResponseItemArray[KConflictItemIndex]->Rect();
+ if ( conflictItemRect.Contains( aPosition ) )
+ {
+ iResponseItemArray[KExtraInfoItemIndex]->RemoveHighlight();
+ iResponseItemArray[KConflictItemIndex]->SetHighlight();
+ iSelectionIndex = KConflictItemIndex;
+ if ( iConfPopup )
+ {
+ iLongTapEventConsumed = ETrue;
+ iConfPopup->ShowPopup();
+ }
+ }
+ else
+ {
+ iResponseItemArray[KConflictItemIndex]->RemoveHighlight();
+ iResponseItemArray[KExtraInfoItemIndex]->SetHighlight();
+ iSelectionIndex = KExtraInfoItemIndex;
+ DrawDeferred();
+ if ( iNormalResponse )
+ {
+ CESMRListQuery* query =
+ CESMRListQuery::NewL( CESMRListQuery::EESMRNormalResponseQuery );
+ CleanupStack::PushL( query );
+ // Use this flag to avoid the same event be handled by
+ // HandleSingletapEventL() when HandleLongtapEventL().
+ iLongTapEventConsumed = ETrue;
+ ret = query->ExecuteLD();
+ CleanupStack::Pop( query );
+ }
+ if ( iRemoveResponse )
+ {
+ CESMRListQuery* query =
+ CESMRListQuery::NewL( CESMRListQuery::EESMRRemoveResponseQuery );
+ CleanupStack::PushL( query );
+ iLongTapEventConsumed = ETrue;
+ ret = query->ExecuteLD();
+ CleanupStack::Pop( query );
+ }
+ }
+ }
+ else
+ {
+ iResponseItemArray[0]->SetHighlight();
+ if ( iNormalResponse )
+ {
+ CESMRListQuery* query =
+ CESMRListQuery::NewL( CESMRListQuery::EESMRNormalResponseQuery );
+ CleanupStack::PushL( query );
+ iLongTapEventConsumed = ETrue;
+ ret = query->ExecuteLD();
+ CleanupStack::Pop( query );
+ }
+
+ if ( iRemoveResponse )
+ {
+ CESMRListQuery* query =
+ CESMRListQuery::NewL( CESMRListQuery::EESMRRemoveResponseQuery );
+ CleanupStack::PushL( query );
+ iLongTapEventConsumed = ETrue;
+ ret = query->ExecuteLD();
+ CleanupStack::Pop( query );
+ }
+ }
+
+ DrawDeferred();
+
+ handled = ETrue;
+ iPointEvent = ETrue;
+
+ if ( KErrCancel != ret )
+ {
+ NotifyEventAsyncL( ret );
+ }
+
+ }
+
+ return handled;
+ }
+
+// EOF
+