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