chxavfileui.cpp

来自「著名的 helix realplayer 基于手机 symbian 系统的 播放」· C++ 代码 · 共 1,125 行 · 第 1/3 页

CPP
1,125
字号
// return error if error other than user cancel occurs
//
// pathDest     -   absolute or relative to current root
//
TInt CHXAvFileUI::DoMoveItemL(const TDesC& pathDest, 
				TInt idxItem)
{
    DPRINTF(SYMP_FILE_UI, ("AvFileUI::DoMoveItemL(): moving idx %d to '%s'\n", idxItem, dbg::CharPtr(pathDest)()));
    SUSPEND_REFRESH(m_spStore);

    CHXAvCleanString msg(R_NOW_MOVING_ITEM_FORMAT, NameFromIndex(idxItem));
    m_spWaitNote->SetTextL(msg());
    m_spWaitNote->StartAndKickL();

    // move one item
    TInt err = MoveItemHelperL(pathDest, idxItem);
    m_spWaitNote->EndL();
    if( IsNonCancelError(err) )
    {
        CHXAvMessageDialog::DoAlertErrorL(CHXAvCleanString(R_ERR_MOVE_FAILED)());
    }

    return err;
}
////////////////////////////////////////////////////////////
// move multipe items to specified folder path
//
// return error if error other than user cancel occurs
//
// pathDest     -   absolute or relative to current root
//
TInt CHXAvFileUI::DoMoveItemsL(const TDesC& pathDest, 
			       const CArrayFix<TInt>& items)
{
    TInt err = KErrNone;
    SUSPEND_REFRESH(m_spStore);

    DPRINTF(SYMP_FILE_UI, ("AvFileUI::DoMoveItemsL(): moving %d items to '%s'\n", items.Count(), dbg::CharPtr(pathDest)()));

    m_spWaitNote->SetTextL(CHXAvCleanString(R_NOW_MOVING_MULT_ITEMS_FORMAT, items.Count())());
#if defined(ASYNC_COPYMOVE)
    EnableWaitNoteCancelButtonL(true);
#endif
    m_spWaitNote->StartAndKickL();

    for( TInt idx = 0; idx < items.Count(); ++idx )
    {
	err = MoveItemHelperL(pathDest, items[idx]);
	if( IsNonCancelError(err) )
	{
            // XXXLCM offer continue, cancel choice?
            DPRINTF(SYMP_FILE_UI, ("AvFileUI::DoMoveItemsL(): move failed (err = %ld)\n", err));
            break;
        }
    }

    m_spWaitNote->EndL();
    if( IsNonCancelError(err) )
    {
        CHXAvMessageDialog::DoAlertErrorL(CHXAvCleanString(R_ERR_MOVE_FAILED)());	   
    }

    return err;
}


////////////////////////////////////////////////////////////
// pathDest fully qualified path (with drive letter), or relative to epStore root
//
TFileName* CHXAvFileUI::AllocSuggestedFileNameL(const TDesC& pathDest, const TDesC& defaultName, TUint flags )
{
    TFileName* pName = 0;

    if( flags & fSuggestUniqueDefaultName )
    {
        // AllocUniqueDefaultNameL() needs full path...
        TFileName* pFullPathDest = m_spStore->AllocFullPathL(pathDest, KNullDesC, CHXAvFile::ntFolder);
        AUTO_PUSH_POP_DEL(pFullPathDest);

        // pick a default file/folder name; we get full path ('c:\realnetworks\root\foo.rm')
        pName = CHXAvFile::AllocUniqueDefaultNameL(*pFullPathDest, defaultName, flags & fWantFolder, *this);
        if(!pName)
        {
            // rare case; display no default name
            DPRINTF(SYMP_FILE_UI, ("AvFileUI::AllocSuggestedFileNameL(): could not find unique name"));
            pName = CHXAvFile::AllocFileNameL(KNullDesC); 
        }
    }
    else
    {
        // we don't know/care whether this name would be unique within the destination path
        pName = CHXAvFile::AllocFileNameL(defaultName);
    }

    return pName;
}
////////////////////////////////////////////////////////////
// get a unique, valid file or folder name from the
// user
//
// args:
//
//   pathDest                 -  absolute or relative to current root
//
//   defaultName              -  filename to use for initializing text in dialog edit box
//                            -  also provides default extension;
//                            -  for folders, trailing '\' is optional (handled)
//
// returns :
//
//   m_nameBuf is set as "name" or "name/" (depending on bWantFolder)
//
//   return false if user cancels
//
// notes:
//
//   if extensions are hidden, they are automatically added to what user enters
//
//   defaultName    prompt      user entry      result
//
//   cat            cat         dog.rm          dog.rm
//   cat            cat         poop            poop
//   cat.rm         cat         flee            flee.rm
//   cat.rm         cat         cat.rm          cat.rm.rm
//   .rm                        bob             bob.rm
//                              bob             bob
//
//   same examples, if extensions are not hidden:
//
//   cat            cat         dog.rm          dog.rm
//   cat            cat         poop            poop
//   cat.rm         cat.rm      flee            flee
//   cat.rm         cat.rm      cat             cat.rm
//   .rm            .rm         bob             bob
//                              bob             bob
//
CHXAvFileUI::QueryTargetNameResult 
CHXAvFileUI::QueryTargetNameL(const TDesC& prompt,const TDesC& pathDest,
		const TDesC& defaultName, TUint flags)                      
{
    DPRINTF(SYMP_FILE_UI, ("AvFileUI::QueryTargetNameL(): in folder '%s'\n", dbg::CharPtr(pathDest)()));

    QueryTargetNameResult res = qtrAbort;

    // reset working buffer
    m_nameBuf.SetLength(0);

    //
    // determine how many chars are left for new filename within given path; we'll
    // restrict user input so we don't overflow filename buffer
    //
    TFileName* pFullPathDest = m_spStore->AllocFullPathL(pathDest, KNullDesC, CHXAvFile::ntFolder);
    AUTO_PUSH_POP_DEL(pFullPathDest);

    TInt cchMaxName = KMaxFileName - pFullPathDest->Length();

    // possibly subtract length of hidden extension or folder suffix
    NameExt ext = GetDisplayText(defaultName, flags & fWantFolder);
    cchMaxName -= ext.second.Length();

    DPRINTF(SYMP_FILE_UI, ("AvFileUI::QueryTargetNameL(): max chars left for name = %d\n", cchMaxName));

    if( cchMaxName <= 0 )
    {
        // destination path is too long!
        return qtrPathTooLong;
    } 
    
    // ui spec requires that we arbitrarily limit names to 40 chars; code does not care
    if (cchMaxName > CHXAvMisc::KAVPMaxNakedFileName )
    {
        cchMaxName = CHXAvMisc::KAVPMaxNakedFileName;
    }

    InitNameBufWithSuggestionL(pathDest, defaultName, flags);
    
    for( bool bNeedToPrompt = true; bNeedToPrompt ; )
    {
	//
        // name buf should have something like 'foo.rm'; now possibly split name into
        // user-display version ('foo') and ext ('.rm')
        //
        HBufC* pbuffNameInfo = m_nameBuf.AllocL(); // nameInfo will refer into this buffer
        AUTO_PUSH_POP_DEL(pbuffNameInfo);
        NameExt nameInfo = GetDisplayText(*pbuffNameInfo, flags & fWantFolder);

        TFileName* pName = CHXAvMessageDialog::GetFileNameFromUserL(prompt, nameInfo.first, cchMaxName);
	if( pName )
	{
            // update name buf, re-adding extension that we might have lopped off for display purposes
	    m_nameBuf.Copy(*pName);
	    HX_DELETE(pName);
	    m_nameBuf.Append(nameInfo.second);

            // assume we'll be able to use this name for now...
            bNeedToPrompt = false;

            DPRINTF(SYMP_FILE_UI, ("FileUi::QueryTargetNameL(): name requested = '%s'\n", dbg::CharPtr(m_nameBuf)()));

            // check for existence of file or folder having same name
	    bool bFileNameExists = m_spStore->PathExistsL(pathDest, m_nameBuf, CHXAvFile::ntFile);
            bool bFolderNameExists =  m_spStore->PathExistsL(pathDest, m_nameBuf, CHXAvFile::ntFolder);

            if( bFolderNameExists )
            {
                DPRINTF(SYMP_FILE_UI, ("FileUi::QueryTargetNameL(): folder matching name already exists\n"));

                // overwrite of folder (or creation of file having same name as existing folder) never allowed
                CHXAvMessageDialog::DoAlertInfoL(CHXAvCleanString(R_ERR_NAME_ALREADY_EXISTS)());
                bNeedToPrompt = true;
            }
            else if(flags & fWantFolder)
            {
                // looking for folder target
                if( bFileNameExists )
                {
                    // overwrite of file (or creeating of folder having same name as existing file never allowed
                    CHXAvMessageDialog::DoAlertInfoL(CHXAvCleanString(R_ERR_NAME_ALREADY_EXISTS)());
                    bNeedToPrompt = true;
                }
                else
                {
                    // user selected a unique folder name (path already checked above)
                    res = qtrUnique;
                }
            }
            else
            {
                // looking for file target
                if( bFileNameExists )
                {
                    if( flags & fDisallowFileOverwrite )
                    {
                        // overwrite of file not allowed
                        CHXAvMessageDialog::DoAlertInfoL(CHXAvCleanString(R_ERR_NAME_ALREADY_EXISTS)());
                        bNeedToPrompt = true;
                    }
                    else
                    {
                        // ask user if we should overwrite selected filename
                        NameExt newNameInfo = GetDisplayText(m_nameBuf, flags & fWantFolder);

                        DPRINTF(SYMP_FILE_UI, ("FileUi::QueryTargetNameL(): file matching name already exists\n"));
              
                        bNeedToPrompt = !CHXAvMessageDialog::DoQueryL(CHXAvCleanString(R_CONF_OVERWRITE_ITEM_FORMAT, newNameInfo.first)());
                        if( !bNeedToPrompt) 
                        {
                            // user opted to overwrite existing file
                            res = qtrOverwrite;
                        }
                    }
                }
                else
                {
                    // user selected a unique folder name
                    res = qtrUnique;
                }
            }

            if( bNeedToPrompt )
            {
                // we will prompt again; ensure that we suggest a unique name from now on
	        InitNameBufWithSuggestionL(pathDest, m_nameBuf, flags | fSuggestUniqueDefaultName);
            }
	}
	else
	{
	    // user canceled
	    m_nameBuf.Copy(KNullDesC);
	    bNeedToPrompt = false;
	}
    }

    // remember this...
    m_spLastUniqueName = m_nameBuf.AllocL();

    return res;
}

////////////////////////////////////////////////////////
// initialize name buffer with a default filename
//
// may or may not be slightly modified to ensure unique within
// destination path (depends on flags)
//
void CHXAvFileUI::InitNameBufWithSuggestionL(const TDesC& pathDest, const TDesC& fileName, TUint flags)
{
    TFileName* pNameToSuggest = AllocSuggestedFileNameL(pathDest, fileName, flags);
    AUTO_PUSH_POP_DEL(pNameToSuggest);

    // work with leaf (filename) part of path ('foo.rm')
    TPtrC ptrNode (CHXAvFile::GetNakedPathNode(*pNameToSuggest));

    m_nameBuf.Copy(ptrNode);
}

////////////////////////////////////////////////////////////
// helper: called from MoveItemHelperL
//
// prompt for a name, then (if user gives good name) do the move
//
TInt CHXAvFileUI::DoPromptMoveItemHelperL(const TDesC& pathDest, TInt idxItem)
{
    SUSPEND_REFRESH(m_spStore);

    const CHXAvFileStore::Entries& entries = m_spStore->GetEntries();
    const TEntry& entry = entries[idxItem].m_entry;

    TInt err = KErrGeneral;
    TUint flags = fSuggestUniqueDefaultName;
    if (entry.IsDir())
    {
        flags |= fWantFolder;
    }
    
    // ask for a suitable filename for the target file
    QueryTargetNameResult res = QueryTargetNameL(CHXAvCleanString(R_PROMPT_ENTER_NEW_NAME)(),
					    pathDest, 
					    entry.iName, flags);
    switch (res)
    {
        case qtrUnique:
        case qtrOverwrite:
            // got target name...
	    err = m_spStore->MoveItemL(idxItem, pathDest, 
				    m_nameBuf, res == qtrOverwrite);
            break;
        case qtrAbort:
	    // user canceled
	    err = KErrCancel;
            break;
        default:
            err = KErrGeneral;
            break;
    }

    return err;
}

////////////////////////////////////////////////////////////
// helper: called from MoveItemHelperL
//
// confirm overwrite, then (if user accepts) do the move
//
TInt CHXAvFileUI::DoOverwriteMoveItemHelperL(const TDesC& pathDest, TInt idxItem)
{
    TInt err = KErrGeneral;

    SUSPEND_REFRESH(m_spStore);

    // check for move to self
    if(m_spStore->IsSamePathL(pathDest, idxItem))
    {
        // do nothing; pretend user canceled (same effect as moving to self)
        err = KErrCancel;
    }
    else 
    {
        //
        // in case where move target path is a folder (and source is either file or folder) we
        // force the user to create a unique name; other apps like Photo Album behave this
        // way (there are some hassles with underlying API when specifying folder as move target,
        // although there are work-arounds)
        //
        bool bFolderExists = m_spStore->NameExistsInTargetPathL(pathDest, idxItem, CHXAvFile::ntFolder);
        if(bFolderExists)
        {
            CHXAvMessageDialog::DoAlertInfoL(CHXAvCleanString(R_ERR_NAME_ALREADY_EXISTS)());
            // prompt for new target name
            err = DoPromptMoveItemHelperL(pathDest, idxItem);
        }
        else
        {
            HX_ASSERT(m_spStore->NameExistsInTargetPathL(pathDest, idxItem, CHXAvFile::ntFile));

⌨️ 快捷键说明

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