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

Symbian

开发平台:

C/C++

  1. /*============================================================================*
  2.  *
  3.  * (c) 1995-2002 RealNetworks, Inc. Patents pending. All rights reserved.
  4.  *
  5.  *============================================================================*/
  6. #include <eikcapc.h>
  7. #include <aknquerydialog.h>
  8. //#include <hlplch.h>
  9. #include "hxsym_debug.h"
  10. #include "chxavmisc.h"
  11. #include "chxavutil.h"
  12. #include "chxavcleanupstack.h"
  13. #include "chxavcleanstring.h"
  14. #include "chxavescapedstring.h"
  15. #include "player_uids.h"
  16. #include "chxaveditplaylistdialog.h"
  17. #include "realplayer.hrh"
  18. #include "hxsym_leaveutil.h"
  19. #include "realplayer.mbg"
  20. #include "r1p.hlp.hrh"
  21. CHXAvEditPlaylistDialog::CHXAvEditPlaylistDialog()
  22. : m_idNextItem(0)
  23. , m_pLastLineAdded(0)
  24. , m_bInEditMode(false)
  25. , m_bListAlteredFromPreDialogState(false)
  26. {
  27. }
  28. CHXAvEditPlaylistDialog::~CHXAvEditPlaylistDialog()
  29. {
  30.     m_file.Close();
  31. }
  32. ////////////////////////////////////////////
  33. //
  34. TInt CHXAvEditPlaylistDialog::SetPlaylistL(const TDesC& playListPath)
  35. {
  36.     TInt err = KErrGeneral;
  37.     // we don't allow empty/invalid playlists (for now)
  38.     CHXString strPath;
  39.     CHXAvStringUtils::DesToString(playListPath, strPath);
  40.     m_spPlaylist = CHXAvRAMParser::Parse(strPath);
  41.     if( m_spPlaylist && (0 != m_spPlaylist->Length()) )
  42.     {
  43.         // open/lock file while dialog is active
  44.         err = m_file.Open(CEikonEnv::Static()->FsSession(), 
  45.             playListPath, EFileWrite|EFileShareExclusive);
  46.     }
  47.     return err;
  48. }
  49. ////////////////////////////////////////////
  50. //
  51. void 
  52. CHXAvEditPlaylistDialog::PreLayoutDynInitL()
  53. {
  54.     PopulateL();
  55. }
  56. ////////////////////////////////////////////
  57. //
  58. void CHXAvEditPlaylistDialog::ProcessCommandL(TInt id)
  59. {
  60.     DPRINTF(SYMP_INFO, ("CHXAvEditPlaylistDialog::ProcessCommandL(): id = %dn", id));
  61.     switch(id)
  62.     {
  63.         case EAknFormCmdEdit:
  64.         {
  65.             HX_ASSERT(!m_bInEditMode);
  66.             m_bInEditMode = true;
  67.             CreateRestoreListL();
  68.             break;
  69.         }
  70.         case EAknFormCmdAdd:
  71.         case EAknFormCmdDelete:
  72.             //XXXLCM the delete case is hard because we get no notification if user says no to are you sure? we assume yes...
  73.             m_bListAlteredFromPreDialogState = true;
  74.             break;
  75.         case ERestorePlaylist:
  76.             DoRestorePreDialogStateL();
  77.             break;
  78.         case EAknCmdHelp:
  79.             {
  80.             //CCoeAppUi* pUi = static_cast<CCoeAppUi*>(iCoeEnv->AppUi());
  81.             //HlpLauncher::LaunchHelpApplicationL( iCoeEnv->WsSession(), pUi->AppHelpContextL() );
  82.             }
  83.             break;
  84.         default:
  85.             break;
  86.     }
  87.     
  88.     CAknForm::ProcessCommandL(id);
  89. }
  90. ////////////////////////////////////////////
  91. // check all urls for proper syntax
  92. bool CHXAvEditPlaylistDialog::VerifyFormL()
  93. {
  94.     return ForEachEdwinL(&CHXAvEditPlaylistDialog::VerifyUrlL);
  95. }
  96. ///////////////////////////////////////////
  97. //ForEachEdwinL helper
  98. bool CHXAvEditPlaylistDialog::WriteUrlL(TInt /*idx*/, CEikEdwin* pEdwin)
  99. {
  100.     HBufC* pText = pEdwin->GetTextInHBufL();
  101.     if(pText)
  102.     {
  103.         AUTO_PUSH_POP_DEL(pText);
  104.     
  105.         //bool bIsValid = CHXAvUtil::ValidURL(*pText);
  106.         const TUint cchNewLine = CHXAvUtil::litSize(CHXAvUtil::KNewline);
  107.         HBufC8* pText8 = HBufC8::NewL(pText->Length() + cchNewLine);
  108.         AUTO_PUSH_POP_DEL(pText8);
  109.         TPtr8 ptr = pText8->Des();
  110.         ptr.Copy(*pText); // note: converts
  111.         ptr.Append(CHXAvUtil::KNewline);
  112.     
  113.         m_file.Write(*pText8);
  114.     }
  115.     return true;
  116. }
  117. ////////////////////////////////////////////
  118. // confirm restore operation with user and do if user agrees
  119. void CHXAvEditPlaylistDialog::DoRestorePreDialogStateL()
  120. {
  121.     bool bDoRestore = CHXAvMessageDialog::DoQueryL(CHXAvCleanString(R_AVP_Q_RESTORE_PLAYLIST)(), CHXAvMessageDialog::QueryOkCancel);
  122.     if( bDoRestore )
  123.     {
  124.         // clear
  125.         for( TInt idx = EIdFirstLine; idx < m_idNextItem; ++idx )
  126.         {
  127.             // delete line with this id (if it exists)
  128.             CCoeControl* pControl = ControlOrNull(idx);
  129.             if(pControl)
  130.             {
  131.                 DeleteLine(idx, EFalse /*no redraw*/);
  132.             }
  133.         
  134.         }
  135.         // re-populate
  136.         PopulateL();
  137.         UpdatePageL(ETrue);
  138.         SaveFormDataL();
  139.         SetInitialCurrentLine();
  140.         m_bListAlteredFromPreDialogState = false;
  141.     }
  142. }
  143. ////////////////////////////////////////////
  144. // called after items are edited and 'yes' is selected by user
  145. // when prompted to save changes
  146. //
  147. TBool CHXAvEditPlaylistDialog::SaveFormDataL()
  148. {
  149.     DPRINTF(SYMP_INFO, ("CHXAvEditPlaylistDialog::SaveFormDataL(): writing filen"));
  150.     // done with these...
  151.     m_spRestoreList = 0; 
  152.     m_bListAlteredFromPreDialogState = true;
  153.     m_bInEditMode = false;
  154.     // write the file
  155.     TInt offset = 0;
  156.     m_file.Seek(ESeekStart, offset);
  157.     ForEachEdwinL(&CHXAvEditPlaylistDialog::WriteUrlL);
  158.     // set size based on current position
  159.     offset = 0;
  160.     m_file.Seek(ESeekCurrent, offset);
  161.     m_file.SetSize(offset);
  162.     // flush
  163.     HXSYM_LEAVE_IF_ERR(m_file.Flush());
  164.     
  165.     return ETrue;
  166. }
  167. ////////////////////////////////////////////
  168. // called when you go back from edit mode and when switch to new item in the list
  169. void CHXAvEditPlaylistDialog::PrepareForFocusTransitionL()
  170. {
  171.     DPRINTF(SYMP_INFO, ("CHXAvEditPlaylistDialog::PrepareForFocusTransitionL()n"));
  172.     CAknForm::PrepareForFocusTransitionL();
  173. };
  174. ///////////////////////////////////////////
  175. //
  176. bool CHXAvEditPlaylistDialog::ForEachEdwinL(PMFNForEach pfn)
  177. {
  178.     bool bGood = true;
  179.     TInt idxPage = ActivePageId();
  180.     TInt lineCount = GetNumberOfLinesOnPage(idxPage);
  181.     for( TInt idx = 0; idx < lineCount; ++idx )
  182.     {
  183.         CEikCaptionedControl* pLine = GetLineByLineAndPageIndex(idx, idxPage);
  184.         HX_ASSERT( (pLine->iId >= EIdFirstLine) && (pLine->iId < m_idNextItem) );
  185.         CEikEdwin* pEdwin = reinterpret_cast<CEikEdwin*>(pLine->iControl);
  186.         bGood = (this->*pfn)(idx, pEdwin);
  187.         if( !bGood )
  188.         {
  189.             break;
  190.         }
  191.     }
  192.     return bGood;
  193. }
  194. ///////////////////////////////////////////
  195. //ForEachEdwinL helper
  196. bool CHXAvEditPlaylistDialog::VerifyUrlL(TInt /*idx*/, CEikEdwin* pEdwin)
  197. {
  198.     bool bIsValid = false;
  199.     HBufC* pText = pEdwin->GetTextInHBufL();
  200.     if(pText)
  201.     {
  202.         AUTO_PUSH_POP_DEL(pText);
  203.         bIsValid = CHXAvUtil::IsValidUrl(*pText);
  204.         if(!bIsValid)
  205.         {
  206.             DPRINTF(SYMP_INFO, ("CHXAvEditPlaylistDialog::VerifyUrl(): bad url: %sn", dbg::CharPtr(*pText)()));
  207.         }
  208.     }
  209.     return bIsValid;
  210. }
  211. ///////////////////////////////////////////
  212. //ForEachEdwinL helper
  213. bool CHXAvEditPlaylistDialog::AppendRestoreListL(TInt /*idx*/, CEikEdwin* pEdwin)
  214. {
  215.     HX_ASSERT(m_spRestoreList);
  216.     HBufC* pText = pEdwin->GetTextInHBufL();
  217.     if(pText)
  218.     {
  219.         AUTO_PUSH_POP_DEL(pText);
  220.         m_spRestoreList->AppendL(*pText); // this copies buffer
  221.     }
  222.     else
  223.     {
  224.         m_spRestoreList->AppendL(KNullDesC); 
  225.     }
  226.     return true;
  227. }
  228. ///////////////////////////////////////////
  229. //ForEachEdwinL helper
  230. bool CHXAvEditPlaylistDialog::RestoreItemL(TInt idx, CEikEdwin* pEdwin)
  231. {
  232.     HX_ASSERT(idx < m_spRestoreList->MdcaCount());
  233.     TPtrC ptr = m_spRestoreList->MdcaPoint(idx);
  234.     pEdwin->SetTextL(&ptr);
  235.     return true;
  236. }
  237. ////////////////////////////////////////////
  238. // save list of items before going into edit-text-mode state,
  239. // in case we need to revert back; once in edit mode, user can
  240. // move from control to control and alter text (hence, we save
  241. // all edwin text, not just the text for currently selected edwin)
  242. void CHXAvEditPlaylistDialog::CreateRestoreListL()
  243. {
  244.     DPRINTF(SYMP_INFO, ("CHXAvEditPlaylistDialog::CreateRestoreListL(): saving backup itemsn"));
  245.     m_spRestoreList = new (ELeave) CDesCArrayFlat(20 /*granularity*/);
  246.     
  247.     ForEachEdwinL(&CHXAvEditPlaylistDialog::AppendRestoreListL);
  248. }
  249. ////////////////////////////////////////////
  250. // called after an item is edited and 'no' is selected by user
  251. // when prompted to save changes (or if we determine url is invalid after 'yes')
  252. //
  253. void CHXAvEditPlaylistDialog::DoNotSaveFormDataL()
  254. {
  255.     DPRINTF(SYMP_INFO, ("CHXAvEditPlaylistDialog::DoNotSaveFormDataL(): restoring itemsn"));
  256.     
  257.     // restore form data to pre-edit-mode state  
  258.     HX_ASSERT(m_spRestoreList);
  259.     ForEachEdwinL(&CHXAvEditPlaylistDialog::RestoreItemL);
  260.     // done with these...
  261.     m_spRestoreList = 0; 
  262.     CAknForm::DoNotSaveFormDataL();
  263. }
  264. ////////////////////////////////////////////
  265. // called when edit mode is exited
  266. TBool CHXAvEditPlaylistDialog::QuerySaveChangesL()
  267. {
  268.     DPRINTF(SYMP_INFO, ("CHXAvEditPlaylistDialog::QuerySaveChangesL()n"));
  269.     // prompts for save; expect SaveFormDataL() or DoNotSaveFormDataL() next...
  270.     return CAknForm::QuerySaveChangesL();
  271. }
  272. ////////////////////////////////////////////////////////
  273. //
  274. void CHXAvEditPlaylistDialog::DeleteCurrentItemL()
  275. {
  276.     DPRINTF(SYMP_INFO, ("CHXAvEditPlaylistDialog::DeleteCurrentItemL()n"));
  277.     // this posts confirmation dialog...
  278.     CAknForm::DeleteCurrentItemL();
  279. }
  280. ////////////////////////////////////////////////////////
  281. //
  282. void CHXAvEditPlaylistDialog::EditCurrentLabelL()
  283. {
  284.     DPRINTF(SYMP_INFO, ("CHXAvEditPlaylistDialog::EditCurrentLabelL()n"));
  285.     CAknForm::EditCurrentLabelL();
  286. }
  287. ////////////////////////////////////////////////////////
  288. //
  289. void CHXAvEditPlaylistDialog::AddItemL()
  290. {
  291.     DPRINTF(SYMP_INFO, ("CHXAvEditPlaylistDialog::AddItemL()n"));
  292.     
  293.     CHXAvCleanString caption(R_AVP_EDIT_PLAYLIST_LINK_CAPTION);
  294.     CHXAvCleanString field(R_AVP_EDIT_PLAYLIST_NEW_ITEM_TEXT);
  295.     bool bDoIt = false;
  296.     TInt idxInsert = -1; // at end by default
  297.     TInt count = GetNumberOfLinesOnPage(ActivePageId());
  298.     if( count > 0 )
  299.     {
  300.         CEikCaptionedControl* pLine = CurrentLine();
  301.         TInt idxCurrent = FindLineIndex(*pLine);
  302.         TInt idxSel = 0;
  303.         CAknListQueryDialog* pDlg = new (ELeave) CAknListQueryDialog(&idxSel);
  304.         TInt ret = pDlg->ExecuteLD(R_AVP_SELECT_PLAYLIST_POS_DLG);
  305.         if(ret != 0)
  306.         {
  307.             bDoIt = true;
  308.             // before = 0; after = 1
  309.             idxInsert = (idxSel == 0) ? idxCurrent : idxCurrent + 1;        
  310.         }
  311.     }
  312.     else
  313.     {
  314.         // insert at end
  315.         bDoIt = true;
  316.     }
  317.     if( bDoIt )
  318.     {
  319.         m_bListAlteredFromPreDialogState = true;
  320.         InsertItemL(caption(), field(), idxInsert);
  321.         UpdatePageL(ETrue);
  322.     }
  323. }
  324. ////////////////////////////////////////////////////////
  325. //
  326. void CHXAvEditPlaylistDialog::DynInitMenuPaneL( TInt id, CEikMenuPane* pPane )
  327. {
  328.     DPRINTF(SYMP_INFO, ("CHXAvEditPlaylistDialog::DynInitMenuPaneL()n"));
  329.     CAknForm::DynInitMenuPaneL( id, pPane );
  330.     // see avkon.hrh
  331.     if ( id == R_AVKON_FORM_MENUPANE )
  332.     {
  333.         // enable add; customize text
  334.         pPane->SetItemDimmed(EAknFormCmdAdd, EFalse);
  335.         pPane->SetItemTextL(EAknFormCmdAdd, CHXAvCleanString(R_AVP_EDITPLAYLIST_ADD_ITEM)());
  336.         TInt idxPage = ActivePageId();
  337.         TInt lineCount = GetNumberOfLinesOnPage(idxPage);
  338.         if( lineCount > 0 )
  339.         {
  340.             // enable delete; customize text
  341.             pPane->SetItemDimmed(EAknFormCmdDelete, EFalse);
  342.             pPane->SetItemTextL(EAknFormCmdDelete, CHXAvCleanString(R_AVP_EDITPLAYLIST_DEL_ITEM)());
  343.         }
  344.         else
  345.         {
  346.             // disable delete
  347.             pPane->SetItemDimmed(EAknFormCmdDelete, ETrue);
  348.         }
  349.         // always disable 'edit label'
  350.         pPane->SetItemDimmed(EAknFormCmdLabel, ETrue);
  351.         if(!m_bInEditMode && m_bListAlteredFromPreDialogState)
  352.         {
  353.             // add 'revert to pre-dialog state' menu item (note: this restore is not same as 'restore list' restore)
  354.             CHXAvMisc::AddMenuItemL(pPane, ERestorePlaylist, R_AVP_M_RESTORE);
  355.         }
  356.         // help menu item (goes last)
  357.         CHXAvMisc::AddMenuItemL(pPane, EAknCmdHelp, R_AVP_MENU_HELP);
  358.         CHXAvMisc::InitHelpMenuItem(pPane);
  359.         
  360.     }
  361. }
  362. ////////////////////////////////////////////////////////
  363. // called for *all* cba presses
  364. TBool CHXAvEditPlaylistDialog::OkToExitL(TInt aButtonId)
  365. {
  366.     bool bAllow = true;
  367.     if(EAknSoftkeyBack == aButtonId)
  368.     {
  369.         if(!m_bInEditMode)
  370.         {
  371.             if( !VerifyFormL() )
  372.             {
  373.                 // warn user
  374.                 bAllow = CHXAvMessageDialog::DoQueryL(CHXAvCleanString(R_AVP_Q_CONTINUE_WITH_BAD_PLAYLIST)(), CHXAvMessageDialog::QueryOkCancel);
  375.             }
  376.             // in case add/delete fields occurred
  377.             SaveFormDataL();
  378.         }
  379.         else
  380.         {
  381.             m_bInEditMode = false;
  382.         }
  383.     }
  384.         
  385.     return bAllow ? CAknForm::OkToExitL(aButtonId) : EFalse;
  386. }
  387. ////////////////////////////////////////////
  388. // CCoeControl
  389. void CHXAvEditPlaylistDialog::GetHelpContext(TCoeHelpContext& aContext) const
  390. {
  391.     aContext = TCoeHelpContext( CHXAvMisc::KHelpUID, KRP_HLP_EDIT_LINK );
  392. }
  393. ////////////////////////////////////////////////////////
  394. //
  395. TKeyResponse CHXAvEditPlaylistDialog::OfferKeyEventL (const TKeyEvent &aKeyEvent, TEventCode aType)
  396. {
  397.     TKeyResponse response = EKeyWasNotConsumed;
  398.     if(EEventKey == aType)
  399.     {
  400.         switch(aKeyEvent.iCode)
  401.         {
  402.         case EKeyOK:
  403.         case EKeyEnter:
  404.             response = EKeyWasConsumed;
  405.             ProcessCommandL(EAknFormCmdEdit); 
  406.             break;
  407.         default:
  408.             // everything else goes to the form
  409.             response = CAknForm::OfferKeyEventL(aKeyEvent, aType);
  410.         }
  411.     }
  412.     else
  413.     {
  414.         response = CAknForm::OfferKeyEventL(aKeyEvent, aType);
  415.     }
  416.     return response;
  417.     
  418. }
  419. ////////////////////////////////////////////////////////
  420. // fill up form with playlist items
  421. void 
  422. CHXAvEditPlaylistDialog::PopulateL()
  423. {
  424.     m_idNextItem = EIdFirstLine;
  425.     m_pLastLineAdded = 0;
  426.     for(CHXAvPlaylistItr iter = *m_spPlaylist; iter.More(); iter.Next())
  427.     {
  428.         const CHXAvURLRep& url = iter.Current();
  429.         // make sure url is unquoted, readable form
  430.         //utString str = url.EscapedPath().GetUnEscapedStr();
  431.         CHXAvEscapedString escUrl = CHXAvEscapedString(url.String());
  432.         CHXString niceUrl = escUrl.GetUnEscapedStr();
  433.         CHXAvCleanString caption(R_AVP_EDIT_PLAYLIST_LINK_CAPTION);
  434.         CHXAvCleanString field(niceUrl);
  435.         InsertItemL(caption(), field());
  436.     }
  437. }
  438. ////////////////////////////////////////////////////////
  439. // helper; called from PopulateL()
  440. void
  441. CHXAvEditPlaylistDialog::InsertItemL(const TDesC& caption, const TDesC& text, TInt idxPos)
  442. {
  443.     TInt idxPage = ActivePageId();
  444.     TInt idxLine = (idxPos != -1) ? idxPos : GetNumberOfLinesOnPage(idxPage);
  445.     DPRINTF(SYMP_INFO, ("CHXAvEditPlaylistDialog::InsertItemL(): adding at idx %dn", idxLine));
  446.     // inserts a new line without doing auto redraw (like CreateLineByTypeL)
  447.     InsertLineL(idxLine, R_AVP_FORM_EDWIN, idxPage);
  448.     // get the line and control we just added (note that id is placeholder)
  449.     CEikCaptionedControl* pLine = Line(EIdInsertLinePlaceHolder);
  450.     CEikEdwin* pEditWin = reinterpret_cast<CEikEdwin*>(pLine->iControl);
  451.     //pEditWin->SetTextLimit(cchLimit);
  452.     pEditWin->SetTextL(&text);
  453.     pLine->SetCaptionL(KNullDesC);
  454.     pLine->SetCaptionL(caption);
  455.     pLine->iId = m_idNextItem++;
  456.     
  457.     // pLine->SetDividerAfter(ETrue);
  458.     TFileName* pImageFilePath = CHXAvFile::AllocAppFolderPathL(CHXAvUtil::KImagesMBMName);
  459.     AUTO_PUSH_POP_DEL(pImageFilePath);
  460.     // XXXLCM
  461.     pLine->SetBitmapFromFileL(*pImageFilePath, EMbmRealplayerFile_network, EMbmRealplayerFile_network_mask); 
  462.     
  463.     // ready to draw
  464.     pLine->ActivateL();
  465.     m_pLastLineAdded = pLine;
  466. }