[PVR][Estuary] Timer settings dialog: Show client name in timer type selection dialog...
[xbmc.git] / xbmc / video / ContextMenus.cpp
blob9ce11f7fc2bc4f241b69b38687c717b7657367cf
1 /*
2 * Copyright (C) 2016-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "ContextMenus.h"
11 #include "Autorun.h"
12 #include "GUIUserMessages.h"
13 #include "PlayListPlayer.h"
14 #include "ServiceBroker.h"
15 #include "application/Application.h"
16 #include "application/ApplicationComponents.h"
17 #include "application/ApplicationPlayer.h"
18 #include "filesystem/Directory.h"
19 #include "guilib/GUIComponent.h"
20 #include "guilib/GUIWindowManager.h"
21 #include "guilib/LocalizeStrings.h"
22 #include "playlists/PlayList.h"
23 #include "settings/MediaSettings.h"
24 #include "utils/StringUtils.h"
25 #include "utils/URIUtils.h"
26 #include "video/VideoUtils.h"
27 #include "video/dialogs/GUIDialogVideoInfo.h"
28 #include "video/windows/GUIWindowVideoBase.h"
29 #include "view/GUIViewState.h"
31 #include <utility>
33 namespace CONTEXTMENU
36 CVideoInfo::CVideoInfo(MediaType mediaType)
37 : CStaticContextMenuAction(19033), m_mediaType(std::move(mediaType))
41 bool CVideoInfo::IsVisible(const CFileItem& item) const
43 if (!item.HasVideoInfoTag())
44 return false;
46 if (item.IsPVRRecording())
47 return false; // pvr recordings have its own implementation for this
49 return item.GetVideoInfoTag()->m_type == m_mediaType;
52 bool CVideoInfo::Execute(const std::shared_ptr<CFileItem>& item) const
54 CGUIDialogVideoInfo::ShowFor(*item);
55 return true;
58 bool CVideoRemoveResumePoint::IsVisible(const CFileItem& itemIn) const
60 CFileItem item(itemIn.GetItemToPlay());
61 if (item.IsDeleted()) // e.g. trashed pvr recording
62 return false;
64 // Folders don't have a resume point
65 return !item.m_bIsFolder && VIDEO_UTILS::GetItemResumeInformation(item).isResumable;
68 bool CVideoRemoveResumePoint::Execute(const std::shared_ptr<CFileItem>& item) const
70 CVideoLibraryQueue::GetInstance().ResetResumePoint(item);
71 return true;
74 bool CVideoMarkWatched::IsVisible(const CFileItem& item) const
76 if (item.IsDeleted()) // e.g. trashed pvr recording
77 return false;
79 if (item.m_bIsFolder && item.IsPlugin()) // we cannot manage plugin folder's watched state
80 return false;
82 if (item.m_bIsFolder) // Only allow video db content, video and recording folders to be updated recursively
84 if (item.HasVideoInfoTag())
85 return item.IsVideoDb();
86 else if (item.GetProperty("IsVideoFolder").asBoolean())
87 return true;
88 else
89 return !item.IsParentFolder() && URIUtils::IsPVRRecordingFileOrFolder(item.GetPath());
91 else if (!item.HasVideoInfoTag())
92 return false;
94 return item.GetVideoInfoTag()->GetPlayCount() == 0;
97 bool CVideoMarkWatched::Execute(const std::shared_ptr<CFileItem>& item) const
99 CVideoLibraryQueue::GetInstance().MarkAsWatched(item, true);
100 return true;
103 bool CVideoMarkUnWatched::IsVisible(const CFileItem& item) const
105 if (item.IsDeleted()) // e.g. trashed pvr recording
106 return false;
108 if (item.m_bIsFolder && item.IsPlugin()) // we cannot manage plugin folder's watched state
109 return false;
111 if (item.m_bIsFolder) // Only allow video db content, video and recording folders to be updated recursively
113 if (item.HasVideoInfoTag())
114 return item.IsVideoDb();
115 else if (item.GetProperty("IsVideoFolder").asBoolean())
116 return true;
117 else
118 return !item.IsParentFolder() && URIUtils::IsPVRRecordingFileOrFolder(item.GetPath());
120 else if (!item.HasVideoInfoTag())
121 return false;
123 return item.GetVideoInfoTag()->GetPlayCount() > 0;
126 bool CVideoMarkUnWatched::Execute(const std::shared_ptr<CFileItem>& item) const
128 CVideoLibraryQueue::GetInstance().MarkAsWatched(item, false);
129 return true;
132 bool CVideoBrowse::IsVisible(const CFileItem& item) const
134 if (item.IsFileFolder(EFILEFOLDER_MASK_ONBROWSE))
135 return false; // handled by CMediaWindow
137 return item.m_bIsFolder && VIDEO_UTILS::IsItemPlayable(item);
140 bool CVideoBrowse::Execute(const std::shared_ptr<CFileItem>& item) const
142 int target = WINDOW_INVALID;
143 if (URIUtils::IsPVRRadioRecordingFileOrFolder(item->GetPath()))
144 target = WINDOW_RADIO_RECORDINGS;
145 else if (URIUtils::IsPVRTVRecordingFileOrFolder(item->GetPath()))
146 target = WINDOW_TV_RECORDINGS;
147 else
148 target = WINDOW_VIDEO_NAV;
150 auto& windowMgr = CServiceBroker::GetGUI()->GetWindowManager();
152 if (target == windowMgr.GetActiveWindow())
154 CGUIMessage msg(GUI_MSG_NOTIFY_ALL, target, 0, GUI_MSG_UPDATE);
155 msg.SetStringParam(item->GetPath());
156 windowMgr.SendMessage(msg);
158 else
160 windowMgr.ActivateWindow(target, {item->GetPath(), "return"});
162 return true;
165 std::string CVideoResume::GetLabel(const CFileItem& item) const
167 return CGUIWindowVideoBase::GetResumeString(item.GetItemToPlay());
170 bool CVideoResume::IsVisible(const CFileItem& itemIn) const
172 CFileItem item(itemIn.GetItemToPlay());
173 if (item.IsDeleted()) // e.g. trashed pvr recording
174 return false;
176 return VIDEO_UTILS::GetItemResumeInformation(item).isResumable;
179 namespace
182 void AddRecordingsToPlayList(const std::shared_ptr<CFileItem>& item, CFileItemList& queuedItems)
184 if (item->m_bIsFolder)
186 CFileItemList items;
187 XFILE::CDirectory::GetDirectory(item->GetPath(), items, "", XFILE::DIR_FLAG_DEFAULTS);
189 const int watchedMode = CMediaSettings::GetInstance().GetWatchedMode("recordings");
190 const bool unwatchedOnly = watchedMode == WatchedModeUnwatched;
191 const bool watchedOnly = watchedMode == WatchedModeWatched;
192 for (const auto& currItem : items)
194 if (currItem->HasVideoInfoTag() &&
195 ((unwatchedOnly && currItem->GetVideoInfoTag()->GetPlayCount() > 0) ||
196 (watchedOnly && currItem->GetVideoInfoTag()->GetPlayCount() <= 0)))
197 continue;
199 AddRecordingsToPlayList(currItem, queuedItems);
202 else
204 queuedItems.Add(item);
208 void AddRecordingsToPlayListAndSort(const std::shared_ptr<CFileItem>& item,
209 CFileItemList& queuedItems)
211 queuedItems.SetPath(item->GetPath());
212 AddRecordingsToPlayList(item, queuedItems);
214 if (!queuedItems.IsEmpty())
216 const int windowId = CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow();
217 if (windowId == WINDOW_TV_RECORDINGS || windowId == WINDOW_RADIO_RECORDINGS)
219 std::unique_ptr<CGUIViewState> viewState(CGUIViewState::GetViewState(windowId, queuedItems));
220 if (viewState)
221 queuedItems.Sort(viewState->GetSortMethod());
226 void PlayAndQueueRecordings(const std::shared_ptr<CFileItem>& item, int windowId)
228 const std::shared_ptr<CFileItem> parentFolderItem =
229 std::make_shared<CFileItem>(URIUtils::GetParentPath(item->GetPath()), true);
231 // add all items of given item's directory to a temporary playlist, start playback of given item
232 CFileItemList queuedItems;
233 AddRecordingsToPlayListAndSort(parentFolderItem, queuedItems);
235 PLAYLIST::CPlayListPlayer& player = CServiceBroker::GetPlaylistPlayer();
237 player.ClearPlaylist(PLAYLIST::TYPE_VIDEO);
238 player.Reset();
239 player.Add(PLAYLIST::TYPE_VIDEO, queuedItems);
241 // figure out where to start playback
242 PLAYLIST::CPlayList& playList = player.GetPlaylist(PLAYLIST::TYPE_VIDEO);
243 int itemToPlay = 0;
245 for (int i = 0; i < queuedItems.Size(); ++i)
247 if (item->IsSamePath(queuedItems.Get(i).get()))
249 itemToPlay = i;
250 break;
254 if (player.IsShuffled(PLAYLIST::TYPE_VIDEO))
256 playList.Swap(0, playList.FindOrder(itemToPlay));
257 itemToPlay = 0;
260 player.SetCurrentPlaylist(PLAYLIST::TYPE_VIDEO);
261 player.Play(itemToPlay, "");
264 void SetPathAndPlay(CFileItem& item)
266 if (!item.m_bIsFolder && item.IsVideoDb())
268 item.SetProperty("original_listitem_url", item.GetPath());
269 item.SetPath(item.GetVideoInfoTag()->m_strFileNameAndPath);
271 item.SetProperty("check_resume", false);
273 if (item.IsLiveTV()) // pvr tv or pvr radio?
275 g_application.PlayMedia(item, "", PLAYLIST::TYPE_VIDEO);
277 else
279 item.SetProperty("playlist_type_hint", PLAYLIST::TYPE_VIDEO);
280 VIDEO_UTILS::PlayItem(std::make_shared<CFileItem>(item));
284 } // unnamed namespace
286 bool CVideoResume::Execute(const std::shared_ptr<CFileItem>& itemIn) const
288 CFileItem item(itemIn->GetItemToPlay());
289 #ifdef HAS_DVD_DRIVE
290 if (item.IsDVD() || item.IsCDDA())
291 return MEDIA_DETECT::CAutorun::PlayDisc(item.GetPath(), true, false);
292 #endif
294 item.SetStartOffset(STARTOFFSET_RESUME);
295 SetPathAndPlay(item);
296 return true;
299 std::string CVideoPlay::GetLabel(const CFileItem& itemIn) const
301 CFileItem item(itemIn.GetItemToPlay());
302 if (item.IsLiveTV())
303 return g_localizeStrings.Get(19000); // Switch to channel
304 if (VIDEO_UTILS::GetItemResumeInformation(item).isResumable)
305 return g_localizeStrings.Get(12021); // Play from beginning
306 return g_localizeStrings.Get(208); // Play
309 bool CVideoPlay::IsVisible(const CFileItem& item) const
311 return VIDEO_UTILS::IsItemPlayable(item);
314 bool CVideoPlay::Execute(const std::shared_ptr<CFileItem>& itemIn) const
316 CFileItem item(itemIn->GetItemToPlay());
317 #ifdef HAS_DVD_DRIVE
318 if (item.IsDVD() || item.IsCDDA())
319 return MEDIA_DETECT::CAutorun::PlayDisc(item.GetPath(), true, true);
320 #endif
321 SetPathAndPlay(item);
322 return true;
325 bool CVideoQueue::IsVisible(const CFileItem& item) const
327 if (CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_VIDEO_PLAYLIST)
328 return false; // Already queued
330 if (!item.CanQueue())
331 return false;
333 return VIDEO_UTILS::IsItemPlayable(item);
336 bool CVideoQueue::Execute(const std::shared_ptr<CFileItem>& item) const
338 if (CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_VIDEO_PLAYLIST)
339 return false; // Already queued
341 VIDEO_UTILS::QueueItem(item, VIDEO_UTILS::QueuePosition::POSITION_END);
342 return true;
345 bool CVideoPlayNext::IsVisible(const CFileItem& item) const
347 if (CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_VIDEO_PLAYLIST)
348 return false; // Already queued
350 if (!item.CanQueue())
351 return false;
353 return VIDEO_UTILS::IsItemPlayable(item);
356 bool CVideoPlayNext::Execute(const std::shared_ptr<CFileItem>& item) const
358 if (CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_VIDEO_PLAYLIST)
359 return false; // Already queued
361 VIDEO_UTILS::QueueItem(item, VIDEO_UTILS::QueuePosition::POSITION_BEGIN);
362 return true;
365 bool CVideoPlayAndQueue::IsVisible(const CFileItem& item) const
367 const int windowId = CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow();
368 if (windowId == WINDOW_VIDEO_PLAYLIST)
369 return false; // Already queued
371 if ((windowId == WINDOW_TV_RECORDINGS || windowId == WINDOW_RADIO_RECORDINGS) &&
372 item.IsUsablePVRRecording())
373 return true;
375 return false; //! @todo implement
378 bool CVideoPlayAndQueue::Execute(const std::shared_ptr<CFileItem>& item) const
380 const int windowId = CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow();
381 if (windowId == WINDOW_VIDEO_PLAYLIST)
382 return false; // Already queued
384 if ((windowId == WINDOW_TV_RECORDINGS || windowId == WINDOW_RADIO_RECORDINGS) &&
385 item->IsUsablePVRRecording())
387 // recursively add items located in the same folder as item to play list, starting with item
388 PlayAndQueueRecordings(item, windowId);
389 return true;
392 return true; //! @todo implement