messagingapp/msgsettings/msginit/src/coutboxsendoperation.cpp
changeset 52 12db4185673b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingapp/msgsettings/msginit/src/coutboxsendoperation.cpp	Wed Aug 18 09:45:25 2010 +0300
@@ -0,0 +1,409 @@
+/*
+* Copyright (c) 2010 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:   Implements class
+*
+*/
+
+
+
+// INCLUDE FILES
+
+#include "coutboxsendoperation.h"   // header
+
+#include <SendUiConsts.h>           // MTM Uids
+#include <msvids.h>                  // Entry Ids
+#include <gsmerror.h>                // SMS sending failure error codes
+#include <smutset.h>
+#include "debugtraces.h"
+
+// ================= MEMBER FUNCTIONS =======================
+
+// Two-phased constructor.
+COutboxSendOperation* COutboxSendOperation::NewL(
+    CMsvSession& aMsvSession,
+    TRequestStatus& aObserverRequestStatus )
+    {
+    // Create the instance of sending operation
+    COutboxSendOperation* self =
+        new (ELeave) COutboxSendOperation(
+            aMsvSession, aObserverRequestStatus );
+
+    // Push self into cleanup stack during construction
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+
+    // Return the object
+    return self;
+    }
+
+// C++ default constructor can NOT contain any code that
+// might leave.
+//
+COutboxSendOperation::COutboxSendOperation(
+    CMsvSession& aMsvSession,
+    TRequestStatus& aObserverRequestStatus )
+    :
+    CMsvOperation( aMsvSession, CActive::EPriorityStandard, aObserverRequestStatus ),
+    iSelections( 4 ),
+    iServices(),
+    iSupportedMsgs( COutboxSendOperation::ESupportsSmsSending )
+    {
+    // Start scheduler
+    CActiveScheduler::Add(this);
+    }
+
+//destructor
+COutboxSendOperation::~COutboxSendOperation()
+    {
+    // Cancel sending
+    Cancel();
+
+    // Delete sending operation
+    delete iOperation;
+    iOperation = NULL;
+
+    // Delete entry
+    delete iEntry;
+    iEntry = NULL;
+
+    // Remove services from queue and destroy message selections
+    iServices.Reset();
+    iSelections.ResetAndDestroy();
+    }
+
+// ----------------------------------------------------
+// COutboxSendOperation::ConstructL
+// ----------------------------------------------------
+//
+void COutboxSendOperation::ConstructL()
+    {
+    // Get rootindex entry
+    iEntry = iMsvSession.GetEntryL( KMsvRootIndexEntryId );
+    iEntry->SetSortTypeL(
+        TMsvSelectionOrdering( KMsvNoGrouping, EMsvSortByNone, ETrue ) );
+
+    // Set sending flags
+    iSupportedMsgs |= ESendSms;
+
+    // Start sending
+    StartSendingL();
+    }
+
+// ----------------------------------------------------
+// COutboxSendOperation::RunL
+// ----------------------------------------------------
+//
+void COutboxSendOperation::RunL()
+    {
+    QDEBUG_WRITE("COutboxSendOperation::RunL");
+    User::LeaveIfError( iStatus.Int() );
+
+    // Check and start sending, if needed
+    TUid sendMtm;
+
+    // Check if messages needs to be sent
+    if( IsSendingNeeded( sendMtm ) )
+        {
+        StartSendingL();
+        }
+    // Nothing to send, complete operation
+    else
+        {
+        CompleteObserver( iStatus.Int() );
+        }
+    }
+
+// ----------------------------------------------------
+// COutboxSendOperation::RunError
+// ----------------------------------------------------
+//
+TInt COutboxSendOperation::RunError( TInt aError )
+    {   
+    CompleteObserver( aError );
+    return aError;
+    }
+
+// ----------------------------------------------------
+// COutboxSendOperation::DoCancel
+// ----------------------------------------------------
+//
+void COutboxSendOperation::DoCancel()
+    {
+    // Check if sending operation is running
+    if( iOperation )
+        {
+        // Cancel it
+        iOperation->Cancel();
+        }
+
+    // Complete operation with current status
+    CompleteObserver( iStatus.Int() );
+    }
+
+// ----------------------------------------------------
+// COutboxSendOperation::ProgressL
+// ----------------------------------------------------
+//
+const TDesC8& COutboxSendOperation::ProgressL()
+    {
+    // Check if operation exists
+    if( iOperation )
+        {
+        // Return the operation
+        return iOperation->ProgressL();
+        }
+
+    // If no operation, return blank information
+    return KNullDesC8();
+    }
+
+// ---------------------------------------------------------
+// COutboxSendOperation::CompleteOperation
+// ---------------------------------------------------------
+//
+void COutboxSendOperation::CompleteObserver( TInt aStatus )
+    {
+    // Get the observer status
+    TRequestStatus* status = &iObserverRequestStatus;
+    User::RequestComplete( status, aStatus );
+    }
+
+// ----------------------------------------------------
+// COutboxSendOperation::StartSendingL
+// ----------------------------------------------------
+//
+void COutboxSendOperation::StartSendingL()
+    {
+    // Remove any sending operation that currently may be running
+    delete iOperation;
+    iOperation = NULL;
+
+
+    // Check if there was errors with creating selection
+    if  ( CheckAndCreateSelectionL() )
+        {
+        // Create new operation and trap any errors
+        SendWaitingSMSMessages();
+        RemoveSelection();
+        }
+    else
+        {
+        CompleteSelf( KErrNone );
+        }
+    }
+
+    // if error, then complete this pass with the error code
+void COutboxSendOperation::SendWaitingSMSMessages()
+    {
+    TRAPD( err, SendWaitingSMSMessagesL() );
+    if  ( err != KErrNone )
+        {
+        ASSERT( !IsActive() );
+        CompleteSelf( err );
+        }
+    }
+
+// ----------------------------------------------------
+// COutboxSendOperation::SendWaitingSMSMessagesL
+// ----------------------------------------------------
+//
+void COutboxSendOperation::SendWaitingSMSMessagesL()
+    {
+    // Get first selection from queue
+    CMsvEntrySelection& selection = ( *iSelections[0] );
+
+    // Get count of messages in queue
+    TInt count = selection.Count();
+
+    // Go through all messages
+    while( count-- )
+        {
+        // Select message
+        iEntry->SetEntryL( selection[count] );
+        TMsvEntry entry( iEntry->Entry() );
+
+        // Check if the message is tried to send when in offline
+        if( ( entry.SendingState() == KMsvSendStateSuspended ||
+              entry.SendingState() == KMsvSendStateFailed) &&
+            ( entry.iError == KErrGsmOfflineOpNotAllowed ||
+              entry.iError == KErrGsmOfflineSimOpNotAllowed) )
+            {
+            // Set message to wait sending
+            entry.SetSendingState( KMsvSendStateWaiting );
+            iEntry->ChangeL( entry );
+            }
+		else
+			{
+			selection.Delete( count );
+			}
+        }
+    selection.Compress();
+
+    // Set entry to outbox
+    iMtm = iEntry->Entry().iMtm;
+    iEntry->SetEntryL( KMsvGlobalOutBoxIndexEntryId );
+	if ( selection.Count() )
+		{
+		iOperation = iEntry->CopyL( selection, iServices[0], iStatus );
+        SetActive();
+		}
+    else
+        {
+        // Nothing to send, but we must complete the observer via our RunL callback
+        CompleteSelf( KErrNone );
+        }
+    }
+
+
+// ----------------------------------------------------
+// COutboxSendOperation::RemoveSelection
+// ----------------------------------------------------
+//
+void COutboxSendOperation::RemoveSelection()
+    {
+    // Clear the the current selection.
+    iServices.Delete(0);
+
+    // Delete selection object and index
+    delete iSelections[0];
+    iSelections.Delete(0);
+    }
+
+// ----------------------------------------------------
+// COutboxSendOperation::CreateSelectionL
+// ----------------------------------------------------
+//
+void COutboxSendOperation::CreateSelectionL(
+    const TUid &aUidForSel,
+    const TMsvId& aServiceId,
+    CMsvEntrySelection*& aSelection )
+    {
+    // Set entry to outbox and get messages from outbox
+    iEntry->SetEntryL( KMsvGlobalOutBoxIndexEntryId );
+    aSelection = iEntry->ChildrenWithMtmL( *&aUidForSel );
+
+    // Check if there is anything to put into array
+    if( aSelection->Count() )
+        {
+        // Put selection to queue
+        CleanupStack::PushL( aSelection );
+        iSelections.AppendL( aSelection );
+        CleanupStack::Pop( aSelection );
+
+        // Put service to queue
+        iServices.AppendL( aServiceId );
+        }
+    else
+        {
+        // Remove selection
+        delete aSelection;
+        aSelection = NULL;
+        }
+    }
+
+// ----------------------------------------------------
+// COutboxSendOperation::CheckAndCreateSelectionL
+// ----------------------------------------------------
+//
+TBool COutboxSendOperation::CheckAndCreateSelectionL()
+    {
+    // Get root index
+    iEntry->SetEntryL( KMsvRootIndexEntryId );
+
+    // MTM, for which the selection is collected
+    TUid sendMtm;
+
+    // Selection of messages for sending
+    CMsvEntrySelection* smsSelection = NULL;
+
+    // While MTM's available for sending
+    while( smsSelection == NULL && IsSendingNeeded( sendMtm ) )
+        {
+        // Find default SMS service
+        TMsvId serviceId =0;
+        TSmsUtilities::ServiceIdL(*iEntry, serviceId);
+        QDEBUG_WRITE_FORMAT("COutboxSendOperation::CheckAndCreateSelectionL ",serviceId );
+        // Check if the service ID is found
+        if( serviceId != KMsvNullIndexEntryId )
+            {
+            // Create selection of messages of specified MTM
+            CreateSelectionL( sendMtm, serviceId, smsSelection );
+            }
+        // Selection has been created, remove the flag
+        RemoveSendingFlag( *&sendMtm );
+        }
+
+    const TBool selectionAvailable = ( smsSelection != NULL );
+    return selectionAvailable;
+    }
+
+// ----------------------------------------------------
+// COutboxSendOperation::RemoveSendingFlag
+// ----------------------------------------------------
+//
+void COutboxSendOperation::RemoveSendingFlag( const TUid& aMtm )
+    {
+    // Decide actions by mtm
+    switch( aMtm.iUid )
+        {
+        // SMS-messages
+        case KSenduiMtmSmsUidValue:
+            iSupportedMsgs &= ~ESendSms;
+            break;        
+        default:
+            break;
+        }
+    }
+
+// ----------------------------------------------------
+// COutboxSendOperation::IsSendingNeeded
+// ----------------------------------------------------
+//
+TBool COutboxSendOperation::IsSendingNeeded(
+    TUid& aMtm ) const
+    {
+    // Set starting condition
+    TBool needSending = EFalse;
+
+    // Check if sms-sending is supported and messages need to be sent
+    if( iSupportedMsgs & ESupportsSmsSending &&
+        iSupportedMsgs & ESendSms )
+        {
+        aMtm = KSenduiMtmSmsUid;
+        needSending = ETrue;
+        }
+    // Otherwise nothing needs to be done
+    else
+        {
+        aMtm.iUid = 0;
+        needSending = EFalse;
+        }
+
+    // Return the result
+    return needSending;
+    }
+
+// ----------------------------------------------------
+// COutboxSendOperation::CompleteSelf
+// ----------------------------------------------------
+//
+void COutboxSendOperation::CompleteSelf( TInt aValue )
+    {
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, aValue );
+    SetActive();
+    }
+    
+// End of file