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