messagingappbase/msgerrorwatcher/src/MsgSentItemsObserver.cpp
changeset 0 72b543305e3a
child 77 da6ac9d688df
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingappbase/msgerrorwatcher/src/MsgSentItemsObserver.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,362 @@
+/*
+* Copyright (c) 2002 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:  
+*       CMsgSentItemsObserver implementation file
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <watcher.h>
+#include <msvids.h>
+
+#include <centralrepository.h>    // link against centralrepository.lib
+#include <cenrepnotifyhandler.h>  // link against CenRepNotifHandler.lib
+#include <messaginginternalcrkeys.h> // for Central Repository keys
+
+#include "MsgSentItemsObserver.h"
+
+#ifdef USE_LOGGER
+#include "MsgErrorWatcherLogging.h"
+#endif
+
+// CONSTANTS
+//const TUid KUidMceApp = { 0x100058C5 }; //needed to request shared data notifications
+const TMsvId KWatcherSentFolderId = KMsvSentEntryIdValue;
+const TUint KMaxRetries = 3;
+const TInt KMaxNumOfItems = 20; //Deafult value in case of error reading CommsDb
+//const TInt KMsgErrorDiskSpaceForDelete = ( 5 * 1024 ); // minimum disk space needed when deleting messages
+//_LIT( KSentItemsInUseOff, "0" );
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::NewL
+//
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+CMsgSentItemsObserver* CMsgSentItemsObserver::NewL( 
+        CMsgErrorWatcher* aWatcher, 
+        CMsvSession* aSession )
+    {
+    CMsgSentItemsObserver* self = new ( ELeave )
+        CMsgSentItemsObserver( aWatcher, aSession );
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::CMsgSentItemsObserver
+//
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// ---------------------------------------------------------
+//
+CMsgSentItemsObserver::CMsgSentItemsObserver( CMsgErrorWatcher* aWatcher, CMsvSession* aSession )
+    : CActive( EPriorityStandard ),
+    iWatcher( aWatcher ),
+    iSession( aSession )
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::~CMsgSentItemsObserver
+//
+// Destructor
+// ---------------------------------------------------------
+//
+CMsgSentItemsObserver::~CMsgSentItemsObserver()
+    {
+    Cancel();
+    if ( iNotifyHandler )
+        {        
+        iNotifyHandler->StopListening();
+        }
+    delete iNotifyHandler;
+    delete iRepository;
+    if( iCleanupFlags & ESentItemsFolderObserverAdded )
+        {
+        iSentItemsFolder->RemoveObserver( *this );
+        }
+    delete iSentItemsFolder;
+    delete iEntry;
+    delete iOp;
+    }
+
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::ConstructL
+//
+// Symbian OS default constructor can leave.
+// ---------------------------------------------------------
+//
+void CMsgSentItemsObserver::ConstructL()
+    {
+#ifdef USE_LOGGER
+    MEWLOGGER_ENTERFN( "SentItems: ConstructL" );
+#endif
+    //iMsgStoreDrive = MessageServer::CurrentDriveL( iSession->FileSession() );
+    //register as observer of sent items folder
+    TMsvSelectionOrdering sort( KMsvNoGrouping, EMsvSortByDateReverse );
+    iSentItemsFolder = CMsvEntry::NewL( *iSession, KWatcherSentFolderId, sort );
+    iSentItemsFolder->AddObserverL( *this );
+    iCleanupFlags |= ESentItemsFolderObserverAdded;
+    
+    //register as observer of user settings for sent folder
+
+    // Central Repository
+    iRepository = CRepository::NewL( KCRUidMuiuSettings );
+    iNotifyHandler = CCenRepNotifyHandler::NewL( *this, *iRepository );
+    iNotifyHandler->StartListeningL();
+
+#ifdef USE_LOGGER
+    MEWLOGGER_LEAVEFN( "SentItems: ConstructL" );
+#endif
+    }
+
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::RunL
+//
+// Will only run when messages have been deleted
+// ---------------------------------------------------------
+//
+void CMsgSentItemsObserver::RunL()
+    {
+    //iSession->FileSession().ReleaseReserveAccess( iMsgStoreDrive );
+#ifdef USE_LOGGER
+    if( iStatus==KErrNone )
+        {
+        MEWLOGGER_WRITE( "SentItems: deletion successful" );
+        }
+    else
+        {
+        MEWLOGGER_WRITEF( _L("SentItems: deletion error %d"), iStatus.Int() );
+        } 
+#endif
+    //Check if new messages have appeared into Sent Items while deleting
+    //the previous one(s).
+#ifdef USE_LOGGER
+    MEWLOGGER_WRITEF( _L("SentItems: Retries: %d"), iRetryCounter );
+#endif
+    if ( iRetryCounter < KMaxRetries )
+        {
+        iRetryCounter++;
+        TRAP_IGNORE( DeleteOldMessagesFromSentFolderL() );
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::DoCancel
+//
+// From active object framework
+// ---------------------------------------------------------
+//
+void CMsgSentItemsObserver::DoCancel()
+    {
+    //iSession->FileSession().ReleaseReserveAccess( iMsgStoreDrive );
+    if ( iOp )
+        {
+        iOp->Cancel();
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::HandleNotifyInt
+//
+// Notification from central repository
+// ---------------------------------------------------------
+//
+void CMsgSentItemsObserver::HandleNotifyInt( TUint32 aId, TInt aNewValue )
+    {    
+    if ( ( aId == KMuiuSentItemsInUse && aNewValue != 0 ) ||
+         ( aId == KMuiuSentItemsCount && SentFolderIsBeingUsed() ) )
+        {
+        iRetryCounter = 0;
+        //This is non-leaving function...
+        TRAPD( dummy, DeleteOldMessagesFromSentFolderL() );
+        dummy=dummy; //Prevent arm5 build warning
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::HandleNotifyGeneric
+// ---------------------------------------------------------
+//
+void CMsgSentItemsObserver::HandleNotifyGeneric( TUint32 /*aId*/ )
+    {
+    //Nothing.
+    }
+    
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::HandleNotifyError
+// ---------------------------------------------------------
+//
+void CMsgSentItemsObserver::HandleNotifyError( TUint32 /*aId*/, TInt /*error*/, CCenRepNotifyHandler* /*aHandler*/ )
+    {
+    //Nothing.
+    }
+  
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::HandleEntryEventL
+//
+// Call back from msg that the sent items folder has changed
+// so check if messages need to be deleted.
+// ---------------------------------------------------------
+//
+void CMsgSentItemsObserver::HandleEntryEventL( TMsvEntryEvent aEvent, TAny* aArg1, TAny* /*aArg2*/, TAny* /*aArg3*/ )
+    {   
+    switch( aEvent )
+        {
+        case EMsvNewChildren:
+            {
+            if( !SentFolderIsBeingUsed() )
+                {
+                //not taking ownership
+                CMsvEntrySelection* selection =
+                    static_cast<CMsvEntrySelection*>( aArg1 );
+                iRetryCounter = 0;
+                DeleteMessagesFromSentFolderL( selection );
+                return;
+                }
+            if( iSentItemsFolder->Count() > SentFolderUpperLimit() )
+                {
+                iRetryCounter = 0;
+                DeleteOldMessagesFromSentFolderL();
+                return;
+                }
+            }
+            break;
+        case EMsvEntryChanged:
+        case EMsvDeletedChildren:
+        case EMsvChildrenChanged:
+        case EMsvEntryDeleted:
+        case EMsvContextInvalid:
+        case EMsvChildrenMissing:
+        case EMsvChildrenInvalid:
+        case EMsvEntryMoved:
+        default:
+            break;
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::SentFolderIsBeingUsed
+//
+// Returns the user setting for use of the sent folder. If there
+// is an error then the default value of ON (i.e ETrue) will
+// be returned.
+// ---------------------------------------------------------
+//
+TBool CMsgSentItemsObserver::SentFolderIsBeingUsed()
+    {
+    TInt isUsed = 1;
+   	iRepository->Get( KMuiuSentItemsInUse, isUsed );
+    return isUsed;
+    }
+
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::SentFolderUpperLimit
+//
+// Returns the user setting for max limit to the number of messages
+// in the sent folder. If there is an error then the default value of
+// KMaxNumOfItems will be returned
+// ---------------------------------------------------------
+//
+TInt CMsgSentItemsObserver::SentFolderUpperLimit()
+    {
+    TInt numItems = KMaxNumOfItems;
+   	iRepository->Get( KMuiuSentItemsCount, numItems );
+    return numItems;
+    }
+
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::DeleteOldMessagesFromSentFolderL
+//
+// If there are more messages in the sent folder than the upper
+// limit set by the user then delete the oldest messages.
+// ---------------------------------------------------------
+//
+void CMsgSentItemsObserver::DeleteOldMessagesFromSentFolderL()
+    {
+    CMsvEntrySelection* children = iSentItemsFolder->ChildrenL();
+    CleanupStack::PushL( children );
+    TInt limit = SentFolderUpperLimit();
+    TInt sentMessageCount = children->Count();
+    if( sentMessageCount <= limit )
+        {
+        CleanupStack::PopAndDestroy( children );
+        return;
+        }
+    CMsvEntrySelection* messagesToBeDeleted = new ( ELeave ) CMsvEntrySelection;
+    CleanupStack::PushL( messagesToBeDeleted );
+    //oldest messages are at the end of the array
+    for( TInt index = sentMessageCount - 1; index >= limit; index-- )
+        {
+        messagesToBeDeleted->AppendL( children->At( index ) );
+        }
+    DeleteMessagesFromSentFolderL( messagesToBeDeleted );
+    CleanupStack::PopAndDestroy( messagesToBeDeleted  ); 
+    CleanupStack::PopAndDestroy( children );
+    }
+
+// ---------------------------------------------------------
+// CMsgSentItemsObserver::DeleteMessagesFromSentFolderL
+//
+// Delete the messages specified by aSelection
+// ---------------------------------------------------------
+//
+void CMsgSentItemsObserver::DeleteMessagesFromSentFolderL( CMsvEntrySelection* aSelection )
+    {
+    if ( !IsActive() )
+        {
+#ifdef USE_LOGGER
+        MEWLOGGER_WRITEF( _L("SentItems: deleting %d messages from sent folder"), aSelection->Count() );
+#endif
+        const TMsvId id = aSelection->At( 0 );
+        delete iEntry;
+        iEntry = 0;
+        iEntry = iSession->GetEntryL( id );
+        iEntry->SetEntryL( iEntry->Entry().Parent() );
+
+        //if ( iSession->FileSession().ReserveDriveSpace( iMsgStoreDrive, KMsgErrorDiskSpaceForDelete ) == KErrNone )
+        //    {
+        //    iSession->FileSession().GetReserveAccess( iMsgStoreDrive );
+        //    }
+
+        delete iOp;
+        iOp = 0;
+        //TRAPD( err,
+        //    {
+            iOp = iEntry->DeleteL( *aSelection, iStatus ); //delete acts on returned CMsvOperation*
+        //    } );
+        //if ( err )
+        //    {
+        //    iSession->FileSession().ReleaseReserveAccess( iMsgStoreDrive );
+        //    User::Leave( err );
+        //    }
+        //else
+        //    {
+            SetActive();
+        //    }
+        }
+    }
+
+//  End of File  
+