chxavpathselector.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:10k
源码类别:

Symbian

开发平台:

C/C++

  1. /*============================================================================*
  2.  *
  3.  * (c) 1995-2002 RealNetworks, Inc. Patents pending. All rights reserved.
  4.  *
  5.  *============================================================================*/
  6. //
  7. // encapsulates ui logic for prompting a path from the user
  8. //
  9. //
  10. // usage:
  11. //
  12. //    CHXAvPathSelector selector;
  13. //    selector.InitL(mediaPathInfo);
  14. //
  15. //    bool bSelected = selector.PromptUserSelectPathL();
  16. //    if( bSelected )
  17. //    {
  18. //        const TDesC& fullPath = selector.GetSelectedPath();
  19. //        /* do something with the path */
  20. //    }
  21. //
  22. // Notes:
  23. //
  24. // Avkon softkey command ids that cause ExecuteLD to return 0:
  25. // 
  26. // EAknSoftkeyCancel:
  27. // EAknSoftkeyBack:
  28. // EAknSoftkeyNo:
  29. //
  30. #include "hxassert.h"
  31. #include "chxavmisc.h"
  32. #include "chxavvector.h"
  33. #include "chxavminmax.h"
  34. #include "chxavfolderpopuplist.h"
  35. #include "chxavfileviewpageinfo.h"
  36. #include "chxavcleanupstack.h"
  37. #include "chxavpathselector.h"
  38. #include "hxsym_leaveutil.h"
  39. #include "hxsym_debug.h"
  40. #include "hxsym_mmc_utils.h"
  41. #include "realplayer.hrh"
  42. ///////////////////////////////////
  43. // ctor
  44. CHXAvPathSelector::CHXAvPathSelector()
  45. : m_idxInitCurrentItem(0)
  46. , m_resIdPrompt(-1)
  47. , m_resIdSelectButtonText(-1)
  48. {
  49. }
  50. ///////////////////////////////////
  51. // dtor
  52. CHXAvPathSelector::~CHXAvPathSelector()
  53. {
  54. }
  55. ///////////////////////////////////
  56. //
  57. void CHXAvPathSelector::ResetForRootFolderPrompt(TInt idxCurrentItem)
  58. {
  59.     m_idxInitCurrentItem = idxCurrentItem;
  60.     m_spCurrentPath = 0;
  61.     m_spRootPath = 0;
  62.     
  63. }
  64. ///////////////////////////////////
  65. //
  66. void CHXAvPathSelector::InitL(const CHXAvVector<CHXAvMediaFolderInfoPtr>& mediaFolderInfo,
  67.                            TInt resIdPrompt, TInt resIdSelectButtonText)
  68. {
  69.    
  70.     m_mediaFolderInfo.Resize(0);
  71.     m_indexes.RemoveAll();
  72.     ResetForRootFolderPrompt(0);
  73.     // copy only valid media folders
  74.     for(TInt idx = 0; idx < mediaFolderInfo.Nelements(); ++idx)
  75.     {
  76.         CHXAvMediaFolderInfoPtr spInfo = mediaFolderInfo[idx];
  77.         spInfo->UpdateDriveInfo();
  78.         const CHXAvFile::DriveInfo& info = spInfo->GetDriveInfo();
  79.         if( CHXAvFile::dsAccessible == info.state || CHXAvFile::dsLocked == info.state)
  80.         {
  81.             CHXAvUtil::Append(m_mediaFolderInfo, spInfo);
  82.         }
  83.     }
  84.     HXSYM_LEAVE_IF_FALSE( m_mediaFolderInfo.Nelements() > 0 );
  85.     m_resIdPrompt = resIdPrompt;
  86.     m_resIdSelectButtonText = resIdSelectButtonText;
  87. }
  88. ////////////////////////////////////////
  89. //
  90. void CHXAvPathSelector::SetPathToChild(const TDesC& listText)
  91. {
  92.     DPRINTF(SYMP_INFO, ("CHXAvPathSelector::SetPathToChild(): set path to child '%s'n", dbg::CharPtr(listText)()));
  93.     //TPtrC folderName( avMisc::TextChunk(listText, 1) );
  94.     CHXAvFile::AppendPath(*m_spCurrentPath, listText, CHXAvFile::ntFolder);
  95. }
  96. ////////////////////////////////////////
  97. //
  98. void CHXAvPathSelector::SetPathToParent()
  99. {
  100.     DPRINTF(SYMP_INFO, ("CHXAvPathSelector::SetPathToChild(): set path to parentn"));
  101.     TPtrC ptrParent = CHXAvFile::GetParentFolder(*m_spCurrentPath);
  102.     m_spCurrentPath->SetLength(ptrParent.Length());
  103. }
  104. ////////////////////////////////////////
  105. //
  106. bool CHXAvPathSelector::CurrentFolderHasSubFoldersL()
  107. {
  108.     TInt childCount = 0;
  109.     const bool bIncludeFolders = true;
  110.     HXSYM_LEAVE_IF_ERR(
  111.         CHXAvFile::GetFolderChildCount(*m_spCurrentPath, childCount, 
  112.                                             bIncludeFolders, CHXAvFile::FilterIncludeNoFiles)
  113.                                             );
  114.     return childCount != 0;
  115. }
  116.              
  117. ////////////////////////////////////////
  118. //
  119. CHXAvPathSelector::Action CHXAvPathSelector::DoFolderPromptL()
  120. {
  121.     DPRINTF(SYMP_INFO, ("CHXAvPathSelector::DoFolderPromptL(): parent path = '%s'n", dbg::CharPtr(*m_spCurrentPath)()));
  122.     HX_ASSERT(m_spCurrentPath);
  123.     
  124.     Action action = Action(-1);
  125.     // generate list of folders under current path
  126.     CDesCArrayFlat* pFolders = CHXAvFile::AllocFolderListL(*m_spCurrentPath);
  127.     AUTO_PUSH_POP_DEL(pFolders);
  128.     HX_ASSERT(pFolders->Count() > 0);
  129.     TInt idxSelected = 0;
  130.     TInt idExitCmd = EAknSoftkeyCancel;
  131.     CHXAvFolderPopupList* pPopup = new (ELeave) CHXAvFolderPopupList(idxSelected, idExitCmd);
  132.     
  133.     // safe cleanup stack init until LD
  134.     {
  135.         AUTO_PUSH_POP(pPopup);
  136.         // make sure initial current item is valid
  137.         m_idxInitCurrentItem = min(m_idxInitCurrentItem, pFolders->Count() - 1);
  138.         // display the list to the user
  139.         pPopup->ConstructL(m_resIdPrompt, m_resIdSelectButtonText, 
  140.             pFolders, m_spCurrentPath.Ptr(), m_idxInitCurrentItem);
  141.     }
  142.     TInt res =  pPopup->ExecuteLD();
  143.     if(res)
  144.     {
  145.         HX_ASSERT(idxSelected < pFolders->Count());
  146.         SetPathToChild( (*pFolders)[idxSelected]);
  147.         if( idExitCmd == EMoveToFolder )
  148.         {
  149.             action = SELECT;
  150.         }
  151.         else
  152.         {
  153.             HX_ASSERT(EOpenFolder == idExitCmd);
  154.             
  155.             if( CurrentFolderHasSubFoldersL() )
  156.             {
  157.                 // enter folder; store current item index for possible return
  158.                 action = ENTER;
  159. m_indexes.Push((void *)idxSelected);
  160.             }
  161.             else
  162.             {
  163.                // go back; we can't enter this folder afterall (nothing to display)3 
  164.                 action = IGNORE;
  165.                 SetPathToParent();
  166.                 m_idxInitCurrentItem = idxSelected;
  167.             }
  168.         }
  169.     }
  170.     else
  171.     {
  172.         action = BACK;
  173.         if( 0 == m_spRootPath->CompareF(*m_spCurrentPath) )
  174.         {
  175.             // current path at root of media store; go back to 'no current media root' state
  176.             m_spCurrentPath = 0;
  177.             m_spRootPath = 0;
  178.         }
  179.         else
  180.         {
  181.             SetPathToParent();
  182.         }
  183.         // recall current item index for parent folder
  184. m_idxInitCurrentItem = (TInt)(m_indexes.TopOfStack());
  185. m_indexes.Pop();
  186.     }
  187.       
  188.     return action;
  189. }
  190. ////////////////////////////////////////
  191. //
  192. CHXAvPathSelector::Action CHXAvPathSelector::DoRootFolderPromptL()
  193. {
  194.     Action action = Action(-1);
  195.     TUint rootFolderCount = m_mediaFolderInfo.Nelements();
  196.     HX_ASSERT(rootFolderCount > 0); // call InitL() first
  197.     // make sure initial current item is valid
  198.     m_idxInitCurrentItem = min(TUint(m_idxInitCurrentItem), rootFolderCount - 1);
  199.     // this value will be updated if user selects something
  200.     TInt idxSelected = 0;
  201.     TInt idExitCmd = EAknSoftkeyCancel;
  202.     CHXAvFolderPopupList* pPopup = new (ELeave) CHXAvFolderPopupList(idxSelected, idExitCmd);
  203.     
  204.     // save cleanupstack init until LD
  205.     {
  206.         AUTO_PUSH_POP(pPopup);
  207.         // begin select process with root media store
  208.         pPopup->ConstructL(m_resIdPrompt, m_resIdSelectButtonText, 
  209.             m_mediaFolderInfo, m_spCurrentPath.Ptr(), m_idxInitCurrentItem);
  210.     }
  211.     TInt res = pPopup->ExecuteLD();
  212.     if(res)
  213.     {
  214.         HX_ASSERT(idxSelected < m_mediaFolderInfo.Nelements());
  215.         TInt err = InitMediaRootPathL(m_mediaFolderInfo[idxSelected]->GetRoot());
  216.         if( KErrNone == err )
  217.         {
  218.             if( idExitCmd == EMoveToFolder )
  219.             {
  220.                 // user selects this path (index)
  221.                 action = SELECT;
  222.                 m_idxInitCurrentItem = idxSelected;
  223.             }
  224.             else
  225.             {
  226.                 HX_ASSERT(EOpenFolder == idExitCmd);
  227.             
  228.                 if( CurrentFolderHasSubFoldersL() )
  229.                 {
  230.                     // enter folder
  231.                     action = ENTER;
  232.                     m_idxInitCurrentItem = 0;
  233.                     //store current item index for possible return back up to this folder
  234.     m_indexes.Push((void *)idxSelected); //XXXLCM cast
  235.                 }
  236.                 else
  237.                 {
  238.                     // go back; we can't enter this folder afterall 
  239.                     action = IGNORE;
  240.                     ResetForRootFolderPrompt(idxSelected);
  241.                 }
  242.             
  243.             }
  244.         }
  245.         else
  246.         {
  247.             // drive probably locked (or otherwise inaccessible)
  248.             action = IGNORE;
  249.             ResetForRootFolderPrompt(idxSelected);
  250.         }
  251.     }
  252.     else
  253.     {
  254.         // back from root selection will result in exit
  255.         action = BACK;
  256.         ResetForRootFolderPrompt(-1);
  257.         HX_ASSERT(m_indexes.GetSize() == 0);
  258.     }
  259.     return action;
  260. }
  261. ////////////////////////////////////////
  262. //
  263. TInt CHXAvPathSelector::InitMediaRootPathL(const TDesC& fullRootPath)
  264. {
  265.     TInt err = KErrGeneral;
  266.     // ensure drive is accessible
  267.     const CHXAvFile::DriveInfo& info = CHXAvFile::GetDriveInfo(fullRootPath);
  268.     switch(info.state)
  269.     {
  270.     case CHXAvFile::dsAccessible:
  271.         err = KErrNone;
  272.         break;
  273.     case CHXAvFile::dsLocked:
  274.         // drive is locked; prompt user for password
  275.         err = util::DoUnlockDriveUi(info.idxDrive);
  276.         break;
  277.     default:
  278.         // drice corrupt, not present, etc.
  279.         err = KErrGeneral;
  280.         break;
  281.     }
  282.     if( KErrNone == err )
  283.     {
  284.         m_spCurrentPath = new (ELeave) TFileName();
  285.         m_spCurrentPath->Copy(fullRootPath);
  286.         m_spRootPath = fullRootPath.AllocL();
  287.     }
  288.     return err;
  289. }
  290. ////////////////////////////////////////
  291. // *** main method for path selector ***
  292. //
  293. // return true if use selects a path
  294. //
  295. bool CHXAvPathSelector::PromptUserSelectPathL()
  296. {   
  297.     Action action = BACK;
  298.     for( bool bContinue = true; bContinue; /*null*/ )
  299.     {
  300.         action = IGNORE;
  301.         if( !m_spCurrentPath )
  302.         {
  303.             // we don't have a media root yet
  304.             action = DoRootFolderPromptL();
  305.             if( action == BACK )
  306.             {
  307.                 // back exits when at top level of media folder tree
  308.                 bContinue = false;
  309.             }
  310.         }
  311.         else
  312.         {
  313.             action = DoFolderPromptL();
  314.         }
  315.         if( SELECT == action )
  316.         {
  317.             // user picked a path
  318.             bContinue = false;
  319.         }
  320.     }
  321.     HX_ASSERT(action == SELECT || action == BACK);
  322.     return action == SELECT;
  323. }
  324. const TDesC& CHXAvPathSelector::GetSelectedPath() const
  325. {
  326.     if( m_spCurrentPath )
  327.     {
  328.         return *m_spCurrentPath;
  329.     }
  330.     return KNullDesC;
  331. }