diff -r 000000000000 -r 72b543305e3a email/imap4mtm/imapsyncmanager/src/cimapopsyncsubs.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/imap4mtm/imapsyncmanager/src/cimapopsyncsubs.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,306 @@ +// Copyright (c) 1999-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: +// imapopsyncsubs.cpp +// +// + +#include "cimapsyncmanager.h" +#include "cimapopsyncsubs.h" +#include "cimapsettings.h" +#include "cimapfolder.h" + +CImapOpSyncSubs* CImapOpSyncSubs::NewL(CMsvServerEntry& aEntry, CImapSession& aSession, CImapSyncManager& aSyncMan,CImapSettings& aImapSettings) + { + CImapOpSyncSubs* self=NewLC(aEntry, aSession, aSyncMan, aImapSettings); + CleanupStack::Pop(); + + return self; + } + +CImapOpSyncSubs* CImapOpSyncSubs::NewLC(CMsvServerEntry& aEntry, CImapSession& aSession,CImapSyncManager& aSyncMan,CImapSettings& aImapSettings) + { + CImapOpSyncSubs* self=new (ELeave) CImapOpSyncSubs(aEntry, aSession, aSyncMan, aImapSettings); + CleanupStack::PushL(self); + + // Non-trivial constructor + self->ConstructL(); + + return self; + } + +CImapOpSyncSubs::~CImapOpSyncSubs() + { + iImapListFolderInfo.ResetAndDestroy(); + } + +void CImapOpSyncSubs::ConstructL() + { + // We're an active object... + CActiveScheduler::Add(this); + + } + +void CImapOpSyncSubs::SynchroniseSubscriptionsL(TRequestStatus& aStatus) + { + // Do we need to know what folders are subscribed remotely? + if (iImapSettings.Synchronise() == EUseLocal && + (iImapSettings.Subscribe() == EUpdateNeither || iImapSettings.Subscribe() == EUpdateLocal)) + { + // Just update any remote subscriptions + iNextSyncAction = CImapSyncManager::EUpdateRemoteSubscription; + Queue(aStatus); + CompleteSelf(); + SetActive(); + } + else + { + // Update our list of remotely subscribed folders + // First, we need to go through the entire service, resetting all + // the 'remote subscribed' flags. + ResetSubscriptionFlagsL(iServiceId); + + // Build a buffer to quote the folder path (it may be necessary) + HBufC16* path=HBufC16::NewLC(iImapSettings.FolderPath().Length()+2); + path->Des().Copy(iImapSettings.FolderPath()); + if (iImapSettings.FolderPath().Length()) + { + path->Des().Append(iImapSettings.PathSeparator()); + } + + path->Des().Append(KStarChar); + + // Quote it + CImapFolder::DoQuoteL(path); + + // List this tree + iNextSyncAction = CImapSyncManager::EProcessRemoteSubscription; + iServerEntry.SetEntry(iServiceId); + TMsvEmailEntry entry = iServerEntry.Entry(); + + iSession.LsubL(iStatus, KNullDesC, path->Des(), iImapListFolderInfo); + + Queue(aStatus); + SetActive(); + CleanupStack::PopAndDestroy(path); + } + } + +CImapOpSyncSubs::CImapOpSyncSubs(CMsvServerEntry& aEntry, CImapSession& aSession, CImapSyncManager& aSyncMan,CImapSettings& aImapSettings) +: CImapSyncOperation(aEntry, aSession, aSyncMan, aImapSettings, EPriorityStandard) + { + } + + +/** +Set the current entry context on the Message server + +@param aId +The entry id to set in the Message server +@leave KErrNotFound if the entry does not exist or KErrLocked if the entry is locked. +*/ +void CImapOpSyncSubs::SetEntryL(const TMsvId aId) + { + User::LeaveIfError(iServerEntry.SetEntry(aId)); + } + +/** +Sets the context's index entry to the specified values on the Message server + +@param aEntry +The new details for the entry. +@leave KErrAccessDenied - the entry is read only (deleted entry, standard folder, or locked); +KErrNotSupported - aEntry is invalid or the ID specified in aEntry is not the same as the context ID +or no context has been set for the object; +KErrNoMemory - a memory allocation failed. +*/ +void CImapOpSyncSubs::ChangeEntryL(const TMsvEntry& aEntry) + { + User::LeaveIfError(iServerEntry.ChangeEntry(aEntry)); + } + +/** +Return a list of all child entries of the currently selected entry node. + +@param aSelection +The ids for the found child entries will be put into this parameter +*/ +void CImapOpSyncSubs::GetChildrenL(CMsvEntrySelection& aSelection) + { + User::LeaveIfError(iServerEntry.GetChildren(aSelection)); + } + +/** +Reset subscription flags for all children, and recurse into folders + +@param aFolder +Folder from which to start the flags resetting +*/ +void CImapOpSyncSubs::ResetSubscriptionFlagsL(const TMsvId aFolder) + { + // Do this one + SetEntryL(aFolder); + TMsvEmailEntry entry = iServerEntry.Entry(); + + // A folder or service? If not, return + if (entry.iType!=KUidMsvServiceEntry && + entry.iType!=KUidMsvFolderEntry) + { + return; + } + + // Reset flag if needed + if (entry.Subscribed()) + { + // Reset flag and save + entry.SetSubscribed(EFalse); + ChangeEntryL(entry); + } + + // Any children? + CMsvEntrySelection *children = new (ELeave) CMsvEntrySelection; + CleanupStack::PushL(children); + GetChildrenL(*children); + if (children->Count()) + { + // Do each in turn + for(TInt child = 0; childCount(); ++child) + { + ResetSubscriptionFlagsL((*children)[child]); + } + } + CleanupStack::PopAndDestroy(); + } + + +/** +Called when async child completes with >=KErrNone +*/ +void CImapOpSyncSubs::DoRunL() + { + // Finish if any server errors. + if (iStatus.Int()!=KErrNone) + { + Complete(iStatus.Int()); + } + + switch(iNextSyncAction) + { + case CImapSyncManager::EProcessRemoteSubscription: + { + // Call returned from the LSUB command. Now process the list. + // Update folder tree + TInt folderscount = iImapListFolderInfo.Count(); + CImapListFolderInfo* folder; + + for(TInt loop = 0;loop < folderscount; ++loop) + { + folder = iImapListFolderInfo[loop]; + iSyncMan.AddSubscribedFolderFromInfoL(folder, iSession.LogId()); + } + iSyncMan.CreateLocalFolderListL(); + + // Now do the remote subscription + iNextSyncAction = CImapSyncManager::EUpdateRemoteSubscription; + CompleteSelf(); + SetActive(); + } + break; + case CImapSyncManager::EUpdateRemoteSubscription: + { + // Process the subscribed and unsubscribed list from the SyncManager. + // This should be done after checking the online subscription list. + + RArray* unsubscribeList = iSyncMan.GetUnSubscribedFolderToDoList(); + RArray* subscribeList = iSyncMan.GetSubscribedFolderToDoList(); + + // Any subscription to do? + if (subscribeList->Count()) + { + // Take it off the head + TMsvId folderid = (*subscribeList)[0]; + subscribeList->Remove(0); + + // Subscribe to it + CImapFolder* tempfolder = iSyncMan.GetTempFolderL(folderid); + CleanupStack::PushL(tempfolder); + iSession.SubscribeL(iStatus, tempfolder->FullFolderPathL()); + CleanupStack::PopAndDestroy(tempfolder); + + // set the subscribed flag for the folder. + SetEntryL(folderid); + TMsvEmailEntry entry = iServerEntry.Entry(); + entry.SetSubscribed(ETrue); + ChangeEntryL(entry); + + SetActive(); + } + // ...or unsubscription? + else if (unsubscribeList->Count()) + { + // Take it off the head + TMsvId folderid = (*unsubscribeList)[0]; + unsubscribeList->Remove(0); + + // Unsubscribe from it + CImapFolder* tempfolder = iSyncMan.GetTempFolderL(folderid); + CleanupStack::PushL(tempfolder); + iSession.UnsubscribeL(iStatus, tempfolder->FullFolderPathL()); + CleanupStack::PopAndDestroy(tempfolder); + + // clear the subscribed flag for the folder. + SetEntryL(folderid); + TMsvEmailEntry entry = iServerEntry.Entry(); + entry.SetSubscribed(EFalse); + ChangeEntryL(entry); + + SetActive(); + } + else + { + // All done. + iNextSyncAction = CImapSyncManager::ENotSyncing; + Complete(iStatus.Int()); + } + } + break; + default: + break; + } + } + +/** +Cancels any outstanding asynchronous service requests. +*/ +void CImapOpSyncSubs::DoCancel() + { + iSession.Cancel(); + CMsgActive::DoCancel(); + } + +/** + +*/ +void CImapOpSyncSubs::DoComplete(TInt& /*aStatus*/) + { + } + +void CImapOpSyncSubs::CompleteSelf() + { + TRequestStatus* status = &iStatus; + iStatus = KRequestPending; + User::RequestComplete(status, KErrNone); + } + + +