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

Symbian

开发平台:

C/C++

  1. /****************************************************************************
  2.  * chxavplayerui.cpp
  3.  * -----------------
  4.  *
  5.  * Synopsis:
  6.  *
  7.  * CHXAvPlayerUI derives from CAknViewAppUI. It manages the views (main view, 
  8.  * file list view, etc.).It contains UI helpers (info messes, notes) shared by
  9.  * views and contains the implementation of UI commands that might be shared 
  10.  * among all views.
  11.  *
  12.  * Views themselves are persistent and wrap view windows. The view windows are
  13.  * normally created/destroyed upon activation/deactivation of a view to save
  14.  * resources.
  15.  *
  16.  *
  17.  * Target:
  18.  * Symbian OS
  19.  *
  20.  *
  21.  * (c) 1995-2003 RealNetworks, Inc. Patents pending. All rights reserved.
  22.  *
  23.  *****************************************************************************/
  24. #include <aknpopup.h>
  25. #include <akntitle.h>
  26. #include <stringloader.h>
  27. #include <eikenv.h>
  28. #include <bautils.h>
  29. #include <coemain.h>
  30. #include <bacntf.h> //CEnvironmentChangeNotifier
  31. //#include <hlplch.h>
  32. #include "chxavplayerdoc.h"
  33. #include "chxavvector.h"
  34. #include "player_uids.h"
  35. #include "chxavviewbase.h"
  36. #include "chxavplayer.h"
  37. #include "chxavfileview.h"
  38. #include "chxavplayview.h"
  39. #include "realplayer.rsg"
  40. #include "realplayer.hrh"
  41. #include "chxavutil.h"
  42. #include "chxavmisc.h"
  43. #include "chxavurllist.h"
  44. #include "chxavurlrep.h"
  45. #include "chxavurlinfo.h"
  46. #include "chxaveditplaylistdialog.h"
  47. #include "chxavstringutils.h"
  48. #include "chxavcleanstring.h"
  49. #include "chxavmessagedialog.h"
  50. #include "chxavrecentclipspopuplist.h"
  51. #include "chxavcleanupstack.h"
  52. #include "chxavplayerui.h"
  53. #include "chxavconfignames.h"
  54. #include "chxavmediafolderinfo.h"
  55. #include "chxavclipinfolist.h"
  56. #include "chxavsettingsview.h"
  57. #include "chxavselectsettingsview.h"
  58. #include "comptr_traits.h"
  59. #include "hxsym_debug.h"
  60. #include "hxsym_leaveutil.h"
  61. #include "hxsym_mmc_utils.h"
  62. #include "....symbianplayer.ver"
  63. #include "chxavaccesspointdb.h"
  64. namespace
  65. {
  66. //
  67. // enums for various shared data keys (see shareddatakeys.h):
  68. //
  69. //KSysApLightsControl
  70. enum BacklightState
  71. {
  72. BacklightNormal     = 0,
  73. BacklightDisplayOn  = 1,    // keypad only on if needeed (depends on grip's state and light sensor)
  74. BacklightAlwaysOn   = 2     // keypad forced on all the time
  75. };
  76. //KSysApMessageToneQuit
  77. enum MessageToneState
  78. {
  79. MessageTonesOff = 0,
  80. MessageTonesOn = 1
  81. };
  82. //KSysAudioStatus
  83. enum AudioStatus
  84. {
  85. AudioStatusNull = 0,
  86. AudioStatusPlaying = 1,
  87. AudioStatusRecording = 2
  88. };
  89. //KSysApAlarmLightActive
  90. enum AlarmLightState
  91. {
  92. AlarmNotFlashing = 0,
  93. AlarmFlashing = 1
  94. };
  95. /*
  96.  * AllocAboutTextL
  97.  * ---------------
  98.  *
  99.  */
  100. HBufC* AllocAboutTextL()
  101. {
  102.     // load descriptors from char*
  103.     CHXAvCleanString buildDate(__DATE__);
  104.     CHXAvCleanString buildTime(__TIME__);
  105.     CHXAvCleanString version(TARVER_STRING_VERSION);
  106.     CHXAvCleanString buildName(TARVER_STR_BUILD_NAME);
  107.     CHXAvCleanString profile(makestr(SYMBIANPLAYER_INSTALL_NAME));
  108.  
  109.     // load about resources
  110.     CHXAvCleanString copyText(R_ABOUT_COPYRIGHT_TEXT);
  111.     CHXAvCleanString voiceAgeText(R_ABOUT_VOICE_AGE_TEXT);
  112.     CHXAvCleanString versionText(R_ABOUT_VERSION, version());
  113.     CHXAvCleanString dateText(R_ABOUT_BUILD_DATE, buildDate());
  114.     CHXAvCleanString timeText(R_ABOUT_BUILD_TIME, buildTime());
  115.     
  116.     
  117.     // calculate buffer needed for full about text
  118.     TUint32 cchTotal = copyText().Length() 
  119.                     + voiceAgeText().Length() 
  120.                     + versionText().Length() 
  121.                     + buildName().Length()
  122.                     + profile().Length()
  123.                     + dateText().Length()
  124.                     + timeText().Length() 
  125.                     ; 
  126.     // add for formatting spaces (newlines)
  127.     cchTotal += 20;
  128.     HBufC* pbuff = HBufC::NewL(cchTotal);
  129.     AUTO_PUSH_POP(pbuff);
  130.     TPtr ptr = pbuff->Des();
  131.    
  132.     // build text
  133.     _LIT(KParagraphBreak, "nn");
  134.     // version: xxx
  135.     ptr.Copy(versionText());
  136.     // date: xxx
  137.     ptr.Append(KNewLine());
  138.     ptr.Append(dateText());
  139.     // time: xxx
  140.     ptr.Append(KNewLine());
  141.     ptr.Append(timeText());
  142.     
  143.     // build name
  144.     if( buildName().Length() > 0)
  145.     {
  146.         ptr.Append(KNewLine());
  147.         ptr.Append(buildName());
  148.     }
  149.     // profile
  150.     ptr.Append(KNewLine);
  151.     ptr.Append(profile());
  152.     // copyright
  153.     ptr.Append(KParagraphBreak());
  154.     ptr.Append(copyText());
  155.     
  156.     // voice age
  157.     ptr.Append(KParagraphBreak());
  158.     ptr.Append(voiceAgeText());
  159.   
  160.     return pbuff;
  161. }
  162. /////////////////////////////////////////////////
  163. // helper
  164. CHXString GetRecentClipsFileName()
  165. {
  166.     TFileName* pFullPathRecentClips = CHXAvFile::AllocAppFolderPathL(CHXAvUtil::KPlayerDataFolder);
  167.     AUTO_PUSH_POP_DEL(pFullPathRecentClips);
  168.     CHXAvFile::AppendPath(*pFullPathRecentClips, KRecentClipsName, CHXAvFile::ntFile);
  169.     CHXString str = CHXAvStringUtils::DescToString(*pFullPathRecentClips);
  170.     return str;
  171. }
  172. } // ns anon
  173.     
  174. ////////////////////////////////////////////////
  175. // CEnvironmentChangeNotifier callback
  176. TInt HandleEnvChange_(TAny* p)
  177. {
  178.     // forward this to the ui
  179.     CHXAvPlayerUI* pUI = reinterpret_cast<CHXAvPlayerUI*>(p);
  180.     pUI->HandleEnvChange();
  181.     return EFalse; // don't call again
  182. }
  183. ////////////////////////////////////////////////
  184. //
  185. void CHXAvPlayerUI::HandleEnvChange()
  186. {
  187.     HX_ASSERT(m_pEnvChange);
  188.     TInt change = m_pEnvChange->Change();
  189.     if( m_bIgnoreFirstEnvChange )
  190.     {
  191.         // ignore:
  192.         // 
  193.         // this is an immediate notification sent after we initially request environment
  194.         // change events; in this case 'change' has bits set for all event notifications
  195.         // that we can receive
  196.         //
  197.         m_bIgnoreFirstEnvChange = false;
  198.     }
  199.     else if( EChangesOutOfMemory & change )
  200.     {
  201.         //
  202.         // OOM:
  203.         //
  204.         // Helix core typically ends up in a weird state after allocation failure
  205.         // because it does not expect/handle leave, so we just display error dialog
  206.         // (if possible) and close app.
  207.         //
  208.         // free some reserve memory we allocated up front
  209.         m_spMemoryReserve = 0;
  210.         TRAPD(err, CHXAvMessageDialog::DoSystemErrorNoteL(KErrNoMemory));
  211.         CloseApp();
  212. #if(0)
  213.         // if play view is active
  214.         CHXAvViewBase *pView = static_cast<CHXAvViewBase *>(iView);
  215.         CHXAvPlayView* pPlayView = GetPlayView();
  216.         if(pPlayView->Id() == pView->Id())
  217.         {
  218.             //pPlayView->FreeMemoryReserve();
  219.             User::CompressAllHeaps();
  220.             TRAP(err, DoBackFromCurrentViewL());
  221.             if(KErrNone != err)
  222.             {
  223.                 CloseApp();
  224.             }
  225.         }
  226. #endif
  227.     }
  228. }
  229. /*
  230.  * CHXAvPlayerUI
  231.  * -------------
  232.  * Player ui constructor.
  233.  *
  234.  */
  235. CHXAvPlayerUI::CHXAvPlayerUI()
  236. : m_recentClips(0)
  237. , m_pPrefChangeObserver(0)
  238. , m_bIsRunningEmbedded(false)
  239. , m_bLaunchAppWithClipPending(false)
  240. , m_pEnvChange(0)
  241. , m_bIgnoreFirstEnvChange(true)
  242. //, m_bIsActivePlaybackState(false)
  243. //, m_bDidScreenSaverSignal(false)
  244. //, m_pPinbModel(0) 
  245. //, m_sysSdClient(this)
  246. //, m_sysApSdClient(this)
  247. {
  248. }
  249. /* 
  250.  * ~CHXAvPlayerUI
  251.  * --------------
  252.  * Player ui destructor.
  253.  *
  254.  */
  255. CHXAvPlayerUI::~CHXAvPlayerUI()
  256. {    
  257.     DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::Dtor()n"));
  258.     //m_sysSdClient.Close();
  259.     //m_sysApSdClient.Close();
  260.     HX_DELETE(m_pEnvChange);
  261. }
  262. /*
  263.  * ConstructL
  264.  * ----------
  265.  * Perform all view object construction and anything else 
  266.  * needed for this class.
  267.  *
  268.  */
  269. void 
  270. CHXAvPlayerUI::ConstructL()
  271.     DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::ConstructL()n"));
  272.     BaseConstructL();
  273.     // only allow one ui instance
  274.     EnsureUniqueInstanceL();
  275.     // load client engine and services
  276.     m_spEngineMgr = new (ELeave) CHXClientEngineManager();
  277.     m_spEngineMgr->ConstructL();
  278.     CHXAvPlayerDoc* pDoc = static_cast<CHXAvPlayerDoc*>(Document());
  279.     pDoc->SetEngineManager(m_spEngineMgr);
  280.     // reserve some memory to help with OOM handling
  281.     const TUint K_MEMORY_RESERVE_BYTES = 0x0400 * 4; // 4K
  282.     m_spMemoryReserve = HBufC::NewL(K_MEMORY_RESERVE_BYTES);
  283.     // enable focus events so we can watch when focus window group changes
  284.     RWindowGroup& rootWin = iCoeEnv->RootWin();
  285.     rootWin.EnableFocusChangeEvents();
  286.     //
  287.     // two shared data client connections are needed because signals are auto-
  288.     // canceled when you switch among shared data files
  289.     //
  290. #if(0)
  291.     // for enabling/disabling screen saver
  292.     HXSYM_LEAVE_IF_ERR(m_sysSdClient.Connect());
  293.     HXSYM_LEAVE_IF_ERR(m_sysSdClient.AssignToTemporaryFile(KSDUidSystem));
  294.     // for enabling/disabling backlight
  295.     HXSYM_LEAVE_IF_ERR(m_sysApSdClient.Connect());
  296.     HXSYM_LEAVE_IF_ERR(m_sysApSdClient.AssignToTemporaryFile(KSDUidSysAp));
  297.     m_sysSdClient.NotifyChange(KSDUidSystem);
  298.     m_sysApSdClient.NotifyChange(KSDUidSysAp);
  299.     // for "add to pinboard"
  300.     m_pPinbModel =  CPinbModel::NewL();
  301. #endif
  302.     // locate full path to app image file
  303.     m_spImageFilePath = CHXAvFile::AllocAppFolderPathL(CHXAvUtil::KImagesMBMName);
  304.     // recent clips
  305.     UINT32 maxRecentClipCount = prefs::GetUINT32(m_spEngineMgr->GetPrefs(), CHXAV_MaxRecentClipCount, 6);
  306.     m_recentClips = new (ELeave) CHXAvURLList(maxRecentClipCount);
  307.     m_recentClips->InitializeL();
  308.     m_recentClips->ReadFile(GetRecentClipsFileName());
  309.     // media store
  310.     UpdateMediaStoreInfoL();
  311.     
  312.     // views
  313.     CHXAvPlayView* pPlayerView = new (ELeave) CHXAvPlayView(VID_PlayerView, this);
  314.     AUTO_PUSH_POP(pPlayerView);
  315.     pPlayerView->ConstructL();
  316.   
  317.     CHXAvFileView* pFileView = new (ELeave) CHXAvFileView(VID_FileView, this);
  318.     AUTO_PUSH_POP(pFileView);
  319.     pFileView->ConstructL();
  320.     
  321.     CHXAvSettingsView *pSettingsView = new (ELeave) CHXAvSettingsView(VID_SettingsView, this);
  322.     AUTO_PUSH_POP(pSettingsView);
  323.     pSettingsView->ConstructL();
  324.     CHXAvSelectSettingsView *pSelectSettingsView = new (ELeave) CHXAvSelectSettingsView(VID_SelectSettingsView, this);
  325.     AUTO_PUSH_POP(pSelectSettingsView);
  326.     pSelectSettingsView->ConstructL();
  327.     // determine default view; add default view first
  328.     m_bIsRunningEmbedded = ContainerAppUi() || iDoorObserver;
  329.     DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::ConstructL(): embedded = '%s'n", dbg::Bool(m_bIsRunningEmbedded)));
  330.     if(m_bIsRunningEmbedded)
  331.     {
  332.         // embedded; start with player view
  333.         m_idxDefaultView = VID_PlayerView;
  334.         AddViewL(pPlayerView);
  335.         AddViewL(pFileView);
  336.         AddViewL(pSettingsView);
  337.         AddViewL(pSelectSettingsView);
  338.         SetDefaultViewL(*pPlayerView);
  339.     }
  340.     else
  341.     {
  342.         // not embedded; start with file view
  343.         m_idxDefaultView = VID_FileView;
  344.         AddViewL(pFileView);
  345.         AddViewL(pPlayerView);
  346.         AddViewL(pSettingsView);
  347.         AddViewL(pSelectSettingsView);
  348.         SetDefaultViewL(*pFileView);
  349.     }
  350.     // register to receive environment change notifications (for OOM)
  351.     m_bIgnoreFirstEnvChange = true;
  352.     HX_ASSERT(!m_pEnvChange);
  353.     TCallBack cb(HandleEnvChange_, this);
  354.     m_pEnvChange = CEnvironmentChangeNotifier::NewL(CActive::EPriorityHigh, cb);
  355.     m_pEnvChange->Start();
  356.     
  357. }
  358. bool CHXAvPlayerUI::EnsureUniqueInstanceHelperL()
  359. {
  360.     DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::EnsureUniqueInstanceHelperL(): acquiring instance token..."));
  361.     bool bGotIt = m_instanceToken.TryAcquire();
  362.     if( !bGotIt )
  363.     {
  364.         DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::EnsureUniqueInstanceHelperL(): failed to acquire token (another app is running); broadcasting close..."));
  365.         // another instance has the instance token
  366.         //
  367.         // send message to other instances to request that it stop and exit
  368.         //
  369.     
  370.         //
  371.         // broadcast 'close' message for other instance to see; other instances
  372.         // receive this message via HandleApplicationSpecificEventL()
  373.         //
  374.         // we broadcast a close message to all apps because it is hard
  375.         // to find embedded instances
  376.         //
  377.         HBufC8* pMsg = CHXAvMisc::MakeHXPlayerPrivateMessageL(KMessage_CloseApp);
  378.         AUTO_PUSH_POP_DEL(pMsg);
  379.         CHXAvMisc::BroadcastWsEventL(KHXPlayerWsEvent, pMsg);
  380.         
  381.         //
  382.         // wait ~5 seconds for other instance
  383.         // to close down before we give up
  384.         //
  385.         const TUint k_maxTryCount = 10;
  386.         const TUint k_msBetweenAttempts = 500;
  387.         const TUint k_showMessageTryIndex = 3; // show mesage after 3 tries (1.5 secs)
  388.         for( TInt tryCount = 0; tryCount < k_maxTryCount && !bGotIt; ++tryCount)
  389.         {
  390.             // wait a bit before next attempt to try to acquire the token; use custom wait so dialogs have chance to draw
  391.             CHXAvUtil::ActiveWait(k_msBetweenAttempts);
  392.             //User::After(k_msBetweenAttempts * k_usecPerMs); 
  393.             bGotIt = m_instanceToken.TryAcquire();
  394.             if( !bGotIt && (k_showMessageTryIndex == tryCount) )   
  395.             {
  396.                 // show note to user that we are shutting down other instance
  397.                 HX_ASSERT(m_spCloseAppWaitNote);
  398.                 m_spCloseAppWaitNote->StartAndKickL();
  399.             }
  400.         }
  401.         m_spCloseAppWaitNote->EndL();
  402.         if( !bGotIt )
  403.         {
  404.             CHXAvMessageDialog::DoAlertErrorL(CHXAvCleanString(R_AVP_N_FAILED_TO_CLOSE_OTHER_INSTANCE)());
  405.         }
  406.             
  407.     }
  408.     return bGotIt;
  409. }
  410. /*
  411.  * EnsureUniqueInstanceL
  412.  * ------------
  413.  * ensure that we close any other app instances
  414.  * that might be running
  415.  *
  416.  */
  417. void CHXAvPlayerUI::EnsureUniqueInstanceL()
  418. {
  419.     m_spCloseAppWaitNote = new (ELeave) CHXAvWaitNote();
  420.     m_spCloseAppWaitNote->SetTextL(CHXAvCleanString(R_AVP_N_CLOSING_OTHER_INSTANCE)());
  421.     // token name for controlling single instance
  422.     _LIT(KUniqueInstanceSemName, "HelixPlayer10009D06");
  423.     m_instanceToken.ConstructL(KUniqueInstanceSemName);
  424.     if(!EnsureUniqueInstanceHelperL())
  425.     {
  426.         DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::EnsureUniqueInstanceL(): other instance failed to close"));
  427.         HXSYM_LEAVE(KLeaveWithoutAlert);
  428.     }
  429. }
  430. ////////////////////////////////////////////
  431. // 
  432. TBool CHXAvPlayerUI::ProcessCommandParametersL(TApaCommand idCmd,
  433.                                             TFileName& aDocumentName,
  434.                                             const TDesC8& /*aTail*/)
  435. {
  436.     DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::ProcessCommandParametersL(%d))n", idCmd));
  437.     DPRINTF(SYMP_INFO, ("doc = '%s'n", dbg::CharPtr(aDocumentName)()));
  438.     // this (call to 2-arg override) causes doc name to be given a new name
  439.     // return CAknViewAppUi::ProcessCommandParametersL(idCmd, aDocumentName);
  440.     
  441.     // this (default) results in CEikDocument::OpenFileL not being called
  442.     // return CAknViewAppUi::ProcessCommandParametersL(idCmd, aDocumentName, aTail);
  443.     // ensures that CEikDocument::OpenFileL is called if a command line arg was provided
  444.     return EFalse;
  445.    
  446. }
  447. ////////////////////////////////////////////
  448. // get here if:
  449. //
  450. // o click on file in file browser (while our app is running)
  451. // o click on app in file browser (while our app is running)
  452. // o someone calls TApaTask::SwitchOpenFile()
  453. // o our document calls us because it gets the openfile request
  454. // 
  455. // all external ways of getting an argument, file, etc. end up
  456. // here
  457. //
  458. // fileArg can be in local path form ('c:myfolderfile.rm') or 
  459. // url form ('rtsp://dfsd/sdf/foo.rm')
  460. //
  461. void CHXAvPlayerUI::OpenFileL(const TDesC& fileArg)
  462. {
  463.     DPRINTF(SYMP_INFO,("avPlayerUI::OpenFileL(): '%s'n", dbg::CharPtr(fileArg)()));
  464.     
  465.     bool bIsUrl = CHXAvUtil::IsValidUrl(fileArg);
  466.     if( bIsUrl )
  467.     {
  468.         // an URL was passed as the argument
  469.         ActivatePlayViewL(fileArg);
  470.     }
  471.     else
  472.     {
  473.         // local file (most likely case)
  474.         HBufC* pFile = CHXAvFile::AllocFileUrlL(fileArg);
  475.         AUTO_PUSH_POP_DEL(pFile);
  476.         ActivatePlayViewL(*pFile);
  477.     }
  478. }
  479. #if(0)
  480. /*
  481.  * CAknViewAppUi::HandleForegroundEventL
  482.  * ----------------------
  483.  * 
  484.  * Called when app gains/looses foreground (not when app views are switching)
  485.  *
  486.  */
  487. void CHXAvPlayerUI::HandleForegroundEventL(TBool bEnterForeground)
  488. {
  489.     DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::HandleForegroundEventL(): enter = '%s'n", dbg::Bool(bEnterForeground)));
  490.     CAknViewAppUi::HandleForegroundEventL(bEnterForeground);
  491. }
  492. #endif
  493. /*
  494.  * CAknViewAppUi::HandleViewDeactivation
  495.  * ----------------------
  496.  * Switch views.  Set the correct back view index for future switches.
  497.  * This is called, then DoActivate for new view, then DoDeactivate for old view.
  498.  */
  499. void
  500. CHXAvPlayerUI::HandleViewDeactivation(const TVwsViewId& idOldView, const TVwsViewId& idNewView)
  501. {
  502.     DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::HandleViewDeactivation()n"));
  503.     bool bIsInterAppViewSwitch = (idOldView.iAppUid != idNewView.iAppUid);
  504.     if(!bIsInterAppViewSwitch)
  505.     {
  506. // Activating another view in our own app...
  507.         HX_ASSERT(idOldView.iAppUid == CHXAvMisc::KAppUID);
  508.         TUid idNew = idNewView.iViewUid;
  509.         TUid idOld = idOldView.iViewUid;
  510.         // special case: if settings view is activating, tell player view not
  511.         // to shut down the player so return gets user back to previous player state
  512.         if(idOld == TUid::Uid(VID_PlayerView) && idNew == TUid::Uid(VID_SelectSettingsView))
  513.         {
  514.             CHXAvPlayView* pPlayView = GetPlayView();
  515.             pPlayView->SetShutdownOnViewDeactivation(false);
  516.         }
  517.         CHXAvViewBase * pNewView = static_cast<CHXAvViewBase *>(View(idNew));
  518.         CHXAvViewBase * pOldView = static_cast<CHXAvViewBase *>(View(idOld));
  519.         HX_ASSERT(pNewView);
  520.         HX_ASSERT(pOldView);
  521.         DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::HandleViewDeactivation(): old = %d; new = %dn", idOld.iUid, idNew.iUid));
  522.         
  523.         if( idNew == TUid::Uid(m_idxDefaultView) )
  524.         {
  525.             // Default view is activating; there is no "last view" to go back to...
  526.             pNewView->SetBackView(-1);
  527.         }
  528.         else
  529.         {
  530.             // Do nothing if returning back to old view that 'launched' the new (now becoming old) view...
  531.             bool bReturning = (pOldView->GetBackView() == pNewView->Id().iUid);
  532.             // Don't set back view to self...
  533.             bool bSame = (pNewView->Id() == pOldView->Id());
  534.             if(!bReturning && !bSame)
  535.             {
  536.                 pNewView->SetBackView(pOldView->Id().iUid);
  537.             }
  538.         }
  539.     }
  540.     CAknViewAppUi::HandleViewDeactivation(idOldView, idNewView);
  541. }
  542. /* 
  543.  * DoBackFromCurrentViewL
  544.  * ----------------------
  545.  * Go back to the previous view from here.
  546.  *
  547.  */
  548. void 
  549. CHXAvPlayerUI::DoBackFromCurrentViewL()
  550. {
  551.     HX_ASSERT(iView);
  552.     CHXAvViewBase *pView = static_cast<CHXAvViewBase *>(iView);
  553.     TInt idxBackView = pView->GetBackView();
  554.     DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::DoBackFromCurrentViewL(): back view = %dn", idxBackView));
  555.     if (idxBackView == -1)
  556.     {
  557.         // If there's no view to go back to, exit...
  558.         HX_ASSERT( TUid::Uid(m_idxDefaultView) == iView->Id());
  559.         HandleCommandL(EEikCmdExit);
  560.     }
  561.     else
  562.     {
  563.         // note: call to base class is intentional
  564.         HX_ASSERT( TUid::Uid(m_idxDefaultView) != iView->Id());
  565.         ActivateLocalViewL(TUid::Uid(idxBackView));
  566.     }
  567. }
  568. ////////////////////////////////////////
  569. // TWsEvent beyond EEventUser received...
  570. void CHXAvPlayerUI::HandleApplicationSpecificEventL(TInt aType,const TWsEvent& aEvent)
  571. {
  572.     DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::HandleApplicationSpecificEventL(): type = %dn", aType));
  573.     // handle possible shutdown command coming from TWsEvent that we send
  574.     if(aType == KHXPlayerWsEvent)
  575.     {
  576.         TUint8* pData = aEvent.EventData();
  577.         if( pData )
  578.         {
  579.             TPtr8 msg(pData, TWsEvent::EWsEventDataSize);
  580.             DPRINTF(SYMP_INFO, ("HandleApplicationSpecificEventL(): message is '%.*s'n", msg.Length(), msg.Ptr()));
  581.         
  582.             // make sure it is not from this thread
  583.             HBufC8* pMsg = MakeHXPlayerPrivateMessageL(KMessage_CloseApp);
  584.             AUTO_PUSH_POP_DEL(pMsg);
  585.             // message will compare equal if it is a close app message from another instance
  586.             if( 0 != pMsg->Compare(msg) )
  587.             {
  588.                 DPRINTF(SYMP_INFO, ("HandlePossibleShutdownCommandL(): closing instancen"));
  589.                 CloseApp();
  590.             }
  591.         }
  592.     }
  593. }
  594. /* 
  595.  * HandleCommandL
  596.  * --------------
  597.  * These are commands that are shared (or conceivably can be shared) among
  598.  * several of the views
  599.  *
  600.  */
  601. void 
  602. CHXAvPlayerUI::HandleCommandL(TInt aCommand)
  603. {
  604.     switch (aCommand)
  605.     {
  606.     case EAknCmdExit:
  607.     case EEikCmdExit:
  608.     case EAknSoftkeyExit:
  609.         CloseApp();
  610. break;
  611.     case EAknSoftkeyBack:
  612. DoBackFromCurrentViewL();
  613. break;
  614.     case EOpenGuide:
  615.         DoOpenGuideL();
  616.         break;
  617.     case EViewSettings:
  618.         DoSelectSettingsL();
  619. break;
  620.     case EAboutDialog:
  621. DoAboutL();
  622. break;
  623.     case EOpenRecentDialog:
  624. DoOpenRecentL();
  625. break;
  626.     case EOpenURLDialog:
  627. DoOpenURLL();
  628. break;
  629.     
  630.     case ERestoreDefaultSettings:
  631.         DoRestoreDefaultSettingsL();
  632.         break;
  633.     case EAknCmdHelp:
  634.         //HlpLauncher::LaunchHelpApplicationL( iCoeEnv->WsSession(), AppHelpContextL() );
  635.         break;
  636.     default:
  637.         // we don't expect any other commands (except possibly a click on an empty softkey)
  638.         HX_ASSERT(EAknSoftkeyEmpty == aCommand);
  639. break;
  640.     }
  641. }
  642. ////////////////////////////////////////////////////////////////
  643. // restore config to installation default
  644. void CHXAvPlayerUI::DoRestoreDefaultSettingsL()
  645. {
  646.     if(CHXAvMessageDialog::DoQueryL(R_CONF_RESTORE_SETTINGS))
  647.     {
  648.         // user confirmed...
  649.         comptr<CHXLitePrefs> spPrefs = m_spEngineMgr->GetPrefs();
  650.         spPrefs->ResetPrefs(); //XXXLCM can fail
  651.         if( m_pPrefChangeObserver )
  652.         {
  653.             m_pPrefChangeObserver->OnPrefsChanged();
  654.         }
  655.         CHXAvMessageDialog::DoAlertConfirmL(CHXAvCleanString(R_SETTINGS_RESTORED)());
  656.     }
  657. }
  658. /* 
  659.  * DoSelectSettingsL
  660.  * -----------------
  661.  * Show the select settings view.
  662.  *
  663.  */
  664. void CHXAvPlayerUI::DoSelectSettingsL()
  665. {
  666.     // prepare select settings view to launch with first item hilighted
  667.     CAknView* pView = View(TUid::Uid(CHXAvPlayerUI::VID_SelectSettingsView));
  668.     HX_ASSERT(pView);
  669.     CHXAvSelectSettingsView* pSelectView = static_cast<CHXAvSelectSettingsView*>(pView);
  670.     pSelectView->ResetCurrentIndex();
  671.     ActivateLocalViewL(TUid::Uid(VID_SelectSettingsView));
  672. }
  673. ////////////////////////////////////////
  674. // 
  675. void
  676. CHXAvPlayerUI::DoEditPlaylistL(const TDesC& playlistPath)
  677. {
  678.     DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::DoEditPlaylistL()n"));
  679.     CHXAvEditPlaylistDialog* pDlg = new (ELeave) CHXAvEditPlaylistDialog();
  680.     TInt err = KErrNone;
  681.     // save cleanupstack init until LD
  682.     {
  683.         AUTO_PUSH_POP(pDlg);
  684.         pDlg->ConstructL();
  685.         // make sure read-only is clear so we can edit (we don't honor this attribute)
  686.         CHXAvFile::EnsureClearReadOnlyAttributeL(playlistPath);
  687.         err = pDlg->SetPlaylistL(playlistPath);
  688.     }
  689.     if(KErrNone == err)
  690.     {
  691.         pDlg->ExecuteLD(R_AVP_EDIT_PLAYLIST_DLG);
  692.     }
  693.     else
  694.     {
  695.         HX_DELETE(pDlg); // <-- since dialog will not delete itself
  696.         CHXAvMessageDialog::DoAlertErrorL(CHXAvCleanString(R_ERR_UNABLE_TO_EDIT_PLAYLIST)());
  697.     }
  698. }
  699. /*
  700.  * DoOpenGuideL
  701.  * ------------
  702.  * Open the guide.
  703.  *
  704.  */
  705. void
  706. CHXAvPlayerUI::DoOpenGuideL()
  707. {
  708.     const TDesC& guideUrl = GetGuideUrlL(false);
  709.     TInt err = KErrGeneral;
  710.     if( guideUrl.Length() > 0 )
  711.     {
  712.         const TInt KWmlBrowserUid = 0x10008D39;
  713.         
  714.         // format web browser message
  715.         _LIT(KOpenUrlMessagePrefix, "4 ");
  716.         TInt cchTotal = guideUrl.Length() + CHXAvUtil::litSize(KOpenUrlMessagePrefix);
  717.         
  718.         HBufC* pBuf = HBufC::NewL(cchTotal);
  719.         AUTO_PUSH_POP_DEL(pBuf);
  720.         TPtr ptr = pBuf->Des();
  721.         ptr.Copy(KOpenUrlMessagePrefix);
  722.         ptr.Append(guideUrl);
  723.         // launch app with message argument
  724.         TRAP(err, CHXAvMisc::LaunchAppL(KWmlBrowserUid, *pBuf));
  725.     }
  726.     if(KErrNone != err)
  727.     {
  728.         //XXXLCM
  729.         CHXAvMessageDialog::DoAlertInfoL(_L("unable to launch guide"));
  730.     }
  731. }
  732. /*
  733.  * CloseApp
  734.  * --------
  735.  * Called when we receive exit command (from user or via system message)
  736.  *
  737.  */
  738. void
  739. CHXAvPlayerUI::CloseApp()
  740. {
  741.     // Write out the recent clips and release...
  742.     HX_ASSERT(m_recentClips);
  743.     if (m_recentClips)
  744.     {
  745. m_recentClips->WriteFile(GetRecentClipsFileName());
  746.     }
  747.     // this prevents mms app from hanging when we exit
  748.     if(iDoorObserver)
  749.     {
  750.         iDoorObserver->NotifyExit(MApaEmbeddedDocObserver::EEmpty);
  751.     }
  752.     // Now we can exit...
  753.     Exit();
  754. }
  755. ////////////////////////////
  756. //HandleWsEventL
  757. void CHXAvPlayerUI::HandleWsEventL(const TWsEvent& event, CCoeControl* pDest)
  758. {
  759.     DPRINTF(SYMP_WSEVENTS, ("CHXAvPlayerUI::HandleWsEventL():  type = %ld; dest = 0x%08xn", event.Type(), pDest));
  760.     switch(event.Type())
  761.     {
  762.         case EEventKeyUp:
  763.         {
  764.             DPRINTF(SYMP_WSEVENTS, ("CHXAvPlayerUI::HandleWsEventL():  key up eventn"));
  765.             TKeyEvent* pKey = event.Key();
  766.             if(pKey)
  767.             {
  768.                 CHXAvViewBase *pActiveView = static_cast<CHXAvViewBase *>(iView);
  769.                 if(pActiveView)
  770.                 {
  771.                     //
  772.                     // special case: for some reason the left-shift up is not received by the CCoeControl
  773.                     // if you click on a softkey while the shift key is held down before releasing the shift key
  774.                     //
  775.                 
  776.                     // XXXLCM we should probably do more to avoid double-event notification
  777.                     if( pKey->iScanCode == EStdKeyLeftShift)
  778.                     {
  779.                         DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::HandleWsEventL():  got shift key up eventn"));
  780.                         pActiveView->GetWindow()->OfferKeyEventL(*pKey, EEventKeyUp);
  781.                     }
  782.                 }
  783.             }
  784.         }
  785.         break;
  786.         case EEventFocusGroupChanged:
  787.         {
  788.             DPRINTF(SYMP_WSEVENTS, ("CHXAvPlayerUI::HandleWsEvent(): focus group changen"));
  789.             TInt wgidFocus = iEikonEnv->WsSession().GetFocusWindowGroup();
  790.             TUid uidFocus = CHXAvMisc::GetAppUidFromWgId(wgidFocus);
  791.             bool bNeedToStopPlayback = !(uidFocus == CHXAvMisc::KScreenSaverUID || 
  792.                                     uidFocus == CHXAvMisc::KAppUID );
  793.             if( bNeedToStopPlayback )
  794.             {
  795.                 DPRINTF(SYMP_WSEVENTS, ("CHXAvPlayerUI::HandleWsEvent(): new app focus is not screen saver or playern"));
  796.                 CHXAvViewBase* pActiveView = static_cast<CHXAvViewBase *>(iView);
  797.                 if( pActiveView )
  798.                 {
  799.                     pActiveView->HandleLosePlayFocus();
  800.                 }
  801.             }
  802.         }
  803.         break;
  804.         default:
  805.             break;
  806.     }
  807.     CAknViewAppUi::HandleWsEventL(event, pDest);
  808. }
  809. ////////////////////////////////////
  810. // ensure play view is activated and attempt to play clip
  811. //
  812. void CHXAvPlayerUI::ActivatePlayViewL(const TDesC& url)
  813. {
  814.     DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::ActivatePlayViewL():  current view exists = '%s' n", dbg::Bool(iView)));
  815.     if( iView && (TUid::Uid(VID_PlayerView) == iView->Id()) )
  816.     {
  817.         // play view is active view
  818.         CHXAvPlayer* pPlayer = GetPlayer();
  819.         HX_ASSERT(pPlayer);
  820.         pPlayer->Play(url);
  821.     }
  822.     else
  823.     {
  824.         // we need to activate play view
  825.         CHXAvPlayView* pPlayView = GetPlayView();
  826.         // set clip to launch on view activation (view activates asynchronously)
  827.         pPlayView->SetViewActivateClipL(url);
  828.         //
  829.         // Activate player view if not in process of app
  830.         // startup (see OnViewForegroundActivateL()).
  831.         // Otherwise wait for default view (file view) to launch.
  832.         //
  833.         // iView becomes non-0 sometime after first foreground event
  834.         // for first activating view
  835.         //
  836.         m_bLaunchAppWithClipPending = (0 == iView);
  837.         if( !m_bLaunchAppWithClipPending )
  838.         {
  839.             ActivateLocalViewL(TUid::Uid(VID_PlayerView));
  840.         }
  841.     }
  842. }
  843. //
  844. // Called when view receives first foreground event after activation
  845. //
  846. void CHXAvPlayerUI::OnViewForegroundActivateL(TInt idxView)
  847. {
  848.     DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::OnViewForegroundActivateL():  current view id  = %dn", idxView));
  849.     //
  850.     // If this app instance was launched with a clip we get a call
  851.     // to OpenFileL() before the default view (i.e., file view in
  852.     // stand-alone launch case) is  activated. If we activate the
  853.     // player view at that time, the default view  will immediately
  854.     // activate after that (and yours truly has not found a good way
  855.     // to prevent this). So to work around this, we wait for the default
  856.     // view to activate before activating the play view.
  857.     //
  858.     if ( (VID_PlayerView != idxView) && m_bLaunchAppWithClipPending) 
  859.     {
  860.         ActivateLocalViewL(TUid::Uid(VID_PlayerView));
  861.     }
  862.     m_bLaunchAppWithClipPending = false;
  863. }
  864. CHXAvPlayView* CHXAvPlayerUI::GetPlayView()
  865. {
  866.     CHXAvPlayView* pPlayView = (CHXAvPlayView *)(View(TUid::Uid(VID_PlayerView)));
  867.     HX_ASSERT(pPlayView);
  868.     return pPlayView;
  869. }
  870. // player will be NULL if play view not activated
  871. comptr<CHXAvPlayer> CHXAvPlayerUI::GetPlayer()
  872. {
  873.     CHXAvPlayView* pPlayView = GetPlayView();
  874.     CHXAvPlayer* pPlayer = pPlayView->GetPlayer();
  875.     HX_ASSERT(pPlayer);
  876.     return pPlayer;
  877. }
  878. /*
  879.  * DoAboutL
  880.  * --------
  881.  * Do about screen.
  882.  *
  883.  */
  884. void 
  885. CHXAvPlayerUI::DoAboutL()
  886. {
  887.     HBufC* pText = AllocAboutTextL();
  888.     AUTO_PUSH_POP_DEL(pText);
  889.     CHXAvMessageDialog::DoLongTextInfoPromptL(CHXAvCleanString(R_ABOUT_CAPTION)(), *pText, CHXAvMessageDialog::PromptBack);
  890. }
  891. /*
  892.  * DoOpenURLL
  893.  * ----------
  894.  * Show the open url dialog.
  895.  *
  896.  */
  897. void 
  898. CHXAvPlayerUI::DoOpenURLL()
  899. {
  900.     CHXAvCleanString promptText(R_PROMPT_ENTER_URL);
  901.    
  902.     //
  903.     // keep prompting until user: a) cancels; or b) enters a valid URL
  904.     //
  905.     
  906.     for(;;)
  907.     {
  908.         HBufC* pDefaultText = 0;
  909.         if(m_lastClipEntered.IsEmpty())
  910.         {
  911.     // fill with default protocol prefix
  912.     pDefaultText = CHXAvUtil::KRTSPProtocolPrefix().AllocL();
  913.         }
  914.         else
  915.         {
  916.             // fill with last text entered by the user
  917.             pDefaultText = CHXAvStringUtils::AllocTextL(m_lastClipEntered);
  918.         }
  919.         AUTO_PUSH_POP_DEL(pDefaultText);
  920. // Query the user for the url...
  921.         HBufC* pUrl = CHXAvMessageDialog::DoQueryTextL(promptText(), *pDefaultText, KMaxFileName);
  922. if (pUrl != NULL)
  923. {
  924.             AUTO_PUSH_POP_DEL(pUrl);
  925.                     
  926.             // remember what user entered (even if it turns out to be bad)
  927.     CHXAvStringUtils::DesToString(*pUrl, m_lastClipEntered);
  928.             ValidateUrlResult res = ValidateUrl(*pUrl);
  929.             if (CHXAvUtil::vuGood == res)
  930.             {
  931.                 ActivatePlayViewL(*pUrl);
  932.                 break;
  933.             }
  934.             else if(CHXAvUtil::vuMissingScheme == res)
  935.             {
  936.                 //
  937.                 // no scheme
  938.                 //
  939.                 // try with 'rtsp' or 'file' appended, depending on whether url looks
  940.                 // like a local or remote url
  941.                 //
  942.                 HBufC* pAlt = 0;
  943.                 TInt idxDrive = CHXAvFile::GetDriveIndex(*pUrl);
  944.                 if(-1 != idxDrive)
  945.                 {
  946.                     // begins with a drive letter, looks like a file path...
  947.                     pAlt = CHXAvFile::AllocFileUrlL(*pUrl);
  948.                 }
  949.                 else
  950.                 {
  951.                     // guess that this is a remote rtsp URL...
  952.                     pAlt = CHXAvStringUtils::AllocTextL(KRTSPProtocolPrefix, *pUrl);
  953.                 }
  954.                 AUTO_PUSH_POP_DEL(pAlt);
  955.                 if(CHXAvUtil::IsValidUrl(*pAlt))
  956.                 {
  957.                     ActivatePlayViewL(*pAlt);
  958.                     break;
  959.                 }
  960.             }
  961.  
  962.             // assume typo; let user edit and try again...
  963.             CHXAvMessageDialog::DoAlertInfoL(CHXAvCleanString(R_ERR_INVALID_URL)()); 
  964. }
  965.         else
  966.         {
  967.             // user cancelled
  968.             break;
  969.         }
  970.     }
  971. }
  972. /*
  973.  * DoOpenRecentL
  974.  * -------------
  975.  * Show the open recent url dialog.  Launch the item that the user selected.
  976.  *
  977.  */
  978. void
  979. CHXAvPlayerUI::DoOpenRecentL()
  980. {
  981.     if (m_recentClips->NumURLs() > 0)
  982.     {
  983. TInt idxSelectedItem = 0;
  984. CHXAvRecentClipsPopupList* pPopup = new (ELeave) CHXAvRecentClipsPopupList(idxSelectedItem);
  985.         
  986.         // save cleanupstack init until LD
  987.         {
  988.     AUTO_PUSH_POP(pPopup);
  989.     pPopup->ConstructL(m_recentClips.raw_ptr());
  990.         }
  991. if (pPopup->ExecuteLD())
  992. {
  993.     // Launch the item that the user selected
  994.     if ((idxSelectedItem >= 0) && (idxSelectedItem < m_recentClips->NumURLs()))
  995.     {
  996.                 ActivatePlayViewL((m_recentClips->GetURL(idxSelectedItem))->URL());
  997.     }
  998. }
  999.     }
  1000.     else
  1001.     {
  1002.         CHXAvMessageDialog::DoAlertInfoL(CHXAvCleanString(R_RECENT_CLIPS_EMPTY)());
  1003.     }
  1004. }
  1005. /*
  1006.  * GetMediaStoreInfoL
  1007.  * ------------------
  1008.  * Return the list of media information..
  1009.  *
  1010.  */
  1011. const CHXAvVector<CHXAvMediaFolderInfoPtr>& 
  1012. CHXAvPlayerUI::GetMediaStoreInfoL(bool bForceUpdate)
  1013. {
  1014.     if( 0 == m_mediaStoreInfo.Nelements() || bForceUpdate )
  1015.     {
  1016.         UpdateMediaStoreInfoL();
  1017.     }
  1018.     return m_mediaStoreInfo;
  1019. }
  1020. /* 
  1021.  * UpdateMediaStoreInfoL
  1022.  * ---------------------
  1023.  * Rebuild media store list
  1024.  *
  1025.  */
  1026. void CHXAvPlayerUI::UpdateMediaStoreInfoL()
  1027. {
  1028.     m_mediaStoreInfo.Resize(0);
  1029.     CHXString strLocalMediaFolder = prefs::GetString(m_spEngineMgr->GetPrefs(), CHXAV_LocalMediaFolder);
  1030.     HXSYM_LEAVE_IF_TRUE(strLocalMediaFolder.IsEmpty());
  1031.     AppendMediaStoreInfoL(strLocalMediaFolder, CHXAvMediaFolderInfo::PATH_ENSURE);
  1032.     CHXString strMmcMediaFolder = prefs::GetString(m_spEngineMgr->GetPrefs(), CHXAV_MmcMediaFolder);
  1033.     if(!strMmcMediaFolder.IsEmpty())
  1034.     {
  1035.         AppendMediaStoreInfoL(strMmcMediaFolder, CHXAvMediaFolderInfo::PATH_OPTIONAL);
  1036.     }   
  1037. }
  1038. /*
  1039.  * AppendMediaStoreInfoL
  1040.  * ---------------------
  1041.  * Here we create each media store, and call routines to find out what's in those locations.
  1042.  *
  1043.  */
  1044. void 
  1045. CHXAvPlayerUI::AppendMediaStoreInfoL(const CHXString& strRootPath, CHXAvMediaFolderInfo::PathCreateType pathType)
  1046. {
  1047.     TFileName* pPath = CHXAvFile::AllocFileNameL(CHXAvCleanString(strRootPath)(), CHXAvFile::ntFolder);
  1048.     AUTO_PUSH_POP_DEL(pPath);
  1049.     CHXAvMediaFolderInfoPtr spInfo = new (ELeave) CHXAvMediaFolderInfo();
  1050.     CHXAvUtil::Append(m_mediaStoreInfo, spInfo);
  1051.     spInfo->InitL(*pPath, pathType);
  1052. }
  1053. ////////////////////////////////////////
  1054. //
  1055. // Guide can be specified in config/preferences as:
  1056. //
  1057. // 1) local file name relative to local guide folder path 
  1058. //        e.g., 'index.html', 'germanindex.wmlc'
  1059. //
  1060. // 3) http url 
  1061. //        e.g., 'http://www.real.com/mobile/home.html'
  1062. //
  1063. // In either case this returns a properly formed 'file' 
  1064. // or 'http' url.
  1065. //
  1066. TPtrC CHXAvPlayerUI::GetGuideUrlL(bool bForceUpdate)
  1067. {
  1068.     TPtrC out(KNullDesC);
  1069.     if( bForceUpdate )
  1070.     {
  1071.         // ensure url is reset
  1072.         m_spGuideUrl = 0;
  1073.     }
  1074.     if( !m_spGuideUrl )
  1075.     {
  1076.         DPRINTF(SYMP_INFO, ("GetGuideUrlL(): current locale is %dn", User::Language()));
  1077.         // look at 'guide'
  1078.         CHXString strGuide = prefs::GetString(m_spEngineMgr->GetPrefs(), CHXAV_Guide);
  1079.         if( !strGuide.IsEmpty() )
  1080.         {
  1081.             bool bLocalize = prefs::GetBool(m_spEngineMgr->GetPrefs(), CHXAV_GuideLocalize);
  1082.         
  1083.             // see if guide is specified as an 'http' url
  1084.             if(CHXAvUtil::IsHttpUrl(strGuide))
  1085.             {
  1086.                 // assume config entry is valid http url...
  1087.                 if( bLocalize )
  1088.                 {
  1089.                      // append '?locale=NN' to url to tell server to retrieve localized guide page
  1090.                     _LIT(KQuestionMark, "?");
  1091.                     _LIT(KGuideLocaleQuery,   "locale=%d");
  1092.                     const TLanguage locale = User::Language();
  1093.                     CHXAvCleanString urlText(strGuide);
  1094.                     CHXAvCleanString urlQuery(KGuideLocaleQuery, locale);
  1095.                     m_spGuideUrl = CHXAvStringUtils::AllocTextL(urlText(), KQuestionMark, urlQuery());
  1096.                 }
  1097.                 else
  1098.                 {
  1099.                     m_spGuideUrl = CHXAvStringUtils::AllocTextL(strGuide);
  1100.                 }
  1101.             }
  1102.             else
  1103.             {
  1104.                 // looks like we are dealing with a local guide
  1105.             
  1106.                 TFileName* pFullPathGuide = CHXAvFile::AllocFullPrefPathL(m_spEngineMgr->GetPrefs(), CHXAV_Guide);
  1107.                 HXSYM_LEAVE_IF_FALSE(pFullPathGuide != 0);
  1108.                 AUTO_PUSH_POP_DEL(pFullPathGuide);
  1109.                 if(bLocalize)
  1110.                 {
  1111.                    
  1112.                     // find localized version, based on TLanguage enum in extension (e.g., for '*.rsc',  '*.r01' == English, '*.r10' == American, etc.)
  1113.                     DPRINTF(SYMP_INFO, ("GetGuideUrlL(): default guide is '%s'n", dbg::CharPtr(*pFullPathGuide)()));
  1114.                 
  1115.                     // appears to require drive in path (despite docs); path is not modified if path is invalid
  1116.                     BaflUtils::NearestLanguageFile(iCoeEnv->FsSession(), *pFullPathGuide); 
  1117.                     DPRINTF(SYMP_INFO, ("GetGuideUrlL(): localized guide is '%s'n", dbg::CharPtr(*pFullPathGuide)()));
  1118.                 }
  1119.                 // ensure path exists
  1120.                 bool bExists = CHXAvFile::PathExists(*pFullPathGuide);
  1121.                 HX_ASSERT(bExists);
  1122.                 if(bExists)
  1123.                 {
  1124.                     // save path fixed up so it is a 'file:///' url
  1125.                     m_spGuideUrl = CHXAvFile::AllocFileUrlL(*pFullPathGuide);
  1126.                 }
  1127.             }
  1128.         }
  1129.     }
  1130.     if( m_spGuideUrl )
  1131.     {
  1132.         out.Set(*m_spGuideUrl);
  1133.     }
  1134.     
  1135.     DPRINTF(SYMP_INFO, ("GetGuideUrlL(): url is '%s'n", dbg::CharPtr(out)()));
  1136.     return out; 
  1137. }
  1138. #if(0)
  1139. ////////////////////////////////////////////////         
  1140. // shared data client notifier
  1141. void CHXAvPlayerUI::HandleNotifyL(const TUid uid, const TDesC& key, const TDesC& val)
  1142. {
  1143.     DPRINTF(SYMP_INFO, ("avPlayerUI::HandleNotifyL(): uid = 0x%08x, key = '%s', val = '%s'n", uid.iUid, dbg::CharPtr(key)(), dbg::CharPtr(val)()));
  1144.     // note: we should not get notifications in cases where we are the source of the change
  1145.     if(KSDUidSysAp == uid)
  1146.     {
  1147.         if (0 == key.CompareF(KSysApLightsControl))
  1148.         {
  1149.             if( !IsEqual(val, BacklightAlwaysOn) )
  1150.             {
  1151.                 DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::HandleNotifyL(): backlight resetn"));
  1152.                 // some events (e.g., incoming sms) reset backlight behavior; ensure this is set correctly
  1153.                 SetActivePlaybackState(m_bIsActivePlaybackState);
  1154.             }
  1155.         }
  1156.         else if(0 == key.CompareF(KSysApAlarmLightActive))
  1157.         {
  1158.             // also see RAlarmServer
  1159.             if( IsEqual(val, AlarmFlashing) )
  1160.             {
  1161.                 DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::HandleNotifyL(): alarm firingn"));
  1162.                 // handle this same way as if we loose app focus
  1163.                 CHXAvViewBase *pActiveView = static_cast<CHXAvViewBase *>(iView);
  1164.                 pActiveView->HandleLosePlayFocus();
  1165.             }
  1166.         }
  1167.         else if(0 == key.CompareF(KSysApMessageToneQuit))
  1168.         {
  1169.             if( IsEqual(val, MessageTonesOff) )
  1170.             {
  1171.                 // we get this when a message comes in in silent mode
  1172.                 DPRINTF(SYMP_INFO, ("CHXAvPlayerUI::HandleNotifyL(): msg tone offn"));
  1173.                 
  1174.                 // in silent mode this resets volume; now we (possibly) reset volume back
  1175.                 m_player->SetVolume(m_player->GetVolume());
  1176.             }
  1177.         }
  1178.     }
  1179. }
  1180. #endif
  1181. /*
  1182.  * GetRecentClipCount
  1183.  * ------------------
  1184.  * Returns the count of urls.
  1185.  *
  1186.  */
  1187. TInt
  1188. CHXAvPlayerUI::GetRecentClipCount() const
  1189. {
  1190.     TInt count = 0;
  1191.     if (m_recentClips)
  1192.     {
  1193. count = m_recentClips->NumURLs();
  1194.     }
  1195.     return count;
  1196. }