a4934865e4b89cb9481e38bf00870e79d4c7b982
[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 #include "utils/StringUtils.h"
44
45 #define BUTTON_OK                 4
46 #define BUTTON_APPLY              5
47 #define BUTTON_CANCEL             6
48 #define RADIOBUTTON_ACTIVE        7
49 #define EDIT_NAME                 8
50 #define BUTTON_CHANNEL_LOGO       9
51 #define IMAGE_CHANNEL_LOGO        10
52 #define RADIOBUTTON_USEEPG        12
53 #define SPIN_EPGSOURCE_SELECTION  13
54 #define RADIOBUTTON_PARENTAL_LOCK 14
55 #define CONTROL_LIST_CHANNELS     20
56 #define BUTTON_GROUP_MANAGER      30
57 #define BUTTON_EDIT_CHANNEL       31
58 #define BUTTON_DELETE_CHANNEL     32
59 #define BUTTON_NEW_CHANNEL        33
60 #define BUTTON_RADIO_TV           34
61
62 using namespace std;
63 using namespace PVR;
64
65 CGUIDialogPVRChannelManager::CGUIDialogPVRChannelManager(void) :
66     CGUIDialog(WINDOW_DIALOG_PVR_CHANNEL_MANAGER, "DialogPVRChannelManager.xml"),
67     m_bIsRadio(false),
68     m_bMovingMode(false),
69     m_bContainsChanges(false),
70     m_iSelected(0),
71     m_channelItems(new CFileItemList)
72 {
73 }
74
75 CGUIDialogPVRChannelManager::~CGUIDialogPVRChannelManager(void)
76 {
77   delete m_channelItems;
78 }
79
80 bool CGUIDialogPVRChannelManager::OnActionMove(const CAction &action)
81 {
82   bool bReturn(false);
83   int iActionId = action.GetID();
84   if (GetFocusedControlID() == CONTROL_LIST_CHANNELS &&
85       (iActionId == ACTION_MOVE_DOWN || iActionId == ACTION_MOVE_UP ||
86        iActionId == ACTION_PAGE_DOWN || iActionId == ACTION_PAGE_UP))
87   {
88     bReturn = true;
89     if (!m_bMovingMode)
90     {
91       CGUIDialog::OnAction(action);
92       int iSelected = m_viewControl.GetSelectedItem();
93       if (iSelected != m_iSelected)
94       {
95         m_iSelected = iSelected;
96         SetData(m_iSelected);
97       }
98     }
99     else
100     {
101       CStdString strNumber;
102       CGUIDialog::OnAction(action);
103
104       bool bMoveUp        = iActionId == ACTION_PAGE_UP || iActionId == ACTION_MOVE_UP;
105       unsigned int iLines = bMoveUp ? abs(m_iSelected - m_viewControl.GetSelectedItem()) : 1;
106       bool bOutOfBounds   = bMoveUp ? m_iSelected <= 0  : m_iSelected >= m_channelItems->Size() - 1;
107       if (bOutOfBounds)
108       {
109         bMoveUp = !bMoveUp;
110         iLines  = m_channelItems->Size() - 1;
111       }
112
113       for (unsigned int iLine = 0; iLine < iLines; iLine++)
114       {
115         unsigned int iNewSelect = bMoveUp ? m_iSelected - 1 : m_iSelected + 1;
116         if (m_channelItems->Get(iNewSelect)->GetProperty("Number").asString() != "-")
117         {
118           strNumber = StringUtils::Format("%i", m_iSelected+1);
119           m_channelItems->Get(iNewSelect)->SetProperty("Number", strNumber);
120           strNumber = StringUtils::Format("%i", iNewSelect+1);
121           m_channelItems->Get(m_iSelected)->SetProperty("Number", strNumber);
122         }
123         m_channelItems->Swap(iNewSelect, m_iSelected);
124         m_iSelected = iNewSelect;
125       }
126
127       m_viewControl.SetItems(*m_channelItems);
128       m_viewControl.SetSelectedItem(m_iSelected);
129     }
130   }
131
132   return bReturn;
133 }
134
135 bool CGUIDialogPVRChannelManager::OnAction(const CAction& action)
136 {
137   return OnActionMove(action) ||
138          CGUIDialog::OnAction(action);
139 }
140
141 void CGUIDialogPVRChannelManager::OnInitWindow()
142 {
143   CGUIDialog::OnInitWindow();
144
145   m_iSelected = 0;
146   m_bIsRadio = false;
147   m_bMovingMode = false;
148   m_bContainsChanges = false;
149   SetProperty("IsRadio", "");
150   Update();
151   SetData(m_iSelected);
152 }
153
154 void CGUIDialogPVRChannelManager::OnDeinitWindow(int nextWindowID)
155 {
156   Clear();
157
158   CGUIDialog::OnDeinitWindow(nextWindowID);
159 }
160
161 bool CGUIDialogPVRChannelManager::OnClickListChannels(CGUIMessage &message)
162 {
163   if (!m_bMovingMode)
164   {
165     int iAction = message.GetParam1();
166     int iItem = m_viewControl.GetSelectedItem();
167
168     /* Check file item is in list range and get his pointer */
169     if (iItem < 0 || iItem >= (int)m_channelItems->Size()) return true;
170
171     /* Process actions */
172     if (iAction == ACTION_SELECT_ITEM || iAction == ACTION_CONTEXT_MENU || iAction == ACTION_MOUSE_RIGHT_CLICK)
173     {
174       /* Show Contextmenu */
175       OnPopupMenu(iItem);
176
177       return true;
178     }
179   }
180   else
181   {
182     CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
183     if (pItem)
184     {
185       pItem->SetProperty("Changed", true);
186       pItem->Select(false);
187       m_bMovingMode = false;
188       m_bContainsChanges = true;
189       return true;
190     }
191   }
192
193   return false;
194 }
195
196 bool CGUIDialogPVRChannelManager::OnClickButtonOK(CGUIMessage &message)
197 {
198   SaveList();
199   Close();
200   return true;
201 }
202
203 bool CGUIDialogPVRChannelManager::OnClickButtonApply(CGUIMessage &message)
204 {
205   SaveList();
206   return true;
207 }
208
209 bool CGUIDialogPVRChannelManager::OnClickButtonCancel(CGUIMessage &message)
210 {
211   Close();
212   return true;
213 }
214
215 bool CGUIDialogPVRChannelManager::OnClickButtonRadioTV(CGUIMessage &message)
216 {
217   if (m_bContainsChanges)
218   {
219     CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
220     if (!pDialog)
221       return true;
222
223     pDialog->SetHeading(20052);
224     pDialog->SetLine(0, "");
225     pDialog->SetLine(1, 19212);
226     pDialog->SetLine(2, 20103);
227     pDialog->DoModal();
228
229     if (pDialog->IsConfirmed())
230       SaveList();
231   }
232
233   m_iSelected = 0;
234   m_bMovingMode = false;
235   m_bContainsChanges = false;
236   m_bIsRadio = !m_bIsRadio;
237   SetProperty("IsRadio", m_bIsRadio ? "true" : "");
238   Update();
239   SetData(m_iSelected);
240   return true;
241 }
242
243 bool CGUIDialogPVRChannelManager::OnClickButtonRadioActive(CGUIMessage &message)
244 {
245   CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_ACTIVE);
246   if (pRadioButton)
247   {
248     CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
249     if (pItem)
250     {
251       pItem->SetProperty("Changed", true);
252       pItem->SetProperty("ActiveChannel", pRadioButton->IsSelected());
253       m_bContainsChanges = true;
254       Renumber();
255       return true;
256     }
257   }
258
259   return false;
260 }
261
262 bool CGUIDialogPVRChannelManager::OnClickButtonRadioParentalLocked(CGUIMessage &message)
263 {
264   CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_PARENTAL_LOCK);
265
266   // ask for PIN first
267   if (!g_PVRManager.CheckParentalPIN(g_localizeStrings.Get(19262).c_str()))
268   {
269     pRadioButton->SetSelected(!pRadioButton->IsSelected());
270     return false;
271   }
272
273   if (pRadioButton)
274   {
275     CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
276     if (pItem)
277     {
278       pItem->SetProperty("Changed", true);
279       pItem->SetProperty("ParentalLocked", pRadioButton->IsSelected());
280       m_bContainsChanges = true;
281       Renumber();
282       return true;
283     }
284   }
285
286   return false;
287 }
288
289 bool CGUIDialogPVRChannelManager::OnClickButtonEditName(CGUIMessage &message)
290 {
291   CGUIEditControl *pEdit = (CGUIEditControl *)GetControl(EDIT_NAME);
292   if (pEdit)
293   {
294     CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
295     if (pItem)
296     {
297       pItem->SetProperty("Changed", true);
298       pItem->SetProperty("Name", pEdit->GetLabel2());
299       m_bContainsChanges = true;
300
301       return true;
302     }
303   }
304
305   return false;
306 }
307
308 bool CGUIDialogPVRChannelManager::OnClickButtonChannelLogo(CGUIMessage &message)
309 {
310   CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
311   if (!pItem)
312     return false;
313   if (CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked())
314     return false;
315   else if (!g_passwordManager.IsMasterLockUnlocked(true))
316     return false;
317
318   // setup our thumb list
319   CFileItemList items;
320
321   // add the current thumb, if available
322   if (!pItem->GetProperty("Icon").asString().empty())
323   {
324     CFileItemPtr current(new CFileItem("thumb://Current", false));
325     current->SetArt("thumb", pItem->GetPVRChannelInfoTag()->IconPath());
326     current->SetLabel(g_localizeStrings.Get(20016));
327     items.Add(current);
328   }
329   else if (pItem->HasArt("thumb"))
330   { // already have a thumb that the share doesn't know about - must be a local one, so we mayaswell reuse it.
331     CFileItemPtr current(new CFileItem("thumb://Current", false));
332     current->SetArt("thumb", pItem->GetArt("thumb"));
333     current->SetLabel(g_localizeStrings.Get(20016));
334     items.Add(current);
335   }
336
337   // and add a "no thumb" entry as well
338   CFileItemPtr nothumb(new CFileItem("thumb://None", false));
339   nothumb->SetIconImage(pItem->GetIconImage());
340   nothumb->SetLabel(g_localizeStrings.Get(20018));
341   items.Add(nothumb);
342
343   CStdString strThumb;
344   VECSOURCES shares;
345   if (CSettings::Get().GetString("pvrmenu.iconpath") != "")
346   {
347     CMediaSource share1;
348     share1.strPath = CSettings::Get().GetString("pvrmenu.iconpath");
349     share1.strName = g_localizeStrings.Get(19018);
350     shares.push_back(share1);
351   }
352   g_mediaManager.GetLocalDrives(shares);
353   if (!CGUIDialogFileBrowser::ShowAndGetImage(items, shares, g_localizeStrings.Get(1030), strThumb))
354     return false;
355
356   if (strThumb == "thumb://Current")
357     return true;
358
359   if (strThumb == "thumb://None")
360     strThumb = "";
361
362   pItem->SetProperty("Icon", strThumb);
363   pItem->SetProperty("Changed", true);
364   m_bContainsChanges = true;
365   return true;
366 }
367
368 bool CGUIDialogPVRChannelManager::OnClickButtonUseEPG(CGUIMessage &message)
369 {
370   CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_USEEPG);
371   if (pRadioButton)
372   {
373     CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
374     if (pItem)
375     {
376       pItem->SetProperty("Changed", true);
377       pItem->SetProperty("UseEPG", pRadioButton->IsSelected());
378       m_bContainsChanges = true;
379
380       return true;
381     }
382   }
383
384   return false;
385 }
386
387 bool CGUIDialogPVRChannelManager::OnClickEPGSourceSpin(CGUIMessage &message)
388 {
389   // TODO: Add EPG scraper support
390   return true;
391 //  CGUISpinControlEx *pSpin = (CGUISpinControlEx *)GetControl(SPIN_EPGSOURCE_SELECTION);
392 //  if (pSpin)
393 //  {
394 //    CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
395 //    if (pItem)
396 //    {
397 //      pItem->SetProperty("EPGSource", (int)0);
398 //      pItem->SetProperty("Changed", true);
399 //      m_bContainsChanges = true;
400 //      return true;
401 //    }
402 //  }
403 }
404
405 bool CGUIDialogPVRChannelManager::OnClickButtonGroupManager(CGUIMessage &message)
406 {
407   /* Load group manager dialog */
408   CGUIDialogPVRGroupManager* pDlgInfo = (CGUIDialogPVRGroupManager*)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_GROUP_MANAGER);
409   if (!pDlgInfo)
410     return false;
411
412   pDlgInfo->SetRadio(m_bIsRadio);
413
414   /* Open dialog window */
415   pDlgInfo->DoModal();
416
417   Update();
418   return true;
419 }
420
421 bool CGUIDialogPVRChannelManager::OnClickButtonEditChannel(CGUIMessage &message)
422 {
423   CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
424   if (!pItem)
425     return false;
426
427   if (pItem->GetProperty("Virtual").asBoolean())
428   {
429     CStdString strURL = pItem->GetProperty("StreamURL").asString();
430     if (CGUIKeyboardFactory::ShowAndGetInput(strURL, g_localizeStrings.Get(19214), false))
431       pItem->SetProperty("StreamURL", strURL);
432     return true;
433   }
434
435   CGUIDialogOK::ShowAndGetInput(19033,19038,0,0);
436   return true;
437 }
438
439 bool CGUIDialogPVRChannelManager::OnClickButtonDeleteChannel(CGUIMessage &message)
440 {
441   CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
442   if (!pItem)
443     return false;
444
445   CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
446   if (!pDialog)
447     return true;
448
449   pDialog->SetHeading(19211);
450   pDialog->SetLine(0, "");
451   pDialog->SetLine(1, 750);
452   pDialog->SetLine(2, "");
453   pDialog->DoModal();
454
455   if (pDialog->IsConfirmed())
456   {
457     if (pItem->GetProperty("Virtual").asBoolean())
458     {
459       pItem->GetPVRChannelInfoTag()->SetVirtual(true);
460       m_channelItems->Remove(m_iSelected);
461       m_viewControl.SetItems(*m_channelItems);
462       Renumber();
463       return true;
464     }
465     CGUIDialogOK::ShowAndGetInput(19033,19038,0,0);
466   }
467   return true;
468 }
469
470 bool CGUIDialogPVRChannelManager::OnClickButtonNewChannel(CGUIMessage &message)
471 {
472   std::vector<long> clients;
473
474   CGUIDialogSelect* pDlgSelect = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
475   if (!pDlgSelect)
476     return false;
477
478   pDlgSelect->SetHeading(19213); // Select Client
479   pDlgSelect->Add(g_localizeStrings.Get(19209));
480   clients.push_back(PVR_VIRTUAL_CLIENT_ID);
481
482   PVR_CLIENTMAP clientMap;
483   if (g_PVRClients->GetConnectedClients(clientMap) > 0)
484   {
485     PVR_CLIENTMAP_ITR itr;
486     for (itr = clientMap.begin() ; itr != clientMap.end(); itr++)
487     {
488       clients.push_back((*itr).first);
489       pDlgSelect->Add((*itr).second->Name());
490     }
491   }
492   pDlgSelect->DoModal();
493
494   int selection = pDlgSelect->GetSelectedLabel();
495   if (selection >= 0 && selection <= (int) clients.size())
496   {
497     int clientID = clients[selection];
498     if (clientID == PVR_VIRTUAL_CLIENT_ID)
499     {
500       CStdString strURL = "";
501       if (CGUIKeyboardFactory::ShowAndGetInput(strURL, g_localizeStrings.Get(19214), false))
502       {
503         if (!strURL.IsEmpty())
504         {
505           CPVRChannel *newchannel = new CPVRChannel(m_bIsRadio);
506           newchannel->SetChannelName(g_localizeStrings.Get(19204));
507           newchannel->SetEPGEnabled(false);
508           newchannel->SetVirtual(true);
509           newchannel->SetStreamURL(strURL);
510           newchannel->SetClientID(PVR_VIRTUAL_CLIENT_ID);
511           if (g_PVRChannelGroups->CreateChannel(*newchannel))
512             g_PVRChannelGroups->GetGroupAll(m_bIsRadio)->Persist();
513
514           CFileItemPtr channel(new CFileItem(*newchannel));
515           if (channel)
516           {
517             channel->SetProperty("ActiveChannel", true);
518             channel->SetProperty("Name", g_localizeStrings.Get(19204));
519             channel->SetProperty("UseEPG", false);
520             channel->SetProperty("Icon", newchannel->IconPath());
521             channel->SetProperty("EPGSource", (int)0);
522             channel->SetProperty("ClientName", g_localizeStrings.Get(19209));
523             channel->SetProperty("ParentalLocked", false);
524
525             m_channelItems->AddFront(channel, m_iSelected);
526             m_viewControl.SetItems(*m_channelItems);
527             Renumber();
528           }
529         }
530       }
531     }
532     else
533     {
534       CGUIDialogOK::ShowAndGetInput(19033,19038,0,0);
535     }
536   }
537   return true;
538 }
539
540 bool CGUIDialogPVRChannelManager::OnMessageClick(CGUIMessage &message)
541 {
542   int iControl = message.GetSenderId();
543   switch(iControl)
544   {
545   case CONTROL_LIST_CHANNELS:
546     return OnClickListChannels(message);
547   case BUTTON_OK:
548     return OnClickButtonOK(message);
549   case BUTTON_APPLY:
550     return OnClickButtonApply(message);
551   case BUTTON_CANCEL:
552     return OnClickButtonCancel(message);
553   case BUTTON_RADIO_TV:
554     return OnClickButtonRadioTV(message);
555   case RADIOBUTTON_ACTIVE:
556     return OnClickButtonRadioActive(message);
557   case RADIOBUTTON_PARENTAL_LOCK:
558     return OnClickButtonRadioParentalLocked(message);
559   case EDIT_NAME:
560     return OnClickButtonEditName(message);
561   case BUTTON_CHANNEL_LOGO:
562     return OnClickButtonChannelLogo(message);
563   case RADIOBUTTON_USEEPG:
564     return OnClickButtonUseEPG(message);
565   case SPIN_EPGSOURCE_SELECTION:
566     return OnClickEPGSourceSpin(message);
567   case BUTTON_GROUP_MANAGER:
568     return OnClickButtonGroupManager(message);
569   case BUTTON_EDIT_CHANNEL:
570     return OnClickButtonEditChannel(message);
571   case BUTTON_DELETE_CHANNEL:
572     return OnClickButtonDeleteChannel(message);
573   case BUTTON_NEW_CHANNEL:
574     return OnClickButtonNewChannel(message);
575   default:
576     return false;
577   }
578 }
579
580 bool CGUIDialogPVRChannelManager::OnMessage(CGUIMessage& message)
581 {
582   unsigned int iMessage = message.GetMessage();
583
584   switch (iMessage)
585   {
586     case GUI_MSG_CLICKED:
587       return OnMessageClick(message);
588   }
589
590   return CGUIDialog::OnMessage(message);
591 }
592
593 void CGUIDialogPVRChannelManager::OnWindowLoaded(void)
594 {
595   CGUIDialog::OnWindowLoaded();
596
597   m_viewControl.Reset();
598   m_viewControl.SetParentWindow(GetID());
599   m_viewControl.AddView(GetControl(CONTROL_LIST_CHANNELS));
600 }
601
602 void CGUIDialogPVRChannelManager::OnWindowUnload(void)
603 {
604   CGUIDialog::OnWindowUnload();
605   m_viewControl.Reset();
606 }
607
608 CFileItemPtr CGUIDialogPVRChannelManager::GetCurrentListItem(int offset)
609 {
610   return m_channelItems->Get(m_iSelected);
611 }
612
613 bool CGUIDialogPVRChannelManager::OnPopupMenu(int iItem)
614 {
615   // popup the context menu
616   // grab our context menu
617   CContextButtons buttons;
618
619   // mark the item
620   if (iItem >= 0 && iItem < m_channelItems->Size())
621     m_channelItems->Get(iItem)->Select(true);
622   else
623     return false;
624
625   CFileItemPtr pItem = m_channelItems->Get(iItem);
626   if (!pItem)
627     return false;
628
629   buttons.Add(CONTEXT_BUTTON_MOVE, 116);              /* Move channel up or down */
630   if (pItem->GetProperty("Virtual").asBoolean())
631     buttons.Add(CONTEXT_BUTTON_EDIT_SOURCE, 1027);    /* Edit virtual channel URL */
632
633   int choice = CGUIDialogContextMenu::ShowAndGetChoice(buttons);
634
635   // deselect our item
636   if (iItem >= 0 && iItem < m_channelItems->Size())
637     m_channelItems->Get(iItem)->Select(false);
638
639   if (choice < 0)
640     return false;
641
642   return OnContextButton(iItem, (CONTEXT_BUTTON)choice);
643 }
644
645 bool CGUIDialogPVRChannelManager::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
646 {
647   /* Check file item is in list range and get his pointer */
648   if (itemNumber < 0 || itemNumber >= (int)m_channelItems->Size()) return false;
649
650   CFileItemPtr pItem = m_channelItems->Get(itemNumber);
651   if (!pItem)
652     return false;
653
654   if (button == CONTEXT_BUTTON_MOVE)
655   {
656     m_bMovingMode = true;
657     pItem->Select(true);
658   }
659   else if (button == CONTEXT_BUTTON_EDIT_SOURCE)
660   {
661     CStdString strURL = pItem->GetProperty("StreamURL").asString();
662     if (CGUIKeyboardFactory::ShowAndGetInput(strURL, g_localizeStrings.Get(19214), false))
663       pItem->SetProperty("StreamURL", strURL);
664   }
665   return true;
666 }
667
668 void CGUIDialogPVRChannelManager::SetData(int iItem)
669 {
670   CGUIEditControl        *pEdit;
671   CGUIRadioButtonControl *pRadioButton;
672
673   /* Check file item is in list range and get his pointer */
674   if (iItem < 0 || iItem >= (int)m_channelItems->Size()) return;
675
676   CFileItemPtr pItem = m_channelItems->Get(iItem);
677   if (!pItem)
678     return;
679
680   pEdit = (CGUIEditControl *)GetControl(EDIT_NAME);
681   if (pEdit)
682   {
683     pEdit->SetLabel2(pItem->GetProperty("Name").asString());
684     pEdit->SetInputType(CGUIEditControl::INPUT_TYPE_TEXT, 19208);
685   }
686
687   pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_ACTIVE);
688   if (pRadioButton) pRadioButton->SetSelected(pItem->GetProperty("ActiveChannel").asBoolean());
689
690   pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_USEEPG);
691   if (pRadioButton) pRadioButton->SetSelected(pItem->GetProperty("UseEPG").asBoolean());
692
693   pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_PARENTAL_LOCK);
694   if (pRadioButton) pRadioButton->SetSelected(pItem->GetProperty("ParentalLocked").asBoolean());
695 }
696
697 void CGUIDialogPVRChannelManager::Update()
698 {
699   // lock our display, as this window is rendered from the player thread
700   g_graphicsContext.Lock();
701   m_viewControl.SetCurrentView(CONTROL_LIST_CHANNELS);
702
703   // empty the lists ready for population
704   Clear();
705
706   CPVRChannelGroupPtr channels = g_PVRChannelGroups->GetGroupAll(m_bIsRadio);
707
708   // No channels available, nothing to do.
709   if(!channels)
710     return;
711
712   for (int iChannelPtr = 0; iChannelPtr < channels->Size(); iChannelPtr++)
713   {
714     CFileItemPtr channelFile = channels->GetByIndex(iChannelPtr);
715     if (!channelFile || !channelFile->HasPVRChannelInfoTag())
716       continue;
717     const CPVRChannel *channel = channelFile->GetPVRChannelInfoTag();
718
719     channelFile->SetProperty("ActiveChannel", !channel->IsHidden());
720     channelFile->SetProperty("Name", channel->ChannelName());
721     channelFile->SetProperty("UseEPG", channel->EPGEnabled());
722     channelFile->SetProperty("Icon", channel->IconPath());
723     channelFile->SetProperty("EPGSource", (int)0);
724     channelFile->SetProperty("ParentalLocked", channel->IsLocked());
725     channelFile->SetProperty("Number", StringUtils::Format("%i", channel->ChannelNumber()));
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 = StringUtils::Format("%i", ++iNextChannelNumber);
838       pItem->SetProperty("Number", strNumber);
839     }
840     else
841       pItem->SetProperty("Number", "-");
842   }
843 }