5572c0b88f87b427d9c5066b1342ca552c33630f
[vuplus_xbmc] / xbmc / pvr / dialogs / GUIDialogPVRChannelManager.cpp
1 /*
2  *      Copyright (C) 2012-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "GUIDialogPVRChannelManager.h"
22
23 #include "FileItem.h"
24 #include "GUIDialogPVRGroupManager.h"
25 #include "dialogs/GUIDialogFileBrowser.h"
26 #include "guilib/GUIKeyboardFactory.h"
27 #include "dialogs/GUIDialogOK.h"
28 #include "dialogs/GUIDialogProgress.h"
29 #include "dialogs/GUIDialogSelect.h"
30 #include "dialogs/GUIDialogYesNo.h"
31 #include "guilib/GUIEditControl.h"
32 #include "guilib/GUIRadioButtonControl.h"
33 #include "guilib/GUISpinControlEx.h"
34 #include "guilib/GUIWindowManager.h"
35 #include "guilib/Key.h"
36 #include "guilib/LocalizeStrings.h"
37 #include "profiles/ProfilesManager.h"
38 #include "pvr/PVRManager.h"
39 #include "pvr/channels/PVRChannelGroupsContainer.h"
40 #include "pvr/addons/PVRClients.h"
41 #include "settings/Settings.h"
42 #include "storage/MediaManager.h"
43
44 #define BUTTON_OK                 4
45 #define BUTTON_APPLY              5
46 #define BUTTON_CANCEL             6
47 #define RADIOBUTTON_ACTIVE        7
48 #define EDIT_NAME                 8
49 #define BUTTON_CHANNEL_LOGO       9
50 #define IMAGE_CHANNEL_LOGO        10
51 #define RADIOBUTTON_USEEPG        12
52 #define SPIN_EPGSOURCE_SELECTION  13
53 #define RADIOBUTTON_PARENTAL_LOCK 14
54 #define CONTROL_LIST_CHANNELS     20
55 #define BUTTON_GROUP_MANAGER      30
56 #define BUTTON_EDIT_CHANNEL       31
57 #define BUTTON_DELETE_CHANNEL     32
58 #define BUTTON_NEW_CHANNEL        33
59 #define BUTTON_RADIO_TV           34
60
61 using namespace std;
62 using namespace PVR;
63
64 CGUIDialogPVRChannelManager::CGUIDialogPVRChannelManager(void) :
65     CGUIDialog(WINDOW_DIALOG_PVR_CHANNEL_MANAGER, "DialogPVRChannelManager.xml"),
66     m_bIsRadio(false),
67     m_bMovingMode(false),
68     m_bContainsChanges(false),
69     m_iSelected(0),
70     m_channelItems(new CFileItemList)
71 {
72 }
73
74 CGUIDialogPVRChannelManager::~CGUIDialogPVRChannelManager(void)
75 {
76   delete m_channelItems;
77 }
78
79 bool CGUIDialogPVRChannelManager::OnActionMove(const CAction &action)
80 {
81   bool bReturn(false);
82   int iActionId = action.GetID();
83   if (GetFocusedControlID() == CONTROL_LIST_CHANNELS &&
84       (iActionId == ACTION_MOVE_DOWN || iActionId == ACTION_MOVE_UP ||
85        iActionId == ACTION_PAGE_DOWN || iActionId == ACTION_PAGE_UP))
86   {
87     bReturn = true;
88     if (!m_bMovingMode)
89     {
90       CGUIDialog::OnAction(action);
91       int iSelected = m_viewControl.GetSelectedItem();
92       if (iSelected != m_iSelected)
93       {
94         m_iSelected = iSelected;
95         SetData(m_iSelected);
96       }
97     }
98     else
99     {
100       CStdString strNumber;
101       CGUIDialog::OnAction(action);
102
103       bool bMoveUp        = iActionId == ACTION_PAGE_UP || iActionId == ACTION_MOVE_UP;
104       unsigned int iLines = bMoveUp ? abs(m_iSelected - m_viewControl.GetSelectedItem()) : 1;
105       bool bOutOfBounds   = bMoveUp ? m_iSelected <= 0  : m_iSelected >= m_channelItems->Size() - 1;
106       if (bOutOfBounds)
107       {
108         bMoveUp = !bMoveUp;
109         iLines  = m_channelItems->Size() - 1;
110       }
111
112       for (unsigned int iLine = 0; iLine < iLines; iLine++)
113       {
114         unsigned int iNewSelect = bMoveUp ? m_iSelected - 1 : m_iSelected + 1;
115         if (m_channelItems->Get(iNewSelect)->GetProperty("Number").asString() != "-")
116         {
117           strNumber.Format("%i", m_iSelected+1);
118           m_channelItems->Get(iNewSelect)->SetProperty("Number", strNumber);
119           strNumber.Format("%i", iNewSelect+1);
120           m_channelItems->Get(m_iSelected)->SetProperty("Number", strNumber);
121         }
122         m_channelItems->Swap(iNewSelect, m_iSelected);
123         m_iSelected = iNewSelect;
124       }
125
126       m_viewControl.SetItems(*m_channelItems);
127       m_viewControl.SetSelectedItem(m_iSelected);
128     }
129   }
130
131   return bReturn;
132 }
133
134 bool CGUIDialogPVRChannelManager::OnAction(const CAction& action)
135 {
136   return OnActionMove(action) ||
137          CGUIDialog::OnAction(action);
138 }
139
140 void CGUIDialogPVRChannelManager::OnInitWindow()
141 {
142   CGUIDialog::OnInitWindow();
143
144   m_iSelected = 0;
145   m_bIsRadio = false;
146   m_bMovingMode = false;
147   m_bContainsChanges = false;
148   SetProperty("IsRadio", "");
149   Update();
150   SetData(m_iSelected);
151 }
152
153 void CGUIDialogPVRChannelManager::OnDeinitWindow(int nextWindowID)
154 {
155   Clear();
156
157   CGUIDialog::OnDeinitWindow(nextWindowID);
158 }
159
160 bool CGUIDialogPVRChannelManager::OnClickListChannels(CGUIMessage &message)
161 {
162   if (!m_bMovingMode)
163   {
164     int iAction = message.GetParam1();
165     int iItem = m_viewControl.GetSelectedItem();
166
167     /* Check file item is in list range and get his pointer */
168     if (iItem < 0 || iItem >= (int)m_channelItems->Size()) return true;
169
170     /* Process actions */
171     if (iAction == ACTION_SELECT_ITEM || iAction == ACTION_CONTEXT_MENU || iAction == ACTION_MOUSE_RIGHT_CLICK)
172     {
173       /* Show Contextmenu */
174       OnPopupMenu(iItem);
175
176       return true;
177     }
178   }
179   else
180   {
181     CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
182     if (pItem)
183     {
184       pItem->SetProperty("Changed", true);
185       pItem->Select(false);
186       m_bMovingMode = false;
187       m_bContainsChanges = true;
188       return true;
189     }
190   }
191
192   return false;
193 }
194
195 bool CGUIDialogPVRChannelManager::OnClickButtonOK(CGUIMessage &message)
196 {
197   SaveList();
198   Close();
199   return true;
200 }
201
202 bool CGUIDialogPVRChannelManager::OnClickButtonApply(CGUIMessage &message)
203 {
204   SaveList();
205   return true;
206 }
207
208 bool CGUIDialogPVRChannelManager::OnClickButtonCancel(CGUIMessage &message)
209 {
210   Close();
211   return true;
212 }
213
214 bool CGUIDialogPVRChannelManager::OnClickButtonRadioTV(CGUIMessage &message)
215 {
216   if (m_bContainsChanges)
217   {
218     CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
219     if (!pDialog)
220       return true;
221
222     pDialog->SetHeading(20052);
223     pDialog->SetLine(0, "");
224     pDialog->SetLine(1, 19212);
225     pDialog->SetLine(2, 20103);
226     pDialog->DoModal();
227
228     if (pDialog->IsConfirmed())
229       SaveList();
230   }
231
232   m_iSelected = 0;
233   m_bMovingMode = false;
234   m_bContainsChanges = false;
235   m_bIsRadio = !m_bIsRadio;
236   SetProperty("IsRadio", m_bIsRadio ? "true" : "");
237   Update();
238   SetData(m_iSelected);
239   return true;
240 }
241
242 bool CGUIDialogPVRChannelManager::OnClickButtonRadioActive(CGUIMessage &message)
243 {
244   CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_ACTIVE);
245   if (pRadioButton)
246   {
247     CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
248     if (pItem)
249     {
250       pItem->SetProperty("Changed", true);
251       pItem->SetProperty("ActiveChannel", pRadioButton->IsSelected());
252       m_bContainsChanges = true;
253       Renumber();
254       return true;
255     }
256   }
257
258   return false;
259 }
260
261 bool CGUIDialogPVRChannelManager::OnClickButtonRadioParentalLocked(CGUIMessage &message)
262 {
263   CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_PARENTAL_LOCK);
264
265   // ask for PIN first
266   if (!g_PVRManager.CheckParentalPIN(g_localizeStrings.Get(19262).c_str()))
267   {
268     pRadioButton->SetSelected(!pRadioButton->IsSelected());
269     return false;
270   }
271
272   if (pRadioButton)
273   {
274     CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
275     if (pItem)
276     {
277       pItem->SetProperty("Changed", true);
278       pItem->SetProperty("ParentalLocked", pRadioButton->IsSelected());
279       m_bContainsChanges = true;
280       Renumber();
281       return true;
282     }
283   }
284
285   return false;
286 }
287
288 bool CGUIDialogPVRChannelManager::OnClickButtonEditName(CGUIMessage &message)
289 {
290   CGUIEditControl *pEdit = (CGUIEditControl *)GetControl(EDIT_NAME);
291   if (pEdit)
292   {
293     CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
294     if (pItem)
295     {
296       pItem->SetProperty("Changed", true);
297       pItem->SetProperty("Name", pEdit->GetLabel2());
298       m_bContainsChanges = true;
299
300       return true;
301     }
302   }
303
304   return false;
305 }
306
307 bool CGUIDialogPVRChannelManager::OnClickButtonChannelLogo(CGUIMessage &message)
308 {
309   CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
310   if (!pItem)
311     return false;
312   if (CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked())
313     return false;
314   else if (!g_passwordManager.IsMasterLockUnlocked(true))
315     return false;
316
317   // setup our thumb list
318   CFileItemList items;
319
320   // add the current thumb, if available
321   if (!pItem->GetProperty("Icon").asString().empty())
322   {
323     CFileItemPtr current(new CFileItem("thumb://Current", false));
324     current->SetArt("thumb", pItem->GetPVRChannelInfoTag()->IconPath());
325     current->SetLabel(g_localizeStrings.Get(20016));
326     items.Add(current);
327   }
328   else if (pItem->HasArt("thumb"))
329   { // already have a thumb that the share doesn't know about - must be a local one, so we mayaswell reuse it.
330     CFileItemPtr current(new CFileItem("thumb://Current", false));
331     current->SetArt("thumb", pItem->GetArt("thumb"));
332     current->SetLabel(g_localizeStrings.Get(20016));
333     items.Add(current);
334   }
335
336   // and add a "no thumb" entry as well
337   CFileItemPtr nothumb(new CFileItem("thumb://None", false));
338   nothumb->SetIconImage(pItem->GetIconImage());
339   nothumb->SetLabel(g_localizeStrings.Get(20018));
340   items.Add(nothumb);
341
342   CStdString strThumb;
343   VECSOURCES shares;
344   if (CSettings::Get().GetString("pvrmenu.iconpath") != "")
345   {
346     CMediaSource share1;
347     share1.strPath = CSettings::Get().GetString("pvrmenu.iconpath");
348     share1.strName = g_localizeStrings.Get(19018);
349     shares.push_back(share1);
350   }
351   g_mediaManager.GetLocalDrives(shares);
352   if (!CGUIDialogFileBrowser::ShowAndGetImage(items, shares, g_localizeStrings.Get(1030), strThumb))
353     return false;
354
355   if (strThumb == "thumb://Current")
356     return true;
357
358   if (strThumb == "thumb://None")
359     strThumb = "";
360
361   pItem->SetProperty("Icon", strThumb);
362   pItem->SetProperty("Changed", true);
363   m_bContainsChanges = true;
364   return true;
365 }
366
367 bool CGUIDialogPVRChannelManager::OnClickButtonUseEPG(CGUIMessage &message)
368 {
369   CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_USEEPG);
370   if (pRadioButton)
371   {
372     CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
373     if (pItem)
374     {
375       pItem->SetProperty("Changed", true);
376       pItem->SetProperty("UseEPG", pRadioButton->IsSelected());
377       m_bContainsChanges = true;
378
379       return true;
380     }
381   }
382
383   return false;
384 }
385
386 bool CGUIDialogPVRChannelManager::OnClickEPGSourceSpin(CGUIMessage &message)
387 {
388   // TODO: Add EPG scraper support
389   return true;
390 //  CGUISpinControlEx *pSpin = (CGUISpinControlEx *)GetControl(SPIN_EPGSOURCE_SELECTION);
391 //  if (pSpin)
392 //  {
393 //    CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
394 //    if (pItem)
395 //    {
396 //      pItem->SetProperty("EPGSource", (int)0);
397 //      pItem->SetProperty("Changed", true);
398 //      m_bContainsChanges = true;
399 //      return true;
400 //    }
401 //  }
402 }
403
404 bool CGUIDialogPVRChannelManager::OnClickButtonGroupManager(CGUIMessage &message)
405 {
406   /* Load group manager dialog */
407   CGUIDialogPVRGroupManager* pDlgInfo = (CGUIDialogPVRGroupManager*)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_GROUP_MANAGER);
408   if (!pDlgInfo)
409     return false;
410
411   pDlgInfo->SetRadio(m_bIsRadio);
412
413   /* Open dialog window */
414   pDlgInfo->DoModal();
415
416   Update();
417   return true;
418 }
419
420 bool CGUIDialogPVRChannelManager::OnClickButtonEditChannel(CGUIMessage &message)
421 {
422   CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
423   if (!pItem)
424     return false;
425
426   if (pItem->GetProperty("Virtual").asBoolean())
427   {
428     CStdString strURL = pItem->GetProperty("StreamURL").asString();
429     if (CGUIKeyboardFactory::ShowAndGetInput(strURL, g_localizeStrings.Get(19214), false))
430       pItem->SetProperty("StreamURL", strURL);
431     return true;
432   }
433
434   CGUIDialogOK::ShowAndGetInput(19033,19038,0,0);
435   return true;
436 }
437
438 bool CGUIDialogPVRChannelManager::OnClickButtonDeleteChannel(CGUIMessage &message)
439 {
440   CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
441   if (!pItem)
442     return false;
443
444   CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
445   if (!pDialog)
446     return true;
447
448   pDialog->SetHeading(19211);
449   pDialog->SetLine(0, "");
450   pDialog->SetLine(1, 750);
451   pDialog->SetLine(2, "");
452   pDialog->DoModal();
453
454   if (pDialog->IsConfirmed())
455   {
456     if (pItem->GetProperty("Virtual").asBoolean())
457     {
458       pItem->GetPVRChannelInfoTag()->SetVirtual(true);
459       m_channelItems->Remove(m_iSelected);
460       m_viewControl.SetItems(*m_channelItems);
461       Renumber();
462       return true;
463     }
464     CGUIDialogOK::ShowAndGetInput(19033,19038,0,0);
465   }
466   return true;
467 }
468
469 bool CGUIDialogPVRChannelManager::OnClickButtonNewChannel(CGUIMessage &message)
470 {
471   std::vector<long> clients;
472
473   CGUIDialogSelect* pDlgSelect = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
474   if (!pDlgSelect)
475     return false;
476
477   pDlgSelect->SetHeading(19213); // Select Client
478   pDlgSelect->Add(g_localizeStrings.Get(19209));
479   clients.push_back(PVR_VIRTUAL_CLIENT_ID);
480
481   PVR_CLIENTMAP clientMap;
482   if (g_PVRClients->GetConnectedClients(clientMap) > 0)
483   {
484     PVR_CLIENTMAP_ITR itr;
485     for (itr = clientMap.begin() ; itr != clientMap.end(); itr++)
486     {
487       clients.push_back((*itr).first);
488       pDlgSelect->Add((*itr).second->Name());
489     }
490   }
491   pDlgSelect->DoModal();
492
493   int selection = pDlgSelect->GetSelectedLabel();
494   if (selection >= 0 && selection <= (int) clients.size())
495   {
496     int clientID = clients[selection];
497     if (clientID == PVR_VIRTUAL_CLIENT_ID)
498     {
499       CStdString strURL = "";
500       if (CGUIKeyboardFactory::ShowAndGetInput(strURL, g_localizeStrings.Get(19214), false))
501       {
502         if (!strURL.IsEmpty())
503         {
504           CPVRChannel *newchannel = new CPVRChannel(m_bIsRadio);
505           newchannel->SetChannelName(g_localizeStrings.Get(19204));
506           newchannel->SetEPGEnabled(false);
507           newchannel->SetVirtual(true);
508           newchannel->SetStreamURL(strURL);
509           newchannel->SetClientID(PVR_VIRTUAL_CLIENT_ID);
510           if (g_PVRChannelGroups->CreateChannel(*newchannel))
511             g_PVRChannelGroups->GetGroupAll(m_bIsRadio)->Persist();
512
513           CFileItemPtr channel(new CFileItem(*newchannel));
514           if (channel)
515           {
516             channel->SetProperty("ActiveChannel", true);
517             channel->SetProperty("Name", g_localizeStrings.Get(19204));
518             channel->SetProperty("UseEPG", false);
519             channel->SetProperty("Icon", newchannel->IconPath());
520             channel->SetProperty("EPGSource", (int)0);
521             channel->SetProperty("ClientName", g_localizeStrings.Get(19209));
522             channel->SetProperty("ParentalLocked", false);
523
524             m_channelItems->AddFront(channel, m_iSelected);
525             m_viewControl.SetItems(*m_channelItems);
526             Renumber();
527           }
528         }
529       }
530     }
531     else
532     {
533       CGUIDialogOK::ShowAndGetInput(19033,19038,0,0);
534     }
535   }
536   return true;
537 }
538
539 bool CGUIDialogPVRChannelManager::OnMessageClick(CGUIMessage &message)
540 {
541   int iControl = message.GetSenderId();
542   switch(iControl)
543   {
544   case CONTROL_LIST_CHANNELS:
545     return OnClickListChannels(message);
546   case BUTTON_OK:
547     return OnClickButtonOK(message);
548   case BUTTON_APPLY:
549     return OnClickButtonApply(message);
550   case BUTTON_CANCEL:
551     return OnClickButtonCancel(message);
552   case BUTTON_RADIO_TV:
553     return OnClickButtonRadioTV(message);
554   case RADIOBUTTON_ACTIVE:
555     return OnClickButtonRadioActive(message);
556   case RADIOBUTTON_PARENTAL_LOCK:
557     return OnClickButtonRadioParentalLocked(message);
558   case EDIT_NAME:
559     return OnClickButtonEditName(message);
560   case BUTTON_CHANNEL_LOGO:
561     return OnClickButtonChannelLogo(message);
562   case RADIOBUTTON_USEEPG:
563     return OnClickButtonUseEPG(message);
564   case SPIN_EPGSOURCE_SELECTION:
565     return OnClickEPGSourceSpin(message);
566   case BUTTON_GROUP_MANAGER:
567     return OnClickButtonGroupManager(message);
568   case BUTTON_EDIT_CHANNEL:
569     return OnClickButtonEditChannel(message);
570   case BUTTON_DELETE_CHANNEL:
571     return OnClickButtonDeleteChannel(message);
572   case BUTTON_NEW_CHANNEL:
573     return OnClickButtonNewChannel(message);
574   default:
575     return false;
576   }
577 }
578
579 bool CGUIDialogPVRChannelManager::OnMessage(CGUIMessage& message)
580 {
581   unsigned int iMessage = message.GetMessage();
582
583   switch (iMessage)
584   {
585     case GUI_MSG_CLICKED:
586       return OnMessageClick(message);
587   }
588
589   return CGUIDialog::OnMessage(message);
590 }
591
592 void CGUIDialogPVRChannelManager::OnWindowLoaded(void)
593 {
594   CGUIDialog::OnWindowLoaded();
595
596   m_viewControl.Reset();
597   m_viewControl.SetParentWindow(GetID());
598   m_viewControl.AddView(GetControl(CONTROL_LIST_CHANNELS));
599 }
600
601 void CGUIDialogPVRChannelManager::OnWindowUnload(void)
602 {
603   CGUIDialog::OnWindowUnload();
604   m_viewControl.Reset();
605 }
606
607 CFileItemPtr CGUIDialogPVRChannelManager::GetCurrentListItem(int offset)
608 {
609   return m_channelItems->Get(m_iSelected);
610 }
611
612 bool CGUIDialogPVRChannelManager::OnPopupMenu(int iItem)
613 {
614   // popup the context menu
615   // grab our context menu
616   CContextButtons buttons;
617
618   // mark the item
619   if (iItem >= 0 && iItem < m_channelItems->Size())
620     m_channelItems->Get(iItem)->Select(true);
621   else
622     return false;
623
624   CFileItemPtr pItem = m_channelItems->Get(iItem);
625   if (!pItem)
626     return false;
627
628   buttons.Add(CONTEXT_BUTTON_MOVE, 116);              /* Move channel up or down */
629   if (pItem->GetProperty("Virtual").asBoolean())
630     buttons.Add(CONTEXT_BUTTON_EDIT_SOURCE, 1027);    /* Edit virtual channel URL */
631
632   int choice = CGUIDialogContextMenu::ShowAndGetChoice(buttons);
633
634   // deselect our item
635   if (iItem >= 0 && iItem < m_channelItems->Size())
636     m_channelItems->Get(iItem)->Select(false);
637
638   if (choice < 0)
639     return false;
640
641   return OnContextButton(iItem, (CONTEXT_BUTTON)choice);
642 }
643
644 bool CGUIDialogPVRChannelManager::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
645 {
646   /* Check file item is in list range and get his pointer */
647   if (itemNumber < 0 || itemNumber >= (int)m_channelItems->Size()) return false;
648
649   CFileItemPtr pItem = m_channelItems->Get(itemNumber);
650   if (!pItem)
651     return false;
652
653   if (button == CONTEXT_BUTTON_MOVE)
654   {
655     m_bMovingMode = true;
656     pItem->Select(true);
657   }
658   else if (button == CONTEXT_BUTTON_EDIT_SOURCE)
659   {
660     CStdString strURL = pItem->GetProperty("StreamURL").asString();
661     if (CGUIKeyboardFactory::ShowAndGetInput(strURL, g_localizeStrings.Get(19214), false))
662       pItem->SetProperty("StreamURL", strURL);
663   }
664   return true;
665 }
666
667 void CGUIDialogPVRChannelManager::SetData(int iItem)
668 {
669   CGUIEditControl        *pEdit;
670   CGUIRadioButtonControl *pRadioButton;
671
672   /* Check file item is in list range and get his pointer */
673   if (iItem < 0 || iItem >= (int)m_channelItems->Size()) return;
674
675   CFileItemPtr pItem = m_channelItems->Get(iItem);
676   if (!pItem)
677     return;
678
679   pEdit = (CGUIEditControl *)GetControl(EDIT_NAME);
680   if (pEdit)
681   {
682     pEdit->SetLabel2(pItem->GetProperty("Name").asString());
683     pEdit->SetInputType(CGUIEditControl::INPUT_TYPE_TEXT, 19208);
684   }
685
686   pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_ACTIVE);
687   if (pRadioButton) pRadioButton->SetSelected(pItem->GetProperty("ActiveChannel").asBoolean());
688
689   pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_USEEPG);
690   if (pRadioButton) pRadioButton->SetSelected(pItem->GetProperty("UseEPG").asBoolean());
691
692   pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_PARENTAL_LOCK);
693   if (pRadioButton) pRadioButton->SetSelected(pItem->GetProperty("ParentalLocked").asBoolean());
694 }
695
696 void CGUIDialogPVRChannelManager::Update()
697 {
698   // lock our display, as this window is rendered from the player thread
699   g_graphicsContext.Lock();
700   m_viewControl.SetCurrentView(CONTROL_LIST_CHANNELS);
701
702   // empty the lists ready for population
703   Clear();
704
705   CPVRChannelGroupPtr channels = g_PVRChannelGroups->GetGroupAll(m_bIsRadio);
706
707   // No channels available, nothing to do.
708   if(!channels)
709     return;
710
711   for (int iChannelPtr = 0; iChannelPtr < channels->Size(); iChannelPtr++)
712   {
713     CFileItemPtr channelFile = channels->GetByIndex(iChannelPtr);
714     if (!channelFile || !channelFile->HasPVRChannelInfoTag())
715       continue;
716     const CPVRChannel *channel = channelFile->GetPVRChannelInfoTag();
717
718     channelFile->SetProperty("ActiveChannel", !channel->IsHidden());
719     channelFile->SetProperty("Name", channel->ChannelName());
720     channelFile->SetProperty("UseEPG", channel->EPGEnabled());
721     channelFile->SetProperty("Icon", channel->IconPath());
722     channelFile->SetProperty("EPGSource", (int)0);
723     channelFile->SetProperty("ParentalLocked", channel->IsLocked());
724     CStdString number; number.Format("%i", channel->ChannelNumber());
725     channelFile->SetProperty("Number", number);
726
727     if (channel->IsVirtual())
728     {
729       channelFile->SetProperty("Virtual", true);
730       channelFile->SetProperty("StreamURL", channel->StreamURL());
731     }
732
733     CStdString clientName;
734     if (channel->ClientID() == PVR_VIRTUAL_CLIENT_ID) /* XBMC internal */
735       clientName = g_localizeStrings.Get(19209);
736     else
737       g_PVRClients->GetClientName(channel->ClientID(), clientName);
738     channelFile->SetProperty("ClientName", clientName);
739
740     m_channelItems->Add(channelFile);
741   }
742
743   CGUISpinControlEx *pSpin = (CGUISpinControlEx *)GetControl(SPIN_EPGSOURCE_SELECTION);
744   if (pSpin)
745   {
746     pSpin->Clear();
747     pSpin->AddLabel(g_localizeStrings.Get(19210), 0);
748     /// TODO: Add Labels for EPG scrapers here
749   }
750
751   Renumber();
752   m_viewControl.SetItems(*m_channelItems);
753   m_viewControl.SetSelectedItem(m_iSelected);
754
755   g_graphicsContext.Unlock();
756 }
757
758 void CGUIDialogPVRChannelManager::Clear(void)
759 {
760   m_viewControl.Clear();
761   m_channelItems->Clear();
762 }
763
764 bool CGUIDialogPVRChannelManager::PersistChannel(CFileItemPtr pItem, CPVRChannelGroupPtr group, unsigned int *iChannelNumber)
765 {
766   if (!pItem || !pItem->HasPVRChannelInfoTag() || !group)
767     return false;
768
769   /* get values from the form */
770   bool bHidden              = !pItem->GetProperty("ActiveChannel").asBoolean();
771   bool bVirtual             = pItem->GetProperty("Virtual").asBoolean();
772   bool bEPGEnabled          = pItem->GetProperty("UseEPG").asBoolean();
773   bool bParentalLocked      = pItem->GetProperty("ParentalLocked").asBoolean();
774   int iEPGSource            = (int)pItem->GetProperty("EPGSource").asInteger();
775   CStdString strChannelName = pItem->GetProperty("Name").asString();
776   CStdString strIconPath    = pItem->GetProperty("Icon").asString();
777   CStdString strStreamURL   = pItem->GetProperty("StreamURL").asString();
778
779   return group->UpdateChannel(*pItem, bHidden, bVirtual, bEPGEnabled, bParentalLocked, iEPGSource, ++(*iChannelNumber), strChannelName, strIconPath, strStreamURL);
780 }
781
782 void CGUIDialogPVRChannelManager::SaveList(void)
783 {
784   if (!m_bContainsChanges)
785    return;
786
787   /* display the progress dialog */
788   CGUIDialogProgress* pDlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
789   pDlgProgress->SetHeading(190);
790   pDlgProgress->SetLine(0, "");
791   pDlgProgress->SetLine(1, 328);
792   pDlgProgress->SetLine(2, "");
793   pDlgProgress->StartModal();
794   pDlgProgress->Progress();
795   pDlgProgress->SetPercentage(0);
796
797   /* persist all channels */
798   unsigned int iNextChannelNumber(0);
799   CPVRChannelGroupPtr group = g_PVRChannelGroups->GetGroupAll(m_bIsRadio);
800   if (!group)
801     return;
802   for (int iListPtr = 0; iListPtr < m_channelItems->Size(); iListPtr++)
803   {
804     CFileItemPtr pItem = m_channelItems->Get(iListPtr);
805     PersistChannel(pItem, group, &iNextChannelNumber);
806
807     pDlgProgress->SetPercentage(iListPtr * 100 / m_channelItems->Size());
808   }
809
810   group->SortAndRenumber();
811   group->Persist();
812   m_bContainsChanges = false;
813   SetItemsUnchanged();
814   pDlgProgress->Close();
815 }
816
817 void CGUIDialogPVRChannelManager::SetItemsUnchanged(void)
818 {
819   for (int iItemPtr = 0; iItemPtr < m_channelItems->Size(); iItemPtr++)
820   {
821     CFileItemPtr pItem = m_channelItems->Get(iItemPtr);
822     if (pItem)
823       pItem->SetProperty("Changed", false);
824   }
825 }
826
827 void CGUIDialogPVRChannelManager::Renumber(void)
828 {
829   int iNextChannelNumber(0);
830   CStdString strNumber;
831   CFileItemPtr pItem;
832   for (int iChannelPtr = 0; iChannelPtr < m_channelItems->Size(); iChannelPtr++)
833   {
834     pItem = m_channelItems->Get(iChannelPtr);
835     if (pItem->GetProperty("ActiveChannel").asBoolean())
836     {
837       strNumber.Format("%i", ++iNextChannelNumber);
838       pItem->SetProperty("Number", strNumber);
839     }
840     else
841       pItem->SetProperty("Number", "-");
842   }
843 }