chxavfileviewwindow.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,905 行 · 第 1/4 页
CPP
1,905 行
// mmc drive swap); since filesystem event notification does
// not specify exactly what changed, we act as through current
// directory view must be updated
//
void CHXAvFileViewWindow::HandlePossibleCurrentFolderChangeL()
{
HX_ASSERT(m_spStore);
// check possibility that current store path (current folder in view)
// has been deleted or renamed
if(CHXAvFile::PathExists(m_spStore->GetFullPath()))
{
// assume current folder needs updating (hard to tell for sure)
TInt idxHilight = m_pListBox->CurrentItemIndex();
if( idxHilight >= 0 ) // -1 == empty
{
//
// get name of last item hilighted; we want to keep it
// hilighted (if possible) as contents of directory change
// from external fs events; we need to copy it
// since RefreshListBoxL() updates the entry list
//
const CHXAvFileStore::Entries& entries = m_spStore->GetEntries();
HX_ASSERT(idxHilight < entries.Nelements());
const TEntry& entry = entries[idxHilight].m_entry;
HBufC* pSearchName = entry.iName.AllocL();
AUTO_PUSH_POP_DEL(pSearchName);
RefreshListBoxL(idxHilight, *pSearchName);
}
else
{
// nothing was previously hilighted
RefreshListBoxL();
}
}
else
{
// reload current page; we could be smarter and try to go up to parent
ResetCurrentPageInfoToRootL();
m_cbReloadPage.Set(1);
}
}
////////////////////////////////////////////////////////////
// usually called when store detects an generated event; when
// store does not exist (because drive/path not present), we
// watch for possible drive mount/unmount events via our own
// filesystem watcher (and may receive events that way)
//
void CHXAvFileViewWindow::OnFileSystemEvent()
{
DPRINTF(SYMP_FILE, ("CHXAvFileViewWindow::OnFileSystemEvent(): something changed...\n"));
TRAPD(err, HandleFileSystemEventL());
DPRINTF(SYMP_FILE, ("CHXAvFileViewWindow::OnFileSystemEvent(): handler err = %ld\n", err));
}
// OnFileSystemEvent helper
void CHXAvFileViewWindow::HandleFileSystemEventL()
{
bool bStateChanged = DoUpdateAndCheckDriveStateL();
if( !m_spStore )
{
DPRINTF(SYMP_INFO, ("OnFileSystemEvent(): no store; drive added?"));
// previously unavailable drive possibly mounted
if( bStateChanged )
{
// drive state for current page has changed; rebuild everything
ReloadCurrentPageL();
}
}
else
{
if(bStateChanged)
{
// current drive state has changed (possibly unmounted);since
// we handle this by possibly destroying the (now invalid) current
// store, which is calling us here, we handle this in a separate callback
m_cbReloadPage.Set(1);
}
else
{
// update contents (if current drive is accessible)
CHXAvMediaFolderInfo* pFolderInfo = m_spCurrentPage->FolderInfo();
const CHXAvFile::DriveInfo info = pFolderInfo->GetDriveInfo();
if( CHXAvFile::dsAccessible == info.state )
{
// we don't know for sure that this event affects our view (we assume it does)
HandlePossibleCurrentFolderChangeL();
}
}
}
}
////////////////////////////////////////////////////
//
bool CHXAvFileViewWindow::HilightItemIsPlaylist() const
{
TInt idxItem = m_pListBox->CurrentItemIndex();
const CHXAvFile::FileInfo& info = GetFileInfoL(idxItem);
bool bIsPlaylist = (info.m_type == CHXAvFile::ftRam || info.m_type == CHXAvFile::ftLink);
if(bIsPlaylist)
{
// verify that playlist is well-formed by attempting to parse it
CHXAvPlaylistPtr spList = CreatePlaylist(info.m_entry);
if( !spList || 0 == spList->Length() )
{
// corrupt or otherwise not-editable
bIsPlaylist = false;
}
}
return bIsPlaylist;
}
////////////////////////////////////////////////////
// true if current item corresponds to a file
bool CHXAvFileViewWindow::HilightItemIsFile() const
{
TInt idxItem = m_pListBox->CurrentItemIndex();
const CHXAvFile::FileInfo& info = GetFileInfoL(idxItem);
return !info.m_entry.IsDir();
}
////////////////////////////////////////////////////
// return true if hilighted item is in the mark list
bool CHXAvFileViewWindow::HilightItemIsMarked() const
{
const CArrayFix<TInt>* pSelectedItems =
m_pListBox->SelectionIndexes();
TInt idxItem = m_pListBox->CurrentItemIndex();
HX_ASSERT(idxItem != -1); // call HasHilightItem() first
for(TInt idx = 0; idx < pSelectedItems->Count(); ++idx)
{
if (idxItem == (*pSelectedItems)[idx])
{
// index was in the list and therefore marked
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////
// get an in-range index closest to idxWanted
//
// return:
//
// -1 if list is empty
// idx of last item if wanted index is beyond the last item
// idxWanted if it is in range
//
TInt CHXAvFileViewWindow::GetBestIndex(TInt idxWanted) const
{
HX_ASSERT(idxWanted >= 0);
// make sure best index is valid; just in case
TInt idxBest = (idxWanted >= 0) ? idxWanted : 0;
TInt itemCount = m_pListBox->Model()->NumberOfItems();
if( idxBest >= itemCount )
{
// wanted index is invalid (beyond last item)
if( itemCount > 0)
{
// next best is last item
idxBest = itemCount - 1;
}
else
{
// empty list
idxBest = -1;
}
}
return idxBest;
}
//
// args:
//
// currentItemName - if not empty, we try to set current index to item that matches this name
// if specified, must be provided in full significant name format, e.g. "foo.rm"
//
// idxLastCurrentItem - preserve index at last or closest to last current item if preferred name
// not mathched or specified
//
void
CHXAvFileViewWindow::SetListBoxSelectionAndDrawL(TInt idxLastCurrentItem,
const TDesC& currentItemName)
{
HX_ASSERT(m_pListBox);
HX_ASSERT(m_spStore);
m_pListBox->Reset();
m_pListBox->ClearSelection();
// ensure zero (not -1) if no current item
idxLastCurrentItem = max(idxLastCurrentItem, 0);
// determine current hilight item
TInt idxCurrent = -1;
if(currentItemName.Length() > 0)
{
// trim possible folder suffix (entries don't keep suffix in name)
TPtrC ptrName = CHXAvFile::GetEnsureNoFolderSuffix(currentItemName);
// see if we can find a match for the given name
const CHXAvFileStore::Entries& entries = m_spStore->GetEntries();
for(TInt idx = 0; idx < entries.Nelements(); ++idx)
{
const TEntry& entry = entries[idx].m_entry;
if (0 == entry.iName.CompareF(ptrName))
{
// found it
idxCurrent = idx;
break;
}
}
}
if( idxCurrent == -1 )
{
idxCurrent = GetBestIndex(idxLastCurrentItem);
}
// check again...
if( idxCurrent >= 0 ) // -1 = empty
{
HX_ASSERT(idxCurrent < m_pListBox->Model()->NumberOfItems());
m_pListBox->SetCurrentItemIndex(idxCurrent);
}
CHXAvMisc::UpdateScrollBar(m_pListBox);
m_pListBox->DrawNow();
}
////////////////////////////////////////////////////////////
// rebuild and redraw listbox contents
//
void
CHXAvFileViewWindow::RefreshListBoxL(TInt idxLastCurrentItem,
const TDesC& currentItemName)
{
HX_ASSERT(m_spStore);
// create new list of items and transfer ownership to the listbox
CDesCArrayFlat* pItems = CreateListItemsL();
AUTO_PUSH_POP(pItems);
CTextListBoxModel* pModel = m_pListBox->Model();
pModel->SetItemTextArray(pItems);
pModel->SetOwnershipType(ELbmOwnsItemArray);
SetListBoxSelectionAndDrawL(idxLastCurrentItem, currentItemName);
}
////////////////////////////////////////////////////
// allocate list box item text for given folder entry
//
//
// main text: folder name
// sub text : count of contents
//
HBufC*
CHXAvFileViewWindow::AllocFolderItemTextL(const TEntry& entry) const
{
HX_ASSERT(entry.IsDir());
// create full path to this folder
TParse parse;
parse.Set(m_spStore->GetFullPath(), 0, 0);
parse.AddDir(entry.iName); // iName relative to base path (does not start with '/')
// find folder child count (nanoplayer files + child folders)
TInt childCount = 0;
const bool bIncludeFolders = true;
HXSYM_LEAVE_IF_ERR(
CHXAvFile::GetFolderChildCount(parse.FullName(), childCount,
bIncludeFolders, CHXAvFile::FilterIncludeNanoPlayerFiles));
_LIT(KSubTextFormat, "%d");
TBuf<40> bufSubText;
bufSubText.Format(KSubTextFormat, childCount);
// this handles localized dirs that may be on mmc
CHXAvFolderDisplayInfo displayInfo;
displayInfo.SetFolderPathL(parse.FullName());
HBufC* pItemText = CHXAvMisc::AllocGrListItemL(displayInfo.GetDisplayText(), bufSubText, ToImageIndex(CHXAvFile::ftFolder));
return pItemText;
}
////////////////////////////////////////////////
// try to create playlist object for given file entry
CHXAvPlaylistPtr
CHXAvFileViewWindow::CreatePlaylist(const TEntry& entry) const
{
HX_ASSERT(!entry.IsDir());
// get full path to this file
TFileName* pPath = CHXAvFile::AllocFileNameL(m_spStore->GetFullPath(), entry.iName);
AUTO_PUSH_POP_DEL(pPath);
CHXString strPath;
CHXAvStringUtils::DesToString(*pPath, strPath);
// try to parse it as a ram file
return CHXAvRAMParser::Parse(strPath);
}
////////////////////////////////////////////////
//
HBufC*
CHXAvFileViewWindow::AllocPlayListDescriptionL(const CHXAvFile::FileInfo& info) const
{
HX_ASSERT(info.m_type == CHXAvFile::ftRam || info.m_type == CHXAvFile::ftLink);
HBufC* pListText = 0;
TInt count = 0;
CHXAvPlaylistPtr spPlaylist = CreatePlaylist(info.m_entry);
if( spPlaylist)
{
// this is a ram file (or a convincing imposter)
count = spPlaylist->Length();
if (count == 1)
{
CHXAvPlaylistItr iter(*spPlaylist);
// set display text to first and only playlist item
const CHXAvURLRep& url = iter.Current();
if( url.Host().GetLength() > 0 )
{
CHXAvCleanString text(url.Host());
pListText = text().AllocL();
}
}
}
if(!pListText)
{
// set display text to count of items in playlist
CHXAvCleanString text(R_AVP_LINK_COUNT, count);
pListText = text().AllocL();
}
return pListText;
}
////////////////////////////////////////////////////
// allocate list box item text for given file entry
//
//
// main text: file name
// sub text : size in bytes if file/ url if ram link
//
HBufC*
CHXAvFileViewWindow::AllocFileItemTextL(const CHXAvFile::FileInfo& info) const
{
const TEntry& entry = info.m_entry;
HX_ASSERT(!entry.IsDir());
TFileName* pPath = CHXAvFile::AllocFileNameL(GetFullPath(),
entry.iName);
AUTO_PUSH_POP_DEL(pPath);
HBufC* pInfoText = 0;
if( (CHXAvFile::ftRam == info.m_type) || (CHXAvFile::ftLink == info.m_type) )
{
// show playlist description
pInfoText = AllocPlayListDescriptionL(info);
}
else
{
// not a playlist file; show size
pInfoText = CHXAvMisc::AllocFileSizeDescL(entry.iSize);
}
AUTO_PUSH_POP_DEL(pInfoText);
NameExt pair = GetDisplayText(entry.iName);
HBufC* pListText = CHXAvMisc::AllocGrListItemL(pair.first, *pInfoText, ToImageIndex(info.m_type));
return pListText;
}
////////////////////////////////////////////////////////////
// allocate formatted list box items for current dircectory
//
void
CHXAvFileViewWindow::AddListItemsForCurrentPathL(CDesCArrayFlat*& pItems) const
{
HX_ASSERT(m_spStore);
// re-build local disk directory entry table
const CHXAvFileStore::Entries& entries = m_spStore->UpdateEntriesL();
TInt count = entries.Nelements();
for(TInt idx = 0; idx < count; ++idx)
{
const CHXAvFile::FileInfo& info = GetFileInfoL(idx);
const TEntry& entry = info.m_entry;
// skip system/hidden files
if(! CHXAvUtil::ShouldHideFromUser(entry) )
{
HBufC* pItemText = 0;
// show only folders and files that we can play
if (info.m_type == CHXAvFile::ftFolder)
{
pItemText = AllocFolderItemTextL(entry);
}
else if (CHXAvFile::IsNanoPlayerFileType(info.m_type))
{
pItemText = AllocFileItemTextL(info);
}
if (pItemText)
{
AUTO_PUSH_POP_DEL(pItemText);
pItems->AppendL(*pItemText); // this copies buffer
}
}
}
}
////////////////////////////////////////////////////////////
//
// create array of listbox items (in list-box item format)
// from current entry info
//
// list-box item format for double item large graphic listbox
// is:
//
// [icon idx]\t{item text}\t{sub-text}
//
CDesCArrayFlat*
CHXAvFileViewWindow::CreateListItemsL() const
{
CDesCArrayFlat* pItems = new (ELeave) CDesCArrayFlat(20 /*granularity*/);
AUTO_PUSH_POP(pItems); // out
if( m_spStore )
{
AddListItemsForCurrentPathL(pItems);
}
return pItems;
}
////////////////////////////////////////////////////////////
// 42 X 29 (their folder = 42 x 36; mark icon = 13 x 13) for large icons
void CHXAvFileViewWindow::CreateAndAddIconsL()
{
CAknIconArray* pIcons = new (ELeave) CAknIconArray(3);
AUTO_PUSH_POP(pIcons);
// order is important!
CHXAvMisc::AddIconHelperL(CHXAvMisc::KAVPAvkonImagePath, theirListBoxIcons, ARRAY_COUNT(theirListBoxIcons), pIcons);
CHXAvMisc::AddIconHelperL(m_playerUI->GetAppImageFilePath(), ourListBoxIcons, ARRAY_COUNT(ourListBoxIcons), pIcons);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?