// TFSEL.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//
   
#include <eikenv.h>
#include <basched.h>
#include <badesca.h>
#include <coecntrl.h>
#include <coeutils.h>
#include <eikfutil.h>
#include <eikappui.h>
#include <e32keys.h>
#include <eikdef.h>
#include <eikmenup.h>
#include <eikdialg.h>
#include <eikmenu.hrh>
#include <eikdialg.hrh>
#include <eikcmds.hrh>
#include <eikdclbx.h>
#include <eikdclbm.h>
#include <eikon.rsg>
#include <eikapp.h>
#include <eikdoc.h>
#include <tfsel.rsg>
#include "tfsel.hrh" 

///////////////////////////////////////////////////////////////////////////////////////////////////
enum TEikFileManagementOperation 
	{
	EEikFCopy, EEikFDelete, EEikFMove, EEikFRename, EEikFAttributes,
	EEikNewFolder, EEikFormatDisk
	};

class CEikFileProgressDialog;

class CEikFileHandler : public CActive, public MFileManObserver
	{
public:
	IMPORT_C CEikFileHandler();
	IMPORT_C ~CEikFileHandler();
	IMPORT_C void ConstructL(CFileMan* aFileMan);
	IMPORT_C CFileMan* FileMan() const;
	IMPORT_C virtual void SetOperationL(TInt aOperation, const CDesCArray* aSourceFullNameArray, const TFileName* aTargetFullName);
	IMPORT_C virtual void SetOperationL(TInt aOperation, const CDesCArray* aSourceFullNameArray, TUint aDirEntryAttributesSetMask, TUint aDirEntryAttributesClearMask);
	IMPORT_C virtual void Start();
protected:					
	IMPORT_C virtual TInt PerformOperationL();
	IMPORT_C virtual void UpdateFileProgressDialogL(const TFileName& aSourceFullName, const TFileName& aTargetFullName);
	IMPORT_C virtual void HandleFileServerErrorL();
	IMPORT_C virtual void HandleAlreadyExistsErrorL();
	IMPORT_C virtual void HandleRmDirFailureL(const TDesC& aFolderFullName, TInt aRetCode);
protected: // from CActive
	IMPORT_C virtual void DoCancel();
	IMPORT_C virtual void RunL();
protected: // from MFileManObserver
	IMPORT_C virtual TControl NotifyFileManStarted();
	// IMPORT_C virtual TControl NotifyFileManOperation();
	IMPORT_C virtual TControl NotifyFileManEnded();
private:
	void DetermineUserReplyFromExitButtonId(TInt aExitButtonId);
private:	
	CFileMan* iFileMan;
	RFs& iFsSession;
	CEikFileProgressDialog* iProgressDialog;
	TInt iOperation;
	TUint iDirEntryAttributesSetMask;
	TUint iDirEntryAttributesClearMask;
	const CDesCArray* iSourceFullNameArray;
	const TFileName* iTargetFullName;
	TInt iIndex;
	TBool iConfirmedForAllFiles;
	TBool iRetryingCurrentOperation;
	TBool iErrorHasBeenHandled;
	// TParse iTempParse1;
	// TParse iTempParse2;
	TFileName iTempName;
	// TBuf<200> iTextMsg;
	// TBuf<120> iFormatStr;
	TInt iInfoDialogId;
	TFileName iProgressText1;
	TFileName iProgressText2;
	TInt iUserReply;
	TFileName iCurrentSource;
	TFileName iCurrentTarget;
	TInt iLastError;
	TFileManError iErrorInfo;
	};
 

class CEikFileProgressDialog : public CEikDialog
    {
public:
    IMPORT_C CEikFileProgressDialog(CEikFileHandler* aFileHandler);
	IMPORT_C void SetLabelsL(const TDesC& aLabel1, const TDesC& aLabel2);
	IMPORT_C virtual void HandleOperationEndedL();
protected: 
	IMPORT_C virtual void PreLayoutDynInitL();
	IMPORT_C virtual void PostLayoutDynInitL();
    IMPORT_C virtual TBool OkToExitL(TInt aButtonId);
protected:
	CEikFileHandler* iFileHandler;
	const CFont* iFont;
    };


class CEikFileManagementDialog : public CEikDialog
	{
protected:
	enum TFlags
		{
		EMultiSelectionAllowed		= 0x0001,
		EOwnSelectionArray			= 0x0002
		};
protected:
	IMPORT_C CEikFileManagementDialog(CDesCArray* aSelectedFullNamesArray);
	IMPORT_C CEikFileManagementDialog(TFileName* aSelectedFullName);
	IMPORT_C virtual ~CEikFileManagementDialog();
	IMPORT_C virtual void PreLayoutDynInitL();
	IMPORT_C virtual TBool OkToExitL(TInt aButtonId);
	IMPORT_C virtual void PerformValidationChecksL();
	virtual TBool PerformRequestedOperationL() = 0;
	IMPORT_C virtual void CheckDriveL(const TDesC& aFullName);
	IMPORT_C virtual void HandleBrowseButtonL();
	IMPORT_C virtual void InitializeControlsL();
	IMPORT_C virtual void SetDialogTitleL();
	// IMPORT_C static TFileName MostSignificantPartOfFullName(const TDesC& aFullName);
	// IMPORT_C static TInt GetFileOrFolderConfirmationL(TInt aDialogTitleResId, TInt aWarningMessageResId, const TDesC& aFullName);
protected:
	CDesCArray* iSelectedFullNamesArray;
	TFileName* iSelectedFullName;
	TInt iOperation;
	TFileName iTargetFullName;
	TInt iUserReply;
	CEikFileHandler* iFileHandler;
	CFileMan* iFileMan;
	TInt iFileManDialogFlags;
	};

class CEikFileOrFolderAttributesDialog : public CEikFileManagementDialog
	{
public:
	IMPORT_C CEikFileOrFolderAttributesDialog(CDesCArray* aSelectedFullNamesArray);
private: // inherited
	IMPORT_C virtual void InitializeControlsL();
	IMPORT_C virtual TBool PerformRequestedOperationL();
	IMPORT_C virtual void SetDialogTitleL();
	IMPORT_C void DetermineDirEntryAttributes();
private:
	TUint iDirEntryAttributesSetMask;
	TUint iDirEntryAttributesClearMask;
	};

class CEikDiskFormatDialog : public CEikDialog
	{
public:
	IMPORT_C CEikDiskFormatDialog();
private: // new
	IMPORT_C TBool GetUserConfirmationL();
	IMPORT_C TInt PerformQuickDiskFormat();
private: // inherited
	IMPORT_C virtual void PreLayoutDynInitL();
	IMPORT_C virtual TBool OkToExitL(TInt aButtonId);
	};


class CEikDiskNameDialog : public CEikDialog
	{
public:
	IMPORT_C CEikDiskNameDialog();
private: // inherited
	IMPORT_C virtual void PreLayoutDynInitL();
	IMPORT_C virtual TBool OkToExitL(TInt aButtonId);
	IMPORT_C virtual void HandleControlStateChangeL(TInt aControlId);
private: // new
	void SetDriveNameEditBoxFromDriveSelector();
	};


class CEikDiskCopyDialog : public CEikFileManagementDialog
	{
public:
	IMPORT_C CEikDiskCopyDialog(TFileName* aPath);
private: // inherited
	IMPORT_C virtual void PerformValidationChecksL();
	IMPORT_C virtual TBool PerformRequestedOperationL();
	IMPORT_C virtual void InitializeControlsL();
	};


class CEikFileOrFolderDeleteDialog : public CEikFileManagementDialog
	{
public:
	IMPORT_C CEikFileOrFolderDeleteDialog(CDesCArray* aSelectedFullNamesArray);
private: // new
	IMPORT_C TBool GetUserConfirmationL();
private: // inherited
	IMPORT_C virtual TBool OkToExitL(TInt aButtonId);
	IMPORT_C virtual TBool PerformRequestedOperationL();
	IMPORT_C virtual void SetDialogTitleL();
	};


class CEikSingleFileCopyDialog : public CEikFileManagementDialog
	{
public:
	IMPORT_C CEikSingleFileCopyDialog(TFileName* aFolderName);
protected: // inherited
	IMPORT_C virtual void PerformValidationChecksL();
	IMPORT_C virtual TBool PerformRequestedOperationL();
	IMPORT_C virtual void InitializeControlsL();
	IMPORT_C virtual void SetDialogTitleL();
	};


class CEikMultipleFilesOrFoldersCopyDialog : public CEikFileManagementDialog
	{
public:
	IMPORT_C CEikMultipleFilesOrFoldersCopyDialog(CDesCArray* aSelectedFullNamesArray);
protected: // inherited
	IMPORT_C virtual void PerformValidationChecksL();
	IMPORT_C virtual TBool PerformRequestedOperationL();
	IMPORT_C virtual void InitializeControlsL();
	IMPORT_C virtual void SetDialogTitleL();
	};


class CEikFileOrFolderMoveDialog : public CEikFileManagementDialog
	{
public:
	IMPORT_C CEikFileOrFolderMoveDialog(CDesCArray* aSelectedFullNamesArray);
protected: // inherited
	IMPORT_C virtual void PerformValidationChecksL();
	IMPORT_C virtual TBool PerformRequestedOperationL();
	IMPORT_C virtual void InitializeControlsL();
	IMPORT_C virtual void SetDialogTitleL();
	};


class CEikFileRenameDialog : public CEikFileManagementDialog
	{
public:
	IMPORT_C CEikFileRenameDialog(TFileName* aFileName);
private: // inherited
	IMPORT_C virtual void PerformValidationChecksL();
	IMPORT_C virtual TBool PerformRequestedOperationL();
	IMPORT_C virtual void InitializeControlsL();
	IMPORT_C virtual void SetDialogTitleL();
	};


class CEikFolderRenameDialog : public CEikFileManagementDialog
	{
public:
	IMPORT_C CEikFolderRenameDialog(TFileName* aFolderName);
private: // inherited
	IMPORT_C virtual void PerformValidationChecksL();
	IMPORT_C virtual TBool PerformRequestedOperationL();
	IMPORT_C virtual void InitializeControlsL();
	IMPORT_C virtual void SetDialogTitleL();
	};


///////////////////////////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////////////////////////
#include "fmdlg.hrh"
#include <eikcfdlg.hrh>
#include <eikdialg.hrh>
#include <eikfbrow.h>
#include <badesca.h>
#include <coeutils.h>
#include <eikenv.h>
#include <f32file.h>
#include <eikfsel.h>
#include <eiklabel.h>
#include <eikprogi.h>
#include <eikinfo.h>
#include <eikfutil.h>
#include <eikon.rsg>

#include <eikbutb.h>

const TInt KMaxDisplayedFullNameLen	= 30;
const TInt KMaxDisplayedFullNameLenInMsg = 20;

const TInt KMaxDirEntryNameLengthInDialogTitleBar = 20;

const TInt KMaxDialogTitleLength = 50;

const TInt KMaxWarningMsgLength = 64;

const TInt KMaxErrorMsgLength = 64;

#if defined(__WINS__)
	const TInt KMaxFileNameLen = 200;
#else
	const TInt KMaxFileNameLen = KMaxFileName;
#endif

static TInt IsFolder(const TDesC& aFullName, TBool& aIsFolder)
	{
	TParsePtrC parse(aFullName);
	if ((parse.DriveAndPath().Length() == 3) && (aFullName.Length() == 3))	
		{
		aIsFolder = ETrue;
		return(KErrNone);
		}
	TEntry entry;
	TInt retcode = CEikonEnv::Static()->FsSession().Entry(aFullName, entry);
	if (retcode == KErrNone)
		aIsFolder = (entry.iAtt & KEntryAttDir);
	return(retcode);
	}

static TFileName MostSignificantPartOfFullName(const TDesC& aFullName)
	{
	TBool entryIsAFolder;
	TInt retcode = IsFolder(aFullName, entryIsAFolder);
	if (retcode != KErrNone)
		return(_L(""));
	if (entryIsAFolder)
		return (EikFileUtils::FolderNameFromFullName(aFullName));
	// assume aFullName refers to a file
	TParsePtrC parse(aFullName);
	return(parse.NameAndExt());
	}

static TInt GetFileOrFolderConfirmationL(TInt aDialogTitleResId, TInt aWarningMessageResId, const TDesC& aFullName)
	{
	TBuf<KMaxDialogTitleLength> title;
	CEikonEnv* env = CEikonEnv::Static();
	env->ReadResource(title, aDialogTitleResId);
	TBuf<KMaxWarningMsgLength> warningMsgFormatStr;
	TBuf<KMaxWarningMsgLength> warningMsg;
	TBool entryIsAFolder = EFalse;
	TInt retcode = KErrNone;
	retcode = IsFolder(aFullName, entryIsAFolder);
	User::LeaveIfError(retcode);
	TBuf<KMaxDisplayedFullNameLenInMsg> abbreviatedName;
	if (entryIsAFolder)
		EikFileUtils::AbbreviateFileName(EikFileUtils::FolderNameFromFullName(aFullName), abbreviatedName);
	else
		EikFileUtils::AbbreviateFileName(aFullName, abbreviatedName);
	env->ReadResource(warningMsgFormatStr, aWarningMessageResId);
	warningMsg.Format(warningMsgFormatStr, &abbreviatedName);
	return(env->QueryWinL(title, warningMsg));
	}


// class CEikFileHandler

EXPORT_C CEikFileHandler::CEikFileHandler() 
	: CActive(CActive::EPriorityLow), iFsSession(CEikonEnv::Static()->FsSession())
    {
	}

EXPORT_C CEikFileHandler::~CEikFileHandler()
	{
	Cancel();
	}

EXPORT_C void CEikFileHandler::ConstructL(CFileMan* aFileMan)
	{
	iFileMan = aFileMan;
	CActiveScheduler::Add(this);
	}

EXPORT_C CFileMan* CEikFileHandler::FileMan() const
	{
	return iFileMan;
	}

EXPORT_C void CEikFileHandler::UpdateFileProgressDialogL(const TFileName& aSourceFullName, const TFileName& aTargetFullName)
	{
	TBuf<KMaxDisplayedFullNameLen> abbrevSourceName;
	EikFileUtils::AbbreviateFileName(aSourceFullName, abbrevSourceName);
	TBuf<KMaxDisplayedFullNameLen> abbrevTargetName;
	EikFileUtils::AbbreviateFileName(aTargetFullName, abbrevTargetName);
	iProgressText1.Zero();
	iProgressText2.Zero();
	if (iOperation == EEikFAttributes)
		{
		iProgressText1 = _L("Setting properties of ");
		iProgressText1.Append(abbrevSourceName);
		}
	if (iOperation == EEikFCopy)
		{
		iProgressText1 = _L("Copying ");
		iProgressText1.Append(abbrevSourceName);
		iProgressText2 = _L("to ");
		iProgressText2.Append(abbrevTargetName);
		}
	else if (iOperation == EEikFMove)
		{
		iProgressText1 = _L("Moving ");
		iProgressText1.Append(abbrevSourceName);
		iProgressText2 = _L("to ");
		iProgressText2.Append(abbrevTargetName);
		}
	else if (iOperation == EEikFRename)
		{
		iProgressText1 = _L("Renaming ");
		iProgressText1.Append(abbrevSourceName);
		iProgressText2 = _L("to ");
		iProgressText2.Append(abbrevTargetName);
		}
	else if (iOperation == EEikFDelete)
		{
		iProgressText1 = _L("Deleting ");
		iProgressText1.Append(abbrevSourceName);
		}
	iProgressDialog->SetLabelsL(iProgressText1, iProgressText2);
	}

EXPORT_C MFileManObserver::TControl CEikFileHandler::NotifyFileManStarted()
	{
	if (iProgressDialog == NULL)
		return(EContinue);

	CFileMan* fileMan = this->FileMan();
	// CFileMan::TAction action = fileMan->CurrentAction();
	TFileName currentSource;
	fileMan->GetCurrentSource(currentSource);
	TFileName currentTarget;
	fileMan->GetCurrentTarget(currentTarget);

	if (iProgressDialog)
		{
		TRAPD(errorCode, UpdateFileProgressDialogL(currentSource, currentTarget));
		if (errorCode)
			{
			CEikonEnv::Static()->HandleError(errorCode);
			iUserReply = EEikAbortFileOp;
			return EAbort;
			}
		}

	return EContinue;
	}

EXPORT_C MFileManObserver::TControl CEikFileHandler::NotifyFileManEnded()
	{
	CFileMan* fileMan = this->FileMan();
	// CFileMan::TAction action = fileMan->CurrentAction();
	fileMan->GetCurrentSource(iCurrentSource);
	fileMan->GetCurrentTarget(iCurrentTarget);
	iLastError = fileMan->GetLastError();
	iErrorInfo = fileMan->GetMoreInfoAboutError();
	if (iLastError != KErrNone)
		{
		// need to trap any called functions that may leave
		TRAPD(errorCode, HandleFileServerErrorL());
		if (errorCode != KErrNone)
			{
			CEikonEnv::Static()->HandleError(errorCode);
			iUserReply = EEikAbortFileOp;
			return EAbort;
			}
		TPtrC sourceFullName((*iSourceFullNameArray)[iIndex]);
		TBool currentEntryIsAFolder;
		TInt retcode = IsFolder(sourceFullName, currentEntryIsAFolder);
		if (retcode != KErrNone)
			{
			CEikonEnv::Static()->HandleError(retcode);
			iUserReply = EEikAbortFileOp;
			return EAbort;
			}
		if (currentEntryIsAFolder)
			{
			if (iUserReply == EEikRetryOpOnCurrFile)
				return ERetry;
			if (iUserReply == EEikAbortFileOp)
				return EAbort;
			}
		}
	return EContinue;
	}

void CEikFileHandler::DetermineUserReplyFromExitButtonId(TInt aExitButtonId)
	{
	// note that if a button with the id "EEikBidCancel" is pressed, we need to test for 0 (since this is what the dialog's ExecuteLD function returns)
	if (iInfoDialogId == R_EIK_DIALOG_SINGLE_FILE_REPLACE)
		iUserReply = ((aExitButtonId == 0) ? EEikRejectOpOnCurrFile : EEikConfirmOpOnCurrFile);
	else if (iInfoDialogId == R_EIK_DIALOG_MULTI_FILE_REPLACE)
		{
		if (aExitButtonId == 0)
			iUserReply = EEikRejectOpOnCurrFile;
		else if (aExitButtonId == EEikBidYes)
			iUserReply = EEikConfirmOpOnCurrFile;
		else if (aExitButtonId == EEikConfirmOpOnAllFiles)
			{
			iUserReply = aExitButtonId;
			iConfirmedForAllFiles = ETrue;
			}
		else
			iUserReply = aExitButtonId;
		}
	else if (iInfoDialogId == R_EIK_DIALOG_SINGLE_FILE_ERROR)
		iUserReply = ((aExitButtonId == 0) ? EEikAbortFileOp : EEikRetryOpOnCurrFile);
	else if (iInfoDialogId == R_EIK_DIALOG_MULTI_FILE_ERROR)
		{
		if (aExitButtonId == 0)
			iUserReply = EEikAbortFileOp; 
		else if (aExitButtonId == EEikBidOk)
			iUserReply = EEikSkipOpOnCurrFile;
		else
			iUserReply = EEikRetryOpOnCurrFile;
		}
	else // must be an irrecoverable error
		iUserReply = EEikAbortFileOp;
	}

EXPORT_C void CEikFileHandler::HandleFileServerErrorL()
	{
	iUserReply = EEikAbortFileOp;

	iErrorHasBeenHandled = ETrue;

	CEikonEnv* env = CEikonEnv::Static();
	TBuf<KMaxErrorMsgLength>* errorMsg = new(ELeave) TBuf<KMaxErrorMsgLength>;
	CleanupStack::PushL(errorMsg);
	TParsePtrC sourceParse(iCurrentSource);
	TParsePtrC targetParse(iCurrentTarget);
	TBuf<KMaxDisplayedFullNameLenInMsg> abbrevSourceName;
	TBuf<KMaxDisplayedFullNameLenInMsg> abbrevTargetName;

	EikFileUtils::AbbreviateFileName(sourceParse.NameAndExt(), abbrevSourceName);
	if (iCurrentTarget.Length() > 0)
		EikFileUtils::AbbreviateFileName(targetParse.NameAndExt(), abbrevTargetName);
	else
		abbrevTargetName = _L("");

	TPtrC sourceFullName((*iSourceFullNameArray)[iIndex]);
	TBool isFolder;
	TInt retcode = IsFolder(sourceFullName, isFolder);
	User::LeaveIfError(retcode);

	if (iLastError == KErrAlreadyExists)
		{
		if (iConfirmedForAllFiles || iRetryingCurrentOperation)
			{
			iUserReply = EEikConfirmOpOnCurrFile;
			CleanupStack::PopAndDestroy();   // "errorMsg"
			return;
			}
		TInt sourceCount = iSourceFullNameArray->Count();
		TBool noMoreEntriesInTheQueue = (sourceCount == 1) || (iIndex == (sourceCount-1));
		TBuf<KMaxDialogTitleLength> infoDialogTitle;
		env->ReadResource(infoDialogTitle, R_EIK_TBUF_DIALOG_TITLE_CONFIRM_FILE_REPLACE);
		if (isFolder)
			iInfoDialogId = R_EIK_DIALOG_MULTI_FILE_REPLACE;
		else
			iInfoDialogId = noMoreEntriesInTheQueue ? R_EIK_DIALOG_SINGLE_FILE_REPLACE : R_EIK_DIALOG_MULTI_FILE_REPLACE;
		TUint attributes;
		iFsSession.Att(iCurrentTarget, attributes);
		if (attributes & KEntryAttReadOnly)
			errorMsg->Format(_L("Replace read-only file \"%S\"?"), &abbrevTargetName);
		else
			errorMsg->Format(_L("Replace file \"%S\"?"), &abbrevTargetName);
		CEikDialog* infoDialog = new(ELeave) CEikInfoDialog(infoDialogTitle, *errorMsg, CEikInfoDialog::EIgnoreEnter);
		TInt exitButtonId = infoDialog->ExecuteLD(iInfoDialogId);
		DetermineUserReplyFromExitButtonId(exitButtonId);
		if (iUserReply == EEikRetryOpOnCurrFile)
			iRetryingCurrentOperation = ETrue;
		CleanupStack::PopAndDestroy();	// "errorMsg"
		return;
		}

	TInt sourceCount = iSourceFullNameArray->Count();
	TBool noMoreEntriesInTheQueue = (sourceCount == 1) || (iIndex == (sourceCount-1));
	TBuf<KMaxDialogTitleLength> infoDialogTitle;
	env->ReadResource(infoDialogTitle, R_EIK_TBUF_DIALOG_TITLE_ERROR);

	if (isFolder)
		iInfoDialogId = R_EIK_DIALOG_MULTI_FILE_ERROR;
	else
		iInfoDialogId = noMoreEntriesInTheQueue ? R_EIK_DIALOG_SINGLE_FILE_ERROR : R_EIK_DIALOG_MULTI_FILE_ERROR;
	
	if (iLastError == KErrInUse)
		{
		if (iErrorInfo == ETrgOpenFailed)
			errorMsg->Format(_L("\"%S\" is in use"), &abbrevTargetName);
		else
			errorMsg->Format(_L("\"%S\" is in use"), &abbrevSourceName);
		}
	else if (iLastError == KErrAccessDenied)
		{
		if (iErrorInfo == ETrgOpenFailed)
			errorMsg->Format(_L("\"%S\" is read-only"), &abbrevTargetName);
		else
			errorMsg->Format(_L("\"%S\" is read-only"), &abbrevSourceName);
		}
	else if (iLastError == KErrDiskFull)
		errorMsg->Format(_L("Disk is full"));
	else if (iLastError == KErrNotReady)
		{
		TBuf<1> driveLetter;
		if (iErrorInfo == ETrgOpenFailed)
			driveLetter.Append(targetParse.Drive().Left(1));
		else
			driveLetter.Append(sourceParse.Drive().Left(1));
		errorMsg->Format(_L("Disk \"%S\" is absent"), &driveLetter);
		}
	else if (iLastError == KErrCorrupt)
		errorMsg->Format(_L("Disk is corrupt"));
	else if (iLastError == KErrBadName)
		{
		if (iErrorInfo == ETrgOpenFailed)
			errorMsg->Format(_L("\"%S\" is an invalid name"), &abbrevTargetName);
		else
			errorMsg->Format(_L("\"%S\" is an invalid name"), &abbrevSourceName);
		iInfoDialogId = R_EIK_DIALOG_IRRECOVERABLE_FILE_ERROR;
		}
	else
		errorMsg->Format(_L("Requested operation cannot be completed: Error %d"), iLastError);
	CEikDialog* infoDialog = new(ELeave) CEikInfoDialog(infoDialogTitle, *errorMsg);
	TInt exitButtonId = infoDialog->ExecuteLD(iInfoDialogId);
	DetermineUserReplyFromExitButtonId(exitButtonId);
	if (iUserReply == EEikRetryOpOnCurrFile)
		iRetryingCurrentOperation = ETrue;
	CleanupStack::PopAndDestroy();	// "errorMsg"
	}

EXPORT_C void CEikFileHandler::HandleAlreadyExistsErrorL()
	{
	TInt errorCode = iFsSession.Delete(iCurrentTarget);
	if (errorCode != KErrNone)
		{
		TBuf<KMaxErrorMsgLength> errorMsg;
		if (errorCode == KErrAccessDenied)		// i.e. file in target folder is read-only
			{
			iFsSession.SetAtt(iCurrentTarget, 0, KEntryAttReadOnly);
			errorCode = iFsSession.Delete(iCurrentTarget);
			} 
		else if (errorCode == KErrInUse)		// i.e. file in target folder is being used
			{
			TParsePtrC targetParse(iCurrentTarget);
			TBuf<KMaxDisplayedFullNameLenInMsg> abbrevTargetName;
			EikFileUtils::AbbreviateFileName(targetParse.NameAndExt(), abbrevTargetName);
			errorMsg.Format(_L("\"%S\" is in use"), &abbrevTargetName);
			TBuf<KMaxDialogTitleLength> infoDialogTitle;
			CEikonEnv::Static()->ReadResource(infoDialogTitle, R_EIK_TBUF_DIALOG_TITLE_ERROR);
			CEikDialog* infoDialog = new(ELeave) CEikInfoDialog(infoDialogTitle, errorMsg);
			if (infoDialog->ExecuteLD(R_EIK_DIALOG_SINGLE_FILE_ERROR))
				iRetryingCurrentOperation = ETrue;
			else
				++iIndex;
			CleanupStack::PopAndDestroy();   // "errorMsg"
			}
		else
			{
			TParsePtrC targetSource(iCurrentSource);
			TBuf<KMaxDisplayedFullNameLenInMsg> abbrevSourceName;
			EikFileUtils::AbbreviateFileName(targetSource.NameAndExt(), abbrevSourceName);
			errorMsg.Format(_L("\"%S\" cannot be copied/moved"), &abbrevSourceName);
			CEikonEnv::Static()->InfoMsg(errorMsg);
			++iIndex;
			}
		}
	}

EXPORT_C void CEikFileHandler::SetOperationL(TInt aOperation, const CDesCArray* aSourceFullNameArray, const TFileName* aTargetFullName)
	{
	iOperation = aOperation;
	iSourceFullNameArray = aSourceFullNameArray;
	iTargetFullName = aTargetFullName;
	if (iOperation != EEikFAttributes)
		{
		iProgressDialog = new(ELeave) CEikFileProgressDialog(this);
		iProgressDialog->ExecuteLD(R_EIK_DIALOG_FILE_PROGRESS);
		}
	}

EXPORT_C void CEikFileHandler::SetOperationL(TInt aOperation, const CDesCArray* aSourceFullNameArray, TUint aDirEntryAttributesSetMask, TUint aDirEntryAttributesClearMask)
	{
	iOperation = aOperation;
	iSourceFullNameArray = aSourceFullNameArray;
	iDirEntryAttributesSetMask = aDirEntryAttributesSetMask;
	iDirEntryAttributesClearMask = aDirEntryAttributesClearMask;
	iProgressDialog = new(ELeave) CEikFileProgressDialog(this);
	iProgressDialog->ExecuteLD(R_EIK_DIALOG_FILE_PROGRESS);
	}

EXPORT_C void CEikFileHandler::Start()
	{
	SetActive();
	iStatus = KRequestPending;
	TRequestStatus* status = &iStatus;
	User::RequestComplete(status, KErrNone);
	}

EXPORT_C TInt CEikFileHandler::PerformOperationL()
	{
	TInt retcode = KErrNone;
	iTempName.Zero();
	TPtrC sourceFullName((*iSourceFullNameArray)[iIndex]);
	TBool currentEntryIsAFolder;
	retcode = IsFolder(sourceFullName, currentEntryIsAFolder);
	User::LeaveIfError(retcode);
#if defined(__WINS__)
		TFileName src;
#endif

	iErrorHasBeenHandled = EFalse;

	switch (iOperation)
		{
	case EEikFAttributes:
		{
		iTempName = _L("");
		UpdateFileProgressDialogL(sourceFullName, iTempName);
		retcode = iFsSession.SetAtt(sourceFullName, iDirEntryAttributesSetMask, iDirEntryAttributesClearMask);
		if (retcode != KErrNone)
			{
			iCurrentSource = sourceFullName;
			iCurrentTarget = iTempName;
			iLastError = retcode;
			HandleFileServerErrorL();
			}
		}
		break;
	case EEikFCopy:
		if (currentEntryIsAFolder)
			{
			iTempName = *iTargetFullName;
			User::LeaveIfError(EikFileUtils::Parse(sourceFullName));
			TParsePtrC sourceParse(sourceFullName);
			if (sourceParse.Path().Compare(_L("\\")) != 0)
				{
				iTempName.Append(EikFileUtils::FolderNameFromFullName(sourceFullName));
				iTempName.Append(_L("\\"));
				}
			if (EikFileUtils::FolderExists(iTempName) && (! iRetryingCurrentOperation))
				{
				if (! GetFileOrFolderConfirmationL(R_EIK_TBUF_DIALOG_TITLE_CONFIRM_FOLDER_REPLACE, R_EIK_TBUF_FOLDER_COPY_REPLACE_WARNING, iTempName))
					return(KErrNone);
				}
			else
				retcode = iFsSession.MkDir(iTempName);
			if (retcode != KErrNone)
				iUserReply = EEikAbortFileOp;
			User::LeaveIfError(retcode);
			retcode = iFileMan->Copy(sourceFullName, iTempName, CFileMan::ERecurse);
			if (retcode == KErrNotFound)
				retcode = KErrNone;
			else if (retcode == KErrArgument)	// assuming this was caused by a cyclic copy/move op
				retcode = iFileMan->RmDir(iTempName);
			else if (! iErrorHasBeenHandled)
				User::LeaveIfError(retcode);
			}
		else
			{
			retcode = iFileMan->Copy(sourceFullName, *iTargetFullName, 0);
			if ((retcode != KErrNone) && (! iErrorHasBeenHandled))
				User::Leave(retcode);
			}
		break;
	case EEikFMove:
		if (currentEntryIsAFolder)
			{
			iTempName = *iTargetFullName;
			iTempName.Append(EikFileUtils::FolderNameFromFullName(sourceFullName));
			iTempName.Append(_L("\\"));
			TBool targetFolderExists = EikFileUtils::FolderExists(iTempName);
			if (targetFolderExists && (! iRetryingCurrentOperation))
				{
				if (! GetFileOrFolderConfirmationL(R_EIK_TBUF_DIALOG_TITLE_CONFIRM_FOLDER_REPLACE, R_EIK_TBUF_FOLDER_MOVE_REPLACE_WARNING, iTempName))
					return(KErrNone);
				}
			else if (! targetFolderExists)
				retcode = iFsSession.MkDir(iTempName);
			if (retcode != KErrNone)
				iUserReply = EEikAbortFileOp;
			User::LeaveIfError(retcode);
			retcode = iFileMan->Move(sourceFullName, iTempName, CFileMan::ERecurse);
			if (retcode == KErrNotFound)
				retcode = KErrNone;
			if ((retcode == KErrArgument) || (retcode == KErrNone))	
				{
				retcode = iFileMan->RmDir(sourceFullName);
				if (retcode != KErrNone)
					HandleRmDirFailureL(sourceFullName, retcode);
				}
			else if (! iErrorHasBeenHandled)
				User::LeaveIfError(retcode);
			}
		else
			{
			retcode = iFileMan->Move(sourceFullName, *iTargetFullName, 0);
			if ((retcode != KErrNone) && (! iErrorHasBeenHandled))
				User::Leave(retcode);
			}
		break;
	case EEikFRename:
		if (currentEntryIsAFolder)
			retcode = iFileMan->Rename(sourceFullName.Left(sourceFullName.Length()-1), iTargetFullName->Left(iTargetFullName->Length()-1), CFileMan::ERecurse);
		else
			retcode = iFileMan->Rename(sourceFullName, *iTargetFullName, 0);
		if ((retcode != KErrNone) && (! iErrorHasBeenHandled))
			User::Leave(retcode);
		break;
	case EEikFDelete:
		if (currentEntryIsAFolder)
			{
			retcode = iFileMan->RmDir(sourceFullName);
			HandleRmDirFailureL(sourceFullName, retcode);
			}
		else
			{
			retcode = iFileMan->Delete(sourceFullName);
			if ((retcode != KErrNone) && (! iErrorHasBeenHandled))
				User::Leave(retcode);
			}
		break;
	default:
		break;
		}
	return(retcode);
	}

EXPORT_C void CEikFileHandler::HandleRmDirFailureL(const TDesC& aFolderFullName, TInt aRetCode)
	{
	if (aRetCode != KErrNone)
		{
		iCurrentSource = aFolderFullName;
		iCurrentTarget = _L("");
		iLastError = aRetCode;
		iErrorInfo = ENoExtraInformation;
		HandleFileServerErrorL();
		}
 	}

EXPORT_C void CEikFileHandler::RunL()
	{
	if (iStatus.Int())
		User::Leave(iStatus.Int());
	if (iIndex >= iSourceFullNameArray->Count())
		{
		if (iProgressDialog)
			iProgressDialog->HandleOperationEndedL();
		return;
		}
	TInt errorCode = KErrNone;
	TRAPD(err, errorCode = PerformOperationL());
	if (err)
		{
		if (iProgressDialog)
			iProgressDialog->HandleOperationEndedL();
		return;
		}
	if (errorCode)
		{
		if (iUserReply == EEikAbortFileOp)
			{
			if (iProgressDialog)
				iProgressDialog->HandleOperationEndedL();
			return;
			}
		if ((iUserReply == EEikSkipOpOnCurrFile) || (iUserReply == EEikRejectOpOnCurrFile))
			  ++iIndex;
		else if ((iUserReply == EEikConfirmOpOnCurrFile) || (iUserReply == EEikConfirmOpOnAllFiles))
			{
			if (iUserReply == EEikConfirmOpOnAllFiles)
				iConfirmedForAllFiles = ETrue;
			if ((iOperation == EEikFCopy) || (iOperation == EEikFMove))
				HandleAlreadyExistsErrorL();
			}
		}
	else
		{
		++iIndex;
		iRetryingCurrentOperation = EFalse;
		}
	if (iIndex >= iSourceFullNameArray->Count())
		{
		if (iProgressDialog)
			iProgressDialog->HandleOperationEndedL();
		return;
		}
	SetActive();
	iStatus = KRequestPending;
	TRequestStatus* status = &iStatus;
	User::RequestComplete(status,KErrNone);
	}

EXPORT_C void CEikFileHandler::DoCancel()
	{
	}


// class CEikFileProgressDialog

EXPORT_C CEikFileProgressDialog::CEikFileProgressDialog(CEikFileHandler* aFileHandler) 
	: iFileHandler(aFileHandler)
    {
    }

EXPORT_C void CEikFileProgressDialog::PreLayoutDynInitL()
    {
	CEikLabel* label1 = (CEikLabel*) Control(EEikCidFileProgressText1);
	CEikLabel* label2 = (CEikLabel*) Control(EEikCidFileProgressText2);
	iFont = iEikonEnv->LegendFont();
	label1->SetFont(iFont);
	label2->SetFont(iFont);
	SetLabelL(EEikCidFileProgressText1, _L("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"));	// temp code
	iFileHandler->Start();
    }

EXPORT_C void CEikFileProgressDialog::PostLayoutDynInitL()
    {
	SetLabelL(EEikCidFileProgressText1, _L(""));
    }
	  
EXPORT_C TBool CEikFileProgressDialog::OkToExitL(TInt /*aButtonId*/)
    {
	iFileHandler->Cancel();
    return(ETrue);
	}

EXPORT_C void CEikFileProgressDialog::SetLabelsL(const TDesC& aLabel1, const TDesC& aLabel2)
	{
	SetLabelL(EEikCidFileProgressText1, aLabel1);
	SetLabelL(EEikCidFileProgressText2, aLabel2);
	User::After(500000);
	}

EXPORT_C void CEikFileProgressDialog::HandleOperationEndedL()
    {
	iFileHandler->Cancel();
	User::After(100000);
	delete(this);
	}


// class CEikFileManagementDialog

EXPORT_C CEikFileManagementDialog::CEikFileManagementDialog(CDesCArray* aSelectedFullNamesArray)
	{
    iSelectedFullNamesArray = aSelectedFullNamesArray;
	}

EXPORT_C CEikFileManagementDialog::CEikFileManagementDialog(TFileName* aSelectedFullName)
	{
    iSelectedFullName = aSelectedFullName;
	}

EXPORT_C CEikFileManagementDialog::~CEikFileManagementDialog()
	{
	if (iFileManDialogFlags & EOwnSelectionArray)
		delete iSelectedFullNamesArray;
	delete iFileMan;
	delete iFileHandler;
	}

EXPORT_C void CEikFileManagementDialog::PreLayoutDynInitL()
	{
	if (! iSelectedFullNamesArray)
		{
		iSelectedFullNamesArray = new(ELeave) CDesCArrayFlat(5);
		iSelectedFullNamesArray->AppendL(*iSelectedFullName);
		}
	iFileHandler = new(ELeave) CEikFileHandler;
	iFileMan = CFileMan::NewL(CEikonEnv::Static()->FsSession(), iFileHandler);
	iFileHandler->ConstructL(iFileMan);
	SetDialogTitleL(); 
	InitializeControlsL();
	}

EXPORT_C void CEikFileManagementDialog::SetDialogTitleL()
	{
	}

EXPORT_C void CEikFileManagementDialog::InitializeControlsL()
	{
	}

EXPORT_C void CEikFileManagementDialog::HandleBrowseButtonL()
	{
	CEikFolderNameSelector* folderSel;
	CEikDriveNameSelector* driveSel;
	TFileName* path = new(ELeave) TFileName;
	CleanupStack::PushL(path);
	folderSel = (CEikFolderNameSelector*) (ControlOrNull(EEikCidDestFolderNameSel));
	driveSel = (CEikDriveNameSelector*) (ControlOrNull(EEikCidDestDriveNameSel));
	*path = folderSel->FullName();
	CDirContentsListBoxModel::TSortOrder order=CDirContentsListBoxModel::EOrderByName;
	CEikFileBrowserDialog* browseDialog = new(ELeave) CEikFileBrowserDialog(*path,CEikFileBrowser::EHideRom|CEikFileBrowserDialog::EAllowFolderCreation,order);
	if (browseDialog->ExecuteLD(R_EIK_DIALOG_FILE_BROWSE))
		driveSel->SetFullNameL(*path);
	CleanupStack::PopAndDestroy();   // path
	}

EXPORT_C TBool CEikFileManagementDialog::OkToExitL(TInt aButtonId)
    {
	if (aButtonId == EEikBidBrowse)
		{
		HandleBrowseButtonL();
		return(EFalse);
		}
	if (aButtonId == EEikBidCancel)
		{
		if (iFileHandler->IsActive())
			iFileHandler->Cancel();
		return(ETrue);
		}
	PerformValidationChecksL();
	TBool okToExit = PerformRequestedOperationL();
	return(okToExit);
	}

EXPORT_C void CEikFileManagementDialog::PerformValidationChecksL()
	{
	}

EXPORT_C void CEikFileManagementDialog::CheckDriveL(const TDesC& aFullName)
	{
	// temporary code!
	User::LeaveIfError(EikFileUtils::Parse(aFullName));
	TParsePtrC parse(aFullName);
	TBuf<1> drive = parse.Drive().Left(1);
	TChar driveLetter = drive[0];
	TInt driveId = 0;
	User::LeaveIfError(RFs::CharToDrive(driveLetter, driveId));
	TVolumeInfo volInfo;
	const TInt retcode=iEikonEnv->FsSession().Volume(volInfo,driveId);
	if (retcode==KErrNone)
		{
		const TInt mediaAtt = volInfo.iDrive.iMediaAtt;
		if (mediaAtt & KMediaAttWriteProtected)
			{
			TBuf<KMaxErrorMsgLength> textMsg;
			TBuf<KMaxErrorMsgLength> formatStr;
			iEikonEnv->ReadResource(formatStr, R_EIK_TBUF_DISK_READONLY_ERR);
			textMsg.Format(formatStr, &drive);
			iEikonEnv->InfoMsg(textMsg);
			CBaActiveScheduler::LeaveNoAlert();
			}
		}
	}


// class CEikFileOrFolderAttributesDialog

EXPORT_C CEikFileOrFolderAttributesDialog::CEikFileOrFolderAttributesDialog(CDesCArray* aSelectedFullNamesArray)
	: CEikFileManagementDialog(aSelectedFullNamesArray) 
	{
    }

EXPORT_C void CEikFileOrFolderAttributesDialog::InitializeControlsL()
	{
	TUint numOfModifiedEntries = 0;
	TUint numOfReadOnlyEntries = 0;
	TUint numOfHiddenEntries = 0;
	TInt retcode = KErrNone;
	TEntry* entry = new(ELeave) TEntry;
	CleanupStack::PushL(entry);
	const TUint dirEntryCount = iSelectedFullNamesArray->Count();
	for (TUint i = 0; i < dirEntryCount; i++)
		{
		retcode = iEikonEnv->FsSession().Entry((*iSelectedFullNamesArray)[i], *entry);
		if (retcode == KErrNone)
			{
			if (entry->iAtt & KEntryAttArchive)
				++ numOfModifiedEntries;
			if (entry->iAtt & KEntryAttReadOnly)
				++ numOfReadOnlyEntries;
			if (entry->iAtt & KEntryAttHidden)
				++ numOfHiddenEntries;
			}
		}

	CleanupStack::PopAndDestroy();  // entry

	if (numOfModifiedEntries == 0)
		SetCheckBoxState(EEikCidFAttribModified, CEikButtonBase::EClear);
	else if (numOfModifiedEntries == dirEntryCount)
		SetCheckBoxState(EEikCidFAttribModified, CEikButtonBase::ESet);
	else if ((numOfModifiedEntries > 0) && (numOfModifiedEntries < dirEntryCount))
		SetCheckBoxState(EEikCidFAttribModified, CEikButtonBase::EIndeterminate);

	if (numOfReadOnlyEntries == 0)
		SetCheckBoxState(EEikCidFAttribReadOnly, CEikButtonBase::EClear);
	else if (numOfReadOnlyEntries == dirEntryCount)
		SetCheckBoxState(EEikCidFAttribReadOnly, CEikButtonBase::ESet);
	else if ((numOfReadOnlyEntries > 0) && (numOfReadOnlyEntries < dirEntryCount))
		SetCheckBoxState(EEikCidFAttribReadOnly, CEikButtonBase::EIndeterminate);

	if (numOfHiddenEntries == 0)
		SetCheckBoxState(EEikCidFAttribHidden, CEikButtonBase::EClear);
	else if (numOfHiddenEntries == dirEntryCount)
		SetCheckBoxState(EEikCidFAttribHidden, CEikButtonBase::ESet);
	else if ((numOfHiddenEntries > 0) && (numOfHiddenEntries < dirEntryCount))
		SetCheckBoxState(EEikCidFAttribHidden, CEikButtonBase::EIndeterminate);
	}

EXPORT_C void CEikFileOrFolderAttributesDialog::DetermineDirEntryAttributes()
	{
	iDirEntryAttributesSetMask = 0;
	iDirEntryAttributesClearMask = 0;

	CEikButtonBase::TState checkBoxState;

	checkBoxState = CheckBoxState(EEikCidFAttribModified);
	if (checkBoxState == CEikButtonBase::ESet)
		iDirEntryAttributesSetMask |= KEntryAttArchive;
	else if (checkBoxState == CEikButtonBase::EClear)
		iDirEntryAttributesClearMask |= KEntryAttArchive;

	checkBoxState = CheckBoxState(EEikCidFAttribReadOnly);
	if (checkBoxState == CEikButtonBase::ESet)
		iDirEntryAttributesSetMask |= KEntryAttReadOnly;
	else if (checkBoxState == CEikButtonBase::EClear)
		iDirEntryAttributesClearMask |= KEntryAttReadOnly;

	checkBoxState = CheckBoxState(EEikCidFAttribHidden);
	if (checkBoxState == CEikButtonBase::ESet)
		iDirEntryAttributesSetMask |= KEntryAttHidden;
	else if (checkBoxState == CEikButtonBase::EClear)
		iDirEntryAttributesClearMask |= KEntryAttHidden;
	}

EXPORT_C TBool CEikFileOrFolderAttributesDialog::PerformRequestedOperationL()
	{
	DetermineDirEntryAttributes();
	iOperation = EEikFAttributes;
	MakeVisible(EFalse);
	iFileHandler->SetOperationL(iOperation, iSelectedFullNamesArray, iDirEntryAttributesSetMask, iDirEntryAttributesClearMask);
	iFileHandler->Start();
	return(ETrue);
	}

EXPORT_C void CEikFileOrFolderAttributesDialog::SetDialogTitleL()
	{
	TBuf<KMaxDialogTitleLength> title;
	TFileName* name = new(ELeave) TFileName;
	CleanupStack::PushL(name);
	if (iSelectedFullNamesArray->Count() == 1)
		{
		TPtrC sourceFullName = (*iSelectedFullNamesArray)[0];
		*name = MostSignificantPartOfFullName(sourceFullName);
		TBuf<KMaxDirEntryNameLengthInDialogTitleBar> abbrevName;
		EikFileUtils::AbbreviateFileName(*name, abbrevName);
		TBool entryIsAFolder;
		TInt retcode = IsFolder(sourceFullName, entryIsAFolder);
		if (retcode == KErrNone)
			{
			if (entryIsAFolder)
				title.Format(_L("Properties of folder \"%S\""), &abbrevName);
			else
				title.Format(_L("Properties of file \"%S\""), &abbrevName);
			}
		else
			User::Leave(retcode);
		}
	else
		title = _L("Properties of selected items");
	CleanupStack::PopAndDestroy();	// name
	SetTitleL(title);
	}


// class CEikDiskFormatDialog

EXPORT_C CEikDiskFormatDialog::CEikDiskFormatDialog()
	{
	}

EXPORT_C void CEikDiskFormatDialog::PreLayoutDynInitL()
	{
	CEikDriveNameSelector* driveSel = (CEikDriveNameSelector*) (ControlOrNull(EEikCidDestDriveNameSel));
	driveSel->AllowCorruptDisk(ETrue);
	driveSel->SetFullNameL(_L("c:\\"));
	}

EXPORT_C TBool CEikDiskFormatDialog::GetUserConfirmationL()
	{
	TBuf<KMaxDialogTitleLength> title;
	iEikonEnv->ReadResource(title, R_EIK_TBUF_DIALOG_TITLE_CONFIRM_DISK_FORMAT);
	TBuf<KMaxWarningMsgLength> warningMsgFormatStr;
	TBuf<KMaxWarningMsgLength> warningMsg;
	CEikDriveNameSelector* driveSel = (CEikDriveNameSelector*) (ControlOrNull(EEikCidDestDriveNameSel));
	TParsePtrC parse(driveSel->FullName());
	iEikonEnv->ReadResource(warningMsgFormatStr, R_EIK_TBUF_DISK_FORMAT_CONFIRM);
	TBuf<1> driveName = parse.Drive().Left(1);
	warningMsg.Format(warningMsgFormatStr, &driveName);
	return(iEikonEnv->QueryWinL(title, warningMsg));
	}

EXPORT_C TInt CEikDiskFormatDialog::PerformQuickDiskFormat()
	{
	CEikDriveNameSelector* driveSel = (CEikDriveNameSelector*) (ControlOrNull(EEikCidDestDriveNameSel));
	TInt count;
	RFormat format;
	TUint formatMode = EQuickFormat;
	TInt r = format.Open(iEikonEnv->FsSession(), driveSel->FullName(), formatMode, count);
	if (r!=KErrNone)
		return(r);
	while (count && r==KErrNone)
		r=format.Next(count);
	format.Close();
	return(r);
	}

EXPORT_C TBool CEikDiskFormatDialog::OkToExitL(TInt aButtonId)
    {
	if (aButtonId == EEikBidCancel)
		return(ETrue);
	TBool confirmed = GetUserConfirmationL();
	if (! confirmed)
		return(ETrue);
	TInt retcode = PerformQuickDiskFormat();
	if (retcode == KErrInUse)
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_DISK_FMT_ERR_INUSE);
	if (retcode == KErrCorrupt)
		iEikonEnv->InfoMsg(R_EIK_TBUF_CANNOT_BE_READ);
	if (retcode == KErrNotReady)
		iEikonEnv->InfoMsg(R_EIK_TBUF_DISK_NOT_PRESENT);
	if (retcode != KErrNone)
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_DISK_FMT_ERR_GENERAL);
	return(ETrue);
	}


// class CEikDiskNameDialog

EXPORT_C CEikDiskNameDialog::CEikDiskNameDialog()
	{
	}

void CEikDiskNameDialog::SetDriveNameEditBoxFromDriveSelector()
	{
	CEikDriveNameSelector* driveSel = (CEikDriveNameSelector*) (Control(EEikCidDestDriveNameSel));
	TInt driveId = 0;
	User::LeaveIfError(iEikonEnv->FsSession().CharToDrive(driveSel->FullName()[0], driveId));
	TFileName driveName;
	TInt retcode = iEikonEnv->FsSession().GetDriveName(driveId, driveName);
	User::LeaveIfError(retcode);
	CEikEdwin* driveNameEditBox = (CEikEdwin*) Control(EEikCidDriveNameEditBox);
	driveNameEditBox->SetTextL(&driveName);
	}

EXPORT_C void CEikDiskNameDialog::PreLayoutDynInitL()
	{
	CEikDriveNameSelector* driveSel = (CEikDriveNameSelector*) (Control(EEikCidDestDriveNameSel));
	driveSel->SetFullNameL(_L("C:\\"));
	SetDriveNameEditBoxFromDriveSelector();
	}

EXPORT_C TBool CEikDiskNameDialog::OkToExitL(TInt aButtonId)
    {
	if (aButtonId == EEikBidCancel)
		return(ETrue);
	TFileName name;
	CEikEdwin* driveNameEd = (CEikEdwin*) Control(EEikCidDriveNameEditBox);
	driveNameEd->GetText(name);
	CEikDriveNameSelector* driveSel = (CEikDriveNameSelector*) (Control(EEikCidDestDriveNameSel));
	TInt driveId = 0;
	User::LeaveIfError(iEikonEnv->FsSession().CharToDrive(driveSel->FullName()[0], driveId));
	TInt retcode = iEikonEnv->FsSession().SetDriveName(driveId, name);
	User::LeaveIfError(retcode);
	return(ETrue);
	}

EXPORT_C void CEikDiskNameDialog::HandleControlStateChangeL(TInt aControlId)
    {
	if (aControlId == EEikCidDestDriveNameSel)
		SetDriveNameEditBoxFromDriveSelector();
    }


// class CEikDiskCopyDialog

EXPORT_C CEikDiskCopyDialog::CEikDiskCopyDialog(TFileName* aPath)
	: CEikFileManagementDialog(aPath) 
	{
    }

EXPORT_C void CEikDiskCopyDialog::InitializeControlsL()
	{
	CEikDriveNameSelector* srcDrive = (CEikDriveNameSelector*) (Control(EEikCidSrcDriveNameSel));
	srcDrive->SetFullNameL(*iSelectedFullName);
	CEikFolderNameSelector* destFolder = (CEikFolderNameSelector*) (ControlOrNull(EEikCidDestFolderNameSel));
	CEikDriveNameSelector* destDrive = (CEikDriveNameSelector*) (ControlOrNull(EEikCidDestDriveNameSel));
	destDrive->SetFileSelectionObserver(destFolder);
	destDrive->SetFullNameL(*iSelectedFullName);
	}

EXPORT_C void CEikDiskCopyDialog::PerformValidationChecksL()
    {
	CEikDriveNameSelector* srcDriveSel = (CEikDriveNameSelector*) (Control(EEikCidSrcDriveNameSel));
	iSelectedFullNamesArray->Reset();
	iSelectedFullNamesArray->AppendL(srcDriveSel->FullName());
	TPtrC sourceFullName((*iSelectedFullNamesArray)[0]);

	CEikFolderNameSelector* destFolderSel = (CEikFolderNameSelector*) (ControlOrNull(EEikCidDestFolderNameSel));
	iTargetFullName = destFolderSel->FullName();

	if (sourceFullName.Left(1).CompareF(iTargetFullName.Left(1)) == 0)
		{
		iTargetFullName.Zero();
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_IDENTICAL_DISKNAMES_ERR);
		}
	}

EXPORT_C TBool CEikDiskCopyDialog::PerformRequestedOperationL()
	{
	iOperation = EEikFCopy;
	MakeVisible(EFalse);
	iFileHandler->SetOperationL(iOperation, iSelectedFullNamesArray, &iTargetFullName);
	return(ETrue);
	}


// class CEikFileOrFolderDeleteDialog

EXPORT_C CEikFileOrFolderDeleteDialog::CEikFileOrFolderDeleteDialog(CDesCArray* aSelectedFullNamesArray)
	: CEikFileManagementDialog(aSelectedFullNamesArray) 
	{
    }

EXPORT_C TBool CEikFileOrFolderDeleteDialog::GetUserConfirmationL()
	{
	TInt count = iSelectedFullNamesArray->Count();
	TBuf<KMaxDialogTitleLength> title;
	iEikonEnv->ReadResource(title, R_EIK_TBUF_DIALOG_TITLE_CONFIRM_FOLDER_DELETE);
	TBuf<KMaxWarningMsgLength> warningMsgFormatStr;
	TBuf<KMaxWarningMsgLength> warningMsg;
	TBool entryIsAFolder = EFalse;
	TInt retcode = KErrNone;
	if (count == 1)
		{
		TPtrC sourceFullName = (*iSelectedFullNamesArray)[0];
		retcode = IsFolder(sourceFullName, entryIsAFolder);
		User::LeaveIfError(retcode);
		if (! entryIsAFolder)
			return(ETrue);
		iEikonEnv->ReadResource(warningMsgFormatStr, R_EIK_TBUF_FOLDER_DELETE_CONFIRM);
		TBuf<KMaxDisplayedFullNameLenInMsg> abbrevFolderName;
		EikFileUtils::AbbreviateFileName(MostSignificantPartOfFullName(sourceFullName), abbrevFolderName);
		warningMsg.Format(warningMsgFormatStr, &abbrevFolderName);
		}
	else
		{
		TBool allSelectedItemsAreFiles = ETrue;
		for (TInt i = 0; i < count; i++)
			{
			TPtrC sourceFullName = (*iSelectedFullNamesArray)[i];
			retcode = IsFolder(sourceFullName, entryIsAFolder);
			User::LeaveIfError(retcode);
			if (entryIsAFolder)
				{
				allSelectedItemsAreFiles = EFalse;
				break;
				}
			}
		if (allSelectedItemsAreFiles)
			return(ETrue);
		iEikonEnv->ReadResource(warningMsgFormatStr, R_EIK_TBUF_FILES_OR_FOLDERS_DELETE_CONFIRM);
		warningMsg.Format(warningMsgFormatStr, count);
		}
	return(iEikonEnv->QueryWinL(title, warningMsg));
	}

EXPORT_C TBool CEikFileOrFolderDeleteDialog::OkToExitL(TInt aButtonId)
    {
	if (aButtonId==EEikBidOk)
		return EFalse;
	if (aButtonId == EEikBidCancel)
		{
		if (iFileHandler->IsActive())
			iFileHandler->Cancel();
		return(ETrue);
		}
	PerformRequestedOperationL();
	return(ETrue);
	}

EXPORT_C TBool CEikFileOrFolderDeleteDialog::PerformRequestedOperationL()
	{
	if (! GetUserConfirmationL())
		return(EFalse);
	iOperation = EEikFDelete;
	MakeVisible(EFalse);
	iFileHandler->SetOperationL(iOperation, iSelectedFullNamesArray, &iTargetFullName);
	return(ETrue);
	}

EXPORT_C void CEikFileOrFolderDeleteDialog::SetDialogTitleL()
	{
	TBuf<KMaxDialogTitleLength> title;
	TFileName* name = new(ELeave) TFileName;
	CleanupStack::PushL(name);
	if (iSelectedFullNamesArray->Count() == 1)
		{
		TPtrC sourceFullName = (*iSelectedFullNamesArray)[0];
		*name = MostSignificantPartOfFullName(sourceFullName);
		TBuf<KMaxDirEntryNameLengthInDialogTitleBar> abbrevName;
		EikFileUtils::AbbreviateFileName(*name, abbrevName);
		TBool entryIsAFolder;
		TInt retcode = IsFolder(sourceFullName, entryIsAFolder);
		if (retcode == KErrNone)
			{
			if (entryIsAFolder)
				title.Format(_L("Delete folder \"%S\" ?"), &abbrevName);
			else
				title.Format(_L("Delete file \"%S\" ?"), &abbrevName);
			}
		else
			User::Leave(retcode);
		}
	else
		title = _L("Delete selected items?");
	CleanupStack::PopAndDestroy();	// name
	SetTitleL(title);
	}


// class CEikFileMoveDialog

EXPORT_C CEikFileOrFolderMoveDialog::CEikFileOrFolderMoveDialog(CDesCArray* aSelectedFullNamesArray)
	: CEikFileManagementDialog(aSelectedFullNamesArray) 
	{
    }

EXPORT_C void CEikFileOrFolderMoveDialog::PerformValidationChecksL()
    {
	CEikFolderNameSelector* destFolder = (CEikFolderNameSelector*) (Control(EEikCidDestFolderNameSel));
	CheckDriveL(destFolder->FullName());
	iTargetFullName = EikFileUtils::DriveAndPathFromFullName(destFolder->FullName());

	TPtrC sourceFullName = (*iSelectedFullNamesArray)[0];
	TBool sourceIsFolder = EFalse;
	TInt retcode = IsFolder(sourceFullName, sourceIsFolder);
	User::LeaveIfError(retcode);

	TParse* sourceParse = new(ELeave) TParse;
	CleanupStack::PushL(sourceParse);

	User::LeaveIfError(EikFileUtils::Parse(iTargetFullName));
	TParsePtrC targetParse(iTargetFullName);

	User::LeaveIfError(sourceParse->Set(sourceFullName, NULL, NULL));

	if (sourceIsFolder)
		User::LeaveIfError(sourceParse->PopDir());

	if (sourceParse->DriveAndPath().CompareF(targetParse.DriveAndPath()) == 0)
		{
		iTargetFullName.Zero();
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_IDENTICAL_FOLDERNAMES_ERR);
		}

	CleanupStack::PopAndDestroy();	// sourceParse
    }

EXPORT_C void CEikFileOrFolderMoveDialog::InitializeControlsL()
	{
	CEikFolderNameSelector* destFolder = (CEikFolderNameSelector*) (ControlOrNull(EEikCidDestFolderNameSel));
	CEikDriveNameSelector* destDrive = (CEikDriveNameSelector*) (ControlOrNull(EEikCidDestDriveNameSel));
	destDrive->SetFileSelectionObserver(destFolder);
	destDrive->SetFullNameL((*iSelectedFullNamesArray)[0]);
	}

EXPORT_C void CEikFileOrFolderMoveDialog::SetDialogTitleL()
	{
	TBuf<KMaxDialogTitleLength> title;
	TFileName* name = new(ELeave) TFileName;
	CleanupStack::PushL(name);
	if (iSelectedFullNamesArray->Count() == 1)
		{
		TPtrC sourceFullName = (*iSelectedFullNamesArray)[0];
		*name = MostSignificantPartOfFullName(sourceFullName);
		TBuf<KMaxDirEntryNameLengthInDialogTitleBar> abbrevName;
		EikFileUtils::AbbreviateFileName(*name, abbrevName);
		TBool entryIsAFolder;
		TInt retcode = IsFolder(sourceFullName, entryIsAFolder);
		if (retcode == KErrNone)
			{
			if (entryIsAFolder)
				title.Format(_L("Move folder \"%S\""), &abbrevName);
			else
				title.Format(_L("Move file \"%S\""), &abbrevName);
			}
		else
			User::Leave(retcode);
		}
	else
		title = _L("Move selected items");
	CleanupStack::PopAndDestroy();	// name
	SetTitleL(title);
	}

EXPORT_C TBool CEikFileOrFolderMoveDialog::PerformRequestedOperationL()
	{
	iOperation = EEikFMove;
	MakeVisible(EFalse);
	iFileHandler->SetOperationL(iOperation, iSelectedFullNamesArray, &iTargetFullName);
	return(ETrue);
	}


// class CEikSingleFileCopyDialog

EXPORT_C CEikSingleFileCopyDialog::CEikSingleFileCopyDialog(TFileName* aSelectedFullName)
	: CEikFileManagementDialog(aSelectedFullName) 
	{
    }

EXPORT_C void CEikSingleFileCopyDialog::InitializeControlsL()
	{
	CEikFileNameEditor* destFile = (CEikFileNameEditor*) (ControlOrNull(EEikCidDestFileNameEd));
	CEikFolderNameSelector* destFolder = (CEikFolderNameSelector*) (ControlOrNull(EEikCidDestFolderNameSel));
	CEikDriveNameSelector* destDrive = (CEikDriveNameSelector*) (ControlOrNull(EEikCidDestDriveNameSel));
	destFolder->SetFileSelectionObserver(destFile);
	destDrive->SetFileSelectionObserver(destFolder);
	destDrive->SetFullNameL(*iSelectedFullName);
	}

EXPORT_C void CEikSingleFileCopyDialog::PerformValidationChecksL()
    {
	CEikFileNameEditor* fileNameEditor = (CEikFileNameEditor*) (Control(EEikCidDestFileNameEd));
	iTargetFullName.Zero();
	fileNameEditor->GetFullNameL(iTargetFullName);
	TPtrC sourceFullName = (*iSelectedFullNamesArray)[0];
	if (sourceFullName.CompareF(iTargetFullName) == 0)
		{
		iTargetFullName.Zero();
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_IDENTICAL_FILENAMES_ERR);
		}
    }

EXPORT_C TBool CEikSingleFileCopyDialog::PerformRequestedOperationL()
	{
	iOperation = EEikFCopy;
	MakeVisible(EFalse);
	iFileHandler->SetOperationL(iOperation, iSelectedFullNamesArray, &iTargetFullName);
	return(ETrue);
	}

EXPORT_C void CEikSingleFileCopyDialog::SetDialogTitleL()
	{
	TBuf<KMaxDialogTitleLength> title;
	TPtrC sourceFullName = (*iSelectedFullNamesArray)[0];
	TFileName* name = new(ELeave) TFileName;
	CleanupStack::PushL(name);
	*name = MostSignificantPartOfFullName(sourceFullName);
	TBuf<KMaxDirEntryNameLengthInDialogTitleBar> abbrevName;
	EikFileUtils::AbbreviateFileName(*name, abbrevName);
	CleanupStack::PopAndDestroy();	// name
	title.Format(_L("Copy file \"%S\""), &abbrevName);
	SetTitleL(title);
	}


// class CEikFileRenameDialog

EXPORT_C CEikFileRenameDialog::CEikFileRenameDialog(TFileName* aSelectedFullName)
	: CEikFileManagementDialog(aSelectedFullName) 
	{
    }

EXPORT_C void CEikFileRenameDialog::InitializeControlsL()
	{
	CEikFileNameEditor* destFile = (CEikFileNameEditor*) (ControlOrNull(EEikCidDestFileNameEd));
	destFile->SetFullNameL(*iSelectedFullName);
	}

EXPORT_C void CEikFileRenameDialog::PerformValidationChecksL()
    {
	CEikFileNameEditor* fileNameEditor = (CEikFileNameEditor*) (Control(EEikCidDestFileNameEd));
	
	fileNameEditor->GetFullNameL(iTargetFullName);

	TParsePtr sourceParse(*iSelectedFullName);

	if (sourceParse.FullName().Compare(iTargetFullName) == 0)
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_OLD_AND_NEW_NAMES_SAME_ERR);

	TEntry* entry = new(ELeave) TEntry;
	CleanupStack::PushL(entry);
	TInt retcode = CEikonEnv::Static()->FsSession().Entry(iTargetFullName, *entry);
	if (retcode == KErrNone)
		{
		if (sourceParse.FullName().CompareF(iTargetFullName) != 0)
			{
			if (entry->iAtt & KEntryAttDir)
				iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_FOLDER_EXISTS_ERR);
			iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_FILE_EXISTS_ERR);
			}
		}

	CleanupStack::PopAndDestroy(); // "entry" 
    }

EXPORT_C TBool CEikFileRenameDialog::PerformRequestedOperationL()
	{
	iOperation = EEikFRename;
	MakeVisible(EFalse);
	iFileHandler->SetOperationL(iOperation, iSelectedFullNamesArray, &iTargetFullName);
	return(ETrue);
	}

EXPORT_C void CEikFileRenameDialog::SetDialogTitleL()
	{
	TBuf<KMaxDialogTitleLength> title;
	TPtrC sourceFullName = (*iSelectedFullNamesArray)[0];
	TFileName* name = new(ELeave) TFileName;
	CleanupStack::PushL(name);
	*name = MostSignificantPartOfFullName(sourceFullName);
	TBuf<KMaxDirEntryNameLengthInDialogTitleBar> abbrevName;
	EikFileUtils::AbbreviateFileName(*name, abbrevName);
	CleanupStack::PopAndDestroy();	// name
	title.Format(_L("Rename file \"%S\""), &abbrevName);
	SetTitleL(title);
	}


// class CEikFolderRenameDialog

EXPORT_C CEikFolderRenameDialog::CEikFolderRenameDialog(TFileName* aSelectedFullName)
	: CEikFileManagementDialog(aSelectedFullName) 
	{
    }

EXPORT_C void CEikFolderRenameDialog::InitializeControlsL()
    {
	CEikFolderNameEditor* destFolder = (CEikFolderNameEditor*) (ControlOrNull(EEikCidDestFolderNameEd));
	destFolder->SetFullNameL(*iSelectedFullName);
	}

EXPORT_C void CEikFolderRenameDialog::PerformValidationChecksL()
    {
	TParsePtrC sourceParse(*iSelectedFullName);
    CEikFolderNameEditor* folderNameEditor = (CEikFolderNameEditor*) Control(EEikCidDestFolderNameEd);
	
	TFileName* folderNameTypedByUser = new(ELeave) TFileName;
	CleanupStack::PushL(folderNameTypedByUser);
	folderNameEditor->GetText(*folderNameTypedByUser);
	TParse* targetParse = new(ELeave) TParse;
	CleanupStack::PushL(targetParse);
	User::LeaveIfError(targetParse->Set(*iSelectedFullName, NULL, NULL));
	User::LeaveIfError(targetParse->PopDir());

	iTargetFullName = EikFileUtils::ValidateFolderNameTypedByUserL(*folderNameTypedByUser, targetParse->DriveAndPath());

	TEntry* entry = new(ELeave) TEntry;
	CleanupStack::PushL(entry);

	TInt retcode = CEikonEnv::Static()->FsSession().Entry(iTargetFullName, *entry);
	if (retcode == KErrNone) 
		{
		if (sourceParse.FullName().CompareF(iTargetFullName) != 0)
			{
			if (entry->iAtt & KEntryAttDir)
				iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_FOLDER_EXISTS_ERR);
			iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_FILE_EXISTS_ERR);
			}
		}
	
	CleanupStack::PopAndDestroy(3);  // "folderNameTypedByUser", "targetParse", and "entry"
    }

EXPORT_C TBool CEikFolderRenameDialog::PerformRequestedOperationL()
	{
	iOperation = EEikFRename;
	MakeVisible(EFalse);
	iFileHandler->SetOperationL(iOperation, iSelectedFullNamesArray, &iTargetFullName);
	return(ETrue);
	}

EXPORT_C void CEikFolderRenameDialog::SetDialogTitleL()
	{
	TBuf<KMaxDialogTitleLength> title;
	TPtrC sourceFullName = (*iSelectedFullNamesArray)[0];
	TFileName* name = new(ELeave) TFileName;
	CleanupStack::PushL(name);
	*name = MostSignificantPartOfFullName(sourceFullName);
	TBuf<KMaxDirEntryNameLengthInDialogTitleBar> abbrevName;
	EikFileUtils::AbbreviateFileName(*name, abbrevName);
	CleanupStack::PopAndDestroy();	// name
	title.Format(_L("Rename folder \"%S\""), &abbrevName);
	SetTitleL(title);
	}


// class CEikMultipleFilesOrFoldersCopyDialog

EXPORT_C CEikMultipleFilesOrFoldersCopyDialog::CEikMultipleFilesOrFoldersCopyDialog(CDesCArray* aSelectedFullNamesArray)
	: CEikFileManagementDialog(aSelectedFullNamesArray) 
	{
    }

EXPORT_C void CEikMultipleFilesOrFoldersCopyDialog::PerformValidationChecksL()
    {
	CEikFolderNameSelector* destFolder = (CEikFolderNameSelector*) (Control(EEikCidDestFolderNameSel));
	CheckDriveL(destFolder->FullName());
	iTargetFullName = EikFileUtils::DriveAndPathFromFullName(destFolder->FullName());

	TPtrC sourceFullName = (*iSelectedFullNamesArray)[0];
	TBool sourceIsFolder = EFalse;
	TInt retcode = IsFolder(sourceFullName, sourceIsFolder);
	User::LeaveIfError(retcode);

	TParse* sourceParse = new(ELeave) TParse;
	CleanupStack::PushL(sourceParse);

	User::LeaveIfError(EikFileUtils::Parse(iTargetFullName));
	TParsePtrC targetParse(iTargetFullName);

	User::LeaveIfError(sourceParse->Set(sourceFullName, NULL, NULL));

	if (sourceIsFolder)
		User::LeaveIfError(sourceParse->PopDir());

	if (sourceParse->DriveAndPath().CompareF(targetParse.DriveAndPath()) == 0)
		{
		iTargetFullName.Zero();
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_IDENTICAL_FOLDERNAMES_ERR);
		}

	CleanupStack::PopAndDestroy();	// sourceParse
    }

EXPORT_C void CEikMultipleFilesOrFoldersCopyDialog::InitializeControlsL()
	{
	CEikFolderNameSelector* destFolder = (CEikFolderNameSelector*) (ControlOrNull(EEikCidDestFolderNameSel));
	CEikDriveNameSelector* destDrive = (CEikDriveNameSelector*) (ControlOrNull(EEikCidDestDriveNameSel));
	destDrive->SetFileSelectionObserver(destFolder);
	destDrive->SetFullNameL((*iSelectedFullNamesArray)[0]);
	}

EXPORT_C void CEikMultipleFilesOrFoldersCopyDialog::SetDialogTitleL()
	{
	TBuf<KMaxDialogTitleLength> title;
	TFileName* name = new(ELeave) TFileName;
	CleanupStack::PushL(name);
	if (iSelectedFullNamesArray->Count() == 1)
		{
		TPtrC sourceFullName = (*iSelectedFullNamesArray)[0];
		*name = MostSignificantPartOfFullName(sourceFullName);
		TBuf<KMaxDirEntryNameLengthInDialogTitleBar> abbrevName;
		EikFileUtils::AbbreviateFileName(*name, abbrevName);
		title.Format(_L("Copy folder \"%S\""), &abbrevName);
		}
	else
		title = _L("Copy selected items");
	CleanupStack::PopAndDestroy();  // name
	SetTitleL(title);
	}

EXPORT_C TBool CEikMultipleFilesOrFoldersCopyDialog::PerformRequestedOperationL()
	{
	iOperation = EEikFCopy;
	MakeVisible(EFalse);
	iFileHandler->SetOperationL(iOperation, iSelectedFullNamesArray, &iTargetFullName);
	return(ETrue);
	}

///////////////////////////////////////////////////////////////////////////////////////////////////


// class CEikDirConListBoxUpdater

class CEikDirConListBoxUpdater : public CActive
	{
public:
	static CEikDirConListBoxUpdater* NewL(RFs& aFsSession, CEikDirContentsListBox* aDirContentsListBox);
	IMPORT_C void RunL();
	IMPORT_C void Start();
private:													
	CEikDirConListBoxUpdater(RFs& aFsSession);
	void DoCancel();
private:													
	RFs& iFsSession;
	CEikDirContentsListBox* iListBox;
	};

CEikDirConListBoxUpdater::CEikDirConListBoxUpdater(RFs& aFsSession)
	: CActive(CActive::EPriorityStandard), iFsSession(aFsSession)
    { }


CEikDirConListBoxUpdater* CEikDirConListBoxUpdater::NewL(RFs& aFsSession, CEikDirContentsListBox* aDirContentsListBox)
	{
	CEikDirConListBoxUpdater *This = new(ELeave) CEikDirConListBoxUpdater(aFsSession);
	This->iListBox = aDirContentsListBox;
	CActiveScheduler::Add(This);
	return(This);
	}

void CEikDirConListBoxUpdater::Start()
	{
	if (IsActive())
		return;
	iStatus = KRequestPending;
	SetActive();
	iFsSession.NotifyChange(ENotifyAll, iStatus);
	}

void CEikDirConListBoxUpdater::RunL()
	{
	if (iStatus.Int())
		User::Leave(iStatus.Int());
	else
		{
		iListBox->UpdateL();
		Start();
		}
	}

void CEikDirConListBoxUpdater::DoCancel()
	{
	}


// class CTestFileManager

class CTestFileManager : public CCoeControl
    {
public:
    void ConstructL();
	~CTestFileManager();
	void HandleFCopyCommandL();
	void HandleFDeleteCommandL();
	void HandleFMoveCommandL();
	void HandleFRenameCommandL();
	void HandleFAttributesCommandL();
	void HandleNewFolderCommandL();
	void HandleFormatDiskCommandL();
	void HandleNameDiskCommandL();
	void HandleCopyDiskCommandL();
	void TestPathExistsFunction();
	void CreateDirContentsListBoxL();
private:
	enum TFlags {EFileSystemChangeNotificationEnabled = 0x01};
private:
	virtual TInt CountComponentControls() const;
	virtual CCoeControl* ComponentControl(TInt aIndex) const;
	virtual void Draw(const TRect& aRect) const;
	TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
	void DisplayMessage(const TDesC& aDes) const;
	virtual void FocusChanged(TDrawNow aDrawNow);
	void DetermineSelectedDirEntry();
private:
	TFileName iPath;		
	CEikDirContentsListBox* iDirContentsListBox;
	CEikDirConListBoxUpdater* iDirConListBoxUpdater;
	CDesCArray* iSelectedDirEntries;
	TFileName iSelectedDirEntry;
	TInt iFileManagerFlags;
	};

void CTestFileManager::ConstructL()
    {
    CreateWindowL();
    Window().SetShadowDisabled(ETrue);
	Window().SetBackgroundColor(KRgbGray);
    SetExtentToWholeScreenL();
	iEikonEnv->WsSession().SetAutoFlush(ETrue);
	iSelectedDirEntries = new(ELeave) CDesCArrayFlat(5);
	CreateDirContentsListBoxL();
	iDirContentsListBox->SetFocus(ETrue);
    ActivateL();
	iDirContentsListBox->ActivateL();
	iDirConListBoxUpdater = CEikDirConListBoxUpdater::NewL(iEikonEnv->FsSession(), iDirContentsListBox);
	iDirConListBoxUpdater->Start();
	iFileManagerFlags |= EFileSystemChangeNotificationEnabled;
    }

void CTestFileManager::CreateDirContentsListBoxL()
	{
	iDirContentsListBox=new(ELeave) CEikDirContentsListBox;
	iDirContentsListBox->ConstructL(this, CEikListBox::EMultipleSelection);
	iDirContentsListBox->CreateScrollBarFrameL(); 
	iDirContentsListBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOn);
	iDirContentsListBox->SetExtentL(TPoint(100,50), TSize(340,154));
	iDirContentsListBox->SetPathL(_L("c:\\*"));
	iDirContentsListBox->UpdateScrollBarsL();
	iDirContentsListBox->SetFocus(ETrue);
	}

void CTestFileManager::FocusChanged(TDrawNow /*aDrawNow*/)
	{
	const TBool focused = IsFocused();
	if (!IsReadyToDraw())
		return;
	if (focused && !(iFileManagerFlags & EFileSystemChangeNotificationEnabled))
		{
		iDirConListBoxUpdater->Start();
		iFileManagerFlags |= EFileSystemChangeNotificationEnabled;
		iDirContentsListBox->UpdateL();
		}
	else if (!focused && iFileManagerFlags & EFileSystemChangeNotificationEnabled)
		{
		iEikonEnv->FsSession().NotifyChangeCancel();
		iDirConListBoxUpdater->Cancel();
		iFileManagerFlags &=~ EFileSystemChangeNotificationEnabled;
		}
	}

TInt CTestFileManager::CountComponentControls() const
	{
	return (iDirContentsListBox? 1 : 0);
	}

CCoeControl* CTestFileManager::ComponentControl(TInt aIndex) const
	{
	if (aIndex==0)
		return iDirContentsListBox;
	return 0;
	}

void CTestFileManager::Draw(const TRect& /*aRect*/) const
	{
	iEikonEnv->FillTexturedRect(Rect());
	}

CTestFileManager::~CTestFileManager()
	{
	if (iFileManagerFlags & EFileSystemChangeNotificationEnabled)
		{
		iEikonEnv->FsSession().NotifyChangeCancel();
		iDirConListBoxUpdater->Cancel();
		}
	delete iDirConListBoxUpdater;
	delete iDirContentsListBox;
	delete iSelectedDirEntries;
	}

void CTestFileManager::DisplayMessage(const TDesC& aMsg) const
	{
	User::After(1000000);
	iEikonEnv->InfoMsg(aMsg);
	User::After(1000000);
	}

TKeyResponse CTestFileManager::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
    {
	iDirContentsListBox->OfferKeyEventL(aKeyEvent, aType);
    return(EKeyWasConsumed);
    }

void CTestFileManager::HandleFDeleteCommandL()
	{
	iDirContentsListBox->GetFullNamesOfSelectedItemsL(iSelectedDirEntries);
	if (iSelectedDirEntries->Count() == 0)
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_OPERATION_NO_ARG_ERR);
    CEikDialog* dialog = new(ELeave) CEikFileOrFolderDeleteDialog(iSelectedDirEntries);
    dialog->ExecuteLD(R_EIK_DIALOG_FILE_OR_FOLDER_DELETE);
	}

void CTestFileManager::HandleFAttributesCommandL()
	{
	iDirContentsListBox->GetFullNamesOfSelectedItemsL(iSelectedDirEntries);
	if (iSelectedDirEntries->Count() == 0)
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_OPERATION_NO_ARG_ERR);
    CEikDialog* dialog = new(ELeave) CEikFileOrFolderAttributesDialog(iSelectedDirEntries);
    dialog->ExecuteLD(R_EIK_DIALOG_FILE_OR_FOLDER_ATTRIBUTES);
	}

void CTestFileManager::HandleFormatDiskCommandL()
	{
    CEikDialog* dialog = new(ELeave) CEikDiskFormatDialog();
    dialog->ExecuteLD(R_EIK_DIALOG_DISK_FORMAT);
	}

void CTestFileManager::HandleNameDiskCommandL()
	{
    CEikDialog* dialog = new(ELeave) CEikDiskNameDialog();
    dialog->ExecuteLD(R_EIK_DIALOG_DISK_NAME);
	}

void CTestFileManager::HandleCopyDiskCommandL()
	{
	TFileName path = _L("c:\\");
    CEikDialog* dialog = new(ELeave) CEikDiskCopyDialog(&path);
    dialog->ExecuteLD(R_EIK_DIALOG_DISK_COPY);
	}

void CTestFileManager::HandleFMoveCommandL()
	{
	iDirContentsListBox->GetFullNamesOfSelectedItemsL(iSelectedDirEntries);
	if (iSelectedDirEntries->Count() == 0)
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_OPERATION_NO_ARG_ERR);
    CEikDialog* dialog = new(ELeave) CEikFileOrFolderMoveDialog(iSelectedDirEntries);
    dialog->ExecuteLD(R_EIK_DIALOG_FILE_OR_FOLDER_MOVE);
	}

void CTestFileManager::HandleFRenameCommandL()
	{
	iDirContentsListBox->GetFullNamesOfSelectedItemsL(iSelectedDirEntries);
	if (iSelectedDirEntries->Count() == 0)
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_OPERATION_NO_ARG_ERR);
	else if (iSelectedDirEntries->Count() > 1)
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_OPERATION_TOO_MANY_ARGS_ERR);
	CEikDialog* dialog;
	TInt dialogResId = 0;
	TFileName fullName((*iSelectedDirEntries)[0]);
	TBool entryIsAFolder;
	TInt retcode = IsFolder(fullName, entryIsAFolder);
	User::LeaveIfError(retcode);
	if (entryIsAFolder)
		{
		dialog = new(ELeave) CEikFolderRenameDialog(&fullName);
		dialogResId = R_EIK_DIALOG_FOLDER_RENAME;
		}
	else
		{
		dialog = new(ELeave) CEikFileRenameDialog(&fullName);
		dialogResId = R_EIK_DIALOG_FILE_RENAME;
		}
    dialog->ExecuteLD(dialogResId);
	}

void CTestFileManager::HandleFCopyCommandL()
	{
	iDirContentsListBox->GetFullNamesOfSelectedItemsL(iSelectedDirEntries);
	if (iSelectedDirEntries->Count() == 0)
		iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_OPERATION_NO_ARG_ERR);
	CEikDialog* dialog;
	TInt dialogResId = R_EIK_DIALOG_MULTIPLE_FILES_OR_FOLDERS_COPY;
	if (iSelectedDirEntries->Count() == 1)
		{
		TFileName sourceFullName((*iSelectedDirEntries)[0]);
		TBool entryIsAFolder;
		TInt  retcode = IsFolder(sourceFullName, entryIsAFolder);
		User::LeaveIfError(retcode);
		if (entryIsAFolder)
			dialog = new(ELeave) CEikMultipleFilesOrFoldersCopyDialog(iSelectedDirEntries);
		else
			{
			dialog = new(ELeave) CEikSingleFileCopyDialog(&sourceFullName);
			dialogResId = R_EIK_DIALOG_SINGLE_FILE_COPY;
			}
		}
	else
		dialog = new(ELeave) CEikMultipleFilesOrFoldersCopyDialog(iSelectedDirEntries);
    dialog->ExecuteLD(dialogResId);
	}

void CTestFileManager::TestPathExistsFunction()
	{
	CEikDialog* dialog = new(ELeave) CEikDialog;
	dialog->ConstructAutoDialogLC(EEikDialogFlagWait, R_EIK_BUTTONS_CANCEL_OK);
	dialog->SetTitleL(_L("Test EikFileUtils::PathExists()"));
	dialog->AddAutoTextEditorL(_L("Text editor"), EPathEditBox, 0, 20, 1, &iPath);
	if (dialog->RunLD())
		if (EikFileUtils::PathExists(iPath))	
			DisplayMessage(_L("Specified path exists!"));
		else
			DisplayMessage(_L("Specified path is invalid!"));
	}


//
// CSimpleAppUi
//

class CSimpleAppUi : public CEikAppUi
    {
public:
    void ConstructL();
	~CSimpleAppUi();
private: // framework
    void HandleCommandL(TInt aCommand);
private:
    CTestFileManager* iTestFileManager;
    };

void CSimpleAppUi::ConstructL()
    {
    BaseConstructL();
    iTestFileManager=new(ELeave) CTestFileManager;
    iTestFileManager->ConstructL();
    AddToStackL(iTestFileManager);
    }

CSimpleAppUi::~CSimpleAppUi()
	{
    delete iTestFileManager;
	}

void CSimpleAppUi::HandleCommandL(TInt aCommand)
    {
    switch (aCommand)
        {
    case EEikCmdExit:
        CBaActiveScheduler::Exit();
		break;
	case EEikCmdFDelete:
		iTestFileManager->HandleFDeleteCommandL();
		break;
	case EEikCmdFCopy:
		iTestFileManager->HandleFCopyCommandL();
		break;
	case EEikCmdFMove:
		iTestFileManager->HandleFMoveCommandL();
		break;
	case EEikCmdFRename:
		iTestFileManager->HandleFRenameCommandL();
		break;
	case EEikCmdFAttributes:
		iTestFileManager->HandleFAttributesCommandL();
		break;
	case EEikCmdFormatDisk:
		iTestFileManager->HandleFormatDiskCommandL();
		break;
	case EEikCmdNameDisk:
		iTestFileManager->HandleNameDiskCommandL();
		break;
	case EEikCmdCopyDisk:
		iTestFileManager->HandleCopyDiskCommandL();
		break;
	case EPathExistsFunction:
		iTestFileManager->TestPathExistsFunction();
		break;
    default:
		iEikonEnv->InfoMsg(_L("Sorry! Not Implemented yet..."));
        break;
        }
    }


//
// CSimpleDocument
//

class CSimpleDocument : public CEikDocument
	{
public:
	CSimpleDocument(CEikApplication& aApp): CEikDocument(aApp) { }
private: // from CApaDocument
	CEikAppUi* CreateAppUiL();
	};

CEikAppUi* CSimpleDocument::CreateAppUiL()
	{
    return(new(ELeave) CSimpleAppUi);
	}


//
// CSimpleApplication
//

class CSimpleApplication : public CEikApplication
	{
private: // from CApaApplication
	CApaDocument* CreateDocumentL();
	TUid AppDllUid() const;
	};

const TUid KUidSimpleApp={233};

TUid CSimpleApplication::AppDllUid() const
	{
	return(KUidSimpleApp);
	}

CApaDocument* CSimpleApplication::CreateDocumentL()
	{
	return(new(ELeave) CSimpleDocument(*this));
	}

//
// EXPORTed functions
//

EXPORT_C CApaApplication* NewApplication()
	{
	return(new CSimpleApplication);
	}

GLDEF_C TInt E32Dll(TDllReason)
	{
	return(KErrNone);
	}
