fileman.cpp
来自「手机文件浏览器 Here are the sources to SMan v1.」· C++ 代码 · 共 433 行 · 第 1/2 页
CPP
433 行
#include "fileman.h"
#include "sman.h"
#include <SMan.rsg>
/*************************************************************
*
* File manager class and observer
*
**************************************************************/
CSManFileMan::~CSManFileMan()
{
delete fileMan;
delete logObj;
fileServer.Close();
}
CSManFileMan::CSManFileMan(CConfig *cData)
{
User::LeaveIfError(fileServer.Connect());
fileMan = CFileMan::NewL(fileServer);
fileMan->SetObserver(this);
logObj = new (ELeave) CLogger(cData);
}
void CSManFileMan::setupDialog()
{
progressDialog = new (ELeave) CFileManLogDialog();
progressDialog->progressValue = -1;
progressDialog->ExecuteLD(R_DIALOG_FILEMANPROGRESS_NOWAIT);
progressText = STATIC_CAST(CEikGlobalTextEditor*, progressDialog->Control(cFileManProgressText));
progressBar = STATIC_CAST(CEikProgressInfo*, progressDialog->Control(cFileManProgressBar));
progressBar->SetFinalValue(100);
progressDialog->ButtonGroupContainer().DimCommand(EEikBidOverwrite, ETrue);
progressDialog->ButtonGroupContainer().DimCommand(EEikBidOverwriteAll, ETrue);
progressDialog->ButtonGroupContainer().DimCommand(EEikBidSkip, ETrue);
progressDialog->ButtonGroupContainer().DimCommand(EEikBidSkipAll, ETrue);
progressDialog->ButtonGroupContainer().DimCommand(EEikBidAbort, ETrue);
progressDialog->DrawNow();
}
void CSManFileMan::doWork()
{
TInt res;
TPath originalPath;
originalPath.Copy(targetPath);
userRet = 0;
prevOverwriteStatus = KErrNone;
progressDialog = NULL;
if (currentOperation == isRename)
{
CFileManRenDialog *renDlg;
for (currentFile = 0; currentFile < fileList->Count(); currentFile++)
{
TParsePtr pName(fileList->At(currentFile));
renDlg = new (ELeave) CFileManRenDialog();
renDlg->fileName.Copy(pName.NameAndExt());
renDlg->filePath.Copy(pName.DriveAndPath());
if (renDlg->ExecuteLD(R_DIALOG_FILEMANRENAME) == EEikBidAbort)
break;
}
}
else if (currentOperation == isDelete)
{
HBufC* dataBuffer = CEikonEnv::Static()->AllocReadResourceL(R_TBUF_MISC_DELETE_TITLE);
HBufC* dataBuffer2 = CEikonEnv::Static()->AllocReadResourceL(R_TBUF_DB_CONFIRM_DELETE);
if (CEikonEnv::Static()->QueryWinL(*dataBuffer, *dataBuffer2))
{
// Again, I'm just paranoid
delete dataBuffer;
delete dataBuffer2;
setupDialog();
for (currentFile = 0; currentFile < fileList->Count(); currentFile++)
{
if (EikFileUtils::FolderExists(fileList->At(currentFile)))
{
TFileName pop;
pop.Copy(fileList->At(currentFile));
pop.Append(_L("\\"));
res = fileMan->RmDir(pop);
}
else
res = fileMan->Delete(fileList->At(currentFile), 0);
if (userRet == EEikBidAbort)
break;
}
}
else
{
delete dataBuffer;
delete dataBuffer2;
}
}
else if (currentOperation == isPaste)
{
if (fileList->Count() > 0)
{
TParsePtr temp(fileList->At(0));
if (temp.DriveAndPath() == targetPath)
CEikonEnv::Static()->InfoMsg(R_TBUF_FILEMAN_SAMETARGETSOURCE);
else
{
setupDialog();
TFileName sourceFile, targetFile;
TBool moveFolderToDiffDrive, sourceIsFolder;
for (currentFile = 0; currentFile < fileList->Count(); currentFile++)
{
moveFolderToDiffDrive = EFalse;
sourceIsFolder = EFalse;
sourceFile.Copy(fileList->At(currentFile));
targetFile.Copy(targetPath);
opSwitch = 0;
if (EikFileUtils::FolderExists(sourceFile))
{
opSwitch = CFileMan::ERecurse;
sourceIsFolder = ETrue;
sourceFile.Append(_L("\\"));
targetFile.Append(EikFileUtils::FolderNameFromFullName(sourceFile));
targetFile.Append(_L("\\"));
/*
the == operator isn't so safe to use with objects but is a nice shortcut. :)
Here, checking if we are moving a folder to a different drive.
There is a bug in CFileMan::Move() that can cause you to lose files.
Here's my post in the symbian newsgroups:
i've tested this using:
1) my own implementation (on emulator and real device)
2) qfileman on real device (on P800)
3) qfileman (on emulator)
4) tracker v2.0 (on P800)
all exhibit the same behaviour.
this is how you reproduce the problem:
1) go to c:\ and create a folder called c:\temp
2) under that, create another folder called c:\temp\ppp
3) under that, create another folder called c:\temp\ppp\kkk
4) under c:\temp\ppp\kkk, create 2 files
5) go to d:\ and create a folder called d:\aaa
6) prior to calling CFileMan::Move(), your code should check if the source
is a folder and if so, it should create the target folder i.e. D:\AAA\PPP\.
i found that CFileMan::Move() needs to have the target existing first, which
is fine.
7) at this point, D:\AAA should have a subfolder in it called D:\AAA\PPP
8) call CFileMan::Move() with the following parameters
- source = C:\TEMP\PPP\
- target = D:\AAA\PPP\
- flag = CFileMan::ERecurse
9) the source is empty and the target only has D:\AAA\PPP, which is also
empty. all the files/folders are gone!
some testing seems to reveal that
1) this only happens when moving across drives
2) it looks as though CFileMan::Move() is ignoring the recursive flag
somehow when dealing with the target but not the source. when i dump a file
in C:\TEMP\PPP, that file (AND ONLY THAT FILE) gets MOVEd across
successfully. everything else under C:\TEMP\PPP\KKK doesn't get operated on.
is this a bug?? can someone from Symbian confirm this??
i have a workaround but error handling isn't exactly elegant all the time.
still, it gets the job done.
*/
if (fileManOperation == CSManFileMan::operationCut)
{
if (!EikFileUtils::FolderExists(targetFile))
fileServer.MkDir(targetFile);
if (sourceFile.Left(1).FindC(targetFile.Left(1)) != 0)
{
// The workaround to the move problem is to do a COPY to target then
// DEL the source
moveFolderToDiffDrive = ETrue;
}
}
}
// Check if destination is subfolder of source
if (targetFile.Left(sourceFile.Length()) != sourceFile)
{
// Nope. Operation is valid.
if (fileManOperation == CSManFileMan::operationCopy)
res = fileMan->Copy(sourceFile, targetFile, opSwitch);
else if (fileManOperation == CSManFileMan::operationCut)
{
if (!moveFolderToDiffDrive)
{
res = fileMan->Move(sourceFile, targetFile, opSwitch);
if ((sourceIsFolder) && (res == KErrNone))
{
res = fileMan->RmDir(sourceFile);
}
}
else
{
res = fileMan->Copy(sourceFile, targetFile, opSwitch);
res = fileMan->RmDir(sourceFile);
}
}
}
else
{
HBufC* dataBuffer = NULL;
// Notify the user
if (fileManOperation == CSManFileMan::operationCopy)
dataBuffer = CEikonEnv::Static()->AllocReadResourceL(R_TBUF_FILEMAN_COPYING);
else if (fileManOperation == CSManFileMan::operationCut)
dataBuffer = CEikonEnv::Static()->AllocReadResourceL(R_TBUF_FILEMAN_MOVING);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?