chxavfileui.cpp
来自「著名的 helix realplayer 基于手机 symbian 系统的 播放」· C++ 代码 · 共 1,125 行 · 第 1/3 页
CPP
1,125 行
// return error if error other than user cancel occurs
//
// pathDest - absolute or relative to current root
//
TInt CHXAvFileUI::DoMoveItemL(const TDesC& pathDest,
TInt idxItem)
{
DPRINTF(SYMP_FILE_UI, ("AvFileUI::DoMoveItemL(): moving idx %d to '%s'\n", idxItem, dbg::CharPtr(pathDest)()));
SUSPEND_REFRESH(m_spStore);
CHXAvCleanString msg(R_NOW_MOVING_ITEM_FORMAT, NameFromIndex(idxItem));
m_spWaitNote->SetTextL(msg());
m_spWaitNote->StartAndKickL();
// move one item
TInt err = MoveItemHelperL(pathDest, idxItem);
m_spWaitNote->EndL();
if( IsNonCancelError(err) )
{
CHXAvMessageDialog::DoAlertErrorL(CHXAvCleanString(R_ERR_MOVE_FAILED)());
}
return err;
}
////////////////////////////////////////////////////////////
// move multipe items to specified folder path
//
// return error if error other than user cancel occurs
//
// pathDest - absolute or relative to current root
//
TInt CHXAvFileUI::DoMoveItemsL(const TDesC& pathDest,
const CArrayFix<TInt>& items)
{
TInt err = KErrNone;
SUSPEND_REFRESH(m_spStore);
DPRINTF(SYMP_FILE_UI, ("AvFileUI::DoMoveItemsL(): moving %d items to '%s'\n", items.Count(), dbg::CharPtr(pathDest)()));
m_spWaitNote->SetTextL(CHXAvCleanString(R_NOW_MOVING_MULT_ITEMS_FORMAT, items.Count())());
#if defined(ASYNC_COPYMOVE)
EnableWaitNoteCancelButtonL(true);
#endif
m_spWaitNote->StartAndKickL();
for( TInt idx = 0; idx < items.Count(); ++idx )
{
err = MoveItemHelperL(pathDest, items[idx]);
if( IsNonCancelError(err) )
{
// XXXLCM offer continue, cancel choice?
DPRINTF(SYMP_FILE_UI, ("AvFileUI::DoMoveItemsL(): move failed (err = %ld)\n", err));
break;
}
}
m_spWaitNote->EndL();
if( IsNonCancelError(err) )
{
CHXAvMessageDialog::DoAlertErrorL(CHXAvCleanString(R_ERR_MOVE_FAILED)());
}
return err;
}
////////////////////////////////////////////////////////////
// pathDest fully qualified path (with drive letter), or relative to epStore root
//
TFileName* CHXAvFileUI::AllocSuggestedFileNameL(const TDesC& pathDest, const TDesC& defaultName, TUint flags )
{
TFileName* pName = 0;
if( flags & fSuggestUniqueDefaultName )
{
// AllocUniqueDefaultNameL() needs full path...
TFileName* pFullPathDest = m_spStore->AllocFullPathL(pathDest, KNullDesC, CHXAvFile::ntFolder);
AUTO_PUSH_POP_DEL(pFullPathDest);
// pick a default file/folder name; we get full path ('c:\realnetworks\root\foo.rm')
pName = CHXAvFile::AllocUniqueDefaultNameL(*pFullPathDest, defaultName, flags & fWantFolder, *this);
if(!pName)
{
// rare case; display no default name
DPRINTF(SYMP_FILE_UI, ("AvFileUI::AllocSuggestedFileNameL(): could not find unique name"));
pName = CHXAvFile::AllocFileNameL(KNullDesC);
}
}
else
{
// we don't know/care whether this name would be unique within the destination path
pName = CHXAvFile::AllocFileNameL(defaultName);
}
return pName;
}
////////////////////////////////////////////////////////////
// get a unique, valid file or folder name from the
// user
//
// args:
//
// pathDest - absolute or relative to current root
//
// defaultName - filename to use for initializing text in dialog edit box
// - also provides default extension;
// - for folders, trailing '\' is optional (handled)
//
// returns :
//
// m_nameBuf is set as "name" or "name/" (depending on bWantFolder)
//
// return false if user cancels
//
// notes:
//
// if extensions are hidden, they are automatically added to what user enters
//
// defaultName prompt user entry result
//
// cat cat dog.rm dog.rm
// cat cat poop poop
// cat.rm cat flee flee.rm
// cat.rm cat cat.rm cat.rm.rm
// .rm bob bob.rm
// bob bob
//
// same examples, if extensions are not hidden:
//
// cat cat dog.rm dog.rm
// cat cat poop poop
// cat.rm cat.rm flee flee
// cat.rm cat.rm cat cat.rm
// .rm .rm bob bob
// bob bob
//
CHXAvFileUI::QueryTargetNameResult
CHXAvFileUI::QueryTargetNameL(const TDesC& prompt,const TDesC& pathDest,
const TDesC& defaultName, TUint flags)
{
DPRINTF(SYMP_FILE_UI, ("AvFileUI::QueryTargetNameL(): in folder '%s'\n", dbg::CharPtr(pathDest)()));
QueryTargetNameResult res = qtrAbort;
// reset working buffer
m_nameBuf.SetLength(0);
//
// determine how many chars are left for new filename within given path; we'll
// restrict user input so we don't overflow filename buffer
//
TFileName* pFullPathDest = m_spStore->AllocFullPathL(pathDest, KNullDesC, CHXAvFile::ntFolder);
AUTO_PUSH_POP_DEL(pFullPathDest);
TInt cchMaxName = KMaxFileName - pFullPathDest->Length();
// possibly subtract length of hidden extension or folder suffix
NameExt ext = GetDisplayText(defaultName, flags & fWantFolder);
cchMaxName -= ext.second.Length();
DPRINTF(SYMP_FILE_UI, ("AvFileUI::QueryTargetNameL(): max chars left for name = %d\n", cchMaxName));
if( cchMaxName <= 0 )
{
// destination path is too long!
return qtrPathTooLong;
}
// ui spec requires that we arbitrarily limit names to 40 chars; code does not care
if (cchMaxName > CHXAvMisc::KAVPMaxNakedFileName )
{
cchMaxName = CHXAvMisc::KAVPMaxNakedFileName;
}
InitNameBufWithSuggestionL(pathDest, defaultName, flags);
for( bool bNeedToPrompt = true; bNeedToPrompt ; )
{
//
// name buf should have something like 'foo.rm'; now possibly split name into
// user-display version ('foo') and ext ('.rm')
//
HBufC* pbuffNameInfo = m_nameBuf.AllocL(); // nameInfo will refer into this buffer
AUTO_PUSH_POP_DEL(pbuffNameInfo);
NameExt nameInfo = GetDisplayText(*pbuffNameInfo, flags & fWantFolder);
TFileName* pName = CHXAvMessageDialog::GetFileNameFromUserL(prompt, nameInfo.first, cchMaxName);
if( pName )
{
// update name buf, re-adding extension that we might have lopped off for display purposes
m_nameBuf.Copy(*pName);
HX_DELETE(pName);
m_nameBuf.Append(nameInfo.second);
// assume we'll be able to use this name for now...
bNeedToPrompt = false;
DPRINTF(SYMP_FILE_UI, ("FileUi::QueryTargetNameL(): name requested = '%s'\n", dbg::CharPtr(m_nameBuf)()));
// check for existence of file or folder having same name
bool bFileNameExists = m_spStore->PathExistsL(pathDest, m_nameBuf, CHXAvFile::ntFile);
bool bFolderNameExists = m_spStore->PathExistsL(pathDest, m_nameBuf, CHXAvFile::ntFolder);
if( bFolderNameExists )
{
DPRINTF(SYMP_FILE_UI, ("FileUi::QueryTargetNameL(): folder matching name already exists\n"));
// overwrite of folder (or creation of file having same name as existing folder) never allowed
CHXAvMessageDialog::DoAlertInfoL(CHXAvCleanString(R_ERR_NAME_ALREADY_EXISTS)());
bNeedToPrompt = true;
}
else if(flags & fWantFolder)
{
// looking for folder target
if( bFileNameExists )
{
// overwrite of file (or creeating of folder having same name as existing file never allowed
CHXAvMessageDialog::DoAlertInfoL(CHXAvCleanString(R_ERR_NAME_ALREADY_EXISTS)());
bNeedToPrompt = true;
}
else
{
// user selected a unique folder name (path already checked above)
res = qtrUnique;
}
}
else
{
// looking for file target
if( bFileNameExists )
{
if( flags & fDisallowFileOverwrite )
{
// overwrite of file not allowed
CHXAvMessageDialog::DoAlertInfoL(CHXAvCleanString(R_ERR_NAME_ALREADY_EXISTS)());
bNeedToPrompt = true;
}
else
{
// ask user if we should overwrite selected filename
NameExt newNameInfo = GetDisplayText(m_nameBuf, flags & fWantFolder);
DPRINTF(SYMP_FILE_UI, ("FileUi::QueryTargetNameL(): file matching name already exists\n"));
bNeedToPrompt = !CHXAvMessageDialog::DoQueryL(CHXAvCleanString(R_CONF_OVERWRITE_ITEM_FORMAT, newNameInfo.first)());
if( !bNeedToPrompt)
{
// user opted to overwrite existing file
res = qtrOverwrite;
}
}
}
else
{
// user selected a unique folder name
res = qtrUnique;
}
}
if( bNeedToPrompt )
{
// we will prompt again; ensure that we suggest a unique name from now on
InitNameBufWithSuggestionL(pathDest, m_nameBuf, flags | fSuggestUniqueDefaultName);
}
}
else
{
// user canceled
m_nameBuf.Copy(KNullDesC);
bNeedToPrompt = false;
}
}
// remember this...
m_spLastUniqueName = m_nameBuf.AllocL();
return res;
}
////////////////////////////////////////////////////////
// initialize name buffer with a default filename
//
// may or may not be slightly modified to ensure unique within
// destination path (depends on flags)
//
void CHXAvFileUI::InitNameBufWithSuggestionL(const TDesC& pathDest, const TDesC& fileName, TUint flags)
{
TFileName* pNameToSuggest = AllocSuggestedFileNameL(pathDest, fileName, flags);
AUTO_PUSH_POP_DEL(pNameToSuggest);
// work with leaf (filename) part of path ('foo.rm')
TPtrC ptrNode (CHXAvFile::GetNakedPathNode(*pNameToSuggest));
m_nameBuf.Copy(ptrNode);
}
////////////////////////////////////////////////////////////
// helper: called from MoveItemHelperL
//
// prompt for a name, then (if user gives good name) do the move
//
TInt CHXAvFileUI::DoPromptMoveItemHelperL(const TDesC& pathDest, TInt idxItem)
{
SUSPEND_REFRESH(m_spStore);
const CHXAvFileStore::Entries& entries = m_spStore->GetEntries();
const TEntry& entry = entries[idxItem].m_entry;
TInt err = KErrGeneral;
TUint flags = fSuggestUniqueDefaultName;
if (entry.IsDir())
{
flags |= fWantFolder;
}
// ask for a suitable filename for the target file
QueryTargetNameResult res = QueryTargetNameL(CHXAvCleanString(R_PROMPT_ENTER_NEW_NAME)(),
pathDest,
entry.iName, flags);
switch (res)
{
case qtrUnique:
case qtrOverwrite:
// got target name...
err = m_spStore->MoveItemL(idxItem, pathDest,
m_nameBuf, res == qtrOverwrite);
break;
case qtrAbort:
// user canceled
err = KErrCancel;
break;
default:
err = KErrGeneral;
break;
}
return err;
}
////////////////////////////////////////////////////////////
// helper: called from MoveItemHelperL
//
// confirm overwrite, then (if user accepts) do the move
//
TInt CHXAvFileUI::DoOverwriteMoveItemHelperL(const TDesC& pathDest, TInt idxItem)
{
TInt err = KErrGeneral;
SUSPEND_REFRESH(m_spStore);
// check for move to self
if(m_spStore->IsSamePathL(pathDest, idxItem))
{
// do nothing; pretend user canceled (same effect as moving to self)
err = KErrCancel;
}
else
{
//
// in case where move target path is a folder (and source is either file or folder) we
// force the user to create a unique name; other apps like Photo Album behave this
// way (there are some hassles with underlying API when specifying folder as move target,
// although there are work-arounds)
//
bool bFolderExists = m_spStore->NameExistsInTargetPathL(pathDest, idxItem, CHXAvFile::ntFolder);
if(bFolderExists)
{
CHXAvMessageDialog::DoAlertInfoL(CHXAvCleanString(R_ERR_NAME_ALREADY_EXISTS)());
// prompt for new target name
err = DoPromptMoveItemHelperL(pathDest, idxItem);
}
else
{
HX_ASSERT(m_spStore->NameExistsInTargetPathL(pathDest, idxItem, CHXAvFile::ntFile));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?