chxavfileviewwindow.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,905 行 · 第 1/4 页

CPP
1,905
字号
/************************************************************************
 * chxCHXAvFileViewWindow.cpp
 * -----------------------
 *
 * Synopsis:
 * Contains the implementation of the CHXAvFileViewWindow.  This is the class
 * that implements the object that is controlled by the CHXAvFileView
 * object.  This class creates and manages the actual controls of the file 
 * view.
 *
 * Target:
 * Symbian OS
 *
 *
 * (c) 1995-2003 RealNetworks, Inc. Patents pending. All rights reserved.
 *
 ************************************************************************/

// Standard includes...
#include <eiklbo.h> 
#include <aknlists.h>
#include <coemain.h>
#include <coeutils.h>
#include <akntabgrp.h>
#include <akntabgrp.h>
#include <aknnavide.h>
#include <akntitle.h>
#include <aknsfld.h>
#include <aknutils.h>
#include <akniconarray.h> 
#include <aknselectionlist.h>
#include <eikfutil.h>
#include <f32file.h> // TSwitch, CFileMan
#include <barsread.h> //TResourceReader
#include <SenduiMtmUids.h>
#include <sendui.h>
#include <SendNorm.rsg>

// Helix includes...
#include "hxassert.h"
#include "ihxpckts.h"
#include "hxstring.h"
#include "hxurl.h"

// Includes from this project...
#include "chxavcleanupstack.h"
#include "chxavfileviewwindow.h"
#include "chxavnamedisplaytrait.h"
#include "chxavfileview.h"
#include "chxavramparser.h"
#include "hxsym_debug.h"
#include "hxsym_leaveutil.h"
#include "hxsym_mmc_utils.h"
#include "chxavcleanstring.h"
#include "chxavurlrep.h"
#include "chxavfolderdisplayinfo.h"
#include "chxavmediafolderinfo.h"
#include "chxavplayerui.h"
#include "chxavfileutil.h"
#include "chxavplayer.h"
#include "chxavplaylist.h"
#include "realplayer.hrh"
#include "realplayer.rsg"

#include "player_uids.h"
#include "chxavurlrep.h"
#include "realplayer.mbg"
#include "r1p.hlp.hrh"


namespace
{

// Order is important! must match TFileViewIconImageIds
CHXAvMisc::ImageInfo const theirListBoxIcons[] =
{
    // mark icon must be first
    { EMbmAvkonQgn_indi_marked_grid_add, EMbmAvkonQgn_indi_marked_grid_add_mask }, // EMarkIcon
    { EMbmAvkonQgn_prop_folder_large, EMbmAvkonQgn_prop_folder_large_mask }, // EFolderIcon
    { EMbmAvkonQgn_prop_group_large, EMbmAvkonQgn_prop_group_large_mask } // EVideosFolderIcon
};

CHXAvMisc::ImageInfo const ourListBoxIcons[] =
{
    { EMbmRealplayerQgn_prop_media_sub, EMbmRealplayerQgn_prop_media_sub_mask }, // EMediaIcon
    { EMbmRealplayerQgn_prop_network_sub, EMbmRealplayerQgn_prop_network_sub_mask }  // EPlaylistIcon
};



// these must match order of icons above; localized folder ids specified in .rss (not here)
TInt ToImageIndex(CHXAvFile::FileType type)
{
    HX_ASSERT(type != CHXAvFile::ftUnknown);
    switch(type)
    {
    case CHXAvFile::ftRam:
        // playlist icon
	return EPlaylistIcon;
    case CHXAvFile::ftLink:
        // link icon
	return EPlaylistIcon;
    case CHXAvFile::ftFolder:
        // folder icon
	return EFolderIcon;
    default: 
        // media icon for everything else
	return EMediaIcon;
    }
}

} // local


/*
 * CHXAvFileViewWindow
 * -------------------
 * constructor
 *
 */
CHXAvFileViewWindow::CHXAvFileViewWindow() 
: CHXAvNameDisplayTrait(true)
, m_pListBox(0) 
, m_pFileView(0) 
, m_playerUI(0) 
, m_wpNaviPane(0) 
, m_wpTabGroup(0) 
, m_bHideTabs(false)
, m_shiftMarkState(smNotMarking)
{
}



/*
 * ~CHXAvFileViewWindow
 * --------------------
 * Dtor.
 *
 */
CHXAvFileViewWindow::~CHXAvFileViewWindow()
{
    HX_DELETE(m_pListBox);
    CleanUpTabs();
}


/*
 * CleanUpTabs
 * -----------
 *
 */
void CHXAvFileViewWindow::CleanUpTabs()
{
    if(m_wpNaviPane)
    {
        if(m_spDecoratedTabGroup)
        {
            // restore navipane
	    m_wpNaviPane->Pop(m_spDecoratedTabGroup.Ptr());
        }
	m_wpNaviPane = 0;
    }
    m_spDecoratedTabGroup = 0;
    m_wpTabGroup = 0;
}


/* 
 * CreateTabsL
 * -----------
 *
 */
void 
CHXAvFileViewWindow::CreateTabsL(TInt idxInitTab)
{
    if(0 == m_wpNaviPane)
    {
        // get handle to the navi pane control
        CEikStatusPane* pStatusPane = iEikonEnv->AppUiFactory()->StatusPane();
	m_wpNaviPane 
            = static_cast<CAknNavigationControlContainer*>(
            pStatusPane->ControlL(TUid::Uid(EEikStatusPaneUidNavi)) );
    }

    // create tab group control to decorate navi pane
    m_spDecoratedTabGroup = m_wpNaviPane->CreateTabGroupL();
    m_wpTabGroup 
        = static_cast<CAknTabGroup*>(m_spDecoratedTabGroup->DecoratedControl());

    // two tabs
    const TInt tabWidthFlag = EAknTabWidthWithTwoTabs;
    m_wpTabGroup->SetTabFixedWidthL(tabWidthFlag);

    // create tabs for tab control
    TInt count = m_spPageInfo->Nelements();
    for(TInt idx = 0; idx < count; ++idx)
    {
        CHXAvFileViewPageInfoPtr pInfo = (*m_spPageInfo)[idx];
        CHXAvMisc::ImageInfo imgInfo = pInfo->GetTabInfo();
        CHXAvMisc::AddTabL(m_wpTabGroup, pInfo->GetTabImageFilePath(), idx, imgInfo.idxImg, imgInfo.idxImgMask);
    }

    // activate the default tab
    m_wpTabGroup->SetActiveTabByIndex(idxInitTab);

    
}

////////////////////////////////////////////////////////////////////
//
void CHXAvFileViewWindow::UpdateTopAndBottomL()
{
    UpdateNaviPaneL();
    CHXAvMisc::UpdateScrollBar(m_pListBox);
}

////////////////////////////////////////////////////////////////////
// 
void CHXAvFileViewWindow::UpdateNaviPaneL()
{
    DPRINTF(SYMP_INFO, ("CHXAvFileViewWindow::UpdateNaviPaneL()\n"));
    if(m_wpNaviPane)
    {
        if(m_spDecoratedTabGroup && !m_bHideTabs)
        {
            m_wpNaviPane->PushL(*m_spDecoratedTabGroup);
        }
        else
        {
            m_wpNaviPane->PushDefaultL();
        }
    }
}

////////////////////////////////////////////////////////////
// called when drive state changed (or may have changed)
void CHXAvFileViewWindow::ReloadCurrentPageL()
{
    LoadPageL(m_wpTabGroup->ActiveTabIndex());
}

////////////////////////////////////////////////////////////
// called when drive goes away or current folder goes aways
void CHXAvFileViewWindow::ResetCurrentPageInfoToRootL()
{
    m_spCurrentPage->Indexes().RemoveAll();
    m_spCurrentPage->SetCurrentIndex(0);
    m_spCurrentPage->FolderInfo()->SetCurrentPathL(KNullDesC);
}

////////////////////////////////////////////////////////////
//
// update drive state and reset page related data that may be 
// invalidated by the change
//
// return 'true' if page needs to be rebuilt (because state has changed)
//
bool CHXAvFileViewWindow::DoUpdateAndCheckDriveStateL()
{
    // query drive for current state info
    CHXAvMediaFolderInfo* pFolderInfo = m_spCurrentPage->FolderInfo();
    TUint32 flags = pFolderInfo->UpdateDriveInfoCheckState();
    if( flags & CHXAvMediaFolderInfo::VOLID_CHANGED )
    {
        // volume id has changed since we last looked at this drive

        // reset current path and folder index stack - they apply
        // to a different drive volume
        ResetCurrentPageInfoToRootL();
    }

    return flags != 0;
}

////////////////////////////////////////////////////////////
// 
// set current page and re-build view to reflect contents of the page
//
void CHXAvFileViewWindow::LoadPageL(TInt idxPage)
{
    HX_ASSERT(idxPage >= 0);
    HX_ASSERT(idxPage < m_spPageInfo->Nelements());
    m_spCurrentPage = (*m_spPageInfo)[idxPage];

    // make sure drive info is up-to-date (handle case of removable drive)
    DoUpdateAndCheckDriveStateL();

    // handle case where saved current path info becomes invalid
    // since we last displayed it (external delete/rename); invalid
    // root handled by file store init
    if(!m_spCurrentPage->FolderInfo()->IsCurrentPathValid())
    {
        ResetCurrentPageInfoToRootL();
    }

    // set text to show if view is empty
    InitEmptyListTextL();

    // init file store model and ui helpers
    InitFileStoreL();

    // init listbox contents
    TInt idxCurrent = m_spCurrentPage->GetSelectedItemIndex();
    RefreshListBoxL(idxCurrent);
    
    // title, navipane, etc.
    m_pFileView->UpdateViewStateL();

    DrawNow();
       
}

////////////////////////////////////////////////////////////
// LoadPageL() helper
//
// re-init file store (and related file ui)
//
// assumes drive info is up-to-date
//
void CHXAvFileViewWindow::InitFileStoreL()
{
    m_spStore = 0;
    m_spFileUI = 0;

    CHXAvMediaFolderInfo* pFolderInfo = m_spCurrentPage->FolderInfo();
    const CHXAvFile::DriveInfo info = pFolderInfo->GetDriveInfo();

    // only create a file store if drive is accessible
    if( CHXAvFile::dsAccessible == info.state )
    {
        //
        // re-create file store (for underlying access to associated
        // media folder) and ui handler 
        //
        m_spStore = new (ELeave) CHXAvFileStore();

        // trap in case path/drive is bad somehow
        TRAPD(err, 
        m_spStore->ConstructL(
        pFolderInfo->GetRoot(), 
        pFolderInfo->GetCurrentPath(),
        m_spCurrentPage->IsAutoCreateRoot()) );
        if(KErrNone == err)
        {   
            m_spFileUI = new (ELeave) CHXAvFileUI();
            m_spFileUI->ConstructL(m_playerUI, m_spStore);

            // stop watching for drive events (store will watch for us)
            m_fsWatcher.StopWatching();

            // request file system events from file store
            CHXAvCompositeCommand& handler = m_spStore->GetEventHandler();
            CHXAvCommand& cmd = MakeCommand(this, &CHXAvFileViewWindow::OnFileSystemEvent);
            handler.AppendL(cmd);
        }
        else
        {
            // abandon these
            m_spStore = 0;
            m_spFileUI = 0;

            // don't leave; default to inaccessible media store state
            CHXAvMessageDialog::DoAlertInfoL(CHXAvCleanString(R_ERR_OPEN_FOLDER_FAILED)());
        }
    }

    if( !m_spStore )
    {
        // normally store watches for us; in this case we want to detect
        BeginWatchingForDriveEventsL();
    }
    
}

////////////////////////////////////////////////////////////
// LoadPageL() helper
//
// set text to display when page is empty (empty folder or invalid drive)
//
// assumes drive info is up-to-date
//
void CHXAvFileViewWindow::InitEmptyListTextL()
{
    DPRINTF(SYMP_INFO, ("CHXAvFileViewWindow::InitEmptyListTextL()\n"));

    TInt idEmptyList = R_AVP_FILE_FOLDER_EMPTY_TEXT;

    CHXAvMediaFolderInfo* pFolderInfo = m_spCurrentPage->FolderInfo();
    const CHXAvFile::DriveInfo info = pFolderInfo->GetDriveInfo();

    if( pFolderInfo->IsMmcFolder() )
    {
        // non-accessible text only applies to mmc (unexpected for flash)
        switch( info.state )
        {
        case CHXAvFile::dsAccessible:
            idEmptyList = R_AVP_FILE_FOLDER_EMPTY_TEXT; 
            break;
        case CHXAvFile::dsCorrupted:
            idEmptyList = R_AVP_MMC_CORRUPT;
            break;
        case CHXAvFile::dsLocked:
            idEmptyList = R_AVP_MMC_LOCKED; 
            break;
        default: 
            idEmptyList = R_AVP_MMC_NOT_INSERTED;
            break;
        }
    }

    m_pListBox->View()->SetListEmptyTextL(CHXAvCleanString(idEmptyList)());
}

////////////////////////////////////////////////////////////
// called when no store for current page
void CHXAvFileViewWindow::BeginWatchingForDriveEventsL()
{
    HX_ASSERT(!m_spStore);
    // watch all drives; we can't specify an actual drive
    m_fsWatcher.SetWatchPathL(KNullDesC); 
    m_fsWatcher.SetNotifyType(ENotifyAll);  
            
    // delay notifications to minimize potential for receiving flood of events
    m_fsWatcher.SetNotificationDelay(2000);
    m_fsWatcher.StartWatching();
}


/* 
 * ConstructL
 * ----------
 *
 */
void CHXAvFileViewWindow::ConstructL(const TRect& rc, CHXAvPlayerUI* pPlayerUi, CHXAvFileView* pFileView,
				     const refptr<CHXAvFileViewPageInfoVector>& spPageInfo,
				     TInt idxCurrentPage)
{
    HX_ASSERT(pPlayerUi);
    HX_ASSERT(pFileView);
    HX_ASSERT(spPageInfo);
    HX_ASSERT(spPageInfo->Nelements() > 0);
    HX_ASSERT(idxCurrentPage < spPageInfo->Nelements());

    m_playerUI = pPlayerUi;
    m_pFileView = pFileView;
    m_spPageInfo = spPageInfo;


    // callback to rebuild current page after drive goes away
    const CHXAvCommand& cmd =
        MakeCommand(this, &CHXAvFileViewWindow::ReloadCurrentPageL);
    m_cbReloadPage.ConstructL(cmd);

    // for watching for mount events (when no store for current drive)
    m_fsWatcher.ConstructL();
    m_fsWatcher.SetEventActionL(MakeCommand(this, &CHXAvFileViewWindow::OnFileSystemEvent));

    // create main view window and listbox
    CreateWindowL();
    CreateFileViewListBoxL();
    SetRect(rc);

    // only create tabs if there is more than one storage location
    if(m_spPageInfo->Nelements() > 1)
    {
        CreateTabsL(idxCurrentPage);
    }

    // build and show initial page
    LoadPageL(idxCurrentPage);
    ActivateL();   
}

////////////////////////////////////////////////////////////
// called when we receive notification that something has
// changed on the file system (and we know it isn't for an

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?