chxavplayview.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:44k
源码类别:

Symbian

开发平台:

Visual C++

  1. /************************************************************************
  2.  * chxavplayview.cpp
  3.  * -----------------
  4.  *
  5.  * Synopsis:
  6.  * Contains the implementation of the CHXAvPlayView class.  This class 
  7.  * will control actual playback once a file/url has been selected for play.
  8.  *
  9.  * Target:
  10.  * Symbian OS
  11.  *
  12.  *
  13.  * (c) 1995-2003 RealNetworks, Inc. Patents pending. All rights reserved.
  14.  *
  15.  ************************************************************************/
  16. // Symbian includes...
  17. #include <coeccntx.h>
  18. #include <eikbtgpc.h>
  19. #include <eikmenub.h>
  20. #include <eikmenup.h>
  21. #include <eikfutil.h>
  22. #include <eikenv.h>
  23. #include <eikappui.h>
  24. #include <eikapp.h>
  25. #include <eikdoc.h>
  26. #include <avkon.hrh>
  27. #include <avkon.rsg>
  28. #include <eikmenup.h>
  29. #include <eikon.hrh>
  30. #include <aknviewappui.h>
  31. #include <apchangeobserver.h>
  32. // Helix includes...
  33. #include "hxassert.h"
  34. #include "ihxpckts.h"
  35. #include "hxstring.h"
  36. #include "hxurl.h"
  37. // Includes for this project...
  38. #include "hxsym_debug.h"
  39. #include "realplayer.rsg"
  40. #include "realplayer.mbg"
  41. #include "chxavplayer.h"
  42. #include "chxavplayerui.h"
  43. #include "chxavfilestore.h"
  44. #include "chxavfileui.h"
  45. #include "chxavclipinfolist.h"
  46. #include "chxavconfignames.h"
  47. #include "chxavinfolistpopup.h"
  48. #include "chxavcleanupstack.h"
  49. #include "chxavnavipanecontrol.h"
  50. #include "chxavplaylistnavicontrol.h"
  51. #include "chxavplayviewwindow.h"
  52. #include "chxavplayerstate.h"
  53. #include "chxavviewbase.h"
  54. #include "chxavplayview.h"
  55. #include "hxapihelp.h"
  56. #include "hxsym_leaveutil.h"
  57. #include "chxavcleanstring.h"
  58. #include "realplayer.hrh"
  59. #include "chxavnetconnectui.h"
  60. #include "chxavplayerr.h"
  61. namespace
  62. {
  63.     // how long to show non-default navi control after user action
  64.     const TUint k_msShowTempNavi = 1000;
  65.     
  66.     // how often to reset inactivity timer so backlight stays on during a video presentation
  67.     const TUint k_msBacklightInterval = 5000;
  68. }
  69. /* 
  70.  * CHXAvPlayView
  71.  * -------------
  72.  * Constructor.
  73.  *
  74.  */
  75. CHXAvPlayView::CHXAvPlayView(TInt viewIndex, CHXAvPlayerUI *playerUI)
  76. : CHXAvViewBase(viewIndex, playerUI)
  77. , m_bViewPlaylistMode(false)
  78. , m_bEnsureResumeOnExitPlaylistMode(false)
  79. , m_lastPhoneState(ESACallNone)
  80. , m_msSeekStep(0)
  81. , m_bShutDownOnViewDeactivate(true)
  82. {
  83. }
  84. /*
  85.  * ~CHXAvPlayView
  86.  * --------------
  87.  * Destructor.
  88.  *
  89.  */
  90. CHXAvPlayView::~CHXAvPlayView()
  91. {
  92.     // player may not be shutdown yet (e.g., exiting from 'child' view)
  93.     HX_ASSERT(m_player);
  94.     if( m_player )
  95.     {
  96.         m_player->ShutDown();
  97.         m_player->GetPlayerState().RemoveObserver(this);
  98.     }
  99. }
  100. /* 
  101.  * ConstructL
  102.  * ----------
  103.  * Construction of elements.
  104.  *
  105.  */
  106. void CHXAvPlayView::ConstructL()
  107. {
  108.     BaseConstructL(R_AVP_PLAYER_VIEW_INFO);
  109.     // timer for hiding volume control after user interaction delay 
  110.     const CHXAvCommand& cmdHide = 
  111. MakeCommand(this, &CHXAvPlayView::HideTempNaviControlNowL);
  112.     m_cbTempNaviDisplay.ConstructL(cmdHide);
  113.     // timer for periodically resetting backlight so it stays on while playing
  114.     const CHXAvCommand& cmdBacklight = 
  115. MakeCommand(this, &CHXAvPlayView::OnBacklightTimer);
  116.     m_cbBacklight.ConstructL(cmdBacklight);
  117.     // see SetEndSeekCallback()
  118.     const CHXAvCommand& cmdEndSeek = MakeCommand(this, &CHXAvPlayView::OnEndSeekCallback);
  119.     m_cbEndSeek.ConstructL(cmdEndSeek);
  120.    
  121.     // watch for phone call events
  122.     const CHXAvCommand& cmdOnPhoneEvent = 
  123.         MakeCommand(this, &CHXAvPlayView::OnPhoneEvent);
  124.     m_saWatcher.ConstructL(KUidCurrentCall, CActive::EPriorityHigh);
  125.     m_lastPhoneState = m_saWatcher.GetSa().GetState(KUidCurrentCall);
  126.     DPRINTF(SYMP_INFO, ("CHXAvPlayView::ContructL(): current phone state = %ldn", m_lastPhoneState));
  127.     m_saWatcher.SetEventActionL(cmdOnPhoneEvent);
  128.     m_saWatcher.StartWatching();
  129.     // command to execute if user cancels while connecting
  130.     const CHXAvCommand& cmdCancelConnect =
  131.         MakeCommand(this, &CHXAvPlayView::OnUserCancelConnect);
  132.     m_spNetConnectUi = new (ELeave) CHXAvNetConnectUI();
  133.     m_spNetConnectUi->ConstructL(m_playerUI->GetClientEngineManager()->GetEngine(), cmdCancelConnect);
  134.     m_player = new (ELeave) CHXAvPlayer();
  135.     m_player->ConstructL(m_playerUI->GetClientEngineManager(), m_spNetConnectUi);
  136. }
  137. ////////////////////////////////////////
  138. //
  139. void
  140. CHXAvPlayView::HandleVolumeCommand(TInt idCmd)
  141. {
  142.     switch(idCmd)
  143.     {
  144.     case EVolUp:
  145.         m_player->StepVolume(1);
  146.         if( m_player->IsMuted())
  147.         {
  148.             // unmute 
  149.             m_player->Mute(false);  
  150.         }
  151.         
  152. break;
  153.     case EVolDown:
  154.         m_player->StepVolume(-1);
  155.         if( m_player->GetVolume() == 0 )
  156.         {
  157.             // ensure mute
  158.             m_player->Mute(true);
  159.         }
  160.         else
  161.         {
  162.             // ensure not muted after user volume change to (still) positive volume level
  163.             m_player->Mute(false);
  164.         }
  165.         break;
  166.     default:
  167.         HX_ASSERT(false);
  168. break;
  169.     }
  170. }
  171. ////////////////////////////////////////////////
  172. //
  173. void CHXAvPlayView::DoExitPlaylistModeL(bool bPlayCurrent)
  174. {
  175.     m_bViewPlaylistMode = false;
  176.     DeactivateNaviPlaylistControl();
  177.     if(bPlayCurrent && m_player->CanResume() )
  178.     {
  179.         m_player->PlayCurrent();
  180.     }
  181.     else
  182.     {
  183.         UpdateSoftkeyMenuStateL();
  184.     }
  185. }
  186. ////////////////////////////////////////////////
  187. // activate navi playlist control with auto-hide timer ON so
  188. // it hides after a brief display
  189. void CHXAvPlayView::ShowTempPlaylistControlL()
  190. {
  191.     if(!m_bViewPlaylistMode)
  192.     {
  193.         ActivateNaviPlaylistControlL(k_msShowTempNavi);
  194.         m_naviPane->PushL(*m_spNaviPlaylistDecorator);
  195.     }
  196. }
  197. ////////////////////////////////////////////////
  198. //
  199. // check for playlist-related commands
  200. //
  201. // return 'false' if we should continuing handling command
  202. //
  203. bool CHXAvPlayView::TryHandlePlaylistCommandL(TInt command)
  204. {
  205.     bool bWasHandled = true;
  206.     if(m_player->IsPlaylistLoaded() && m_player->GetPlaylistItemCount() > 1 )
  207.     {
  208.         switch(command)
  209.         {
  210.             case EShowPlaylistInfo:
  211.                 HX_ASSERT(!m_bViewPlaylistMode);
  212.                 ShowTempPlaylistControlL();
  213.                 break;
  214.             case EEnterPlaylistMode:
  215.                 //HX_ASSERT(!m_bViewPlaylistMode);
  216.                 if( !m_bViewPlaylistMode )
  217.                 {
  218.                     m_bEnsureResumeOnExitPlaylistMode = m_player->IsPlaying();
  219.                     m_bViewPlaylistMode = true;
  220.                     UpdateSoftkeyMenuStateL();
  221.                     
  222.                     // activate navi playlist control with auto-hide timer OFF
  223.                     ActivateNaviPlaylistControlL(0);
  224.                     m_naviPane->PushL(*m_spNaviPlaylistDecorator);
  225.                 }
  226.                 break;
  227.             case EExitPlaylistMode:
  228.                 HX_ASSERT(m_bViewPlaylistMode);
  229.                 if( m_bViewPlaylistMode)
  230.                 {
  231.                     DoExitPlaylistModeL(m_bEnsureResumeOnExitPlaylistMode);
  232.                     
  233.                 }
  234.                 break;
  235.             case ENextClip:
  236.                 m_player->AdvancePlaylist(CHXAvPlayer::advanceNext | CHXAvPlayer::advanceLoop);
  237.                 ShowTempPlaylistControlL();
  238.                 if(!m_bViewPlaylistMode && m_player->CanResume())
  239.                 {
  240.                     m_player->PlayCurrent();
  241.                 }
  242.         break;
  243.             case EPrevClip:
  244.                 m_player->AdvancePlaylist(CHXAvPlayer::advancePrev | CHXAvPlayer::advanceLoop);
  245.                 ShowTempPlaylistControlL();
  246.                 if(!m_bViewPlaylistMode && m_player->CanResume())
  247.                 {
  248.                     m_player->PlayCurrent();
  249.                 }
  250.         break;
  251.             case EShowDefaultMenu:
  252.                 DoExitPlaylistModeL(false);
  253.                 HandleShowPopupL();
  254.                 break;
  255.             default:
  256.                 bWasHandled = false;
  257.                 break;
  258.         }
  259.     }
  260.     else
  261.     {
  262.         switch(command)
  263.         {
  264.             // ignore these when playlist not loaded
  265.             case EShowPlaylistInfo:
  266.             case EEnterPlaylistMode:
  267.             case EExitPlaylistMode:
  268.             case ENextClip:
  269.             case EPrevClip:
  270.                 break;
  271.             default:
  272.                 bWasHandled = false;
  273.                 break;
  274.         }
  275.     }
  276.  
  277.     return bWasHandled;
  278. }
  279. void CHXAvPlayView::DoTogglePlayState()
  280. {
  281.     if (m_player->IsPaused())
  282.     {
  283. m_player->Resume();
  284.     }
  285.     else if (m_player->IsStopped())
  286.     {
  287. m_player->PlayCurrent();
  288.     }
  289.     else
  290.     {
  291. m_player->Pause();
  292.     }
  293. }
  294. /*
  295.  * HandleSeekKeyCommand
  296.  * --------------------
  297.  * User pressed seek forward/back key.
  298.  *
  299.  */
  300. void 
  301. CHXAvPlayView::HandleSeekKeyCommand(bool bForward)
  302. {
  303.     DPRINTF(SYMP_INFO, ("CHXAvPlayView::HandleSeekKeyCommand('%s')n", dbg::Bool(bForward)));
  304.     if (m_player->IsSeeking())
  305.     {
  306. HX_ASSERT(!m_player->GetClipInfo().IsLive());
  307. UINT32 newTime = m_player->GetClipTime();
  308.  
  309. m_msSeekStep = GetNextSeekStep(m_msSeekStep);
  310. if( bForward )
  311. {
  312.     // ok if we go past duration -- player handles it by moving to next clip (or stopping)
  313.     newTime += m_msSeekStep;
  314. }
  315. else
  316. {
  317.     newTime = m_player->GetClipTime();
  318.     if( newTime > m_msSeekStep )
  319.     {
  320. newTime -= m_msSeekStep;
  321.     }
  322.     else
  323.     {
  324. newTime = 0;
  325.     }
  326. }
  327. m_player->SetSeekPoint(newTime);
  328.     }
  329. }
  330. ////////////////////////////////////////
  331. //
  332. void CHXAvPlayView::DoViewClipInfoL()
  333. {
  334.     CHXAvClipInfoList* pList = new (ELeave) CHXAvClipInfoList();
  335.     AUTO_PUSH_POP(pList);
  336.     pList->ConstructL();
  337.     pList->BuildClipInfoL(m_player);
  338.     CHXAvInfoListPopup* pPopup = new (ELeave) CHXAvInfoListPopup();
  339.     // save cleanupstack init until LD
  340.     {
  341.         AUTO_PUSH_POP(pPopup);
  342.         pPopup->ConstructL( CHXAvCleanString(R_AVP_CLIPINF_TITLE)(), pList);
  343.     }
  344.     pPopup->ExecuteLD();
  345. }
  346. ////////////////////////////////////////
  347. //
  348. void
  349. CHXAvPlayView::DoSaveL()
  350. {
  351.     //
  352.     // perform action based on type of URL:
  353.     //
  354.     // local ram url  -> copy ram file
  355.     // local rm url   -> copy file
  356.     // network url    -> create link
  357.     //
  358.     CHXString strSource;
  359.     bool bUserCancelled = false;
  360.     bool bSavingPlaylist = false;
  361.     // save playlist or current clip that is playing?
  362.     if( m_player->IsPlaylistLoaded() &&  m_player->GetPlaylistItemCount() > 1)
  363.     {
  364.         // query user: playlist or current clip
  365.         TInt idxSel = 0;
  366.         CAknListQueryDialog* pDlg = new (ELeave) CAknListQueryDialog(&idxSel);
  367.         TInt ret = pDlg->ExecuteLD(R_AVP_SELECT_SAVE_SOURCE_DLG);
  368.         if(ret != 0)
  369.         {
  370.             //HX_ASSERT((ret == EAknSoftkeyOk) || (ret == EAknSoftkeyYes));
  371.             bool bCopyRam = (idxSel == 0);
  372.             if( bCopyRam )
  373.             {
  374.                 // save playlist (ram)
  375.                 bSavingPlaylist = true;
  376.                 strSource = m_player->GetMainURL();
  377.             }
  378.         }
  379.         else
  380.         {
  381.             bUserCancelled = true;
  382.         }
  383.     }
  384.     if(!bUserCancelled)
  385.     {
  386.    
  387.         const CHXAvVector<CHXAvMediaFolderInfoPtr>& storeInfo = m_playerUI->GetMediaStoreInfoL();
  388.         // XXXLCM automatic smart pointer not cleanup stack safe
  389.         // set an arbitrary 'current path' for the file store
  390.         CHXAvFileStorePtr spStore = new (ELeave) CHXAvFileStore();
  391.         spStore->ConstructL(storeInfo[0]->GetRoot());
  392.         CHXAvFileUIPtr spFileUi = new (ELeave) CHXAvFileUI();
  393.         spFileUi->ConstructL(m_playerUI, spStore);
  394.         if(strSource.IsEmpty())
  395.         {
  396.             // set source file to current URL
  397.             strSource = m_player->GetPlayURL(); 
  398.         }
  399.         HX_ASSERT(!strSource.IsEmpty());
  400.         CHXAvCleanString urlText(strSource);
  401.         
  402.         if( CHXAvUtil::IsLocal(urlText()))
  403.         {
  404.             //
  405.             // copy file
  406.             //
  407.             // use source filename for default name
  408.     // url may be escaped; get unescaped path-only portion 
  409.             // (e.g., realnetworksrootfoo.rm)
  410.     HBufC* pSrcPath = CHXAvUtil::AllocStdPathFromPlayerUrlL(urlText()); 
  411.     AUTO_PUSH_POP_DEL(pSrcPath);
  412.             bool bIsValidLocalPath = CHXAvFile::PathExists(*pSrcPath);
  413.             HX_ASSERT(bIsValidLocalPath); // menu item should be hidden to prevent this
  414.             if( bIsValidLocalPath )
  415.             {
  416.                 if( bSavingPlaylist )
  417.                 {
  418.             spFileUi->DoSavePlaylistL(*pSrcPath, KNullDesC);
  419.                 }
  420.                 else
  421.                 {
  422.                 
  423.                     spFileUi->DoSaveClipL(*pSrcPath, KNullDesC);
  424.                 }
  425.             }
  426.         }
  427.         else
  428.         {
  429.             //
  430.             // create link
  431.             //
  432.             // set default link name to clip display title
  433.             HBufC* pTitleText = CHXAvMisc::AllocTitleL(m_player);
  434.             if(pTitleText)
  435.             {
  436.                 AUTO_PUSH_POP_DEL(pTitleText);
  437.                 spFileUi->DoCreateLinkL(strSource, *pTitleText);
  438.             }
  439.             else
  440.             {
  441.                 spFileUi->DoCreateLinkL(strSource, KNullDesC);
  442.             }
  443.     
  444.         }
  445.     }
  446. }
  447. ////////////////////////////////////////////////         
  448. // we want to delay a bit (i.e., after the last seek key press)
  449. // before telling  the player to end seeking (and resume play at
  450. // new point);
  451. //
  452. // this allows for a user entering a series of quick key presses and
  453. // avoids excessive start and end seek commands
  454. //
  455. void CHXAvPlayView::SetEndSeekCallback(bool bEnable)
  456. {
  457.     if(bEnable && m_player->IsSeeking())
  458.     {
  459.         const TUint32 k_msEndSeekDelay = 400;
  460. m_cbEndSeek.Set(k_msEndSeekDelay);
  461.     }
  462.     else
  463.     {
  464. m_cbEndSeek.Stop();
  465.     }
  466. }
  467. ////////////////////////////////////////////////         
  468. // see SetEndSeekCallback()
  469. void CHXAvPlayView::OnEndSeekCallback()
  470. {
  471.     // only call end seek if we are still in seek mode; it is possible that 
  472.     // state changed (e.g., stop requested) since we set the end seek callback
  473.     if( m_player->IsSeeking() )
  474.     {
  475.         m_player->EndSeek();
  476.     }
  477. }
  478. /*
  479.  * EnterSeekMode
  480.  * -------------
  481.  * Start and end seek.
  482.  *
  483.  */
  484. void 
  485. CHXAvPlayView::EnterSeekMode(bool bEnter)
  486. {
  487.     if (bEnter)
  488.     {
  489.         m_msSeekStep = 0; 
  490.         SetEndSeekCallback(false);
  491.         // player may be seeking in case where end seek callback was pending
  492.         if (!m_player->IsSeeking() && m_player->CanSeek())
  493.         {
  494.     // on-demand clip is seek-able
  495.     m_player->StartSeek();
  496.         }
  497.     }
  498.     else
  499.     {
  500.         // don't do seek right away (see SetEndSeekCalback)
  501.         SetEndSeekCallback(true);
  502.     }
  503.     
  504. }
  505. /*
  506.  * GetNextSeekStep
  507.  * ---------------
  508.  * Seek in larger steps as a seek key is held down, up to an absolute max step.
  509.  *
  510.  */
  511. UINT32   
  512. CHXAvPlayView::GetNextSeekStep(UINT32 msSeekStep)
  513. {
  514.     const UINT32 ONE_SECOND_MS      = 1000;
  515.     const UINT32 BIG_SEEK_DIV_MS    = 20;  // 5 % per step
  516.     if (m_player != NULL)
  517.     {
  518. UINT32 duration = m_player->GetClipDuration();
  519. UINT32 msMaxStep = duration / BIG_SEEK_DIV_MS;
  520. if( msSeekStep != 0 )
  521. {
  522.     // double current step
  523.     msSeekStep *= 2;
  524. }
  525. else
  526. {
  527.     // init first step
  528.     msSeekStep = ONE_SECOND_MS;
  529. }
  530. // confine value to our limits
  531. msSeekStep = max(ONE_SECOND_MS, min(msSeekStep, msMaxStep));
  532.     }
  533.     DPRINTF(SYMP_INFO, ("CHXAvPlayView::GetNextSeekStep(): next step = %lu ms", msSeekStep));
  534.     return msSeekStep;
  535. }
  536. // helper
  537. void CHXAvPlayView::HandleShowPopupL()
  538. {
  539.     // pop up left options menu
  540.     //
  541.     // showing a popup menu prevents us from getting the key up event; just in case,
  542.     // ensure we deactivate the playlist control
  543.     //
  544.     if( m_player->IsPlaying() )
  545.     {
  546.         // pause or stop
  547.         DoTogglePlayState();
  548.     }
  549.     if(m_player->IsPaused())
  550.     {
  551.         ShowPopupMenuL(R_AVP_PAUSE_MENU_BAR);
  552.     }
  553.     else if (m_player->IsStopped()) 
  554.     {
  555.         ShowPopupMenuL(R_AVP_STOPPED_MENU_BAR);
  556.     }
  557.     else if(m_player->GetClipInfo().IsLive())
  558.     {
  559.         ShowPopupMenuL(R_AVP_LIVE_PLAY_MENU_BAR);
  560.     }
  561. }
  562. /*
  563.  * HandleCommandL
  564.  * --------------
  565.  * Handle commands passed to us by our control and directly.
  566.  *
  567.  */
  568. void CHXAvPlayView::HandleCommandL(TInt command)
  569. {
  570.     bool bWasHandled = TryHandlePlaylistCommandL(command);
  571.     if( !bWasHandled )
  572.     {
  573.         switch(command)
  574.         {
  575.         case EPlayPause:  
  576.             HX_ASSERT(m_player->CanPause() || m_player->CanResume());
  577.             DoTogglePlayState();
  578.     break;
  579.         case EStop:
  580.     m_player->Stop();
  581.     break;
  582.         case EBeginSeek:
  583.             HX_ASSERT(m_player->CanSeek());
  584.     EnterSeekMode(true);
  585.     break;
  586.         case EEndSeek:
  587.     EnterSeekMode(false);
  588.     break;
  589.         case ESeekForward:
  590.     HandleSeekKeyCommand(true);
  591.     break;
  592.         case ESeekBack:
  593.     HandleSeekKeyCommand(false);
  594.     break;
  595.         case EVolUp:
  596.         case EVolDown:
  597.             HandleVolumeCommand(command);
  598.             break;
  599.         case EMute:
  600.             m_player->Mute(!m_player->IsMuted());
  601.             break;
  602.         case ESaveToFolder:
  603.             DoSaveL();
  604.             break;
  605.         case EClipInfoDialog:
  606.             DoViewClipInfoL();
  607.             break;
  608.         case EShowDefaultMenu: 
  609.             HandleShowPopupL();
  610.             break;
  611.         /*case EToggleFullScreen:
  612.             m_wpStatusPane->MakeVisible(!m_wpStatusPane->IsVisible());
  613.     break;*/
  614.         default:
  615.             CHXAvViewBase::HandleCommandL(command);
  616.     break;
  617.         }
  618.     }
  619. }
  620. /*
  621.  * UpdateViewStateL
  622.  * ----------------
  623.  * ensure that view is in sync with player state
  624.  *
  625.  */
  626. void CHXAvPlayView::UpdateViewStateL()
  627. {
  628.     UpdateSoftkeyMenuStateL();
  629.     UpdateTitleL();
  630.     UpdateContextPaneL();
  631.     UpdateNaviVolumeControlL();
  632.     UpdateNaviPlaylistControlL();
  633.     UpdateNaviDefaultControlL();
  634. }   
  635. ////////////////////////////////////////////////////////////
  636. // set file to launch on next view activation
  637. void CHXAvPlayView::SetViewActivateClipL(const TDesC& file)
  638. {
  639.     m_spViewActivateClip = file.AllocL();
  640. }
  641. /*
  642.  * CreateViewWindowForActivatingViewL
  643.  * -------------------
  644.  * Construct view window needed for active view
  645.  *
  646.  */
  647. CCoeControl* CHXAvPlayView::CreateViewWindowForActivatingViewL()
  648. {
  649.     DPRINTF(SYMP_INFO, ("CHXAvPlayView::CreateViewWindowForActivatingViewL()n"));
  650.     if(!m_spWindow)
  651.     {
  652.         m_spWindow = new (ELeave) CHXAvPlayViewWindow();
  653.         m_spWindow->ConstructL(m_playerUI, this, ClientRect());
  654.     }
  655.     return m_spWindow.raw_ptr();
  656. }
  657. /*
  658.  * FinishViewActivateL
  659.  * -------------------
  660.  * View window is active and on top of control stack. Now
  661.  * is a good time to allocate additional resources needed
  662.  * for the active view.
  663.  *
  664.  */
  665. void CHXAvPlayView::FinishViewActivateL()
  666. {
  667.     DPRINTF(SYMP_INFO, ("CHXAvPlayView::FinishViewActivateL()n"));
  668.     HX_ASSERT(m_spWindow);
  669.     CHXAvPresentationWindow* pRenderWin = m_spWindow->GetPresentationWindow();
  670.     // shut down player by default when view deactivates
  671.     m_bShutDownOnViewDeactivate = true;
  672.     if( m_player->IsShutDown() )
  673.     {
  674.         m_player->InitPlayerL(pRenderWin);
  675.     }
  676.     m_player->GetPlayerState().AddObserver(m_spNetConnectUi.raw_ptr());
  677.     m_player->GetPlayerState().AddObserver(this);
  678. }
  679. /*
  680.  * FinishViewDeactivateL
  681.  * ---------------------
  682.  * Destroy resources not needed when view is inactive
  683.  *
  684.  */
  685. void CHXAvPlayView::FinishViewDeactivateL()
  686. {
  687.     DPRINTF(SYMP_INFO, ("CHXAvPlayView::FinishViewDeactivateL()n"));
  688.      // this ensures that next view gets a restored status pane
  689.     m_spNaviVolDecorator = 0;
  690.     m_spNaviDefaultDecorator = 0;
  691.     m_spNaviPlaylistDecorator = 0;
  692.     // ensure we don't get observation messages (and try to do ui stuff in response) when inactive
  693.     m_player->GetPlayerState().RemoveObserver(this);
  694.     m_player->GetPlayerState().RemoveObserver(m_spNetConnectUi.raw_ptr());
  695.     if( m_bShutDownOnViewDeactivate )
  696.     {
  697.         // shutting down player saves some resources and ensures no cpu is used for static rendering
  698.         m_player->ShutDown();
  699.         // only destroy window if player is shutdown (otherwise player site still needs presentation window)
  700.         m_spWindow = 0;
  701.     }
  702.     
  703.     m_bViewPlaylistMode = false;
  704.     m_bEnsureResumeOnExitPlaylistMode = false;
  705.    
  706.     // in case we were full screen
  707.     //   m_wpStatusPane->MakeVisible(ETrue);
  708. }
  709. /* 
  710.  * OnPlayInitiate
  711.  * --------------
  712.  * CHXAvPlayerStateObserver
  713.  *
  714.  */
  715. void 
  716. CHXAvPlayView::OnPlayInitiate(const char *url)
  717. {
  718.     DPRINTF(SYMP_INFO, ("CHXAvPlayView::OnPlayInitiate(): '%s'n", (const char*)url));
  719.     UpdateContextPaneL();
  720.     UpdateSoftkeyMenuStateL();
  721.     UpdateTitleL();
  722. }
  723. /*
  724.  * OnMute
  725.  * ------
  726.  * CHXAvPlayerStateObserver, mute.
  727.  *
  728.  */
  729. void 
  730. CHXAvPlayView::OnMute(bool bMute)
  731. {
  732.     if(bMute)
  733.     {
  734.         //
  735.         // mute state is indicated on the default navi control - hide temp
  736.         // navi control so user can see it (vol control does not show mute)
  737.         //
  738.         HideTempNaviControlNowL();
  739.     }
  740. }
  741. void
  742. CHXAvPlayView::OnBacklightTimer()
  743. {
  744.     User::ResetInactivityTime();
  745. }
  746. /*
  747.  * OnResume
  748.  * --------
  749.  * CHXAvPlayerStateObserver, started playing again.
  750.  *
  751.  */
  752. void 
  753. CHXAvPlayView::OnResume()
  754. {
  755.     UpdateContextPaneL();
  756.     UpdateSoftkeyMenuStateL();
  757.     InitBacklightState();
  758. }
  759. /*
  760.  * OnStop
  761.  * ------
  762.  * CHXAvPlayerStateObserver, stopped.
  763.  *
  764.  */
  765. void 
  766. CHXAvPlayView::OnStop()
  767. {
  768.     UpdateContextPaneL();
  769.     UpdateSoftkeyMenuStateL();
  770.     m_cbBacklight.Stop();
  771. }
  772. /*
  773.  * OnPause
  774.  * -------
  775.  * CHXAvPlayerStateObserver, paused.
  776.  *
  777.  */
  778. void 
  779. CHXAvPlayView::OnPause()
  780. {
  781.     UpdateContextPaneL();
  782.     UpdateSoftkeyMenuStateL();
  783.     m_cbBacklight.Stop();
  784. }
  785. void 
  786. CHXAvPlayView::OnAdvancePlaylist()
  787. {
  788.     UpdateTitleL();
  789.     UpdateSoftkeyMenuStateL();
  790. }
  791. /*
  792.  * OnBeginBuffering
  793.  * ----------------
  794.  *
  795.  */
  796. void 
  797. CHXAvPlayView::OnBeginBuffering(bool /*bIsBegin*/)
  798. {
  799.     // update everything when entering/exiting buffering state
  800.     UpdateContextPaneL();
  801.     UpdateSoftkeyMenuStateL();  
  802. }
  803. /*
  804.  * OnBeginSeek
  805.  * -----------
  806.  * CHXAvPlayerStateObserver
  807.  *
  808.  */
  809. void 
  810. CHXAvPlayView::OnBeginSeek()
  811. {
  812.     UpdateSoftkeyMenuStateL();
  813.     // this event only happens from user interaction; override volume control
  814.     HideTempNaviControlNowL();
  815. }
  816. /*
  817.  * OnLoadSession
  818.  * -------------
  819.  * Change the softkeys to show a stop button now that we are actually playing back.
  820.  *
  821.  */
  822. void 
  823. CHXAvPlayView::OnLoadSession(IHXRequest *request)
  824. {
  825.     CHXAvURLListPtr spRecentClips = m_playerUI->GetRecentClipsList();
  826.     // Add this url to the recent clip list...
  827.     HX_ASSERT(spRecentClips);
  828.     if (spRecentClips)
  829.     {
  830.         HBufC* pTitleText = CHXAvMisc::AllocTitleL(m_player);
  831.         if( pTitleText )
  832.         {
  833.             AUTO_PUSH_POP_DEL(pTitleText);
  834.             CHXString strUrl = m_player->GetPlayURL();
  835.             CHXString strTitle = CHXAvStringUtils::DescToString(*pTitleText);
  836.     CHXAvURLInfo* pInfo = new (ELeave) CHXAvURLInfo(strUrl, strTitle); //XXXLCM leave
  837.     spRecentClips->AddHead(pInfo);
  838.         }
  839.     }
  840.     UpdateContextPaneL();
  841.     UpdateSoftkeyMenuStateL();
  842.     UpdateTitleL();
  843.     // this is the first time we can know this is a video presentation
  844.     InitBacklightState();
  845.     
  846. }
  847. void CHXAvPlayView::InitBacklightState()
  848. {
  849.     if(m_player->GetClipInfo().IsVideoPresentation())
  850.     {
  851.         // set repeating callback for keeping backlight on
  852.         m_cbBacklight.Set(k_msBacklightInterval, CHXAvCallback::REPEAT); 
  853.     }
  854. }
  855. /*
  856.  * OnVolume
  857.  * --------
  858.  * CHXAvPlayerStateObserver, volume changing.
  859.  *
  860.  */
  861. void 
  862. CHXAvPlayView::OnVolume(unsigned int /*percentVol*/)
  863. {
  864.     //if( bIsUserCommand )
  865.     //{
  866.     if(!m_bViewPlaylistMode )
  867.     {
  868.         ActivateNaviVolumeControlL(k_msShowTempNavi);
  869.         UpdateNaviVolumeControlL();
  870.         m_naviPane->PushL(*m_spNaviVolDecorator);
  871.     }
  872. }
  873. void
  874. CHXAvPlayView::OnNetConnect()
  875. {
  876.     UpdateSoftkeyMenuStateL();
  877. }
  878. /*
  879.  * UpdateSoftkeyMenuStateL
  880.  * ----------------------
  881.  * Update the softeky and menu bar based on the player state.
  882.  *
  883.  */
  884. void 
  885. CHXAvPlayView::UpdateSoftkeyMenuStateL()
  886. {
  887.     CEikMenuBar* pMenuBar = MenuBar();
  888.     HX_ASSERT(pMenuBar);
  889.     if(!pMenuBar)
  890.     {
  891. return;
  892.     }
  893.     const CHXAvPlayerState& state = m_player->GetPlayerState();
  894.     CHXAvPlayerState::State playState = state.GetState();
  895.     
  896.     TInt idMenuBar = -1;
  897.     TInt idCba = -1;
  898.     if( m_bViewPlaylistMode )
  899.     {
  900.         idCba = R_AVP_PLAYER_VIEW_PLAYLIST_MODE_CBA;
  901.         idMenuBar = R_AVP_EMPTY_MENU_BAR;
  902.     }
  903.     else
  904.     {
  905.         switch (playState)
  906.         {
  907.         case CHXAvPlayerState::Stopped:
  908.          idCba = R_AVP_PLAYER_VIEW_IDLE_CBA;
  909.     idMenuBar = R_AVP_STOPPED_MENU_BAR;
  910.     break;
  911.         case CHXAvPlayerState::Paused:
  912.     idCba = R_AVP_PLAYER_VIEW_PAUSE_CBA;
  913.     idMenuBar = R_AVP_PAUSE_MENU_BAR;
  914.     break;
  915.         case CHXAvPlayerState::Initiating:
  916.             idCba = R_AVP_PLAYER_VIEW_CONNECTING_CBA;
  917.             idMenuBar = R_AVP_EMPTY_MENU_BAR;
  918.             break;
  919.         case CHXAvPlayerState::Seeking:
  920.             idCba = R_AVKON_SOFTKEYS_EMPTY;
  921.             idMenuBar = R_AVP_EMPTY_MENU_BAR;
  922.             break;
  923.         case CHXAvPlayerState::Connecting:
  924.             idCba = R_AVP_PLAYER_VIEW_CONNECTING_CBA;
  925.             idMenuBar = R_AVP_EMPTY_MENU_BAR;
  926.             break;
  927.         case CHXAvPlayerState::Playing:
  928.     if (m_player->GetClipInfo().IsLive())
  929.     {
  930. idCba = R_AVP_PLAYER_VIEW_LIVE_PLAY_CBA;
  931. idMenuBar = R_AVP_LIVE_PLAY_MENU_BAR;
  932.     }
  933.     else
  934.     {
  935. idCba = R_AVP_PLAYER_VIEW_PLAY_CBA;
  936. idMenuBar = R_AVP_EMPTY_MENU_BAR;
  937.     }
  938.     break;
  939.         default:
  940.     break;
  941.         }
  942.     }
  943.     if (idMenuBar != -1 && idCba != -1)
  944.     {
  945. Cba()->SetCommandSetL(idCba);
  946. pMenuBar->SetMenuTitleResourceId(idMenuBar);
  947. if (!m_playerUI->IsDisplayingMenuOrDialog())
  948. {
  949.     Cba()->DrawNow();
  950. }
  951.     }
  952. }
  953. //////////////////////////////
  954. // update volume control (if active) to match current player volume state
  955. // 
  956. void CHXAvPlayView::UpdateNaviVolumeControlL()
  957. {
  958.     if( m_spNaviVolDecorator)
  959.     {
  960. CAknVolumeControl* volControl = static_cast<CAknVolumeControl*>(
  961.     m_spNaviVolDecorator->DecoratedControl());
  962.         TUint vol = m_player->GetVolume();
  963.         HX_ASSERT( vol >= 0 && vol <= 100);
  964.         // scale volume to vol (0 - 100) to control setting scale (1 - 10)
  965.         TUint scaleVol = ( 10 * (vol + 9) ) / 100;
  966.         if( scaleVol == 0 )
  967.         {
  968.             scaleVol = 1;
  969.         }
  970.         HX_ASSERT(scaleVol >=1 && scaleVol <= 10);
  971. volControl->SetValue(scaleVol);
  972.     }
  973. }
  974. ////////////////////////////////////
  975. //
  976. void CHXAvPlayView::UpdateNaviPlaylistControlL()
  977. {
  978.     // nothing
  979. }
  980. ////////////////////////////////////
  981. //
  982. void CHXAvPlayView::DeactivateNaviVolumeControl()
  983. {
  984.     if(m_spNaviVolDecorator)
  985.     {
  986.         if( m_cbTempNaviDisplay.IsPending() )
  987.         {
  988.             m_cbTempNaviDisplay.Stop();
  989.         }
  990. m_naviPane->Pop(m_spNaviVolDecorator.Ptr());
  991. m_spNaviVolDecorator = 0;
  992.     }
  993. }
  994. ////////////////////////////////////
  995. //
  996. void CHXAvPlayView::DeactivateNaviPlaylistControl()
  997. {
  998.     m_bViewPlaylistMode = false;
  999.     if(m_spNaviPlaylistDecorator)
  1000.     {
  1001.         if( m_cbTempNaviDisplay.IsPending() )
  1002.         {
  1003.             m_cbTempNaviDisplay.Stop();
  1004.         }
  1005. m_naviPane->Pop(m_spNaviPlaylistDecorator.Ptr());
  1006. m_spNaviPlaylistDecorator = 0;
  1007.     }
  1008. }
  1009. ////////////////////////////////////
  1010. //
  1011. void CHXAvPlayView::HideTempNaviControlNowL()
  1012. {
  1013.     // one of these is showing; hide
  1014.     DeactivateNaviVolumeControl();
  1015.     DeactivateNaviPlaylistControl();
  1016.     // now re-display custom control
  1017.     DrawNaviDefaultControlNowL();
  1018.    
  1019. }
  1020. ///////////////////////////////////
  1021. // activate volume display callback and show the control
  1022. //
  1023. void CHXAvPlayView::ActivateNaviVolumeControlL(TUint msHide)
  1024. {
  1025.     // ensure playlist control is hidden
  1026.     DeactivateNaviPlaylistControl();
  1027.     if( msHide )
  1028.     {
  1029.         // set timer for hiding volume control after a delay
  1030.         m_cbTempNaviDisplay.Set(msHide);
  1031.     }
  1032.     if( !m_spNaviVolDecorator )
  1033.     {
  1034. // R_AVKON_NAVI_PANE_RECORDER_VOLUME_INDICATOR
  1035. m_spNaviVolDecorator = m_naviPane->CreateVolumeIndicatorL(R_AVKON_NAVI_PANE_VOLUME_INDICATOR);
  1036.     }
  1037. }
  1038. ///////////////////////////////////
  1039. // activate playlist callback and show the control
  1040. //
  1041. void CHXAvPlayView::ActivateNaviPlaylistControlL(TUint msHide)
  1042. {
  1043.     // ensure volume control is hidden
  1044.     DeactivateNaviVolumeControl();
  1045.     if( msHide != 0 )
  1046.     {
  1047.         // set timer for hiding playlist control after a delay
  1048.         m_cbTempNaviDisplay.Set(msHide);
  1049.     }
  1050.     else if(m_cbTempNaviDisplay.IsPending())
  1051.     {
  1052.         m_cbTempNaviDisplay.Stop();
  1053.     }
  1054.     
  1055.     if( !m_spNaviPlaylistDecorator )
  1056.     {
  1057.         // create custom navi control (status and timer, etc)
  1058.         CHXAvPlaylistNaviControl* pControl = CHXAvPlaylistNaviControl::NewL(m_player, *m_naviPane);
  1059.         AUTO_PUSH_POP(pControl);
  1060.         // draw only works well if done via the navi pane push (from the decorator)
  1061.         const CHXAvCommand& cmdRefresh =
  1062.         MakeCommand(this, &CHXAvPlayView::DrawNaviPlaylistControlNowL);
  1063.         // navi pane control must draw itself via the navi pane
  1064.         pControl->SetRefreshCommandL(cmdRefresh);
  1065.         // decorator assumes ownership of our custom control
  1066.         m_spNaviPlaylistDecorator = CAknNavigationDecorator::NewL(m_naviPane, pControl);
  1067.     }
  1068. }
  1069. ////////////////////////////////////////
  1070. // update navi control so it is showing if necessary
  1071. // and redrawn; volume control takes precedence (unless
  1072. // user action causes navi control state change)
  1073. //
  1074. void CHXAvPlayView::UpdateNaviDefaultControlL()
  1075. {
  1076.     CHXAvNaviPaneControl* pControl = 0;
  1077.     if( m_spNaviDefaultDecorator )
  1078.     {
  1079.         pControl = static_cast<CHXAvNaviPaneControl*>(m_spNaviDefaultDecorator->DecoratedControl());
  1080.     }
  1081.     else
  1082.     {
  1083.         // create custom navi control (status and timer, etc)
  1084.         pControl = CHXAvNaviPaneControl::NewL(m_player, *m_naviPane);
  1085.         AUTO_PUSH_POP(pControl);
  1086.         // draw only works well if done via the navi pane push (from the decorator)
  1087.         const CHXAvCommand& cmdRefresh =
  1088.         MakeCommand(this, &CHXAvPlayView::DrawNaviDefaultControlNowL);
  1089.         // navi pane control must draw itself via the navi pane
  1090.         pControl->SetRefreshCommandL(cmdRefresh);
  1091.         // decorator assumes ownership of our custom control
  1092.         m_spNaviDefaultDecorator = CAknNavigationDecorator::NewL(m_naviPane, pControl);
  1093.     }
  1094.     pControl->UpdateEverythingL();
  1095.     DrawNaviDefaultControlNowL();
  1096. }
  1097. ///////////////////////////////////
  1098. //
  1099. void CHXAvPlayView::OnPhoneEvent()
  1100. {
  1101.     // phone call state changed to one of following (enums in order):
  1102.     //
  1103.     // ESACallNone,
  1104.     // ESACallVoice,
  1105.     // ESACallFax,
  1106.     // ESACallData,
  1107.     // ESACallAlerting,
  1108.     // ESACallRinging,
  1109.     // ESACallAlternating
  1110.     //
  1111.     TSysAgentEvent event = m_saWatcher.GetSaEvent();
  1112.     TInt state = event.State();
  1113.     HX_ASSERT(event.Uid() == KUidCurrentCall);
  1114.     DPRINTF(SYMP_INFO, ("CHXAvPlayView::OnPhoneEvent(): phone state now = %ldn", state));
  1115.     
  1116.     switch(state)
  1117.     {
  1118.         case ESACallNone:
  1119.         {
  1120.             // END call
  1121.             DPRINTF(SYMP_INFO, ("CHXAvPlayView::OnPhoneEvent(): call (type = %ld) endedn", m_lastPhoneState));
  1122.             if(ESACallData == m_lastPhoneState)
  1123.             {
  1124.                 //
  1125.                 // data call has ended; user will be prompted by system to re-connect modem;
  1126.                 // if user opts not to reconnect, backend socket user does not get notification
  1127.                 // and ends up in weird state
  1128.                 //
  1129.                 HaltPlayer();
  1130.             }
  1131.         
  1132.         }
  1133.         break;
  1134.         case ESACallVoice:
  1135.         case ESACallFax:
  1136.         case ESACallAlerting:
  1137.         case ESACallRinging:
  1138.         case ESACallAlternating:
  1139.             // BEGIN call
  1140.             DPRINTF(SYMP_INFO, ("CHXAvPlayView::OnPhoneEvent(): call starting or startedn"));
  1141.             HaltPlayer(); // just in case; we expect deactivate/loose focus event as well
  1142.             break;
  1143.         default:
  1144.             // ignore....
  1145.             break;
  1146.     }
  1147.     m_lastPhoneState = state;
  1148. }
  1149. void CHXAvPlayView::HandleForegroundEventL(TBool bEnterForeground)
  1150. {
  1151.     DPRINTF(SYMP_INFO, ("CHXAvPlayView::HandleForegroundEventL(): enter = '%s'n", dbg::Bool(bEnterForeground)));
  1152.     CHXAvViewBase::HandleForegroundEventL(bEnterForeground);
  1153.     if( bEnterForeground)
  1154.     {
  1155.         // in case this is first foreground event after activation
  1156.         if(m_spViewActivateClip)
  1157.         {
  1158.             m_player->Play(*m_spViewActivateClip);
  1159.             m_spViewActivateClip = 0;
  1160.         }
  1161.     }
  1162.     else
  1163.     {
  1164.         if(m_bViewPlaylistMode)
  1165.         {
  1166.             // we may miss shift up key event if it occurs while we are not in foreground
  1167.             DoExitPlaylistModeL(false);
  1168.         }
  1169.     }
  1170.     
  1171. }
  1172. ////////////////////////////////////////////////
  1173. // app is loosing focus and we are active view
  1174. void CHXAvPlayView::HandleLosePlayFocus()
  1175. {
  1176.     HaltPlayer();
  1177. }
  1178. void CHXAvPlayView::HaltPlayer()
  1179. {
  1180.     if( m_player )
  1181.     {
  1182.         bool bIsHalted = m_player->IsStopped() || m_player->IsPaused();
  1183.         if(!bIsHalted)
  1184.         {
  1185.             if(m_player->CanPause())
  1186.             {
  1187.                 m_player->Pause();
  1188.             }
  1189.             else
  1190.             {
  1191.                 m_player->Stop();
  1192.             }
  1193.         }
  1194.     }
  1195. }
  1196. ////////////////////////////////////////
  1197. //
  1198. void CHXAvPlayView::DrawNaviPlaylistControlNowL()
  1199. {
  1200.     HX_ASSERT(!m_spNaviVolDecorator);
  1201.     if( m_spNaviPlaylistDecorator) 
  1202.     {
  1203.         m_naviPane->PushL(*m_spNaviPlaylistDecorator);
  1204.     }
  1205. }
  1206. ////////////////////////////////////////
  1207. //
  1208. void CHXAvPlayView::DrawNaviDefaultControlNowL()
  1209. {
  1210.     // don't draw custom if temp control is up
  1211.     if( m_spNaviDefaultDecorator  && !m_spNaviVolDecorator && !m_spNaviPlaylistDecorator) 
  1212.     {
  1213.         m_naviPane->PushL(*m_spNaviDefaultDecorator);
  1214.     }
  1215.     
  1216. }
  1217. ////////////////////////////////////////////////
  1218. // ensure that title reflects state of the
  1219. // player
  1220. //
  1221. void CHXAvPlayView::UpdateTitleL()
  1222. {
  1223.     DPRINTF(SYMP_INFO, ("CHXAvPlayView::UpdateTitleL()n")); 
  1224.     HBufC* pTitleText = CHXAvMisc::AllocTitleL(m_player);
  1225.     if( pTitleText )
  1226.     {
  1227.         AUTO_PUSH_POP_DEL(pTitleText);
  1228.         m_titlePane->SetTextL(*pTitleText);
  1229.     }
  1230.     else
  1231.     {
  1232.         // probably means no current url, let alone a file header
  1233.         SetDefaultAppTitleL();
  1234.     }
  1235. }
  1236. //////////////////////////////////////////////
  1237. // hide or show clip info based on availability 
  1238. // of clip info
  1239. void CHXAvPlayView::InitClipInfoMenuItem(CEikMenuPane* pMenuPane)
  1240. {
  1241.     bool bShow = (m_player->GetClipInfo().GetFileHeader(0) != 0);
  1242.     pMenuPane->SetItemDimmed(EClipInfoDialog, !bShow);
  1243. }
  1244. //////////////////////////////////////////////
  1245. // hide or show playlist menu items depending
  1246. // on whether or not a playlist is loaded
  1247. void CHXAvPlayView::InitPlaylistMenuItems(CEikMenuPane* pMenuPane)
  1248. {
  1249.     bool bEnable = m_player->IsPlaylistLoaded() && m_player->GetPlaylistItemCount() > 1;
  1250.     pMenuPane->SetItemDimmed(EPrevClip, !bEnable);
  1251.     pMenuPane->SetItemDimmed(ENextClip, !bEnable);
  1252. }
  1253. //////////////////////////////////////////////
  1254. // hide or show save based on the currently
  1255. // loaded url
  1256. void CHXAvPlayView::InitSaveMenuItem(CEikMenuPane* pMenuPane)
  1257. {
  1258.     bool bHideIt = true;
  1259.     CHXAvCleanString txtSaveUrl(m_player->GetMainURL());
  1260.     //
  1261.     // hide 'save' menu item only for local clips that:
  1262.     //
  1263.     //  1) are already under one of our media folders and not in a hidden folder
  1264.     //  2) that reference an invalid path
  1265.     //  
  1266.     // note: playlists (ram's) are always local 
  1267.     //
  1268.     
  1269.     if( CHXAvUtil::IsLocal(txtSaveUrl()) )
  1270.     {
  1271. // convert file url to full local path format
  1272. HBufC* pPath = CHXAvUtil::AllocStdPathFromPlayerUrlL(txtSaveUrl()); 
  1273. AUTO_PUSH_POP_DEL(pPath);
  1274.         if( !CHXAvFile::PathExists(*pPath) )
  1275.         {
  1276.             // can't save invalid path!
  1277.             bHideIt = true;
  1278.         }
  1279.         else
  1280.         {
  1281.             //
  1282.             // XXXLCM it arguably would be a nice idea to enable save all the time (as long as path is valid);
  1283.             //        this would allow one way to copy from phone to mmc (or just ability to make new copy for
  1284.             //        whatever reason)
  1285.             //
  1286.             // check if path exists under a media store root; if it does, hide it (already saved)
  1287.             // 
  1288.             // exception: if under the system folder (which is hidden), enable it
  1289.             //
  1290.             const CHXAvVector<CHXAvMediaFolderInfoPtr>& info = m_playerUI->GetMediaStoreInfoL();
  1291.             for(TInt idx = 0; idx < info.Nelements(); ++idx)
  1292.             {
  1293.                 TPtrC folder = info[idx]->GetRoot();
  1294.                 // get relative path (without drive letter)
  1295.                 TInt idxStart = 0;
  1296.                 if(CHXAvFile::GetDriveIndex(*pPath) >= 0)
  1297.                 {
  1298.                     idxStart = 2;
  1299.                 }
  1300.                 TPtrC relPath(pPath->Mid(idxStart));
  1301.                 bool bIsUnderSystemFolder = CHXAvFile::IsSubPath(CHXAvUtil::KEPSystemFolderName, relPath);
  1302.           
  1303.                 bHideIt =  CHXAvFile::IsSubPath(folder, *pPath) && !bIsUnderSystemFolder;
  1304.                 if( bHideIt )
  1305.                 {
  1306.                     // no need to keep looking...
  1307.                     break;
  1308.                 }
  1309.             }
  1310.         }
  1311.     }
  1312.     pMenuPane->SetItemDimmed(ESaveToFolder, bHideIt);
  1313.     /*// if it is already saved, we can add it to the pinboard
  1314.     if (bHideIt)
  1315.     {
  1316. // add to pinboard
  1317. m_wpContext->PinbModel().AddLinkMenuItemL(*pMenuPane, EClipInfoDialog);
  1318.     }*/
  1319.     
  1320. }
  1321. ////////////////////////////////////////////////
  1322. // idle (stopped) state
  1323. void CHXAvPlayView::InitIdleOptionsMenu(CEikMenuPane* pMenuPane)
  1324. {
  1325.     // enable play if player can be resumed (has a(n) URL) 
  1326.     TBool bEnablePlay = m_player->CanResume();
  1327.     pMenuPane->SetItemDimmed(EPlayPause, !bEnablePlay);
  1328.     // save
  1329.     InitSaveMenuItem(pMenuPane);
  1330.     // clip info
  1331.     InitClipInfoMenuItem(pMenuPane);
  1332.     // playlist items
  1333.     InitPlaylistMenuItems(pMenuPane);
  1334.     
  1335.     // mute
  1336.     TInt textResID = m_player->IsMuted() ? R_MENU_UNMUTE : R_MENU_MUTE;
  1337.     pMenuPane->SetItemTextL(EMute, textResID);
  1338. #if(0)
  1339.     // full screen
  1340.     const bool bEnableFullScreen = false;
  1341.     if( m_player->IsStopped() && bEnableFullScreen )
  1342.     {
  1343. // only if player stopped (until backend supports dynamic resize)
  1344. pMenuPane->SetItemDimmed(EToggleFullScreen, EFalse);
  1345. TInt textResID = StatusPane()->IsVisible() ? R_MENU_ENTER_FULL_SCREEN : R_MENU_EXIT_FULL_SCREEN;
  1346. pMenuPane->SetItemTextL(EToggleFullScreen, textResID);
  1347.     }
  1348.     else
  1349.     {
  1350. pMenuPane->SetItemDimmed(EToggleFullScreen, ETrue);
  1351.     }
  1352. #endif
  1353.     CHXAvMisc::InitHelpMenuItem(pMenuPane);
  1354.     
  1355. }
  1356. ////////////////////////////////////////////////
  1357. // items common to pause and live
  1358. void CHXAvPlayView::InitNonIdleMenuOptions(CEikMenuPane* pMenuPane)
  1359. {
  1360.     // mute
  1361.     TInt textResID = m_player->IsMuted() ? R_MENU_UNMUTE : R_MENU_MUTE;
  1362.     pMenuPane->SetItemTextL(EMute, textResID);
  1363.     // save
  1364.     InitSaveMenuItem(pMenuPane);
  1365.     // clip info
  1366.     InitClipInfoMenuItem(pMenuPane);
  1367.     // prev next
  1368.     InitPlaylistMenuItems(pMenuPane);
  1369. }
  1370. ////////////////////////////////////////////////
  1371. //
  1372. void CHXAvPlayView::InitLivePlayOptionsMenu(CEikMenuPane* pMenuPane)
  1373. {
  1374.     InitNonIdleMenuOptions(pMenuPane);
  1375. }
  1376. ////////////////////////////////////////////////
  1377. //
  1378. void CHXAvPlayView::InitPausedOptionsMenu(CEikMenuPane* pMenuPane)
  1379. {
  1380.     InitNonIdleMenuOptions(pMenuPane);
  1381.     CHXAvMisc::InitHelpMenuItem(pMenuPane);
  1382. }
  1383. ////////////////////////////////////////////////
  1384. // Called when a menu pane is about to be displayed
  1385. // 
  1386. void
  1387. CHXAvPlayView::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* pMenuPane)
  1388. {
  1389.     bool bInitCommonItems = true;
  1390.     //
  1391.     // note: there is no menu in play state (just cba)
  1392.     //
  1393.     DPRINTF(SYMP_WSEVENTS, ("CHXAvPlayView::DynInitMenuPaneL(id=%d)n", aResourceId));
  1394.     switch(aResourceId)
  1395.     {
  1396.     case R_AVP_PLAYER_VIEW_IDLE_MENU_PANE:
  1397. InitIdleOptionsMenu(pMenuPane);
  1398.         break;
  1399.     case R_AVP_PLAYER_VIEW_PAUSED_MENU_PANE:
  1400. InitPausedOptionsMenu(pMenuPane);
  1401.         break;
  1402.     case R_AVP_PLAYER_VIEW_LIVE_PLAY_MENU_PANE:
  1403.         InitLivePlayOptionsMenu(pMenuPane);
  1404.         break;
  1405.     default:
  1406.         bInitCommonItems = false;
  1407.         break;
  1408.     }
  1409.     if(bInitCommonItems)
  1410.     {
  1411.         CHXAvMisc::InitDebugMenuItemsL(pMenuPane);
  1412.     }
  1413.     
  1414. }
  1415. ////////////////////////////////////////////////////
  1416. // update context pane (i.e., app icon area) to reflect player state
  1417. //
  1418. void CHXAvPlayView::UpdateContextPaneL()
  1419. {
  1420. #if(0)
  1421.     bool bShowResumePendingIcon = false;
  1422.     //
  1423.     // dim icon while playback pending unless we are running
  1424.     // embedded (in that case we don't want to overwrite the
  1425.     // container app icon)
  1426.     // 
  1427.     if( !m_playerUI->IsRunningEmbedded() )
  1428.     {
  1429.         CHXAvPlayerState::State state = m_player->GetPlayerState(),GetState();
  1430.         bShowResumePendingIcon = (state == CHXAvPlayerState::Connecting);
  1431.         bShowResumePendingIcon |= (CHXAvPlayerState::NotBuffering != m_player->GetPlayerState().GetBufferState());
  1432.     }
  1433.     if(bShowResumePendingIcon)
  1434.     {
  1435.         // grey out the app icon
  1436. m_contextPane->SetPictureFromFileL(m_playerUI->GetAppImageFilePath(), 
  1437.     EMbmRealplayerQgn_menu_rp_grey_cxt, EMbmRealplayerQgn_menu_rp_grey_cxt_mask);
  1438.     }
  1439.     else
  1440.     {
  1441. // set default icon from AIF
  1442. m_contextPane->SetPictureToDefaultL();
  1443.     }
  1444. #endif
  1445. }
  1446. ////////////////////////////////////////
  1447. // connect note callback
  1448. void CHXAvPlayView::OnUserCancelConnect()
  1449. {
  1450.     m_player->Stop();
  1451. }
  1452. // we must be last in observer chain
  1453. void
  1454. CHXAvPlayView::OnError(HX_RESULT code)
  1455. {   
  1456.     //
  1457.     // lookup user error message
  1458.     //
  1459.     UINT32 ulErrorStringID = ErrorStringTable[0].m_ulErrorStringID;
  1460.     for (int i = 0;
  1461.         i < sizeof(ErrorStringTable) / sizeof(ErrorStringTable[0]); ++i)
  1462.     {
  1463.         if(ErrorStringTable[i].m_ulErrorTag == code)
  1464.         {
  1465.             ulErrorStringID = ErrorStringTable[i].m_ulErrorStringID;
  1466.             break;
  1467.         }
  1468.     }
  1469.     CHXAvCleanString errText(ulErrorStringID);
  1470.     comptr<CHXLitePrefs> prefs = m_playerUI->GetClientEngineManager()->GetPrefs();
  1471.     const bool bAppendHexCode = prefs::GetBool(prefs, CHXAV_ErrMsgIncludeCode, true);
  1472.     // Let's not do any more memory allocations than we have to if we are 
  1473.     // here precisely because we are out of memory.
  1474.     if(bAppendHexCode && code != HXR_OUTOFMEMORY)
  1475.     {
  1476.         //
  1477.         // create stringified error code to append to error message text
  1478.         //
  1479.         HBufC* pCodeText = 0;
  1480. #if defined(HELIX_FEATURE_DPRINTF)
  1481.         // get nice (translated) version of result code 
  1482.         CHXString str("n");
  1483.         str += dbg::ErrorCode(code);
  1484.         pCodeText = CHXAvStringUtils::AllocTextL(str);
  1485. #else
  1486.         // in this case, just format number
  1487.         _LIT(KErrCodeFormat, "n0x%08x");
  1488.         pCodeText = CHXAvStringUtils::AllocFormatTextHexArgL(KErrCodeFormat, code);
  1489. #endif
  1490.         AUTO_PUSH_POP_DEL(pCodeText);
  1491.         //
  1492.         // form message: user text + appended error code
  1493.         //
  1494.         HBufC* pFullText = CHXAvStringUtils::AllocTextL(errText(), *pCodeText);
  1495.         AUTO_PUSH_POP_DEL(pFullText);
  1496.         CHXAvMessageDialog::DoAlertErrorL(*pFullText);
  1497.     }
  1498.     else
  1499.     {
  1500.         CHXAvMessageDialog::DoAlertErrorL(errText());
  1501.     }
  1502. }