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 + -
显示快捷键?