phonebookui/Phonebook2/GroupExtension/src/CPguSendMessageGroupCmd.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
child 68 9da50d567e3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/GroupExtension/src/CPguSendMessageGroupCmd.cpp	Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,684 @@
+/*
+* Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Phonebook 2 Group UI Extension send message command.
+*
+*/
+
+
+// INCLUDE FILES
+#include "CPguSendMessageGroupCmd.h"
+#include "CPguUIExtensionPlugin.h"
+
+// Phonebook 2
+#include "MPbk2ProcessDecorator.h"
+#include <MPbk2ContactNameFormatter.h>
+#include <MPbk2ContactUiControl.h>
+#include <MPbk2CommandObserver.h>
+#include <Pbk2UIControls.rsg>
+#include <TPbk2AddressSelectParams.h>
+#include <CPbk2AddressSelect.h>
+#include <MPbk2AppUi.h>
+#include <MPbk2ApplicationServices.h>
+
+// Virtual Phonebook
+#include <VPbkFieldType.hrh>
+#include <CVPbkContactManager.h>
+#include <MVPbkContactLink.h>
+#include <MVPbkContactOperationBase.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkContactFieldTextData.h>
+#include <MVPbkStoreContactFieldCollection.h>
+#include <RVPbkContactFieldDefaultPriorities.h>
+#include <MVPbkContactGroup.h>
+#include <MVPbkContactLinkArray.h>
+
+// System includes
+#include <featmgr.h>
+#include <coemain.h>
+#include <barsread.h>
+#include <sendui.h>
+#include <SenduiMtmUids.h>
+#include <CMessageData.h>
+#include <eikenv.h>
+#include <akntitle.h>
+#include <eikspane.h>
+#include <avkon.hrh>
+#include <avkon.rsg>
+#include <layoutmetadata.cdl.h>
+// Debugging headers
+#include <Pbk2Debug.h>
+
+/// Unnamed namespace for local definitions
+namespace {
+
+const TInt KDefaultTitleFormat = MPbk2ContactNameFormatter::EUseSeparator;
+const TInt KGranularity( 4 );
+
+#ifdef _DEBUG
+
+enum TPanicCode
+    {
+    EPanicUnknownMedia = 1,
+    ERunL_InvalidState,
+    EPanicLogic
+    };
+
+void Panic(TPanicCode aReason)
+    {
+    _LIT(KPanicText, "CPguSendMessageGroupCmd");
+    User::Panic(KPanicText,aReason);
+    }
+
+#endif // _DEBUG
+
+}  /// namespace
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::CPguSendMessageGroupCmd
+// --------------------------------------------------------------------------
+//
+CPguSendMessageGroupCmd::CPguSendMessageGroupCmd(
+        MPbk2ContactUiControl& aUiControl, 
+        CPguUIExtensionPlugin* aPguUIExtensionPlugin ) :
+    CActive( EPriorityIdle ),
+    iUiControl( &aUiControl ),
+    iPguUIExtensionPlugin( aPguUIExtensionPlugin )   
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::~CPguSendMessageGroupCmd
+// --------------------------------------------------------------------------
+//
+CPguSendMessageGroupCmd::~CPguSendMessageGroupCmd()
+    {
+    Cancel();
+    
+    if( iUiControl )
+        {
+        iUiControl->RegisterCommand( NULL );
+        }
+		
+    delete iMessageData;  
+    delete iSelectedContacts;
+    delete iMtmFilter;
+    delete iRetrieveOperation;
+    delete iStoreContact;
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::NewL
+// --------------------------------------------------------------------------
+//
+CPguSendMessageGroupCmd* CPguSendMessageGroupCmd::NewL
+        ( MPbk2ContactUiControl& aUiControl,
+		      CPguUIExtensionPlugin*  aPguUIExtensionPlugin ) 
+    {
+    CPguSendMessageGroupCmd* self =
+        new ( ELeave ) CPguSendMessageGroupCmd( aUiControl,
+            aPguUIExtensionPlugin );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::ConstructL
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::ConstructL()
+    {
+    
+    iUiControl->RegisterCommand( this );
+    
+    iFieldPropertyArray = &Phonebook2::Pbk2AppUi()->
+        ApplicationServices().FieldProperties();
+
+    iMtmFilter = new(ELeave) CArrayFixFlat<TUid>( KGranularity );
+    iMtmFilter->AppendL(KSenduiMtmPostcardUid);  // hide postcard
+
+    iSendingCapabilities.iFlags = TSendingCapabilities::ESupportsEditor;
+    iSelectedContacts = iUiControl->SelectedContactsOrFocusedContactL();
+    iMessageData = CMessageData::NewL();
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::ExecuteLD
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::ExecuteLD()
+    {
+    iCurrentContactLinkIndex = 0;
+    iState = EShowWriteQuery;
+    IssueRequest();
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::AddObserver
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::AddObserver( MPbk2CommandObserver& aObserver )
+    {
+    iCommandObserver = &aObserver;
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::ResetUiControl
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::ResetUiControl(
+        MPbk2ContactUiControl& aUiControl)
+    {
+    if (iUiControl == &aUiControl)
+        {
+        iUiControl = NULL;
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::DoCancel
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::DoCancel()
+    {
+    //Do nothing
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::RunL
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::RunL()
+    {
+    switch ( iState )
+        {
+        case ERetrieving:
+            {
+            if ( iSelectedContacts )
+                {
+                if ( iSelectedContacts->Count() == iCurrentContactLinkIndex )
+                    {
+                    iState = EStarting;
+                    IssueRequest();
+                    }
+                    else
+                    {
+                    RetrieveContactL( iSelectedContacts->At(
+                                            iCurrentContactLinkIndex ) );
+                    iCurrentContactLinkIndex++;
+                    }
+                }
+            else
+                {
+                iState = EStopping;
+                IssueRequest();
+                }
+            break;
+            }
+        case EShowWriteQuery:
+            {
+            iMtmUid = ShowWriteQueryL();
+            if ( iMtmUid == KNullUid )
+                {
+                iState = EStopping;
+                // Disconnect the relationship between control and command
+                iUiControl->RegisterCommand( NULL );
+                iUiControl = NULL;
+                }
+            else
+                {
+                iState = ERetrieving;
+                }
+            IssueRequest();
+            break;
+            }
+        case EResolveGroup:
+            {
+            ResolveGroupL();
+            break;
+            }
+        case EResolveURL:
+            {
+            ResolveUrlL();
+            break;
+            }
+        case EStarting:
+            {
+            DoSendMessageL();
+            break;
+            }
+        case EStopping:
+            {
+            iSendMessage = EFalse;
+            ProcessDismissed( KErrNone );
+            break;
+            }
+        default:
+            {
+            __ASSERT_DEBUG(EFalse, Panic(ERunL_InvalidState));
+            break;
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::RunError
+// --------------------------------------------------------------------------
+//
+TInt CPguSendMessageGroupCmd::RunError( TInt aError )
+    {
+    return FilterErrors( aError );
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::VPbkSingleContactOperationComplete
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::VPbkSingleContactOperationComplete(
+        MVPbkContactOperationBase& aOperation,
+        MVPbkStoreContact* aContact )
+    {
+    if ( &aOperation == iRetrieveOperation )
+        {
+        delete iRetrieveOperation;
+        iRetrieveOperation = NULL;
+
+        // We now have a store contact
+        delete iStoreContact;
+        iStoreContact = aContact;
+
+        if ( iStoreContact->Group() )
+            {
+            iState = EResolveGroup;
+            IssueRequest();
+            }
+        else
+            {
+            iState = EResolveURL;
+            IssueRequest();
+            }
+        }
+    else
+        {
+        IssueStopRequest();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::VPbkSingleContactOperationFailed
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::VPbkSingleContactOperationFailed(
+        MVPbkContactOperationBase& aOperation,
+        TInt aError )
+    {
+    if ( &aOperation == iRetrieveOperation )
+        {
+        delete iRetrieveOperation;
+        iRetrieveOperation = NULL;
+
+        // We cannot get the contact, so we have to
+        // fail. We cannot continue, since this operation
+        // was executed only in case of one contact.
+        ProcessDismissed( aError );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::ShowWriteQueryL
+// --------------------------------------------------------------------------
+//
+TUid CPguSendMessageGroupCmd::ShowWriteQueryL()
+    {
+    TUid uid = Phonebook2::Pbk2AppUi()->ApplicationServices().SendUiL()->
+        ShowTypedQueryL( CSendUi::EWriteMenu, NULL, iSendingCapabilities,
+            iMtmFilter );
+    return uid;
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::RetrieveContactL
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::RetrieveContactL(
+        const MVPbkContactLink& aContactLink )
+    {
+    // Retrieve the actual store contact from the given link
+    iRetrieveOperation = Phonebook2::Pbk2AppUi()->ApplicationServices().
+        ContactManager().RetrieveContactL( aContactLink, *this );
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::DoSendMessageL
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::DoSendMessageL()
+    {
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPguSendMessageGroupCmd::DoSendMessageL() start") );
+
+    if ( iSendMessage )
+        {
+        // Gets current tile pane and saves it to title
+        HBufC* title = NULL;
+        CAknTitlePane* titlePane = NULL;
+        CEikStatusPane *sp = CEikonEnv::Static()->AppUiFactory()->StatusPane();
+        titlePane = STATIC_CAST( CAknTitlePane*, 
+            sp->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) ) );
+        title = titlePane->Text()->AllocLC();
+
+        Phonebook2::Pbk2AppUi()->ApplicationServices().SendUiL()->
+            CreateAndSendMessageL( iMtmUid, iMessageData );
+
+        if( !Layout_Meta_Data::IsLandscapeOrientation() )
+            {
+            sp->SwitchLayoutL( R_AVKON_STATUS_PANE_LAYOUT_USUAL );
+            sp->MakeVisible( ETrue );
+            
+            // Sets title pane for tile which was save
+            titlePane->SetText( title );
+            sp->DrawNow();
+            }
+        else
+            {
+            // Sets title pane for tile which was save
+            titlePane->SetText( title );
+            }
+        CleanupStack::Pop();
+        }
+
+    iState = EStopping;
+    IssueRequest();
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::ResolveGroupL
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::ResolveGroupL()
+    {
+    MVPbkContactLinkArray* linkArray =
+        iStoreContact->Group()->ItemsContainedLC();
+    CleanupStack::Pop(); //linkArray
+
+    delete iSelectedContacts;
+    iSelectedContacts = linkArray;
+    iCurrentContactLinkIndex = 0;
+
+    iState = ERetrieving;
+    IssueRequest();
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::ResolveUrlL
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::ResolveUrlL()
+    {
+    TResourceReader resReader;
+    TUid techTypeUid = Phonebook2::Pbk2AppUi()->ApplicationServices().
+        SendUiL()->TechnologyType( iMtmUid );
+
+    RVPbkContactFieldDefaultPriorities defaults;
+    CleanupClosePushL( defaults );
+
+    TInt resourceId = PrepareAddressSelectL( defaults, techTypeUid );
+    CCoeEnv::Static()->CreateResourceReaderLC( resReader, resourceId );
+
+    TPbk2AddressSelectParams params(
+        *iStoreContact,
+        Phonebook2::Pbk2AppUi()->ApplicationServices().ContactManager(),
+        Phonebook2::Pbk2AppUi()->ApplicationServices().NameFormatter(),
+        *iFieldPropertyArray,
+        resReader );
+    params.SetFocusedField( iFocusedField );
+    params.SetUseDefaultDirectly( ETrue );
+    params.SetDefaultPriorities( defaults );
+    params.SetSuppressWarnings( ETrue );
+
+    CPbk2AddressSelect* addressSelect = CPbk2AddressSelect::NewL( params );
+    MVPbkStoreContactField* selectedField = addressSelect->ExecuteLD();
+
+    CleanupStack::PopAndDestroy( 2 ); // defaults, resReader
+
+    if ( selectedField )
+        {
+        CleanupDeletePushL( selectedField );
+        SetAddressFromFieldL( *selectedField );
+        CleanupStack::PopAndDestroy(); // selectedField
+        iState = ERetrieving;
+        iSendMessage = ETrue;
+        }
+    else 
+        {
+        if ( iPguUIExtensionPlugin->IsEndCallKeyPressed() )
+    	       {
+    	       iPguUIExtensionPlugin->ClearEndCallKeyPressedFlag();
+    	       iState = EStopping;
+             }
+        else
+            {
+	          iState = ERetrieving;
+            } 
+        }          
+    IssueRequest();
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::PrepareAddressSelectL
+// --------------------------------------------------------------------------
+//
+inline TInt CPguSendMessageGroupCmd::PrepareAddressSelectL
+        ( RVPbkContactFieldDefaultPriorities& aPriorities,
+          TUid aTechType )
+    {
+    // Precondition
+    __ASSERT_DEBUG( iMtmUid != KNullUid, Panic( EPanicUnknownMedia) );
+
+    TInt resourceId = KErrNotFound;
+
+    // SMS
+    if ( iMtmUid == KSenduiMtmSmsUid ||
+         aTechType == KSenduiTechnologySmsUid )
+        {
+        if ( FeatureManager::FeatureSupported( KFeatureIdEmailOverSms ) )
+            {
+            resourceId = R_PBK2_EMAIL_OVER_SMS_ADDRESS_SELECT;
+            User::LeaveIfError( aPriorities.Append
+                ( EVPbkDefaultTypeEmailOverSms ) );
+            }
+        else
+            {
+            resourceId = R_PBK2_PHONE_NUMBER_SELECT;
+            User::LeaveIfError( aPriorities.Append( EVPbkDefaultTypeSms ) );
+            }
+        }
+    // MMS
+    else if ( iMtmUid == KSenduiMtmMmsUid ||
+              aTechType == KSenduiTechnologyMmsUid )
+        {
+        resourceId = R_PBK2_MMS_ADDRESS_SELECT;
+        User::LeaveIfError( aPriorities.Append( EVPbkDefaultTypeMms ) );
+        }
+    // E-mail
+    else if ( iMtmUid ==  KSenduiMtmSmtpUid ||
+              aTechType == KSenduiTechnologyMailUid )
+        {
+        resourceId = R_PBK2_EMAIL_ADDRESS_SELECT;
+        User::LeaveIfError( aPriorities.Append( EVPbkDefaultTypeEmail ) );
+        }
+    // Unified message
+    else if ( iMtmUid == KSenduiMtmUniMessageUid )
+        {
+        if ( FeatureManager::FeatureSupported( KFeatureIdMMS ) )
+            {
+            if (Phonebook2::Pbk2AppUi()->ApplicationServices().
+                LocallyVariatedFeatureEnabled( EVPbkLVShowEmailInSendMsg ))
+            {
+                resourceId = R_PBK2_UNIFIED_EDITOR_MMS_ADDRESS_SELECT;
+            }
+            else
+            {
+                resourceId = R_PBK2_UNIFIED_EDITOR_PHONE_NUMBER_SELECT;
+            }
+            User::LeaveIfError( aPriorities.Append( EVPbkDefaultTypeMms ) );
+            }
+
+        if ( FeatureManager::FeatureSupported
+                ( KFeatureIdEmailOverSms ) )
+            {
+            if ( resourceId == KErrNotFound )
+                {
+                resourceId =
+                    R_PBK2_UNIFIED_EDITOR_EMAIL_OVER_SMS_ADDRESS_SELECT;
+                }
+            // Include SMS default always in unified message,
+            // in addition it has MMS default included with higher priority
+            User::LeaveIfError( aPriorities.Append(
+                EVPbkDefaultTypeEmailOverSms ) );
+            }
+        else
+            {
+            if ( resourceId == KErrNotFound )
+                {
+                resourceId = R_PBK2_UNIFIED_EDITOR_PHONE_NUMBER_SELECT;
+                }
+            // Include SMS default always in unified message,
+            // in addition it has MMS default included with higher priority
+            User::LeaveIfError( aPriorities.Append( EVPbkDefaultTypeSms ) );
+            }
+        }
+
+    // Postcondition
+    __ASSERT_DEBUG( resourceId != KErrNotFound, Panic( EPanicLogic) );
+
+    return resourceId;
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::SetAddressFromFieldL
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::SetAddressFromFieldL(
+        MVPbkStoreContactField& aField )
+    {
+    HBufC* address = MVPbkContactFieldTextData::Cast( aField.FieldData() ).
+        Text().AllocL();
+    CleanupStack::PushL( address );
+
+    if ( address && address->Des().Length() > 0 )
+        {
+        HBufC* nameBuffer =
+            Phonebook2::Pbk2AppUi()->ApplicationServices().NameFormatter().
+                GetContactTitleOrNullL(
+                    static_cast<const MVPbkBaseContactFieldCollection&>(
+                        iStoreContact->Fields() ),
+                        KDefaultTitleFormat );
+        if ( nameBuffer )
+            {
+            CleanupStack::PushL( nameBuffer );
+            iMessageData->AppendToAddressL( *address, *nameBuffer );
+            CleanupStack::PopAndDestroy( nameBuffer );
+            }
+        else
+            {
+            iMessageData->AppendToAddressL( *address );
+            }
+        }
+    CleanupStack::PopAndDestroy( address );
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::ProcessDismissed
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::ProcessDismissed( TInt /*aCancelCode*/ )
+    {
+    if (iUiControl)
+        {
+        iUiControl->UpdateAfterCommandExecution();
+        }
+
+    // Notify command owner that the command has finished
+    if ( iCommandObserver )
+        {
+        iCommandObserver->CommandFinished( *this );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::FilterErrors
+// --------------------------------------------------------------------------
+//
+TInt CPguSendMessageGroupCmd::FilterErrors( TInt aErrorCode )
+    {
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPguSendMessageGroupCmd::FilterErrors(%d) start"), aErrorCode);
+
+    TInt result = aErrorCode;
+    switch ( aErrorCode )
+        {
+        case KErrNotFound:  // FALLTHROUGH
+        case KErrInUse:
+            {
+            // Ignore these errors
+            // KErrNotFound means that somebody got the contact first
+            // KErrInUse means that the contact is open
+            result = KErrNone;
+            break;
+            }
+        default:  // Something more serious happened -> give up
+            {
+            Cancel();
+            ProcessDismissed( aErrorCode );
+            break;
+            }
+        }
+
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING(
+        "CPguSendMessageGroupCmd::FilterErrors(%d) end"), result );
+
+    return result;
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::IssueRequest
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::IssueRequest()
+    {
+    if ( !IsActive() )
+        {
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );
+        SetActive();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPguSendMessageGroupCmd::IssueStopRequest
+// --------------------------------------------------------------------------
+//
+void CPguSendMessageGroupCmd::IssueStopRequest()
+    {
+    iState = EStopping;
+    if ( !IsActive() )
+        {
+        IssueRequest();
+        }
+    }
+
+//  End of File