chxavpathselector.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 376 行
CPP
376 行
/*============================================================================*
*
* (c) 1995-2002 RealNetworks, Inc. Patents pending. All rights reserved.
*
*============================================================================*/
//
// encapsulates ui logic for prompting a path from the user
//
//
// usage:
//
// CHXAvPathSelector selector;
// selector.InitL(mediaPathInfo);
//
// bool bSelected = selector.PromptUserSelectPathL();
// if( bSelected )
// {
// const TDesC& fullPath = selector.GetSelectedPath();
// /* do something with the path */
// }
//
// Notes:
//
// Avkon softkey command ids that cause ExecuteLD to return 0:
//
// EAknSoftkeyCancel:
// EAknSoftkeyBack:
// EAknSoftkeyNo:
//
#include "hxassert.h"
#include "chxavmisc.h"
#include "chxavvector.h"
#include "chxavminmax.h"
#include "chxavfolderpopuplist.h"
#include "chxavfileviewpageinfo.h"
#include "chxavcleanupstack.h"
#include "chxavpathselector.h"
#include "hxsym_leaveutil.h"
#include "hxsym_debug.h"
#include "hxsym_mmc_utils.h"
#include "realplayer.hrh"
///////////////////////////////////
// ctor
CHXAvPathSelector::CHXAvPathSelector()
: m_idxInitCurrentItem(0)
, m_resIdPrompt(-1)
, m_resIdSelectButtonText(-1)
{
}
///////////////////////////////////
// dtor
CHXAvPathSelector::~CHXAvPathSelector()
{
}
///////////////////////////////////
//
void CHXAvPathSelector::ResetForRootFolderPrompt(TInt idxCurrentItem)
{
m_idxInitCurrentItem = idxCurrentItem;
m_spCurrentPath = 0;
m_spRootPath = 0;
}
///////////////////////////////////
//
void CHXAvPathSelector::InitL(const CHXAvVector<CHXAvMediaFolderInfoPtr>& mediaFolderInfo,
TInt resIdPrompt, TInt resIdSelectButtonText)
{
m_mediaFolderInfo.Resize(0);
m_indexes.RemoveAll();
ResetForRootFolderPrompt(0);
// copy only valid media folders
for(TInt idx = 0; idx < mediaFolderInfo.Nelements(); ++idx)
{
CHXAvMediaFolderInfoPtr spInfo = mediaFolderInfo[idx];
spInfo->UpdateDriveInfo();
const CHXAvFile::DriveInfo& info = spInfo->GetDriveInfo();
if( CHXAvFile::dsAccessible == info.state || CHXAvFile::dsLocked == info.state)
{
CHXAvUtil::Append(m_mediaFolderInfo, spInfo);
}
}
HXSYM_LEAVE_IF_FALSE( m_mediaFolderInfo.Nelements() > 0 );
m_resIdPrompt = resIdPrompt;
m_resIdSelectButtonText = resIdSelectButtonText;
}
////////////////////////////////////////
//
void CHXAvPathSelector::SetPathToChild(const TDesC& listText)
{
DPRINTF(SYMP_INFO, ("CHXAvPathSelector::SetPathToChild(): set path to child '%s'\n", dbg::CharPtr(listText)()));
//TPtrC folderName( avMisc::TextChunk(listText, 1) );
CHXAvFile::AppendPath(*m_spCurrentPath, listText, CHXAvFile::ntFolder);
}
////////////////////////////////////////
//
void CHXAvPathSelector::SetPathToParent()
{
DPRINTF(SYMP_INFO, ("CHXAvPathSelector::SetPathToChild(): set path to parent\n"));
TPtrC ptrParent = CHXAvFile::GetParentFolder(*m_spCurrentPath);
m_spCurrentPath->SetLength(ptrParent.Length());
}
////////////////////////////////////////
//
bool CHXAvPathSelector::CurrentFolderHasSubFoldersL()
{
TInt childCount = 0;
const bool bIncludeFolders = true;
HXSYM_LEAVE_IF_ERR(
CHXAvFile::GetFolderChildCount(*m_spCurrentPath, childCount,
bIncludeFolders, CHXAvFile::FilterIncludeNoFiles)
);
return childCount != 0;
}
////////////////////////////////////////
//
CHXAvPathSelector::Action CHXAvPathSelector::DoFolderPromptL()
{
DPRINTF(SYMP_INFO, ("CHXAvPathSelector::DoFolderPromptL(): parent path = '%s'\n", dbg::CharPtr(*m_spCurrentPath)()));
HX_ASSERT(m_spCurrentPath);
Action action = Action(-1);
// generate list of folders under current path
CDesCArrayFlat* pFolders = CHXAvFile::AllocFolderListL(*m_spCurrentPath);
AUTO_PUSH_POP_DEL(pFolders);
HX_ASSERT(pFolders->Count() > 0);
TInt idxSelected = 0;
TInt idExitCmd = EAknSoftkeyCancel;
CHXAvFolderPopupList* pPopup = new (ELeave) CHXAvFolderPopupList(idxSelected, idExitCmd);
// safe cleanup stack init until LD
{
AUTO_PUSH_POP(pPopup);
// make sure initial current item is valid
m_idxInitCurrentItem = min(m_idxInitCurrentItem, pFolders->Count() - 1);
// display the list to the user
pPopup->ConstructL(m_resIdPrompt, m_resIdSelectButtonText,
pFolders, m_spCurrentPath.Ptr(), m_idxInitCurrentItem);
}
TInt res = pPopup->ExecuteLD();
if(res)
{
HX_ASSERT(idxSelected < pFolders->Count());
SetPathToChild( (*pFolders)[idxSelected]);
if( idExitCmd == EMoveToFolder )
{
action = SELECT;
}
else
{
HX_ASSERT(EOpenFolder == idExitCmd);
if( CurrentFolderHasSubFoldersL() )
{
// enter folder; store current item index for possible return
action = ENTER;
m_indexes.Push((void *)idxSelected);
}
else
{
// go back; we can't enter this folder afterall (nothing to display)3
action = IGNORE;
SetPathToParent();
m_idxInitCurrentItem = idxSelected;
}
}
}
else
{
action = BACK;
if( 0 == m_spRootPath->CompareF(*m_spCurrentPath) )
{
// current path at root of media store; go back to 'no current media root' state
m_spCurrentPath = 0;
m_spRootPath = 0;
}
else
{
SetPathToParent();
}
// recall current item index for parent folder
m_idxInitCurrentItem = (TInt)(m_indexes.TopOfStack());
m_indexes.Pop();
}
return action;
}
////////////////////////////////////////
//
CHXAvPathSelector::Action CHXAvPathSelector::DoRootFolderPromptL()
{
Action action = Action(-1);
TUint rootFolderCount = m_mediaFolderInfo.Nelements();
HX_ASSERT(rootFolderCount > 0); // call InitL() first
// make sure initial current item is valid
m_idxInitCurrentItem = min(TUint(m_idxInitCurrentItem), rootFolderCount - 1);
// this value will be updated if user selects something
TInt idxSelected = 0;
TInt idExitCmd = EAknSoftkeyCancel;
CHXAvFolderPopupList* pPopup = new (ELeave) CHXAvFolderPopupList(idxSelected, idExitCmd);
// save cleanupstack init until LD
{
AUTO_PUSH_POP(pPopup);
// begin select process with root media store
pPopup->ConstructL(m_resIdPrompt, m_resIdSelectButtonText,
m_mediaFolderInfo, m_spCurrentPath.Ptr(), m_idxInitCurrentItem);
}
TInt res = pPopup->ExecuteLD();
if(res)
{
HX_ASSERT(idxSelected < m_mediaFolderInfo.Nelements());
TInt err = InitMediaRootPathL(m_mediaFolderInfo[idxSelected]->GetRoot());
if( KErrNone == err )
{
if( idExitCmd == EMoveToFolder )
{
// user selects this path (index)
action = SELECT;
m_idxInitCurrentItem = idxSelected;
}
else
{
HX_ASSERT(EOpenFolder == idExitCmd);
if( CurrentFolderHasSubFoldersL() )
{
// enter folder
action = ENTER;
m_idxInitCurrentItem = 0;
//store current item index for possible return back up to this folder
m_indexes.Push((void *)idxSelected); //XXXLCM cast
}
else
{
// go back; we can't enter this folder afterall
action = IGNORE;
ResetForRootFolderPrompt(idxSelected);
}
}
}
else
{
// drive probably locked (or otherwise inaccessible)
action = IGNORE;
ResetForRootFolderPrompt(idxSelected);
}
}
else
{
// back from root selection will result in exit
action = BACK;
ResetForRootFolderPrompt(-1);
HX_ASSERT(m_indexes.GetSize() == 0);
}
return action;
}
////////////////////////////////////////
//
TInt CHXAvPathSelector::InitMediaRootPathL(const TDesC& fullRootPath)
{
TInt err = KErrGeneral;
// ensure drive is accessible
const CHXAvFile::DriveInfo& info = CHXAvFile::GetDriveInfo(fullRootPath);
switch(info.state)
{
case CHXAvFile::dsAccessible:
err = KErrNone;
break;
case CHXAvFile::dsLocked:
// drive is locked; prompt user for password
err = util::DoUnlockDriveUi(info.idxDrive);
break;
default:
// drice corrupt, not present, etc.
err = KErrGeneral;
break;
}
if( KErrNone == err )
{
m_spCurrentPath = new (ELeave) TFileName();
m_spCurrentPath->Copy(fullRootPath);
m_spRootPath = fullRootPath.AllocL();
}
return err;
}
////////////////////////////////////////
// *** main method for path selector ***
//
// return true if use selects a path
//
bool CHXAvPathSelector::PromptUserSelectPathL()
{
Action action = BACK;
for( bool bContinue = true; bContinue; /*null*/ )
{
action = IGNORE;
if( !m_spCurrentPath )
{
// we don't have a media root yet
action = DoRootFolderPromptL();
if( action == BACK )
{
// back exits when at top level of media folder tree
bContinue = false;
}
}
else
{
action = DoFolderPromptL();
}
if( SELECT == action )
{
// user picked a path
bContinue = false;
}
}
HX_ASSERT(action == SELECT || action == BACK);
return action == SELECT;
}
const TDesC& CHXAvPathSelector::GetSelectedPath() const
{
if( m_spCurrentPath )
{
return *m_spCurrentPath;
}
return KNullDesC;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?