/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
C++ | 412 lines | 326 code | 60 blank | 26 comment | 53 complexity | 74dcbd1a3bdedc87bc27b45dedf42d8d MD5 | raw file
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
22#include "ContextMenuManager.h"
23#include "GUIInfoManager.h"
24#include "cores/AudioEngine/Engines/ActiveAE/AudioDSPAddons/ActiveAEDSP.h"
25#include "epg/EpgContainer.h"
26#include "dialogs/GUIDialogKaiToast.h"
27#include "dialogs/GUIDialogOK.h"
28#include "dialogs/GUIDialogYesNo.h"
29#include "guilib/GUIKeyboardFactory.h"
30#include "guilib/GUIRadioButtonControl.h"
31#include "guilib/GUIWindowManager.h"
32#include "input/Key.h"
33#include "threads/SingleLock.h"
34#include "utils/StringUtils.h"
35#include "utils/Variant.h"
36
37#include "pvr/PVRManager.h"
38#include "pvr/addons/PVRClients.h"
39#include "pvr/channels/PVRChannelGroupsContainer.h"
40#include "pvr/dialogs/GUIDialogPVRChannelManager.h"
41#include "pvr/dialogs/GUIDialogPVRGroupManager.h"
42#include "pvr/timers/PVRTimers.h"
43
44#include "GUIWindowPVRChannels.h"
45
46using namespace PVR;
47using namespace EPG;
48
49CGUIWindowPVRChannels::CGUIWindowPVRChannels(bool bRadio) :
50 CGUIWindowPVRBase(bRadio, bRadio ? WINDOW_RADIO_CHANNELS : WINDOW_TV_CHANNELS, "MyPVRChannels.xml"),
51 m_bShowHiddenChannels(false)
52{
53 g_EpgContainer.RegisterObserver(this);
54 g_infoManager.RegisterObserver(this);
55}
56
57CGUIWindowPVRChannels::~CGUIWindowPVRChannels()
58{
59 g_infoManager.UnregisterObserver(this);
60 g_EpgContainer.UnregisterObserver(this);
61}
62
63void CGUIWindowPVRChannels::GetContextButtons(int itemNumber, CContextButtons &buttons)
64{
65 if (itemNumber < 0 || itemNumber >= m_vecItems->Size())
66 return;
67 CFileItemPtr pItem = m_vecItems->Get(itemNumber);
68 CPVRChannelPtr channel(pItem->GetPVRChannelInfoTag());
69
70 if (channel->GetEPGNow())
71 {
72 buttons.Add(CONTEXT_BUTTON_INFO, 19047); /* Programme information */
73 buttons.Add(CONTEXT_BUTTON_FIND, 19003); /* Find similar */
74 }
75
76 if (channel->IsRecording())
77 buttons.Add(CONTEXT_BUTTON_STOP_RECORD, 19059); /* Stop recording */
78 else if (g_PVRClients->SupportsTimers(channel->ClientID()))
79 buttons.Add(CONTEXT_BUTTON_START_RECORD, 264); /* Record */
80
81 if (CServiceBroker::GetADSP().IsProcessing())
82 buttons.Add(CONTEXT_BUTTON_ACTIVE_ADSP_SETTINGS, 15047); /* Audio DSP settings */
83
84 if (g_PVRClients->HasMenuHooks(channel->ClientID(), PVR_MENUHOOK_CHANNEL))
85 buttons.Add(CONTEXT_BUTTON_MENU_HOOKS, 19195); /* PVR client specific action */
86
87 // Add parent buttons before the Manage button
88 CGUIWindowPVRBase::GetContextButtons(itemNumber, buttons);
89
90 buttons.Add(CONTEXT_BUTTON_EDIT, 16106); /* Manage... */
91}
92
93std::string CGUIWindowPVRChannels::GetDirectoryPath(void)
94{
95 return StringUtils::Format("pvr://channels/%s/%s/",
96 m_bRadio ? "radio" : "tv",
97 m_bShowHiddenChannels ? ".hidden" : GetChannelGroup()->GroupName().c_str());
98}
99
100bool CGUIWindowPVRChannels::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
101{
102 if (itemNumber < 0 || itemNumber >= m_vecItems->Size())
103 return false;
104 CFileItemPtr pItem = m_vecItems->Get(itemNumber);
105
106 return OnContextButtonAdd(pItem.get(), button) ||
107 OnContextButtonInfo(pItem.get(), button) ||
108 OnContextButtonGroupManager(pItem.get(), button) ||
109 OnContextButtonUpdateEpg(pItem.get(), button) ||
110 OnContextButtonStartRecord(pItem.get(), button) ||
111 OnContextButtonStopRecord(pItem.get(), button) ||
112 OnContextButtonManage(pItem.get(), button) ||
113 OnContextButtonActiveAEDSPSettings(pItem.get(), button) ||
114 CGUIWindowPVRBase::OnContextButton(itemNumber, button);
115}
116
117bool CGUIWindowPVRChannels::Update(const std::string &strDirectory, bool updateFilterPath /* = true */)
118{
119 bool bReturn = CGUIWindowPVRBase::Update(strDirectory);
120
121 if (bReturn)
122 {
123 CSingleLock lock(m_critSection);
124 /* empty list for hidden channels */
125 if (m_vecItems->GetObjectCount() == 0 && m_bShowHiddenChannels)
126 {
127 /* show the visible channels instead */
128 m_bShowHiddenChannels = false;
129 lock.Leave();
130 Update(GetDirectoryPath());
131 }
132 }
133 return bReturn;
134}
135
136void CGUIWindowPVRChannels::UpdateButtons(void)
137{
138 CGUIRadioButtonControl *btnShowHidden = (CGUIRadioButtonControl*) GetControl(CONTROL_BTNSHOWHIDDEN);
139 if (btnShowHidden)
140 {
141 btnShowHidden->SetVisible(g_PVRChannelGroups->GetGroupAll(m_bRadio)->GetNumHiddenChannels() > 0);
142 btnShowHidden->SetSelected(m_bShowHiddenChannels);
143 }
144
145 CGUIWindowPVRBase::UpdateButtons();
146 SET_CONTROL_LABEL(CONTROL_LABEL_HEADER1, m_bShowHiddenChannels ? g_localizeStrings.Get(19022) : GetChannelGroup()->GroupName());
147}
148
149bool CGUIWindowPVRChannels::OnAction(const CAction &action)
150{
151 switch (action.GetID())
152 {
153 case REMOTE_0:
154 case REMOTE_1:
155 case REMOTE_2:
156 case REMOTE_3:
157 case REMOTE_4:
158 case REMOTE_5:
159 case REMOTE_6:
160 case REMOTE_7:
161 case REMOTE_8:
162 case REMOTE_9:
163 return ActionInputChannelNumber(action.GetID() - REMOTE_0);
164 }
165
166 return CGUIWindowPVRBase::OnAction(action);
167}
168
169bool CGUIWindowPVRChannels::OnMessage(CGUIMessage& message)
170{
171 bool bReturn = false;
172 switch (message.GetMessage())
173 {
174 case GUI_MSG_CLICKED:
175 if (message.GetSenderId() == m_viewControl.GetCurrentControl())
176 {
177 int iItem = m_viewControl.GetSelectedItem();
178 if (iItem >= 0 && iItem < m_vecItems->Size())
179 {
180 bReturn = true;
181 switch (message.GetParam1())
182 {
183 case ACTION_SELECT_ITEM:
184 case ACTION_MOUSE_LEFT_CLICK:
185 case ACTION_PLAY:
186 ActionPlayChannel(m_vecItems->Get(iItem).get());
187 break;
188 case ACTION_SHOW_INFO:
189 ShowEPGInfo(m_vecItems->Get(iItem).get());
190 break;
191 case ACTION_DELETE_ITEM:
192 ActionDeleteChannel(m_vecItems->Get(iItem).get());
193 break;
194 case ACTION_CONTEXT_MENU:
195 case ACTION_MOUSE_RIGHT_CLICK:
196 OnPopupMenu(iItem);
197 break;
198 default:
199 bReturn = false;
200 break;
201 }
202 }
203 }
204 else if (message.GetSenderId() == CONTROL_BTNSHOWHIDDEN)
205 {
206 CGUIRadioButtonControl *radioButton = (CGUIRadioButtonControl*)GetControl(CONTROL_BTNSHOWHIDDEN);
207 if (radioButton)
208 {
209 m_bShowHiddenChannels = radioButton->IsSelected();
210 Update(GetDirectoryPath());
211 }
212
213 bReturn = true;
214 }
215 else if (message.GetSenderId() == CONTROL_BTNFILTERCHANNELS)
216 {
217 std::string filter = GetProperty("filter").asString();
218 CGUIKeyboardFactory::ShowAndGetFilter(filter, false);
219 OnFilterItems(filter);
220 UpdateButtons();
221
222 bReturn = true;
223 }
224 break;
225 case GUI_MSG_REFRESH_LIST:
226 switch(message.GetParam1())
227 {
228 case ObservableMessageChannelGroup:
229 case ObservableMessageTimers:
230 case ObservableMessageEpg:
231 case ObservableMessageEpgContainer:
232 case ObservableMessageEpgActiveItem:
233 case ObservableMessageCurrentItem:
234 case ObservableMessageRecordings:
235 {
236 SetInvalid();
237 break;
238 }
239 case ObservableMessageChannelGroupReset:
240 {
241 Refresh(true);
242 break;
243 }
244 }
245 break;
246 }
247
248 return bReturn || CGUIWindowPVRBase::OnMessage(message);
249}
250
251bool CGUIWindowPVRChannels::OnContextButtonAdd(CFileItem *item, CONTEXT_BUTTON button)
252{
253 bool bReturn = false;
254
255 if (button == CONTEXT_BUTTON_ADD)
256 {
257 CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19038});
258 bReturn = true;
259 }
260
261 return bReturn;
262}
263
264bool CGUIWindowPVRChannels::OnContextButtonGroupManager(CFileItem *item, CONTEXT_BUTTON button)
265{
266 bool bReturn = false;
267
268 if (button == CONTEXT_BUTTON_GROUP_MANAGER)
269 {
270 ShowGroupManager();
271 bReturn = true;
272 }
273
274 return bReturn;
275}
276
277bool CGUIWindowPVRChannels::OnContextButtonInfo(CFileItem *item, CONTEXT_BUTTON button)
278{
279 bool bReturn = false;
280
281 if (button == CONTEXT_BUTTON_INFO)
282 {
283 ShowEPGInfo(item);
284 bReturn = true;
285 }
286
287 return bReturn;
288}
289
290bool CGUIWindowPVRChannels::OnContextButtonManage(CFileItem *item, CONTEXT_BUTTON button)
291{
292 bool bReturn = false;
293
294 if (button == CONTEXT_BUTTON_EDIT)
295 {
296 // Create context sub menu
297 CContextButtons buttons;
298 buttons.Add(CONTEXT_BUTTON_GROUP_MANAGER, 19048);
299 buttons.Add(CONTEXT_BUTTON_CHANNEL_MANAGER, 19199);
300 buttons.Add(CONTEXT_BUTTON_UPDATE_EPG, 19251);
301
302 // Get the response
303 int button = CGUIDialogContextMenu::ShowAndGetChoice(buttons);
304 if (button >= 0)
305 {
306 switch ((CONTEXT_BUTTON)button)
307 {
308 case CONTEXT_BUTTON_GROUP_MANAGER:
309 ShowGroupManager();
310 break;
311 case CONTEXT_BUTTON_CHANNEL_MANAGER:
312 ShowChannelManager();
313 break;
314 case CONTEXT_BUTTON_UPDATE_EPG:
315 OnContextButtonUpdateEpg(item, (CONTEXT_BUTTON)button);
316 break;
317 default:
318 break;
319 }
320
321 // Refresh the list in case anything was changed
322 Refresh(true);
323 }
324
325 bReturn = true;
326 }
327
328 return bReturn;
329}
330
331bool CGUIWindowPVRChannels::OnContextButtonStartRecord(CFileItem *item, CONTEXT_BUTTON button)
332{
333 bool bReturn = false;
334
335 if (button == CONTEXT_BUTTON_START_RECORD)
336 {
337 AddTimer(item);
338 bReturn = true;
339 }
340 else if (button == CONTEXT_BUTTON_ADD_TIMER)
341 {
342 AddTimerRule(item);
343 bReturn = true;
344 }
345
346 return bReturn;
347}
348
349bool CGUIWindowPVRChannels::OnContextButtonStopRecord(CFileItem *item, CONTEXT_BUTTON button)
350{
351 bool bReturn = false;
352
353 if (button == CONTEXT_BUTTON_STOP_RECORD)
354 {
355 StopRecordFile(item);
356 bReturn = true;
357 }
358
359 return bReturn;
360}
361
362bool CGUIWindowPVRChannels::OnContextButtonUpdateEpg(CFileItem *item, CONTEXT_BUTTON button)
363{
364 bool bReturn = false;
365
366 if (button == CONTEXT_BUTTON_UPDATE_EPG)
367 {
368 CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
369 if (!pDialog)
370 return bReturn;
371
372 CPVRChannelPtr channel(item->GetPVRChannelInfoTag());
373
374 pDialog->SetHeading(CVariant{19251});
375 pDialog->SetLine(0, CVariant{g_localizeStrings.Get(19252)});
376 pDialog->SetLine(1, CVariant{channel->ChannelName()});
377 pDialog->SetLine(2, CVariant{""});
378 pDialog->Open();
379
380 if (!pDialog->IsConfirmed())
381 return bReturn;
382
383 bReturn = UpdateEpgForChannel(item);
384
385 std::string strMessage = StringUtils::Format("%s: '%s'", g_localizeStrings.Get(bReturn ? 19253 : 19254).c_str(), channel->ChannelName().c_str());
386 CGUIDialogKaiToast::QueueNotification(bReturn ? CGUIDialogKaiToast::Info : CGUIDialogKaiToast::Error,
387 g_localizeStrings.Get(19166),
388 strMessage);
389 }
390
391 return bReturn;
392}
393
394void CGUIWindowPVRChannels::ShowChannelManager()
395{
396 CGUIDialogPVRChannelManager *dialog = (CGUIDialogPVRChannelManager *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_CHANNEL_MANAGER);
397 if (dialog)
398 dialog->Open();
399}
400
401void CGUIWindowPVRChannels::ShowGroupManager(void)
402{
403 /* Load group manager dialog */
404 CGUIDialogPVRGroupManager* pDlgInfo = (CGUIDialogPVRGroupManager*)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_GROUP_MANAGER);
405 if (!pDlgInfo)
406 return;
407
408 pDlgInfo->SetRadio(m_bRadio);
409 pDlgInfo->Open();
410
411 return;
412}