email/imap4mtm/imapsyncmanager/src/cimapsyncmanager.cpp
changeset 0 72b543305e3a
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // imapsyncmanager.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 
       
    19 #include "cimapsyncmanager.h"
       
    20 #include "cimapopsyncfoldertree.h"
       
    21 #include "cimapopsyncsubs.h"
       
    22 #include "cimapfolder.h"
       
    23 #include "cimapsessionconsts.h"
       
    24 #include "cimaplogger.h"
       
    25 
       
    26 #ifdef __IMAP_LOGGING
       
    27 #include <utf.h>
       
    28 #endif
       
    29 
       
    30 // Inbox mailbox name
       
    31 _LIT(KIMAP_INBOX, "INBOX");
       
    32 
       
    33 // Inbox mailbox name used for display purposes
       
    34 _LIT(KImapInboxDisplayName, "Inbox");
       
    35 
       
    36 /**
       
    37 Private default class constructor
       
    38 */
       
    39 CImapSyncManager::CImapSyncManager(CMsvServerEntry& aEntry, CImapSettings& aImapSettings)
       
    40 :	CMsgActive(EPriorityStandard), 
       
    41 	iServerEntry(aEntry), 
       
    42 	iImapSettings(aImapSettings),
       
    43 	iInboxClearNewFlags(ETrue),
       
    44 	iNonInboxClearNewFlags(ETrue)
       
    45 	{
       
    46 	}
       
    47 
       
    48 /**
       
    49 Class destructor
       
    50 */
       
    51 CImapSyncManager::~CImapSyncManager()
       
    52 	{
       
    53 	delete iFolderTreeSync;
       
    54 	delete iSyncSubs;
       
    55 	delete iSubscribeList;
       
    56 	delete iUnsubscribeList;
       
    57 	delete iInbox;
       
    58 	iFolderList.ResetAndDestroy();
       
    59 	}
       
    60 
       
    61 /**
       
    62 Static factory constructor
       
    63 
       
    64 @param aServiceId
       
    65 The TMsvId of the Imap service that is being accessed.
       
    66 @param aOffLine The CImapOfflineControl that provides access methods to pending offline operations
       
    67 @return The constructed CImapSuncManager object pushed onto the cleanup stack
       
    68 */
       
    69 EXPORT_C CImapSyncManager* CImapSyncManager::NewLC(CMsvServerEntry& aEntry, CImapSettings& aImapSettings)
       
    70 	{
       
    71 	CImapSyncManager* self=new (ELeave) CImapSyncManager( aEntry, aImapSettings);
       
    72 	CleanupStack::PushL(self);
       
    73 
       
    74 	// Non-trivial constructor
       
    75 	self->ConstructL();
       
    76 	return self;
       
    77 	}
       
    78 
       
    79 /**
       
    80 Static factory constructor with cleanup
       
    81 
       
    82 @param aServiceId
       
    83 The TMsvId of the Imap service that is being accessed.
       
    84 @param aOffLine The CImapOfflineControl that provides access methods to pending offline operations
       
    85 @return The constructed CImapSuncManager object
       
    86 */
       
    87 EXPORT_C CImapSyncManager* CImapSyncManager::NewL(CMsvServerEntry& aEntry, CImapSettings& aImapSettings)
       
    88 	{
       
    89 	CImapSyncManager* self=NewLC( aEntry, aImapSettings);
       
    90 	CleanupStack::Pop();
       
    91 	return self;
       
    92 	}
       
    93 
       
    94 /**
       
    95 The non-trival constructor. Initialise the data members and create the subcribed local folder list
       
    96 */
       
    97 void CImapSyncManager::ConstructL()
       
    98 	{
       
    99 
       
   100 	// Get the flags from iImapSettings
       
   101 	iSynchroniseStrategy = iImapSettings.Synchronise();
       
   102 	iSubscribeStrategy = iImapSettings.Subscribe();
       
   103 	iServiceId = iImapSettings.ServiceId();
       
   104 	// Find the inbox
       
   105 	GetInboxL();
       
   106 	// Create the list for the rest of the folders
       
   107 	iSubscribeList=new (ELeave) RArray<TUint>(4);
       
   108 	iUnsubscribeList=new (ELeave) RArray<TUint>(4);
       
   109 	CreateLocalFolderListL();
       
   110 	// We're an active object...
       
   111 	CActiveScheduler::Add(this);
       
   112 	}
       
   113 
       
   114 	
       
   115 /** 
       
   116 Set the current entry context on the Message server
       
   117 
       
   118 @param aId
       
   119 The entry id to set in the Message server
       
   120 @leave KErrNotFound if the entry does not exist or KErrLocked if the entry is locked.
       
   121 */
       
   122 void CImapSyncManager::SetEntryL(const TMsvId aId)
       
   123 	{
       
   124 	User::LeaveIfError(iServerEntry.SetEntry(aId));
       
   125 	}
       
   126 
       
   127 /**
       
   128 Sets the context's index entry to the specified values on the Message server
       
   129 
       
   130 @param  aEntry
       
   131 The new details for the entry.
       
   132 @leave KErrAccessDenied - the entry is read only (deleted entry, standard folder, or locked); 
       
   133 KErrNotSupported - aEntry is invalid or the ID specified in aEntry is not the same as the context ID
       
   134 or no context has been set for the object; 
       
   135 KErrNoMemory - a memory allocation failed. 
       
   136 */
       
   137 void CImapSyncManager::ChangeEntryL(const TMsvEntry& aEntry)
       
   138 	{
       
   139 	User::LeaveIfError(iServerEntry.ChangeEntry(aEntry));
       
   140 	}
       
   141 
       
   142 /**
       
   143 Change entry in bulk mode (i.e no index file commit. no notify)
       
   144 
       
   145 @param  aEntry
       
   146 The new details for the entry.
       
   147 @leave KErrAccessDenied - the entry is read only (deleted 
       
   148 entry, standard folder, or locked); 
       
   149 KErrNotSupported - aEntry is invalid or the 
       
   150 ID specified in aEntry is not the same as the context ID or no context has been 
       
   151 set for the object; 
       
   152 KErrNoMemory - a memory allocation failed.
       
   153 */
       
   154 void CImapSyncManager::ChangeEntryBulkL(const TMsvEntry& aEntry)
       
   155 	{
       
   156 	User::LeaveIfError(iServerEntry.ChangeEntryBulk(aEntry));
       
   157 	}
       
   158 
       
   159 /**
       
   160 Return a list of all child entries of the currently selected entry node.
       
   161 
       
   162 @param  aSelection
       
   163 The ids for the found child entries will be put into this parameter
       
   164 */
       
   165 void CImapSyncManager::GetChildrenL(CMsvEntrySelection& aSelection)
       
   166 	{
       
   167 	User::LeaveIfError(iServerEntry.GetChildren(aSelection));
       
   168 	}
       
   169 
       
   170 /** 
       
   171 Returns a pointer to the CImapFolder object associated with the passed entry ID.
       
   172 CImapSyncManager maintains an array of CImapFolder objects that are subscribed
       
   173 according to sync and subscribe strategy settings - if the folder exists in this
       
   174 array then the pointer to this instance is returned. Otherwise a CImapFolder
       
   175 instance is created for the specified folder and appended to the list.
       
   176 
       
   177 As the folder list is rebuilt on folder tree synscronisation, code using this
       
   178 API cannot expect a returned pointer to remain valid following an account or
       
   179 folder tree synchronisation operation.
       
   180 
       
   181 This method preserves the context of the shared CMsvServerEntry
       
   182 
       
   183 @param aMsvId The TMsvId of the folder as stored in the message server
       
   184 
       
   185 @param aAddToSubscribedList holds bool value,  ETure adds to subscribed list, EFalse does not add.
       
   186 
       
   187 @return NULL if the folder does not exist, pointer to the CImapFolder object otherwise.
       
   188 */
       
   189 EXPORT_C CImapFolder* CImapSyncManager::GetFolderL(TMsvId aMsvId, TBool aAddToSubscribedList)
       
   190 	{
       
   191 	TMsvId preservedId = iServerEntry.Entry().Id();
       
   192 	
       
   193 	// Retrieve the folder from the maintained list if it is present.
       
   194 	// Will be present if it is subscribed according to settings.
       
   195 	CImapFolder* folder = GetFolderFromList(aMsvId);
       
   196 	
       
   197 	if (folder==NULL)
       
   198 		{
       
   199 		// Requested folder is not in the list of subscribed mailboxes.
       
   200 		// It may have been subscribed locally since the last folder sync 
       
   201 		// operation, or the client application may be attempting to access
       
   202 		// a non-subscribed folder.
       
   203 		// Create an instance for the folder and add it to the folder list.
       
   204 		SetEntryL(aMsvId);
       
   205 		TMsvEmailEntry entry = iServerEntry.Entry();
       
   206 		folder = CImapFolder::NewLC(*this, iServerEntry, entry, iImapSettings, KNullDesC());
       
   207 		if(aAddToSubscribedList)
       
   208 			{
       
   209 			iFolderList.AppendL(folder);
       
   210 			}
       
   211 		CleanupStack::Pop(folder);
       
   212 
       
   213 		// recover original serverentry context
       
   214 		SetEntryL(preservedId);
       
   215 		}
       
   216 	return folder;
       
   217 	}
       
   218 
       
   219 /**
       
   220 Returns a pointer to the CImapFolder object associated with the passed entry ID,
       
   221 if it appears in the array of CImapFolders.
       
   222 
       
   223 @param aMsvId The TMsvId of the folder as stored in the message server
       
   224 @return NULL if the folder is not in the list, pointer to the CImapFolder object otherwise.
       
   225 */
       
   226 CImapFolder* CImapSyncManager::GetFolderFromList(TMsvId aMsvId)
       
   227 	{
       
   228 	// Check the inbox first
       
   229 	if(iInbox)
       
   230 		{
       
   231 		if(iInbox->MailboxId() == aMsvId)
       
   232 			{
       
   233 			return iInbox;
       
   234 			}
       
   235 		}
       
   236 		
       
   237 	TInt count = iFolderList.Count();
       
   238 	
       
   239 	for(TInt i = 0; i < count; i++)
       
   240 		{
       
   241 		if(iFolderList[i]->MailboxId() == aMsvId)
       
   242 			{
       
   243 			return iFolderList[i];
       
   244 			}
       
   245 		}
       
   246 
       
   247 	// the folder does not exist
       
   248 	return NULL;
       
   249 	}
       
   250 
       
   251 /** 
       
   252 This function populates the CImapfolder object passed in by the caller using the TMsvId given to get the relevent folder from
       
   253 the message server.
       
   254 
       
   255 @param aMsvId.
       
   256 The TMsvId of the folder as stored in the message server to be use to find the imap folder 
       
   257 @return Returns NULL if the folder is not subscribed or does not exist, pointer to the CImapFolder object otherwise.
       
   258 */
       
   259 EXPORT_C CImapFolder* CImapSyncManager::GetTempFolderL(TMsvId aMsvId)
       
   260 	{
       
   261 	CImapFolder* tempfolder = NULL;
       
   262 	SetEntryL(aMsvId);
       
   263 	TMsvEmailEntry entry = iServerEntry.Entry();
       
   264 	tempfolder = CImapFolder::NewLC(*this, iServerEntry, entry, iImapSettings, KNullDesC());
       
   265 	CleanupStack::Pop(tempfolder);
       
   266 		
       
   267 	return tempfolder;
       
   268 	}
       
   269 
       
   270 /** 
       
   271 This function populates the CImapfolder object that represent the current service Inbox
       
   272 
       
   273 @return Returns the pointer to the CImapFolder representing the Inbox.
       
   274 */
       
   275 EXPORT_C CImapFolder* CImapSyncManager::Inbox()
       
   276 	{
       
   277 	return iInbox;
       
   278 	}
       
   279 	
       
   280 RArray<TUint>* CImapSyncManager::GetUnSubscribedFolderToDoList()
       
   281 	{
       
   282 	return iUnsubscribeList;
       
   283 	}
       
   284 	
       
   285 RArray<TUint>* CImapSyncManager::GetSubscribedFolderToDoList()
       
   286 	{
       
   287 	return iSubscribeList;
       
   288 	}
       
   289 
       
   290 
       
   291 /** 
       
   292 Search through the messaging server to find the entry that represented the inbox and if not already
       
   293 in the list of CImapFolder objects, create one.
       
   294 */
       
   295 void CImapSyncManager::GetInboxL()
       
   296 	{
       
   297 
       
   298 	// Remove the old inbox
       
   299 	delete iInbox;
       
   300 	iInbox = NULL;
       
   301 		
       
   302 	// First of all, synchronise the inbox
       
   303 	CMsvEntrySelection *findinbox=new (ELeave) CMsvEntrySelection;
       
   304 	CleanupStack::PushL(findinbox);
       
   305 	SetEntryL(iServiceId);
       
   306 	GetChildrenL(*findinbox);
       
   307 	
       
   308 	// Find inbox	
       
   309 	TMsvId inboxid=0;
       
   310 	for(TInt a=0;a<findinbox->Count();a++)
       
   311 		{
       
   312 		SetEntryL((*findinbox)[a]);
       
   313 		if(iServerEntry.Entry().iDetails.CompareF(KIMAP_INBOX)==0)
       
   314 			{
       
   315 			inboxid=(*findinbox)[a];
       
   316 			TMsvEmailEntry e = iServerEntry.Entry();
       
   317 			if((iInbox = GetFolderFromList(inboxid)) == NULL)
       
   318 				{
       
   319 				CImapFolder* tempfolder = CImapFolder::NewLC(*this, iServerEntry, e, iImapSettings, KIMAP_INBOX());
       
   320 				CleanupStack::Pop(tempfolder);
       
   321 				iInbox = tempfolder;
       
   322 				}
       
   323 
       
   324 			// Mailbox flag not set? It always should be. This will 'repair' it.
       
   325 			if(!e.Mailbox())
       
   326 				{
       
   327 				// Set it
       
   328 				e.SetMailbox(ETrue);
       
   329 				ChangeEntryL(e);
       
   330 				}
       
   331 			
       
   332 			// Found the inbox, so no need to search any further
       
   333 			break; // from for loop
       
   334 			}
       
   335 		}
       
   336 
       
   337 	// Clean up
       
   338 	CleanupStack::PopAndDestroy(findinbox);
       
   339 	findinbox = NULL;
       
   340 
       
   341 	// Not found/no entries?
       
   342 	if(inboxid == 0)
       
   343 		{
       
   344 		// Create an inbox entry below the service. This is a local-only
       
   345 		// creation as the server *WILL* have an inbox.
       
   346 		SetEntryL(iServiceId);
       
   347 		TMsvEmailEntry entry;
       
   348 
       
   349 		entry.iType = KUidMsvFolderEntry;
       
   350 		entry.iMtm = KUidMsgTypeIMAP4;
       
   351 		entry.iServiceId = iServiceId;
       
   352 		entry.SetMtmData1(0);
       
   353 		entry.SetMtmData2(0);
       
   354 		entry.SetMtmData3(0);
       
   355 		entry.iSize = 0;
       
   356 		entry.SetUID(0);
       
   357 		entry.SetValidUID(EFalse);
       
   358 		entry.SetMailbox(ETrue);
       
   359 		entry.SetLocalSubscription(ETrue);
       
   360 		entry.SetComplete(ETrue);
       
   361 		entry.iDetails.Set(KImapInboxDisplayName);
       
   362 		User::LeaveIfError(iServerEntry.CreateEntry(entry));
       
   363 
       
   364 		// Set inbox
       
   365 		// not there so add it
       
   366 		CImapFolder* tempfolder = CImapFolder::NewLC(*this, iServerEntry, entry, iImapSettings, KIMAP_INBOX());
       
   367 		CleanupStack::Pop(tempfolder);
       
   368 		iInbox = tempfolder;
       
   369 		}
       
   370 	}
       
   371 
       
   372 /**
       
   373 Synchronise outstanding delete operations on all subscribe folders on the IMAP service
       
   374 
       
   375 @param aStatus
       
   376 The TRequestStatus to complete
       
   377 @param aSession
       
   378 The session to be use for the sync operation
       
   379 */
       
   380 EXPORT_C void CImapSyncManager::SynchroniseDeletesL(TRequestStatus& /*aStatus*/, CImapSession& /*aSession*/)
       
   381 	{
       
   382 	}
       
   383 
       
   384 /**
       
   385 Function to synchronise the inbox only.
       
   386 
       
   387 @param aStatus
       
   388 The TRequestStatus to complete
       
   389 @param aSession
       
   390 The session to be use for the sync operation
       
   391 */
       
   392 EXPORT_C void CImapSyncManager::SynchroniseInboxL(TRequestStatus& aStatus, CImapSession& aSession)
       
   393 	{
       
   394 	//initialise progress 
       
   395 	iFoldersToDo=0;
       
   396 	iFoldersDone=0;
       
   397 	iFoldersNotFound=0;
       
   398 	iErrorCode=KErrNone;
       
   399 	iSyncDoSingleStep = ETrue;
       
   400 	
       
   401 	iSession = &aSession;
       
   402 	
       
   403 	// Note the invisibility
       
   404 	iNewFoldersAreInvisible = iImapSettings.UpdatingSeenFlags();
       
   405 	iPerformDeletes = iImapSettings.DeleteEmailsWhenDisconnecting();
       
   406 
       
   407 	// Get the synchronise settings
       
   408 	iSynchroniseStrategy = iImapSettings.Synchronise();
       
   409 	iSubscribeStrategy = iImapSettings.Subscribe();
       
   410 
       
   411 	GetInboxL();
       
   412 
       
   413 	// Reset stats: 1 folder remaining (inbox)
       
   414 	iFoldersToDo = 1;
       
   415 	iSyncProgressState = TImap4SyncProgress::ESyncInbox;
       
   416 	
       
   417 	// Synchronise with the inbox
       
   418 	iInbox->SelectL(iStatus, aSession, EFalse);
       
   419 	iSyncState = EInboxSelect;
       
   420 	iNextSyncAction = EInboxSync;
       
   421 
       
   422 	Queue(aStatus);
       
   423 	SetActive();
       
   424 	}
       
   425 	
       
   426 /**
       
   427 Synchronise the subscription status for the folders on the remote server only.
       
   428 
       
   429 @param aStatus
       
   430 The TRequestStatus to complete
       
   431 @param aSession
       
   432 The session to be use for the sync operation
       
   433 */
       
   434 EXPORT_C void CImapSyncManager::SynchroniseFolderSubscriptionsL(TRequestStatus& aStatus, CImapSession& aSession)
       
   435 	{
       
   436 	// Only do this step
       
   437 	iSyncDoSingleStep = ETrue;
       
   438 
       
   439 	// Save the session
       
   440 	iSession = &aSession;
       
   441 
       
   442 	// Run the sync folder subscriptions status step
       
   443 	// set iSyncState when folder subscription is kicked off in DoRunL()
       
   444 	iNextSyncAction = ECheckRemoteSubscription;
       
   445 
       
   446 	Queue(aStatus);
       
   447 	CompleteSelf();
       
   448 	SetActive();
       
   449 	}
       
   450 	
       
   451 /**
       
   452 At the first call the value of aFolderId should be set to 0. This parameter will be updated with
       
   453 each call. Therefore after each calll to this function the value of aFolderCounter should be check,
       
   454 if the value is -1 then the last folder has already been processed.
       
   455 The Inbox is not part of this function call.
       
   456 
       
   457 @param aFolderCounter
       
   458 Folder counter to keep track of the current folder to be process. 
       
   459 */
       
   460 EXPORT_C void CImapSyncManager::NextSubscribedFoldersL(TMsvId& aFolderId)
       
   461 	{
       
   462 	// Only do this step
       
   463 	iSyncDoSingleStep = ETrue;
       
   464 
       
   465 	if(aFolderId > 0)
       
   466 		{
       
   467 		// Get the next folder TMsvId and sets the variable
       
   468 		++iSyncFolderCounter;
       
   469 		if((iSyncFolderCounter) < iFolderList.Count())
       
   470 			{
       
   471 			CImapFolder *folder = iFolderList[iSyncFolderCounter];
       
   472 			aFolderId = folder->MailboxId();
       
   473 			}
       
   474 		else
       
   475 			{			
       
   476 			aFolderId = -1;
       
   477 			}
       
   478 		}
       
   479 	else if(aFolderId == 0)
       
   480 		{
       
   481 		iSyncFolderCounter = 0;
       
   482 
       
   483 		if(iFolderList.Count() > 0)
       
   484 			{
       
   485 			CImapFolder *folder = iFolderList[0];
       
   486 			aFolderId = folder->MailboxId();
       
   487 			}
       
   488 		else
       
   489 			{
       
   490 			aFolderId = -1;
       
   491 			}
       
   492 		}
       
   493 	else
       
   494 		{
       
   495 		aFolderId = -1;
       
   496 		__ASSERT_DEBUG(EFalse,TImapServerPanic::ImapPanic(TImapServerPanic::EImapSyncManagerInvalidFolderID));
       
   497 		}
       
   498 	}
       
   499 
       
   500 /**
       
   501 Perform the next synchronise step for all subscribed folders on the IMAP service.
       
   502 This function should only be call after one to NextSubscribedFoldersL to setup the folder to be synchronise.
       
   503 The Inbox will not be synchronise with this function call.
       
   504 
       
   505 @param aStatus
       
   506 The TRequestStatus to complete
       
   507 @param aSession
       
   508 The session to be use for the sync operation
       
   509 @param aFolderId
       
   510 Folder id to keep track of the current folder to be process. 
       
   511 */
       
   512 EXPORT_C void CImapSyncManager::SynchroniseSubscribedFoldersL(TRequestStatus& aStatus, CImapSession& aSession, TMsvId& aFolderId)
       
   513 	{
       
   514 	// Only do this step
       
   515 	iSyncDoSingleStep = ETrue;
       
   516 
       
   517 	// Save the session
       
   518 	iSession = &aSession;
       
   519 
       
   520 	// Run the sync folder subscriptions status step
       
   521 	if(aFolderId > 0)
       
   522 		{
       
   523 		iNextSyncAction = EFolderSelect;
       
   524 		Queue(aStatus);
       
   525 		CompleteSelf();
       
   526 		SetActive();
       
   527 		}
       
   528 	}
       
   529 
       
   530 /**
       
   531 Synchronises the local view of the directory structure on the remote IMAP server
       
   532 
       
   533 @param aStatus
       
   534 The TRequestStatus to complete
       
   535 @param aSession
       
   536 The session to be use for the sync operation
       
   537 */
       
   538 EXPORT_C void CImapSyncManager::SynchroniseFolderTreeL(TRequestStatus& aStatus, CImapSession& aSession)
       
   539 	{
       
   540 	// Only do this step
       
   541 	iSyncDoSingleStep = ETrue;
       
   542 
       
   543 	// Save the session
       
   544 	iSession = &aSession;
       
   545 
       
   546 	// Note where this list came from
       
   547 	iServiceId = iImapSettings.ServiceId();
       
   548 
       
   549 	// Create the synchronise tree object and starts the sync
       
   550 	if(iFolderTreeSync)
       
   551 		{
       
   552 		delete iFolderTreeSync;
       
   553 		iFolderTreeSync = NULL;
       
   554 		}
       
   555 
       
   556 	iSyncState = ESynchroniseTree;
       
   557 	iNextSyncAction = EEndSynchroniseTree;
       
   558 	//update the progress object
       
   559 	iSyncProgressState= TImap4SyncProgress::ESyncFolderTree;
       
   560 
       
   561 	iFolderTreeSync = CImapOpSyncFolderTree::NewL(iServerEntry, *iSession, *this, iImapSettings);
       
   562 	iFolderTreeSync->SynchroniseTreeL(iStatus);
       
   563 
       
   564 	Queue(aStatus);
       
   565 	SetActive();
       
   566 	}
       
   567 
       
   568 /**
       
   569 Callback function for the operation class CImapOpSyncSubs.
       
   570 Cycle through the list of local subscribed folders and creates one from the CImapListFolderInfo if
       
   571 it does not exist in the list.
       
   572 
       
   573 @param aFolderInfo
       
   574 The CImapListFolderInfo to be processed
       
   575 */
       
   576 #ifdef __IMAP_LOGGING
       
   577 void CImapSyncManager::AddSubscribedFolderFromInfoL(CImapListFolderInfo* aFolderInfo, TInt aLogId)
       
   578 #else //__IMAP_LOGGING
       
   579 void CImapSyncManager::AddSubscribedFolderFromInfoL(CImapListFolderInfo* aFolderInfo, TInt /*aLogId*/)
       
   580 #endif //__IMAP_LOGGING
       
   581 	{
       
   582 #ifdef __IMAP_LOGGING
       
   583 	HBufC8* tempBuf = HBufC8::NewL(aFolderInfo->FolderName().Length());
       
   584 	TPtr8 tempBufPtr = tempBuf->Des();
       
   585 	CnvUtfConverter::ConvertFromUnicodeToUtf7(tempBufPtr, aFolderInfo->FolderName(), EFalse);
       
   586 	__LOG_FORMAT((aLogId, "AddSubscribedFolderFromInfoL - %S", &tempBufPtr));
       
   587 	delete tempBuf;
       
   588 #endif
       
   589 
       
   590 	// Don't add the INBOX
       
   591 	if(aFolderInfo->FolderName().CompareF(KIMAP_INBOX) == 0)
       
   592 		{
       
   593 		return;
       
   594 		}
       
   595 
       
   596 	// Search the folder list and don't add it if it's already there
       
   597 	TInt foldercount = iFolderList.Count();
       
   598 	for (int i = 0; i < foldercount; i++)
       
   599 		{
       
   600 		if(iFolderList[i]->FullFolderPathL().Compare(aFolderInfo->FolderName()) == 0)
       
   601 			{
       
   602 			// Found the folder object just return
       
   603 			return;
       
   604 			}
       
   605 		}
       
   606 
       
   607 	TMsvId folderid = FindAndSetFolderL(aFolderInfo->FolderName(), aFolderInfo->iHierarchySeperator);
       
   608 	
       
   609 	if(folderid != -1)
       
   610 		{
       
   611 		// Set subscribed flag
       
   612 		TMsvEmailEntry entry = iServerEntry.Entry();
       
   613 		if(!entry.Subscribed())
       
   614 			{
       
   615 			// It needs changing, do it
       
   616 			entry.SetVisible(ETrue);
       
   617 			if (iSubscribeStrategy == EUpdateLocal || iSubscribeStrategy == EUpdateBoth)
       
   618 				{
       
   619 				// set local subscribe flag if updating local flags
       
   620 				entry.SetLocalSubscription(ETrue);
       
   621 				}
       
   622 			entry.SetSubscribed(ETrue);
       
   623 			ChangeEntryL(entry);
       
   624 			}
       
   625 
       
   626 		// Create and add the CImapfolder object
       
   627 		CImapFolder* tempfolder = CImapFolder::NewLC(*this, iServerEntry, entry, iImapSettings, KNullDesC());
       
   628 		iFolderList.AppendL(tempfolder);
       
   629 		CleanupStack::Pop(tempfolder);
       
   630 		__LOG_TEXT(aLogId, "Folder Added");
       
   631 		}
       
   632 	}
       
   633 
       
   634 /**
       
   635 Create a CImapFolder list of local subscribed folder from scratch
       
   636 */
       
   637 void CImapSyncManager::CreateLocalFolderListL()
       
   638 	{
       
   639 	// Clear list of folders to sync, and subscribe/unsubscribe lists
       
   640 	iFolderList.ResetAndDestroy();
       
   641 
       
   642 	AddLocalFoldersL(iImapSettings.ServiceId());
       
   643 	
       
   644 	// Complete any bulk entry changes that occured during AddLocalFoldersL()
       
   645 	iServerEntry.CompleteBulk();
       
   646 	}
       
   647 
       
   648 /**
       
   649 For a given folder id cycle through the current list of folders and create a new CImapFolder item 
       
   650 if it's not already in the list. Do not add the Inbox or the service.
       
   651 
       
   652 @param aFolder
       
   653 The TMsvId of the folder to be added.
       
   654 */
       
   655 void CImapSyncManager::AddIfNotThereL(TMsvId aFolder)
       
   656 	{
       
   657 	// first see if we already have this folder and return if we do
       
   658 	for (int i=0; i < iFolderList.Count(); i++)
       
   659 		{
       
   660 		if( iFolderList[i]->MailboxId() == aFolder)
       
   661 			{
       
   662 			return;
       
   663 			}
       
   664 		}
       
   665 
       
   666 	// don't add the inbox or service
       
   667 	if(aFolder == iInbox->MailboxId() || aFolder == iServiceId)
       
   668 		{
       
   669 		return;
       
   670 		}
       
   671 	
       
   672 	// visit folder
       
   673 	SetEntryL(aFolder);
       
   674 	TMsvEmailEntry e=iServerEntry.Entry();
       
   675 	// not there so add it
       
   676 	CImapFolder* tempfolder = CImapFolder::NewLC(*this, iServerEntry, e, iImapSettings, KNullDesC());
       
   677 	iFolderList.AppendL(tempfolder);
       
   678 	CleanupStack::Pop(tempfolder);
       
   679 	}
       
   680 
       
   681 /**
       
   682 Add local (subscribed) folders to iFolderList - this is the list of
       
   683 folders that are to be synchronised according to flags and settings.
       
   684 Recursive.
       
   685 
       
   686 Also updates subscription flags on the TMsvEntry for the folder
       
   687 and adds the folder to iSubscribeList or iUnsubscribeList if remote
       
   688 update of subscription flag is required. These arrays are used
       
   689 during subscription synchronisation later in the sync procedure.
       
   690 
       
   691 
       
   692 @param aFolder
       
   693 TMsvId of the folder in the local message store.
       
   694 */
       
   695 void CImapSyncManager::AddLocalFoldersL(const TMsvId aFolder)
       
   696 	{
       
   697 	// Select the entry
       
   698 	SetEntryL(aFolder);
       
   699 	TMsvEmailEntry entry = iServerEntry.Entry();
       
   700 
       
   701 	// Is it actually a folder or service? If not, ignore it. 
       
   702 	if(entry.iType != KUidMsvServiceEntry &&
       
   703 		entry.iType != KUidMsvFolderEntry)
       
   704 		{
       
   705 		return;
       
   706 		}
       
   707 
       
   708 	// What we do now depends on the strategy
       
   709 
       
   710 	// addthisone indicates this folder should be added to the list of folders
       
   711 	// that are to be synchronised according to subscription flags and settings.
       
   712 	TBool addthisone = EFalse;
       
   713 	
       
   714 	switch(iSynchroniseStrategy)
       
   715 		{
       
   716 	case EUseLocal:
       
   717 		{
       
   718 		// Is it locally subscribed?
       
   719 		if(entry.LocalSubscription())
       
   720 			{
       
   721 			addthisone = ETrue;
       
   722 			}
       
   723 		}
       
   724 		break;
       
   725 
       
   726 	case EUseRemote:
       
   727 		{
       
   728 		// Is it remotely subscribed?
       
   729 		if(entry.Subscribed())
       
   730 			{
       
   731 			addthisone = ETrue;
       
   732 			}
       
   733 		}
       
   734 		break;
       
   735 
       
   736 	case EUseCombination:
       
   737 		{
       
   738 		// Either will do
       
   739 		if(entry.LocalSubscription() || entry.Subscribed())
       
   740 			{
       
   741 			addthisone = ETrue;
       
   742 			}
       
   743 		}
       
   744 		break;
       
   745 	default:
       
   746 		{
       
   747 		__ASSERT_DEBUG(EFalse,TImapServerPanic::ImapPanic(TImapServerPanic::EAddLocalFolderInvalidSynchStrategy));
       
   748 		break;
       
   749 		}
       
   750 		}
       
   751 
       
   752 	
       
   753 	// Any childrenlist?
       
   754 	CMsvEntrySelection *childrenlist = new (ELeave) CMsvEntrySelection;
       
   755 	CleanupStack::PushL(childrenlist);
       
   756 	GetChildrenL(*childrenlist);
       
   757 	TInt noofchildren = childrenlist->Count();
       
   758 
       
   759 	if(aFolder != iInbox->MailboxId() && aFolder != iServiceId)
       
   760 		{
       
   761 		if(addthisone)
       
   762 			{
       
   763 			// Do updating
       
   764 			switch(iSubscribeStrategy)
       
   765 				{
       
   766 			case EUpdateNeither:
       
   767 				break;
       
   768 
       
   769 			case EUpdateLocal:
       
   770 				{
       
   771 				if(!entry.LocalSubscription())
       
   772 					{
       
   773 					// Update local subscription flag
       
   774 					entry.SetLocalSubscription(ETrue);
       
   775 					SetEntryL(aFolder);
       
   776 					ChangeEntryBulkL(entry); // bulk op completed by the caller of this method
       
   777 					}
       
   778 				}
       
   779 				break;
       
   780 			case EUpdateRemote:
       
   781 				{
       
   782 				if(!entry.Subscribed())
       
   783 					{
       
   784 					iSubscribeList->InsertInOrder(entry.Id());
       
   785 					}
       
   786 				}
       
   787 				break;
       
   788 			case EUpdateBoth:
       
   789 				{
       
   790 				if(entry.LocalSubscription() || entry.Subscribed())
       
   791 					{
       
   792 					if (!entry.LocalSubscription())
       
   793 						{
       
   794 						// Update local subscription flag
       
   795 						entry.SetLocalSubscription(ETrue);
       
   796 						SetEntryL(aFolder);
       
   797 						ChangeEntryBulkL(entry); // bulk op completed by the caller of this method
       
   798 						}
       
   799 					if (!entry.Subscribed())
       
   800 						{
       
   801 						// set the remote subscribed flag...
       
   802 						iSubscribeList->InsertInOrder(entry.Id());
       
   803 						}
       
   804 					}
       
   805 				}
       
   806 				break;
       
   807 			default:
       
   808 				{
       
   809 				__ASSERT_DEBUG(EFalse, TImapServerPanic::ImapPanic(TImapServerPanic::EAddLocalFolderInvalidSubscribeStrategy));
       
   810 				break;	
       
   811 				}
       
   812 				}
       
   813 			}
       
   814 		else // if(!addthisone)
       
   815 			{
       
   816 			// Do updating
       
   817 			switch(iSubscribeStrategy)
       
   818 				{
       
   819 			case EUpdateNeither:
       
   820 				break;
       
   821 
       
   822 			case EUpdateLocal:
       
   823 				{
       
   824 				if(entry.LocalSubscription())
       
   825 					{
       
   826 					// Update local subscription flag
       
   827 					entry.SetLocalSubscription(EFalse);
       
   828 					SetEntryL(aFolder);
       
   829 					ChangeEntryBulkL(entry); // bulk op completed by the caller of this method
       
   830 					}
       
   831 				}
       
   832 				break;
       
   833 			case EUpdateRemote:
       
   834 				{
       
   835 				if(entry.Subscribed())
       
   836 					{
       
   837 					iUnsubscribeList->InsertInOrder(entry.Id());
       
   838 					}
       
   839 				else if (entry.LocalSubscription())
       
   840 					{
       
   841 					iSubscribeList->InsertInOrder(entry.Id());
       
   842 					addthisone = ETrue;
       
   843 					}
       
   844 				}
       
   845 				break;
       
   846 			case EUpdateBoth:
       
   847 				{
       
   848 				if(entry.LocalSubscription() || entry.Subscribed())
       
   849 					{
       
   850 					if (!entry.LocalSubscription())
       
   851 						{
       
   852 						// Update local subscription flag
       
   853 						entry.SetLocalSubscription(ETrue);
       
   854 						SetEntryL(aFolder);
       
   855 						ChangeEntryBulkL(entry); // bulk op completed by the caller of this method
       
   856 						}
       
   857 					if (!entry.Subscribed())
       
   858 						{
       
   859 						iSubscribeList->InsertInOrder(entry.Id());
       
   860 						addthisone = ETrue;
       
   861 						}
       
   862 					}
       
   863 				}
       
   864 				break;	
       
   865 				} // end of switch 
       
   866 			} // end of if (addthisone)
       
   867 
       
   868 		// add subscribed afterwards
       
   869 		if(addthisone)
       
   870 			{
       
   871 			AddIfNotThereL(aFolder);
       
   872 			}
       
   873 		else
       
   874 			{
       
   875 			// This folder is not subscribed, but has childrenlist. 
       
   876 			// If any childrenlist are messages, then delete.
       
   877 			if(noofchildren)
       
   878 				{
       
   879 				// This folder is not subscribed to, so check if it has any messages.
       
   880 				// Do each in turn
       
   881 				TInt child = childrenlist->Count();
       
   882 				while (child--)
       
   883 					{
       
   884 					SetEntryL((*childrenlist)[child]);
       
   885 					TMsvEmailEntry deletingentry = iServerEntry.Entry();
       
   886 
       
   887 					// Is it a message?
       
   888 					if(deletingentry.iType == KUidMsvMessageEntry)
       
   889 						{
       
   890 						SetEntryL(deletingentry.Id());
       
   891 						SetEntryL(iServerEntry.Entry().Parent());
       
   892 						iServerEntry.DeleteEntry(deletingentry.Id());
       
   893 						}
       
   894 					}
       
   895 
       
   896 				// If we've some childrenlist then get the childrenlist list again
       
   897 				SetEntryL(aFolder);
       
   898 				GetChildrenL(*childrenlist);
       
   899 				noofchildren=childrenlist->Count();
       
   900 				} // end of if(noofchildren) 
       
   901 			}
       
   902 		} // end of if(aFolder != iInbox->MailboxId() && aFolder != iServiceId)
       
   903 	
       
   904 
       
   905 	// Any childrenlist?
       
   906 	if(noofchildren)
       
   907 		{
       
   908 		// Do each in turn
       
   909 		for(TInt child=0;child<childrenlist->Count();child++)
       
   910 			{
       
   911 			AddLocalFoldersL((*childrenlist)[child]);
       
   912 			}
       
   913 		
       
   914 		// Complete any bulk entry changes that occured during AddLocalFoldersL()
       
   915 		iServerEntry.CompleteBulk();
       
   916 		}
       
   917 
       
   918 	CleanupStack::PopAndDestroy(childrenlist);
       
   919 	}
       
   920 
       
   921 
       
   922 /**
       
   923 Deleting the child messages of the given folder from the message server.
       
   924 
       
   925 @param aDeleteFolderId
       
   926 The TMsvId of the foler whose content is to be deleted.
       
   927 */
       
   928 EXPORT_C void CImapSyncManager::DeleteFolderContentsL(TMsvId aDeleteFolderId)
       
   929 	{
       
   930 	// Select the entry
       
   931 	SetEntryL(aDeleteFolderId);
       
   932 	TMsvEmailEntry entry = iServerEntry.Entry();
       
   933 
       
   934 	// Is it actually a folder or service? If not, ignore it. 
       
   935 	if(entry.iType != KUidMsvServiceEntry &&
       
   936 		entry.iType != KUidMsvFolderEntry)
       
   937 		{
       
   938 		return;
       
   939 		}
       
   940 
       
   941 	// Any childrenlist?
       
   942 	CMsvEntrySelection *childrenlist = new (ELeave) CMsvEntrySelection;
       
   943 	CleanupStack::PushL(childrenlist);
       
   944 	GetChildrenL(*childrenlist);
       
   945 	TInt noofchildren = childrenlist->Count();
       
   946 
       
   947 	// Any childrenlist?
       
   948 	if(noofchildren)
       
   949 		{
       
   950 		// Do each in turn
       
   951 		for(TInt child = 0; child < childrenlist->Count(); ++child)
       
   952 			{
       
   953 			TMsvEntry* entryPtr;
       
   954 			TMsvId id = (*childrenlist)[child];
       
   955 			User::LeaveIfError(iServerEntry.GetEntryFromId(id, entryPtr));
       
   956 
       
   957 			// Is it a message? And is it real (not shadow)
       
   958 			if(entryPtr->iType == KUidMsvMessageEntry &&
       
   959 				entryPtr->iRelatedId == KMsvNullIndexEntryId )
       
   960 				{
       
   961 				// yes it is... remove it
       
   962 				TInt err (iServerEntry.DeleteEntry(id));
       
   963 				if(err == KErrInUse)
       
   964 					{
       
   965 					// Dont leave if err = KErrInUse
       
   966 					}
       
   967 				else
       
   968 					{
       
   969 					User::LeaveIfError(err);
       
   970 					}
       
   971 				}
       
   972 			}
       
   973 		}
       
   974 
       
   975 	CleanupStack::PopAndDestroy(childrenlist);
       
   976 	}
       
   977 
       
   978 /**
       
   979 Remove the given folder from the folder index and delete the contents.
       
   980 
       
   981 @param aDeleteFolderId
       
   982 The TMsvId of the foler to be deleted.
       
   983 */
       
   984 EXPORT_C void CImapSyncManager::RemoveFolderL(TMsvId aMsvId)
       
   985 	{
       
   986 	// Search the folder list and remove the folder
       
   987 	TInt foldercount = iFolderList.Count();
       
   988 	for (int i = 0; i < foldercount; i++)
       
   989 		{
       
   990 		if( iFolderList[i]->MailboxId() == aMsvId)
       
   991 			{
       
   992 			// Found the folder object remove then return
       
   993 			delete iFolderList[i];
       
   994 			iFolderList.Remove(i);
       
   995 			break;
       
   996 			}
       
   997 		}
       
   998 
       
   999 	DeleteFolderContentsL(aMsvId);
       
  1000 
       
  1001 	SetEntryL(aMsvId);
       
  1002 	TMsvEmailEntry entry = iServerEntry.Entry();
       
  1003 	SetEntryL(entry.Parent());
       
  1004 	iServerEntry.DeleteEntry(aMsvId);
       
  1005 	}
       
  1006 	
       
  1007 /**
       
  1008 Called to notify the sync manager of a change in a folder's name.
       
  1009 The TMsvEmailEntry for the folder is updated with the new name.
       
  1010 The CImapFolder object representing the folder and that of any children
       
  1011 folders affected by the namechange is also updated to show the new path.
       
  1012 This must be called after a remote folder has been renamed.
       
  1013 
       
  1014 @param aFolderId id of the folder that has been renamed
       
  1015 @param aNewName  the new folder name
       
  1016 */
       
  1017 EXPORT_C void CImapSyncManager::RenameLocalL(TMsvId aFolderId, const TDesC& aNewName)
       
  1018 	{
       
  1019 
       
  1020 	// First rename the folder on the local message server
       
  1021 	SetEntryL(aFolderId);
       
  1022 		
       
  1023 	TMsvEmailEntry entry = iServerEntry.Entry();
       
  1024 	entry.iDetails.Set(aNewName);
       
  1025 	ChangeEntryL(entry);
       
  1026 	
       
  1027 	// Search the folder list and rename the folder if we have it subscribed
       
  1028 	// then search the rest of the folder list and resets the full path for any subfolders.
       
  1029 	TInt foldercount = iFolderList.Count();
       
  1030 	CImapFolder* folder = NULL;
       
  1031 	
       
  1032 	for (int i = 0; i < foldercount; i++)
       
  1033 		{
       
  1034 		if( iFolderList[i]->MailboxId() == aFolderId)
       
  1035 			{
       
  1036 			folder = iFolderList[i];
       
  1037 			// Found the folder object
       
  1038 			break;
       
  1039 			}
       
  1040 		}
       
  1041 	
       
  1042 	if(folder)
       
  1043 		{
       
  1044 		// Save a copy of the old folder name
       
  1045 		RBuf folderparentnamebuffer;
       
  1046 		folderparentnamebuffer.CleanupClosePushL();
       
  1047 		folderparentnamebuffer.CreateL(folder->FullFolderPathL());
       
  1048 
       
  1049 		// reset the path for the rename folder
       
  1050 		// - this will be rebuilt when next requested
       
  1051 		folder->SetFullFolderPathL(KNullDesC());
       
  1052 		
       
  1053 		TPtrC folderparentpath;
       
  1054 		// Try and find the parent folder in the folder list
       
  1055 		for (int i = 0; i < foldercount; i++)
       
  1056 			{
       
  1057 			folderparentpath.Set((iFolderList[i]->FullFolderPathL().Left(folderparentnamebuffer.Length())));
       
  1058 			if( folderparentpath.Compare(folderparentnamebuffer) == 0)
       
  1059 				{
       
  1060 				// Found the parent name, reset the path
       
  1061 				iFolderList[i]->SetFullFolderPathL(KNullDesC());
       
  1062 				}
       
  1063 			}
       
  1064 			
       
  1065 		CleanupStack::PopAndDestroy(&folderparentnamebuffer);
       
  1066 		}
       
  1067 	}
       
  1068 
       
  1069 
       
  1070 /**
       
  1071 Find the folder in the message server using the given path the sets the server context.
       
  1072 
       
  1073 @param aFullPath
       
  1074 The full pathname of the folder relative to the service.
       
  1075 @param aHierarchySeperator
       
  1076 The character that is use as the path separator for the full pathname.
       
  1077 @return The TMsvId of the folder if it was found in the message server.
       
  1078 */
       
  1079 TMsvId CImapSyncManager::FindAndSetFolderL(const TPtrC& aFullPath, TChar& aHierarchySeperator)
       
  1080 	{
       
  1081 	TPtrC path(aFullPath);
       
  1082 	TMsvId foundfolderid = -1;
       
  1083 	
       
  1084 	if (iImapSettings.FolderPath().Length() != 0)
       
  1085 		{
       
  1086 		//FolderPath will be 8 bit Descriptor, so we need to convert into 16 bit
       
  1087 		HBufC* tempPath = HBufC::NewL(iImapSettings.FolderPath().Length());
       
  1088 		tempPath->Des().Copy(iImapSettings.FolderPath());
       
  1089 		
       
  1090 		if (path.Match(tempPath->Des()) == 0)
       
  1091 			{
       
  1092 			TInt separator = path.Locate(aHierarchySeperator);
       
  1093 			if (separator == iImapSettings.FolderPath().Length())
       
  1094 				{
       
  1095 				++separator;
       
  1096 				if (separator < path.Length())
       
  1097 					{
       
  1098 					path.Set(path.Mid(separator));
       
  1099 					}
       
  1100 				else
       
  1101 					{
       
  1102 					// Path contains only the settings FolderPath and separator. This is an error.
       
  1103 					delete tempPath;
       
  1104 					return KErrNotFound;
       
  1105 					}
       
  1106 				}
       
  1107 			}
       
  1108 		delete tempPath;
       
  1109 		}
       
  1110  			
       
  1111 	// Go down through path
       
  1112 	CMsvEntrySelection*	selection = new (ELeave) CMsvEntrySelection();
       
  1113 	CleanupStack::PushL(selection);
       
  1114 	
       
  1115 	TMsvId currentpos = iServiceId;
       
  1116 			
       
  1117 	while(currentpos)
       
  1118 		{
       
  1119 		// Truncate this bit of path: look for a hierarchy separator
       
  1120 		TInt separator = path.Locate(aHierarchySeperator);
       
  1121 		TPtrC element(path);
       
  1122 
       
  1123 		// Anything?
       
  1124 		if(separator != KErrNotFound)
       
  1125 			{
       
  1126 			// Truncate this element there
       
  1127 			element.Set(element.Left(separator));
       
  1128 			}
       
  1129 
       
  1130 		// Try to find this element at the search level
       
  1131 		SetEntryL(currentpos);
       
  1132 		GetChildrenL(*selection);
       
  1133 
       
  1134 		// Nothing? Give up.
       
  1135 		if(!selection->Count())
       
  1136 			{
       
  1137 			break;				// out of while
       
  1138 			}
       
  1139 			
       
  1140 		// Check all the children
       
  1141 		TInt a;
       
  1142 
       
  1143 		for(a = 0; a < selection->Count(); ++a)
       
  1144 			{
       
  1145 			// This one?
       
  1146 			SetEntryL((*selection)[a]);
       
  1147 
       
  1148 			// Check if the path element matches the current entry details field.
       
  1149 			// We need to do a specific check if the entry is the inbox, because
       
  1150 			// inbox is case insensitive.
       
  1151 			if ((iServerEntry.Entry().iType == KUidMsvFolderEntry && iServerEntry.Entry().iDetails.Compare(element) == 0 )||
       
  1152 			    (element.CompareF(KIMAP_INBOX) == 0 && EntryIsInbox(iServerEntry.Entry())))
       
  1153 				{
       
  1154 				// Found it! Are we at the end, ie no more elements?
       
  1155 				if(separator == KErrNotFound)
       
  1156 					{
       
  1157 					// Get the entry TMsvId
       
  1158 					TMsvEmailEntry entry = iServerEntry.Entry();
       
  1159 					foundfolderid = entry.Id();
       
  1160 					
       
  1161 					// All done: this will exit the loop
       
  1162 					currentpos = 0;
       
  1163 					break;
       
  1164 					}
       
  1165 				else
       
  1166 					{
       
  1167 					// Update path
       
  1168 					currentpos = (*selection)[a];
       
  1169 					path.Set(path.Mid(separator+1, path.Length()-separator-1));
       
  1170 
       
  1171 					// Exit loop
       
  1172 					break;
       
  1173 					}
       
  1174 				}
       
  1175 			}
       
  1176 
       
  1177 		if(a == selection->Count())
       
  1178 			{
       
  1179 			// Didn't find it. Humm
       
  1180 			// Didn't find entry : tree out of date?
       
  1181 			break;				// out of while
       
  1182 			}
       
  1183 		}
       
  1184 	CleanupStack::PopAndDestroy(selection);
       
  1185 	selection = NULL;
       
  1186 	
       
  1187 	return foundfolderid;
       
  1188 	}
       
  1189 
       
  1190 /**
       
  1191 Returns updated progress information on outstanding synchronisation operations.
       
  1192 
       
  1193 @param aProgress
       
  1194 The reference to the progress object to be fill in with the local progress information.
       
  1195 */
       
  1196 EXPORT_C void CImapSyncManager::Progress(TImap4SyncProgress& aProgress)
       
  1197 	{
       
  1198 	//copy values from member progress ob into aProgress
       
  1199 	//this includes the progress information set by CImapFolder
       
  1200 	
       
  1201 	if(iInbox)
       
  1202 		{
       
  1203 		iInbox->Progress(aProgress);
       
  1204 		}
       
  1205 	aProgress.iFoldersToDo=iFoldersToDo;
       
  1206 	aProgress.iFoldersDone=iFoldersDone;
       
  1207 	aProgress.iFoldersNotFound=iFoldersNotFound;
       
  1208 	aProgress.iState=iSyncProgressState;
       
  1209 	aProgress.iErrorCode=iErrorCode;	
       
  1210 	}
       
  1211 
       
  1212 /**
       
  1213 Called when async child completes with >=KErrNone
       
  1214 */
       
  1215 void CImapSyncManager::DoRunL()
       
  1216 	{
       
  1217 	//update the progress object
       
  1218 	iErrorCode=iStatus.Int();
       
  1219 	
       
  1220 	// Handle any server errors
       
  1221 	if(iStatus.Int()!=KErrNone)
       
  1222 		{
       
  1223 		if(TInt err=ProcessSessionError() != KErrNone)
       
  1224 			{
       
  1225 			Complete(err);
       
  1226 			return;
       
  1227 			}
       
  1228 		}
       
  1229 		
       
  1230 	switch(iNextSyncAction)
       
  1231 		{
       
  1232 	case EInboxSync:
       
  1233 		{
       
  1234 		// Start the sync of the current folder (ie, the inbox)
       
  1235 		iNextSyncAction = EEndSingleSyncStep;
       
  1236 		iSyncState = EInboxSync;
       
  1237 		iSyncProgressState=TImap4SyncProgress::ESyncInbox;
       
  1238         iInbox->SynchroniseL(iStatus, *iSession, EFalse, 0);
       
  1239 		SetActive();
       
  1240 		}
       
  1241 		break;
       
  1242 
       
  1243 	case ECheckRemoteSubscription:
       
  1244 		{
       
  1245 		// Create the sync subscriptions object to update the local subscriptions
       
  1246 		if(iSyncDoSingleStep)
       
  1247 			{
       
  1248 			iNextSyncAction = EEndSingleSyncStep;
       
  1249 			}
       
  1250 		else
       
  1251 			{
       
  1252 			iNextSyncAction = ESynchronise;
       
  1253 			}
       
  1254 		
       
  1255 		// Update folder tree
       
  1256 		if(iSyncSubs)
       
  1257 			{
       
  1258 			delete iSyncSubs;
       
  1259 			iSyncSubs = NULL;
       
  1260 			}
       
  1261 		
       
  1262 		iSyncState = ECheckRemoteSubscription;
       
  1263 		iSyncSubs = CImapOpSyncSubs::NewL(iServerEntry, *iSession, *this, iImapSettings);
       
  1264 		//update the progress object		
       
  1265 		iSyncProgressState=TImap4SyncProgress::EUpdateRemoteSubscription;
       
  1266 		iSyncSubs->SynchroniseSubscriptionsL(iStatus);
       
  1267 		SetActive();
       
  1268 		}
       
  1269 		break;
       
  1270 	case EFolderSelect:
       
  1271 		{	
       
  1272 		//update the progess object
       
  1273 		++iFoldersDone;
       
  1274 		iSyncProgressState=TImap4SyncProgress::ESyncOther;
       
  1275 		
       
  1276 		// This case is for the picking the next folder for the full sync.
       
  1277 		if(iSyncFolderCounter >= iFolderList.Count())
       
  1278 			{
       
  1279 			// Ran out of folders. Finishing sync
       
  1280 			Complete(iStatus.Int());
       
  1281 			}
       
  1282 		else
       
  1283 			{
       
  1284 			CImapFolder *folder = iFolderList[iSyncFolderCounter];
       
  1285 			iNextSyncAction = EFolderSynchronise;
       
  1286 			iSyncState = EFolderSelect;
       
  1287 			folder->SelectL(iStatus, *iSession);
       
  1288 			SetActive();
       
  1289 			}
       
  1290 		}
       
  1291 		break;
       
  1292 	case EFolderSynchronise:
       
  1293 		{
       
  1294 		// This case is for synching the selected folder during a full sync.
       
  1295 		// Back to select next folder
       
  1296 		CImapFolder *folder = iFolderList[iSyncFolderCounter];
       
  1297 
       
  1298 		if(iSyncDoSingleStep)
       
  1299 			{
       
  1300 			iNextSyncAction = EEndSingleSyncStep;
       
  1301 			}
       
  1302 		else
       
  1303 			{
       
  1304 			iNextSyncAction = EFolderSelect;
       
  1305 			++iSyncFolderCounter;
       
  1306 			}
       
  1307 		
       
  1308 		iSyncState = EFolderSynchronise;
       
  1309 		iSyncProgressState=TImap4SyncProgress::ESyncOther;
       
  1310 		folder->SynchroniseL(iStatus, *iSession, EFalse, 0);
       
  1311 		SetActive();
       
  1312 		}
       
  1313 		break;
       
  1314 	case ESynchronise:
       
  1315 		{
       
  1316 		// This case is for the full synching start with selecting the inbox.
       
  1317 		// Starts the full sync process by reseting the folder counter
       
  1318 		iSyncFolderCounter = 0;
       
  1319 
       
  1320 		iSyncState = ESynchronise;
       
  1321 		iNextSyncAction = EFolderSelect;
       
  1322 		CompleteSelf();
       
  1323 		SetActive();
       
  1324 		}
       
  1325 		break;
       
  1326 
       
  1327 	case EEndSynchroniseTree:
       
  1328 		{
       
  1329 		// We have finished synchronising the folder tree, so now build the
       
  1330 		// list of locally subscribed folders
       
  1331 		CreateLocalFolderListL();
       
  1332 		// Fall through to next state
       
  1333 		}
       
  1334 
       
  1335 	case EEndInboxSync:
       
  1336 		// Finishing the Synching of the inbox
       
  1337 	case EEndSingleSyncStep:
       
  1338 		{
       
  1339 		iSyncProgressState = TImap4SyncProgress::EIdle;
       
  1340 		Complete(iStatus.Int());
       
  1341 		}
       
  1342 		break;
       
  1343 	
       
  1344 	default:
       
  1345 		break;
       
  1346 		}
       
  1347 	}
       
  1348 
       
  1349 /**
       
  1350 Called when completing a client request.
       
  1351 
       
  1352 @param aErr
       
  1353 The completed error code.
       
  1354 */
       
  1355 void CImapSyncManager::DoComplete(TInt& aErr)
       
  1356 	{
       
  1357 	// clean up the internal states
       
  1358 	iSyncState = ENotSyncing;
       
  1359 	iNextSyncAction = ENotSyncing;
       
  1360 	iErrorCode = aErr;
       
  1361 	}
       
  1362 
       
  1363 /**
       
  1364 Handles any positive completion codes
       
  1365 */
       
  1366 TInt CImapSyncManager::ProcessSessionError()
       
  1367 	{
       
  1368 	TInt errCode = iStatus.Int();
       
  1369 	if( errCode==KErrImapNo || errCode==KErrImapBad)
       
  1370 		{
       
  1371 		ProcessNegativeServerResponse(errCode);
       
  1372 		}
       
  1373 	return errCode;
       
  1374 	}
       
  1375 
       
  1376 /** 
       
  1377 Specific handling for NO and BAD server responses.
       
  1378 The error code is updated to KErrNone if it has been successfully 
       
  1379 fielded by the sync manager.
       
  1380 
       
  1381 @param aErrCode
       
  1382 Reference to the error code. 
       
  1383 */
       
  1384 void CImapSyncManager::ProcessNegativeServerResponse(TInt& aErrCode)
       
  1385 	{
       
  1386 	// iSyncState describes current outstanding operation
       
  1387 	switch (iSyncState)
       
  1388 		{
       
  1389 	case EInboxSelect:
       
  1390 		{
       
  1391 		++iFoldersNotFound;
       
  1392 		break;
       
  1393 		}
       
  1394 	case EFolderSelect:
       
  1395 		{
       
  1396 		// SELECT folder has failed.. 
       
  1397 		++iFoldersNotFound;
       
  1398 		if(!iSyncDoSingleStep)
       
  1399 			{
       
  1400 			// Doing all folders... 
       
  1401 			// ignore error and proceed to the next
       
  1402 			iNextSyncAction = EFolderSelect;
       
  1403 			aErrCode = KErrNone;
       
  1404 			}
       
  1405 		break;
       
  1406 		}
       
  1407 	case EInboxSync:
       
  1408 	case ECheckRemoteSubscription:
       
  1409 	case EFolderSynchronise:
       
  1410 		{
       
  1411 		// NO/BAD responses should have been handled in the
       
  1412 		// folder or operation classes.
       
  1413 		break;
       
  1414 		}
       
  1415 	case ESynchronise:	// self completing state
       
  1416 	case EEndInboxSync:
       
  1417 	case EEndSynchroniseTree:
       
  1418 	case EEndSingleSyncStep:
       
  1419 	default:
       
  1420 		{
       
  1421 		// unexpected states.
       
  1422 		break;
       
  1423 		}
       
  1424 		} // end of switch (iSyncState)
       
  1425 	}
       
  1426 
       
  1427 
       
  1428 /**
       
  1429 "Silent" cancel for migration - 
       
  1430 Resets the error code to KErrNone following the cancel
       
  1431 */
       
  1432 EXPORT_C void CImapSyncManager::CancelForMigrate()
       
  1433 	{
       
  1434 	Cancel();
       
  1435 	iErrorCode=KErrNone;
       
  1436 	}
       
  1437 
       
  1438 /**
       
  1439 Cancels any outstanding asynchronous service requests.
       
  1440 */
       
  1441 void CImapSyncManager::DoCancel()
       
  1442 	{
       
  1443 	// iSyncState describes current outstanding operation
       
  1444 	switch (iSyncState)
       
  1445 		{
       
  1446 	case EInboxSelect:
       
  1447 	case EFolderSelect:
       
  1448 		{
       
  1449 		// Note that although select operations are performed on a folder they
       
  1450 		// actually pass our iStatus to the session, so that is why we cancel
       
  1451 		// the session for them.
       
  1452 		iSession->Cancel();
       
  1453 		break;
       
  1454 		}
       
  1455 	case EInboxSync:
       
  1456 		{
       
  1457 		iInbox->Cancel();
       
  1458 		break;
       
  1459 		}
       
  1460 	case ESynchroniseTree:
       
  1461 		{
       
  1462 		iFolderTreeSync->Cancel();
       
  1463 		break;
       
  1464 		}
       
  1465 	
       
  1466 	case ECheckRemoteSubscription:
       
  1467 		{
       
  1468 		iSyncSubs->Cancel();
       
  1469 		break;
       
  1470 		}
       
  1471 	case EFolderSynchronise:
       
  1472 		{
       
  1473 		(iFolderList[iSyncFolderCounter])->Cancel();
       
  1474 		break;
       
  1475 		}
       
  1476 
       
  1477 	case ESynchronise:	// self completing state
       
  1478 	case EEndInboxSync:
       
  1479 	case EEndSynchroniseTree:
       
  1480 	case EEndSingleSyncStep:
       
  1481 	case ENotSyncing:
       
  1482 		{
       
  1483 		break;
       
  1484 		}
       
  1485 
       
  1486 	default:
       
  1487 		{
       
  1488 		__ASSERT_DEBUG(EFalse,
       
  1489 		               TImapServerPanic::ImapPanic(TImapServerPanic::ESyncManagerCancelUnexpectedState));
       
  1490 		break;
       
  1491 		}
       
  1492 		} // end of switch
       
  1493 
       
  1494 	CMsgActive::DoCancel();
       
  1495 	}
       
  1496 
       
  1497 void CImapSyncManager::CompleteSelf()
       
  1498 	{
       
  1499 	TRequestStatus* status = &iStatus;
       
  1500 	iStatus = KRequestPending;
       
  1501 	User::RequestComplete(status, KErrNone);
       
  1502 	}
       
  1503 
       
  1504 TBool CImapSyncManager::InboxClearNewFlags()
       
  1505 	{
       
  1506 	return iInboxClearNewFlags;
       
  1507 	}
       
  1508 
       
  1509 TBool CImapSyncManager::NonInboxClearNewFlags()
       
  1510 	{
       
  1511 	return iNonInboxClearNewFlags;
       
  1512 	}
       
  1513 
       
  1514 EXPORT_C void CImapSyncManager::ResetInboxClearNewFlags()
       
  1515 	{
       
  1516 	iInboxClearNewFlags = EFalse;
       
  1517 	}
       
  1518 
       
  1519 EXPORT_C void CImapSyncManager::ResetNonInboxClearNewFlags()
       
  1520 	{
       
  1521 	iNonInboxClearNewFlags = EFalse;
       
  1522 	}
       
  1523 
       
  1524 /**
       
  1525 Checks if the entry passed in is the inbox.
       
  1526 
       
  1527 @param aEntry Entry to check
       
  1528 @return ETrue if entry is inbox, EFalse otherwise
       
  1529 */
       
  1530 TBool CImapSyncManager::EntryIsInbox(const TMsvEntry& aEntry)
       
  1531 	{
       
  1532 	if (aEntry.Parent() == iImapSettings.ServiceId() &&
       
  1533 	    aEntry.iDetails.CompareF(KIMAP_INBOX) == 0)
       
  1534 		{
       
  1535 		return ETrue;
       
  1536 		}
       
  1537 
       
  1538 	return EFalse;
       
  1539 	}
       
  1540 
       
  1541 /**
       
  1542 Returns pointer to the nth CImapFolder object in the subscribed folder array.
       
  1543 Also returns aNumSubscribedFolders updated with the total number of subscribed folders.
       
  1544 
       
  1545 @param aFolderId index in the array for requested folder, the nth subscribed folder (0 offset)
       
  1546 @param aNumSubscribedFolders updated with total number of subscribed folders.
       
  1547 @return  NULL if aFolderId exceeds the number of subscribed folders, 
       
  1548            pointer to subscribed CImapFolder object otherwise
       
  1549 */
       
  1550 EXPORT_C CImapFolder* CImapSyncManager::GetSubscribedFolder(TInt32 aFolderId, TInt32& aNumSubscribedFolders)
       
  1551 	{
       
  1552 	// return updated number of folders for progress reporting
       
  1553 	aNumSubscribedFolders = iFolderList.Count();
       
  1554 	
       
  1555 	if (aFolderId >= aNumSubscribedFolders)
       
  1556 		{
       
  1557 		return NULL;
       
  1558 		}
       
  1559 	else
       
  1560 		{
       
  1561 		return iFolderList[aFolderId];
       
  1562 		}
       
  1563 	}
       
  1564 
       
  1565 
       
  1566